Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Wikipedia: Mediawiki-CVS

SVN: [29996] branches/ApiEdit_Vodafone/includes

 

 

Wikipedia mediawiki-cvs RSS feed   Index | Next | Previous | View Threaded


catrope at svn

Jan 20, 2008, 10:41 AM

Post #1 of 1 (212 views)
Permalink
SVN: [29996] branches/ApiEdit_Vodafone/includes

Revision: 29996
Author: catrope
Date: 2008-01-20 18:41:22 +0000 (Sun, 20 Jan 2008)

Log Message:
-----------
ApiEdit_Vodafone svnmerge part 3

Modified Paths:
--------------
branches/ApiEdit_Vodafone/includes/AjaxFunctions.php
branches/ApiEdit_Vodafone/includes/Article.php
branches/ApiEdit_Vodafone/includes/CoreParserFunctions.php
branches/ApiEdit_Vodafone/includes/DefaultSettings.php
branches/ApiEdit_Vodafone/includes/Defines.php
branches/ApiEdit_Vodafone/includes/EditPage.php
branches/ApiEdit_Vodafone/includes/ExternalEdit.php
branches/ApiEdit_Vodafone/includes/GlobalFunctions.php
branches/ApiEdit_Vodafone/includes/HTMLCacheUpdate.php
branches/ApiEdit_Vodafone/includes/ImagePage.php
branches/ApiEdit_Vodafone/includes/Linker.php
branches/ApiEdit_Vodafone/includes/MessageCache.php
branches/ApiEdit_Vodafone/includes/Parser.php
branches/ApiEdit_Vodafone/includes/Parser_OldPP.php
branches/ApiEdit_Vodafone/includes/RawPage.php
branches/ApiEdit_Vodafone/includes/SiteConfiguration.php
branches/ApiEdit_Vodafone/includes/Skin.php
branches/ApiEdit_Vodafone/includes/SpecialBlockip.php
branches/ApiEdit_Vodafone/includes/SpecialExport.php
branches/ApiEdit_Vodafone/includes/SpecialIpblocklist.php
branches/ApiEdit_Vodafone/includes/SpecialUndelete.php
branches/ApiEdit_Vodafone/includes/SpecialVersion.php
branches/ApiEdit_Vodafone/includes/SpecialWithoutinterwiki.php
branches/ApiEdit_Vodafone/includes/Title.php
branches/ApiEdit_Vodafone/includes/Wiki.php
branches/ApiEdit_Vodafone/includes/api/ApiBase.php
branches/ApiEdit_Vodafone/includes/api/ApiBlock.php
branches/ApiEdit_Vodafone/includes/api/ApiDelete.php
branches/ApiEdit_Vodafone/includes/api/ApiLogin.php
branches/ApiEdit_Vodafone/includes/api/ApiLogout.php
branches/ApiEdit_Vodafone/includes/api/ApiMain.php
branches/ApiEdit_Vodafone/includes/api/ApiMove.php
branches/ApiEdit_Vodafone/includes/api/ApiProtect.php
branches/ApiEdit_Vodafone/includes/api/ApiQueryAllmessages.php
branches/ApiEdit_Vodafone/includes/api/ApiQueryAllpages.php
branches/ApiEdit_Vodafone/includes/api/ApiQueryImageInfo.php
branches/ApiEdit_Vodafone/includes/api/ApiRollback.php
branches/ApiEdit_Vodafone/includes/api/ApiUnblock.php
branches/ApiEdit_Vodafone/includes/api/ApiUndelete.php
branches/ApiEdit_Vodafone/includes/filerepo/File.php
branches/ApiEdit_Vodafone/includes/filerepo/FileRepo.php
branches/ApiEdit_Vodafone/includes/filerepo/LocalFile.php
branches/ApiEdit_Vodafone/includes/filerepo/LocalRepo.php
branches/ApiEdit_Vodafone/includes/filerepo/RepoGroup.php

Modified: branches/ApiEdit_Vodafone/includes/AjaxFunctions.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/AjaxFunctions.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/AjaxFunctions.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -86,7 +86,7 @@
$term = $wgContLang->ucfirst( $term );
$term_title = Title::newFromText( $term );

- $memckey = wfMemcKey( 'ajaxsearch', md5( $term_title->getFullText() ) );
+ $memckey = $term_title ? wfMemcKey( 'ajaxsearch', md5( $term_title->getFullText() ) ) : wfMemcKey( 'ajaxsearch', md5( $term ) );
$cached = $wgMemc->get($memckey);
if( is_array( $cached ) && $cached['version'] == AJAX_SEARCH_VERSION ) {
$response = new AjaxResponse( $cached['html'] );

Modified: branches/ApiEdit_Vodafone/includes/Article.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Article.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Article.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -1944,7 +1944,7 @@
}

$wgOut->setPagetitle( wfMsg( 'confirmdelete' ) );
-
+
# Better double-check that it hasn't been deleted yet!
$dbw = wfGetDB( DB_MASTER );
$conds = $this->mTitle->pageCond();
@@ -1954,6 +1954,17 @@
return;
}

+ # Hack for big sites
+ $bigHistory = $this->isBigDeletion();
+ if( $bigHistory && !$this->mTitle->userCan( 'bigdelete' ) ) {
+ global $wgLang, $wgDeleteRevisionsLimit;
+ $wgOut->addWikiText( "<div class='error'>\n" .
+ wfMsg( 'delete-toobig',
+ $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) .
+ "</div>\n" );
+ return;
+ }
+
if( $confirm ) {
$this->doDelete( $reason );
if( $wgRequest->getCheck( 'wpWatch' ) ) {
@@ -1972,10 +1983,41 @@
if( $hasHistory && !$confirm ) {
$skin=$wgUser->getSkin();
$wgOut->addHTML( '<strong>' . wfMsg( 'historywarning' ) . ' ' . $skin->historyLink() . '</strong>' );
+ if( $bigHistory ) {
+ global $wgLang, $wgDeleteRevisionsLimit;
+ $wgOut->addWikiText( "<div class='error'>\n" .
+ wfMsg( 'delete-warning-toobig',
+ $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) .
+ "</div>\n" );
+ }
}

return $this->confirmDelete( '', $reason );
}
+
+ /**
+ * @return bool whether or not the page surpasses $wgDeleteRevisionsLimit revisions
+ */
+ function isBigDeletion() {
+ global $wgDeleteRevisionsLimit;
+ if( $wgDeleteRevisionsLimit ) {
+ $revCount = $this->estimateRevisionCount();
+ return $revCount > $wgDeleteRevisionsLimit;
+ }
+ return false;
+ }
+
+ /**
+ * @return int approximate revision count
+ */
+ function estimateRevisionCount() {
+ $dbr = wfGetDB();
+ // For an exact count...
+ //return $dbr->selectField( 'revision', 'COUNT(*)',
+ // array( 'rev_page' => $this->getId() ), __METHOD__ );
+ return $dbr->estimateRowCount( 'revision', '*',
+ array( 'rev_page' => $this->getId() ), __METHOD__ );
+ }

/**
* Get the last N authors
@@ -2267,17 +2309,16 @@
* @param string $fromP - Name of the user whose edits to rollback.
* @param string $summary - Custom summary. Set to default summary if empty.
* @param string $token - Rollback token.
- * @param bool $bot - If true, mark all reverted edits as bot.
+ * @param bool $bot - If true, mark all reverted edits as bot.
*
* @param array $resultDetails contains result-specific array of additional values
* 'alreadyrolled' : 'current' (rev)
* success : 'summary' (str), 'current' (rev), 'target' (rev)
*
- * @return array of errors, each error formatted as array(messagekey, param1, param2, ...).
- * On success, the array is empty. This array can also be passed to OutputPage::showPermissionsErrorPage().
- * NOTE: If the user is blocked, 'blocked' is passed as a message, but it doesn't exist. Be sure to check
- * it before calling showPermissionsErrorPage(). The same is true for 'actionthrottledtext', which
- * is passed if the rate limit is passed.
+ * @return array of errors, each error formatted as
+ * array(messagekey, param1, param2, ...).
+ * On success, the array is empty. This array can also be passed to
+ * OutputPage::showPermissionsErrorPage().
*/
public function doRollback( $fromP, $summary, $token, $bot, &$resultDetails ) {
global $wgUser;
@@ -2292,9 +2333,6 @@
if ( $wgUser->pingLimiter('rollback') || $wgUser->pingLimiter() ) {
$errors[] = array( 'actionthrottledtext' );
}
- if ( $wgUser->isBlocked() )
- $errors[] = array( 'blocked' );
-
# If there were errors, bail out now
if(!empty($errors))
return $errors;
@@ -2303,15 +2341,22 @@
}

/**
- * Backend implementation of doRollback(), please refer there for parameter and return value documentation
+ * Backend implementation of doRollback(), please refer there for parameter
+ * and return value documentation
*
- * NOTE: This function does NOT check ANY permissions, it just commits the rollback to the DB.
- * Therefore, you should only call this function directly if you really know what you're doing. If you don't, use doRollback() instead
+ * NOTE: This function does NOT check ANY permissions, it just commits the
+ * rollback to the DB Therefore, you should only call this function direct-
+ * ly if you want to use custom permissions checks. If you don't, use
+ * doRollback() instead.
*/
public function commitRollback($fromP, $summary, $bot, &$resultDetails) {
- global $wgUseRCPatrol;
+ global $wgUseRCPatrol, $wgUser;
$dbw = wfGetDB( DB_MASTER );

+ if( wfReadOnly() ) {
+ return array( array( 'readonlytext' ) );
+ }
+
# Get the last editor
$current = Revision::newFromTitle( $this->mTitle );
if( is_null( $current ) ) {
@@ -2411,19 +2456,34 @@
$wgRequest->getBool( 'bot' ),
$details
);
-
- if(in_array(array('blocked'), $result)) {
+
+ if( in_array( array( 'blocked' ), $result ) ) {
$wgOut->blockedPage();
return;
}
- if(in_array(array('actionthrottledtext'), $result)) {
+ if( in_array( array( 'actionthrottledtext' ), $result ) ) {
$wgOut->rateLimited();
return;
}
- if(!empty($result)) {
- $wgOut->showPermissionsErrorPage( $result );
+ # Display permissions errors before read-only message -- there's no
+ # point in misleading the user into thinking the inability to rollback
+ # is only temporary.
+ if( !empty($result) && $result !== array( array('readonlytext') ) ) {
+ # array_diff is completely broken for arrays of arrays, sigh. Re-
+ # move any 'readonlytext' error manually.
+ $out = array();
+ foreach( $result as $error ) {
+ if( $error != array( 'readonlytext' ) ) {
+ $out []= $error;
+ }
+ }
+ $wgOut->showPermissionsErrorPage( $out );
return;
}
+ if( $result == array( array('readonlytext') ) ) {
+ $wgOut->readOnlyPage();
+ return;
+ }

$current = $details['current'];
$target = $details['target'];
@@ -2496,7 +2556,7 @@
* @param $changed Whether or not the content actually changed
*/
function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange, $newid, $changed = true ) {
- global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgParser;
+ global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgParser, $wgEnableParserCache;

wfProfileIn( __METHOD__ );

@@ -2511,8 +2571,10 @@
}

# Save it to the parser cache
- $parserCache =& ParserCache::singleton();
- $parserCache->save( $editInfo->output, $this, $wgUser );
+ if ( $wgEnableParserCache ) {
+ $parserCache =& ParserCache::singleton();
+ $parserCache->save( $editInfo->output, $this, $wgUser );
+ }

# Update the links tables
$u = new LinksUpdate( $this->mTitle, $editInfo->output );
@@ -2896,9 +2958,11 @@
global $wgDeferredUpdateList, $wgUseFileCache;

// Invalidate caches of articles which include this page
- $update = new HTMLCacheUpdate( $title, 'templatelinks' );
- $wgDeferredUpdateList[] = $update;
+ $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'templatelinks' );

+ // Invalidate the caches of all pages which redirect here
+ $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'redirect' );
+
# Purge squid for this page only
$title->purgeSquid();

@@ -3123,7 +3187,7 @@
* @param bool $cache
*/
public function outputWikiText( $text, $cache = true ) {
- global $wgParser, $wgUser, $wgOut;
+ global $wgParser, $wgUser, $wgOut, $wgEnableParserCache;

$popts = $wgOut->parserOptions();
$popts->setTidy(true);
@@ -3132,7 +3196,7 @@
$popts, true, true, $this->getRevIdFetched() );
$popts->setTidy(false);
$popts->enableLimitReport( false );
- if ( $cache && $this && $parserOutput->getCacheTime() != -1 ) {
+ if ( $wgEnableParserCache && $cache && $this && $parserOutput->getCacheTime() != -1 ) {
$parserCache =& ParserCache::singleton();
$parserCache->save( $parserOutput, $this, $wgUser );
}

Modified: branches/ApiEdit_Vodafone/includes/CoreParserFunctions.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/CoreParserFunctions.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/CoreParserFunctions.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -221,6 +221,13 @@
return '';
}
$tagName = strtolower( trim( $frame->expand( array_shift( $args ) ) ) );
+
+ if ( count( $args ) ) {
+ $inner = $frame->expand( array_shift( $args ) );
+ } else {
+ $inner = null;
+ }
+
$stripList = $parser->getStripList();
if ( !in_array( $tagName, $stripList ) ) {
return '<span class="error">' .
@@ -228,37 +235,28 @@
'</span>';
}

- $lastNumberedNode = false;
$attributes = array();
foreach ( $args as $arg ) {
if ( !$xpath ) {
$xpath = new DOMXPath( $arg->ownerDocument );
}
$names = $xpath->query( 'name', $arg );
- if ( $names->item( 0 )->hasAttributes() ) {
- $lastNumberedNode = $arg;
- } else {
+ if ( !$names->item( 0 )->hasAttributes() ) {
$name = $frame->expand( $names->item( 0 ), PPFrame::STRIP_COMMENTS );
- if ( preg_match( '/^\d+$/', $name ) ) {
- // For = suppression syntax {{#tag|thing|1=2=3=4}}
- $lastNumberedNode = $arg;
- } else {
- $values = $xpath->query( 'value', $arg );
- $attributes[$name] = trim( $frame->expand( $values->item( 0 ) ) );
+ $values = $xpath->query( 'value', $arg );
+ $value = trim( $frame->expand( $values->item( 0 ) ) );
+ if ( preg_match( '/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m ) ) {
+ $value = isset( $m[1] ) ? $m[1] : '';
}
- }
+ $attributes[$name] = $value;
+ }
}

- if ( !$lastNumberedNode ) {
- $inner = null;
- } else {
- $values = $xpath->query( 'value', $lastNumberedNode );
- $inner = $frame->expand( $values->item( 0 ) );
- }
$params = array(
'name' => $tagName,
'inner' => $inner,
- 'attributes' => $attributes
+ 'attributes' => $attributes,
+ 'close' => "</$tagName>",
);
return $parser->extensionSubstitution( $params, $frame );
}

Modified: branches/ApiEdit_Vodafone/includes/DefaultSettings.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/DefaultSettings.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/DefaultSettings.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -157,6 +157,7 @@
$wgHashedUploadDirectory = true;
$wgLogo = false; /// defaults to "{$wgStylePath}/common/images/wiki.png"
$wgFavicon = '/favicon.ico';
+$wgAppleTouchIcon = false; /// This one'll actually default to off. For iPhone and iPod Touch web app bookmarks
$wgMathPath = false; /// defaults to "{$wgUploadPath}/math"
$wgMathDirectory = false; /// defaults to "{$wgUploadDirectory}/math"
$wgTmpDirectory = false; /// defaults to "{$wgUploadDirectory}/tmp"
@@ -460,7 +461,12 @@
*/
$wgRepositoryBaseUrl="http://commons.wikimedia.org/wiki/Image:";

+/**
+ * Experimental feature still under debugging.
+ */
+$wgFileRedirects = false;

+
#
# Email settings
#
@@ -1094,6 +1100,7 @@
$wgGroupPermissions['sysop']['block'] = true;
$wgGroupPermissions['sysop']['createaccount'] = true;
$wgGroupPermissions['sysop']['delete'] = true;
+$wgGroupPermissions['sysop']['bigdelete'] = true; // can be separately configured for pages with > $wgDeleteRevisionsLimit revs
$wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text
$wgGroupPermissions['sysop']['undelete'] = true;
$wgGroupPermissions['sysop']['editinterface'] = true;
@@ -1242,6 +1249,12 @@
*/
$wgAddGroups = $wgRemoveGroups = array();

+/**
+ * Optional to restrict deletion of pages with higher revision counts
+ * to users with the 'bigdelete' permission. (Default given to sysops.)
+ */
+$wgDeleteRevisionsLimit = 0;
+
# Proxy scanner settings
#


Modified: branches/ApiEdit_Vodafone/includes/Defines.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Defines.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Defines.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -262,13 +262,14 @@

# Hook support constants
define( 'MW_SUPPORTS_EDITFILTERMERGED', 1 );
+define( 'MW_SUPPORTS_PARSERFIRSTCALLINIT', 1 );

# Allowed values for Parser::$mOutputType
# Parameter to Parser::startExternalParse().
define( 'OT_HTML', 1 );
define( 'OT_WIKI', 2 );
-define( 'OT_MSG' , 3 );
-define( 'OT_PREPROCESS', 4 );
+define( 'OT_PREPROCESS', 3 );
+define( 'OT_MSG' , 3 ); // b/c alias for OT_PREPROCESS

# Flags for Parser::setFunctionHook
define( 'SFH_NO_HASH', 1 );
@@ -282,4 +283,4 @@
define( 'APCOND_EDITCOUNT', 1 );
define( 'APCOND_AGE', 2 );
define( 'APCOND_EMAILCONFIRMED', 3 );
-define( 'APCOND_INGROUPS', 4 );
\ No newline at end of file
+define( 'APCOND_INGROUPS', 4 );

Modified: branches/ApiEdit_Vodafone/includes/EditPage.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/EditPage.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/EditPage.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -38,6 +38,8 @@
const AS_OK = 230;
const AS_END = 231;
const AS_SPAM_ERROR = 232;
+ const AS_IMAGE_REDIRECT_ANON = 233;
+ const AS_IMAGE_REDIRECT_LOGGED = 234;

var $mArticle;
var $mTitle;
@@ -699,6 +701,17 @@
return self::AS_HOOK_ERROR;
}

+ # Check image redirect
+ if ( $wgTitle->getNamespace() == NS_IMAGE &&
+ Title::newFromRedirect( $this->textbox1 ) instanceof Title &&
+ !$wgUser->isAllowed( 'upload' ) ) {
+ if( $wgUser->isAnon() ) {
+ return self::AS_IMAGE_REDIRECT_ANON;
+ } else {
+ return self::AS_IMAGE_REDIRECT_LOGGED;
+ }
+ }
+
# Reintegrate metadata
if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
$this->mMetaData = '' ;
@@ -2196,6 +2209,10 @@
$this->blockedPage();
return false;

+ case self::AS_IMAGE_REDIRECT_ANON:
+ $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
+ return false;
+
case self::AS_READ_ONLY_PAGE_ANON:
$this->userNotLoggedInPage();
return false;
@@ -2216,6 +2233,10 @@
case self::AS_BLANK_ARTICLE:
$wgOut->redirect( $wgTitle->getFullURL() );
return false;
+
+ case self::AS_IMAGE_REDIRECT_LOGGED:
+ $wgOut->permissionRequired( 'upload' );
+ return false;
}
}
}

