Difference between revisions of "Extension:CurrentPages"

From Organic Design wiki
(1.0.1 - forgot to clear out old data on change of hour)
(1.0.2alpha - change storage from file to DB - not tested or debugged yet)
Line 7: Line 7:
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
   
 
   
define('CURRENTPAGES_VERSION','1.0.1, 2008-05-25');
+
define('CURRENTPAGES_VERSION','1.0.2alpha, 2008-05-25');
  
 
$egCurrentPagesMagic          = 'currentpages';
 
$egCurrentPagesMagic          = 'currentpages';
$egCurrentPagesThreshold      = 10;              # Minimum number of views a title must have to be shown in the list
 
  
$egCurrentPagesFile            = dirname(__FILE__).'/CurrentPages.data'; # file used to store $egCurrentPagesData array
 
 
 
$wgExtensionFunctions[]        = 'efSetupCurrentPages';
 
$wgExtensionFunctions[]        = 'efSetupCurrentPages';
 
$wgHooks['LanguageGetMagic'][] = 'efCurrentPagesLanguageGetMagic';
 
$wgHooks['LanguageGetMagic'][] = 'efCurrentPagesLanguageGetMagic';
Line 29: Line 26:
 
  */
 
  */
 
function efSetupCurrentPages() {
 
function efSetupCurrentPages() {
global $wgUser, $wgParser, $egCurrentPagesMagic, $egCurrentPagesData, $egCurrentPagesFile;
+
global $wgTitle, $wgUser, $wgParser, $egCurrentPagesMagic, $egCurrentPagesData, $egCurrentPagesFile;
 
$wgParser->setFunctionHook($egCurrentPagesMagic, 'efCurrentPagesMagic');
 
$wgParser->setFunctionHook($egCurrentPagesMagic, 'efCurrentPagesMagic');
  
 
if (isset($_REQUEST['action'])) return; # Don't count pages which are not a simple page view request
 
if (isset($_REQUEST['action'])) return; # Don't count pages which are not a simple page view request
  
$title = Title::newFromText($_REQUEST['title']);
+
# Get article ID corresponding to title request
if (!is_object($title) || !$title->exists()) return; # Don't include non-existent titles
+
$title = is_object($wgTitle) ? $wgTitle : Title::newFromText($_REQUEST['title']);
 +
$id = is_object($title) ? $title->getArticleID() : 0;
 +
if ($id < 1) return;
 
 
# Only include item if it can resolve to a text name
+
# Create the DB table if it doesn't exist
$title = $title->getPrefixedText();
+
$db = &wfGetDB(DB_MASTER);
if ($title) {
+
$table = $db->tableName('currentpages_hourlyviews');
 +
if (!$db->tableExists($table)) {
 +
$query = "CREATE TABLE $table (hour INTEGER, page INTEGER, views INTEGER);";
 +
$result = $db->query($query);
 +
$db->freeResult($result);
 +
}
  
# Read the $egCurrentPagesData array from file
+
# If the hour has changed, clear any existing data out
$data = file_get_contents($egCurrentPagesFile);
+
# - current hour is stored in a special row where hour is -1
$egCurrentPagesData = $data ? unserialize($data) : array();
+
$hour = strftime('%H');
 +
$cond = "hour < 0";
 +
$res = $db->selectRow($table, 'views', $cond);
 +
if ($row = $db->fetchRow($res)) {
 +
$db->freeResult($res);
 +
if ($row[0] != $hour) {
 +
# Current hour has changed, update DB entry and clear out current items in this hour
 +
$db->update($table, array('hour' => -1, 'views' => $hour), $cond);
 +
$db->delete($table, "hour = $hour");
 +
}
 +
} else {
 +
# No entry for current hour yet, add it now
 +
$db->freeResult($res);
 +
$db->insert($table, array('hour' => -1, 'views' => $hour));
 +
}
  
# If the hour has changed, clear any existing data out
+
# Increment a title
$hour = strftime('%H');
+
$cond = "hour = $hour AND page = $page";
if (!isset($egCurrentPagesData[$hour]) || (isset($egCurrentPagesData['H']) && $egCurrentPagesData['H'] != $hour))
+
$db->selectRow($table, 'views', $cond);
$egCurrentPagesData[$hour] = array();
+
if ($row = $db->fetchRow($res)) {
$egCurrentPagesData['H'] = $hour;
+
$db->freeResult($res);
 +
$db->update($table, array('hour' => $hour, 'page' => $page, 'views' => $row[0]+1), $cond);
 +
}
 +
else {
 +
# No entry for current hour yet, add it now
 +
$db->freeResult($res);
 +
$db->insert($table, array('hour' => $hour, 'page' => $page, 'views' => 1));
 +
}
  
# Increment the entry for current hour and title
+
}
$egCurrentPagesData[$hour][$title] = isset($egCurrentPagesData[$hour][$title]) ? $egCurrentPagesData[$hour][$title]+1 : 1;
 
  
# Write the $egCurrentPagesData array back to file
 
file_put_contents($egCurrentPagesFile, serialize($egCurrentPagesData));
 
}
 
}
 
 
 
