Tell me more ×
WordPress Answers is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm creating a plugin for a friend to log search terms on his site. It's very basic. It creates a new table to store terms entered in the search box. It converts the search term to lower case, checks the database for a matching term and either inserts the term into the database or increases the count of a matching term. It was working as expected on my hosting account. Then I installed it on a WP install on a GoDaddy hosting account...

As long as I'm logged in it seems to work whether or not there is a matching term in the database. When I search the site as a guest, it will add a new unique search term to the database but if there is an existing term it does nothing. Well, that's not entirely true. I've seen it increase the count a few times but not by 1, by 2. It seems to function very sporadically on GoDaddy. I can't make sense of this. The actual plugin can be found here.

I appreciate any time spent looking at this.

Thanks

// Register function to be called when plugin is activated
register_activation_hook( __FILE__, 'mac_search_log_activation' );

function mac_search_log_activation(){
    global $wpdb;
    $prefix = $wpdb->prefix;
    $creation_query =
        'CREATE TABLE ' . $prefix . 'mac_search_log (
            `id` mediumint(8) NOT NULL AUTO_INCREMENT,
            `full_search_term` text NOT NULL,
            `count` mediumint(8) NOT NULL,
            PRIMARY KEY (`id`)
            );';

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $creation_query );
}

// Register function to be called when administration pages init takes place
add_action( 'admin_init', 'mac_search_log_admin_init' );

function mac_search_log_admin_init(){
    add_action('admin_post_delete_mac_search_log_term', 'delete_mac_search_log_term');
}

// Register function to be called when admin menu is constructed
add_action( 'admin_menu', 'mac_search_log_settings_menu' );

// Add new menu item for Search Term History
function mac_search_log_settings_menu() {
    add_menu_page( 'Search Term History',
        'Search Term History', 'manage_options',
        'search-term-history',
        'mac_search_log_config_page',
        null,
        4.7);
}