Modified: branches/ApiEdit_Vodafone/includes/ExternalEdit.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/ExternalEdit.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/ExternalEdit.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -34,6 +34,7 @@
$name=$this->mTitle->getText();
$pos=strrpos($name,".")+1;
header ( "Content-type: application/x-external-editor; charset=".$this->mCharset );
+ header( "Cache-control: no-cache" );

# $type can be "Edit text", "Edit file" or "Diff text" at the moment
# See the protocol specifications at [[m:Help:External editors/Tech]] for

Modified: branches/ApiEdit_Vodafone/includes/GlobalFunctions.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/GlobalFunctions.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/GlobalFunctions.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -427,24 +427,12 @@
function wfMsgGetKey( $key, $useDB, $forContent = false, $transform = true ) {
global $wgParser, $wgContLang, $wgMessageCache, $wgLang;

- /* <Vyznev> btw, is all that code in wfMsgGetKey() that check
- * if the message cache exists of not really necessary, or is
- * it just paranoia?
- * <TimStarling> Vyznev: it's probably not necessary
- * <TimStarling> I think I wrote it in an attempt to report DB
- * connection errors properly
- * <TimStarling> but eventually we gave up on using the
- * message cache for that and just hard-coded the strings
- * <TimStarling> it may have other uses, it's not mere paranoia
- */
-
- if ( is_object( $wgMessageCache ) )
- $transstat = $wgMessageCache->getTransform();
-
+ # If $wgMessageCache isn't initialised yet, try to return something sensible.
if( is_object( $wgMessageCache ) ) {
- if ( ! $transform )
- $wgMessageCache->disableTransform();
$message = $wgMessageCache->get( $key, $useDB, $forContent );
+ if ( $transform ) {
+ $message = $wgMessageCache->transform( $message );
+ }
} else {
if( $forContent ) {
$lang = &$wgContLang;
@@ -456,22 +444,13 @@
# ISSUE: Should we try to handle "message/lang" here too?
$key = str_replace( ' ' , '_' , $wgContLang->lcfirst( $key ) );

- wfSuppressWarnings();
if( is_object( $lang ) ) {
$message = $lang->getMessage( $key );
} else {
$message = false;
}
- wfRestoreWarnings();
-
- if ( $transform && strstr( $message, '{{' ) !== false ) {
- $message = $wgParser->transformMsg($message, $wgMessageCache->getParserOptions() );
- }
}

- if ( is_object( $wgMessageCache ) && ! $transform )
- $wgMessageCache->setTransform( $transstat );
-
return $message;
}


Modified: branches/ApiEdit_Vodafone/includes/HTMLCacheUpdate.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/HTMLCacheUpdate.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/HTMLCacheUpdate.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -25,6 +25,7 @@
{
public $mTitle, $mTable, $mPrefix;
public $mRowsPerJob, $mRowsPerQuery;
+ public $mResult;

function __construct( $titleTo, $table ) {
global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery;
@@ -40,15 +41,14 @@
$cond = $this->getToCondition();
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( $this->mTable, $this->getFromField(), $cond, __METHOD__ );
- $resWrap = new ResultWrapper( $dbr, $res );
+ $this->mResult = $res;
if ( $dbr->numRows( $res ) != 0 ) {
if ( $dbr->numRows( $res ) > $this->mRowsPerJob ) {
- $this->insertJobs( $resWrap );
+ $this->insertJobs( $res );
} else {
- $this->invalidateIDs( $resWrap );
+ $this->invalidateIDs( $res );
}
}
- $dbr->freeResult( $res );
}

function insertJobs( ResultWrapper $res ) {
@@ -87,6 +87,7 @@
'imagelinks' => 'il',
'categorylinks' => 'cl',
'templatelinks' => 'tl',
+ 'redirect' => 'rd',

# Not needed
# 'externallinks' => 'el',
@@ -107,17 +108,15 @@
}

function getToCondition() {
+ $prefix = $this->getPrefix();
switch ( $this->mTable ) {
case 'pagelinks':
+ case 'templatelinks':
+ case 'redirect':
return array(
- 'pl_namespace' => $this->mTitle->getNamespace(),
- 'pl_title' => $this->mTitle->getDBkey()
+ "{$prefix}_namespace" => $this->mTitle->getNamespace(),
+ "{$prefix}_title" => $this->mTitle->getDBkey()
);
- case 'templatelinks':
- return array(
- 'tl_namespace' => $this->mTitle->getNamespace(),
- 'tl_title' => $this->mTitle->getDBkey()
- );
case 'imagelinks':
return array( 'il_to' => $this->mTitle->getDBkey() );
case 'categorylinks':
@@ -218,7 +217,6 @@
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( $this->table, $fromField, $conds, __METHOD__ );
$update->invalidateIDs( new ResultWrapper( $dbr, $res ) );
- $dbr->freeResult( $res );

return true;
}

Modified: branches/ApiEdit_Vodafone/includes/ImagePage.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/ImagePage.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/ImagePage.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -411,25 +411,23 @@

$sk = $wgUser->getSkin();

- $line = $this->img->nextHistoryLine();
-
- if ( $line ) {
+ if ( $this->img->exists() ) {
$list = new ImageHistoryList( $sk, $this->img );
- $file = $this->repo->newFileFromRow( $line );
+ $file = $this->img;
$dims = $file->getDimensionsString();
$s = $list->beginImageHistoryList() .
- $list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp),
- $this->mTitle->getDBkey(), $line->img_user,
- $line->img_user_text, $line->img_size, $line->img_description,
+ $list->imageHistoryLine( true, wfTimestamp(TS_MW, $file->getTimestamp()),
+ $this->mTitle->getDBkey(), $file->getUser('id'),
+ $file->getUser('text'), $file->getSize(), $file->getDescription(),
$dims
);

- while ( $line = $this->img->nextHistoryLine() ) {
- $file = $this->repo->newFileFromRow( $line );
+ $hist = $this->img->getHistory();
+ foreach( $hist as $file ) {
$dims = $file->getDimensionsString();
- $s .= $list->imageHistoryLine( false, $line->oi_timestamp,
- $line->oi_archive_name, $line->oi_user,
- $line->oi_user_text, $line->oi_size, $line->oi_description,
+ $s .= $list->imageHistoryLine( false, wfTimestamp(TS_MW, $file->getTimestamp()),
+ $file->getArchiveName(), $file->getUser('id'),
+ $file->getUser('text'), $file->getSize(), $file->getDescription(),
$dims
);
}

Modified: branches/ApiEdit_Vodafone/includes/Linker.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Linker.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Linker.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -723,6 +723,10 @@
$upload = SpecialPage::getTitleFor( 'Upload' );
if( $text == '' )
$text = htmlspecialchars( $title->getPrefixedText() );
+ $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title );
+ if( $redir ) {
+ return $this->makeKnownLinkObj( $title, $text, $query, $trail, $prefix );
+ }
$q = 'wpDestFile=' . $title->getPartialUrl();
if( $query != '' )
$q .= '&' . $query;

Modified: branches/ApiEdit_Vodafone/includes/MessageCache.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/MessageCache.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/MessageCache.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -500,9 +500,6 @@
if( $message === false ) {
return '&lt;' . htmlspecialchars($key) . '&gt;';
}
-
- # Replace brace tags
- $message = $this->transform( $message );
return $message;
}

@@ -584,12 +581,11 @@
# Clone it and store it
$this->mParser = clone $wgParser;
}
- if ( !$this->mDisableTransform && $this->mParser ) {
+ if ( $this->mParser ) {
if( strpos( $message, '{{' ) !== false ) {
$popts = $this->getParserOptions();
- if ( $interface ) { $popts->setInterfaceMessage(true); }
+ $popts->setInterfaceMessage( $interface );
$message = $this->mParser->transformMsg( $message, $popts );
- if ( $interface ) { $popts->setInterfaceMessage(false); }
}
}
return $message;
@@ -597,11 +593,13 @@

function disable() { $this->mDisable = true; }
function enable() { $this->mDisable = false; }
- function disableTransform() { $this->mDisableTransform = true; }
- function enableTransform() { $this->mDisableTransform = false; }
- function setTransform( $x ) { $this->mDisableTransform = $x; }
- function getTransform() { return $this->mDisableTransform; }

+ /** @deprecated */
+ function disableTransform() {}
+ function enableTransform() {}
+ function setTransform( $x ) {}
+ function getTransform() { return false; }
+
/**
* Add a message to the cache
*

Modified: branches/ApiEdit_Vodafone/includes/Parser.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Parser.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Parser.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -15,15 +15,17 @@
* (which in turn the browser understands, and can display).
*
* <pre>
- * There are four main entry points into the Parser class:
+ * There are five main entry points into the Parser class:
* parse()
* produces HTML output
* preSaveTransform().
* produces altered wiki markup.
- * transformMsg()
- * performs brace substitution on MediaWiki messages
* preprocess()
* removes HTML comments and expands templates
+ * cleanSig()
+ * Cleans a signature before saving it to preferences
+ * extractSections()
+ * Extracts sections from an article for section editing
*
* Globals used:
* objects: $wgLang, $wgContLang
@@ -126,6 +128,7 @@
if ( !$this->mFirstCall ) {
return;
}
+ $this->mFirstCall = false;

wfProfileIn( __METHOD__ );
global $wgAllowDisplayTitle, $wgAllowSlowParserFunctions;
@@ -174,7 +177,8 @@
}

$this->initialiseVariables();
- $this->mFirstCall = false;
+
+ wfRunHooks( 'ParserFirstCallInit', array( &$this ) );
wfProfileOut( __METHOD__ );
}

@@ -245,12 +249,27 @@
$this->ot = array(
'html' => $ot == OT_HTML,
'wiki' => $ot == OT_WIKI,
- 'msg' => $ot == OT_MSG,
'pre' => $ot == OT_PREPROCESS,
);
}

/**
+ * Set the context title
+ */
+ function setTitle( $t ) {
+ if ( !$t || $t instanceof FakeTitle ) {
+ $t = Title::newFromText( 'NO TITLE' );
+ }
+ if ( strval( $t->getFragment() ) !== '' ) {
+ # Strip the fragment to avoid various odd effects
+ $this->mTitle = clone $t;
+ $this->mTitle->setFragment( '' );
+ } else {
+ $this->mTitle = $t;
+ }
+ }
+
+ /**
* Accessor for mUniqPrefix.
*
* @public
@@ -296,7 +315,7 @@
}

$this->mOptions = $options;
- $this->mTitle =& $title;
+ $this->setTitle( $title );
$oldRevisionId = $this->mRevisionId;
$oldRevisionTimestamp = $this->mRevisionTimestamp;
if( $revid !== null ) {
@@ -393,6 +412,7 @@
if ( $this->mOptions->getEnableLimitReport() ) {
$max = $this->mOptions->getMaxIncludeSize();
$limitReport =
+ "NewPP limit report\n" .
"Preprocessor node count: {$this->mPPNodeCount}/{$this->mOptions->mMaxPPNodeCount}\n" .
"Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .
"Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n";
@@ -430,16 +450,13 @@
$this->clearState();
$this->setOutputType( OT_PREPROCESS );
$this->mOptions = $options;
- $this->mTitle = $title;
+ $this->setTitle( $title );
if( $revid !== null ) {
$this->mRevisionId = $revid;
}
wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
$text = $this->replaceVariables( $text );
- if ( $this->mOptions->getRemoveComments() ) {
- $text = Sanitizer::removeHTMLcomments( $text );
- }
$text = $this->mStripState->unstripBoth( $text );
wfProfileOut( __METHOD__ );
return $text;
@@ -2565,7 +2582,7 @@
* self::PTD_FOR_INCLUSION Handle <noinclude>/<includeonly> as if the text is being
* included. Default is to assume a direct page view.
*
- * The generated DOM tree must depend only on the input text, the flags, and $this->ot['msg'].
+ * The generated DOM tree must depend only on the input text and the flags.
* The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
*
* Any flag added to the $flags parameter here, or any other parameter liable to cause a
@@ -2582,47 +2599,24 @@
wfProfileIn( __METHOD__ );
wfProfileIn( __METHOD__.'-makexml' );

- static $msgRules, $normalRules, $inclusionSupertags, $nonInclusionSupertags;
- if ( !$msgRules ) {
- $msgRules = array(
- '{' => array(
- 'end' => '}',
- 'names' => array(
- 2 => 'template',
- ),
- 'min' => 2,
- 'max' => 2,
+ $rules = array(
+ '{' => array(
+ 'end' => '}',
+ 'names' => array(
+ 2 => 'template',
+ 3 => 'tplarg',
),
- '[' => array(
- 'end' => ']',
- 'names' => array( 2 => null ),
- 'min' => 2,
- 'max' => 2,
- )
- );
- $normalRules = array(
- '{' => array(
- 'end' => '}',
- 'names' => array(
- 2 => 'template',
- 3 => 'tplarg',
- ),
- 'min' => 2,
- 'max' => 3,
- ),
- '[' => array(
- 'end' => ']',
- 'names' => array( 2 => null ),
- 'min' => 2,
- 'max' => 2,
- )
- );
- }
- if ( $this->ot['msg'] ) {
- $rules = $msgRules;
- } else {
- $rules = $normalRules;
- }
+ 'min' => 2,
+ 'max' => 3,
+ ),
+ '[' => array(
+ 'end' => ']',
+ 'names' => array( 2 => null ),
+ 'min' => 2,
+ 'max' => 2,
+ )
+ );
+
$forInclusion = $flags & self::PTD_FOR_INCLUSION;

$xmlishElements = $this->getStripList();
@@ -2644,19 +2638,18 @@
// Use "A" modifier (anchored) instead of "^", because ^ doesn't work with an offset
$elementsRegex = "~($xmlishRegex)(?:\s|\/>|>)|(!--)~iA";

- $stack = array(); # Stack of unclosed parentheses
- $stackIndex = -1; # Stack read pointer
+ $stack = new PPDStack;

- $searchBase = implode( '', array_keys( $rules ) ) . '<';
+ $searchBase = '[.{<';
$revText = strrev( $text ); // For fast reverse searches

$i = 0; # Input pointer, starts out pointing to a pseudo-newline before the start
- $topAccum = '<root>'; # Top level text accumulator
- $accum =& $topAccum; # Current text accumulator
+ $accum =& $stack->getAccum(); # Current text accumulator
+ $accum = '<root>';
$findEquals = false; # True to find equals signs in arguments
- $findHeading = false; # True to look at LF characters for possible headings
$findPipe = false; # True to take notice of pipe characters
$headingIndex = 1;
+ $inHeading = false; # True if $i is inside a possible heading
$noMoreGT = false; # True if there are no more greater-than (>) signs right of $i
$findOnlyinclude = $enableOnlyinclude; # True to ignore all input up to the next <onlyinclude>
$fakeLineStart = true; # Do a line-start run without outputting an LF character
@@ -2682,21 +2675,29 @@
} else {
# Find next opening brace, closing brace or pipe
$search = $searchBase;
- if ( $stackIndex == -1 ) {
+ if ( $stack->top === false ) {
$currentClosing = '';
- // Look for headings only at the top stack level
- // Among other things, this resolves the ambiguity between =
- // for headings and = for template arguments
- $search .= "\n";
} else {
- $currentClosing = $stack[$stackIndex]['close'];
+ $currentClosing = $stack->top->close;
$search .= $currentClosing;
}
if ( $findPipe ) {
$search .= '|';
}
if ( $findEquals ) {
+ // First equals will be for the template
$search .= '=';
+ } else {
+ // Look for headings
+ // We can't look for headings when $findEquals is true, because the ambiguity
+ // between template name/value separators and heading starts would be unresolved
+ // until the closing double-brace is found. This would mean either infinite
+ // backtrack, or creating and updating two separate tree structures until the
+ // end of the ambiguity -- one tree structure assuming a heading, and the other
+ // assuming a template argument.
+ //
+ // Easier to just break some section edit links.
+ $search .= "\n";
}
$rule = null;
# Output literal section, advance input counter
@@ -2723,10 +2724,10 @@
} elseif ( $curChar == '<' ) {
$found = 'angle';
} elseif ( $curChar == "\n" ) {
- if ( $stackIndex == -1 ) {
+ if ( $inHeading ) {
+ $found = 'line-end';
+ } else {
$found = 'line-start';
- } else {
- $found = 'line-end';
}
} elseif ( $curChar == $currentClosing ) {
$found = 'close';
@@ -2792,8 +2793,8 @@
$accum = substr( $accum, 0, -$wsLength );
}
// Do a line-start run next time to look for headings after the comment,
- // but only if stackIndex=-1, because headings don't exist at deeper levels.
- if ( $stackIndex == -1 ) {
+ // but only if stack->top===false, because headings don't exist at deeper levels.
+ if ( $stack->top === false ) {
$fakeLineStart = true;
}
} else {
@@ -2890,27 +2891,32 @@
'parts' => array( str_repeat( '=', $count ) ),
'startPos' => $i,
'count' => $count );
- $stack[++$stackIndex] = $piece;
+ $stack->push( $piece );
+ $accum =& $stack->getAccum();
+ extract( $stack->getFlags() );
$i += $count;
- $accum =& $stack[$stackIndex]['parts'][0];
- $findPipe = false;
}
}

elseif ( $found == 'line-end' ) {
- $piece = $stack[$stackIndex];
+ $piece = $stack->top;
// A heading must be open, otherwise \n wouldn't have been in the search list
- assert( $piece['open'] == "\n" );
- assert( $stackIndex == 0 );
+ assert( $piece->open == "\n" );
// Search back through the input to see if it has a proper close
// Do this using the reversed string since the other solutions (end anchor, etc.) are inefficient
$m = false;
- $count = $piece['count'];
- if ( preg_match( "/\s*(={{$count}})/A", $revText, $m, 0, strlen( $text ) - $i ) ) {
- if ( $i - strlen( $m[0] ) == $piece['startPos'] ) {
+ $count = $piece->count;
+ if ( preg_match( "/\s*(=+)/A", $revText, $m, 0, strlen( $text ) - $i ) ) {
+ if ( $i - strlen( $m[0] ) == $piece->startPos ) {
// This is just a single string of equals signs on its own line
- // Divide by two and round down to create start and end delimiters
- $count = intval( $count / 2 );
+ // Replicate the doHeadings behaviour /={count}(.+)={count}/
+ // First find out how many equals signs there really are (don't stop at 6)
+ $count = strlen( $m[1] );
+ if ( $count < 3 ) {
+ $count = 0;
+ } else {
+ $count = min( 6, intval( ( $count - 1 ) / 2 ) );
+ }
} else {
$count = min( strlen( $m[1] ), $count );
}
@@ -2927,12 +2933,9 @@
$element = $accum;
}
// Unwind the stack
- // Headings can only occur on the top level, so this is a bit simpler than the
- // generic stack unwind operation in the close case
- unset( $stack[$stackIndex--] );
- $accum =& $topAccum;
- $findEquals = false;
- $findPipe = false;
+ $stack->pop();
+ $accum =& $stack->getAccum();
+ extract( $stack->getFlags() );

// Append the result to the enclosing accumulator
$accum .= $element;
@@ -2959,11 +2962,9 @@
'lineStart' => ($i > 0 && $text[$i-1] == "\n"),
);

- $stackIndex ++;
- $stack[$stackIndex] = $piece;
- $accum =& $stack[$stackIndex]['parts'][0];
- $findEquals = false;
- $findPipe = true;
+ $stack->push( $piece );
+ $accum =& $stack->getAccum();
+ extract( $stack->getFlags() );
} else {
# Add literal brace(s)
$accum .= htmlspecialchars( str_repeat( $curChar, $count ) );
@@ -2972,15 +2973,15 @@
}

elseif ( $found == 'close' ) {
- $piece = $stack[$stackIndex];
+ $piece = $stack->top;
# lets check if there are enough characters for closing brace
- $maxCount = $piece['count'];
+ $maxCount = $piece->count;
$count = strspn( $text, $curChar, $i, $maxCount );

# check for maximum matching characters (if there are 5 closing
# characters, we will probably need only 3 - depending on the rules)
$matchingCount = 0;
- $rule = $rules[$piece['open']];
+ $rule = $rules[$piece->open];
if ( $count > $rule['max'] ) {
# The specified maximum exists in the callback array, unless the caller
# has made an error
@@ -3005,19 +3006,19 @@
$name = $rule['names'][$matchingCount];
if ( $name === null ) {
// No element, just literal text
- $element = str_repeat( $piece['open'], $matchingCount ) .
- implode( '|', $piece['parts'] ) .
+ $element = str_repeat( $piece->open, $matchingCount ) .
+ implode( '|', $piece->parts ) .
str_repeat( $rule['end'], $matchingCount );
} else {
# Create XML element
# Note: $parts is already XML, does not need to be encoded further
- $parts = $piece['parts'];
+ $parts = $piece->parts;
$title = $parts[0];
unset( $parts[0] );

# The invocation is at the start of the line if lineStart is set in
# the stack, and all opening brackets are used up.
- if ( $maxCount == $matchingCount && !empty( $piece['lineStart'] ) ) {
+ if ( $maxCount == $matchingCount && !empty( $piece->lineStart ) ) {
$attr = ' lineStart="1"';
} else {
$attr = '';
@@ -3027,8 +3028,8 @@
$element .= "<title>$title</title>";
$argIndex = 1;
foreach ( $parts as $partIndex => $part ) {
- if ( isset( $piece['eqpos'][$partIndex] ) ) {
- $eqpos = $piece['eqpos'][$partIndex];
+ if ( isset( $piece->eqpos[$partIndex] ) ) {
+ $eqpos = $piece->eqpos[$partIndex];
$argName = substr( $part, 0, $eqpos );
$argValue = substr( $part, $eqpos + 1 );
$element .= "<part><name>$argName</name>=<value>$argValue</value></part>";
@@ -3044,84 +3045,73 @@
$i += $matchingCount;

# Unwind the stack
- unset( $stack[$stackIndex--] );
- if ( $stackIndex == -1 ) {
- $accum =& $topAccum;
- $findEquals = false;
- $findPipe = false;
- } else {
- $partCount = count( $stack[$stackIndex]['parts'] );
- $accum =& $stack[$stackIndex]['parts'][$partCount - 1];
- $findPipe = $stack[$stackIndex]['open'] != "\n";
- $findEquals = $findPipe && $partCount > 1
- && !isset( $stack[$stackIndex]['eqpos'][$partCount - 1] );
- }
+ $stack->pop();
+ $accum =& $stack->getAccum();

# Re-add the old stack element if it still has unmatched opening characters remaining
- if ($matchingCount < $piece['count']) {
- $piece['parts'] = array( '' );
- $piece['count'] -= $matchingCount;
- $piece['eqpos'] = array();
+ if ($matchingCount < $piece->count) {
+ $piece->parts = array( '' );
+ $piece->count -= $matchingCount;
+ $piece->eqpos = array();
# do we still qualify for any callback with remaining count?
- $names = $rules[$piece['open']]['names'];
+ $names = $rules[$piece->open]['names'];
$skippedBraces = 0;
$enclosingAccum =& $accum;
- while ( $piece['count'] ) {
- if ( array_key_exists( $piece['count'], $names ) ) {
- $stackIndex++;
- $stack[$stackIndex] = $piece;
- $accum =& $stack[$stackIndex]['parts'][0];
- $findEquals = true;
- $findPipe = true;
+ while ( $piece->count ) {
+ if ( array_key_exists( $piece->count, $names ) ) {
+ $stack->push( $piece );
+ $accum =& $stack->getAccum();
break;
}
- --$piece['count'];
+ --$piece->count;
$skippedBraces ++;
}
- $enclosingAccum .= str_repeat( $piece['open'], $skippedBraces );
+ $enclosingAccum .= str_repeat( $piece->open, $skippedBraces );
}

+ extract( $stack->getFlags() );
+
# Add XML element to the enclosing accumulator
$accum .= $element;
}

elseif ( $found == 'pipe' ) {
- $stack[$stackIndex]['parts'][] = '';
- $partsCount = count( $stack[$stackIndex]['parts'] );
- $accum =& $stack[$stackIndex]['parts'][$partsCount - 1];
- $findEquals = true;
+ $findEquals = true; // shortcut for getFlags()
+ $stack->top->addPart();
+ $accum =& $stack->getAccum();
++$i;
- }
+ }

elseif ( $found == 'equals' ) {
- $findEquals = false;
- $partsCount = count( $stack[$stackIndex]['parts'] );
- $stack[$stackIndex]['eqpos'][$partsCount - 1] = strlen( $accum );
+ $findEquals = false; // shortcut for getFlags()
+ $partsCount = count( $stack->top->parts );
+ $stack->top->eqpos[$partsCount - 1] = strlen( $accum );
$accum .= '=';
++$i;
}
}

# Output any remaining unclosed brackets
- foreach ( $stack as $piece ) {
- if ( $piece['open'] == "\n" ) {
- $topAccum .= $piece['parts'][0];
+ foreach ( $stack->stack as $piece ) {
+ if ( $piece->open == "\n" ) {
+ $stack->topAccum .= $piece->parts[0];
} else {
- $topAccum .= str_repeat( $piece['open'], $piece['count'] ) . implode( '|', $piece['parts'] );
+ $stack->topAccum .= str_repeat( $piece->open, $piece->count ) . implode( '|', $piece->parts );
}
}
- $topAccum .= '</root>';
+ $stack->topAccum .= '</root>';
+ $xml = $stack->topAccum;

wfProfileOut( __METHOD__.'-makexml' );
wfProfileIn( __METHOD__.'-loadXML' );
$dom = new DOMDocument;
wfSuppressWarnings();
- $result = $dom->loadXML( $topAccum );
+ $result = $dom->loadXML( $xml );
wfRestoreWarnings();
if ( !$result ) {
// Try running the XML through UtfNormal to get rid of invalid characters
- $topAccum = UtfNormal::cleanUp( $topAccum );
- $result = $dom->loadXML( $topAccum );
+ $xml = UtfNormal::cleanUp( $xml );
+ $result = $dom->loadXML( $xml );
if ( !$result ) {
throw new MWException( __METHOD__.' generated invalid XML' );
}
@@ -3154,8 +3144,8 @@
*
* Note that the substitution depends on value of $mOutputType:
* OT_WIKI: only {{subst:}} templates
- * OT_MSG: only magic variables
- * OT_HTML: all templates and magic variables
+ * OT_PREPROCESS: templates but not extension tags
+ * OT_HTML: all templates and extension tags
*
* @param string $tex The text to transform
* @param PPFrame $frame Object describing the arguments passed to the template
@@ -3727,6 +3717,15 @@
}
}
} else {
+ if ( is_null( $attrText ) ) {
+ $attrText = '';
+ }
+ if ( isset( $params['attributes'] ) ) {
+ foreach ( $params['attributes'] as $attrName => $attrValue ) {
+ $attrText .= ' ' . htmlspecialchars( $attrName ) . '="' .
+ htmlspecialchars( $attrValue ) . '"';
+ }
+ }
if ( $content === null ) {
$output = "<$name$attrText/>";
} else {
@@ -4088,7 +4087,7 @@
*/
function preSaveTransform( $text, &$title, $user, $options, $clearState = true ) {
$this->mOptions = $options;
- $this->mTitle =& $title;
+ $this->setTitle( $title );
$this->setOutputType( OT_WIKI );

if ( $clearState ) {
@@ -4238,7 +4237,10 @@
function cleanSig( $text, $parsing = false ) {
if ( !$parsing ) {
global $wgTitle;
- $this->startExternalParse( $wgTitle, new ParserOptions(), OT_MSG );
+ $this->clearState();
+ $this->setTitle( $wgTitle );
+ $this->mOptions = new ParserOptions;
+ $this->setOutputType = OT_PREPROCESS;
}

# FIXME: regex doesn't respect extension tags or nowiki
@@ -4276,7 +4278,7 @@
* @public
*/
function startExternalParse( &$title, $options, $outputType, $clearState = true ) {
- $this->mTitle =& $title;
+ $this->setTitle( $title );
$this->mOptions = $options;
$this->setOutputType( $outputType );
if ( $clearState ) {
@@ -4285,16 +4287,11 @@
}

/**
- * Transform a MediaWiki message by replacing magic variables.
+ * Wrapper for preprocess()
*
- * For some unknown reason, it also expands templates, but only to the
- * first recursion level. This is wrong and broken, probably introduced
- * accidentally during refactoring, but probably relied upon by thousands
- * of users.
- *
- * @param string $text the text to transform
+ * @param string $text the text to preprocess
* @param ParserOptions $options options
- * @return string the text with variables substituted
+ * @return string
* @public
*/
function transformMsg( $text, $options ) {
@@ -4310,18 +4307,8 @@
$executing = true;

wfProfileIn($fname);
+ $text = $this->preprocess( $text, $wgTitle, $options );

- if ( $wgTitle && !( $wgTitle instanceof FakeTitle ) ) {
- $this->mTitle = $wgTitle;
- } else {
- $this->mTitle = Title::newFromText('msg');
- }
- $this->mOptions = $options;
- $this->setOutputType( OT_MSG );
- $this->clearState();
- $text = $this->replaceVariables( $text );
- $text = $this->mStripState->unstripBoth( $text );
-
$executing = false;
wfProfileOut($fname);
return $text;
@@ -5034,7 +5021,7 @@
private function extractSections( $text, $section, $mode, $newText='' ) {
global $wgTitle;
$this->clearState();
- $this->mTitle = $wgTitle; // not generally used but removes an ugly failure mode
+ $this->setTitle( $wgTitle ); // not generally used but removes an ugly failure mode
$this->mOptions = new ParserOptions;
$this->setOutputType( OT_WIKI );
$curIndex = 0;
@@ -5270,22 +5257,6 @@
* @todo document, briefly.
* @addtogroup Parser
*/
-class OnlyIncludeReplacer {
- var $output = '';
-
- function replace( $matches ) {
- if ( substr( $matches[1], -1 ) == "\n" ) {
- $this->output .= substr( $matches[1], 0, -1 );
- } else {
- $this->output .= $matches[1];
- }
- }
-}
-
-/**
- * @todo document, briefly.
- * @addtogroup Parser
- */
class StripState {
var $general, $nowiki;

@@ -5327,6 +5298,22 @@
}

/**
+ * @todo document, briefly.
+ * @addtogroup Parser
+ */
+class OnlyIncludeReplacer {
+ var $output = '';
+
+ function replace( $matches ) {
+ if ( substr( $matches[1], -1 ) == "\n" ) {
+ $this->output .= substr( $matches[1], 0, -1 );
+ } else {
+ $this->output .= $matches[1];
+ }
+ }
+}
+
+/**
* An expansion frame, used as a context to expand the result of preprocessToDom()
*/
class PPFrame {
@@ -5409,22 +5396,16 @@
return $root;
}

- if ( $this->parser->ot['html']
- && ++$this->parser->mPPNodeCount > $this->parser->mOptions->mMaxPPNodeCount )
+ if ( ++$this->parser->mPPNodeCount > $this->parser->mOptions->mMaxPPNodeCount )
{
- return $this->parser->insertStripItem( '<!-- node-count limit exceeded -->' );
+ return '<span class="error">Node-count limit exceeded</span>';
}

- if ( is_array( $root ) ) {
+ if ( is_array( $root ) || $root instanceof DOMNodeList ) {
$s = '';
foreach ( $root as $node ) {
$s .= $this->expand( $node, $flags );
}
- } elseif ( $root instanceof DOMNodeList ) {
- $s = '';
- foreach ( $root as $node ) {
- $s .= $this->expand( $node, $flags );
- }
} elseif ( $root instanceof DOMNode ) {
if ( $root->nodeType == XML_TEXT_NODE ) {
$s = $root->nodeValue;
@@ -5451,7 +5432,7 @@
$titles = $xpath->query( 'title', $root );
$title = $titles->item( 0 );
$parts = $xpath->query( 'part', $root );
- if ( $flags & self::NO_ARGS || $this->parser->ot['msg'] ) {
+ if ( $flags & self::NO_ARGS ) {
$s = '{{{' . $this->implodeWithFlags( '|', $flags, $title, $parts ) . '}}}';
} else {
$params = array( 'title' => $title, 'parts' => $parts, 'text' => 'FIXME' );
@@ -5693,7 +5674,6 @@
}

function getArgument( $name ) {
- wfDebug( __METHOD__." getting '$name'\n" );
$text = $this->getNumberedArgument( $name );
if ( $text === false ) {
$text = $this->getNamedArgument( $name );
@@ -5701,3 +5681,88 @@
return $text;
}
}
+
+/**
+ * Stack class to help Parser::preprocessToDom()
+ */
+class PPDStack {
+ var $stack, $topAccum, $top;
+
+ function __construct() {
+ $this->stack = array();
+ $this->topAccum = '';
+ $this->top = false;
+ }
+
+ function &getAccum() {
+ if ( count( $this->stack ) ) {
+ return $this->top->getAccum();
+ } else {
+ return $this->topAccum;
+ }
+ }
+
+ function push( $data ) {
+ if ( $data instanceof PPDStackElement ) {
+ $this->stack[] = $data;
+ } else {
+ $this->stack[] = new PPDStackElement( $data );
+ }
+ $this->top =& $this->stack[ count( $this->stack ) - 1 ];
+ }
+
+ function pop() {
+ if ( !count( $this->stack ) ) {
+ throw new MWException( __METHOD__.': no elements remaining' );
+ }
+ $temp = array_pop( $this->stack );
+ if ( count( $this->stack ) ) {
+ $this->top =& $this->stack[ count( $this->stack ) - 1 ];
+ } else {
+ $this->top = false;
+ }
+ }
+
+ function getFlags() {
+ if ( !count( $this->stack ) ) {
+ return array(
+ 'findEquals' => false,
+ 'findPipe' => false,
+ 'inHeading' => false,
+ );
+ } else {
+ return $this->top->getFlags();
+ }
+ }
+}
+
+class PPDStackElement {
+ var $open, $close, $count, $parts, $eqpos, $lineStart;
+
+ function __construct( $data = array() ) {
+ $this->parts = array( '' );
+ $this->eqpos = array();
+
+ foreach ( $data as $name => $value ) {
+ $this->$name = $value;
+ }
+ }
+
+ function &getAccum() {
+ return $this->parts[count($this->parts) - 1];
+ }
+
+ function addPart( $s = '' ) {
+ $this->parts[] = $s;
+ }
+
+ function getFlags() {
+ $partCount = count( $this->parts );
+ $findPipe = $this->open != "\n" && $this->open != '[.';
+ return array(
+ 'findPipe' => $findPipe,
+ 'findEquals' => $findPipe && $partCount > 1 && !isset( $this->eqpos[$partCount - 1] ),
+ 'inHeading' => $this->open == "\n",
+ );
+ }
+}

Modified: branches/ApiEdit_Vodafone/includes/Parser_OldPP.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Parser_OldPP.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Parser_OldPP.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -81,6 +81,7 @@
if ( !$this->mFirstCall ) {
return;
}
+ $this->mFirstCall = false;

wfProfileIn( __METHOD__ );
global $wgAllowDisplayTitle, $wgAllowSlowParserFunctions;
@@ -128,7 +129,8 @@
}

$this->initialiseVariables();
- $this->mFirstCall = false;
+
+ wfRunHooks( 'ParserFirstCallInit', array( &$this ) );
wfProfileOut( __METHOD__ );
}

@@ -3829,7 +3831,7 @@
*/
function getUserSig( &$user ) {
global $wgMaxSigChars;
-
+
$username = $user->getName();
$nickname = $user->getOption( 'nickname' );
$nickname = $nickname === '' ? $username : $nickname;
@@ -3884,7 +3886,7 @@
*/
function cleanSig( $text, $parsing = false ) {
global $wgTitle;
- $this->startExternalParse( $wgTitle, new ParserOptions(), $parsing ? OT_WIKI : OT_MSG );
+ $this->startExternalParse( $this->mTitle, new ParserOptions(), $parsing ? OT_WIKI : OT_MSG );

$substWord = MagicWord::get( 'subst' );
$substRegex = '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase();

Modified: branches/ApiEdit_Vodafone/includes/RawPage.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/RawPage.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/RawPage.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -126,8 +126,7 @@
$url = $_SERVER['PHP_SELF'];
}

- $ua = @$_SERVER['HTTP_USER_AGENT'];
- if( strcmp( $wgScript, $url ) && strpos( $ua, 'MSIE' ) !== false ) {
+ if( strcmp( $wgScript, $url ) ) {
# Internet Explorer will ignore the Content-Type header if it
# thinks it sees a file extension it recognizes. Make sure that
# all raw requests are done through the script node, which will

Modified: branches/ApiEdit_Vodafone/includes/SiteConfiguration.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SiteConfiguration.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SiteConfiguration.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -36,11 +36,25 @@

if ( !is_null( $retval ) && count( $params ) ) {
foreach ( $params as $key => $value ) {
- $retval = str_replace( '$' . $key, $value, $retval );
+ $retval = $this->doReplace( '$' . $key, $value, $retval );
}
}
return $retval;
}
+
+ /** Type-safe string replace; won't do replacements on non-strings */
+ function doReplace( $from, $to, $in ) {
+ if( is_string( $in ) ) {
+ return str_replace( $from, $to, $in );
+ } elseif( is_array( $in ) ) {
+ foreach( $in as $key => $val ) {
+ $in[$key] = $this->doReplace( $from, $to, $val );
+ }
+ return $in;
+ } else {
+ return $in;
+ }
+ }

/** */
function getAll( $wiki, $suffix, $params ) {

Modified: branches/ApiEdit_Vodafone/includes/Skin.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Skin.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Skin.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -153,13 +153,17 @@
}

function initPage( &$out ) {
- global $wgFavicon, $wgScriptPath, $wgSitename, $wgContLang;
+ global $wgFavicon, $wgAppleTouchIcon, $wgScriptPath, $wgSitename, $wgContLang;

wfProfileIn( __METHOD__ );

if( false !== $wgFavicon ) {
$out->addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) );
}
+
+ if( false !== $wgAppleTouchIcon ) {
+ $out->addLink( array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) );
+ }

$code = $wgContLang->getCode();
$name = $wgContLang->getLanguageName( $code );

Modified: branches/ApiEdit_Vodafone/includes/SpecialBlockip.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialBlockip.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialBlockip.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -282,17 +282,10 @@
}
}

- const BLOCK_SUCCESS = 0; // Success
- const BLOCK_RANGE_INVALID = 1; // Invalid IP range
- const BLOCK_RANGE_DISABLED = 2; // Sysops can't block ranges
- const BLOCK_NONEXISTENT_USER = 3; // No such user
- const BLOCK_IP_INVALID = 4; // Invalid IP address
- const BLOCK_EXPIRY_INVALID = 5; // Invalid expiry time
- const BLOCK_ALREADY_BLOCKED = 6; // User is already blocked
/**
* Backend block code.
* $userID and $expiry will be filled accordingly
- * Returns one of the BLOCK_* constants
+ * @return array(message key, arguments) on failure, empty array on success
*/
function doBlock(&$userId = null, &$expiry = null)
{
@@ -313,23 +306,23 @@
# IPv4
if ( $wgSysopRangeBans ) {
if ( !IP::isIPv4( $this->BlockAddress ) || $matches[2] < 16 || $matches[2] > 32 ) {
- return self::BLOCK_RANGE_INVALID;
+ return array('ip_range_invalid');
}
$this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
} else {
# Range block illegal
- return self::BLOCK_RANGE_DISABLED;
+ return array('range_block_disabled');
}
} else if ( preg_match( "/^($rxIP6)\\/(\\d{1,3})$/", $this->BlockAddress, $matches ) ) {
# IPv6
if ( $wgSysopRangeBans ) {
if ( !IP::isIPv6( $this->BlockAddress ) || $matches[2] < 64 || $matches[2] > 128 ) {
- return self::BLOCK_RANGE_INVALID;
+ return array('ip_range_invalid');
}
$this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
} else {
# Range block illegal
- return self::BLOCK_RANGE_DISABLED;
+ return array('range_block_disabled');
}
} else {
# Username block
@@ -337,13 +330,12 @@
$user = User::newFromName( $this->BlockAddress );
if( !is_null( $user ) && $user->getID() ) {
# Use canonical name
- $this->BlockAddress = $user->getName();
$userId = $user->getID();
} else {
- return self::BLOCK_NONEXISTENT_USER;
+ return array('nosuchusershort', htmlspecialchars($user->getName()));
}
} else {
- return self::BLOCK_IP_INVALID;
+ return array('badipaddress');
}
}
}
@@ -361,7 +353,7 @@
$expirestr = $this->BlockOther;

if (strlen($expirestr) == 0) {
- return self::BLOCK_EXPIRY_INVALID;
+ return array('ipb_expiry_invalid');
}

if ( $expirestr == 'infinite' || $expirestr == 'indefinite' ) {
@@ -371,7 +363,7 @@
$expiry = strtotime( $expirestr );

if ( $expiry < 0 || $expiry === false ) {
- return self::BLOCK_EXPIRY_INVALID;
+ return array('ipb_expiry_invalid');
}

$expiry = wfTimestamp( TS_MW, $expiry );
@@ -387,7 +379,7 @@
if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) {

if ( !$block->insert() ) {
- return self::BLOCK_ALREADY_BLOCKED;
+ return array('ipb_already_blocked', htmlspecialchars($this->BlockAddress));
}

wfRunHooks('BlockIpComplete', array($block, $wgUser));
@@ -404,8 +396,10 @@
$reasonstr, $logParams );

# Report to the user
- return self::BLOCK_SUCCESS;
+ return array();
}
+ else
+ return array('hookaborted');
}

/**
@@ -416,34 +410,14 @@
{
global $wgOut;
$retval = $this->doBlock();
- switch($retval)
- {
- case self::BLOCK_RANGE_INVALID:
- $this->showForm( wfMsg( 'ip_range_invalid' ) );
- return;
- case self::BLOCK_RANGE_DISABLED:
- $this->showForm( wfMsg( 'range_block_disabled' ) );
- return;
- case self::BLOCK_NONEXISTENT_USER:
- $this->showForm( wfMsg( 'nosuchusershort', htmlspecialchars( $this->BlockAddress ) ) );
- return;
- case self::BLOCK_IP_INVALID:
- $this->showForm( wfMsg( 'badipaddress' ) );
- return;
- case self::BLOCK_EXPIRY_INVALID:
- $this->showForm( wfMsg( 'ipb_expiry_invalid' ) );
- return;
- case self::BLOCK_ALREADY_BLOCKED:
- $this->showForm( wfMsg( 'ipb_already_blocked', htmlspecialchars( $this->BlockAddress ) ) );
- return;
- case self::BLOCK_SUCCESS:
- $titleObj = SpecialPage::getTitleFor( 'Blockip' );
- $wgOut->redirect( $titleObj->getFullURL( 'action=success&ip=' .
- urlencode( $this->BlockAddress ) ) );
- return;
- default:
- throw new MWException( __METHOD__ . ": Unknown return value ``{$retval}''" );
+ if(empty($retval)) {
+ $titleObj = SpecialPage::getTitleFor( 'Blockip' );
+ $wgOut->redirect( $titleObj->getFullURL( 'action=success&ip=' .
+ urlencode( $this->BlockAddress ) ) );
+ return;
}
+ $key = array_shift($retval);
+ $this->showForm(wfMsgReal($key, $retval));
}

function showSuccess() {

Modified: branches/ApiEdit_Vodafone/includes/SpecialExport.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialExport.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialExport.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -50,6 +50,61 @@
}

/**
+ * Expand a list of pages to include templates used in those pages.
+ * @param $inputPages array, list of titles to look up
+ * @param $pageSet array, associative array indexed by titles for output
+ * @return array associative array index by titles
+ */
+function wfExportGetTemplates( $inputPages, $pageSet ) {
+ return wfExportGetLinks( $inputPages, $pageSet,
+ 'templatelinks',
+ array( 'tl_namespace AS namespace', 'tl_title AS title' ),
+ array( 'page_id=tl_from' ) );
+}
+
+/**
+ * Expand a list of pages to include images used in those pages.
+ * @param $inputPages array, list of titles to look up
+ * @param $pageSet array, associative array indexed by titles for output
+ * @return array associative array index by titles
+ */
+function wfExportGetImages( $inputPages, $pageSet ) {
+ return wfExportGetLinks( $inputPages, $pageSet,
+ 'imagelinks',
+ array( NS_IMAGE . ' AS namespace', 'il_to AS title' ),
+ array( 'page_id=il_from' ) );
+}
+
+/**
+ * Expand a list of pages to include items used in those pages.
+ * @private
+ */
+function wfExportGetLinks( $inputPages, $pageSet, $table, $fields, $join ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ foreach( $inputPages as $page ) {
+ $title = Title::newFromText( $page );
+ $pageSet[$title->getPrefixedText()] = true;
+ if( $title ) {
+ /// @fixme May or may not be more efficient to batch these
+ /// by namespace when given multiple input pages.
+ $result = $dbr->select(
+ array( 'page', $table ),
+ $fields,
+ array_merge( $join,
+ array(
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbKey() ) ),
+ __METHOD__ );
+ foreach( $result as $row ) {
+ $template = Title::makeTitle( $row->namespace, $row->title );
+ $pageSet[$template->getPrefixedText()] = true;
+ }
+ }
+ }
+ return $pageSet;
+}
+
+/**
*
*/
function wfSpecialExport( $page = '' ) {
@@ -66,6 +121,11 @@
if ( $catname !== '' && $catname !== NULL && $catname !== false ) {
$t = Title::makeTitleSafe( NS_CATEGORY, $catname );
if ( $t ) {
+ /**
+ * @fixme This can lead to hitting memory limit for very large
+ * categories. Ideally we would do the lookup synchronously
+ * during the export in a single query.
+ */
$catpages = wfExportGetPagesFromCategory( $t );
if ( $catpages ) $page .= "\n" . implode( "\n", $catpages );
}
@@ -123,7 +183,7 @@

$list_authors = $wgRequest->getCheck( 'listauthors' );
if ( !$curonly || !$wgExportAllowListContributors ) $list_authors = false ;
-
+
if ( $doexport ) {
$wgOut->disable();

@@ -136,8 +196,26 @@
$filename = urlencode( $wgSitename . '-' . wfTimestampNow() . '.xml' );
$wgRequest->response()->header( "Content-disposition: attachment;filename={$filename}" );
}
- $pages = explode( "\n", $page );
+
+ /* Split up the input and look up linked pages */
+ $inputPages = array_filter( explode( "\n", $page ) );
+ $pageSet = array_flip( $inputPages );

+ if( $wgRequest->getCheck( 'templates' ) ) {
+ $pageSet = wfExportGetTemplates( $inputPages, $pageSet );
+ }
+
+ /*
+ // Enable this when we can do something useful exporting/importing image information. :)
+ if( $wgRequest->getCheck( 'images' ) ) {
+ $pageSet = wfExportGetImages( $inputPages, $pageSet );
+ }
+ */
+
+ $pages = array_keys( $pageSet );
+
+ /* Ok, let's get to it... */
+
$db = wfGetDB( DB_SLAVE );
$exporter = new WikiExporter( $db, $history );
$exporter->list_authors = $list_authors ;
@@ -188,6 +266,9 @@
} else {
$wgOut->addHtml( wfMsgExt( 'exportnohistory', 'parse' ) );
}
+ $form .= Xml::checkLabel( wfMsg( 'export-templates' ), 'templates', 'wpExportTemplates', false ) . '<br />';
+ // Enable this when we can do something useful exporting/importing image information. :)
+ //$form .= Xml::checkLabel( wfMsg( 'export-images' ), 'images', 'wpExportImages', false ) . '<br />';
$form .= Xml::checkLabel( wfMsg( 'export-download' ), 'wpDownload', 'wpDownload', true ) . '<br />';

$form .= Xml::submitButton( wfMsg( 'export-submit' ) );

Modified: branches/ApiEdit_Vodafone/includes/SpecialIpblocklist.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialIpblocklist.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialIpblocklist.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -150,7 +150,7 @@
* Backend code for unblocking. doSubmit() wraps around this.
* $range is only used when UNBLOCK_BLOCKED_AS_RANGE is returned, in which
* case it contains the range $ip is part of.
- * Returns one of UNBLOCK_*
+ * @return array array(message key, parameters) on failure, empty array on success
*/

static function doUnblock(&$id, &$ip, &$reason, &$range = null)
@@ -158,7 +158,7 @@
if ( $id ) {
$block = Block::newFromID( $id );
if ( !$block ) {
- return self::UNBLOCK_NO_SUCH_ID;
+ return array('ipb_cant_unblock', htmlspecialchars($id));
}
$ip = $block->getRedactedName();
} else {
@@ -168,19 +168,20 @@
$id = substr( $ip, 1 );
$block = Block::newFromID( $id );
if( !$block ) {
- return self::UNBLOCK_NO_SUCH_ID;
+ return array('ipb_cant_unblock', htmlspecialchars($id));
}
+ $ip = $block->getRedactedName();
} else {
$block = Block::newFromDB( $ip );
if ( !$block ) {
- return self::UNBLOCK_USER_NOT_BLOCKED;
+ return array('ipb_cant_unblock', htmlspecialchars($id));
}
if( $block->mRangeStart != $block->mRangeEnd
&& !strstr( $ip, "/" ) ) {
/* If the specified IP is a single address, and the block is
* a range block, don't unblock the range. */
$range = $block->mAddress;
- return self::UNBLOCK_BLOCKED_AS_RANGE;
+ return array('ipb_blocked_as_range', $ip, $range);
}
}
}
@@ -189,31 +190,28 @@

# Delete block
if ( !$block->delete() ) {
- return self::UNBLOCK_UNKNOWNERR;
+ return array('ipb_cant_unblock', htmlspecialchars($id));
}

# Make log entry
$log = new LogPage( 'block' );
$log->addEntry( 'unblock', Title::makeTitle( NS_USER, $ip ), $reason );
- return self::UNBLOCK_SUCCESS;
+ return array();
}

function doSubmit() {
global $wgOut;
- $retval = self::doUnblock(&$this->id, &$this->ip, &$this->reason, &$range);
- if($retval == self::UNBLOCK_SUCCESS) {
- # Report to the user
- $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
- $success = $titleObj->getFullURL( "action=success&successip=" . urlencode( $this->ip ) );
- $wgOut->redirect( $success );
- } else if($retval == self::UNBLOCK_BLOCKED_AS_RANGE) {
- $this->showForm( wfMsg( 'ipb_blocked_as_range', $this->ip, $range ) );
- } else { // UI code doesn't distinguish between errors much. Maybe it should
- if ( !$this->ip && $this->id ) {
- $this->ip = '#' . $this->id;
- }
- $this->showForm( wfMsg( 'ipb_cant_unblock', htmlspecialchars( $this->id ) ) );
+ $retval = self::doUnblock($this->id, $this->ip, $this->reason, $range);
+ if(!empty($retval))
+ {
+ $key = array_shift($retval);
+ $this->showForm(wfMsgReal($key, $retval));
+ return;
}
+ # Report to the user
+ $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
+ $success = $titleObj->getFullURL( "action=success&successip=" . urlencode( $this->ip ) );
+ $wgOut->redirect( $success );
}

function showList( $msg ) {

Modified: branches/ApiEdit_Vodafone/includes/SpecialUndelete.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialUndelete.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialUndelete.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -303,9 +303,6 @@
return ($n > 0);
}

- const UNDELETE_NOTHINGRESTORED = 0; // No revisions could be restored
- const UNDELETE_NOTAVAIL = -1; // Not all requested revisions are available
- const UNDELETE_UNKNOWNERR = -2; // Unknown error
/**
* Restore the given (or all) text and file revisions for the page.
* Once restored, the items will be removed from the archive tables.
@@ -315,7 +312,8 @@
* @param string $comment
* @param array $fileVersions
*
- * @return array(number of revisions restored, number of file versions restored, log reason) on success or UNDELETE_* on failure
+ * @return array(number of file revisions restored, number of image revisions restored, log message)
+ * on success, false on failure
*/
function undelete( $timestamps, $comment = '', $fileVersions = array() ) {
// If both the set of text revisions and file revisions are empty,
@@ -335,8 +333,8 @@

if( $restoreText ) {
$textRestored = $this->undeleteRevisions( $timestamps );
- if($textRestored < 0) // It must be one of UNDELETE_*
- return $textRestored;
+ if($textRestored === false) // It must be one of UNDELETE_*
+ return false;
} else {
$textRestored = 0;
}
@@ -357,7 +355,7 @@
$wgContLang->formatNum( $filesRestored ) );
} else {
wfDebug( "Undelete: nothing undeleted...\n" );
- return self::UNDELETE_NOTHINGRESTORED;
+ return false;
}

if( trim( $comment ) != '' )
@@ -376,10 +374,11 @@
* @param string $comment
* @param array $fileVersions
*
- * @return int number of revisions restored on success or UNDELETE_* on failure
+ * @return mixed number of revisions restored or false on failure
*/
private function undeleteRevisions( $timestamps ) {
- if ( wfReadOnly() ) return 0;
+ if ( wfReadOnly() )
+ return false;

$restoreAll = empty( $timestamps );

@@ -444,7 +443,7 @@
);
if( $dbw->numRows( $result ) < count( $timestamps ) ) {
wfDebug( __METHOD__.": couldn't find all requested rows\n" );
- return self::UNDELETE_NOTAVAIL;
+ return false;
}

$revision = null;

Modified: branches/ApiEdit_Vodafone/includes/SpecialVersion.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialVersion.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialVersion.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -102,7 +102,7 @@
wfRunHooks( 'SpecialVersionExtensionTypes', array( &$this, &$extensionTypes ) );

$out = "<h2>Extensions</h2>\n";
- $out .= wfOpenElement('table', array('id' => 'sv-ext') );
+ $out .= Xml::openElement('table', array('id' => 'sv-ext') );

foreach ( $extensionTypes as $type => $text ) {
if ( isset ( $wgExtensionCredits[$type] ) && count ( $wgExtensionCredits[$type] ) ) {
@@ -143,7 +143,7 @@
$out .= $this->openExtType('Skin extension functions');
$out .= '<tr><td colspan="3">' . $this->listToText( $wgSkinExtensionFunction ) . "</td></tr>\n";
}
- $out .= wfCloseElement( 'table' );
+ $out .= Xml::closeElement( 'table' );
return $out;
}

@@ -187,7 +187,7 @@
ksort( $myWgHooks );

$ret = "<h2>Hooks</h2>\n"
- . wfOpenElement('table', array('id' => 'sv-hooks') )
+ . Xml::openElement('table', array('id' => 'sv-hooks') )
. "<tr><th>Hook name</th><th>Subscribed by</th></tr>\n";

foreach ($myWgHooks as $hook => $hooks)
@@ -205,13 +205,13 @@

if(!$this->firstExtOpened) {
// Insert a spacing line
- $out .= '<tr class="sv-space">' . wfElement( 'td', $opt ) . "</tr>\n";
+ $out .= '<tr class="sv-space">' . Xml::element( 'td', $opt ) . "</tr>\n";
}
$this->firstExtOpened = false;

if($name) { $opt['id'] = "sv-$name"; }

- $out .= "<tr>" . wfElement( 'th', $opt, $text) . "</tr>\n";
+ $out .= "<tr>" . Xml::element( 'th', $opt, $text) . "</tr>\n";
return $out;
}


Modified: branches/ApiEdit_Vodafone/includes/SpecialWithoutinterwiki.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/SpecialWithoutinterwiki.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/SpecialWithoutinterwiki.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -8,13 +8,41 @@
* @author Rob Church <robchur [at] gmail>
*/
class WithoutInterwikiPage extends PageQueryPage {
+ private $prefix = '';

function getName() {
return 'Withoutinterwiki';
}

function getPageHeader() {
- return '<p>' . wfMsgExt( 'withoutinterwiki-header', array( 'parseinline' ) ) . '</p>';
+ global $wgScript, $wgContLang;
+ $prefix = $this->prefix;
+ $t = SpecialPage::getTitleFor( $this->getName() );
+ $align = $wgContLang->isRtl() ? 'left' : 'right';
+
+ $s = '<p>' . wfMsgExt( 'withoutinterwiki-header', array( 'parseinline' ) ) . '</p>';
+ $s .= Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
+ $s .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
+ $s .= Xml::hidden( 'title', $t->getPrefixedText() );
+ $s .= Xml::openElement( 'table', array( 'id' => 'nsselect', 'class' => 'withoutinterwiki' ) );
+ $s .= "<tr>
+ <td align='$align'>" .
+ Xml::label( wfMsg( 'allpagesprefix' ), 'wiprefix' ) .
+ "</td>
+ <td>" .
+ Xml::input( 'prefix', 20, htmlspecialchars ( $prefix ), array( 'id' => 'wiprefix' ) ) .
+ "</td>
+ </tr>
+ <tr>
+ <td align='$align'></td>
+ <td>" .
+ Xml::submitButton( wfMsgHtml( 'withoutinterwiki-submit' ) ) .
+ "</td>
+ </tr>";
+ $s .= Xml::closeElement( 'table' );
+ $s .= Xml::closeElement( 'form' );
+ $s .= Xml::closeElement( 'div' );
+ return $s;
}

function sortDescending() {
@@ -32,6 +60,7 @@
function getSQL() {
$dbr = wfGetDB( DB_SLAVE );
list( $page, $langlinks ) = $dbr->tableNamesN( 'page', 'langlinks' );
+ $prefix = $this->prefix ? "AND page_title LIKE '" . $dbr->escapeLike( $this->prefix ) . "%'" : '';
return
"SELECT 'Withoutinterwiki' AS type,
page_namespace AS namespace,
@@ -42,14 +71,22 @@
ON ll_from = page_id
WHERE ll_title IS NULL
AND page_namespace=" . NS_MAIN . "
- AND page_is_redirect = 0";
+ AND page_is_redirect = 0
+ {$prefix}";
}

+ function setPrefix( $prefix = '' ) {
+ $this->prefix = $prefix;
+ }
+
}

function wfSpecialWithoutinterwiki() {
+ global $wgRequest;
list( $limit, $offset ) = wfCheckLimits();
+ $prefix = $wgRequest->getVal( 'prefix' );
$wip = new WithoutInterwikiPage();
+ $wip->setPrefix( $prefix );
$wip->doQuery( $offset, $limit );
}


Modified: branches/ApiEdit_Vodafone/includes/Title.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Title.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Title.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -207,6 +207,9 @@
* Make an array of titles from an array of IDs
*/
public static function newFromIDs( $ids ) {
+ if ( !count( $ids ) ) {
+ return array();
+ }
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'page', array( 'page_namespace', 'page_title' ),
'page_id IN (' . $dbr->makeList( $ids ) . ')', __METHOD__ );
@@ -2305,10 +2308,14 @@
return 'badarticleerror';
}

- if ( $auth && (
- !$this->userCan( 'edit' ) || !$nt->userCan( 'edit' ) ||
- !$this->userCan( 'move' ) || !$nt->userCan( 'move' ) ) ) {
- return 'protectedpage';
+ if ( $auth ) {
+ global $wgUser;
+ $errors = array_merge($this->getUserPermissionsErrors('move', $wgUser),
+ $this->getUserPermissionsErrors('edit', $wgUser),
+ $nt->getUserPermissionsErrors('move', $wgUser),
+ $nt->getUserPermissionsErrors('edit', $wgUser));
+ if($errors !== array())
+ return $errors[0][0];
}

global $wgUser;

Modified: branches/ApiEdit_Vodafone/includes/Wiki.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/Wiki.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/Wiki.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -220,6 +220,10 @@

switch( $title->getNamespace() ) {
case NS_IMAGE:
+ $file = wfFindFile( $title );
+ if( $file && $file->getRedirected() ) {
+ return new Article( $title );
+ }
return new ImagePage( $title );
case NS_CATEGORY:
return new CategoryPage( $title );
@@ -245,7 +249,8 @@

// Namespace might change when using redirects
if( ( $action == 'view' || $action == 'render' ) && !$request->getVal( 'oldid' ) &&
- $request->getVal( 'redirect' ) != 'no' ) {
+ $request->getVal( 'redirect' ) != 'no' &&
+ !( $wgTitle->getNamespace() == NS_IMAGE && wfFindFile( $wgTitle->getText() ) ) ) {

$dbr = wfGetDB(DB_SLAVE);
$article->loadPageData($article->pageDataFromTitle($dbr, $title));

Modified: branches/ApiEdit_Vodafone/includes/api/ApiBase.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiBase.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiBase.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -554,6 +554,10 @@
* Array that maps message keys to error messages. $1 and friends are replaced.
*/
public static $messageMap = array(
+ // This one MUST be present, or dieUsageMsg() will recurse infinitely
+ 'unknownerror' => array('code' => 'unknownerror', 'info' => "Unknown error: ``\$1''"),
+
+ // Messages from Title::getUserPermissionsErrors()
'ns-specialprotected' => array('code' => 'unsupportednamespace', 'info' => "Pages in the Special namespace can't be edited"),
'protectedinterface' => array('code' => 'protectednamespace-interface', 'info' => "You're not allowed to edit interface messages"),
'namespaceprotected' => array('code' => 'protectednamespace', 'info' => "You're not allowed to edit pages in the ``\$1'' namespace"),
@@ -565,12 +569,55 @@
'badaccess-group1' => array('code' => 'permissiondenied', 'info' => "Permission denied"), // Can't use the parameter 'cause it's wikilinked
'badaccess-group2' => array('code' => 'permissiondenied', 'info' => "Permission denied"),
'badaccess-groups' => array('code' => 'permissiondenied', 'info' => "Permission denied"),
- 'unknownerror' => array('code' => 'unknownerror', 'info' => "Unknown error"),
'titleprotected' => array('code' => 'protectedtitle', 'info' => "This title has been protected from creation"),
'nocreate-loggedin' => array('code' => 'cantcreate', 'info' => "You don't have permission to create new pages"),
'nocreatetext' => array('code' => 'cantcreate-anon', 'info' => "Anonymous users can't create new pages"),
'movenologintext' => array('code' => 'cantmove-anon', 'info' => "Anonymous users can't move pages"),
- 'movenotallowed' => array('code' => 'cantmove', 'info' => "You don't have permission to move pages")
+ 'movenotallowed' => array('code' => 'cantmove', 'info' => "You don't have permission to move pages"),
+ 'confirmedittiext' => array('code' => 'confirmemail', 'info' => "You must confirm your e-mail address before you can edit"),
+ 'blockedtext' => array('code' => 'blocked', 'info' => "You have been blocked from editing"),
+ 'autoblockedtext' => array('code' => 'autoblocked', 'info' => "Your IP address has been blocked automatically, because it was used by a blocked user"),
+
+ // Miscellaneous interface messages
+ 'alreadyrolled' => array('code' => 'alreadyrolled', 'info' => "The page you tried to rollback was already rolled back"),
+ 'cantrollback' => array('code' => 'onlyauthor', 'info' => "The page you tried to rollback only has one author"),
+ 'readonlytext' => array('code' => 'readonly', 'info' => "The wiki is currently in read-only mode"),
+ 'sessionfailure' => array('code' => 'badtoken', 'info' => "Invalid token"),
+ 'cannotdelete' => array('code' => 'cantdelete', 'info' => "Couldn't delete ``\$1''. Maybe it was deleted already by someone else"),
+ 'notanarticle' => array('code' => 'missingtitle', 'info' => "The page you requested doesn't exist"),
+ 'selfmove' => array('code' => 'selfmove', 'info' => "Can't move a page to itself"),
+ 'immobile_namespace' => array('code' => 'immobilenamespace', 'info' => "You tried to move pages from or to a namespace that is protected from moving"),
+ 'articleexists' => array('code' => 'articleexists', 'info' => "The destination article already exists and is not a redirect to the source article"),
+ 'protectedpage' => array('code' => 'protectedpage', 'info' => "You don't have permission to perform this move"),
+ 'hookaborted' => array('code' => 'hookaborted', 'info' => "The modification you tried to make was aborted by an extension hook"),
+ 'cantmove-titleprotected' => array('code' => 'protectedtitle', 'info' => "The destination article has been protected from creation"),
+ // 'badarticleerror' => shouldn't happen
+ // 'badtitletext' => shouldn't happen
+ 'ip_range_invalid' => array('code' => 'invalidrange', 'info' => "Invalid IP range"),
+ 'range_block_disabled' => array('code' => 'rangedisabled', 'info' => "Blocking IP ranges has been disabled"),
+ 'nosuchusershort' => array('code' => 'nosuchuser', 'info' => "The user you specified doesn't exist"),
+ 'badipaddress' => array('code' => 'invalidip', 'info' => "Invalid IP address specified"),
+ 'ipb_expiry_invalid' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time"),
+ 'ipb_already_blocked' => array('code' => 'alreadyblocked', 'info' => "The user you tried to block was already blocked"),
+ 'ipb_blocked_as_range' => array('code' => 'blockedasrange', 'info' => "IP address ``\$1'' was blocked as part of range ``\$2''. You can't unblock the IP invidually, but you can unblock the range as a whole."),
+ 'ipb_cant_unblock' => array('code' => 'cantunblock', 'info' => "The block you specified was not found. It may have been unblocked already"),
+
+ // API-specific messages
+ 'missingparam' => array('code' => 'no$1', 'info' => "The \$1 parameter must be set"),
+ 'invalidtitle' => array('code' => 'invalidtitle', 'info' => "Bad title ``\$1''"),
+ 'invaliduser' => array('code' => 'invaliduser', 'info' => "Invalid username ``\$1''"),
+ 'invalidexpiry' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time"),
+ 'pastexpiry' => array('code' => 'pastexpiry', 'info' => "Expiry time is in the past"),
+ 'create-titleexists' => array('code' => 'create-titleexists', 'info' => "Existing titles can't be protected with 'create'"),
+ 'missingtitle-createonly' => array('code' => 'missingtitle-createonly', 'info' => "Missing titles can only be protected with 'create'"),
+ 'cantblock' => array('code' => 'cantblock', 'info' => "You don't have permission to block users"),
+ 'canthide' => array('code' => 'canthide', 'info' => "You don't have permission to hide user names from the block log"),
+ 'cantblock-email' => array('code' => 'cantblock-email', 'info' => "You don't have permission to block users from sending e-mail through the wiki"),
+ 'unblock-notarget' => array('code' => 'notarget', 'info' => "Either the id or the user parameter must be set"),
+ 'unblock-idanduser' => array('code' => 'idanduser', 'info' => "The id and user parameters can\'t be used together"),
+ 'cantunblock' => array('code' => 'permissiondenied', 'info' => "You don't have permission to unblock users"),
+ 'cannotundelete' => array('code' => 'cantundelete', 'info' => "Couldn't undelete: the requested revisions may not exist, or may have been undeleted already"),
+ 'permdenied-undelete' => array('code' => 'permissiondenied', 'info' => "You don't have permission to restore deleted revisions"),
);

/**
@@ -580,9 +627,9 @@
public function dieUsageMsg($error) {
$key = array_shift($error);
if(isset(self::$messageMap[$key]))
- $this->dieUsage(wfMsgReplaceArgs(self::$messageMap[$key]['info'], $error), self::$messageMap[$key]['code']);
- // If the key isn't present, throw an "unknown error
- $this->dieUsage(self::$messageMap['unknownerror']['info'], self::$messageMap['unknownerror']['code']);
+ $this->dieUsage(wfMsgReplaceArgs(self::$messageMap[$key]['info'], $error), wfMsgReplaceArgs(self::$messageMap[$key]['code'], $error));
+ // If the key isn't present, throw an "unknown error"
+ $this->dieUsageMsg(array('unknownerror', $key));
}

/**
@@ -605,6 +652,13 @@
public function isEditMode() {
return false;
}
+
+ /**
+ * Indicates whether this module must be called with a POST request
+ */
+ public function mustBePosted() {
+ return false;
+ }


/**

Modified: branches/ApiEdit_Vodafone/includes/api/ApiBlock.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiBlock.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiBlock.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -61,21 +61,23 @@
}

if(is_null($params['user']))
- $this->dieUsage('The user parameter must be set', 'nouser');
+ $this->dieUsageMsg(array('missingparam', 'user'));
if(is_null($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));
if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
+ $this->dieUsageMsg(array('sessionfailure'));
if(!$wgUser->isAllowed('block'))
- $this->dieUsage('You don\'t have permission to block users', 'permissiondenied');
+ $this->dieUsageMsg(array('cantblock'));
if($params['hidename'] && !$wgUser->isAllowed('hideuser'))
- $this->dieUsage('You don\'t have permission to hide user names from the block log', 'nohide');
+ $this->dieUsageMsg(array('canthide'));
+ if($params['noemail'] && !$wgUser->isAllowed('blockemail'))
+ $this->dieUsageMsg(array('cantblock-email'));
if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ $this->dieUsageMsg(array('readonlytext'));

$form = new IPBlockForm('');
$form->BlockAddress = $params['user'];
- $form->BlockReason = $params['reason'];
+ $form->BlockReason = (is_null($params['reason']) ? '' : $params['reason']);
$form->BlockReasonList = 'other';
$form->BlockExpiry = ($params['expiry'] == 'never' ? 'infinite' : $params['expiry']);
$form->BlockOther = '';
@@ -88,27 +90,11 @@
$dbw = wfGetDb(DB_MASTER);
$dbw->begin();
$retval = $form->doBlock($userID, $expiry);
- switch($retval)
- {
- case IPBlockForm::BLOCK_SUCCESS:
- break; // We'll deal with that later
- case IPBlockForm::BLOCK_RANGE_INVALID:
- $this->dieUsage("Invalid IP range ``{$params['user']}''", 'invalidrange');
- case IPBlockForm::BLOCK_RANGE_DISABLED:
- $this->dieUsage('Blocking IP ranges has been disabled', 'rangedisabled');
- case IPBlockForm::BLOCK_NONEXISTENT_USER:
- $this->dieUsage("User ``{$params['user']}'' doesn't exist", 'nosuchuser');
- case IPBlockForm::BLOCK_IP_INVALID:
- $this->dieUsage("Invaild IP address ``{$params['user']}''", 'invalidip');
- case IPBlockForm::BLOCK_EXPIRY_INVALID:
- $this->dieUsage("Invalid expiry time ``{$params['expiry']}''", 'invalidexpiry');
- case IPBlockForm::BLOCK_ALREADY_BLOCKED:
- $this->dieUsage("User ``{$params['user']}'' is already blocked", 'alreadyblocked');
- default:
- $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
- }
+ if(!empty($retval))
+ // We don't care about multiple errors, just report one of them
+ $this->dieUsageMsg($retval);
+
$dbw->commit();
-
$res['user'] = $params['user'];
$res['userID'] = $userID;
$res['expiry'] = ($expiry == Block::infinity() ? 'infinite' : $expiry);
@@ -127,6 +113,8 @@
$this->getResult()->addValue(null, $this->getModuleName(), $res);
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'user' => null,
@@ -152,7 +140,7 @@
'anononly' => 'Block anonymous users only (i.e. disable anonymous edits for this IP)',
'nocreate' => 'Prevent account creation',
'autoblock' => 'Automatically block the last used IP address, and any subsequent IP addresses they try to login from',
- 'noemail' => 'Prevent user from sending e-mail through the wiki',
+ 'noemail' => 'Prevent user from sending e-mail through the wiki. (Requires the "blockemail" right.)',
'hidename' => 'Hide the username from the block log. (Requires the "hideuser" right.)'
);
}

Modified: branches/ApiEdit_Vodafone/includes/api/ApiDelete.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiDelete.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiDelete.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -40,14 +40,6 @@
parent :: __construct($main, $action);
}

- /* Return values for the delete function. */
- const DELETE_SUCCESS = 0;
- const DELETE_PERM = 1;
- const DELETE_BLOCKED = 2;
- const DELETE_READONLY = 3;
- const DELETE_BADTOKEN = 4;
- const DELETE_BADARTICLE = 5;
-
/**
* Extracts the title, token, and reason from the request parameters and invokes
* the local delete() function with these as arguments. It does not make use of
@@ -62,49 +54,26 @@

$titleObj = NULL;
if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
+ $this->dieUsageMsg(array('missingparam', 'title'));
if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));

- // delete() also checks for these, but we wanna save some work
- if(!$wgUser->isAllowed('delete'))
- $this->dieUsage('You don\'t have permission to delete pages', 'permissiondenied');
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
$titleObj = Title::newFromText($params['title']);
if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ $this->dieUsageMsg(array('invalidtitle', $params['title']));
if(!$titleObj->exists())
- $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
+ $this->dieUsageMsg(array('notanarticle'));

$articleObj = new Article($titleObj);
$reason = (isset($params['reason']) ? $params['reason'] : NULL);
$dbw = wfGetDb(DB_MASTER);
$dbw->begin();
- $retval = self::delete(&$articleObj, $params['token'], &$reason);
+ $retval = self::delete($articleObj, $params['token'], $reason);
+
+ if(!empty($retval))
+ // We don't care about multiple errors, just report one of them
+ $this->dieUsageMsg(current($retval));

- switch($retval)
- {
- case self::DELETE_SUCCESS:
- break; // We'll deal with that later
- case self::DELETE_PERM: // If we get PERM, BLOCKED or READONLY that's weird, but it's possible
- $this->dieUsage('You don\'t have permission to delete', 'permissiondenied');
- case self::DELETE_BLOCKED:
- $this->dieUsage('You have been blocked from editing', 'blocked');
- case self::DELETE_READONLY:
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- case self::DELETE_BADTOKEN:
- $this->dieUsage('Invalid token', 'badtoken');
- case self::DELETE_BADARTICLE:
- $this->dieUsage("The article ``{$params['title']}'' doesn't exist or has already been deleted", 'missingtitle');
- default:
- // delete() has apparently invented a new error, which is extremely weird
- $this->dieDebug(__METHOD__, "delete() returned an unknown error ($retval)");
- }
- // $retval has to be self::DELETE_SUCCESS if we get here
$dbw->commit();
$r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
$this->getResult()->addValue(null, $this->getModuleName(), $r);
@@ -116,38 +85,41 @@
* @param Article $article - Article object to work on
* @param string $token - Delete token (same as edit token)
* @param string $reason - Reason for the deletion. Autogenerated if NULL
- * @return DELETE_SUCCESS on success, DELETE_* on failure
+ * @return Title::getUserPermissionsErrors()-like array
*/
public static function delete(&$article, $token, &$reason = NULL)
{
global $wgUser;

- // Check permissions first
- if(!$article->mTitle->userCan('delete'))
- return self::DELETE_PERM;
- if($wgUser->isBlocked())
- return self::DELETE_BLOCKED;
+ // Check permissions
+ $errors = $article->mTitle->getUserPermissionsErrors('delete', $wgUser);
+ if(!empty($errors))
+ return $errors;
if(wfReadOnly())
- return self::DELETE_READONLY;
+ return array(array('readonlytext'));
+ if($wgUser->isBlocked())
+ return array(array('blocked'));

// Check token
if(!$wgUser->matchEditToken($token))
- return self::DELETE_BADTOKEN;
+ return array(array('sessionfailure'));

// Auto-generate a summary, if necessary
if(is_null($reason))
{
$reason = $article->generateReason($hasHistory);
if($reason === false)
- return self::DELETE_BADARTICLE;
+ return array(array('cannotdelete'));
}

// Luckily, Article.php provides a reusable delete function that does the hard work for us
if($article->doDeleteArticle($reason))
- return self::DELETE_SUCCESS;
- return self::DELETE_BADARTICLE;
+ return array();
+ return array(array('cannotdelete', $article->mTitle->getPrefixedText()));
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'title' => null,

Modified: branches/ApiEdit_Vodafone/includes/api/ApiLogin.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiLogin.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiLogin.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -217,6 +217,8 @@
private function getMemCacheKey() {
return wfMemcKey( 'apilogin', 'badlogin', 'ip', wfGetIP() );
}
+
+ public function mustBePosted() { return true; }

protected function getAllowedParams() {
return array (

Modified: branches/ApiEdit_Vodafone/includes/api/ApiLogout.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiLogout.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiLogout.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -37,7 +37,7 @@
class ApiLogout extends ApiBase {

public function __construct($main, $action) {
- parent :: __construct($main, $action, 'lo');
+ parent :: __construct($main, $action);
}

public function execute() {

Modified: branches/ApiEdit_Vodafone/includes/api/ApiMain.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiMain.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiMain.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -325,8 +325,11 @@
return;
}
}
-
+
if (!$this->mInternalMode) {
+ // Ignore mustBePosted() for internal calls
+ if($module->mustBePosted() && !$this->mRequest->wasPosted())
+ $this->dieUsage("The {$this->mAction} module requires a POST request", 'mustbeposted');

// See if custom printer is used
$this->mPrinter = $module->getCustomPrinter();

Modified: branches/ApiEdit_Vodafone/includes/api/ApiMove.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiMove.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiMove.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -46,55 +46,45 @@

$titleObj = NULL;
if(!isset($params['from']))
- $this->dieUsage('The from parameter must be set', 'nofrom');
+ $this->dieUsageMsg(array('missingparam', 'from'));
if(!isset($params['to']))
- $this->dieUsage('The to parameter must be set', 'noto');
+ $this->dieUsageMsg(array('missingparam', 'to'));
if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));
if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
+ $this->dieUsageMsg(array('sessionfailure'));

- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- if($params['noredirect'] && !$wgUser->isAllowed('suppressredirect'))
- $this->dieUsage("You don't have permission to suppress redirect creation", 'nosuppress');
-
$fromTitle = Title::newFromText($params['from']);
if(!$fromTitle)
- $this->dieUsage("Bad title ``{$params['from']}''", 'invalidtitle');
+ $this->dieUsageMsg(array('invalidtitle', $params['from']));
if(!$fromTitle->exists())
- $this->dieUsage("``{$params['from']}'' doesn't exist", 'missingtitle');
+ $this->dieUsageMsg(array('notanarticle'));
$fromTalk = $fromTitle->getTalkPage();

-
$toTitle = Title::newFromText($params['to']);
if(!$toTitle)
- $this->dieUsage("Bad title ``{$params['to']}''", 'invalidtitle');
+ $this->dieUsageMsg(array('invalidtitle', $params['to']));
$toTalk = $toTitle->getTalkPage();

+ // Run getUserPermissionsErrors() here so we get message arguments too,
+ // rather than just a message key. The latter is troublesome for messages
+ // that use arguments.
+ // FIXME: moveTo() should really return an array, requires some
+ // refactoring of other code, though (mainly SpecialMovepage.php)
+ $errors = array_merge($fromTitle->getUserPermissionsErrors('move', $wgUser),
+ $fromTitle->getUserPermissionsErrors('edit', $wgUser),
+ $toTitle->getUserPermissionsErrors('move', $wgUser),
+ $toTitle->getUserPermissionsErrors('edit', $wgUser));
+ if(!empty($errors))
+ // We don't care about multiple errors, just report one of them
+ $this->dieUsageMsg(current($errors));
+
$dbw = wfGetDB(DB_MASTER);
$dbw->begin();
$retval = $fromTitle->moveTo($toTitle, true, $params['reason'], !$params['noredirect']);
if($retval !== true)
- switch($retval)
- {
- // case 'badtitletext': Can't happen
- // case 'badarticleerror': Can't happen
- case 'selfmove':
- $this->dieUsage("Can't move ``{$params['from']}'' to itself", 'selfmove');
- case 'immobile_namespace':
- if($fromTitle->isMovable())
- $this->dieUsage("Pages in the ``{$fromTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-from');
- $this->dieUsage("Pages in the ``{$toTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-to');
- case 'articleexists':
- $this->dieUsage("``{$toTitle->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTitle->getPrefixedText()}''", 'targetexists');
- case 'protectedpage':
- $this->dieUsage("You don't have permission to move ``{$fromTitle->getPrefixedText()}'' to ``{$toTitle->getPrefixedText()}''", 'permissiondenied');
- default:
- throw new MWException( "Title::moveTo: Unknown return value ``{$retval}''" );
- }
+ $this->dieUsageMsg(array($retval));
+
$r = array('from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason']);
if(!$params['noredirect'])
$r['redirectcreated'] = '';
@@ -111,36 +101,17 @@
}
// We're not gonna dieUsage() on failure, since we already changed something
else
- switch($retval)
- {
- case 'immobile_namespace':
- if($fromTalk->isMovable())
- {
- $r['talkmove-error-code'] = 'immobilenamespace-from';
- $r['talkmove-error-info'] = "Pages in the ``{$fromTalk->getNsText()}'' namespace can't be moved";
- }
- else
- {
- $r['talkmove-error-code'] = 'immobilenamespace-to';
- $r['talkmove-error-info'] = "Pages in the ``{$toTalk->getNsText()}'' namespace can't be moved";
- }
- break;
- case 'articleexists':
- $r['talkmove-error-code'] = 'targetexists';
- $r['talkmove-error-info'] = "``{$toTalk->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTalk->getPrefixedText()}''";
- break;
- case 'protectedpage':
- $r['talkmove-error-code'] = 'permissiondenied';
- $r['talkmove-error-info'] = "You don't have permission to move ``{$fromTalk->getPrefixedText()}'' to ``{$toTalk->getPrefixedText()}''";
- default:
- $r['talkmove-error-code'] = 'unknownerror';
- $r['talkmove-error-info'] = "Unknown error ``$retval''";
- }
+ {
+ $r['talkmove-error-code'] = ApiBase::$messageMap[$retval]['code'];
+ $r['talkmove-error-info'] = ApiBase::$messageMap[$retval]['info'];
+ }
}
$dbw->commit(); // Make sure all changes are really written to the DB
$this->getResult()->addValue(null, $this->getModuleName(), $r);
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'from' => null,

Modified: branches/ApiEdit_Vodafone/includes/api/ApiProtect.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiProtect.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiProtect.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -43,24 +43,23 @@

$titleObj = NULL;
if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
+ $this->dieUsageMsg(array('missingparam', 'title'));
if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));
if(!isset($params['protections']) || empty($params['protections']))
- $this->dieUsage('The protections parameter must be set', 'noprotections');
+ $this->dieUsageMsg(array('missingparam', 'protections'));

- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
+ $this->dieUsageMsg(array('sessionfailure'));

$titleObj = Title::newFromText($params['title']);
if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
- if(!$titleObj->userCan('protect'))
- $this->dieUsage('You don\'t have permission to change protection levels', 'permissiondenied');
+ $this->dieUsageMsg(array('invalidtitle', $params['title']));
+
+ $errors = $titleObj->getUserPermissionsErrors('protect', $wgUser);
+ if(!empty($errors))
+ // We don't care about multiple errors, just report one of them
+ $this->dieUsageMsg(current($errors));

if(in_array($params['expiry'], array('infinite', 'indefinite', 'never')))
$expiry = Block::infinity();
@@ -68,11 +67,11 @@
{
$expiry = strtotime($params['expiry']);
if($expiry < 0 || $expiry == false)
- $this->dieUsage('Invalid expiry time', 'invalidexpiry');
+ $this->dieUsageMsg(array('invalidexpiry'));

$expiry = wfTimestamp(TS_MW, $expiry);
if($expiry < wfTimestampNow())
- $this->dieUsage('Expiry time is in the past', 'pastexpiry');
+ $this->dieUsageMsg(array('pastexpiry'));
}

$protections = array();
@@ -81,9 +80,9 @@
$p = explode('=', $prot);
$protections[$p[0]] = ($p[1] == 'all' ? '' : $p[1]);
if($titleObj->exists() && $p[0] == 'create')
- $this->dieUsage("Existing titles can't be protected with 'create'", 'create-titleexists');
+ $this->dieUsageMsg(array('create-titleexists'));
if(!$titleObj->exists() && $p[0] != 'create')
- $this->dieUsage("Missing titles can only be protected with 'create'", 'missingtitle');
+ $this->dieUsageMsg(array('missingtitles-createonly'));
}

$dbw = wfGetDb(DB_MASTER);
@@ -95,15 +94,23 @@
$ok = $titleObj->updateTitleProtection($protections['create'], $params['reason'], $expiry);
if(!$ok)
// This is very weird. Maybe the article was deleted or the user was blocked/desysopped in the meantime?
- $this->dieUsage('Unknown error', 'unknownerror');
+ // Just throw an unknown error in this case, as it's very likely to be a race condition
+ $this->dieUsageMsg(array());
$dbw->commit();
- $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason'], 'expiry' => wfTimestamp(TS_ISO_8601, $expiry));
+ $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason']);
+ if($expiry == Block::infinity())
+ $res['expiry'] = 'infinity';
+ else
+ $res['expiry'] = wfTimestamp(TS_ISO_8601, $expiry);
+
if($params['cascade'])
$res['cascade'] = '';
$res['protections'] = $protections;
$this->getResult()->addValue(null, $this->getModuleName(), $res);
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'title' => null,

Modified: branches/ApiEdit_Vodafone/includes/api/ApiQueryAllmessages.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiQueryAllmessages.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiQueryAllmessages.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -42,6 +42,13 @@
public function execute() {
global $wgMessageCache;
$params = $this->extractRequestParams();
+
+ if(!is_null($params['lang']))
+ {
+ global $wgLang;
+ $wgLang = Language::factory($params['lang']);
+ }
+

//Determine which messages should we print
$messages_target = array();
@@ -93,6 +100,7 @@
ApiBase :: PARAM_DFLT => '*',
),
'filter' => array(),
+ 'lang' => null,
);
}

@@ -100,6 +108,7 @@
return array (
'messages' => 'Which messages to output. "*" means all messages',
'filter' => 'Return only messages that contains specified string',
+ 'lang' => 'Language code',
);
}

@@ -110,7 +119,7 @@
protected function getExamples() {
return array(
'api.php?action=query&meta=allmessages&amfilter=ipb-',
- 'api.php?action=query&meta=allmessages&ammessages=august|mainpage',
+ 'api.php?action=query&meta=allmessages&ammessages=august|mainpage&amlang=de',
);
}


Modified: branches/ApiEdit_Vodafone/includes/api/ApiQueryAllpages.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiQueryAllpages.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiQueryAllpages.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -95,10 +95,22 @@
$this->dieUsage('prlevel may not be used without prtype', 'params');
}

- $this->addTables('page');
+ if($params['filterlanglinks'] == 'withoutlanglinks') {
+ $pageName = $this->getDB()->tableName('page');
+ $llName = $this->getDB()->tableName('langlinks');
+ $tables = "$pageName LEFT JOIN $llName ON page_id=ll_from";
+ $this->addWhere('ll_from IS NULL');
+ $this->addTables($tables);
+ $forceNameTitleIndex = false;
+ } else if($params['filterlanglinks'] == 'withlanglinks') {
+ $this->addTables(array('page', 'langlinks'));
+ $this->addWhere('page_id=ll_from');
+ $forceNameTitleIndex = false;
+ } else {
+ $this->addTables('page');
+ }
if ($forceNameTitleIndex)
$this->addOption('USE INDEX', 'name_title');
-

if (is_null($resultPageSet)) {
$this->addFields(array (
@@ -191,6 +203,14 @@
'ascending',
'descending'
)
+ ),
+ 'filterlanglinks' => array(
+ ApiBase :: PARAM_TYPE => array(
+ 'withlanglinks',
+ 'withoutlanglinks',
+ 'all'
+ ),
+ ApiBase :: PARAM_DFLT => 'all'
)
);
}
@@ -206,6 +226,7 @@
'maxsize' => 'Limit to pages with at most this many bytes',
'prtype' => 'Limit to protected pages only',
'prlevel' => 'The protection level (must be used with apprtype= parameter)',
+ 'filterlanglinks' => 'Filter based on whether a page has langlinks',
'limit' => 'How many total pages to return.'
);
}