/**
 
/**
 
  * Needed in MediaWiki >1.8.0 for magic word hooks to work properly
 
  * Needed in MediaWiki >1.8.0 for magic word hooks to work properly
Line 69: Line 88:
  
 
function efCurrentPagesMagic(&$parser, $n = 0, $start = "*", $end = "\n") {
 
function efCurrentPagesMagic(&$parser, $n = 0, $start = "*", $end = "\n") {
global $egCurrentPagesTitles, $egCurrentPagesThreshold;
+
global $egCurrentPagesTitles;
 
$parser->disableCache();
 
$parser->disableCache();
 
 
# Build sorted totals by title
+
# Query DB to get total views for each title over all hours
if (!is_array($egCurrentPagesTitles)) {
+
$dbr = &wfGetDB(DB_SLAVE);
global $egCurrentPagesFile, $egCurrentPagesData;
+
$table = $db->tableName('currentpages_hourlyviews');
+
$res = $db->select(
# Read the $egCurrentPagesData array from file if non existent
+
$table,
if (!is_array($egCurrentPagesData)) {
+
'page, SUM(views) AS totals',
$data = file_get_contents($egCurrentPagesFile);
+
'hour >= 0',
$egCurrentPagesData = $data ? unserialize($data) : array();
+
'',
}
+
array('GROUP BY' => 'page', 'ORDER BY' => 'totals DESC', 'LIMIT' => $n)
+
);
# Convert the data into a list of title => viewcount
 
$egCurrentPagesTitles = array();
 
foreach ($egCurrentPagesData as $hour => $titles) {
 
if (is_numeric($hour)) {
 
foreach ($titles as $title => $views) {
 
$egCurrentPagesTitles[$title] = isset($egCurrentPagesTitles[$title]) ? $egCurrentPagesTitles[$title]+$views : $views;
 
}
 
}
 
}
 
  
# Sort the titles by view-count
 
arsort($egCurrentPagesTitles, SORT_NUMERIC);
 
}
 
 
 
# Render the title list
 
# Render the title list
 
$list = '';
 
$list = '';
if ($n < 1) $n = 10;
+
while ($row = $db->fetchRow($res)) {
foreach ($egCurrentPagesTitles as $title => $views) {
+
$title = Title::newFromID($row[0]);
if (--$n == 0 || $views < $egCurrentPagesThreshold) break;
+
$page  = $title->getPrefixedText();
$title = preg_replace("/^(Category|Image):/",":$1:",$title);
+
$link  = $title->getText();
$list .= "{$start}[[{$title}]] <span class=\"currentpages_views\">({$views})</span>{$end}";
+
$list .= "{$start}[[:{$page}|{$link}]] <span class=\"currentpages_views\">({$row[1]})</span>{$end}";
}
+
}
 +
$db->freeResult($res);
 +
 
return $list;
 
return $list;
 
}
 
}

Revision as of 06:00, 25 May 2008

<?php

  1. Extension:CurrentPages
Info.svg These are the MediaWiki extensions we're using and/or developing. Please refer to the information on the mediawiki.org wiki for installation and usage details. Extensions here which have no corresponding mediawiki article are either not ready for use or have been superseded. You can also browse our extension code in our local Subversion repository or our GitHub mirror.

Template:Php

  1. - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
  2. - Author: User:Nad
  3. - Started: 2008-05-24

if (!defined('MEDIAWIKI')) die('Not an entry point.');

define('CURRENTPAGES_VERSION','1.0.2alpha, 2008-05-25');

$egCurrentPagesMagic = 'currentpages';

$wgExtensionFunctions[] = 'efSetupCurrentPages'; $wgHooks['LanguageGetMagic'][] = 'efCurrentPagesLanguageGetMagic';

$wgExtensionCredits['parserhook'][] = array( 'name' => 'CurrentPages', 'author' => 'User:Nad', 'description' => 'Adds a magic word for return a bullet list of most viewed pages within the last 24 hours.', 'url' => 'http://www.mediawiki.org/wiki/Extension:CurrentPages', 'version' => CURRENTPAGES_VERSION );

/**

* Called from $wgExtensionFunctions array when initialising extensions
*/

