Extension:RandomInclude/RandomInclude.php
From MediaWiki.org
This is part of the source code for the RandomInclude extension.
Instructions
- To download, select the text in the box below and save it in a file named RandomInclude.php in the extensions directory of your wiki.
- Suggest patches on the extension discussion page.
[edit] RandomInclude.php
<?php # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # http://www.gnu.org/copyleft/gpl.html // RandomInclude MediaWiki extension. // Includes a random text. // Copyright (C) 2007 - Benner Sistemas, 2008 - John Erling Blad. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #---------------------------------------------------------------------------- # Extension initialization #---------------------------------------------------------------------------- $wgRandomInclude = array(); $RandomIncludeVersion = '1.3.5'; $wgExtensionCredits['parserhook'][] = array( 'name'=>'RandomInclude', 'version'=>$RandomIncludeVersion, 'author'=>'Fernando Correia, John Erling Blad', 'url'=>'http://www.mediawiki.org/wiki/Extension:RandomInclude', 'description' => 'Includes a random text' ); $wgExtensionFunctions[] = "wfRandomIncludeExtension"; $wgExtensionFunctions[] = 'wfRandomIncludeParserFunctionSetup'; $wgHooks['LanguageGetMagic'][] = 'wfRandomIncludeMagic'; function wfRandomIncludeExtension() { global $wgParser; $wgParser->setHook( "random", "wfRenderRandomInclude" ); } function wfRandomIncludeParserFunctionSetup() { global $wgParser; $wgParser->setFunctionHook( 'random', 'wfRenderRandomIncludeParserFunction' ); } function wfRandomIncludeMagic( &$magicWords, $langCode ) { $magicWords['random'] = array( 0, 'random' ); return true; } #---------------------------------------------------------------------------- # Rendering #---------------------------------------------------------------------------- // Processes the {{#random:}} parser function. function wfRenderRandomIncludeParserFunction( &$parser, $argv ) { $attr = array(); $cont = array(); $mypat = isset($wgRandomInclude['pattern']) ? $wgRandomInclude['pattern'] : "\n"; $a = func_get_args(); array_shift($a); foreach ($a as $item) { $t = explode('=', $item); switch ($t[0]) { case 'pattern': $attr[] = $t[0] . '="' . $t[1] . '"'; $mypat = $t[1]; $mypat = str_replace(array('\n', '¶'), array("\n", "\n"), $mypat); break; case 'separator': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'count': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'limit': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'period': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'hash': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'seed': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'cache': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'mode': $attr[] = $t[0] . '="' . $t[1] . '"'; break; case 'format': $attr[] = $t[0] . '="' . $t[1] . '"'; break; default: $cont[] = $item; break; } } $cont2 = array(); foreach ($cont as $item) { $t = explode($mypat, $item); foreach ($t as $i) { $i = trim($i); if (strlen($i)) $cont2[] = $i; } } $result = '<random ' . join(' ', $attr) . '>' . join($mypat, $cont2) . '</random>'; return $result; } // Local digest, can be reimplemented // MD5 is quite heavy, and can probably be replaced by a simpler digest function wfRenderRandomDigest( $any ) { $acc = 0; if (is_int($any)) $any = dechex($any + 0); foreach (str_split(md5("" . $any), 4) as $h) { $acc ^= hexdec($h); } return $acc; } // Processes the <random> extension tag. function wfRenderRandomInclude( $input, $argv, $parser ) { global $wgUser; global $wgMessageCache; global $wgRandomInclude; $sStartList = '<ul>'; $sEndList = '</ul>'; $sStartItem = '<li>'; $sEndItem = '</li>'; $sk =& $wgUser->getSkin(); $retries = 0; $pattern = $argv['pattern'] ? $argv['pattern'] : (isset($wgRandomInclude['pattern']) ? $wgRandomInclude['pattern'] : "\n"); $pattern = str_replace(array('\n', '¶'), array("\n", "\n"), $pattern); $separator = $argv['separator'] ? $argv['separator'] : (isset($wgRandomInclude['separator']) ? $wgRandomInclude['separator'] : ''); $count = $argv['count'] ? $argv['count'] : (isset($wgRandomInclude['count']) ? $wgRandomInclude['count'] : 1); $limit = $argv['limit'] ? $argv['limit'] : (isset($wgRandomInclude['limit']) ? $wgRandomInclude['limit'] : 20); $cache = $argv['cache'] ? $argv['cache'] : (isset($wgRandomInclude['cache']) ? $wgRandomInclude['cache'] : 'none'); $seed = $argv['seed'] ? $argv['seed'] : (isset($wgRandomInclude['seed']) ? $wgRandomInclude['seed'] : 'none'); if ($seed != 'none') { srand($seed = intval($seed)); if ('disable' == $cache) $parser->disableCache(); } $hash = $argv['hash'] ? $argv['hash'] : (isset($wgRandomInclude['hash']) ? $wgRandomInclude['hash'] : 'none'); if ($hash != 'none') { $hash = wfRenderRandomDigest($hash); if ('disable' == $cache) $parser->disableCache(); } $period = $argv['period'] ? $argv['period'] : (isset($wgRandomInclude['period']) ? $wgRandomInclude['period'] : 'none'); if ($period != 'none') { $now = time(); switch ($period) { case 'minute': $hash = $now - $now%60; // 60 seconds in a minute break; case 'hour': $hash = $now - $now%3600; // 60*60 seconds in a hour break; case 'day': $hash = $now - $now%86400; // 24*60*60 seconds in a day break; case 'week': $hash = $now - $now%604800; // 7*24*60*60 seconds in a week break; default: $hash = $now - $now%intval($period); break; } if ('disable' == $cache) $parser->disableCache(); } $mode = $argv['mode'] ? $argv['mode'] : (isset($wgRandomInclude['mode']) ? $wgRandomInclude['mode'] : ($count == 1 ? 'none' : 'unordered')); switch ($mode) { case 'none': $sStartList = ''; $sEndList = ''; $sStartItem = ''; $sEndItem = ''; break; case 'ordered': $sStartList = "<ol>\n"; $sEndList = "</ol>\n"; $sStartItem = "<li>\n"; $sEndItem = "</li>\n"; $separator = ''; break; case 'unordered': $sStartList = "<ul>\n"; $sEndList = "</ul>\n"; $sStartItem = "<li>\n"; $sEndItem = "</li>\n"; $separator = ''; break; default: $tpl = $wgMessageCache->getMsgFromNamespace('Random-' . $mode); if (!$tpl) $tpl = '<' . $mode . '>'; $sStartList = ''; $sEndList = ''; $sStartItem = '{{' . $tpl . '|'; $sEndItem = '}}'; break; } $format = $argv['format'] ? $argv['format'] : (isset($wgRandomInclude['format']) ? $wgRandomInclude['format'] : 'none'); if ($format != 'none') { $f = explode(',', $format); $sStartList = htmlspecialchars($f[0]); $sStartItem = htmlspecialchars($f[1]); $sEndItem = htmlspecialchars($f[2]); $sEndList = htmlspecialchars($f[3]); } $values = explode($pattern, $input); $keep = array(); $idxs = array(); while (count($keep) < $count && count($values) && (++$retries <= $limit)) { if ($hash == 'none') { $idx = rand(0, count($values) - 1); } else { $idx = wfRenderRandomDigest($hash + count($keep) + $retries) % count($values); $idxs[] = $hash + count($keep) + $retries; $idxs[] = $idx; } $randomText = trim($values[$idx]); if ($randomText) { $keep[] = $randomText; $retries = 0; $values[$idx] = ''; } } //process results of request, outputing equivalent of <li>[[Article]]</li> for each result, //or something similar if the list uses other startlist/endlist $n = 0; $separator = htmlspecialchars($separator); $output = $sStartList; foreach ($keep as $item) { $item = htmlspecialchars($item); if ($n++) $output .= $separator; $tmp = $sStartItem; $tmp .= $item; $tmp .= $sEndItem; $output .= str_replace(array('%ITEM%', '%COUNT%'), array($item, $n), $tmp); } $output .= $sEndList; $output = str_replace(array('²{', '}²', '²[', ']²', '¦', '\n', '¶'), array('{{', '}}', '[[', ']]', '|', "\n", "\n"), $output); return $parser->internalParse($output . " __NOEDITSECTION__"); }