Modified: branches/ApiEdit_Vodafone/includes/api/ApiQueryImageInfo.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiQueryImageInfo.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiQueryImageInfo.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -42,16 +42,20 @@
public function execute() {
$params = $this->extractRequestParams();

- $history = $params['history'];
-
$prop = array_flip($params['prop']);
- $fld_timestamp = isset($prop['timestamp']);
- $fld_user = isset($prop['user']);
- $fld_comment = isset($prop['comment']);
- $fld_url = isset($prop['url']);
- $fld_size = isset($prop['size']);
- $fld_sha1 = isset($prop['sha1']);
- $fld_metadata = isset($prop['metadata']);
+ $this->fld_timestamp = isset($prop['timestamp']);
+ $this->fld_user = isset($prop['user']);
+ $this->fld_comment = isset($prop['comment']);
+ $this->fld_url = isset($prop['url']);
+ $this->fld_size = isset($prop['size']);
+ $this->fld_sha1 = isset($prop['sha1']);
+ $this->fld_metadata = isset($prop['metadata']);
+
+ if($params['urlheight'] != -1 && $params['urlwidth'] == -1)
+ $this->dieUsage("iiurlheight cannot be used without iiurlwidth", 'iiurlwidth');
+ $this->scale = ($params['urlwidth'] != -1);
+ $this->urlwidth = $params['urlwidth'];
+ $this->urlheight = $params['urlheight'];

$pageIds = $this->getPageSet()->getAllTitlesByNamespace();
if (!empty($pageIds[NS_IMAGE])) {
@@ -66,54 +70,21 @@
} else {

$repository = $img->getRepoName();
-
- $isCur = true;
- $count = 0;
- while($line = $img->nextHistoryLine()) { // assignment
- # FIXME: Limiting to 500 because it's unlimited right now
- # 500+ image histories are scarce, but this has DoS potential
- # FileRepo.php should be fixed
- if($count++ == 500)
- break;
- $row = get_object_vars( $line );
- $vals = array();
- $prefix = $isCur ? 'img' : 'oi';
-
- if ($fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row["${prefix}_timestamp"]);
- if ($fld_user) {
- $vals['user'] = $row["${prefix}_user_text"];
- if(!$row["${prefix}_user"])
- $vals['anon'] = '';
- }
- if ($fld_size) {
- $vals['size'] = intval($row["{$prefix}_size"]);
- $vals['width'] = intval($row["{$prefix}_width"]);
- $vals['height'] = intval($row["{$prefix}_height"]);
- }
- if ($fld_url)
- $vals['url'] = $isCur ? $img->getURL() : $img->getArchiveUrl($row["oi_archive_name"]);
- if ($fld_comment)
- $vals['comment'] = $row["{$prefix}_description"];
-
- if ($fld_sha1)
- $vals['sha1'] = wfBaseConvert($row["{$prefix}_sha1"], 36, 16, 40);
-
- if ($fld_metadata) {
- $metadata = unserialize($row["{$prefix}_metadata"]);
- $vals['metadata'] = $metadata ? $metadata : null;
- $this->getResult()->setIndexedTagName_recursive($vals['metadata'], 'meta');
- }
-
- $data[] = $vals;
-
- if (!$history) // Stop after the first line.
- break;
-
- $isCur = false;
+
+ // Get information about the current version first
+ // Check that the current version is within the start-end boundaries
+ if((is_null($params['start']) || $img->getTimestamp() <= $params['start']) &&
+ (is_null($params['end']) || $img->getTimestamp() >= $params['end'])) {
+ $data[] = $this->getInfo($img);
}

- $img->resetHistory();
+ // Now get the old revisions
+ if($params['limit'] > 1) {
+ $oldies = $img->getHistory($params['limit'] - 1, $params['start'], $params['end']);
+ if(!empty($oldies))
+ foreach($oldies as $oldie)
+ $data[] = $this->getInfo($oldie);
+ }
}

$this->getResult()->addValue(array(
@@ -126,6 +97,44 @@
}
}

+ /**
+ * Get result information for an image revision
+ * @param File f The image
+ * @return array Result array
+ */
+ protected function getInfo($f) {
+ $vals = array();
+ if($this->fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $f->getTimestamp());
+ if($this->fld_user) {
+ $vals['user'] = $f->getUser();
+ if(!$f->getUser('id'))
+ $vals['anon'] = '';
+ }
+ if($this->fld_size) {
+ $vals['size'] = $f->getSize();
+ $vals['width'] = $f->getWidth();
+ $vals['height'] = $f->getHeight();
+ }
+ if($this->fld_url) {
+ if($this->scale && !$f->isOld()) {
+ $vals['url'] = $f->createThumb($this->urlwidth, $this->urlheight);
+ } else {
+ $vals['url'] = $f->getURL();
+ }
+ }
+ if($this->fld_comment)
+ $vals['comment'] = $f->getDescription();
+ if($this->fld_sha1)
+ $vals['sha1'] = $f->getSha1();
+ if($this->fld_metadata) {
+ $metadata = unserialize($f->getMetadata());
+ $vals['metadata'] = $metadata ? $metadata : null;
+ $this->getResult()->setIndexedTagName_recursive($vals['metadata'], 'meta');
+ }
+ return $vals;
+ }
+
protected function getAllowedParams() {
return array (
'prop' => array (
@@ -141,14 +150,38 @@
'metadata'
)
),
- 'history' => false,
+ 'limit' => array(
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_DFLT => 1,
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'start' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'urlwidth' => array(
+ ApiBase :: PARAM_TYPE => 'integer',
+ ApiBase :: PARAM_DFLT => -1
+ ),
+ 'urlheight' => array(
+ ApiBase :: PARAM_TYPE => 'integer',
+ ApiBase :: PARAM_DFLT => -1
+ )
);
}

protected function getParamDescription() {
return array (
'prop' => 'What image information to get.',
- 'history' => 'Include upload history',
+ 'limit' => 'How many image revisions to return',
+ 'start' => 'Timestamp to start listing from',
+ 'end' => 'Timestamp to stop listing at',
+ 'urlwidth' => 'If iiprop=url is set, a URL to an image scaled to this width will be returned. Only the current version of the image can be scaled.',
+ 'urlheight' => 'Similar to iiurlwidth. Cannot be used without iiurlwidth',
);
}

@@ -161,7 +194,7 @@
protected function getExamples() {
return array (
'api.php?action=query&titles=Image:Albert%20Einstein%20Head.jpg&prop=imageinfo',
- 'api.php?action=query&titles=Image:Test.jpg&prop=imageinfo&iihistory&iiprop=timestamp|user|url',
+ 'api.php?action=query&titles=Image:Test.jpg&prop=imageinfo&iilimit=50&iiend=20071231235959&iiprop=timestamp|user|url',
);
}


Modified: branches/ApiEdit_Vodafone/includes/api/ApiRollback.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiRollback.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiRollback.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -43,32 +43,31 @@

$titleObj = NULL;
if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
+ $this->dieUsageMsg(array('missingparam', 'title'));
if(!isset($params['user']))
- $this->dieUsage('The user parameter must be set', 'nouser');
+ $this->dieUsageMsg(array('missingparam', 'user'));
if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));

- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
$titleObj = Title::newFromText($params['title']);
if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ $this->dieUsageMsg(array('invalidtitle', $params['title']));
+ if(!$titleObj->exists())
+ $this->dieUsageMsg(array('notanarticle'));

$username = User::getCanonicalName($params['user']);
if(!$username)
- $this->dieUsage("Invalid username ``{$params['user']}''", 'invaliduser');
+ $this->dieUsageMsg(array('invaliduser', $params['user']));

$articleObj = new Article($titleObj);
$summary = (isset($params['summary']) ? $params['summary'] : "");
$details = null;
$dbw = wfGetDb(DB_MASTER);
$dbw->begin();
- $retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], &$details);
+ $retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], $details);

if(!empty($retval))
- // We don't care about multiple errors, just report the first one
+ // We don't care about multiple errors, just report one of them
$this->dieUsageMsg(current($retval));

$dbw->commit();
@@ -87,6 +86,8 @@
$this->getResult()->addValue(null, $this->getModuleName(), $info);
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'title' => null,

Modified: branches/ApiEdit_Vodafone/includes/api/ApiUnblock.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiUnblock.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiUnblock.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -41,7 +41,7 @@

/**
* Unblocks the specified user or provides the reason the unblock failed.
- */
+ */
public function execute() {
global $wgUser;
$this->getMain()->requestWriteMode();
@@ -55,47 +55,35 @@
}

