function tguy_sm_save_search($posts) { // Check if the request is a search, and if so then save details. // This is a filter but does not change the posts. global $wpdb, $wp_query, $tguy_sm_save_count; if (is_search() && !is_paged() && !is_admin() && (0 === $tguy_sm_save_count || TGUY_SM_ALLOW_DUPLICATE_SAVES) && (tguy_sm_array_value($_SERVER, 'HTTP_REFERER') || TGUY_SM_ALLOW_EMPTY_REFERER)) { // Get all details of this search // search string is the raw query $search_string = $wp_query->query_vars['s']; if (get_magic_quotes_gpc()) { $search_string = stripslashes($search_string); } // search terms is the words in the query $search_terms = $search_string; $search_terms = preg_replace('/[," ]+/', ' ', $search_terms); $search_terms = trim($search_terms); $hit_count = $wp_query->found_posts; // Thanks to Will for this line // Other useful details of the search $details = ''; $options = get_option('tguy_search_meter'); if ($options['sm_details_verbose']) { if (TGUY_SM_ALLOW_DUPLICATE_SAVES) { $details .= "Search Meter save count: {$tguy_sm_save_count}\n"; } foreach (array('REQUEST_URI', 'REQUEST_METHOD', 'QUERY_STRING', 'REMOTE_ADDR', 'HTTP_USER_AGENT', 'HTTP_REFERER') as $header) { $details .= $header . ': ' . tguy_sm_array_value($_SERVER, $header) . "\n"; } } // Sanitise as necessary $search_string = $wpdb->escape($search_string); $search_terms = $wpdb->escape($search_terms); $details = $wpdb->escape($details); // Save the individual search to the DB $query = "INSERT INTO `{$wpdb->prefix}searchmeter_recent` (`terms`,`datetime`,`hits`,`details`)\n\t\tVALUES ('{$search_string}',NOW(),{$hit_count},'{$details}')"; $success = $wpdb->query($query); if ($success) { // Ensure table never grows larger than TGUY_SM_HISTORY_SIZE + 100 $rowcount = $wpdb->get_var("SELECT count(`datetime`) as rowcount\n\t\t\t\tFROM `{$wpdb->prefix}searchmeter_recent`"); if (TGUY_SM_HISTORY_SIZE + 100 < $rowcount) { // find time of (TGUY_SM_HISTORY_SIZE)th entry $dateZero = $wpdb->get_var("SELECT `datetime`\n\t\t\t\t\tFROM `{$wpdb->prefix}searchmeter_recent`\n\t\t\t\t\tORDER BY `datetime` DESC LIMIT " . TGUY_SM_HISTORY_SIZE . ", 1"); $query = "DELETE FROM `{$wpdb->prefix}searchmeter_recent` WHERE `datetime` < '{$dateZero}'"; $success = $wpdb->query($query); } } // Save search summary into the DB. Usually this will be a new row, so try to insert first $query = "INSERT INTO `{$wpdb->prefix}searchmeter` (`terms`,`date`,`count`,`last_hits`)\n\t\tVALUES ('{$search_terms}',CURDATE(),1,{$hit_count})"; // Temporarily suppress errors, as this query is expected to fail on duplicate searches in a single day. Thanks to James Collins. $suppress = $wpdb->suppress_errors(); $success = $wpdb->query($query); $wpdb->suppress_errors($suppress); if (!$success) { $query = "UPDATE `{$wpdb->prefix}searchmeter` SET\n\t\t\t\t`count` = `count` + 1,\n\t\t\t\t`last_hits` = {$hit_count}\n\t\t\tWHERE `terms` = '{$search_terms}' AND `date` = CURDATE()"; $success = $wpdb->query($query); } ++$tguy_sm_save_count; } return $posts; }
function tguy_sm_options_page() { if (isset($_POST['submitted'])) { check_admin_referer('search-meter-update-options_all'); $options = get_option('tguy_search_meter'); $options['sm_view_stats_capability'] = $_POST['sm_view_stats_capability']; $sm_filter_words = $_POST['sm_filter_words']; if (get_magic_quotes_gpc()) { $sm_filter_words = stripslashes($sm_filter_words); } $options['sm_filter_words'] = preg_replace('/\\s+/', ' ', trim($sm_filter_words)); $options['sm_ignore_admin_search'] = (bool) $_POST['sm_ignore_admin_search']; $options['sm_details_verbose'] = (bool) $_POST['sm_details_verbose']; $options['sm_disable_donation'] = (bool) $_POST['sm_disable_donation']; update_option('tguy_search_meter', $options); echo '<div id="message" class="updated fade"><p><strong>Plugin settings saved.</strong></p></div>'; } else { if (isset($_POST['tguy_sm_reset'])) { check_admin_referer('search-meter-reset-stats'); tguy_sm_reset_stats(); echo '<div id="message" class="updated fade"><p><strong>Statistics have been reset.</strong></p></div>'; } } $options = get_option('tguy_search_meter'); $view_stats_capability = tguy_sm_array_value($options, 'sm_view_stats_capability'); if ($view_stats_capability == '') { $view_stats_capability = TGUY_SM_DEFAULT_VIEW_STATS_CAPABILITY; } ?> <div class="wrap"> <h2>Search Meter Settings</h2> <form name="searchmeter" action="" method="post"> <?php if (function_exists('wp_nonce_field')) { wp_nonce_field('search-meter-update-options_all'); } ?> <input type="hidden" name="submitted" value="1" /> <table class="form-table"> <tr> <th scope="row">Show statistics to</th> <td> <fieldset> <label title='Users with "read" capability'> <input type="radio" name="sm_view_stats_capability" value="read" <?php echo $view_stats_capability == 'read' ? "checked=\"checked\"" : ""; ?> /> All logged-in users</label><br> <label title='Users with "publish_posts" capability'> <input type="radio" name="sm_view_stats_capability" value="publish_posts" <?php echo $view_stats_capability == 'publish_posts' ? "checked=\"checked\"" : ""; ?> /> Post authors and administrators</label><br> <label title='Users with "manage_options" capability'> <input type="radio" name="sm_view_stats_capability" value="manage_options" <?php echo $view_stats_capability == 'manage_options' ? "checked=\"checked\"" : ""; ?> /> Administrators only</label> </fieldset> </td> </tr> <tr valign="top"> <th scope="row">Search filter</th> <td> <fieldset> <label for="sm_filter_words">When a search term contains any of these words, it will be filtered and will not show up in the Recent Searches or Popular Searches widgets. This will match inside words, so “press” will match “WordPress”.</label> <textarea name="sm_filter_words" rows="3" cols="40" id="sm_filter_words" class="large-text code"><?php echo esc_html(tguy_sm_array_value($options, 'sm_filter_words')); ?> </textarea> </fieldset> </td> </tr> <tr> <th class="th-full" scope="row" colspan="2"> <label for="sm_ignore_admin_search" title='Administrators are users with "manage_options" capability'> <input type="checkbox" id="sm_ignore_admin_search" name="sm_ignore_admin_search" <?php echo tguy_sm_array_value($options, 'sm_ignore_admin_search') ? 'checked="checked"' : ''; ?> /> Ignore searches made by logged-in administrators </label> </th> </tr> <tr> <th class="th-full" scope="row" colspan="2"> <label for="sm_details_verbose"> <input type="checkbox" id="sm_details_verbose" name="sm_details_verbose" <?php echo tguy_sm_array_value($options, 'sm_details_verbose') ? 'checked="checked"' : ''; ?> /> Keep detailed information about recent searches (taken from HTTP headers) </label> </th> </tr> <tr> <th class="th-full" scope="row" colspan="2"> <label for="sm_disable_donation"> <input type="checkbox" id="sm_disable_donation" name="sm_disable_donation" <?php echo tguy_sm_array_value($options, 'sm_disable_donation') ? 'checked="checked"' : ''; ?> /> Hide the “Do you find this plugin useful?” box </label> </th> </tr> </table> <p class="submit"> <input name="Submit" class="button-primary" value="Save Changes" type="submit"> </p> </form> <h3>Reset statistics</h3> <p>Click this button to reset all search statistics. This will delete all information about previous searches.</p> <form name="tguy_sm_admin" action="" method="post"> <?php if (function_exists('wp_nonce_field')) { wp_nonce_field('search-meter-reset-stats'); } ?> <p class="submit"> <input name="tguy_sm_reset" class="button-secondary delete" value="Reset Statistics" type="submit" onclick="return confirm('You are about to delete all saved search statistics.\n \'Cancel\' to stop, \'OK\' to delete.');" /> </p> </form> <h3>Notes</h3> <p>To see your search statistics, go to the <a href="index.php?page=<?php echo plugin_basename(__FILE__); ?> ">Search Meter Dashboard</a>.</p> <p>For information and updates, see the <a href="http://thunderguy.com/semicolon/wordpress/search-meter-wordpress-plugin/">Search Meter home page</a>. At that page, you can also offer suggestions, request new features or report problems.</p> <?php if (!tguy_sm_array_value($options, 'sm_disable_donation')) { tguy_sm_show_donation_message(); } ?> </div> <?php }
function tguy_sm_save_search($posts) { // Check if the request is a search, and if so then save details. // This is a filter but does not change the posts. global $wpdb, $wp_query, $tguy_sm_save_count; // The filter may get called more than once for a given request. We ignore these duplicates. // Recording duplicate searches can be enabled by adding this line to functions.php: // add_filter('search_meter_record_duplicates', function() { return true; }); // Setting to true will record duplicates (the fact that it's a dupe will be recorded in the // details). This will mess up the stats, but could be useful for troubleshooting. $record_duplicates = apply_filters('search_meter_record_duplicates', false); if (is_search() && !is_paged() && !is_admin() && (0 === $tguy_sm_save_count || $record_duplicates) && tguy_sm_array_value($_SERVER, 'HTTP_REFERER')) { $options = get_option('tguy_search_meter'); // Break out if we're supposed to ignore admin searches if (tguy_sm_array_value($options, 'sm_ignore_admin_search') && current_user_can("manage_options")) { return $posts; // EARLY EXIT } // Get all details of this search // search string is the raw query $search_string = $wp_query->query_vars['s']; if (get_magic_quotes_gpc()) { $search_string = stripslashes($search_string); } // search terms is the words in the query $search_terms = $search_string; $search_terms = preg_replace('/[," ]+/', ' ', $search_terms); $search_terms = trim($search_terms); $hit_count = $wp_query->found_posts; // Thanks to Will for this line // Other useful details of the search $details = ''; if (tguy_sm_array_value($options, 'sm_details_verbose')) { if ($record_duplicates) { $details .= "Search Meter save count: {$tguy_sm_save_count}\n"; } foreach (array('REQUEST_URI', 'REQUEST_METHOD', 'QUERY_STRING', 'REMOTE_ADDR', 'HTTP_USER_AGENT', 'HTTP_REFERER') as $header) { $details .= $header . ': ' . tguy_sm_array_value($_SERVER, $header) . "\n"; } } // Save the individual search to the DB $success = $wpdb->query($wpdb->prepare("\n\t\t\tINSERT INTO `{$wpdb->prefix}searchmeter_recent` (`terms`,`datetime`,`hits`,`details`)\n\t\t\tVALUES (%s, NOW(), %d, %s)", $search_string, $hit_count, $details)); if ($success) { $rowcount = $wpdb->get_var("SELECT count(`datetime`) as rowcount\n\t\t\t\tFROM `{$wpdb->prefix}searchmeter_recent`"); // History size can be overridden by a user by adding a line like this to functions.php: // add_filter('search_meter_history_size', function() { return 50000; }); $history_size = apply_filters('search_meter_history_size', 500); // Ensure history table never grows larger than (history size) + 100; truncate it // to (history size) when it gets too big. (This we way will only truncate the table // every 100 searches, rather than every time.) if ($history_size + 100 < $rowcount) { // find time of ($history_size)th entry; delete everything before that $dateZero = $wpdb->get_var($wpdb->prepare("SELECT `datetime`\n\t\t\t\t\tFROM `{$wpdb->prefix}searchmeter_recent`\n\t\t\t\t\tORDER BY `datetime` DESC LIMIT %d, 1", $history_size)); $query = "DELETE FROM `{$wpdb->prefix}searchmeter_recent` WHERE `datetime` < '{$dateZero}'"; $success = $wpdb->query($query); } } // Save search summary into the DB. Usually this will be a new row, so try to insert first // Temporarily suppress errors, as this query is expected to fail on duplicate searches in a single day. Thanks to James Collins. $suppress = $wpdb->suppress_errors(); $success = $wpdb->query($wpdb->prepare("\n\t\t\tINSERT INTO `{$wpdb->prefix}searchmeter` (`terms`,`date`,`count`,`last_hits`)\n\t\t\tVALUES (%s, CURDATE(), 1, %d)", $search_terms, $hit_count)); $wpdb->suppress_errors($suppress); if (!$success) { $success = $wpdb->query($wpdb->prepare("\n\t\t\t\tUPDATE `{$wpdb->prefix}searchmeter` SET\n\t\t\t\t\t`count` = `count` + 1,\n\t\t\t\t\t`last_hits` = %d\n\t\t\t\tWHERE `terms` = %s AND `date` = CURDATE()", $hit_count, $search_terms)); } ++$tguy_sm_save_count; } return $posts; }