r34641 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r34640‎ | r34641 | r34642 >
Date:05:04, 12 May 2008
Author:dantman
Status:old
Tags:
Comment:
Committing CreateBox, DPLforum, and StringFunctions as is for Algorithm (Ross McClure).
Modified paths:
  • /trunk/extensions/CreateBox (added) (history)
  • /trunk/extensions/CreateBox/CreateBox.php (added) (history)
  • /trunk/extensions/DPLforum (added) (history)
  • /trunk/extensions/DPLforum/DPLforum.php (added) (history)
  • /trunk/extensions/StringFunctions (added) (history)
  • /trunk/extensions/StringFunctions/StringFunctions.php (added) (history)

Diff [purge]

Index: trunk/extensions/StringFunctions/StringFunctions.php
@@ -0,0 +1,437 @@
 2+<?php
 3+/*
 4+
 5+ Defines a subset of parser functions that operate with strings.
 6+
 7+ {{#len:value}}
 8+
 9+ Returns the length of the given value.
 10+ See: http://php.net/manual/function.strlen.php
 11+
 12+
 13+ {{#pos:value|key|offset}}
 14+
 15+ Returns the first position of key inside the given value, or an empty string.
 16+ If offset is defined, this method will not search the first offset characters.
 17+ See: http://php.net/manual/function.strpos.php
 18+
 19+
 20+ {{#rpos:value|key}}
 21+
 22+ Returns the last position of key inside the given value, or -1 if the key is
 23+ not found. When using this to search for the last delimiter, add +1 to the
 24+ result to retreive position after the last delimiter. This also works when
 25+ the delimiter is not found, because "-1 + 1" is zero, which is the beginning
 26+ of the given value.
 27+ See: http://php.net/manual/function.strrpos.php
 28+
 29+
 30+ {{#sub:value|start|length}}
 31+
 32+ Returns a substring of the given value with the given starting position and
 33+ length. If length is omitted, this returns the rest of the string.
 34+ See: http://php.net/manual/function.substr.php
 35+
 36+
 37+ {{#pad:value|length|with|direction}}
 38+
 39+ Returns the value padded to the certain length with the given with string.
 40+ If the with string is not given, spaces are used for padding. The direction
 41+ may be specified as: 'left', 'center' or 'right'.
 42+ See: http://php.net/manual/function.str-pad.php
 43+
 44+
 45+ {{#replace:value|from|to}}
 46+
 47+ Returns the given value with all occurences of 'from' replaced with 'to'.
 48+ See: http://php.net/manual/function.str-replace.php
 49+
 50+
 51+ {{#explode:value|delimiter|position}}
 52+
 53+ Splits the given value into pieces by the given delimiter and returns the
 54+ position-th piece. Empty string is returned if there are not enough pieces.
 55+ Note: Pieces are counted from 0.
 56+ Note: A negative value can be used to count pieces from the end, instead of
 57+ counting from the beginning. The last piece is at position -1.
 58+ See: http://php.net/manual/function.explode.php
 59+
 60+
 61+ {{#urlencode:value}}
 62+
 63+ URL-encodes the given value.
 64+ See: http://php.net/manual/function.urlencode.php
 65+
 66+
 67+ {{#urldecode:value}}
 68+
 69+ URL-decodes the given value.
 70+ See: http://php.net/manual/function.urldecode.php
 71+
 72+
 73+ Copyright (c) 2008 Ross McClure & Juraj Simlovic
 74+ http://www.mediawiki.org/wiki/User:Algorithm
 75+ http://www.mediawiki.org/wiki/User:jsimlo
 76+
 77+ Permission is hereby granted, free of charge, to any person
 78+ obtaining a copy of this software and associated documentation
 79+ files (the "Software"), to deal in the Software without
 80+ restriction, including without limitation the rights to use,
 81+ copy, modify, merge, publish, distribute, sublicense, and/or sell
 82+ copies of the Software, and to permit persons to whom the
 83+ Software is furnished to do so, subject to the following
 84+ conditions:
 85+
 86+ The above copyright notice and this permission notice shall be
 87+ included in all copies or substantial portions of the Software.
 88+
 89+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 90+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 91+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 92+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 93+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 94+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 95+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 96+ OTHER DEALINGS IN THE SOFTWARE.
 97+
 98+*/
 99+
 100+$wgExtensionCredits['parserhook'][] = array(
 101+'name' => 'StringFunctions',
 102+'version' => '2.0', // Dec 10, 2007
 103+'description' => 'Enhances parser with string functions',
 104+'author' => array('Ross McClure', 'Juraj Simlovic'),
 105+'url' => 'http://www.mediawiki.org/wiki/Extension:StringFunctions',
 106+);
 107+
 108+$wgExtensionFunctions[] = 'wfStringFunctions';
 109+
 110+$wgHooks['LanguageGetMagic'][] = 'wfStringFunctionsLanguageGetMagic';
 111+
 112+function wfStringFunctions ( ) {
 113+ global $wgParser, $wgExtStringFunctions;
 114+ global $wgStringFunctionsLimitSearch;
 115+ global $wgStringFunctionsLimitReplace;
 116+ global $wgStringFunctionsLimitPad;
 117+
 118+ $wgExtStringFunctions = new ExtStringFunctions ( );
 119+ $wgStringFunctionsLimitSearch = 30;
 120+ $wgStringFunctionsLimitReplace = 30;
 121+ $wgStringFunctionsLimitPad = 100;
 122+
 123+ $wgParser->setFunctionHook('len', array(&$wgExtStringFunctions,'runLen' ));
 124+ $wgParser->setFunctionHook('pos', array(&$wgExtStringFunctions,'runPos' ));
 125+ $wgParser->setFunctionHook('rpos', array(&$wgExtStringFunctions,'runRPos' ));
 126+ $wgParser->setFunctionHook('sub', array(&$wgExtStringFunctions,'runSub' ));
 127+ $wgParser->setFunctionHook('pad', array(&$wgExtStringFunctions,'runPad' ));
 128+ $wgParser->setFunctionHook('replace', array(&$wgExtStringFunctions,'runReplace' ));
 129+ $wgParser->setFunctionHook('explode', array(&$wgExtStringFunctions,'runExplode' ));
 130+ $wgParser->setFunctionHook('urlencode',array(&$wgExtStringFunctions,'runUrlEncode'));
 131+ $wgParser->setFunctionHook('urldecode',array(&$wgExtStringFunctions,'runUrlDecode'));
 132+}
 133+
 134+function wfStringFunctionsLanguageGetMagic( &$magicWords, $langCode = "en" ) {
 135+ switch ( $langCode ) {
 136+ default:
 137+ $magicWords['len'] = array ( 0, 'len' );
 138+ $magicWords['pos'] = array ( 0, 'pos' );
 139+ $magicWords['rpos'] = array ( 0, 'rpos' );
 140+ $magicWords['sub'] = array ( 0, 'sub' );
 141+ $magicWords['pad'] = array ( 0, 'pad' );
 142+ $magicWords['replace'] = array ( 0, 'replace' );
 143+ $magicWords['explode'] = array ( 0, 'explode' );
 144+ $magicWords['urlencode'] = array ( 0, 'urlencode' );
 145+ $magicWords['urldecode'] = array ( 0, 'urldecode' );
 146+ }
 147+ return true;
 148+}
 149+
 150+class ExtStringFunctions {
 151+ /**
 152+ * Splits the string into its component parts using preg_match_all().
 153+ * $chars is set to the resulting array of multibyte characters.
 154+ * Returns count($chars).
 155+ */
 156+ function mwSplit ( &$parser, $str, &$chars ) {
 157+ # Get marker prefix & suffix
 158+ $prefix = preg_quote( $parser->mUniqPrefix );
 159+ if( isset($parser->mMarkerSuffix) )
 160+ $suffix = preg_quote( $parser->mMarkerSuffix );
 161+ else if ( strcmp( MW_PARSER_VERSION, '1.6.1' ) > 0 )
 162+ $suffix = 'QINU\x07';
 163+ else $suffix = 'QINU';
 164+
 165+ # Treat strip markers as single multibyte characters
 166+ $count = preg_match_all('/' . $prefix . '.*?' . $suffix . '|./su', $str, $arr);
 167+ $chars = $arr[0];
 168+ return $count;
 169+ }
 170+
 171+ /**
 172+ * {{#len:value}}
 173+ */
 174+ function runLen ( &$parser, $inStr = '' ) {
 175+ return $this->mwSplit ( $parser, $inStr, $chars );
 176+ }
 177+
 178+ /**
 179+ * {{#pos:value|key|offset}}
 180+ * Note: If the needle is an empty string, single space is used instead.
 181+ * Note: If the needle is not found, empty string is returned.
 182+ * Note: The needle is limited to specific length.
 183+ */
 184+ function runPos ( &$parser, $inStr = '', $inNeedle = '', $inOffset = 0 ) {
 185+ global $wgStringFunctionsLimitSearch;
 186+
 187+ if ( $inNeedle === '' ) {
 188+ # empty needle
 189+ $needle = array(' ');
 190+ $nSize = 1;
 191+ } else {
 192+ # convert needle
 193+ $nSize = $this->mwSplit ( $parser, $inNeedle, $needle );
 194+
 195+ if ( $nSize > $wgStringFunctionsLimitSearch ) {
 196+ $nSize = $wgStringFunctionsLimitSearch;
 197+ $needle = array_slice ( $needle, 0, $nSize );
 198+ }
 199+ }
 200+
 201+ # convert string
 202+ $size = $this->mwSplit( $parser, $inStr, $chars ) - $nSize;
 203+ $inOffset = max ( intval($inOffset), 0 );
 204+
 205+ # find needle
 206+ for ( $i = $inOffset; $i <= $size; $i++ ) {
 207+ if ( $chars[$i] !== $needle[0] ) continue;
 208+ for ( $j = 1; ; $j++ ) {
 209+ if ( $j >= $nSize ) return $i;
 210+ if ( $chars[$i + $j] !== $needle[$j] ) break;
 211+ }
 212+ }
 213+
 214+ # return empty string upon not found
 215+ return '';
 216+ }
 217+
 218+ /**
 219+ * {{#rpos:value|key}}
 220+ * Note: If the needle is an empty string, single space is used instead.
 221+ * Note: If the needle is not found, -1 is returned.
 222+ * Note: The needle is limited to specific length.
 223+ */
 224+ function runRPos ( &$parser, $inStr = '', $inNeedle = '' ) {
 225+ global $wgStringFunctionsLimitSearch;
 226+
 227+ if ( $inNeedle === '' ) {
 228+ # empty needle
 229+ $needle = array(' ');
 230+ $nSize = 1;
 231+ } else {
 232+ # convert needle
 233+ $nSize = $this->mwSplit ( $parser, $inNeedle, $needle );
 234+
 235+ if ( $nSize > $wgStringFunctionsLimitSearch ) {
 236+ $nSize = $wgStringFunctionsLimitSearch;
 237+ $needle = array_slice ( $needle, 0, $nSize );
 238+ }
 239+ }
 240+
 241+ # convert string
 242+ $size = $this->mwSplit( $parser, $inStr, $chars ) - $nSize;
 243+
 244+ # find needle
 245+ for ( $i = $size; $i >= 0; $i-- ) {
 246+ if ( $chars[$i] !== $needle[0] ) continue;
 247+ for ( $j = 1; ; $j++ ) {
 248+ if ( $j >= $nSize ) return $i;
 249+ if ( $chars[$i + $j] !== $needle[$j] ) break;
 250+ }
 251+ }
 252+
 253+ # return -1 upon not found
 254+ return "-1";
 255+ }
 256+
 257+ /**
 258+ * {{#sub:value|start|length}}
 259+ * Note: If length is zero, the rest of the input is returned.
 260+ */
 261+ function runSub ( &$parser, $inStr = '', $inStart = 0, $inLength = 0 ) {
 262+ # convert string
 263+ $this->mwSplit( $parser, $inStr, $chars );
 264+
 265+ # zero length
 266+ if ( intval($inLength) == 0 )
 267+ return join('', array_slice( $chars, intval($inStart) ));
 268+
 269+ # non-zero length
 270+ return join('', array_slice( $chars, intval($inStart), intval($inLength) ));
 271+ }
 272+
 273+ /**
 274+ * {{#pad:value|length|with|direction}}
 275+ * Note: Length of the resulting string is limited.
 276+ */
 277+ function runPad( &$parser, $inStr = '', $inLen = 0, $inWith = '', $inDirection = '' ) {
 278+ global $wgStringFunctionsLimitPad;
 279+
 280+ # direction
 281+ switch ( strtolower ( $inDirection ) ) {
 282+ case 'center':
 283+ $direction = STR_PAD_BOTH;
 284+ break;
 285+ case 'right':
 286+ $direction = STR_PAD_RIGHT;
 287+ break;
 288+ case 'left':
 289+ default:
 290+ $direction = STR_PAD_LEFT;
 291+ break;
 292+ }
 293+
 294+ # prevent markers in padding
 295+ $a = explode ( $parser->mUniqPrefix, $inWith, 2 );
 296+ if ( $a[0] === '' )
 297+ $inWith = ' ';
 298+ else $inWith = $a[0];
 299+
 300+ # limit pad length
 301+ $inLen = intval ( $inLen );
 302+ if ($wgStringFunctionsLimitPad > 0)
 303+ $inLen = min ( $inLen, $wgStringFunctionsLimitPad );
 304+
 305+ # adjust for multibyte strings
 306+ $inLen += strlen( $inStr ) - $this->mwSplit( $parser, $inStr, $a );
 307+
 308+ # pad
 309+ return str_pad ( $inStr, $inLen, $inWith, $direction );
 310+ }
 311+
 312+ /**
 313+ * {{#replace:value|from|to}}
 314+ * Note: If the needle is an empty string, single space is used instead.
 315+ * Note: The needle is limited to specific length.
 316+ * Note: The product is limited to specific length.
 317+ */
 318+ function runReplace( &$parser, $inStr = '', $inReplaceFrom = '', $inReplaceTo = '' ) {
 319+ global $wgStringFunctionsLimitSearch, $wgStringFunctionsLimitReplace;
 320+
 321+ if ( $inReplaceFrom === '' ) {
 322+ # empty needle
 323+ $needle = array(' ');
 324+ $nSize = 1;
 325+ } else {
 326+ # convert needle
 327+ $nSize = $this->mwSplit ( $parser, $inReplaceFrom, $needle );
 328+ if ( $nSize > $wgStringFunctionsLimitSearch ) {
 329+ $nSize = $wgStringFunctionsLimitSearch;
 330+ $needle = array_slice ( $needle, 0, $nSize );
 331+ }
 332+ }
 333+
 334+ # convert product
 335+ $pSize = $this->mwSplit ( $parser, $inReplaceTo, $product );
 336+ if ( $pSize > $wgStringFunctionsLimitReplace ) {
 337+ $pSize = $wgStringFunctionsLimitReplace;
 338+ $product = array_slice ( $product, 0, $pSize );
 339+ }
 340+
 341+ # remove markers in product
 342+ for( $i = 0; $i < $pSize; $i++ ) {
 343+ if( strlen( $product[$i] ) > 6 ) $product[$i] = ' ';
 344+ }
 345+
 346+ # convert string
 347+ $size = $this->mwSplit ( $parser, $inStr, $chars ) - $nSize;
 348+
 349+ # replace
 350+ for ( $i = 0; $i <= $size; $i++ ) {
 351+ if ( $chars[$i] !== $needle[0] ) continue;
 352+ for ( $j = 1; ; $j++ ) {
 353+ if ( $j >= $nSize ) {
 354+ array_splice ( $chars, $i, $j, $product );
 355+ $size += ( $pSize - $nSize );
 356+ $i += ( $pSize - 1 );
 357+ break;
 358+ }
 359+ if ( $chars[$i + $j] !== $needle[$j] ) break;
 360+ }
 361+ }
 362+ return join('', $chars);
 363+ }
 364+
 365+ /**
 366+ * {{#explode:value|delimiter|position}}
 367+ * Note: Negative position can be used to specify tokens from the end.
 368+ * Note: If the divider is an empty string, single space is used instead.
 369+ * Note: The divider is limited to specific length.
 370+ * Note: Empty string is returned, if there is not enough exploded chunks.
 371+ */
 372+ function runExplode ( &$parser, $inStr = '', $inDiv = '', $inPos = 0 ) {
 373+ global $wgStringFunctionsLimitSearch;
 374+
 375+ if ( $inDiv === '' ) {
 376+ # empty divider
 377+ $div = array(' ');
 378+ $dSize = 1;
 379+ } else {
 380+ # convert divider
 381+ $dSize = $this->mwSplit ( $parser, $inDiv, $div );
 382+ if ( $dSize > $wgStringFunctionsLimitSearch ) {
 383+ $dSize = $wgStringFunctionsLimitSearch;
 384+ $div = array_slice ( $div, 0, $dSize );
 385+ }
 386+ }
 387+
 388+ # convert string
 389+ $size = $this->mwSplit ( $parser, $inStr, $chars ) - $dSize;
 390+
 391+ # explode
 392+ $inPos = intval ( $inPos );
 393+ $tokens = array();
 394+ $start = 0;
 395+ for ( $i = 0; $i <= $size; $i++ ) {
 396+ if ( $chars[$i] !== $div[0] ) continue;
 397+ for ( $j = 1; ; $j++ ) {
 398+ if ( $j >= $dSize ) {
 399+ if ( $inPos > 0 ) $inPos--;
 400+ else {
 401+ $tokens[] = join('', array_slice($chars, $start, ($i - $start)));
 402+ if ( $inPos == 0 ) return $tokens[0];
 403+ }
 404+ $start = $i + $j;
 405+ $i = $start - 1;
 406+ break;
 407+ }
 408+ if ( $chars[$i + $j] !== $div[$j] ) break;
 409+ }
 410+ }
 411+ $tokens[] = join('', array_slice( $chars, $start ));
 412+
 413+ # negative $inPos
 414+ if ( $inPos < 0 ) $inPos += count ( $tokens );
 415+
 416+ # out of range
 417+ if ( !isset ( $tokens[$inPos] ) ) return "";
 418+
 419+ # in range
 420+ return $tokens[$inPos];
 421+ }
 422+
 423+ /**
 424+ * {{#urlencode:value}}
 425+ */
 426+ function runUrlEncode ( &$parser, $inStr = '' ) {
 427+ # encode
 428+ return urlencode ( $inStr );
 429+ }
 430+
 431+ /**
 432+ * {{#urldecode:value}}
 433+ */
 434+ function runUrlDecode ( &$parser, $inStr = '' ) {
 435+ # decode
 436+ return urldecode ( $inStr );
 437+ }
 438+}