if(is_null($params['id']) && is_null($params['user']))
- $this->dieUsage('Either the id or the user parameter must be set', 'notarget');
+ $this->dieUsageMsg(array('unblock-notarget'));
if(!is_null($params['id']) && !is_null($params['user']))
- $this->dieUsage('The id and user parameters can\'t be used together', 'idanduser');
+ $this->dieUsageMsg(array('unblock-idanduser'));
if(is_null($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));
if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
+ $this->dieUsageMsg(array('sessionfailure'));
if(!$wgUser->isAllowed('block'))
- $this->dieUsage('You don\'t have permission to unblock users', 'permissiondenied');
+ $this->dieUsageMsg(array('cantunblock'));
if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ $this->dieUsageMsg(array('readonlytext'));

$id = $params['id'];
$user = $params['user'];
- $reason = $params['reason'];
+ $reason = (is_null($params['reason']) ? '' : $params['reason']);
$dbw = wfGetDb(DB_MASTER);
$dbw->begin();
- $retval = IPUnblockForm::doUnblock(&$id, &$user, &$reason, &$range);
+ $retval = IPUnblockForm::doUnblock($id, $user, $reason, $range);
+ if(!empty($retval))
+ $this->dieUsageMsg($retval);

- switch($retval)
- {
- case IPUnblockForm::UNBLOCK_SUCCESS:
- break; // We'll deal with that later
- case IPUnblockForm::UNBLOCK_NO_SUCH_ID:
- $this->dieUsage("There is no block with ID ``$id''", 'nosuchid');
- case IPUnblockForm::UNBLOCK_USER_NOT_BLOCKED:
- $this->dieUsage("User ``$user'' is not blocked", 'notblocked');
- case IPUnblockForm::UNBLOCK_BLOCKED_AS_RANGE:
- $this->dieUsage("IP address ``$user'' was blocked as part of range ``$range''. You can't unblock the IP invidually, but you can unblock the range as a whole.", 'blockedasrange');
- case IPUnblockForm::UNBLOCK_UNKNOWNERR:
- $this->dieUsage("Unknown error", 'unknownerr');
- default:
- $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
- }
$dbw->commit();
-
$res['id'] = $id;
$res['user'] = $user;
$res['reason'] = $reason;
$this->getResult()->addValue(null, $this->getModuleName(), $res);
}
+
+ public function mustBePosted() { return true; }

