Plugin Not Working, But Only On GoDaddy Hosted site

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.

Read More

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.

Related posts

Leave a Reply

1 comment

  1. I was able to recreate this, but it was a CDN (edge cache) and/or browser cache in my configuration that was bypassing your query.

    For the browser cache to be a problem, the searches had to occur as the result of a link click. For example, if you clicked a link to ?s=term, it would check the browser cache first. If this occurred as the result of a form GET then it should bypass the browser cache, but I may be wrong about that.

    To test this: check your .htaccess file for caching rules. Go Daddy uses browser caching rules to improve performance and compatibility with CDNs.

    For the CDN / edge cache to be a problem, you would have to be a visitor (no cookies). CDNs cache pages along with meta information (i.e. how the page “varies”) and this is usually the user agent, language, and some other things.

    Go Daddy’s ultimate hosting plans come with a CDN feature (which is what I tested with), but this may also happen with cloudflare or another CDN, too.

    To test this: Visit your site in a different browser or modify your hosts file to use your hosting server’s IP address instead of your CDN’s ip address.

    For a solution, I personally recommend using ajax. You cannot prevent some layer from caching the rendered HTML output of a search page, but you can embed an ajax callback to log the search string.

    I hope this helps!