\ No newline at end of file
Property changes on: trunk/extensions/StringFunctions/StringFunctions.php
___________________________________________________________________
Added: svn:eol-style
1439 + native
Index: trunk/extensions/CreateBox/CreateBox.php
@@ -0,0 +1,135 @@
 2+<?php
 3+/*
 4+
 5+ CreateBox v1.5 -- Specialized Inputbox for page creation
 6+
 7+ Author: Ross McClure
 8+ http://www.mediawiki.org/wiki/User:Algorithm
 9+
 10+ Inputbox written by Erik Moeller <moeller@scireview.de>
 11+
 12+ This program is free software; you can redistribute it and/or modify
 13+ it under the terms of the GNU General Public License as published by
 14+ the Free Software Foundation; either version 2 of the License, or
 15+ (at your option) any later version.
 16+
 17+ This program is distributed in the hope that it will be useful,
 18+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 19+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 20+ GNU General Public License for more details.
 21+
 22+ You should have received a copy of the GNU General Public License along
 23+ with this program; if not, write to the Free Software Foundation, Inc.,
 24+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 25+ http://www.gnu.org/copyleft/gpl.html
 26+
 27+ To install, add following to LocalSettings.php
 28+ include("extensions/create.php");
 29+
 30+*/
 31+
 32+$wgExtensionFunctions[] = "wfCreateBox";
 33+$wgHooks['UnknownAction'][] = 'actionCreate';
 34+$wgExtensionCredits['parserhook'][] = array(
 35+ 'name' => 'CreateBox',
 36+ 'url' => 'http://www.mediawiki.org/wiki/Extension:CreateBox',
 37+ 'description' => 'Specialized Inputbox for page creation',
 38+ 'author' => 'Ross McClure',
 39+ 'version' => '1.5'
 40+);
 41+
 42+function wfCreateBox() {
 43+ global $wgParser, $wgMessageCache;
 44+
 45+ $wgMessageCache->addMessages( array(
 46+ 'create' => "Create",
 47+ 'create_exists' => "Sorry, \"'''{{FULLPAGENAME}}'''\" already " .
 48+ "exists.\n\nYou cannot create this page, but you can " .
 49+ "[{{fullurl:{{FULLPAGENAME}}|action=edit}} edit it], " .
 50+ "[{{fullurl:{{FULLPAGENAME}}}} read it], or choose to " .
 51+ "create a different page using the box below.\n\n" .
 52+ "<createbox>break=no</createbox>"
 53+ ));
 54+
 55+ $wgParser->setHook( "createbox", "acMakeBox" );
 56+}
 57+
 58+function actionCreate($action, $article) {
 59+ if($action != 'create') return true;
 60+
 61+ global $wgRequest;
 62+ $prefix = $wgRequest->getVal('prefix');
 63+ $text = $wgRequest->getVal('title');
 64+ if($prefix && strpos($text, $prefix)!==0) {
 65+ $title = Title::newFromText( $prefix . $text );
 66+ if(is_null($title)) {
 67+ global $wgTitle;
 68+ $wgTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle' );
 69+ throw new ErrorPageError( 'badtitle', 'badtitletext' );
 70+ }
 71+ else if($title->getArticleID() == 0) acRedirect($title, 'edit');
 72+ else acRedirect($title, 'create');
 73+ }
 74+ else if($wgRequest->getVal('section')=='new' || $article->getID() == 0) {
 75+ acRedirect($article->getTitle(), 'edit');
 76+ } else {
 77+ global $wgOut;
 78+ $text = $article->getTitle()->getPrefixedText();
 79+ $wgOut->setPageTitle($text);
 80+ $wgOut->setHTMLTitle(wfMsg('pagetitle', $text.' - '.wfMsg('create')));
 81+ $wgOut->addWikiText(wfMsg('create_exists'));
 82+ }
 83+ return false;
 84+}
 85+
 86+function acGetOption(&$input,$name,$value=NULL) {
 87+ if(preg_match("/^\s*$name\s*=\s*(.*)/mi",$input,$matches)) {
 88+ if(is_int($value)) return intval($matches[1]);
 89+ else return htmlspecialchars($matches[1]);
 90+ }
 91+ return $value;
 92+}
 93+
 94+function acMakeBox($input, $argv, &$parser) {
 95+ global $wgRequest, $wgScript;
 96+ if($wgRequest->getVal('action')=='create') {
 97+ $prefix = $wgRequest->getVal('prefix');
 98+ $preload = $wgRequest->getVal('preload');
 99+ $editintro = $wgRequest->getVal('editintro');
 100+ $text = $parser->getTitle()->getPrefixedText();
 101+ if($prefix && strpos($text, $prefix)===0)
 102+ $text = substr($text, strlen($prefix));
 103+ } else {
 104+ $prefix = acGetOption($input,'prefix');
 105+ $preload = acGetOption($input,'preload');
 106+ $editintro = acGetOption($input,'editintro');
 107+ $text = acGetOption($input,'default');
 108+ }
 109+ $submit = htmlspecialchars($wgScript);
 110+ $width = acGetOption($input,'width',0);
 111+ $align = acGetOption($input,'align','center');
 112+ $br = ((acGetOption($input,'break','no')=='no') ? '' : '<br />');
 113+ $label = acGetOption($input,'buttonlabel',wfMsgHtml("createarticle"));
 114+ $output=<<<ENDFORM
 115+<div class="createbox" align="{$align}">
 116+<form name="createbox" action="{$submit}" method="get" class="createboxForm">
 117+<input type='hidden' name="action" value="create">
 118+<input type="hidden" name="prefix" value="{$prefix}" />
 119+<input type="hidden" name="preload" value="{$preload}" />
 120+<input type="hidden" name="editintro" value="{$editintro}" />
 121+<input class="createboxInput" name="title" type="text" value="{$text}" size="{$width}"/>{$br}
 122+<input type='submit' name="create" class="createboxButton" value="{$label}"/>
 123+</form></div>
 124+ENDFORM;
 125+ return $parser->replaceVariables($output);
 126+}
 127+
 128+function acRedirect($title, $action) {
 129+ global $wgRequest, $wgOut;
 130+ $query = "action={$action}&prefix=" . $wgRequest->getVal('prefix') .
 131+ "&preload=" . $wgRequest->getVal('preload') .
 132+ "&editintro=" . $wgRequest->getVal('editintro') .
 133+ "&section=" . $wgRequest->getVal('section');
 134+ $wgOut->setSquidMaxage( 1200 );
 135+ $wgOut->redirect($title->getFullURL( $query ), '301');
 136+}