// Function to render plugin admin page
function mac_search_log_config_page() {
    global $wpdb;
    ?>

    <!-- Top-level menu -->
    <div id="mac_search_log-general" class="wrap">
        <h2>Searched Terms</h2>

        <form method="post"
              action="<?php echo admin_url( 'admin-post.php' ); ?>">
            <input type="hidden" name="action" value="delete_mac_search_log_term" />
            <?php wp_nonce_field( 'mac_search_log_term_deletion' ); ?>

        <?php
        $term_query = 'select * from ';
        $term_query .= $wpdb->prefix;
        $term_query .= 'mac_search_log ORDER by count DESC';

        $term_items = $wpdb->get_results( $wpdb->prepare( $term_query ), ARRAY_A );
        ?>

       <table class="wp-list-table widefat fixed" >
            <thead><tr>
                <th style="width: 50px">Delete</th><th style="width: 300px">Search Term</th><th>Count</th></tr></thead>

            <?php
            // Display search terms if query returned results
            if ( $term_items ) {
                foreach ( $term_items as $term_item ) {
                    echo '<tr style="background: #FFF">';

                    echo '<td><input type="checkbox" name="terms[]" value="';
                    echo esc_attr( $term_item['id'] ) . '" /></td>';

                    echo '<td>' . $term_item['full_search_term'] . '</td>';;
                    echo '<td>' . $term_item['count'] . '</td></tr>';
                }
            } else {
                echo '<tr style="background: #FFF">';
                echo '<td colspan=4>No Searches Yet</td></tr>';
            }
            ?>
        </table><br />

            <input type="submit" value="Delete Selected"
                   class="button-primary"/>
        </form>


    </div>
    <?php }

    add_filter('pre_get_posts','MACSearchLog');

    function MACSearchLog($query) {
        if ($query->is_search) {
            global $wpdb;
            $term = strtolower($query->query_vars['s']);

            $term_query = 'select * from ';
            $term_query .= $wpdb->prefix;
            $term_query .= 'mac_search_log';
            $term_query .= ' WHERE full_search_term = "'.$term.'"';

            $term_items = $wpdb->get_row( $wpdb->prepare( $term_query ), ARRAY_A );

            if(empty($term_items)){
                // insert term and set count to 1
                $term_item = array(
                    'full_search_term' => $term,
                    'count' => 1
                );
                $wpdb->insert($wpdb->prefix.'mac_search_log', $term_item);

            }else{
                // update existing row count++
                $new_query = 'UPDATE ';
                $new_query .= $wpdb->prefix;
                $new_query .= 'mac_search_log';
                $new_query .= ' SET count = count+1 ';
                $new_query .= 'WHERE id = '.$term_items['id'];
                $wpdb->query($wpdb->prepare($new_query));
            }

        }

    }

    function delete_mac_search_log_term(){
        $deleted_terms = array();
        // Check that user has proper security level
        if ( !current_user_can( 'manage_options' ) )
            wp_die( 'Not allowed' );
        // Check if nonce field is present
        check_admin_referer( 'mac_search_log_term_deletion' );
        // If search terms are present, cycle through array and call SQL
        // command to delete entries one by one
        if ( !empty( $_POST['terms'] ) ) {
        // Retrieve array of search term IDs to be deleted
            $terms_to_delete = $_POST['terms'];
            global $wpdb;
            foreach ( $terms_to_delete as $term_to_delete ) {
                $deleted_terms[] = get_search_term_by_id(intval($term_to_delete));// TO GET SEARCH TERMS FOR EMAIL
                $query = 'DELETE from ' . $wpdb->prefix;
                $query .= 'mac_search_log ';
                $query .= 'WHERE id = ' .
                    intval( $term_to_delete );
                $wpdb->query( $wpdb->prepare( $query ) );
            }
        }
        // UNCOMMENT THE FOLLOWING 2 LINES TO DISPATCH EMAIL WITH DELETED SEARCH TERMS
    //    $terms = print_r($deleted_terms, true);
    //    wp_mail( get_option('admin_email'), 'Search Terms Deleted', $terms);

        // Reload the search term history page
        wp_redirect( add_query_arg( 'page', 'search-term-history',
            admin_url( 'admin.php' ) ) );
        exit;
    }

    function get_search_term_by_id($id){
        global $wpdb;
        $term_query = 'select * from ';
        $term_query .= $wpdb->prefix;
        $term_query .= 'mac_search_log ';
        $term_query .= 'WHERE `id` = '.$id;

        $term_item = $wpdb->get_row( $wpdb->prepare( $term_query ), OBJECT );

        if($term_item){
                return $term_item->full_search_term;
        }else{
            return null;
        }
    }

Edit: I've been logging queries and everything else involved. Nothing looks off. I replaced the SQL query with $wpdb->update() and replaced if(empty($term_items)){ with if($term_items) while swapping the associated actions, and that seems to have cleared up some of the anomolies with the count, but it just will not update on the GoDaddy account unless I am logged in. On one hand I find it hard to believe that a different hosting account would have an effect on this, but I've seen stranger things from GoDaddy in the past.

share|improve this question
just from a quick glance I can see that prepare isn't being used correctly. it's probably not a reason things would be misbehaving, but it's definitely something that should be fixed. see this post for an explanation. – Milo Jan 27 at 5:52
@Milo Thanks for the heads up on that. I was unaware it worked like printf() I made that change and now on GoDaddy it will update once when searching as a guest, but does nothing after the first update. Still works as expected on HostGator. Guess this is one step closer to solving the problem. – Mark Jan 27 at 8:16
@Milo I guess the single update as Guest was an anomaly, it's not updating at all as Guest today on GoDaddy. I had a question about prepare(). If I change the first query in the above code to use %s for table name then use ->prepare($term_query, $table_name) it puts backticks around the table name and I get no results. Any idea why that would be? If I include the table name in the query and use ->prepare($term_query) there are no backticks around the table name and it returns all my rows. – Mark Jan 27 at 20:58
On a side note, I called GoDaddy with the slim hope they might have a suggestion. After a few minutes, the guy came back and asked if I had posted something about this recently on StackExchange. Nice tech support, GoDaddy. – Mark Jan 28 at 11:07

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.