protected function getAllowedParams() {
return array (

Modified: branches/ApiEdit_Vodafone/includes/api/ApiUndelete.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/api/ApiUndelete.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/api/ApiUndelete.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -43,22 +43,22 @@

$titleObj = NULL;
if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
+ $this->dieUsageMsg(array('missingparam', 'title'));
if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
+ $this->dieUsageMsg(array('missingparam', 'token'));

if(!$wgUser->isAllowed('undelete'))
- $this->dieUsage('You don\'t have permission to restore deleted revisions', 'permissiondenied');
+ $this->dieUsageMsg(array('permdenied-undelete'));
if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
+ $this->dieUsageMsg(array('blockedtext'));
if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ $this->dieUsageMsg(array('readonlytext'));
if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
+ $this->dieUsageMsg(array('sessionfailure'));

$titleObj = Title::newFromText($params['title']);
if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ $this->dieUsageMsg(array('invalidtitle', $params['title']));

// Convert timestamps
if(!is_array($params['timestamps']))
@@ -71,17 +71,9 @@
$dbw->begin();
$retval = $pa->undelete((isset($params['timestamps']) ? $params['timestamps'] : array()), $params['reason']);
if(!is_array($retval))
- switch($retval)
- {
- case PageArchive::UNDELETE_NOTHINGRESTORED:
- $this->dieUsage('No revisions could be restored', 'norevs');
- case PageArchive::UNDELETE_NOTAVAIL:
- $this->dieUsage('Not all requested revisions could be found', 'revsnotfound');
- case PageArchive::UNDELETE_UNKNOWNERR:
- $this->dieUsage('Undeletion failed with unknown error', 'unknownerror');
- }
+ $this->dieUsageMsg(array('cannotundelete'));
+
$dbw->commit();
-
$info['title'] = $titleObj->getPrefixedText();
$info['revisions'] = $retval[0];
$info['fileversions'] = $retval[1];
@@ -89,6 +81,8 @@
$this->getResult()->addValue(null, $this->getModuleName(), $info);
}

+ public function mustBePosted() { return true; }
+
protected function getAllowedParams() {
return array (
'title' => null,

Modified: branches/ApiEdit_Vodafone/includes/filerepo/File.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/filerepo/File.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/filerepo/File.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -46,7 +46,7 @@
/**
* The following member variables are not lazy-initialised
*/
- var $repo, $title, $lastError;
+ var $repo, $title, $lastError, $redirected;

/**
* Call this constructor from child classes
@@ -220,6 +220,14 @@
public function getHeight( $page = 1 ) { return false; }

/**
+ * Returns ID or name of user who uploaded the file
+ * STUB
+ *
+ * @param $type string 'text' or 'id'
+ */
+ public function getUser( $type='text' ) { return null; }
+
+ /**
* Get the duration of a media file in seconds
*/
public function getLength() {
@@ -628,6 +636,18 @@
}

/**
+ * Return a fragment of the history of file.
+ *
+ * STUB
+ * @param $limit integer Limit of rows to return
+ * @param $start timestamp Only revisions older than $start will be returned
+ * @param $end timestamp Only revisions newer than $end will be returned
+ */
+ function getHistory($limit = null, $start = null, $end = null) {
+ return false;
+ }
+
+ /**
* Return the history of this file, line by line. Starts with current version,
* then old versions. Should return an object similar to an image/oldimage
* database row.
@@ -994,6 +1014,14 @@
}

/**
+ * Get discription of file revision
+ * STUB
+ */
+ function getDescription() {
+ return null;
+ }
+
+ /**
* Get the 14-character timestamp of the file upload, or false if
* it doesn't exist
*/
@@ -1131,6 +1159,14 @@
return '';
}
}
+
+ function getRedirected() {
+ return $this->redirected;
+ }
+
+ function redirectedFrom( $from ) {
+ $this->redirected = $from;
+ }
}
/**
* Aliases for backwards compatibility with 1.6

Modified: branches/ApiEdit_Vodafone/includes/filerepo/FileRepo.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/filerepo/FileRepo.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/filerepo/FileRepo.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -90,6 +90,19 @@
if ( $img->exists() ) {
return $img;
}
+
+ # Now try redirects
+ $redir = $this->checkRedirect( $title );
+ if( $redir && $redir->getNamespace() == NS_IMAGE) {
+ $img = $this->newFile( $redir );
+ if( !$img ) {
+ return false;
+ }
+ if( $img->exists() ) {
+ $img->redirectedFrom( $title->getText() );
+ return $img;
+ }
+ }
}

/**
@@ -400,5 +413,15 @@
* STUB
*/
function cleanupDeletedBatch( $storageKeys ) {}
+
+ /**
+ * Checks if there is a redirect named as $title
+ * STUB
+ *
+ * @param Title $title Title of image
+ */
+ function checkRedirect( $title ) {
+ return false;
+ }
}