\ No newline at end of file
Property changes on: trunk/extensions/CreateBox/CreateBox.php
___________________________________________________________________
Added: svn:eol-style
1137 + native
Index: trunk/extensions/DPLforum/DPLforum.php
@@ -0,0 +1,499 @@
 2+<?php
 3+/*
 4+
 5+ DPLforum v3.2 -- DynamicPageList-based forum extension
 6+
 7+ Author: Ross McClure
 8+ http://www.mediawiki.org/wiki/User:Algorithm
 9+
 10+ DynamicPageList written by: n:en:User:IlyaHaykinson n:en:User:Amgine
 11+ http://en.wikinews.org/wiki/User:Amgine
 12+ http://en.wikinews.org/wiki/User:IlyaHaykinson
 13+
 14+ This program is free software; you can redistribute it and/or modify
 15+ it under the terms of the GNU General Public License as published by
 16+ the Free Software Foundation; either version 2 of the License, or
 17+ (at your option) any later version.
 18+
 19+ This program is distributed in the hope that it will be useful,
 20+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 21+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 22+ GNU General Public License for more details.
 23+
 24+ You should have received a copy of the GNU General Public License along
 25+ with this program; if not, write to the Free Software Foundation, Inc.,
 26+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 27+ http://www.gnu.org/copyleft/gpl.html
 28+
 29+ To install, add following to LocalSettings.php
 30+ include("extensions/forum.php");
 31+
 32+*/
 33+
 34+$wgExtensionFunctions[] = "wfDPLforum";
 35+$wgHooks['LanguageGetMagic'][] = 'wfDPLmagic';
 36+$wgExtensionCredits['parserhook'][] = array(
 37+'name' => 'DPLforum',
 38+'url' => 'http://www.mediawiki.org/wiki/Extension:DPLforum',
 39+'description' => 'DPL-based forum extension',
 40+'author' => 'Ross McClure',
 41+'version' => '3.2'
 42+);
 43+
 44+function wfDPLforum()
 45+{
 46+ global $wgParser, $wgMessageCache;
 47+
 48+ $wgMessageCache->addMessages( array(
 49+ 'forum_by' => 'by',
 50+ 'forum_edited' => ' - Last edited',
 51+ 'forum_never' => 'Never',
 52+ 'forum_toofew' => 'DPL Forum: Too few categories!',
 53+ 'forum_toomany' => 'DPL Forum: Too many categories!'
 54+ ));
 55+
 56+ $wgParser->setHook('forum','parseForum');
 57+ $wgParser->setFunctionHook('forumlink', array(new DPLForum(),'link'));
 58+}
 59+
 60+function wfDPLmagic(&$magicWords,$langCode="en")
 61+{
 62+ switch($langCode)
 63+ {
 64+ default: $magicWords['forumlink'] = array (0,'forumlink');
 65+ }
 66+ return true;
 67+}
 68+
 69+function parseForum($input, $argv, &$parser)
 70+{
 71+ $f = new DPLForum();
 72+ return $f->parse($input, $parser);
 73+}
 74+
 75+class DPLForum
 76+{
 77+ var $minCategories = 1; // Minimum number of categories to look for
 78+ var $maxCategories = 6; // Maximum number of categories to look for
 79+ var $maxResultCount = 50; // Maximum number of results to allow
 80+ var $unlimitedResults = true; // Allow unlimited results
 81+ var $unlimitedCategories = false; // Allow unlimited categories
 82+ var $requireCache = false; // Only clear the cache on purge
 83+
 84+ // Restricted namespaces cannot be searched for page author or creation time.
 85+ // Unless this array is empty, namespace-free searches are also restricted.
 86+ // Note: Only integers in this array are checked.
 87+ var $restrictNamespace = array(); // No restrictions
 88+
 89+ var $bTableMode;
 90+ var $bTimestamp;
 91+ var $bLinkHistory;
 92+ var $bEmbedHistory;
 93+ var $bShowNamespace;
 94+ var $bAddAuthor;
 95+ var $bAddCreationDate;
 96+ var $bAddLastEdit;
 97+ var $bAddLastEditor;
 98+ var $bCompactAuthor;
 99+ var $bCompactEdit;
 100+ var $sInput;
 101+ var $sOmit;
 102+ var $vMarkNew;
 103+
 104+ function cat(&$parser, $name)
 105+ {
 106+ $cats = array();
 107+ if(preg_match_all("/^\s*$name\s*=\s*(.*)/mi",$this->sInput,$matches))
 108+ {
 109+ foreach($matches[1] as $cat)
 110+ {
 111+ $title = Title::newFromText($parser->replaceVariables(trim($cat)));
 112+ if( !is_null( $title ) )
 113+ $cats[] = $title;
 114+ }
 115+ }
 116+ return $cats;
 117+ }
 118+
 119+ function get($name, $value=NULL, $parser=NULL)
 120+ {
 121+ if(preg_match("/^\s*$name\s*=\s*(.*)/mi",$this->sInput,$matches))
 122+ {
 123+ $arg = trim($matches[1]);
 124+ if(is_int($value)) return intval($arg);
 125+ else if(is_null($parser)) return htmlspecialchars($arg);
 126+ else return $parser->replaceVariables($arg);
 127+ }
 128+ return $value;
 129+ }
 130+
 131+ function link(&$parser, $count, $page='', $text='')
 132+ {
 133+ $count = intval($count);
 134+ if($count<1) return '';
 135+
 136+ if($this->requireCache) $offset = 0;
 137+ else
 138+ {
 139+ global $wgRequest;
 140+ $parser->disableCache();
 141+ $offset = intval($wgRequest->getVal('offset',''));
 142+ }
 143+
 144+ $i = intval($page);
 145+ if(($i!=0) && ctype_digit($page[0])) $i -= 1;
 146+ else $i += intval($offset / $count);
 147+ if($this->link_test($i,$page)) return '';
 148+
 149+ if($text==='') $text = ($i + 1);
 150+ $page = ($count * $i);
 151+ if($page == $offset) return $text;
 152+
 153+ return '[{{fullurl:{{FULLPAGENAME}}|offset='.$page.'}} '.$text.']';
 154+ }
 155+
 156+ function link_test($page, $cond)
 157+ {
 158+ if(preg_match("/\\d+(\\D+)(\\d+)/",$cond,$m))
 159+ {
 160+ $m[1] = strtr($m[1], array(('&l'.'t;')=>'<', ('&g'.'t;')=>'>'));
 161+ $m[2] = intval($m[2])-1;
 162+ switch($m[1])
 163+ {
 164+ case '<': return ($page >= $m[2]);
 165+ case '>': return ($page <= $m[2]);
 166+ case '<=': return ($page > $m[2]);
 167+ case '>=': return ($page < $m[2]);
 168+ }
 169+ }
 170+ return ($page < 0);
 171+ }
 172+
 173+ function msg($type, $error=NULL)
 174+ {
 175+ if($error && ($this->get('suppresserrors')=='true')) return '';
 176+ return htmlspecialchars(wfMsg($type));
 177+ }
 178+
 179+ function parse(&$input, &$parser)
 180+ {
 181+ global $wgContLang;
 182+
 183+ $this->sInput =& $input;
 184+ $sPrefix = $this->get('prefix','',$parser);
 185+ $this->sOmit = $this->get('omit',$sPrefix,$parser);
 186+ $this->bAddAuthor = ($this->get('addauthor')=='true');
 187+ $this->bTimestamp = ($this->get('timestamp')!='false');
 188+ $this->bAddLastEdit = ($this->get('addlastedit')!='false');
 189+ $this->bAddLastEditor = ($this->get('addlasteditor')=='true');
 190+ $this->bAddCreationDate = ($this->get('addcreationdate')=='true');
 191+
 192+ switch($this->get('historylink'))
 193+ {
 194+ case 'embed':
 195+ case 'true': $this->bEmbedHistory = true;
 196+ case 'append':
 197+ case 'show': $this->bLinkHistory = true;
 198+ }
 199+ $sOrder = 'rev_timestamp';
 200+ switch($this->get('ordermethod'))
 201+ {
 202+ case 'categoryadd':
 203+ case 'created':
 204+ $sOrder = 'first_time';
 205+ break;
 206+ case 'pageid':
 207+ $sOrder = 'page_id';
 208+ }
 209+
 210+ $arg = $this->get('compact');
 211+ if($arg=='all' || strpos($arg,'edit')===0)
 212+ $this->bCompactEdit = $this->bAddLastEdit;
 213+ $this->bCompactAuthor = ($arg=='author' || $arg=='all');
 214+
 215+ $arg = $this->get('namespace','',$parser);
 216+ $iNamespace = $wgContLang->getNsIndex($arg);
 217+ if(!$iNamespace)
 218+ {
 219+ if(($arg) || ($arg==='0')) $iNamespace = intval($arg);
 220+ else $iNamespace = -1;
 221+ }
 222+ if($iNamespace<0)
 223+ $this->bShowNamespace = ($this->get('shownamespace')!='false');
 224+ else $this->bShowNamespace = ($this->get('shownamespace')=='true');
 225+
 226+ $this->bTableMode = false;
 227+ $sStartItem = $sEndItem = '';
 228+ $bCountMode = false;
 229+ $arg = $this->get('mode');
 230+ switch($arg)
 231+ {
 232+ case 'none':
 233+ $sEndItem = '<br/>';
 234+ break;
 235+ case 'count':
 236+ $bCountMode = true;
 237+ break;
 238+ case 'list':
 239+ case 'ordered':
 240+ case 'unordered':
 241+ $sStartItem = '<li>';
 242+ $sEndItem = '</li>';
 243+ break;
 244+ case 'table':
 245+ default:
 246+ $this->bTableMode = true;
 247+ $sStartItem = '<tr>';
 248+ $sEndItem = '</tr>';
 249+ }
 250+ $aCategories = $this->cat($parser,'category');
 251+ $aExcludeCategories = $this->cat($parser,'notcategory');
 252+ $cats = count($aCategories);
 253+ $nocats = count($aExcludeCategories);
 254+ $total = $cats + $nocats;
 255+ $output = '';
 256+
 257+ if($sPrefix==='' && (($cats < 1 && $iNamespace < 0) ||
 258+ ($total < $this->minCategories))) return $this->msg('forum_toofew',1);
 259+ if(($total > $this->maxCategories) && (!$this->unlimitedCategories))
 260+ return $this->msg('forum_toomany',1);
 261+
 262+ $count = 1;
 263+ $start = $this->get('start',0);
 264+ $title = Title::newFromText($parser->replaceVariables(
 265+ trim($this->get('title'))));
 266+ if(!($bCountMode || $this->requireCache || $this->get('cache')=='true'))
 267+ {
 268+ $parser->disableCache();
 269+
 270+ if(is_null($title))
 271+ {
 272+ global $wgRequest;
 273+ $start += intval($wgRequest->getVal('offset'));
 274+ }
 275+ }
 276+ if($start < 0) $start = 0;
 277+
 278+ if(is_null($title))
 279+ {
 280+ $count = $this->get('count',0);
 281+ if($count > 0)
 282+ {
 283+ if($count > $this->maxResultCount)
 284+ $count = $this->maxResultCount;
 285+ }
 286+ else if($this->unlimitedResults)
 287+ $count = 0x7FFFFFFF; // maximum integer value
 288+ else
 289+ $count = $this->maxResultCount;
 290+ }
 291+
 292+ //build the SQL query
 293+ $dbr =& wfGetDB( DB_SLAVE );
 294+ $sPageTable = $dbr->tableName( 'page' );
 295+ $sRevTable = $dbr->tableName( 'revision' );
 296+ $categorylinks = $dbr->tableName( 'categorylinks' );
 297+ $sSqlSelectFrom = "SELECT page_namespace, page_title,"
 298+ . " r.rev_user_text, r.rev_timestamp";
 299+ $arg = " FROM $sPageTable INNER JOIN $sRevTable"
 300+ . " AS r ON page_latest = r.rev_id";
 301+
 302+ if($bCountMode)
 303+ {
 304+ $sSqlSelectFrom = "SELECT COUNT(*) AS num_rows FROM $sPageTable";
 305+ }
 306+ else if(($this->bAddAuthor || $this->bAddCreationDate ||
 307+ ($sOrder=='first_time')) && ((!$this->restrictNamespace) ||
 308+ ($iNamespace>=0 && !in_array($iNamespace,$this->restrictNamespace))))
 309+ {
 310+ $sSqlSelectFrom .= ", o.rev_user_text AS first_user, o.rev_timestamp AS"
 311+ . " first_time" . $arg . " INNER JOIN $sRevTable AS o"
 312+ . " ON o.rev_id =( SELECT MIN(q.rev_id) FROM $sRevTable"
 313+ . " AS q WHERE q.rev_page = page_id )";
 314+ }
 315+ else
 316+ {
 317+ if($sOrder=='first_time') $sOrder = 'page_id';
 318+ $sSqlSelectFrom .= $arg;
 319+ }
 320+
 321+ $sSqlWhere = ' WHERE 1=1';
 322+ if($iNamespace >= 0)
 323+ $sSqlWhere = ' WHERE page_namespace='.$iNamespace;
 324+
 325+ if($sPrefix!=='')
 326+ {
 327+ // Escape SQL special characters
 328+ $sPrefix = strtr($sPrefix, array('\\'=>'\\\\\\\\',
 329+ ' '=>'\\_', '_'=>'\\_', '%'=>'\\%', '\''=>'\\\''));
 330+ $sSqlWhere .= " AND page_title LIKE BINARY '".$sPrefix."%'";
 331+ }
 332+
 333+ switch($this->get('redirects'))
 334+ {
 335+ case 'only':
 336+ $sSqlWhere .= ' AND page_is_redirect = 1';
 337+ case 'include':
 338+ break;
 339+ case 'exclude':
 340+ default:
 341+ $sSqlWhere .= ' AND page_is_redirect = 0';
 342+ break;
 343+ }
 344+
 345+ $n = 1;
 346+ for($i = 0; $i < $cats; $i++) {
 347+ $sSqlSelectFrom .= " INNER JOIN $categorylinks AS" .
 348+ " c{$n} ON page_id = c{$n}.cl_from AND c{$n}.cl_to=" .
 349+ $dbr->addQuotes( $aCategories[$i]->getDbKey() );
 350+ $n++;
 351+ }
 352+ for($i = 0; $i < $nocats; $i++) {
 353+ $sSqlSelectFrom .= " LEFT OUTER JOIN $categorylinks AS" .
 354+ " c{$n} ON page_id = c{$n}.cl_from AND c{$n}.cl_to=" .
 355+ $dbr->addQuotes( $aExcludeCategories[$i]->getDbKey() );
 356+ $sSqlWhere .= " AND c{$n}.cl_to IS NULL";
 357+ $n++;
 358+ }
 359+
 360+ if(!$bCountMode)
 361+ {
 362+ $sSqlWhere .= " ORDER BY $sOrder ";
 363+ if($this->get('order')=='ascending') $sSqlWhere .= 'ASC';
 364+ else $sSqlWhere .= 'DESC';
 365+ }
 366+ $sSqlWhere .= " LIMIT $start, $count";
 367+
 368+ //DEBUG: output SQL query
 369+ //$output .= 'QUERY: [' . $sSqlSelectFrom . $sSqlWhere . "]<br />";
 370+
 371+ // process the query
 372+ $res = $dbr->query($sSqlSelectFrom . $sSqlWhere);
 373+
 374+ $this->vMarkNew = $dbr->timestamp(time() -
 375+ intval($this->get('newdays',7) * 86400));
 376+
 377+ if($bCountMode)
 378+ {
 379+ if($row = $dbr->fetchObject( $res )) $output .= $row->num_rows;
 380+ else $output .= '0';
 381+ }
 382+ else if(is_null($title))
 383+ {
 384+ while($row = $dbr->fetchObject( $res ))
 385+ {
 386+ $title = Title::makeTitle($row->page_namespace, $row->page_title);
 387+ $output .= $sStartItem;
 388+ $output .= $this->buildOutput($title, $title, $row->rev_timestamp,
 389+ $row->rev_user_text, $row->first_user, $row->first_time);
 390+ $output .= $sEndItem . "\n";
 391+ }
 392+ }
 393+ else
 394+ {
 395+ $output .= $sStartItem;
 396+ if($row = $dbr->fetchObject( $res ))
 397+ {
 398+ $output .= $this->buildOutput(Title::makeTitle($row->page_namespace,
 399+ $row->page_title), $title, $row->rev_timestamp, $row->rev_user_text);
 400+ }
 401+ else
 402+ {
 403+ $output .= $this->buildOutput(NULL, $title, $this->msg('forum_never'));
 404+ }
 405+ $output .= $sEndItem . "\n";
 406+ }
 407+ return $output;
 408+ }
 409+
 410+ // Generates a single line of output.
 411+ function buildOutput($page, $title, $time, $user='', $author='', $made='')
 412+ {
 413+ global $wgLang, $wgUser;
 414+ $sk =& $wgUser->getSkin();
 415+ $tm =& $this->bTableMode;
 416+ $by = $this->msg('forum_by');
 417+ $output = '';
 418+
 419+ if($this->bAddCreationDate)
 420+ {
 421+ if(is_numeric($made)) $made = $wgLang->date($made, true);
 422+ if($page && $this->bLinkHistory && !$this->bAddLastEdit)
 423+ {
 424+ if($this->bEmbedHistory)
 425+ $made = $sk->makeKnownLinkObj($page, $made, 'action=history');
 426+ else
 427+ $made .= ' (' . $sk->makeKnownLinkObj($page,
 428+ wfMsg('hist'), 'action=history') . ')';
 429+ }
 430+ if($tm) $output .= "<td class='forum_created'>$made</td>";
 431+ else if($made) $output = "{$made}: ";
 432+ }
 433+ if($tm) $output .= "<td class='forum_title'>";
 434+
 435+ $text = $query = $props = '';
 436+ if($this->bShowNamespace == true) $text = $title->getEscapedText();
 437+ else $text = htmlspecialchars($title->getText());
 438+ if(($this->sOmit) && strpos($text, $this->sOmit)===0)
 439+ $text = substr($text, strlen($this->sOmit));
 440+ if(is_numeric($time))
 441+ {
 442+ if($this->bTimestamp) $query = 't=' . $time;
 443+ if($time > $this->vMarkNew) $props = " class='forum_new'";
 444+ }
 445+ $output .= $sk->makeKnownLinkObj($title, $text, $query, '', '', $props);
 446+ $text = '';
 447+
 448+ if($this->bAddAuthor)
 449+ {
 450+ $author = Title::newFromText( $author, NS_USER );
 451+ if($author) $author = $sk->makeKnownLinkObj($author,$author->getText());
 452+ if($tm)
 453+ {
 454+ if($this->bCompactAuthor)
 455+ {
 456+ if($author)
 457+ $output .= " <span class='forum_author'>$by {$author}</span>";
 458+ else $output .= " <span class='forum_author'>&nb"."sp;</span>";
 459+ }
 460+ else $output .= "</td><td class='forum_author'>$author";
 461+ }
 462+ else if($author) $output .= " $by $author";
 463+ }
 464+
 465+ if($this->bAddLastEdit)
 466+ {
 467+ if(is_numeric($time)) $time = $wgLang->timeanddate($time, true);
 468+ if($page && $this->bLinkHistory)
 469+ {
 470+ if($this->bEmbedHistory)
 471+ $time = $sk->makeKnownLinkObj($page, $time, 'action=history');
 472+ else
 473+ $time .= ' (' . $sk->makeKnownLinkObj($page,
 474+ wfMsg('hist'), 'action=history') . ')';
 475+ }
 476+ if($tm) $output .= "</td><td class='forum_edited'>$time";
 477+ else $text .= "$time ";
 478+ }
 479+
 480+ if($this->bAddLastEditor)
 481+ {
 482+ $user = Title::newFromText( $user, NS_USER );
 483+ if($user) $user = $sk->makeKnownLinkObj($user, $user->getText());
 484+ if($tm)
 485+ {
 486+ if($this->bCompactEdit)
 487+ {
 488+ if($user)
 489+ $output .= " <span class='forum_editor'>$by {$user}</span>";
 490+ else $output .= " <span class='forum_editor'>&nb"."sp;</span>";
 491+ }
 492+ else $output .= "</td><td class='forum_editor'>$user";
 493+ }
 494+ else if($user) $text .= "$by $user";
 495+ }
 496+ if($tm) $output .= "</td>";
 497+ else if($text) $output .= $this->msg('forum_edited') . " $text";
 498+ return $output;
 499+ }
 500+}
\ No newline at end of file
Property changes on: trunk/extensions/DPLforum/DPLforum.php
___________________________________________________________________
Added: svn:eol-style
1501 + native

Status & tagging log