function efSetupCurrentPages() { global $wgTitle, $wgUser, $wgParser, $egCurrentPagesMagic, $egCurrentPagesData, $egCurrentPagesFile; $wgParser->setFunctionHook($egCurrentPagesMagic, 'efCurrentPagesMagic');

if (isset($_REQUEST['action'])) return; # Don't count pages which are not a simple page view request

# Get article ID corresponding to title request $title = is_object($wgTitle) ? $wgTitle : Title::newFromText($_REQUEST['title']); $id = is_object($title) ? $title->getArticleID() : 0; if ($id < 1) return;

# Create the DB table if it doesn't exist $db = &wfGetDB(DB_MASTER); $table = $db->tableName('currentpages_hourlyviews'); if (!$db->tableExists($table)) { $query = "CREATE TABLE $table (hour INTEGER, page INTEGER, views INTEGER);"; $result = $db->query($query); $db->freeResult($result); }

# If the hour has changed, clear any existing data out # - current hour is stored in a special row where hour is -1 $hour = strftime('%H'); $cond = "hour < 0"; $res = $db->selectRow($table, 'views', $cond); if ($row = $db->fetchRow($res)) { $db->freeResult($res); if ($row[0] != $hour) { # Current hour has changed, update DB entry and clear out current items in this hour $db->update($table, array('hour' => -1, 'views' => $hour), $cond); $db->delete($table, "hour = $hour"); } } else { # No entry for current hour yet, add it now $db->freeResult($res); $db->insert($table, array('hour' => -1, 'views' => $hour)); }

# Increment a title $cond = "hour = $hour AND page = $page"; $db->selectRow($table, 'views', $cond); if ($row = $db->fetchRow($res)) { $db->freeResult($res); $db->update($table, array('hour' => $hour, 'page' => $page, 'views' => $row[0]+1), $cond); } else { # No entry for current hour yet, add it now $db->freeResult($res); $db->insert($table, array('hour' => $hour, 'page' => $page, 'views' => 1)); }

}

/**

* Needed in MediaWiki >1.8.0 for magic word hooks to work properly
*/

function efCurrentPagesLanguageGetMagic(&$magicWords,$langCode = 0) { global $egCurrentPagesMagic; $magicWords[$egCurrentPagesMagic] = array($langCode,$egCurrentPagesMagic); return true; }

function efCurrentPagesMagic(&$parser, $n = 0, $start = "*", $end = "\n") { global $egCurrentPagesTitles; $parser->disableCache();

# Query DB to get total views for each title over all hours $dbr = &wfGetDB(DB_SLAVE); $table = $db->tableName('currentpages_hourlyviews'); $res = $db->select( $table, 'page, SUM(views) AS totals', 'hour >= 0', , array('GROUP BY' => 'page', 'ORDER BY' => 'totals DESC', 'LIMIT' => $n) );

# Render the title list $list = ; while ($row = $db->fetchRow($res)) { $title = Title::newFromID($row[0]); $page = $title->getPrefixedText(); $link = $title->getText(); $list .= "{$start}[[:{$page}|{$link}]] ({$row[1]}){$end}"; } $db->freeResult($res);

return $list; }