Modified: branches/ApiEdit_Vodafone/includes/filerepo/LocalFile.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/filerepo/LocalFile.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/filerepo/LocalFile.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -5,7 +5,7 @@
/**
* Bump this number when serialized cache records may be incompatible.
*/
-define( 'MW_FILE_VERSION', 4 );
+define( 'MW_FILE_VERSION', 6 );

/**
* Class to represent a local file in the wiki's own database
@@ -29,24 +29,26 @@
/**#@+
* @private
*/
- var $fileExists, # does the file file exist on disk? (loadFromXxx)
- $historyLine, # Number of line to return by nextHistoryLine() (constructor)
- $historyRes, # result of the query for the file's history (nextHistoryLine)
- $width, # \
- $height, # |
- $bits, # --- returned by getimagesize (loadFromXxx)
- $attr, # /
- $media_type, # MEDIATYPE_xxx (bitmap, drawing, audio...)
- $mime, # MIME type, determined by MimeMagic::guessMimeType
- $major_mime, # Major mime type
- $minor_mime, # Minor mime type
- $size, # Size in bytes (loadFromXxx)
- $metadata, # Handler-specific metadata
- $timestamp, # Upload timestamp
- $sha1, # SHA-1 base 36 content hash
- $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
- $upgraded, # Whether the row was upgraded on load
- $locked; # True if the image row is locked
+ var $fileExists, # does the file file exist on disk? (loadFromXxx)
+ $historyLine, # Number of line to return by nextHistoryLine() (constructor)
+ $historyRes, # result of the query for the file's history (nextHistoryLine)
+ $width, # \
+ $height, # |
+ $bits, # --- returned by getimagesize (loadFromXxx)
+ $attr, # /
+ $media_type, # MEDIATYPE_xxx (bitmap, drawing, audio...)
+ $mime, # MIME type, determined by MimeMagic::guessMimeType
+ $major_mime, # Major mime type
+ $minor_mime, # Minor mime type
+ $size, # Size in bytes (loadFromXxx)
+ $metadata, # Handler-specific metadata
+ $timestamp, # Upload timestamp
+ $sha1, # SHA-1 base 36 content hash
+ $user, $user_text, # User, who uploaded the file
+ $description, # Description of current revision of the file
+ $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
+ $upgraded, # Whether the row was upgraded on load
+ $locked; # True if the image row is locked

