From 52d7970bad92e6fc35b217345cf9fd1f242e932b Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Thu, 26 Apr 2012 13:05:27 +0900 Subject: [PATCH] Issue #1209532 by timmillwood: Count node views via AJAX in the statistics module. --- core/modules/search/search.test | 8 +++- core/modules/statistics/statistics.js | 12 ++++++ core/modules/statistics/statistics.module | 30 ++++++-------- core/modules/statistics/statistics.php | 33 +++++++++++++++ core/modules/statistics/statistics.test | 49 +++++++++++++++++++++++ 5 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 core/modules/statistics/statistics.js create mode 100644 core/modules/statistics/statistics.php diff --git a/core/modules/search/search.test b/core/modules/search/search.test index b6f5ae8e0447..b01fcf7c46fb 100644 --- a/core/modules/search/search.test +++ b/core/modules/search/search.test @@ -450,8 +450,14 @@ class SearchRankingTestCase extends SearchWebTestCase { variable_set('statistics_count_content_views', 1); // Then View one of the nodes a bunch of times. + // Manually calling statistics.php, simulating ajax behavior. + $nid = $nodes['views'][1]->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; for ($i = 0; $i < 5; $i ++) { - $this->drupalGet('node/' . $nodes['views'][1]->nid); + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); } // Test each of the possible rankings. diff --git a/core/modules/statistics/statistics.js b/core/modules/statistics/statistics.js new file mode 100644 index 000000000000..65793d36e646 --- /dev/null +++ b/core/modules/statistics/statistics.js @@ -0,0 +1,12 @@ +(function ($) { + $(document).ready(function() { + var nid = Drupal.settings.statistics.nid; + var basePath = Drupal.settings.basePath + $.ajax({ + type: "POST", + cache: false, + url: basePath+"core/modules/statistics/statistics.php", + data: "nid="+nid + }); + }); +})(jQuery); diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module index d9e9b49a9779..38cd0203ba3c 100644 --- a/core/modules/statistics/statistics.module +++ b/core/modules/statistics/statistics.module @@ -41,7 +41,6 @@ function statistics_help($path, $arg) { } } - /** * Implements hook_exit(). * @@ -57,22 +56,6 @@ function statistics_exit() { // in which case we need to bootstrap to the session phase anyway. drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); - if (variable_get('statistics_count_content_views', 0)) { - // We are counting content views. - if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == NULL) { - // A node has been viewed, so update the node's counters. - db_merge('node_counter') - ->key(array('nid' => arg(1))) - ->fields(array( - 'daycount' => 1, - 'totalcount' => 1, - 'timestamp' => REQUEST_TIME, - )) - ->expression('daycount', 'daycount + 1') - ->expression('totalcount', 'totalcount + 1') - ->execute(); - } - } if (variable_get('statistics_enable_access_log', 0)) { drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION); @@ -115,6 +98,19 @@ function statistics_permission() { * Implements hook_node_view(). */ function statistics_node_view($node, $view_mode) { + if (!empty($node->nid) && $view_mode == 'full') { + $node->content['#attached']['js'] = array( + drupal_get_path('module', 'statistics') . '/statistics.js' => array( + 'scope' => 'footer' + ), + ); + $settings = array('nid' => $node->nid); + $node->content['#attached']['js'][] = array( + 'data' => array('statistics' => $settings), + 'type' => 'setting', + ); + } + if ($view_mode != 'rss') { if (user_access('view post access counter')) { $statistics = statistics_get($node->nid); diff --git a/core/modules/statistics/statistics.php b/core/modules/statistics/statistics.php new file mode 100644 index 000000000000..040dc19f8f0b --- /dev/null +++ b/core/modules/statistics/statistics.php @@ -0,0 +1,33 @@ +<?php + +/** + * @file + * Handles counts of node views via AJAX with minimal bootstrap. + */ + +// Change the directory to the Drupal root. +chdir('../../..'); + +/** +* Root directory of Drupal installation. +*/ +define('DRUPAL_ROOT', getcwd()); + +include_once DRUPAL_ROOT . '/core/includes/bootstrap.inc'; +drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); +if (variable_get('statistics_count_content_views', 0)) { + $nid = $_POST['nid']; + if (is_numeric($nid)) { + db_merge('node_counter') + ->key(array('nid' => $nid)) + ->fields(array( + 'daycount' => 1, + 'totalcount' => 1, + 'timestamp' => REQUEST_TIME, + )) + ->expression('daycount', 'daycount + 1') + ->expression('totalcount', 'totalcount + 1') + ->execute(); + } +} + diff --git a/core/modules/statistics/statistics.test b/core/modules/statistics/statistics.test index d19fd92444a9..6f19e37f8bfe 100644 --- a/core/modules/statistics/statistics.test +++ b/core/modules/statistics/statistics.test @@ -104,6 +104,13 @@ class StatisticsLoggingTestCase extends DrupalWebTestCase { // Verify logging of an uncached page. $this->drupalGet($path); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $this->node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->assertIdentical($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Testing an uncached page.')); $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC); $this->assertTrue(is_array($log) && count($log) == 1, t('Page request was logged.')); @@ -113,6 +120,8 @@ class StatisticsLoggingTestCase extends DrupalWebTestCase { // Verify logging of a cached page. $this->drupalGet($path); + // Manually calling statistics.php, simulating ajax behavior. + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->assertIdentical($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Testing a cached page.')); $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC); $this->assertTrue(is_array($log) && count($log) == 2, t('Page request was logged.')); @@ -123,6 +132,8 @@ class StatisticsLoggingTestCase extends DrupalWebTestCase { // Test logging from authenticated users $this->drupalLogin($this->auth_user); $this->drupalGet($path); + // Manually calling statistics.php, simulating ajax behavior. + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC); // Check the 6th item since login and account pages are also logged $this->assertTrue(is_array($log) && count($log) == 6, t('Page request was logged.')); @@ -219,6 +230,13 @@ class StatisticsReportsTestCase extends StatisticsTestCase { // Visit a node to have something show up in the block. $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->blocking_user->uid)); $this->drupalGet('node/' . $node->nid); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); // Configure and save the block. $block = block_load('statistics', 'popular'); @@ -353,6 +371,13 @@ class StatisticsAdminTestCase extends DrupalWebTestCase { // Hit the node. $this->drupalGet('node/' . $this->test_node->nid); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $this->test_node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->drupalGet('admin/reports/pages'); $this->assertText('node/1', t('Test node found.')); @@ -360,9 +385,11 @@ class StatisticsAdminTestCase extends DrupalWebTestCase { // Hit the node again (the counter is incremented after the hit, so // "1 view" will actually be shown when the node is hit the second time). $this->drupalGet('node/' . $this->test_node->nid); + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->assertText('1 view', t('Node is viewed once.')); $this->drupalGet('node/' . $this->test_node->nid); + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->assertText('2 views', t('Node is viewed 2 times.')); } @@ -373,6 +400,13 @@ class StatisticsAdminTestCase extends DrupalWebTestCase { variable_set('statistics_count_content_views', 1); $this->drupalGet('node/' . $this->test_node->nid); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $this->test_node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $result = db_select('node_counter', 'n') ->fields('n', array('nid')) @@ -432,7 +466,15 @@ class StatisticsAdminTestCase extends DrupalWebTestCase { variable_set('statistics_flush_accesslog_timer', 1); $this->drupalGet('node/' . $this->test_node->nid); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $this->test_node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->drupalGet('node/' . $this->test_node->nid); + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $this->assertText('1 view', t('Node is viewed once.')); $this->drupalGet('admin/reports/pages'); @@ -481,6 +523,13 @@ class StatisticsTokenReplaceTestCase extends StatisticsTestCase { // Hit the node. $this->drupalGet('node/' . $node->nid); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $node->nid; + $post = http_build_query(array('nid' => $nid)); + $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics'). '/statistics.php'; + drupal_http_request($stats_path, array('method' => 'POST', 'data' => $post, 'headers' => $headers, 'timeout' => 10000)); $statistics = statistics_get($node->nid); // Generate and test tokens. -- GitLab