Extension:RandomInclude/RandomInclude.php

From MediaWiki.org
Jump to: navigation, search

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 = '&lt;' . $mode . '&gt;';
                $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 = array_rand($values);
                }
                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__");
 
}
Personal tools
Namespaces
Variants
Actions
Site
Support
Download
Development
Communication
Print/export
Toolbox