/**#@-*/

@@ -155,7 +157,7 @@

function getCacheFields( $prefix = 'img_' ) {
static $fields = array( 'size', 'width', 'height', 'bits', 'media_type',
- 'major_mime', 'minor_mime', 'metadata', 'timestamp', 'sha1' );
+ 'major_mime', 'minor_mime', 'metadata', 'timestamp', 'sha1', 'user', 'user_text', 'description' );
static $results = array();
if ( $prefix == '' ) {
return $fields;
@@ -382,6 +384,20 @@
}

/**
+ * Returns ID or name of user who uploaded the file
+ *
+ * @param $type string 'text' or 'id'
+ */
+ function getUser($type='text') {
+ $this->load();
+ if( $type == 'text' ) {
+ return $this->user_text;
+ } elseif( $type == 'id' ) {
+ return $this->user;
+ }
+ }
+
+ /**
* Get handler-specific metadata
*/
function getMetadata() {
@@ -559,6 +575,28 @@
/** purgeDescription inherited */
/** purgeEverything inherited */

+ function getHistory($limit = null, $start = null, $end = null) {
+ $dbr = $this->repo->getSlaveDB();
+ $conds = $opts = array();
+ $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBKey() );
+ if( $start !== null ) {
+ $conds[] = "oi_timestamp < '" . $dbr->timestamp( $start ) . "'";
+ }
+ if( $end !== null ) {
+ $conds[] = "oi_timestamp > '" . $dbr->timestamp( $end ). "'";
+ }
+ if( $limit ) {
+ $opts['LIMIT'] = $limit;
+ }
+ $opts['ORDER BY'] = 'oi_timestamp DESC';
+ $res = $dbr->select('oldimage', '*', $conds, __METHOD__, $opts);
+ $r = array();
+ while( $row = $dbr->fetchObject($res) ) {
+ $r[] = OldLocalFile::newFromRow($row, $this->repo);
+ }
+ return $r;
+ }
+
/**
* Return the history of this file, line by line.
* starts with current version, then old versions.
@@ -682,6 +720,9 @@
if ( !$props ) {
$props = $this->repo->getFileProps( $this->getVirtualUrl() );
}
+ $props['description'] = $comment;
+ $props['user'] = $wgUser->getID();
+ $props['user_text'] = $wgUser->getName();
$this->setProps( $props );

// Delete thumbnails and refresh the metadata cache
@@ -968,6 +1009,11 @@
return $html;
}

+ function getDescription() {
+ $this->load();
+ return $this->description;
+ }
+
function getTimestamp() {
$this->load();
return $this->timestamp;

Modified: branches/ApiEdit_Vodafone/includes/filerepo/LocalRepo.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/filerepo/LocalRepo.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/filerepo/LocalRepo.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -62,4 +62,52 @@
}
return $status;
}
+
+ /**
+ * Function link Title::getArticleID().
+ * We can't say Title object, what database it should use, so we duplicate that function here.
+ */
+ private function getArticleID( $title ) {
+ if( !$title instanceof Title ) {
+ return 0;
+ }
+ $dbr = $this->getSlaveDB();
+ $id = $dbr->selectField(
+ 'page', // Table
+ 'page_id', //Field
+ array( //Conditions
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDbKey(),
+ ),
+ __METHOD__ //Function name
+ );
+ return $id;
+ }
+
+ function checkRedirect( $title ) {
+ global $wgFileRedirects;
+ if( !$wgFileRedirects ) {
+ return false;
+ }
+
+ if( $title instanceof Title && $title->getNamespace() == NS_MEDIA ) {
+ $title = Title::makeTitle( NS_IMAGE, $title->getText() );
+ }
+
+ $id = $this->getArticleID( $title );
+ if( !$id ) {
+ return false;
+ }
+ $dbr = $this->getSlaveDB();
+ $row = $dbr->selectRow(
+ 'redirect',
+ array( 'rd_title', 'rd_namespace' ),
+ array( 'rd_from' => $id ),
+ __METHOD__
+ );
+ if( !$row ) {
+ return false;
+ }
+ return Title::makeTitle( $row->rd_namespace, $row->rd_title );
+ }
}

Modified: branches/ApiEdit_Vodafone/includes/filerepo/RepoGroup.php
===================================================================
--- branches/ApiEdit_Vodafone/includes/filerepo/RepoGroup.php 2008-01-20 18:39:49 UTC (rev 29995)
+++ branches/ApiEdit_Vodafone/includes/filerepo/RepoGroup.php 2008-01-20 18:41:22 UTC (rev 29996)
@@ -77,6 +77,27 @@
}

/**
+ * Interface for FileRepo::checkRedirect()
+ */
+ function checkRedirect( $title ) {
+ if ( !$this->reposInitialised ) {
+ $this->initialiseRepos();
+ }
+
+ $redir = $this->localRepo->checkRedirect( $title );
+ if( $redir ) {
+ return $redir;
+ }
+ foreach ( $this->foreignRepos as $repo ) {
+ $redir = $repo->checkRedirect( $title );
+ if ( $redir ) {
+ return $redir;
+ }
+ }
+ return false;
+ }
+
+ /**
* Get the repo instance with a given key.
*/
function getRepo( $index ) {



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS [at] lists
http://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Wikipedia mediawiki-cvs RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.