? boost-503628-1.patch
Index: boost.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/boost/boost.module,v
retrieving revision 1.3.2.2.2.5.2.66
diff -u -p -r1.3.2.2.2.5.2.66 boost.module
--- boost.module	30 Jun 2009 02:59:08 -0000	1.3.2.2.2.5.2.66
+++ boost.module	1 Jul 2009 05:47:24 -0000
@@ -114,63 +114,6 @@ function boost_init() {
 }
 
 /**
- * Implementation of hook_footer().
- *
- * Place boost stat counter image into pages footer.
- *
- * NOTE HTML code could be added to the $buffer directly, right before </body>,
- * inside _boost_ob_handler() function. Would prevent 2x counts on first view.
- */
-function boost_footer() {
-  Global $base_path, $user;
-  $filename = 'boost_stats.php';
-
-  if (   strpos($_SERVER['SCRIPT_FILENAME'], 'index.php') === FALSE
-      || variable_get('site_offline', 0)
-      || $_SERVER['REQUEST_METHOD'] != 'GET'
-      || $_SERVER['SERVER_SOFTWARE'] === 'PHP CLI'
-      || !BOOST_ENABLED
-      || isset($_GET['nocache'])
-      || !boost_is_cacheable($GLOBALS['_boost_path'])
-      || !empty($user->uid)
-      || !file_exists($filename)
-      ) {
-    return;
-  }
-
-  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '' && variable_get('statistics_count_content_views', 0)) {
-    $nid = arg(1);
-  }
-  if ((variable_get('statistics_enable_access_log', 0)) && (module_invoke('throttle', 'status') == 0)) {
-    $title = drupal_urlencode(strip_tags(drupal_get_title()));
-    $q = $_GET['q'];
-  }
-  $img_start = '<div style="display:inline;"><img src="' . $base_path . $filename;
-  $img_end = '" alt="" /></div>';
-  $ns_start = $img_start;
-  $ns_end = $img_end;
-  $ns = '';
-  $js_start = '<script type="text/javascript">';
-  $js_end = '</script>';
-  $js = '';
-
-  if (isset($nid) & !isset($title)) {
-    return $ns_start . '?nid=' . $nid . $ns_end;
-  }
-  elseif (isset($nid) & isset($title)) {
-    $ns = '<noscript>' . $ns_start . '?nid=' . $nid . '&amp;q=' . $q . '&amp;title=' . $title . $ns_end . '</noscript>';
-    $js = $js_start . 'boost_nid="nid=' . $nid . '"; boost_q="q=' . $q . '"; boost_title="title=' . $title . '"; boost_referrer="referer=" + document.referrer;';
-    $js .= " document.write('" . $img_start . "?' + boost_nid + '&amp;' + boost_q + '&amp;' + boost_title + '&amp;' + boost_referrer + '" . $img_end . "');" . $js_end;
-  }
-  elseif (!isset($nid) & isset($title)) {
-    $ns = '<noscript>' . $ns_start . '?q=' . $q . '&amp;title=' . $title . $ns_end . '</noscript>';
-    $js = $js_start . 'boost_q="q=' . $q . '"; boost_title="title=' . $title . '"; boost_referrer="referer=" + document.referrer;';
-    $js .= " document.write('" . $img_start . "?' + boost_q + '&amp;' + boost_title + '&amp;' + boost_referrer + '" . $img_end . "');" . $js_end;
-  }
-  return $js . $ns;
-}
-
-/**
  * Implementation of hook_exit(). Performs cleanup tasks.
  *
  * For POST requests by anonymous visitors, this adds a dummy query string
@@ -254,11 +197,20 @@ function boost_form_alter(&$form, $form_
  * Implementation of hook_cron(). Performs periodic actions.
  */
 function boost_cron() {
-  if (!BOOST_ENABLED) return;
+  if (!BOOST_ENABLED) {
+    return;
+  }
 
+  // Expire old content
   if (variable_get('boost_expire_cron', TRUE) && boost_cache_db_expire()) {
     watchdog('boost', 'Expired stale files from static page cache.', array(), WATCHDOG_NOTICE);
   }
+
+  // Update Stats
+  if (module_exists('statistics') && variable_get('boost_block_show_stats', FALSE)) {
+    $block = module_invoke('statistics', 'block', 'view', 0);
+    variable_set('boost_statistics_html', $block['content']);
+  }
 }
 
 /*
@@ -367,12 +319,31 @@ function boost_block($op = 'list', $delt
     case 'list':
       return array(
         'status' => array(
-          'info'   => t('Boost page cache status'),
+          'info'   => t('Boost: Pages cache status'),
+          'region' => 'right',
+          'weight' => 10,
+          'cache'  => BLOCK_NO_CACHE,
+        ),
+        'stats' => array(
+          'info'   => t('Boost: AJAX core statistics'),
           'region' => 'right',
           'weight' => 10,
           'cache'  => BLOCK_NO_CACHE,
         ),
       );
+    case 'configure':
+      if ($delta == 'stats') {
+        $form['items'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Display Statistics'),
+        '#default_value' => variable_get('boost_block_show_stats', FALSE),
+        );
+      return $form;
+      }
+    case 'save':
+      if ($delta == 'stats') {
+        variable_set('boost_block_show_stats', $edit['items']);
+      }
     case 'view':
       $block = array();
       switch ($delta) {
@@ -411,6 +382,37 @@ function boost_block($op = 'list', $delt
             $block['content'] = theme('boost_cache_status', isset($ttl) ? $ttl : -1, $output);
           }
           break;
+        case 'stats':
+          $filename = 'boost_stats.php';
+          $block = module_invoke('statistics', 'block', 'view', 0);
+          variable_set('boost_statistics_html', $block['content']);
+
+          if (!( strpos($_SERVER['SCRIPT_FILENAME'], 'index.php') === FALSE
+              || variable_get('site_offline', 0)
+              || $_SERVER['REQUEST_METHOD'] != 'GET'
+              || $_SERVER['SERVER_SOFTWARE'] === 'PHP CLI'
+              || !BOOST_ENABLED
+              || isset($_GET['nocache'])
+              || !boost_is_cacheable($GLOBALS['_boost_path'])
+              || !empty($user->uid)
+              || !file_exists($filename)
+              || !module_exists('statistics')
+              )) {
+            if (variable_get('boost_block_show_stats', FALSE)) {
+              $block = array();
+              $block['subject'] = 'Popular content';
+              $block['content'] = '<div id="boost-stats"></div>' . boost_stats_generate($filename);
+            }
+            else {
+              $block = array();
+              $block['content'] = '<div id="boost-stats" style="display:none;"></div>' . boost_stats_generate($filename);
+            }
+          }
+          elseif (!variable_get('boost_block_show_stats', FALSE)) {
+            $block = array();
+          }
+
+
       }
       return $block;
   }
@@ -429,12 +431,60 @@ function boost_block_form() {
   return ($form);
 }
 
-
 function boost_block_form_submit(&$form_state, $form) {
   boost_cache_expire_derivative($form['values']['path'], TRUE);
 }
 
 /**
+ * Generate js/html for boost stat counter.
+ *
+ * NOTE HTML code could be added to the $buffer directly. Would prevent 2x
+ * counts on first view. Would be hard to do though.
+ *
+ * @param $filename
+ *   Name of boost's statistics php file.
+ */
+function boost_stats_generate($filename) {
+  Global $base_path;
+
+  // is node & node count enabled.
+  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '' && variable_get('statistics_count_content_views', 0)) {
+    $nid = 'nid=' . arg(1);;
+  }
+  else {
+    $nid = 'nid=NULL';
+  }
+
+  // access log enabled.
+  if ((variable_get('statistics_enable_access_log', 0)) && (module_invoke('throttle', 'status') == 0)) {
+    $title = 'title=' . drupal_urlencode(strip_tags(drupal_get_title()));
+    $q = 'q=' . $_GET['q'];
+  }
+  else {
+    $title = 'title=NULL';
+    $q = 'q=NULL';
+  }
+
+  $page_js = array(
+    'boost' => array(
+      'nid' => $nid,
+      'q' => $q,
+      'title' => $title,
+    ),
+  );
+  $site_js = '$("#boost-stats").load(Drupal.settings.basePath + "boost_stats.php?js=2" + "&" + Drupal.settings.boost.nid + "&" + Drupal.settings.boost.q + "&" + Drupal.settings.boost.title + "&referer=" + document.referrer);';
+
+  // page specific variables
+  drupal_add_js($page_js, 'setting', 'header');
+  // site-wide code
+  drupal_add_js($site_js, 'inline', 'footer');
+  // no script code
+  $page_ns = '<noscript><div style="display:inline;"><img src="' . $base_path . $filename . '?js=0' . '&amp;'. $nid . '&amp;'. $title . '&amp;'. $q . '" alt="" /></div></noscript>';
+
+  return $page_ns;
+}
+
+/**
  * Implementation of hook_theme().
  */
 function boost_theme() {
@@ -1097,7 +1147,7 @@ function boost_cache_css_js_files($buffe
     $temp = explode(' />', array_pop($css));
     $css[] = array_shift($temp);
     $css = implode('',$css);
-    _boost_copy_css_files($css);  
+    _boost_copy_css_files($css);
   }
   if (BOOST_CACHE_JS) {
     $js = explode('<script type="text/javascript" ', $buffer);
Index: stats/boost_stats.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/boost/stats/Attic/boost_stats.php,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 boost_stats.php
--- stats/boost_stats.php	23 Jun 2009 00:23:55 -0000	1.1.2.3
+++ stats/boost_stats.php	1 Jul 2009 05:47:24 -0000
@@ -1,26 +1,10 @@
 <?php
 // $Id: boost_stats.php,v 1.1.2.3 2009/06/23 00:23:55 mikeytown2 Exp $
 
-// Script should take under 1mb of memory to work.
-// Prime php for background operations
-ob_end_clean();
-header("Connection: close");
-ignore_user_abort();
-
-// Output of 1 pixel transparent gif
-ob_start();
-header("Content-type: image/gif");
-header("Expires: Wed, 11 Nov 1998 11:11:11 GMT");
-header("Cache-Control: no-cache");
-header("Cache-Control: must-revalidate");
-header("Content-Length: 43");
-header("Connection: close");
-printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",71,73,70,56,57,97,1,0,1,0,128,255,0,192,192,192,0,0,0,33,249,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,0,2,2,68,1,0,59);
-ob_end_flush();
-flush();
-
-// Image returned and connection closed.
-// Do background processing. Time taken below should not effect page load times.
+if (isset($_GET['js']) && $_GET['js']==0) {
+  // stats not called via JS, send image out & close connection.
+  boost_stats_async_image();
+}
 
 // Exit script if nothing was passed to it.
 if (   !isset($_GET['nid'])
@@ -31,38 +15,63 @@ if (   !isset($_GET['nid'])
   exit;
 }
 
-// Set variables passed via GET.
-$nid = isset($_GET['nid']) ? $_GET['nid'] : NULL;
-$title = isset($_GET['title']) ? urldecode($_GET['title']) : NULL;
-$q = isset($_GET['q']) ? $_GET['q'] : NULL;
-$referer = isset($_GET['referer']) ? $_GET['referer'] : NULL;
-
-// Connect to DB.
-include_once './includes/bootstrap.inc';
-drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
-
-// Get stat settings.
-$count_views = db_fetch_array(db_query_range("SELECT value FROM {variable} WHERE name = '%s'", 'statistics_count_content_views', 0, 1));
-$count_views = unserialize($count_views['value']);
-$access_log = db_fetch_array(db_query_range("SELECT value FROM {variable} WHERE name = '%s'", 'statistics_enable_access_log', 0, 1));
-$access_log = unserialize($access_log['value']);
+// connect to db & set variables.
+boost_stats_init();
 
 // Set node counter.
-if ($count_views) {
-  // We are counting content views.
-  if (isset($nid) && is_numeric($nid)) {
-    // A node has been viewed, so update the node's counters.
-    db_query('UPDATE {node_counter} SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d', time(), $nid);
-    // If we affected 0 rows, this is the first time viewing the node.
-    if (!db_affected_rows()) {
-      // We must create a new row to store counters for the new node.
-      db_query('INSERT INTO {node_counter} (nid, daycount, totalcount, timestamp) VALUES (%d, 1, 1, %d)', $nid, time());
-    }
-  }
+if ($count_views && isset($nid) && is_numeric($nid)) {
+  boost_stats_update_node_counter();
 }
 
 // Set access log.
 if ($access_log && isset($title) && isset($q)) {
+  boost_stats_add_access_log();
+}
+
+// Send stats block html.
+if ($stats) {
+  boost_stats_output_stats_block();
+}
+
+// end of script, exit.
+exit;
+
+Function boost_stats_async_image() {
+  // Script should take under 1mb of memory to work.
+  // Prime php for background operations
+  ob_end_clean();
+  header("Connection: close");
+  ignore_user_abort();
+
+  // Output of 1 pixel transparent gif
+  ob_start();
+  header("Content-type: image/gif");
+  header("Expires: Wed, 11 Nov 1998 11:11:11 GMT");
+  header("Cache-Control: no-cache");
+  header("Cache-Control: must-revalidate");
+  header("Content-Length: 43");
+  header("Connection: close");
+  printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",71,73,70,56,57,97,1,0,1,0,128,255,0,192,192,192,0,0,0,33,249,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,0,2,2,68,1,0,59);
+  ob_end_flush();
+  flush();
+
+  // Image returned and connection closed.
+  // Do background processing. Time taken below should not effect page load times.
+}
+
+Function boost_stats_init() {
+  Global $nid, $title, $q, $referer, $session_id, $uid, $stats, $count_views, $access_log, $stats_block;
+
+  // Connect to DB.
+  include_once './includes/bootstrap.inc';
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
+
+  // Set variables passed via GET.
+  $nid = isset($_GET['nid']) ? $_GET['nid'] : NULL;
+  $title = isset($_GET['title']) ? urldecode($_GET['title']) : NULL;
+  $q = isset($_GET['q']) ? $_GET['q'] : NULL;
+  $referer = isset($_GET['referer']) ? $_GET['referer'] : NULL;
+  $stats = (isset($_GET['js']) && $_GET['js'] == 2) ? TRUE : NULL;
   $session_id = session_id();
   if (empty($session_id)) {
     $session_id = $_COOKIE[session_name()];
@@ -72,6 +81,45 @@ if ($access_log && isset($title) && isse
     }
   }
   $uid = 0;
+
+  // Node Counter
+  if (isset($nid)) {
+    $count_views = db_fetch_array(db_query_range("SELECT value FROM {variable} WHERE name = '%s'", 'statistics_count_content_views', 0, 1));
+    $count_views = unserialize($count_views['value']);
+  }
+
+  // Access Log
+  if (isset($title) && isset($q)) {
+    $access_log = db_fetch_array(db_query_range("SELECT value FROM {variable} WHERE name = '%s'", 'statistics_enable_access_log', 0, 1));
+    $access_log = unserialize($access_log['value']);
+  }
+
+  // stats block
+  if (isset($stats)) {
+    $stats_block = db_fetch_array(db_query_range("SELECT value FROM {variable} WHERE name = '%s'", 'boost_statistics_html', 0, 1));
+    $stats_block = unserialize($stats_block['value']);
+  }
+}
+
+Function boost_stats_update_node_counter() {
+  Global $nid;
+
+  // A node has been viewed, so update the node's counters.
+  db_query('UPDATE {node_counter} SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d', time(), $nid);
+  // If we affected 0 rows, this is the first time viewing the node.
+  if (!db_affected_rows()) {
+    // We must create a new row to store counters for the new node.
+    db_query('INSERT INTO {node_counter} (nid, daycount, totalcount, timestamp) VALUES (%d, 1, 1, %d)', $nid, time());
+  }
+}
+
+Function boost_stats_add_access_log() {
+  Global $title, $q, $referer, $session_id, $uid;
+
   db_query("INSERT INTO {accesslog} (title, path, url, hostname, uid, sid, timer, timestamp) values('%s', '%s', '%s', '%s', %d, '%s', %d, %d)", $title, $q, $referer, ip_address(), $uid, $session_id, timer_read('page'), time());
 }
-exit;
\ No newline at end of file
+
+Function boost_stats_output_stats_block() {
+  Global $stats_block;
+  echo $stats_block;
+}
