Index: trunk/extensions/SearchLog/SearchLog.alias.php |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Aliases for extension SearchLog |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +$specialPageAliases = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Brion Vibber |
| 14 | + */ |
| 15 | +$specialPageAliases['en'] = array( |
| 16 | + 'SearchLog' => array( 'SearchLog' ), |
| 17 | +); |
Property changes on: trunk/extensions/SearchLog/SearchLog.alias.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 18 | + native |
Index: trunk/extensions/SearchLog/SearchLog_body.php |
— | — | @@ -0,0 +1,127 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class for Special:SearchLog |
| 5 | + */ |
| 6 | +class SpecialSearchLog extends SpecialPage { |
| 7 | + const ENTIRE_LOG = 'searchlog-entire'; |
| 8 | + |
| 9 | + public function __construct() { |
| 10 | + parent::__construct( 'SearchLog', 'searchlog-read' ); |
| 11 | + } |
| 12 | + |
| 13 | + /** |
| 14 | + * Get the location of the current log file. Will always be in $wgSearchLogPath/logs/ |
| 15 | + * Default (if $wgSearchLogFile is not set) is to return your hostname (minus the www.) |
| 16 | + * @return String |
| 17 | + */ |
| 18 | + public static function getLogName() { |
| 19 | + global $wgSearchLogPath, $wgSearchLogFile, $wgServer; |
| 20 | + if( !$wgSearchLogFile ) { |
| 21 | + $file = str_replace( 'www.', '', parse_url( $wgServer, PHP_URL_HOST ) ); |
| 22 | + } else { |
| 23 | + $file = $wgSearchLogFile; |
| 24 | + } |
| 25 | + return $wgSearchLogPath . $file; |
| 26 | + } |
| 27 | + |
| 28 | + public function execute( $par ) { |
| 29 | + global $wgOut, $wgSearchLogDateFormat, $wgRequest, $wgLang; |
| 30 | + |
| 31 | + $this->setHeaders(); |
| 32 | + $period = $wgRequest->getVar( 'period', false ); |
| 33 | + $match = array(); |
| 34 | + |
| 35 | + # Get the dates of the first and last entries for the dropdown list range |
| 36 | + wfSuppressWarnings(); |
| 37 | + $fh = fopen( self::getLogName(), 'r' ); |
| 38 | + wfRestoreWarnings(); |
| 39 | + if ( $fh ) { |
| 40 | + if ( preg_match('/^([0-9]{4})([0-9]{2})[0-9]{2},/', fread( $fh ,16 ), $match ) ) { |
| 41 | + list(,$y1,$m1) = $match; |
| 42 | + } |
| 43 | + $len = fstat( $fh ); |
| 44 | + $len = $len['size'] % 1024; |
| 45 | + fseek( $fh, -$len, SEEK_END ); |
| 46 | + $end = explode( "\n", fread( $fh, $len ) ); |
| 47 | + $end = $end[ count( $end ) -2 ]; |
| 48 | + if ( preg_match('/^([0-9]{4})([0-9]{2})[0-9]{2},/', $end, $match ) ) { |
| 49 | + list(,$y2,$m2) = $match; |
| 50 | + } |
| 51 | + fclose( $fh ); |
| 52 | + } |
| 53 | + |
| 54 | + # Construct a list of months if first and last successfully obtained |
| 55 | + $months = ''; |
| 56 | + if ( $y1 && $y2 ) { |
| 57 | + while ( ( $y1 * 100 + $m1 ) <= ( $y2 * 100 + $m2 ) ) { |
| 58 | + $p = strftime( $wgSearchLogDateFormat, mktime( 0, 0, 0, $m1, 1, $y1 ) ); |
| 59 | + $selected = $p == $period ? ' selected' : ''; |
| 60 | + $months .= "<option$selected>$p</option>\n"; |
| 61 | + if ( $m1 == 12 ) { |
| 62 | + $m1 = 1; $y1++; |
| 63 | + } else { |
| 64 | + $m1++; |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + # Render the months as a dropdown-list |
| 70 | + $wgOut->addHTML( |
| 71 | + "<fieldset><legend>" . wfMsgHtml( 'searchlog-timeperiod' ) . "</legend>" |
| 72 | + . Html::element( 'form', array( 'method' => 'POST', |
| 73 | + 'action' => $this->getTitle()->getLocalURL( 'action=submit' ) ) ) |
| 74 | + . "<select name=\"period\">" |
| 75 | + . Html::element( 'option', array( 'value' => self::ENTIRE_LOG ), |
| 76 | + wfMsg( 'searchlog-entire' ) ) |
| 77 | + . "$months</select>" |
| 78 | + . Html::input( 'input', '', array( 'type' => 'submit' ) ) |
| 79 | + . "<br /><br />" |
| 80 | + . Xml::checkLabel( wfMsg( 'searchlog-unicode' ), 'wpEscapeChars', 'wpEscapeChars', true ) |
| 81 | + . '</form></fieldset>' |
| 82 | + ); |
| 83 | + |
| 84 | + # Generate a report if a period was specified |
| 85 | + if ( $period === false ) { |
| 86 | + $period = self::ENTIRE_LOG; |
| 87 | + } |
| 88 | + if ( $period ) { |
| 89 | + $headingPeriod = $period == self::ENTIRE_LOG ? wfMsgNoTrans( self::ENTIRE_LOG ) : $period; |
| 90 | + $heading = wfMsgNoTrans( 'searchlog-heading', $headingPeriod ); |
| 91 | + $wgOut->addWikiText( "== $heading ==", true ); |
| 92 | + wfSuppressWarnings(); |
| 93 | + $fh = fopen( self::getLogName(), 'r' ); |
| 94 | + wfRestoreWarnings(); |
| 95 | + if ( $fh ) { |
| 96 | + # Scan the file and sum the search phrases over the period |
| 97 | + $total = array(); |
| 98 | + while ( !feof( $fh ) ) { |
| 99 | + if ( preg_match('/^([0-9]{4})([0-9]{2})([0-9]{2}),(.+?),(.+?),(.+?),(.+)$/', fgets( $fh ), $match ) ) { |
| 100 | + list(,$y,$m,$d,$time,$user,$type,$phrase) = $match; |
| 101 | + $p = strftime( $wgSearchLogDateFormat, mktime( 0, 0, 0, $m, 1, $y ) ); |
| 102 | + $i = strtolower( trim( $phrase ) ); |
| 103 | + if ( $period == self::ENTIRE_LOG || $period == $p ) { |
| 104 | + $total[$i] = isset( $total[$i] ) ? ++$total[$i] : 1; |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + fclose( $fh ); |
| 109 | + |
| 110 | + # Render the totals in a table |
| 111 | + $table = "\n<table class=\"sortable\" id=\"searchlog\">\n" |
| 112 | + . "<tr><th>" . wfMsgHtml( 'searchlog-phrase' ) ."</th>" |
| 113 | + . "<th>" . wfMsgHtml( 'searchlog-occurances' ) . "</th></tr>"; |
| 114 | + foreach ( $total as $phrase => $count ) { |
| 115 | + if( $wgRequest->getBool( 'wpEscapeChars' ) ) { |
| 116 | + $phrase = preg_replace( "/&/", "&", $phrase ); |
| 117 | + } |
| 118 | + $count = $wgLang->formatNum( $count ); |
| 119 | + $table .= "<tr><td>[[$phrase]]</td><td>$count</td></tr>\n"; |
| 120 | + } |
| 121 | + $table .= "</table>\n"; |
| 122 | + $wgOut->addWikiText( $table, true ); |
| 123 | + } else { |
| 124 | + $wgOut->addWikiMsg( "searchlog-cantopen", true ); |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | +} |
Property changes on: trunk/extensions/SearchLog/SearchLog_body.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 129 | + native |
Index: trunk/extensions/SearchLog/SearchLog.i18n.php |
— | — | @@ -0,0 +1,22 @@ |
| 2 | +<?php |
| 3 | +/* |
| 4 | + * Localization file for SearchLog extension |
| 5 | + */ |
| 6 | + |
| 7 | +$messages = array(); |
| 8 | + |
| 9 | +/** |
| 10 | + * English |
| 11 | + * @author Nad |
| 12 | + */ |
| 13 | +$messages['en'] = array( |
| 14 | + 'searchlog' => 'Search Log', |
| 15 | + 'searchlog-desc' => 'Logs usage of the search box and allows reporting of keyword totals during given time periods', |
| 16 | + 'searchlog-cantopen' => "Couldn't open log file <tt>$1</tt>", |
| 17 | + 'searchlog-heading' => 'Search keywords used over $1 period', |
| 18 | + 'searchlog-unicode' => 'Display raw unicode', |
| 19 | + 'searchlog-timeperiod' => 'Select time period:', |
| 20 | + 'searchlog-entire' => 'Entire log', |
| 21 | + 'searchlog-phrase' => 'Search phrase', |
| 22 | + 'searchlog-occurences' => 'Number of occurences during period', |
| 23 | +); |
Property changes on: trunk/extensions/SearchLog/SearchLog.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 24 | + native |
Index: trunk/extensions/SearchLog/SearchLog.php |
— | — | @@ -3,138 +3,68 @@ |
4 | 4 | # - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html) |
5 | 5 | # - Author: [http://www.organicdesign.co.nz/nad User:Nad] |
6 | 6 | # - Started: 2007-05-16 |
7 | | - |
8 | | -if (!defined('MEDIAWIKI')) die('Not an entry point.'); |
9 | | - |
10 | | -define('SEARCHLOG_VERSION','1.0.8, 2008-2-08'); |
11 | | - |
12 | | -$wgSearchLogPath = dirname(__FILE__); |
13 | | -$wgSearchLogFile = "$wgSearchLogPath/logs/".preg_replace('/^www./','',$_SERVER['SERVER_NAME']); |
14 | | -$wgSearchLogEntireLog = 'Entire log'; # Should be a message |
| 7 | + |
| 8 | +if ( !defined('MEDIAWIKI') ) { |
| 9 | + die( 'Not an entry point.' ); |
| 10 | +} |
| 11 | + |
| 12 | +define( 'SEARCHLOG_VERSION', '1.0.8, 2008-2-08' ); |
| 13 | + |
| 14 | +$dir = dirname( __FILE__ ) . '/'; |
| 15 | + |
| 16 | +// Search log config |
| 17 | +$wgSearchLogPath = $dir . "logs/"; |
| 18 | +$wgSearchLogFile = false; // defaults to your server name unless customized |
15 | 19 | $wgSearchLogDateFormat = '%b %Y'; |
16 | | -$wgSearchLogReportHeading = "Search keywords used over '''\$1''' period"; # Should be a message |
17 | | -$wgSearchLogGroup = ''; # restrict viewing to a particular group by setting this |
18 | | -$wgExtensionFunctions[] = 'wfSetupSearchLog'; |
19 | | - |
| 20 | + |
| 21 | +// Classes and messages and special pages, oh my. |
| 22 | +$wgAutoloadClasses['SpecialSearchLog'] = $dir . 'SearchLog_body.php'; |
| 23 | +$wgExtensionMessageFiles['SearchLog'] = $dir . 'SearchLog.i18n.php'; |
| 24 | +$wgExtensionAliasesFiles['SearchLog'] = $dir . 'SearchLog.alias.php'; |
| 25 | +$wgSpecialPages['SearchLog'] = 'SpecialSearchLog'; |
| 26 | + |
| 27 | +// Permissions |
| 28 | +$wgAvailableRights[] = 'searchlog-read'; |
| 29 | +$wgGroupPermissions['*']['searchlog-read']; |
| 30 | + |
| 31 | +// Credits |
20 | 32 | $wgExtensionCredits['specialpage'][] = array( |
21 | | - 'name' => 'Special:SearchLog', |
22 | | - 'author' => '[http://www.organicdesign.co.nz/nad User:Nad]', |
23 | | - 'description' => 'Logs usage of the search box and allows reporting of keyword totals during given time periods', |
24 | | - 'url' => 'http://www.mediawiki.org/wiki/Extension:SearchLog', |
25 | | - 'version' => SEARCHLOG_VERSION |
26 | | - ); |
27 | | - |
28 | | -require_once "$IP/includes/SpecialPage.php"; |
29 | | - |
30 | | -class SpecialSearchLog extends SpecialPage { |
31 | | - |
32 | | - # Constructor |
33 | | - function SpecialSearchLog() { |
34 | | - global $wgSearchLogGroup; |
35 | | - SpecialPage::SpecialPage('SearchLog',$wgSearchLogGroup); |
36 | | - } |
37 | | - |
38 | | - # Override SpecialPage::execute() |
39 | | - function execute() { |
40 | | - global $wgOut,$wgSearchLogFile,$wgSearchLogEntireLog,$wgSearchLogReportHeading,$wgSearchLogDateFormat,$wgRequest; |
41 | | - $this->setHeaders(); |
42 | | - $title = Title::makeTitle(NS_SPECIAL,'SearchLog'); |
43 | | - $period = isset($_REQUEST['period']) ? $_REQUEST['period'] : false; |
44 | | - $error = ''; |
45 | | - |
46 | | - # Get the dates of the first and last entries for the dropdown list range |
47 | | - if ($fh = fopen($wgSearchLogFile,'r')) { |
48 | | - if (preg_match('/^([0-9]{4})([0-9]{2})[0-9]{2},/',fread($fh,16),$match)) list(,$y1,$m1) = $match; |
49 | | - $len = fstat($fh); |
50 | | - $len = $len['size'] % 1024; |
51 | | - fseek($fh,-$len,SEEK_END); |
52 | | - $end = explode("\n",fread($fh,$len)); |
53 | | - $end = $end[count($end)-2]; |
54 | | - if (preg_match('/^([0-9]{4})([0-9]{2})[0-9]{2},/',$end,$match)) list(,$y2,$m2) = $match; |
55 | | - fclose($fh); |
56 | | - } |
57 | | - |
58 | | - # Construct a list of months if first and last successfully obtained |
59 | | - $months = ''; |
60 | | - if ($y1 && $y2) while (($y1*100+$m1) <= ($y2*100+$m2)) { |
61 | | - $p = strftime($wgSearchLogDateFormat,mktime(0,0,0,$m1,1,$y1)); |
62 | | - $selected = $p == $period ? ' selected' : ''; |
63 | | - $months .= "<option$selected>$p</option>\n"; |
64 | | - if ($m1 == 12) { $m1 = 1; $y1++; } else $m1++; |
65 | | - } |
66 | | - |
67 | | - # Render the months as a dropdown-list |
68 | | - $wgOut->addHTML( |
69 | | - "<fieldset><legend>Select time period: </legend>" |
70 | | - . wfElement('form',array('action' => $title->getLocalURL('action=submit'),'method' => 'POST'),null) |
71 | | - . "<select name=\"period\"><option>$wgSearchLogEntireLog</option>$months</select>" |
72 | | - . wfElement('input',array('type' => 'submit')) |
73 | | - . "<br /><br />" |
74 | | - . wfCheckLabel("Display raw Unicode","wpEscapeChars", "wpEscapeChars", $checked = true) |
75 | | - . '</form></fieldset>' |
76 | | - ); |
77 | | - |
78 | | - # Generate a report if a period was specified |
79 | | - if ($period === false) $period = $wgSearchLogEntireLog; |
80 | | - if ($period) { |
81 | | - $heading = str_replace('$1',$period,$wgSearchLogReportHeading); |
82 | | - $wgOut->addWikiText("== $heading ==",true); |
83 | | - if ($fh = fopen($wgSearchLogFile,'r')) { |
84 | | - |
85 | | - # Scan the file and sum the search phrases over the period |
86 | | - $total = array(); |
87 | | - while (!feof($fh)) { |
88 | | - if (preg_match('/^([0-9]{4})([0-9]{2})([0-9]{2}),(.+?),(.+?),(.+?),(.+)$/',fgets($fh),$match)) { |
89 | | - list(,$y,$m,$d,$time,$user,$type,$phrase) = $match; |
90 | | - $p = strftime($wgSearchLogDateFormat,mktime(0,0,0,$m,1,$y)); |
91 | | - $i = strtolower(trim($phrase)); |
92 | | - if ($period == $wgSearchLogEntireLog || $period == $p) $total[$i] = isset($total[$i]) ? ++$total[$i] : 1; |
93 | | - } |
94 | | - } |
95 | | - fclose($fh); |
96 | | - |
97 | | - # Render the totals in a table |
98 | | - $table = "\n<table class=\"sortable\" id=\"searchlog\">\n"; |
99 | | - $table .= "<tr><th>Search phrase</th><th>Number of occurences during period</th></tr>"; |
100 | | - foreach ($total as $k => $v) { |
101 | | - if($wgRequest->getBool('wpEscapeChars')) { |
102 | | - $k = preg_replace("/&/", "&", $k); |
103 | | - } |
104 | | - $table .= "<tr><td>[[$k]]</td><td>$v</td></tr>\n"; |
105 | | - } |
106 | | - $table .= "</table>\n"; |
107 | | - |
108 | | - } else $error = "Couldn't open log file <tt>$wgSearchLogFile</tt>"; |
109 | | - if ($error) $wgOut->addWikiText($error,true); |
110 | | - else $wgOut->addWikiText($table,true); |
111 | | - } |
112 | | - } |
113 | | - |
114 | | - } |
115 | | - |
| 33 | + 'name' => 'Special:SearchLog', |
| 34 | + 'author' => '[http://www.organicdesign.co.nz/nad User:Nad]', |
| 35 | + 'descriptionmsg' => 'searchlog-desc', |
| 36 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:SearchLog', |
| 37 | + 'version' => SEARCHLOG_VERSION |
| 38 | +); |
| 39 | + |
| 40 | +// Hooks/ext functions |
| 41 | +$wgExtensionFunctions[] = 'wfSetupSearchLog'; |
| 42 | + |
116 | 43 | # Called from $wgExtensionFunctions array when initialising extensions |
117 | 44 | function wfSetupSearchLog() { |
118 | | - global $wgLanguageCode,$wgMessageCache,$wgSearchLogFile,$wgUser; |
119 | | - |
| 45 | + global $wgUser; |
| 46 | + |
120 | 47 | # If a search has been posted, log the info |
121 | | - if (isset($_REQUEST['search'])) { |
| 48 | + if ( isset($_REQUEST['search'] ) ) { |
122 | 49 | $search = $_REQUEST['search']; |
123 | | - if (isset($_REQUEST['fulltext'])) $type = 'fulltext'; |
124 | | - elseif (isset($_REQUEST['go'])) $type = 'go'; |
125 | | - else $type = 'other'; |
126 | | - |
| 50 | + if ( isset( $_REQUEST['fulltext'] ) ) { |
| 51 | + $type = 'fulltext'; |
| 52 | + } elseif ( isset( $_REQUEST['go'] ) ) { |
| 53 | + $type = 'go'; |
| 54 | + } else { |
| 55 | + $type = 'other'; |
| 56 | + } |
| 57 | + |
127 | 58 | # Append the data to the file |
128 | | - if (empty($search)) $search = $_REQUEST[$type]; |
129 | | - if ($fh = fopen($wgSearchLogFile,'a')) { |
130 | | - $text = date('Ymd,H:i:s,').$wgUser->getName().",$type,$search"; |
131 | | - fwrite($fh,"$text\n"); |
132 | | - fclose($fh); |
133 | | - } |
| 59 | + if ( empty( $search ) ) { |
| 60 | + $search = $_REQUEST[$type]; |
134 | 61 | } |
135 | | - |
136 | | - # Add the messages used by the specialpage |
137 | | - $wgMessageCache->addMessages(array('searchlog' => 'Search Log')); |
138 | | - |
139 | | - # Add the specialpage to the environment |
140 | | - SpecialPage::addPage(new SpecialSearchLog()); |
| 62 | + wfSuppressWarnings(); |
| 63 | + $fh = fopen( SpecialSearchLog::getLogName(), 'a' ); |
| 64 | + wfRestoreWarnings(); |
| 65 | + if ( $fh ) { |
| 66 | + $text = date( 'Ymd,H:i:s,' ) . $wgUser->getName() . ",$type,$search"; |
| 67 | + fwrite( $fh, "$text\n" ); |
| 68 | + fclose( $fh ); |
| 69 | + } |
141 | 70 | } |
| 71 | +} |