hits_table = $wpdb->prefix . 'bsuite3_hits'; $this->rterms_table = $wpdb->prefix . 'bsuite3_refs_terms'; // get the options // $this->options = unserialize(get_option('bStat3')); $this->ktnxbye = FALSE; // register hooks add_filter('the_content', array(&$this, 'hitit')); // activation and menu hooks register_activation_hook(__FILE__, array(&$this, 'activate')); add_action('widgets_init', array(&$this, 'widgets_register')); add_action('admin_menu', array(&$this, 'addmenus')); // end register WordPress hooks // register the taxonomy for search terms register_taxonomy( 'bsuite_search' , 'post' ); } function addmenus() { add_submenu_page('index.php', 'bSuite bStat Reports', 'bStat Reports', 2, __FILE__, array(&$this, 'reports')); } function reports() { global $wpdb, $bsuite; require(ABSPATH . PLUGINDIR .'/'. plugin_basename(dirname(__FILE__)) .'/bstat_reports.php'); } function activate() { $this->createtables(); // set some defaults for the widgets if(!get_option('bstat_pop_posts')) update_option('bstat_pop_posts', array('title' => 'Popular Posts', 'number' => 5, 'days' => 7)); if(!get_option('bstat_pop_refs')) update_option('bstat_pop_refs', array('title' => 'Popular Searches', 'number' => 5, 'days' => 7)); } function hitit(&$content){ // nonce this if($this->ktnxbye) return($content); global $wp_query; $id = 0; // if this hit can't be pinned on something else, we give it to post #0 if(is_singular()) $id = $wp_query->posts[0]->ID; $this->hit_post($id); $this->hit_ref($id); $this->ktnxbye = TRUE; // we're using the the_content hook because wp_head is theme dependent, // and template_redirect and loop_start could execute repeatedly // and defied my nonce-ing attempts return($content); } function hit_post($post_id) { global $wpdb; if($post_id = (int) $post_id){ $request = "INSERT INTO $this->hits_table (post_id, hit_count, hit_date) VALUES ($post_id, 1, NOW()) ON DUPLICATE KEY UPDATE hit_count = hit_count + 1;"; $wpdb->query($request); return(TRUE); } return(FALSE); } function hit_ref($post_id) { global $wpdb, $bsuite; $search = $this->get_search_terms($this->get_search_engine()); if(empty($search)) return(FALSE); // if we've got the full bsuite, then // set the object var so everybody can use this data if(!empty($bsuite)){ $bsuite->the_search_array = $search; $bsuite->the_search_terms = implode($search, ' '); } // check if this search is already in the terms table if(!is_term(implode($search, ' '), 'bsuite_search')) wp_insert_term(implode($search, ' '), 'bsuite_search'); // it's in the terms table, what's the id? $term_id = is_term(implode($search, ' ')); // write it to the bsuite3_refs table with date if(!empty($term_id) && $post_id = (int) $post_id){ $request = "INSERT INTO $this->rterms_table (post_id, term_id, hit_count, hit_date) VALUES ($post_id, $term_id, 1, NOW()) ON DUPLICATE KEY UPDATE hit_count = hit_count + 1;"; $wpdb->query($request); } // add it to the post's terms // disabled now because of memory problems it causes //if(is_singular()) // wp_set_object_terms($post_id, implode($search, ' '), 'bsuite_search', TRUE); return(TRUE); } function get_search_engine() { // a lot of inspiration and code for this function was taken from // Search Hilite by Ryan Boren and Matt Mullenweg global $wp_query; if( empty($_SERVER['HTTP_REFERER']) && empty($wp_query->query_vars['s'])) return false; if ( is_search() ) return('internal'); $referer = urldecode($_SERVER['HTTP_REFERER']); if (preg_match('|^http://(www)?\.?google.*|i', $referer)) return('google'); if (preg_match('|^http://search\.yahoo.*|i', $referer)) return('yahoo'); if (preg_match('|^http://search\.lycos.*|i', $referer)) return('lycos'); $siteurl = get_option('home'); if (preg_match("#^$siteurl#i", $referer)) return('internal'); return(FALSE); } function get_search_terms($engine = 'google') { // a lot of inspiration and code for this function was taken from // Search Hilite by Ryan Boren and Matt Mullenweg if(empty($engine)) return(FALSE); $referer = urldecode($_SERVER['HTTP_REFERER']); $query_array = array(); switch ($engine) { case 'google': // Google query parsing code adapted from Dean Allen's // Google Hilite 0.3. http://textism.com $query_terms = preg_replace('/^.*q=([^&]+)&?.*$/i','$1', $referer); $query_terms = preg_replace('/\'|"/', '', $query_terms); $query_array = preg_split ("/[\s,\+\.]+/", $query_terms); break; case 'lycos': $query_terms = preg_replace('/^.*query=([^&]+)&?.*$/i','$1', $referer); $query_terms = preg_replace('/\'|"/', '', $query_terms); $query_array = preg_split ("/[\s,\+\.]+/", $query_terms); break; case 'yahoo': $query_terms = preg_replace('/^.*p=([^&]+)&?.*$/i','$1', $referer); $query_terms = preg_replace('/\'|"/', '', $query_terms); $query_array = preg_split ("/[\s,\+\.]+/", $query_terms); break; case 'internal': $search = get_query_var('s'); $search_terms = get_query_var('search_terms'); if (!empty($search_terms)) { $query_array = $search_terms; } else if (!empty($search)) { $query_array = array($search); } else { $query_terms = preg_replace('/^.*s=([^&]+)&?.*$/i','$1', $referer); if(preg_match('|^http://|i', $query_terms)) return(FALSE); $query_terms = preg_replace('/\'|"/', '', $query_terms); $query_array = preg_split ("/[\s,\+\.]+/", $query_terms); } } return $query_array; } function post_hits( $args = '' ) { global $wpdb; $defaults = array( 'return' => 'formatted', 'days' => 0, 'template' => '
  • %%title%% (%%hits%%)
  • ' ); $args = wp_parse_args( $args, $defaults ); $post_id = (int) $args['post_id'] > 1 ? 'AND post_id = '. (int) $args['post_id'] : ''; $date = ''; if($args['days'] > 1) $date = "AND hit_date > '". date("Y-m-d", mktime(0, 0, 0, date("m") , date("d") - $args['days'], date("Y"))) ."'"; // here's the query, but let's try to get the data from cache first $request = "SELECT FORMAT(SUM(hit_count), 0) AS hits, FORMAT(AVG(hit_count), 0) AS average FROM $this->hits_table WHERE 1=1 $post_id $date "; if ( !$result = wp_cache_get( (int) $args['post_id'] .'_'. (int) $args['days'], 'bstat_post_hits' ) ) { $result = $wpdb->get_results($request, ARRAY_A); wp_cache_add( (int) $args['post_id'] .'_'. (int) $args['days'], $result, 'bstat_post_hits', 3600 ); } if(empty($result)) return(NULL); if($args['return'] == 'array') return($result); if($args['return'] == 'formatted'){ $list = str_replace(array('%%avg%%','%%hits%%'), array($result[0]['average'], $result[0]['hits']), $args['template']); return($list); } } function pop_posts( $args = '' ) { global $wpdb, $bsuite; if( $bsuite->get_loadavg() > 10 ) return( FALSE ); $defaults = array( 'count' => 15, 'return' => 'formatted', 'template' => '
  • %%title%% (%%hits%%)
  • ' ); $args = wp_parse_args( $args, $defaults ); $date = 'AND hit_date = DATE(NOW())'; if($args['days'] > 1) $date = "AND hit_date > '". date("Y-m-d", mktime(0, 0, 0, date("m") , date("d") - $args['days'], date("Y"))) ."'"; $limit = 'LIMIT '. (0 + $args['count']); $request = "SELECT post_id, SUM(hit_count) AS hit_count FROM $this->hits_table WHERE 1=1 AND post_id <> 0 $date GROUP BY post_id ORDER BY hit_count DESC $limit"; $result = $wpdb->get_results($request, ARRAY_A); if(empty($result)) return(NULL); if($args['return'] == 'array') return($result); if($args['return'] == 'formatted'){ $list = ''; foreach($result as $post){ $list .= str_replace(array('%%title%%','%%hits%%','%%link%%'), array(get_the_title($post['post_id']), $post['hit_count'], get_permalink($post['post_id'])), $args['template']); } return($list); } } function pop_refs( $args = '' ) { global $wpdb, $bsuite; if( $bsuite->get_loadavg() > 10 ) return( FALSE ); $defaults = array( 'count' => 15, 'return' => 'formatted', 'template' => '
  • %%title%% (%%hits%%)
  • ' ); $args = wp_parse_args( $args, $defaults ); $date = 'AND hit_date = DATE(NOW())'; if($args['days'] > 1) $date = "AND hit_date > '". date("Y-m-d", mktime(0, 0, 0, date("m") , date("d") - $args['days'], date("Y"))) ."'"; $limit = 'LIMIT '. (0 + $args['count']); $request = "SELECT term_id, SUM(hit_count) AS hit_count FROM $this->rterms_table WHERE 1=1 $date GROUP BY term_id ORDER BY hit_count DESC $limit"; $result = $wpdb->get_results($request, ARRAY_A); if(empty($result)) return(NULL); if($args['return'] == 'array') return($result); if($args['return'] == 'formatted'){ $list = ''; foreach($result as $row){ $term = get_term($row['term_id'], 'bsuite_search'); $list .= str_replace(array('%%title%%','%%hits%%'), array($term->name, $row['hit_count']), $args['template']); } return($list); } } // widgets function widget_popular_posts($args) { global $post, $wpdb; extract($args, EXTR_SKIP); $options = get_option('bstat_pop_posts'); $title = empty($options['title']) ? __('Popular Posts') : $options['title']; if ( !$number = (int) $options['number'] ) $number = 5; else if ( $number < 1 ) $number = 1; else if ( $number > 15 ) $number = 15; if ( !$days = (int) $options['days'] ) $days = 7; else if ( $days < 1 ) $days = 1; else if ( $days > 30 ) $days = 30; if ( !$pop_posts = wp_cache_get( 'bstat_pop_posts', 'widget' ) ) { $pop_posts = $this->pop_posts("limit=$number&days=$days"); wp_cache_add( 'bstat_pop_posts', $pop_posts, 'widget', 3600 ); } if ( !empty($pop_posts) ) { ?> widget_popular_posts_delete_cache(); } $title = attribute_escape($options['title']); if ( !$number = (int) $options['number'] ) $number = 5; if ( !$days = (int) $options['days'] ) $days = 7; ?>

    15 ) $number = 15; if ( !$days = (int) $options['days'] ) $days = 7; else if ( $days < 1 ) $days = 1; else if ( $days > 30 ) $days = 30; if ( !$pop_refs = wp_cache_get( 'bstat_pop_refs', 'widget' ) ) { $pop_refs = $this->pop_refs("limit=$number&days=$days"); wp_cache_add( 'bstat_pop_refs', $pop_refs, 'widget', 3600 ); } if ( !empty($pop_refs) ) { ?> widget_popular_refs_delete_cache(); } $title = attribute_escape($options['title']); if ( !$number = (int) $options['number'] ) $number = 5; if ( !$days = (int) $options['days'] ) $days = 7; ?>

    =') ) { if ( ! empty($wpdb->charset) ) $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; if ( ! empty($wpdb->collate) ) $charset_collate .= " COLLATE $wpdb->collate"; } require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); dbDelta(" CREATE TABLE $this->hits_table ( post_id bigint(20) unsigned NOT NULL default '0', hit_count smallint(6) unsigned NOT NULL default '0', hit_date date NOT NULL default '0000-00-00', PRIMARY KEY (post_id,hit_date), KEY post_id_and_hit_date (post_id,hit_date) ) $charset_collate "); dbDelta(" CREATE TABLE $this->rterms_table ( post_id bigint(20) unsigned NOT NULL default '0', term_id bigint(20) unsigned NOT NULL default '0', hit_count smallint(6) unsigned NOT NULL default '0', hit_date date NOT NULL default '0000-00-00', PRIMARY KEY (hit_date,term_id,post_id), KEY post_id_and_hit_date (post_id,hit_date) ) $charset_collate "); } } // now instantiate this object $bstat = & new bStat; // deprecated functions function bstat_todaypop($limit, $before, $after, $return = 0) { global $bstat; if(!empty($return)) return($bstat->pop_posts(array('limit' => $limit, 'days' => 0, 'template' => $before .'%%title%% (%%hits%%)'. $after ))); echo $bstat->pop_posts(array('limit' => $limit, 'days' => 0, 'template' => $before .'%%title%% (%%hits%%)'. $after )); } function bstat_recentpop($limit, $days, $before, $after, $return = 0) { global $bstat; if(!empty($return)) return($bstat->pop_posts(array('limit' => $limit, 'days' => $days, 'template' => $before .'%%title%% (%%hits%%)'. $after ))); echo $bstat->pop_posts(array('limit' => $limit, 'days' => $days, 'template' => $before .'%%title%% (%%hits%%)'. $after )); } function bstat_todayrefs($maxresults, $before, $after, $return = 0) { global $bstat; if(!empty($return)) return($bstat->pop_refs(array('limit' => $limit, 'days' => 0, 'template' => $before .'%%title%% (%%hits%%)'. $after ))); echo $bstat->pop_refs(array('limit' => $limit, 'days' => 0, 'template' => $before .'%%title%% (%%hits%%)'. $after )); } function bstat_recentrefs($maxresults, $days, $before, $after, $return = 0) { global $bstat; if(!empty($return)) return($bstat->pop_refs(array('limit' => $limit, 'days' => $days, 'template' => $before .'%%title%% (%%hits%%)'. $after ))); echo $bstat->pop_refs(array('limit' => $limit, 'days' => $days, 'template' => $before .'%%title%% (%%hits%%)'. $after )); } function bstat_hits($template = '%%hits%% hits, about %%avg%% daily', $post_id = NULL, $todayonly = 0, $return = NULL) { global $bstat; if(!empty($return)) return($bstat->post_hits(array('post_id' => $post_id,'days' => $todayonly, 'template' => $template ))); echo $bstat->post_hits(array('post_id' => $post_id,'days' => $todayonly, 'template' => $template )); } function bstat_pulse($post_id = 0, $maxwidth = 400, $disptext = 1, $dispcredit = 1, $accurate = 4) { // this one isn't so much deprecated as, well, // the code sucks and I haven't re-written it yet global $wpdb, $bstat; $post_id = (int) $post_id; $for_post_id = $post_id > 1 ? 'AND post_id = '. $post_id : ''; // here's the query, but let's try to get the data from cache first $request = "SELECT SUM(hit_count) AS hits, hit_date FROM $bstat->hits_table WHERE 1=1 $for_post_id GROUP BY hit_date "; if ( !$result = wp_cache_get( $post_id, 'bstat_post_pulse' ) ) { $result = $wpdb->get_results($request, ARRAY_A); wp_cache_add( $post_id, $result, 'bstat_post_pulse', 3600 ); } if(empty($result)) return(NULL); $tot = count($result); if(count($result)>0){ $point = null; $point[] = 0; foreach($result as $row){ $point[] = $row['hits']; } $sum = array_sum($point); $max = max($point); $avg = round($sum / $tot); if($accurate == 4){ $graphaccurate = get_option('bstat_graphaccurate'); }else{ $graphaccurate = $accurate; } $minwidth = ($maxwidth / 8.1); if($graphaccurate) $minwidth = ($maxwidth / 4.1); while(count($point) <= $minwidth){ $newpoint = null; for ($i = 0; $i < count($point); $i++) { if($i > 0){ if(!$graphaccurate) $newpoint[] = ((($point[$i-1] * 2) + $point[$i]) / 3); $newpoint[] = (($point[$i-1] + $point[$i]) / 2); if(!$graphaccurate) $newpoint[] = (($point[$i-1] + ($point[$i-1] * 2)) / 3); } $newpoint[] = $point[$i]; } $point = $newpoint; } $tot = count($point); $width = round($maxwidth / $tot); if($width > 3) $width = 4; if($width < 1) $width = 1; if(($width * $tot) > $maxwidth) $skipstart = (($width * $tot) - $maxwidth) / $width; $i = 1; $hit_chart = ""; foreach($point as $row){ if((!$skipstart) || ($i > $skipstart)){ $hit_chart .= "graph element."; } $i++; } $pre = "
    "; $post = "
    "; $disptext = ($disptext == 1) ? (number_format($sum) .' total reads, averaging '. number_format($avg) .' daily') : (""); $dispcredit = ($dispcredit == 1) ? ("stats powered by bSuite bStat") : (""); $disptext = (($disptext) || ($dispcredit)) ? ("\n

    $disptext\n
    $dispcredit

    ") : (""); echo($pre . $hit_chart . "\n" . $disptext . $post); } } function bstat_discussionbycomment($limit, $before, $after, $return = 0) { // this function (like the one below) is here only for people who refuse // to use widgets. If you do use widgets _and_ this function, you'll get // cache collisions, as these use the same cache name as the widgets. global $wpdb; $limit = (int) $limit; if ( !$comments = wp_cache_get( 'recent_comments', 'widget' ) ) { $comments = $wpdb->get_results("SELECT comment_author, comment_author_url, comment_ID, comment_post_ID FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT $limit"); wp_cache_add( 'recent_comments', $comments, 'widget' ); } $comments = ''; if( $commented_posts ) { foreach( $commented_posts as $comment ) { $comments .= $before . sprintf(__('%1$s on %2$s'), get_comment_author_link(), '' . get_the_title($comment->comment_post_ID) . ''). $after; } } if(!empty($return)) return($comments); echo $comments; } function bstat_discussionbypost($limit, $before, $after, $return = 0) { // this one brought back from the dead specifically for cliffy. // please use the widgets instead. global $wpdb; $limit = (int) $limit; if ( !$commented_posts = wp_cache_get( 'recently_commented_posts', 'widget' ) ) { $commented_posts = $wpdb->get_results("SELECT comment_ID, comment_post_ID, COUNT(comment_post_ID) as comment_count, MAX(comment_date_gmt) AS sort_order FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID ORDER BY sort_order DESC LIMIT $limit"); wp_cache_add( 'recently_commented_posts', $commented_posts, 'widget' ); } $comments = ''; if( $commented_posts ) { foreach( $commented_posts as $comment ) { $comments .= $before .'' . get_the_title($comment->comment_post_ID) . ' ('. $comment->comment_count .')'. $after; } } if(!empty($return)) return($comments); echo $comments; } ?>