2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* File for articles
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-08-02 20:43:11 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2005-04-12 02:18:57 +00:00
|
|
|
* Class representing a MediaWiki article and history.
|
2004-09-02 23:28:24 +00:00
|
|
|
*
|
2005-04-12 02:07:16 +00:00
|
|
|
* See design.txt for an overview.
|
2004-09-02 23:28:24 +00:00
|
|
|
* Note: edit user interface and cache support functions have been
|
2006-10-11 08:25:26 +00:00
|
|
|
* moved to separate EditPage and HTMLFileCache classes.
|
2004-09-03 00:20:26 +00:00
|
|
|
*
|
2010-03-15 23:22:50 +00:00
|
|
|
* @internal documentation reviewed 15 Mar 2010
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-04-14 23:10:40 +00:00
|
|
|
class Article {
|
2007-03-28 14:16:43 +00:00
|
|
|
/**@{{
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
|
|
|
|
*/
|
2011-04-25 11:59:31 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var RequestContext
|
|
|
|
|
*/
|
|
|
|
|
protected $mContext;
|
2011-04-12 23:00:49 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
var $mContent; // !<
|
|
|
|
|
var $mContentLoaded = false; // !<
|
|
|
|
|
var $mCounter = -1; // !< Not loaded
|
|
|
|
|
var $mDataLoaded = false; // !<
|
|
|
|
|
var $mIsRedirect = false; // !<
|
|
|
|
|
var $mLatest = false; // !<
|
|
|
|
|
var $mOldId; // !<
|
2011-04-25 11:59:31 +00:00
|
|
|
var $mPreparedEdit = false;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Title
|
|
|
|
|
*/
|
|
|
|
|
var $mRedirectedFrom = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Title
|
|
|
|
|
*/
|
|
|
|
|
var $mRedirectTarget = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Title
|
|
|
|
|
*/
|
2010-02-14 22:07:30 +00:00
|
|
|
var $mRedirectUrl = false; // !<
|
|
|
|
|
var $mRevIdFetched = 0; // !<
|
2011-04-25 11:59:31 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Revision
|
|
|
|
|
*/
|
|
|
|
|
var $mLastRevision = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Revision
|
|
|
|
|
*/
|
|
|
|
|
var $mRevision = null;
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
var $mTimestamp = ''; // !<
|
2010-03-15 14:05:54 +00:00
|
|
|
var $mTitle; // !< Title object
|
2010-02-14 22:07:30 +00:00
|
|
|
var $mTouched = '19700101000000'; // !<
|
2011-04-25 11:59:31 +00:00
|
|
|
|
|
|
|
|
/**
|
2011-06-07 22:28:57 +00:00
|
|
|
* @var ParserOptions: ParserOptions object for $wgUser articles
|
2011-04-25 11:59:31 +00:00
|
|
|
*/
|
|
|
|
|
var $mParserOptions;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var ParserOutput
|
|
|
|
|
*/
|
|
|
|
|
var $mParserOutput;
|
|
|
|
|
|
2007-03-28 14:16:43 +00:00
|
|
|
/**@}}*/
|
2004-09-02 23:28:24 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructor and clear the article
|
2011-05-28 18:58:51 +00:00
|
|
|
* @param $title Title Reference to a Title object.
|
2006-04-19 15:46:24 +00:00
|
|
|
* @param $oldId Integer revision ID, null to fetch from request, zero for current
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function __construct( Title $title, $oldId = null ) {
|
2011-05-17 22:03:20 +00:00
|
|
|
// @todo FIXME: Does the reference play any role here?
|
2003-09-01 08:30:14 +00:00
|
|
|
$this->mTitle =& $title;
|
2005-12-30 09:33:11 +00:00
|
|
|
$this->mOldId = $oldId;
|
2003-09-01 08:30:14 +00:00
|
|
|
}
|
2008-08-21 00:45:13 +00:00
|
|
|
|
2011-05-22 18:38:04 +00:00
|
|
|
/**
|
|
|
|
|
* Create an Article object of the appropriate class for the given page.
|
|
|
|
|
*
|
|
|
|
|
* @param $title Title
|
|
|
|
|
* @param $context RequestContext
|
|
|
|
|
* @return Article object
|
|
|
|
|
*/
|
|
|
|
|
public static function newFromTitle( $title, RequestContext $context ) {
|
|
|
|
|
if ( NS_MEDIA == $title->getNamespace() ) {
|
|
|
|
|
// FIXME: where should this go?
|
|
|
|
|
$title = Title::makeTitle( NS_FILE, $title->getDBkey() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$article = null;
|
|
|
|
|
wfRunHooks( 'ArticleFromTitle', array( &$title, &$article ) );
|
|
|
|
|
if ( $article ) {
|
|
|
|
|
$article->setContext( $context );
|
|
|
|
|
return $article;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch( $title->getNamespace() ) {
|
|
|
|
|
case NS_FILE:
|
|
|
|
|
$page = new ImagePage( $title );
|
|
|
|
|
break;
|
|
|
|
|
case NS_CATEGORY:
|
|
|
|
|
$page = new CategoryPage( $title );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$page = new Article( $title );
|
|
|
|
|
}
|
|
|
|
|
$page->setContext( $context );
|
|
|
|
|
return $page;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-16 13:34:43 +00:00
|
|
|
/**
|
2010-06-28 07:17:16 +00:00
|
|
|
* Constructor from an page id
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $id Int article ID to load
|
2008-08-16 13:34:43 +00:00
|
|
|
*/
|
|
|
|
|
public static function newFromID( $id ) {
|
|
|
|
|
$t = Title::newFromID( $id );
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: Doesn't inherit right
|
2009-11-05 16:30:56 +00:00
|
|
|
return $t == null ? null : new self( $t );
|
2010-02-14 22:07:30 +00:00
|
|
|
# return $t == null ? null : new static( $t ); // PHP 5.3
|
2008-08-16 13:34:43 +00:00
|
|
|
}
|
2006-11-20 05:41:53 +00:00
|
|
|
|
2006-01-13 00:29:20 +00:00
|
|
|
/**
|
|
|
|
|
* Tell the page view functions that this view was redirected
|
|
|
|
|
* from another page on the wiki.
|
2006-04-19 15:46:24 +00:00
|
|
|
* @param $from Title object.
|
2006-01-13 00:29:20 +00:00
|
|
|
*/
|
2010-03-14 23:20:40 +00:00
|
|
|
public function setRedirectedFrom( Title $from ) {
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->mRedirectedFrom = $from;
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2008-04-11 15:20:45 +00:00
|
|
|
/**
|
|
|
|
|
* If this page is a redirect, get its target
|
|
|
|
|
*
|
|
|
|
|
* The target will be fetched from the redirect table if possible.
|
|
|
|
|
* If this page doesn't have an entry there, call insertRedirect()
|
2011-05-21 20:06:57 +00:00
|
|
|
* @return Title|mixed object, or null if this page is not a redirect
|
2008-04-11 15:20:45 +00:00
|
|
|
*/
|
|
|
|
|
public function getRedirectTarget() {
|
2010-06-28 07:17:16 +00:00
|
|
|
if ( !$this->mTitle->isRedirect() ) {
|
2008-04-11 15:20:45 +00:00
|
|
|
return null;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-28 07:17:16 +00:00
|
|
|
if ( $this->mRedirectTarget !== null ) {
|
2008-04-11 15:20:45 +00:00
|
|
|
return $this->mRedirectTarget;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-11 15:20:45 +00:00
|
|
|
# Query the redirect table
|
2008-11-28 14:29:25 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-02-18 19:37:23 +00:00
|
|
|
$row = $dbr->selectRow( 'redirect',
|
2010-07-08 10:49:36 +00:00
|
|
|
array( 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ),
|
2010-02-14 22:07:30 +00:00
|
|
|
array( 'rd_from' => $this->getID() ),
|
2008-11-28 14:29:25 +00:00
|
|
|
__METHOD__
|
2008-04-11 15:20:45 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-07-08 10:49:36 +00:00
|
|
|
// rd_fragment and rd_interwiki were added later, populate them if empty
|
|
|
|
|
if ( $row && !is_null( $row->rd_fragment ) && !is_null( $row->rd_interwiki ) ) {
|
|
|
|
|
return $this->mRedirectTarget = Title::makeTitle(
|
|
|
|
|
$row->rd_namespace, $row->rd_title,
|
|
|
|
|
$row->rd_fragment, $row->rd_interwiki );
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-04-11 15:20:45 +00:00
|
|
|
# This page doesn't have an entry in the redirect table
|
|
|
|
|
return $this->mRedirectTarget = $this->insertRedirect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Insert an entry for this page into the redirect table.
|
|
|
|
|
*
|
|
|
|
|
* Don't call this function directly unless you know what you're doing.
|
2010-07-08 10:49:36 +00:00
|
|
|
* @return Title object or null if not a redirect
|
2008-04-11 15:20:45 +00:00
|
|
|
*/
|
|
|
|
|
public function insertRedirect() {
|
2010-07-08 10:49:36 +00:00
|
|
|
// recurse through to only get the final target
|
2011-01-09 11:46:15 +00:00
|
|
|
$retval = Title::newFromRedirectRecurse( $this->getRawText() );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$retval ) {
|
2008-04-11 15:20:45 +00:00
|
|
|
return null;
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2010-07-08 10:49:36 +00:00
|
|
|
$this->insertRedirectEntry( $retval );
|
|
|
|
|
return $retval;
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-07-08 10:49:36 +00:00
|
|
|
/**
|
|
|
|
|
* Insert or update the redirect table entry for this page to indicate
|
|
|
|
|
* it redirects to $rt .
|
|
|
|
|
* @param $rt Title redirect target
|
|
|
|
|
*/
|
|
|
|
|
public function insertRedirectEntry( $rt ) {
|
2008-11-28 14:29:25 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2010-02-14 22:07:30 +00:00
|
|
|
$dbw->replace( 'redirect', array( 'rd_from' ),
|
2008-11-28 14:29:25 +00:00
|
|
|
array(
|
2008-04-11 15:20:45 +00:00
|
|
|
'rd_from' => $this->getID(),
|
2010-07-08 10:49:36 +00:00
|
|
|
'rd_namespace' => $rt->getNamespace(),
|
|
|
|
|
'rd_title' => $rt->getDBkey(),
|
|
|
|
|
'rd_fragment' => $rt->getFragment(),
|
|
|
|
|
'rd_interwiki' => $rt->getInterwiki(),
|
2008-11-28 14:29:25 +00:00
|
|
|
),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
2008-04-11 15:20:45 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-13 00:29:20 +00:00
|
|
|
/**
|
2010-07-08 10:49:36 +00:00
|
|
|
* Get the Title object or URL this page redirects to
|
2008-04-15 17:32:23 +00:00
|
|
|
*
|
2006-01-13 00:29:20 +00:00
|
|
|
* @return mixed false, Title of in-wiki target, or string with URL
|
|
|
|
|
*/
|
2008-07-04 09:38:12 +00:00
|
|
|
public function followRedirect() {
|
2010-07-08 10:49:36 +00:00
|
|
|
return $this->getRedirectURL( $this->getRedirectTarget() );
|
2008-07-04 09:38:12 +00:00
|
|
|
}
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2008-07-04 09:38:12 +00:00
|
|
|
/**
|
|
|
|
|
* Get the Title object this text redirects to
|
|
|
|
|
*
|
2010-03-14 23:20:40 +00:00
|
|
|
* @param $text string article content containing redirect info
|
2008-07-04 09:38:12 +00:00
|
|
|
* @return mixed false, Title of in-wiki target, or string with URL
|
2011-03-12 18:14:33 +00:00
|
|
|
* @deprecated since 1.17
|
2008-07-04 09:38:12 +00:00
|
|
|
*/
|
|
|
|
|
public function followRedirectText( $text ) {
|
2010-06-28 07:17:16 +00:00
|
|
|
// recurse through to only get the final target
|
2010-07-08 10:49:36 +00:00
|
|
|
return $this->getRedirectURL( Title::newFromRedirectRecurse( $text ) );
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-07-08 10:49:36 +00:00
|
|
|
/**
|
|
|
|
|
* Get the Title object or URL to use for a redirect. We use Title
|
|
|
|
|
* objects for same-wiki, non-special redirects and URLs for everything
|
|
|
|
|
* else.
|
|
|
|
|
* @param $rt Title Redirect target
|
|
|
|
|
* @return mixed false, Title object of local target, or string with URL
|
|
|
|
|
*/
|
|
|
|
|
public function getRedirectURL( $rt ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $rt ) {
|
|
|
|
|
if ( $rt->getInterwiki() != '' ) {
|
|
|
|
|
if ( $rt->isLocal() ) {
|
2006-01-13 00:29:20 +00:00
|
|
|
// Offsite wikis need an HTTP redirect.
|
|
|
|
|
//
|
|
|
|
|
// This can be hard to reverse and may produce loops,
|
|
|
|
|
// so they may be disabled in the site configuration.
|
|
|
|
|
$source = $this->mTitle->getFullURL( 'redirect=no' );
|
|
|
|
|
return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) );
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $rt->getNamespace() == NS_SPECIAL ) {
|
2006-11-23 08:25:56 +00:00
|
|
|
// Gotta handle redirects to special pages differently:
|
2006-01-13 00:29:20 +00:00
|
|
|
// Fill the HTTP response "Location" header and ignore
|
|
|
|
|
// the rest of the page we're on.
|
|
|
|
|
//
|
|
|
|
|
// This can be hard to reverse, so they may be disabled.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $rt->isSpecial( 'Userlogout' ) ) {
|
2006-01-13 00:29:20 +00:00
|
|
|
// rolleyes
|
|
|
|
|
} else {
|
|
|
|
|
return $rt->getFullURL();
|
|
|
|
|
}
|
2006-03-11 17:13:49 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-01-14 21:19:17 +00:00
|
|
|
return $rt;
|
2006-01-13 00:29:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-01-13 00:29:20 +00:00
|
|
|
// No or invalid redirect
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2004-12-29 01:07:43 +00:00
|
|
|
/**
|
2010-06-28 07:17:16 +00:00
|
|
|
* Get the title object of the article
|
|
|
|
|
* @return Title object of this page
|
2004-12-29 01:07:43 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getTitle() {
|
2005-07-01 00:03:31 +00:00
|
|
|
return $this->mTitle;
|
2004-12-29 01:07:43 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2008-11-30 10:10:15 +00:00
|
|
|
* Clear the object
|
2011-05-17 22:03:20 +00:00
|
|
|
* @todo FIXME: Shouldn't this be public?
|
2008-11-30 10:10:15 +00:00
|
|
|
* @private
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function clear() {
|
2005-03-18 08:37:50 +00:00
|
|
|
$this->mDataLoaded = false;
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->mContentLoaded = false;
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2011-04-10 06:32:50 +00:00
|
|
|
$this->mCounter = -1; # Not loaded
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->mRedirectedFrom = null; # Title object if set
|
2008-04-11 15:20:45 +00:00
|
|
|
$this->mRedirectTarget = null; # Title object if set
|
2011-04-10 06:32:50 +00:00
|
|
|
$this->mLastRevision = null; # Latest revision
|
|
|
|
|
$this->mTimestamp = '';
|
2004-06-08 19:51:10 +00:00
|
|
|
$this->mTouched = '19700101000000';
|
2005-03-18 08:37:50 +00:00
|
|
|
$this->mIsRedirect = false;
|
2005-03-29 16:38:30 +00:00
|
|
|
$this->mRevIdFetched = 0;
|
2005-12-30 09:33:11 +00:00
|
|
|
$this->mRedirectUrl = false;
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->mLatest = false;
|
2007-11-12 07:30:40 +00:00
|
|
|
$this->mPreparedEdit = false;
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2006-01-13 00:29:20 +00:00
|
|
|
* Note that getContent/loadContent do not follow redirects anymore.
|
|
|
|
|
* If you need to fetch redirectable content easily, try
|
2010-05-30 18:09:03 +00:00
|
|
|
* the shortcut in Article::followRedirect()
|
2004-09-02 23:28:24 +00:00
|
|
|
*
|
2010-06-28 07:17:16 +00:00
|
|
|
* This function has side effects! Do not use this function if you
|
|
|
|
|
* only want the real revision text if any.
|
|
|
|
|
*
|
2004-09-03 00:20:26 +00:00
|
|
|
* @return Return the text of this revision
|
2009-12-26 20:03:33 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getContent() {
|
2011-02-03 15:31:38 +00:00
|
|
|
global $wgUser;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->getID() === 0 ) {
|
2008-11-28 14:29:25 +00:00
|
|
|
# If this is a MediaWiki:x message, then load the messages
|
|
|
|
|
# and return the message value for x.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
2011-02-05 15:11:52 +00:00
|
|
|
$text = $this->mTitle->getDefaultMessageText();
|
2011-02-03 15:29:13 +00:00
|
|
|
if ( $text === false ) {
|
2008-11-28 18:37:31 +00:00
|
|
|
$text = '';
|
2011-02-03 15:29:13 +00:00
|
|
|
}
|
2005-12-28 14:47:30 +00:00
|
|
|
} else {
|
2009-01-12 08:11:22 +00:00
|
|
|
$text = wfMsgExt( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon', 'parsemag' );
|
2005-12-28 14:47:30 +00:00
|
|
|
}
|
2008-11-28 14:29:25 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
return $text;
|
2005-07-03 04:00:33 +00:00
|
|
|
} else {
|
2006-01-13 00:29:20 +00:00
|
|
|
$this->loadContent();
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-04-11 08:27:35 +00:00
|
|
|
return $this->mContent;
|
2004-05-13 12:20:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2009-01-10 13:41:22 +00:00
|
|
|
/**
|
|
|
|
|
* Get the text of the current revision. No side-effects...
|
|
|
|
|
*
|
|
|
|
|
* @return Return the text of the current revision
|
2009-12-26 20:03:33 +00:00
|
|
|
*/
|
2009-01-10 13:41:22 +00:00
|
|
|
public function getRawText() {
|
|
|
|
|
// Check process cache for current revision
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mContentLoaded && $this->mOldId == 0 ) {
|
2009-01-10 13:41:22 +00:00
|
|
|
return $this->mContent;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-01-10 13:41:22 +00:00
|
|
|
$rev = Revision::newFromTitle( $this->mTitle );
|
|
|
|
|
$text = $rev ? $rev->getRawText() : false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-01-10 13:41:22 +00:00
|
|
|
return $text;
|
|
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2009-01-26 13:51:03 +00:00
|
|
|
/**
|
|
|
|
|
* Get the text that needs to be saved in order to undo all revisions
|
|
|
|
|
* between $undo and $undoafter. Revisions must belong to the same page,
|
|
|
|
|
* must exist and must not be deleted
|
2009-06-18 02:50:16 +00:00
|
|
|
* @param $undo Revision
|
2009-01-26 13:51:03 +00:00
|
|
|
* @param $undoafter Revision Must be an earlier revision than $undo
|
|
|
|
|
* @return mixed string on success, false on failure
|
|
|
|
|
*/
|
|
|
|
|
public function getUndoText( Revision $undo, Revision $undoafter = null ) {
|
2010-09-12 10:02:19 +00:00
|
|
|
$currentRev = Revision::newFromTitle( $this->mTitle );
|
|
|
|
|
if ( !$currentRev ) {
|
|
|
|
|
return false; // no page
|
|
|
|
|
}
|
2009-01-26 13:51:03 +00:00
|
|
|
$undo_text = $undo->getText();
|
|
|
|
|
$undoafter_text = $undoafter->getText();
|
2010-09-12 10:02:19 +00:00
|
|
|
$cur_text = $currentRev->getText();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-01-26 13:51:03 +00:00
|
|
|
if ( $cur_text == $undo_text ) {
|
|
|
|
|
# No use doing a merge if it's just a straight revert.
|
|
|
|
|
return $undoafter_text;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-01-26 13:51:03 +00:00
|
|
|
$undone_text = '';
|
2010-05-30 14:28:54 +00:00
|
|
|
|
|
|
|
|
if ( !wfMerge( $undo_text, $undoafter_text, $cur_text, $undone_text ) ) {
|
2009-01-26 13:51:03 +00:00
|
|
|
return false;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-26 13:51:03 +00:00
|
|
|
return $undone_text;
|
|
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2006-01-07 12:10:04 +00:00
|
|
|
* @return int The oldid of the article that is to be shown, 0 for the
|
|
|
|
|
* current revision
|
2004-11-13 08:40:34 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getOldID() {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_null( $this->mOldId ) ) {
|
2005-12-30 09:33:11 +00:00
|
|
|
$this->mOldId = $this->getOldIDFromRequest();
|
2004-11-13 08:40:34 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
return $this->mOldId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets $this->mRedirectUrl to a correct URL if the query parameters are incorrect
|
2006-01-07 12:10:04 +00:00
|
|
|
*
|
|
|
|
|
* @return int The old id for the request
|
2005-12-30 09:33:11 +00:00
|
|
|
*/
|
2008-08-26 00:32:55 +00:00
|
|
|
public function getOldIDFromRequest() {
|
2005-12-30 09:33:11 +00:00
|
|
|
global $wgRequest;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
$this->mRedirectUrl = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2004-11-13 08:40:34 +00:00
|
|
|
$oldid = $wgRequest->getVal( 'oldid' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $oldid ) ) {
|
2005-08-16 23:36:16 +00:00
|
|
|
$oldid = intval( $oldid );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgRequest->getVal( 'direction' ) == 'next' ) {
|
2004-10-02 21:36:36 +00:00
|
|
|
$nextid = $this->mTitle->getNextRevisionID( $oldid );
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( $nextid ) {
|
2004-10-02 21:36:36 +00:00
|
|
|
$oldid = $nextid;
|
|
|
|
|
} else {
|
2005-12-30 09:33:11 +00:00
|
|
|
$this->mRedirectUrl = $this->mTitle->getFullURL( 'redirect=no' );
|
2004-10-02 21:36:36 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $wgRequest->getVal( 'direction' ) == 'prev' ) {
|
2004-10-02 21:36:36 +00:00
|
|
|
$previd = $this->mTitle->getPreviousRevisionID( $oldid );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $previd ) {
|
2004-10-02 21:36:36 +00:00
|
|
|
$oldid = $previd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$oldid ) {
|
2005-12-30 09:33:11 +00:00
|
|
|
$oldid = 0;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
return $oldid;
|
2004-11-13 08:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2005-12-30 09:33:11 +00:00
|
|
|
* Load the revision (including text) into this object
|
2004-12-19 08:00:50 +00:00
|
|
|
*/
|
2006-01-13 00:29:20 +00:00
|
|
|
function loadContent() {
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( $this->mContentLoaded ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-03 17:12:27 +00:00
|
|
|
$this->fetchContent( $this->getOldID() );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-12-19 08:00:50 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2011-04-12 20:21:16 +00:00
|
|
|
/**
|
|
|
|
|
* Return the list of revision fields that should be selected to create
|
|
|
|
|
* a new page.
|
|
|
|
|
*/
|
|
|
|
|
public static function selectFields() {
|
|
|
|
|
return array(
|
|
|
|
|
'page_id',
|
|
|
|
|
'page_namespace',
|
|
|
|
|
'page_title',
|
|
|
|
|
'page_restrictions',
|
|
|
|
|
'page_counter',
|
|
|
|
|
'page_is_redirect',
|
|
|
|
|
'page_is_new',
|
|
|
|
|
'page_random',
|
|
|
|
|
'page_touched',
|
|
|
|
|
'page_latest',
|
|
|
|
|
'page_len',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-14 10:06:28 +00:00
|
|
|
/**
|
|
|
|
|
* Fetch a page record with the given conditions
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $dbr DatabaseBase object
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $conditions Array
|
2010-03-14 23:20:40 +00:00
|
|
|
* @return mixed Database result resource, or false on failure
|
2005-03-14 10:06:28 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
protected function pageData( $dbr, $conditions ) {
|
2011-04-12 20:21:16 +00:00
|
|
|
$fields = self::selectFields();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-08-15 22:43:59 +00:00
|
|
|
wfRunHooks( 'ArticlePageDataBefore', array( &$this, &$fields ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-06-28 07:17:16 +00:00
|
|
|
$row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-08-15 22:43:59 +00:00
|
|
|
wfRunHooks( 'ArticlePageDataAfter', array( &$this, &$row ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-06-28 07:17:16 +00:00
|
|
|
return $row;
|
2005-03-14 10:06:28 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-01-07 12:10:04 +00:00
|
|
|
/**
|
2010-03-14 23:20:40 +00:00
|
|
|
* Fetch a page record matching the Title object's namespace and title
|
|
|
|
|
* using a sanitized title string
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $dbr DatabaseBase object
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $title Title object
|
2010-03-14 23:20:40 +00:00
|
|
|
* @return mixed Database result resource, or false on failure
|
2006-01-07 12:10:04 +00:00
|
|
|
*/
|
2011-04-12 20:21:16 +00:00
|
|
|
protected function pageDataFromTitle( $dbr, $title ) {
|
2005-03-14 10:06:28 +00:00
|
|
|
return $this->pageData( $dbr, array(
|
|
|
|
|
'page_namespace' => $title->getNamespace(),
|
|
|
|
|
'page_title' => $title->getDBkey() ) );
|
|
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-01-07 12:10:04 +00:00
|
|
|
/**
|
2010-03-14 23:20:40 +00:00
|
|
|
* Fetch a page record matching the requested ID
|
|
|
|
|
*
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $dbr DatabaseBase
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $id Integer
|
2011-04-12 20:26:56 +00:00
|
|
|
* @return mixed Database result resource, or false on failure
|
2006-01-07 12:10:04 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
protected function pageDataFromId( $dbr, $id ) {
|
2006-01-07 12:10:04 +00:00
|
|
|
return $this->pageData( $dbr, array( 'page_id' => $id ) );
|
2005-03-14 10:06:28 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-03-18 08:37:50 +00:00
|
|
|
/**
|
|
|
|
|
* Set the general counter, title etc data loaded from
|
|
|
|
|
* some source.
|
|
|
|
|
*
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $data Object|String $res->fetchObject() object or the string "fromdb" to reload
|
2005-03-18 08:37:50 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function loadPageData( $data = 'fromdb' ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $data === 'fromdb' ) {
|
2011-01-03 19:50:01 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$data = $this->pageDataFromTitle( $dbr, $this->mTitle );
|
2006-03-16 02:32:30 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2008-04-09 18:23:34 +00:00
|
|
|
$lc = LinkCache::singleton();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $data ) {
|
2010-06-15 12:14:54 +00:00
|
|
|
$lc->addGoodLinkObj( $data->page_id, $this->mTitle, $data->page_len, $data->page_is_redirect, $data->page_latest );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2009-08-21 18:11:13 +00:00
|
|
|
$this->mTitle->mArticleID = intval( $data->page_id );
|
2006-03-16 02:32:30 +00:00
|
|
|
|
2008-12-09 22:24:21 +00:00
|
|
|
# Old-fashioned restrictions
|
2008-12-09 22:28:34 +00:00
|
|
|
$this->mTitle->loadRestrictions( $data->page_restrictions );
|
2007-01-12 01:44:33 +00:00
|
|
|
|
2009-08-21 18:11:13 +00:00
|
|
|
$this->mCounter = intval( $data->page_counter );
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->mTouched = wfTimestamp( TS_MW, $data->page_touched );
|
2009-08-21 18:11:13 +00:00
|
|
|
$this->mIsRedirect = intval( $data->page_is_redirect );
|
|
|
|
|
$this->mLatest = intval( $data->page_latest );
|
2006-03-16 02:32:30 +00:00
|
|
|
} else {
|
2010-06-28 07:17:16 +00:00
|
|
|
$lc->addBadLinkObj( $this->mTitle );
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->mTitle->mArticleID = 0;
|
|
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2010-05-30 14:28:54 +00:00
|
|
|
$this->mDataLoaded = true;
|
2005-03-18 08:37:50 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2004-12-19 08:00:50 +00:00
|
|
|
/**
|
2005-01-11 01:28:18 +00:00
|
|
|
* Get text of an article from database
|
2006-01-13 00:29:20 +00:00
|
|
|
* Does *NOT* follow redirects.
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $oldid Int: 0 for whatever the latest revision is
|
2010-03-14 23:20:40 +00:00
|
|
|
* @return mixed string containing article contents, or false if null
|
2004-12-19 08:00:50 +00:00
|
|
|
*/
|
2006-01-13 00:29:20 +00:00
|
|
|
function fetchContent( $oldid = 0 ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mContentLoaded ) {
|
2004-12-19 08:00:50 +00:00
|
|
|
return $this->mContent;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-12-19 08:00:50 +00:00
|
|
|
# Pre-fill content with error message so that if something
|
|
|
|
|
# fails we'll have something telling us what we intended.
|
|
|
|
|
$t = $this->mTitle->getPrefixedText();
|
2008-06-05 17:33:31 +00:00
|
|
|
$d = $oldid ? wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ) : '';
|
2009-09-22 11:13:41 +00:00
|
|
|
$this->mContent = wfMsgNoTrans( 'missing-article', $t, $d ) ;
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $oldid ) {
|
2005-03-14 10:06:28 +00:00
|
|
|
$revision = Revision::newFromId( $oldid );
|
2010-06-28 07:17:16 +00:00
|
|
|
if ( $revision === null ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . " failed to retrieve specified revision, id $oldid\n" );
|
2004-12-19 08:00:50 +00:00
|
|
|
return false;
|
2003-11-02 13:57:24 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-03 19:50:01 +00:00
|
|
|
if ( !$this->mDataLoaded || $this->getID() != $revision->getPage() ) {
|
|
|
|
|
$data = $this->pageDataFromId( wfGetDB( DB_SLAVE ), $revision->getPage() );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$data ) {
|
2011-01-03 19:50:01 +00:00
|
|
|
wfDebug( __METHOD__ . " failed to get page data linked to revision id $oldid\n" );
|
2005-03-18 08:37:50 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-03 19:50:01 +00:00
|
|
|
$this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title );
|
2005-03-18 08:37:50 +00:00
|
|
|
$this->loadPageData( $data );
|
2005-03-18 05:38:49 +00:00
|
|
|
}
|
2011-01-03 19:50:01 +00:00
|
|
|
} else {
|
|
|
|
|
if ( !$this->mDataLoaded ) {
|
|
|
|
|
$this->loadPageData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $this->mLatest === false ) {
|
|
|
|
|
wfDebug( __METHOD__ . " failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-18 08:37:50 +00:00
|
|
|
$revision = Revision::newFromId( $this->mLatest );
|
2011-01-03 19:50:01 +00:00
|
|
|
if ( $revision === null ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . " failed to retrieve current page, rev_id {$this->mLatest}\n" );
|
2005-03-18 05:38:49 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2004-12-19 08:00:50 +00:00
|
|
|
}
|
2004-08-07 03:50:46 +00:00
|
|
|
|
2011-05-17 22:03:20 +00:00
|
|
|
// @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
|
2006-03-16 19:04:25 +00:00
|
|
|
// We should instead work with the Revision object when we need it...
|
2008-09-24 09:44:45 +00:00
|
|
|
$this->mContent = $revision->getText( Revision::FOR_THIS_USER ); // Loads if user is allowed
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2011-01-08 20:07:18 +00:00
|
|
|
if ( $revision->getId() == $this->mLatest ) {
|
|
|
|
|
$this->setLastEdit( $revision );
|
|
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2008-05-22 15:02:33 +00:00
|
|
|
$this->mRevIdFetched = $revision->getId();
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->mContentLoaded = true;
|
2005-06-29 05:15:32 +00:00
|
|
|
$this->mRevision =& $revision;
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2010-06-30 07:42:07 +00:00
|
|
|
wfRunHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) );
|
2005-12-21 12:02:18 +00:00
|
|
|
|
2004-03-23 10:11:24 +00:00
|
|
|
return $this->mContent;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2011-05-10 22:54:59 +00:00
|
|
|
* No-op
|
2011-05-06 20:59:58 +00:00
|
|
|
* @deprecated since 1.18
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2011-05-10 22:54:59 +00:00
|
|
|
public function forUpdate() {
|
2011-04-14 20:00:25 +00:00
|
|
|
wfDeprecated( __METHOD__ );
|
2004-08-20 14:59:49 +00:00
|
|
|
}
|
2004-09-01 02:57:26 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2006-01-07 12:10:04 +00:00
|
|
|
* @return int Page ID
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getID() {
|
2010-06-28 07:17:16 +00:00
|
|
|
return $this->mTitle->getArticleID();
|
2003-11-24 10:24:04 +00:00
|
|
|
}
|
2005-07-01 20:36:04 +00:00
|
|
|
|
2005-06-29 23:44:03 +00:00
|
|
|
/**
|
2006-01-07 12:10:04 +00:00
|
|
|
* @return bool Whether or not the page exists in the database
|
2005-06-29 23:44:03 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function exists() {
|
|
|
|
|
return $this->getId() > 0;
|
2005-06-29 23:44:03 +00:00
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2008-12-22 23:38:58 +00:00
|
|
|
/**
|
|
|
|
|
* Check if this page is something we're going to be showing
|
|
|
|
|
* some sort of sensible content for. If we return false, page
|
|
|
|
|
* views (plain action=view) will return an HTTP 404 response,
|
|
|
|
|
* so spiders and robots can know they're following a bad link.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function hasViewableContent() {
|
|
|
|
|
return $this->exists() || $this->mTitle->isAlwaysKnown();
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2004-09-11 11:39:24 +00:00
|
|
|
/**
|
2006-01-07 12:10:04 +00:00
|
|
|
* @return int The view count for the page
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getCount() {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( -1 == $this->mCounter ) {
|
2003-04-14 23:10:40 +00:00
|
|
|
$id = $this->getID();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $id == 0 ) {
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->mCounter = 0;
|
|
|
|
|
} else {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-06-18 02:50:16 +00:00
|
|
|
$this->mCounter = $dbr->selectField( 'page',
|
|
|
|
|
'page_counter',
|
|
|
|
|
array( 'page_id' => $id ),
|
2011-04-13 00:50:44 +00:00
|
|
|
__METHOD__
|
2008-11-28 14:29:25 +00:00
|
|
|
);
|
2006-03-16 02:32:30 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2003-04-14 23:10:40 +00:00
|
|
|
return $this->mCounter;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2010-05-30 14:28:54 +00:00
|
|
|
* Determine whether a page would be suitable for being counted as an
|
2006-01-07 12:10:04 +00:00
|
|
|
* article in the site_stats table based on the title & its content
|
|
|
|
|
*
|
2011-05-14 17:11:32 +00:00
|
|
|
* @param $editInfo Object or false: object returned by prepareTextForEdit(),
|
|
|
|
|
* if false, the current database state will be used
|
|
|
|
|
* @return Boolean
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2011-05-14 17:11:32 +00:00
|
|
|
public function isCountable( $editInfo = false ) {
|
|
|
|
|
global $wgArticleCountMethod;
|
|
|
|
|
|
|
|
|
|
if ( !$this->mTitle->isContentPage() ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$text = $editInfo ? $editInfo->pst : false;
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2011-05-14 17:11:32 +00:00
|
|
|
if ( $this->isRedirect( $text ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-05-14 17:11:32 +00:00
|
|
|
switch ( $wgArticleCountMethod ) {
|
|
|
|
|
case 'any':
|
|
|
|
|
return true;
|
|
|
|
|
case 'comma':
|
|
|
|
|
if ( $text === false ) {
|
|
|
|
|
$text = $this->getRawText();
|
|
|
|
|
}
|
2011-06-01 00:15:02 +00:00
|
|
|
return strpos( $text, ',' ) !== false;
|
2011-05-14 17:11:32 +00:00
|
|
|
case 'link':
|
|
|
|
|
if ( $editInfo ) {
|
|
|
|
|
// ParserOutput::getLinks() is a 2D array of page links, so
|
|
|
|
|
// to be really correct we would need to recurse in the array
|
|
|
|
|
// but the main array should only have items in it if there are
|
|
|
|
|
// links.
|
|
|
|
|
return (bool)count( $editInfo->output->getLinks() );
|
|
|
|
|
} else {
|
|
|
|
|
return (bool)wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
|
|
|
|
|
array( 'pl_from' => $this->getId() ), __METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-01 00:03:31 +00:00
|
|
|
/**
|
2004-09-11 11:39:24 +00:00
|
|
|
* Tests if the article text represents a redirect
|
2006-01-07 12:10:04 +00:00
|
|
|
*
|
2010-03-15 01:08:07 +00:00
|
|
|
* @param $text mixed string containing article contents, or boolean
|
2006-01-07 12:10:04 +00:00
|
|
|
* @return bool
|
2004-09-11 11:39:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function isRedirect( $text = false ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $text === false ) {
|
2011-01-03 18:15:44 +00:00
|
|
|
if ( !$this->mDataLoaded ) {
|
|
|
|
|
$this->loadPageData();
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-03 18:15:44 +00:00
|
|
|
return (bool)$this->mIsRedirect;
|
2004-09-11 11:39:24 +00:00
|
|
|
} else {
|
2011-01-03 18:15:44 +00:00
|
|
|
return Title::newFromRedirect( $text ) !== null;
|
2004-09-11 11:39:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-06-29 23:44:03 +00:00
|
|
|
/**
|
|
|
|
|
* Returns true if the currently-referenced revision is the current edit
|
|
|
|
|
* to this page (and it exists).
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function isCurrent() {
|
2007-05-07 07:57:29 +00:00
|
|
|
# If no oldid, this is the current version.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->getOldID() == 0 ) {
|
2007-05-07 07:57:29 +00:00
|
|
|
return true;
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-12 12:50:46 +00:00
|
|
|
return $this->exists() && $this->mRevision && $this->mRevision->isCurrent();
|
2005-06-29 23:44:03 +00:00
|
|
|
}
|
2005-07-01 20:36:04 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2004-12-19 08:00:50 +00:00
|
|
|
* Loads everything except the text
|
2004-09-02 23:28:24 +00:00
|
|
|
* This isn't necessary for all uses, so it's only done if needed.
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
protected function loadLastEdit() {
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $this->mLastRevision !== null ) {
|
|
|
|
|
return; // already loaded
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2005-02-06 07:28:21 +00:00
|
|
|
# New or non-existent articles have no user information
|
|
|
|
|
$id = $this->getID();
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( 0 == $id ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2005-02-06 07:28:21 +00:00
|
|
|
|
2011-01-08 20:07:18 +00:00
|
|
|
$revision = Revision::loadFromPageId( wfGetDB( DB_MASTER ), $id );
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $revision ) {
|
2011-01-08 20:07:18 +00:00
|
|
|
$this->setLastEdit( $revision );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-08 20:07:18 +00:00
|
|
|
/**
|
2011-01-09 11:48:10 +00:00
|
|
|
* Set the latest revision
|
2011-01-08 20:07:18 +00:00
|
|
|
*/
|
|
|
|
|
protected function setLastEdit( Revision $revision ) {
|
|
|
|
|
$this->mLastRevision = $revision;
|
|
|
|
|
$this->mTimestamp = $revision->getTimestamp();
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* @return string GMT timestamp of last article revision
|
2011-01-09 17:41:42 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getTimestamp() {
|
2006-03-16 02:32:30 +00:00
|
|
|
// Check if the field has been filled by ParserCache::get()
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mTimestamp ) {
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->loadLastEdit();
|
|
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
return wfTimestamp( TS_MW, $this->mTimestamp );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
2011-04-10 06:32:50 +00:00
|
|
|
* @param $audience Integer: one of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return int user ID for the user that made the last article revision
|
|
|
|
|
*/
|
2011-04-10 06:32:50 +00:00
|
|
|
public function getUser( $audience = Revision::FOR_PUBLIC ) {
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->loadLastEdit();
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $this->mLastRevision ) {
|
|
|
|
|
return $this->mLastRevision->getUser( $audience );
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
2011-04-10 06:32:50 +00:00
|
|
|
* @param $audience Integer: one of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return string username of the user that made the last article revision
|
|
|
|
|
*/
|
2011-04-10 06:32:50 +00:00
|
|
|
public function getUserText( $audience = Revision::FOR_PUBLIC ) {
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->loadLastEdit();
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $this->mLastRevision ) {
|
|
|
|
|
return $this->mLastRevision->getUserText( $audience );
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
2011-04-10 06:32:50 +00:00
|
|
|
* @param $audience Integer: one of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return string Comment stored for the last article revision
|
|
|
|
|
*/
|
2011-04-10 06:32:50 +00:00
|
|
|
public function getComment( $audience = Revision::FOR_PUBLIC ) {
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->loadLastEdit();
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $this->mLastRevision ) {
|
|
|
|
|
return $this->mLastRevision->getComment( $audience );
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Returns true if last revision was marked as "minor edit"
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return boolean Minor edit indicator for the last article revision.
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getMinorEdit() {
|
2003-04-14 23:10:40 +00:00
|
|
|
$this->loadLastEdit();
|
2011-04-10 06:32:50 +00:00
|
|
|
if ( $this->mLastRevision ) {
|
|
|
|
|
return $this->mLastRevision->isMinor();
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Use this to fetch the rev ID used on page views
|
|
|
|
|
*
|
|
|
|
|
* @return int revision ID of last article revision
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getRevIdFetched() {
|
2011-01-09 17:41:42 +00:00
|
|
|
if ( $this->mRevIdFetched ) {
|
|
|
|
|
return $this->mRevIdFetched;
|
|
|
|
|
} else {
|
|
|
|
|
return $this->getLatest();
|
|
|
|
|
}
|
2005-03-26 18:24:32 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2006-04-19 15:46:24 +00:00
|
|
|
/**
|
2011-04-12 12:09:11 +00:00
|
|
|
* Get a list of users who have edited this article, not including the user who made
|
|
|
|
|
* the most recent revision, which you can get from $article->getUser() if you want it
|
2011-05-28 16:31:00 +00:00
|
|
|
* @return UserArrayFromResult
|
2006-04-19 15:46:24 +00:00
|
|
|
*/
|
2011-04-12 12:09:11 +00:00
|
|
|
public function getContributors() {
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: This is expensive; cache this info somewhere.
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-09-23 11:31:52 +00:00
|
|
|
|
2011-04-30 14:08:12 +00:00
|
|
|
if ( $dbr->implicitGroupby() ) {
|
|
|
|
|
$realNameField = 'user_real_name';
|
|
|
|
|
} else {
|
|
|
|
|
$realNameField = 'FIRST(user_real_name) AS user_real_name';
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$tables = array( 'revision', 'user' );
|
2004-07-10 03:09:26 +00:00
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$fields = array(
|
2011-04-30 14:08:12 +00:00
|
|
|
'rev_user as user_id',
|
2011-04-12 12:09:11 +00:00
|
|
|
'rev_user_text AS user_name',
|
2011-04-30 14:08:12 +00:00
|
|
|
$realNameField,
|
2011-04-12 12:09:11 +00:00
|
|
|
'MAX(rev_timestamp) AS timestamp',
|
|
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$conds = array( 'rev_page' => $this->getId() );
|
|
|
|
|
|
|
|
|
|
// The user who made the top revision gets credited as "this page was last edited by
|
|
|
|
|
// John, based on contributions by Tom, Dick and Harry", so don't include them twice.
|
|
|
|
|
$user = $this->getUser();
|
2009-09-23 11:31:52 +00:00
|
|
|
if ( $user ) {
|
2011-04-12 12:09:11 +00:00
|
|
|
$conds[] = "rev_user != $user";
|
2009-09-23 11:31:52 +00:00
|
|
|
} else {
|
2011-04-12 12:09:11 +00:00
|
|
|
$conds[] = "rev_user_text != {$dbr->addQuotes( $this->getUserText() )}";
|
2009-09-23 11:31:52 +00:00
|
|
|
}
|
|
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$conds[] = "{$dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER )} = 0"; // username hidden?
|
2004-04-29 01:58:20 +00:00
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$jconds = array(
|
|
|
|
|
'user' => array( 'LEFT JOIN', 'rev_user = user_id' ),
|
|
|
|
|
);
|
2004-09-01 02:57:26 +00:00
|
|
|
|
2011-04-12 12:09:11 +00:00
|
|
|
$options = array(
|
|
|
|
|
'GROUP BY' => array( 'rev_user', 'rev_user_text' ),
|
|
|
|
|
'ORDER BY' => 'timestamp DESC',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $jconds );
|
2008-08-18 19:21:55 +00:00
|
|
|
return new UserArrayFromResult( $res );
|
2004-04-23 21:01:29 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* This is the default action of the index.php entry point: just view the
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* page of the given title.
|
2009-12-26 20:03:33 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function view() {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgUser, $wgOut, $wgRequest, $wgParser;
|
2010-08-05 14:37:50 +00:00
|
|
|
global $wgUseFileCache, $wgUseETag;
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-06-04 00:25:53 +00:00
|
|
|
|
2004-08-09 05:38:11 +00:00
|
|
|
# Get variables from query string
|
2004-11-13 08:40:34 +00:00
|
|
|
$oldid = $this->getOldID();
|
2011-03-12 14:21:41 +00:00
|
|
|
|
|
|
|
|
# getOldID may want us to redirect somewhere else
|
|
|
|
|
if ( $this->mRedirectUrl ) {
|
|
|
|
|
$wgOut->redirect( $this->mRedirectUrl );
|
|
|
|
|
wfDebug( __METHOD__ . ": redirecting due to oldid\n" );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wgOut->setArticleFlag( true );
|
|
|
|
|
# Set page title (may be overridden by DISPLAYTITLE)
|
|
|
|
|
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
|
|
|
|
|
|
|
|
|
|
# If we got diff in the query, we want to see a diff page instead of the article.
|
|
|
|
|
if ( $wgRequest->getCheck( 'diff' ) ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": showing diff page\n" );
|
|
|
|
|
$this->showDiffPage();
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Allow frames by default
|
|
|
|
|
$wgOut->allowClickjacking();
|
|
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$parserCache = ParserCache::singleton();
|
|
|
|
|
|
2010-08-09 07:41:25 +00:00
|
|
|
$parserOptions = $this->getParserOptions();
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Render printable version, use printable version cache
|
|
|
|
|
if ( $wgOut->isPrintable() ) {
|
|
|
|
|
$parserOptions->setIsPrintable( true );
|
2010-08-05 14:37:50 +00:00
|
|
|
$parserOptions->setEditSection( false );
|
|
|
|
|
} else if ( $wgUseETag && !$this->mTitle->quickUserCan( 'edit' ) ) {
|
|
|
|
|
$parserOptions->setEditSection( false );
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
|
2009-03-05 23:04:13 +00:00
|
|
|
# Try client and file cache
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $oldid === 0 && $this->checkTouched() ) {
|
|
|
|
|
if ( $wgUseETag ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$wgOut->setETag( $parserCache->getETag( $this, $parserOptions ) );
|
2008-12-10 05:33:57 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-09-29 15:54:43 +00:00
|
|
|
# Is it client cached?
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgOut->checkLastModified( $this->getTouched() ) ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": done 304\n" );
|
2008-12-09 11:41:31 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-09 11:41:31 +00:00
|
|
|
return;
|
2009-03-05 23:04:13 +00:00
|
|
|
# Try file cache
|
2010-02-14 22:07:30 +00:00
|
|
|
} else if ( $wgUseFileCache && $this->tryFileCache() ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": done file cache\n" );
|
2008-12-09 11:41:31 +00:00
|
|
|
# tell wgOut that output is taken care of
|
|
|
|
|
$wgOut->disable();
|
|
|
|
|
$this->viewUpdates();
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-09 11:41:31 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-05 14:37:50 +00:00
|
|
|
if ( !$wgUseETag && !$this->mTitle->quickUserCan( 'edit' ) ) {
|
|
|
|
|
$parserOptions->setEditSection( false );
|
|
|
|
|
}
|
|
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Should the parser cache be used?
|
|
|
|
|
$useParserCache = $this->useParserCache( $oldid );
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( 'Article::view using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" );
|
2010-08-03 22:32:09 +00:00
|
|
|
if ( $wgUser->getStubThreshold() ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
wfIncrStats( 'pcache_miss_stub' );
|
2006-06-04 00:25:53 +00:00
|
|
|
}
|
|
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$wasRedirected = $this->showRedirectedFromHeader();
|
|
|
|
|
$this->showNamespaceHeader();
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
# Iterate through the possible ways of constructing the output text.
|
|
|
|
|
# Keep going until $outputDone is set, or we run out of things to do.
|
|
|
|
|
$pass = 0;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$outputDone = false;
|
2010-04-10 23:52:07 +00:00
|
|
|
$this->mParserOutput = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
while ( !$outputDone && ++$pass ) {
|
|
|
|
|
switch( $pass ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
case 1:
|
|
|
|
|
wfRunHooks( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
# Try the parser cache
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $useParserCache ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->mParserOutput = $parserCache->get( $this, $parserOptions );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
if ( $this->mParserOutput !== false ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": showing parser cache contents\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
$wgOut->addParserOutput( $this->mParserOutput );
|
|
|
|
|
# Ensure that UI elements requiring revision ID have
|
|
|
|
|
# the correct version information.
|
|
|
|
|
$wgOut->setRevisionId( $this->mLatest );
|
|
|
|
|
$outputDone = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
$text = $this->getContent();
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $text === false || $this->getID() == 0 ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": showing missing article\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->showMissingArticle();
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return;
|
|
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
# Another whitelist check in case oldid is altering the title
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mTitle->userCanRead() ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": denied on secondary read check\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
$wgOut->loginToUse();
|
|
|
|
|
$wgOut->output();
|
|
|
|
|
$wgOut->disable();
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return;
|
|
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
# Are we looking at an old revision
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $oldid && !is_null( $this->mRevision ) ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->setOldSubtitle( $oldid );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
if ( !$this->showDeletedRevisionHeader() ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": cannot view deleted revision\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-09-06 08:22:09 +00:00
|
|
|
# If this "old" version is the current, then try the parser cache...
|
2009-08-31 19:19:12 +00:00
|
|
|
if ( $oldid === $this->getLatest() && $this->useParserCache( false ) ) {
|
|
|
|
|
$this->mParserOutput = $parserCache->get( $this, $parserOptions );
|
|
|
|
|
if ( $this->mParserOutput ) {
|
2010-12-13 19:47:34 +00:00
|
|
|
wfDebug( __METHOD__ . ": showing parser cache for current rev permalink\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
$wgOut->addParserOutput( $this->mParserOutput );
|
2009-09-06 08:22:09 +00:00
|
|
|
$wgOut->setRevisionId( $this->mLatest );
|
2010-08-23 14:13:41 +00:00
|
|
|
$outputDone = true;
|
2010-12-13 19:47:34 +00:00
|
|
|
break;
|
2009-08-31 19:19:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
# Ensure that UI elements requiring revision ID have
|
|
|
|
|
# the correct version information.
|
|
|
|
|
$wgOut->setRevisionId( $this->getRevIdFetched() );
|
|
|
|
|
|
|
|
|
|
# Pages containing custom CSS or JavaScript get special treatment
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage() ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": showing CSS/JS source\n" );
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->showCssOrJsPage();
|
|
|
|
|
$outputDone = true;
|
2010-11-01 00:07:17 +00:00
|
|
|
} else {
|
|
|
|
|
$rt = Title::newFromRedirectArray( $text );
|
|
|
|
|
if ( $rt ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": showing redirect=no page\n" );
|
|
|
|
|
# Viewing a redirect page (e.g. with parameter redirect=no)
|
|
|
|
|
# Don't append the subtitle if this was an old revision
|
|
|
|
|
$wgOut->addHTML( $this->viewRedirect( $rt, !$wasRedirected && $this->isCurrent() ) );
|
|
|
|
|
# Parse just to get categories, displaytitle, etc.
|
|
|
|
|
$this->mParserOutput = $wgParser->parse( $text, $this->mTitle, $parserOptions );
|
|
|
|
|
$wgOut->addParserOutputNoText( $this->mParserOutput );
|
|
|
|
|
$outputDone = true;
|
|
|
|
|
}
|
2009-08-31 19:19:12 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
# Run the parse, protected by a pool counter
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": doing uncached parse\n" );
|
2010-08-09 21:53:21 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
$key = $parserCache->getKey( $this, $parserOptions );
|
2010-08-27 20:57:32 +00:00
|
|
|
$poolArticleView = new PoolWorkArticleView( $this, $key, $useParserCache, $parserOptions );
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
if ( !$poolArticleView->execute() ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
# Connection or timeout error
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
$outputDone = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
# Should be unreachable, but just in case...
|
|
|
|
|
default:
|
|
|
|
|
break 2;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-10 13:38:50 +00:00
|
|
|
# Adjust the title if it was set by displaytitle, -{T|}- or language conversion
|
2010-04-10 23:52:07 +00:00
|
|
|
if ( $this->mParserOutput ) {
|
|
|
|
|
$titleText = $this->mParserOutput->getTitleText();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-04-10 23:52:07 +00:00
|
|
|
if ( strval( $titleText ) !== '' ) {
|
|
|
|
|
$wgOut->setPageTitle( $titleText );
|
|
|
|
|
}
|
2010-04-10 13:38:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-04-11 13:04:58 +00:00
|
|
|
# For the main page, overwrite the <title> element with the con-
|
|
|
|
|
# tents of 'pagetitle-view-mainpage' instead of the default (if
|
|
|
|
|
# that's not empty).
|
2010-06-28 07:17:16 +00:00
|
|
|
# This message always exists because it is in the i18n files
|
2011-02-17 17:06:06 +00:00
|
|
|
if ( $this->mTitle->equals( Title::newMainPage() ) ) {
|
|
|
|
|
$msg = wfMessage( 'pagetitle-view-mainpage' )->inContentLanguage();
|
|
|
|
|
if ( !$msg->isDisabled() ) {
|
|
|
|
|
$wgOut->setHTMLTitle( $msg->title( $this->mTitle )->text() );
|
|
|
|
|
}
|
2010-04-11 13:04:58 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
# Now that we've filled $this->mParserOutput, we know whether
|
|
|
|
|
# there are any __NOINDEX__ tags on the page
|
|
|
|
|
$policy = $this->getRobotPolicy( 'view' );
|
|
|
|
|
$wgOut->setIndexPolicy( $policy['index'] );
|
|
|
|
|
$wgOut->setFollowPolicy( $policy['follow'] );
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
|
|
|
|
$this->showViewFooter();
|
|
|
|
|
$this->viewUpdates();
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Show a diff page according to current request variables. For use within
|
|
|
|
|
* Article::view() only, other callers should use the DifferenceEngine class.
|
|
|
|
|
*/
|
|
|
|
|
public function showDiffPage() {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgRequest, $wgUser;
|
2009-12-26 20:03:33 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$diff = $wgRequest->getVal( 'diff' );
|
|
|
|
|
$rcid = $wgRequest->getVal( 'rcid' );
|
|
|
|
|
$diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) );
|
|
|
|
|
$purge = $wgRequest->getVal( 'action' ) == 'purge';
|
2010-02-14 22:07:30 +00:00
|
|
|
$unhide = $wgRequest->getInt( 'unhide' ) == 1;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$oldid = $this->getOldID();
|
|
|
|
|
|
2009-10-28 18:18:05 +00:00
|
|
|
$de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid, $purge, $unhide );
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// DifferenceEngine directly fetched the revision:
|
|
|
|
|
$this->mRevIdFetched = $de->mNewid;
|
|
|
|
|
$de->showDiffPage( $diffOnly );
|
|
|
|
|
|
2011-03-12 14:21:41 +00:00
|
|
|
if ( $diff == 0 || $diff == $this->getLatest() ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Run view updates for current revision only
|
|
|
|
|
$this->viewUpdates();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* Show a page view for a page formatted as CSS or JavaScript. To be called by
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* Article::view() only.
|
|
|
|
|
*
|
2009-12-26 20:03:33 +00:00
|
|
|
* This is hooked by SyntaxHighlight_GeSHi to do syntax highlighting of these
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* page views.
|
|
|
|
|
*/
|
2010-08-07 22:17:00 +00:00
|
|
|
protected function showCssOrJsPage() {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-06-02 19:47:28 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div id='mw-clearyourcache'>\n$1\n</div>", 'clearyourcache' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// Give hooks a chance to customise the output
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( wfRunHooks( 'ShowRawCssJs', array( $this->mContent, $this->mTitle, $wgOut ) ) ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// Wrap the whole lot in a <pre> and don't parse
|
|
|
|
|
$m = array();
|
|
|
|
|
preg_match( '!\.(css|js)$!u', $this->mTitle->getText(), $m );
|
|
|
|
|
$wgOut->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
|
|
|
|
|
$wgOut->addHTML( htmlspecialchars( $this->mContent ) );
|
|
|
|
|
$wgOut->addHTML( "\n</pre>\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
/**
|
|
|
|
|
* Get the robot policy to be used for the current view
|
|
|
|
|
* @param $action String the action= GET parameter
|
|
|
|
|
* @return Array the policy that should be set
|
|
|
|
|
* TODO: actions other than 'view'
|
|
|
|
|
*/
|
2010-02-14 22:07:30 +00:00
|
|
|
public function getRobotPolicy( $action ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
global $wgOut, $wgArticleRobotPolicies, $wgNamespaceRobotPolicies;
|
|
|
|
|
global $wgDefaultRobotPolicy, $wgRequest;
|
|
|
|
|
|
|
|
|
|
$ns = $this->mTitle->getNamespace();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $ns == NS_USER || $ns == NS_USER_TALK ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Don't index user and user talk pages for blocked users (bug 11443)
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mTitle->isSubpage() ) {
|
2011-03-21 19:12:41 +00:00
|
|
|
if ( Block::newFromTarget( null, $this->mTitle->getText() ) instanceof Block ) {
|
2010-05-30 14:28:54 +00:00
|
|
|
return array(
|
|
|
|
|
'index' => 'noindex',
|
|
|
|
|
'follow' => 'nofollow'
|
|
|
|
|
);
|
2009-01-14 23:42:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->getID() === 0 || $this->getOldID() ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
# Non-articles (special pages etc), and old revisions
|
2010-05-30 14:28:54 +00:00
|
|
|
return array(
|
|
|
|
|
'index' => 'noindex',
|
|
|
|
|
'follow' => 'nofollow'
|
|
|
|
|
);
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $wgOut->isPrintable() ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Discourage indexing of printable versions, but encourage following
|
2010-05-30 14:28:54 +00:00
|
|
|
return array(
|
|
|
|
|
'index' => 'noindex',
|
|
|
|
|
'follow' => 'follow'
|
|
|
|
|
);
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $wgRequest->getInt( 'curid' ) ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# For ?curid=x urls, disallow indexing
|
2010-05-30 14:28:54 +00:00
|
|
|
return array(
|
|
|
|
|
'index' => 'noindex',
|
|
|
|
|
'follow' => 'follow'
|
|
|
|
|
);
|
2009-08-31 19:19:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Otherwise, construct the policy based on the various config variables.
|
|
|
|
|
$policy = self::formatRobotPolicy( $wgDefaultRobotPolicy );
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $wgNamespaceRobotPolicies[$ns] ) ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Honour customised robot policies for this namespace
|
2010-05-30 14:28:54 +00:00
|
|
|
$policy = array_merge(
|
|
|
|
|
$policy,
|
|
|
|
|
self::formatRobotPolicy( $wgNamespaceRobotPolicies[$ns] )
|
|
|
|
|
);
|
2009-08-31 19:19:12 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->canUseNoindex() && is_object( $this->mParserOutput ) && $this->mParserOutput->getIndexPolicy() ) {
|
2009-09-01 14:11:29 +00:00
|
|
|
# __INDEX__ and __NOINDEX__ magic words, if allowed. Incorporates
|
|
|
|
|
# a final sanity check that we have really got the parser output.
|
2010-05-30 14:28:54 +00:00
|
|
|
$policy = array_merge(
|
|
|
|
|
$policy,
|
|
|
|
|
array( 'index' => $this->mParserOutput->getIndexPolicy() )
|
|
|
|
|
);
|
2005-12-26 13:01:18 +00:00
|
|
|
}
|
2009-08-31 19:19:12 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] ) ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
# (bug 14900) site config can override user-defined __INDEX__ or __NOINDEX__
|
2010-05-30 14:28:54 +00:00
|
|
|
$policy = array_merge(
|
|
|
|
|
$policy,
|
|
|
|
|
self::formatRobotPolicy( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] )
|
|
|
|
|
);
|
2009-08-31 19:19:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $policy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a String robot policy into an associative array, to allow
|
|
|
|
|
* merging of several policies using array_merge().
|
|
|
|
|
* @param $policy Mixed, returns empty array on null/false/'', transparent
|
|
|
|
|
* to already-converted arrays, converts String.
|
2011-01-06 15:55:56 +00:00
|
|
|
* @return Array: 'index' => <indexpolicy>, 'follow' => <followpolicy>
|
2009-08-31 19:19:12 +00:00
|
|
|
*/
|
2010-02-14 22:07:30 +00:00
|
|
|
public static function formatRobotPolicy( $policy ) {
|
|
|
|
|
if ( is_array( $policy ) ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
return $policy;
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( !$policy ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
return array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$policy = explode( ',', $policy );
|
|
|
|
|
$policy = array_map( 'trim', $policy );
|
|
|
|
|
|
|
|
|
|
$arr = array();
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $policy as $var ) {
|
|
|
|
|
if ( in_array( $var, array( 'index', 'noindex' ) ) ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
$arr['index'] = $var;
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( in_array( $var, array( 'follow', 'nofollow' ) ) ) {
|
2009-08-31 19:19:12 +00:00
|
|
|
$arr['follow'] = $var;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
return $arr;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* If this request is a redirect view, send "redirected from" subtitle to
|
|
|
|
|
* $wgOut. Returns true if the header was needed, false if this is not a
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* redirect view. Handles both local and remote redirects.
|
2010-03-15 01:08:07 +00:00
|
|
|
*
|
|
|
|
|
* @return boolean
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
*/
|
|
|
|
|
public function showRedirectedFromHeader() {
|
2011-04-25 11:59:31 +00:00
|
|
|
global $wgOut, $wgRequest, $wgRedirectSources;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
|
|
|
|
$rdfrom = $wgRequest->getVal( 'rdfrom' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $this->mRedirectedFrom ) ) {
|
2006-01-13 00:29:20 +00:00
|
|
|
// This is an internally redirected page view.
|
|
|
|
|
// We'll need a backlink to the source page for navigation.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
$redir = Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mRedirectedFrom,
|
|
|
|
|
null,
|
|
|
|
|
array(),
|
|
|
|
|
array( 'redirect' => 'no' ),
|
|
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-22 18:30:13 +00:00
|
|
|
$s = wfMsgExt( 'redirectedfrom', array( 'parseinline', 'replaceafter' ), $redir );
|
2006-01-13 00:29:20 +00:00
|
|
|
$wgOut->setSubtitle( $s );
|
2006-12-08 06:09:15 +00:00
|
|
|
|
|
|
|
|
// Set the fragment if one was specified in the redirect
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( strval( $this->mTitle->getFragment() ) != '' ) {
|
2006-12-08 06:09:15 +00:00
|
|
|
$fragment = Xml::escapeJsString( $this->mTitle->getFragmentForURL() );
|
|
|
|
|
$wgOut->addInlineScript( "redirectToFragment(\"$fragment\");" );
|
|
|
|
|
}
|
2009-02-13 16:17:39 +00:00
|
|
|
|
|
|
|
|
// Add a <link rel="canonical"> tag
|
|
|
|
|
$wgOut->addLink( array( 'rel' => 'canonical',
|
2009-02-17 22:51:19 +00:00
|
|
|
'href' => $this->mTitle->getLocalURL() )
|
2009-02-13 16:17:39 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return true;
|
2006-01-13 00:29:20 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $rdfrom ) {
|
2006-01-13 00:29:20 +00:00
|
|
|
// This is an externally redirected view, from some other wiki.
|
|
|
|
|
// If it was reported from a trusted site, supply a backlink.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
$redir = Linker::makeExternalLink( $rdfrom, $rdfrom );
|
2008-12-22 18:30:13 +00:00
|
|
|
$s = wfMsgExt( 'redirectedfrom', array( 'parseinline', 'replaceafter' ), $redir );
|
2006-01-13 00:29:20 +00:00
|
|
|
$wgOut->setSubtitle( $s );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return true;
|
2006-01-13 00:29:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* Show a header specific to the namespace currently being viewed, like
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* [[MediaWiki:Talkpagetext]]. For Article::view().
|
|
|
|
|
*/
|
|
|
|
|
public function showNamespaceHeader() {
|
|
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->isTalkPage() ) {
|
2011-01-14 10:51:05 +00:00
|
|
|
if ( !wfMessage( 'talkpageheader' )->isDisabled() ) {
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div class=\"mw-talkpageheader\">\n$1\n</div>", array( 'talkpageheader' ) );
|
2009-03-27 20:22:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2009-03-27 20:22:52 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
|
|
|
|
* Show the footer section of an ordinary page view
|
|
|
|
|
*/
|
|
|
|
|
public function showViewFooter() {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgOut, $wgUseTrackbacks;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_USER_TALK && IP::isValid( $this->mTitle->getText() ) ) {
|
|
|
|
|
$wgOut->addWikiMsg( 'anontalkpagetext' );
|
2004-06-04 10:40:44 +00:00
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# If we have been passed an &rcid= parameter, we want to give the user a
|
|
|
|
|
# chance to mark this new article as patrolled.
|
|
|
|
|
$this->showPatrolFooter();
|
2004-07-08 14:53:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Trackbacks
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgUseTrackbacks ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$this->addTrackbacks();
|
|
|
|
|
}
|
2011-01-14 21:54:29 +00:00
|
|
|
|
|
|
|
|
wfRunHooks( 'ArticleViewFooter', array( $this ) );
|
|
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2008-12-22 23:38:58 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* If patrol is possible, output a patrol UI box. This is called from the
|
|
|
|
|
* footer section of ordinary page views. If patrol is not possible or not
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* desired, does nothing.
|
|
|
|
|
*/
|
|
|
|
|
public function showPatrolFooter() {
|
2009-07-15 09:48:25 +00:00
|
|
|
global $wgOut, $wgRequest, $wgUser;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$rcid = $wgRequest->getVal( 'rcid' );
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-06-28 07:17:16 +00:00
|
|
|
if ( !$rcid || !$this->mTitle->quickUserCan( 'patrol' ) ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2010-10-23 16:56:07 +00:00
|
|
|
$token = $wgUser->editToken( $rcid );
|
2011-01-04 06:12:33 +00:00
|
|
|
$wgOut->preventClickjacking();
|
2009-07-15 09:48:25 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$wgOut->addHTML(
|
|
|
|
|
"<div class='patrollink'>" .
|
|
|
|
|
wfMsgHtml(
|
|
|
|
|
'markaspatrolledlink',
|
2011-04-25 11:59:31 +00:00
|
|
|
Linker::link(
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'markaspatrolledtext' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'action' => 'markpatrolled',
|
2010-08-01 15:50:30 +00:00
|
|
|
'rcid' => $rcid,
|
|
|
|
|
'token' => $token,
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
),
|
|
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
)
|
|
|
|
|
) .
|
|
|
|
|
'</div>'
|
|
|
|
|
);
|
2009-12-26 20:03:33 +00:00
|
|
|
}
|
2008-08-08 00:01:53 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* Show the error text for a missing article. For articles in the MediaWiki
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* namespace, show the default message text. To be called from Article::view().
|
|
|
|
|
*/
|
|
|
|
|
public function showMissingArticle() {
|
2009-09-08 19:39:04 +00:00
|
|
|
global $wgOut, $wgRequest, $wgUser;
|
2009-09-13 02:07:21 +00:00
|
|
|
|
2010-02-10 13:08:24 +00:00
|
|
|
# Show info in user (talk) namespace. Does the user exist? Is he blocked?
|
2009-09-13 02:07:21 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_USER || $this->mTitle->getNamespace() == NS_USER_TALK ) {
|
2009-10-10 09:29:44 +00:00
|
|
|
$parts = explode( '/', $this->mTitle->getText() );
|
|
|
|
|
$rootPart = $parts[0];
|
2010-02-19 10:37:20 +00:00
|
|
|
$user = User::newFromName( $rootPart, false /* allow IP users*/ );
|
2009-10-10 09:29:44 +00:00
|
|
|
$ip = User::isIP( $rootPart );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-19 10:37:20 +00:00
|
|
|
if ( !$user->isLoggedIn() && !$ip ) { # User does not exist
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
|
2009-10-10 09:29:44 +00:00
|
|
|
array( 'userpage-userdoesnotexist-view', $rootPart ) );
|
2010-02-19 10:37:20 +00:00
|
|
|
} else if ( $user->isBlocked() ) { # Show log extract if the user is currently blocked
|
2010-02-10 13:08:24 +00:00
|
|
|
LogEventsList::showLogExtract(
|
|
|
|
|
$wgOut,
|
|
|
|
|
'block',
|
2010-02-19 10:37:20 +00:00
|
|
|
$user->getUserPage()->getPrefixedText(),
|
2010-02-10 13:08:24 +00:00
|
|
|
'',
|
|
|
|
|
array(
|
|
|
|
|
'lim' => 1,
|
|
|
|
|
'showIfEmpty' => false,
|
|
|
|
|
'msgKey' => array(
|
2010-02-19 10:37:20 +00:00
|
|
|
'blocked-notice-logextract',
|
|
|
|
|
$user->getName() # Support GENDER in notice
|
2010-02-10 13:08:24 +00:00
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
2009-09-13 02:07:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-09-14 18:10:13 +00:00
|
|
|
wfRunHooks( 'ShowMissingArticle', array( $this ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Show delete and move logs
|
2009-09-16 17:17:16 +00:00
|
|
|
LogEventsList::showLogExtract( $wgOut, array( 'delete', 'move' ), $this->mTitle->getPrefixedText(), '',
|
|
|
|
|
array( 'lim' => 10,
|
|
|
|
|
'conds' => array( "log_action != 'revision'" ),
|
|
|
|
|
'showIfEmpty' => false,
|
2009-12-26 20:03:33 +00:00
|
|
|
'msgKey' => array( 'moveddeleted-notice' ) )
|
2009-09-15 12:41:15 +00:00
|
|
|
);
|
2005-07-01 20:36:04 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Show error message
|
|
|
|
|
$oldid = $this->getOldID();
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $oldid ) {
|
2009-12-26 20:03:33 +00:00
|
|
|
$text = wfMsgNoTrans( 'missing-article',
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$this->mTitle->getPrefixedText(),
|
|
|
|
|
wfMsgNoTrans( 'missingarticle-rev', $oldid ) );
|
|
|
|
|
} elseif ( $this->mTitle->getNamespace() === NS_MEDIAWIKI ) {
|
|
|
|
|
// Use the default message text
|
2011-02-05 15:11:52 +00:00
|
|
|
$text = $this->mTitle->getDefaultMessageText();
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
} else {
|
2009-09-08 19:39:04 +00:00
|
|
|
$createErrors = $this->mTitle->getUserPermissionsErrors( 'create', $wgUser );
|
|
|
|
|
$editErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser );
|
|
|
|
|
$errors = array_merge( $createErrors, $editErrors );
|
2009-12-26 20:03:33 +00:00
|
|
|
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( !count( $errors ) ) {
|
2010-03-07 18:29:22 +00:00
|
|
|
$text = wfMsgNoTrans( 'noarticletext' );
|
2010-05-30 14:28:54 +00:00
|
|
|
} else {
|
2010-03-07 18:29:22 +00:00
|
|
|
$text = wfMsgNoTrans( 'noarticletext-nopermission' );
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2004-02-27 02:24:14 +00:00
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$text = "<div class='noarticletext'>\n$text\n</div>";
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->hasViewableContent() ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// If there's no backing content, send a 404 Not Found
|
|
|
|
|
// for better machine handling of broken links.
|
2011-03-25 03:36:18 +00:00
|
|
|
$wgRequest->response()->header( "HTTP/1.1 404 Not Found" );
|
2005-04-07 23:04:08 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$wgOut->addWikiText( $text );
|
|
|
|
|
}
|
2006-06-13 11:37:09 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* If the revision requested for view is deleted, check permissions.
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* Send either an error message or a warning header to $wgOut.
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return boolean true if the view is allowed, false if not.
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
*/
|
|
|
|
|
public function showDeletedRevisionHeader() {
|
|
|
|
|
global $wgOut, $wgRequest;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// Not deleted
|
|
|
|
|
return true;
|
2004-08-09 05:38:11 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// If the user is not allowed to see it...
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) {
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
'rev-deleted-text-permission' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return false;
|
|
|
|
|
// If the user needs to confirm that they want to see it...
|
2010-02-14 22:07:30 +00:00
|
|
|
} else if ( $wgRequest->getInt( 'unhide' ) != 1 ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Give explanation and add a link to view the revision...
|
|
|
|
|
$oldid = intval( $this->getOldID() );
|
|
|
|
|
$link = $this->mTitle->getFullUrl( "oldid={$oldid}&unhide=1" );
|
2009-07-30 18:01:41 +00:00
|
|
|
$msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
|
|
|
|
|
'rev-suppressed-text-unhide' : 'rev-deleted-text-unhide';
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
|
2010-02-14 22:07:30 +00:00
|
|
|
array( $msg, $link ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return false;
|
|
|
|
|
// We are allowed to see...
|
|
|
|
|
} else {
|
2009-07-30 18:01:41 +00:00
|
|
|
$msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
|
|
|
|
|
'rev-suppressed-text-view' : 'rev-deleted-text-view';
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", $msg );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return true;
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Should the parser cache be used?
|
|
|
|
|
*
|
|
|
|
|
* @return boolean
|
|
|
|
|
*/
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
public function useParserCache( $oldid ) {
|
2008-07-03 19:05:06 +00:00
|
|
|
global $wgUser, $wgEnableParserCache;
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2008-07-03 19:05:06 +00:00
|
|
|
return $wgEnableParserCache
|
2010-08-03 22:32:09 +00:00
|
|
|
&& $wgUser->getStubThreshold() == 0
|
2008-07-03 19:05:06 +00:00
|
|
|
&& $this->exists()
|
|
|
|
|
&& empty( $oldid )
|
|
|
|
|
&& !$this->mTitle->isCssOrJsPage()
|
|
|
|
|
&& !$this->mTitle->isCssJsSubpage();
|
|
|
|
|
}
|
2008-08-08 00:01:53 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
|
|
|
|
* Execute the uncached parse for action=view
|
|
|
|
|
*/
|
|
|
|
|
public function doViewParse() {
|
|
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$oldid = $this->getOldID();
|
2010-08-09 07:41:25 +00:00
|
|
|
$parserOptions = $this->getParserOptions();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Render printable version, use printable version cache
|
|
|
|
|
$parserOptions->setIsPrintable( $wgOut->isPrintable() );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Don't show section-edit links on old revisions... this way lies madness.
|
2010-12-29 16:42:46 +00:00
|
|
|
if ( !$this->isCurrent() || $wgOut->isPrintable() || !$this->mTitle->quickUserCan( 'edit' ) ) {
|
2010-08-05 14:37:50 +00:00
|
|
|
$parserOptions->setEditSection( false );
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$useParserCache = $this->useParserCache( $oldid );
|
|
|
|
|
$this->outputWikiText( $this->getContent(), $useParserCache, $parserOptions );
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
return true;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2009-12-26 20:03:33 +00:00
|
|
|
* Try to fetch an expired entry from the parser cache. If it is present,
|
|
|
|
|
* output it and return true. If it is not present, output nothing and
|
|
|
|
|
* return false. This is used as a callback function for
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
* PoolCounter::executeProtected().
|
2010-03-15 01:08:07 +00:00
|
|
|
*
|
|
|
|
|
* @return boolean
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
*/
|
|
|
|
|
public function tryDirtyCache() {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
$parserCache = ParserCache::singleton();
|
2010-12-26 19:23:11 +00:00
|
|
|
$options = $this->getParserOptions();
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-05 14:37:50 +00:00
|
|
|
if ( $wgOut->isPrintable() ) {
|
|
|
|
|
$options->setIsPrintable( true );
|
2010-08-18 10:00:42 +00:00
|
|
|
$options->setEditSection( false );
|
2010-08-05 14:37:50 +00:00
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$output = $parserCache->getDirty( $this, $options );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
if ( $output ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": sending dirty output\n" );
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
wfDebugLog( 'dirty', "dirty output " . $parserCache->getKey( $this, $options ) . "\n" );
|
|
|
|
|
$wgOut->setSquidMaxage( 0 );
|
2009-09-01 14:11:29 +00:00
|
|
|
$this->mParserOutput = $output;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$wgOut->addParserOutput( $output );
|
|
|
|
|
$wgOut->addHTML( "<!-- parser cache is expired, sending anyway due to pool overload-->\n" );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
wfDebugLog( 'dirty', "dirty missing\n" );
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": no dirty cache\n" );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-02 02:39:09 +00:00
|
|
|
/**
|
|
|
|
|
* View redirect
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $target Title|Array of destination(s) to redirect
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $appendSubtitle Boolean [optional]
|
|
|
|
|
* @param $forceKnown Boolean: should the image be shown as a bluelink regardless of existence?
|
2010-03-15 01:08:07 +00:00
|
|
|
* @return string containing HMTL with redirect link
|
2008-08-02 02:39:09 +00:00
|
|
|
*/
|
|
|
|
|
public function viewRedirect( $target, $appendSubtitle = true, $forceKnown = false ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
global $wgOut, $wgContLang, $wgStylePath;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !is_array( $target ) ) {
|
2009-01-21 20:42:32 +00:00
|
|
|
$target = array( $target );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-22 01:24:04 +00:00
|
|
|
$imageDir = $wgContLang->getDir();
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $appendSubtitle ) {
|
2008-07-02 10:33:42 +00:00
|
|
|
$wgOut->appendSubtitle( wfMsgHtml( 'redirectpagesub' ) );
|
2008-05-11 19:49:08 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-01-21 20:42:32 +00:00
|
|
|
// the loop prepends the arrow image before the link, so the first case needs to be outside
|
|
|
|
|
$title = array_shift( $target );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $forceKnown ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
$link = Linker::linkKnown( $title, htmlspecialchars( $title->getFullText() ) );
|
2008-11-28 14:29:25 +00:00
|
|
|
} else {
|
2011-04-25 11:59:31 +00:00
|
|
|
$link = Linker::link( $title, htmlspecialchars( $title->getFullText() ) );
|
2009-01-21 20:42:32 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-06-28 07:17:16 +00:00
|
|
|
$nextRedirect = $wgStylePath . '/common/images/nextredirect' . $imageDir . '.png';
|
|
|
|
|
$alt = $wgContLang->isRTL() ? '←' : '→';
|
2010-05-30 14:28:54 +00:00
|
|
|
// Automatically append redirect=no to each link, since most of them are redirect pages themselves.
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $target as $rt ) {
|
2010-06-28 07:17:16 +00:00
|
|
|
$link .= Html::element( 'img', array( 'src' => $nextRedirect, 'alt' => $alt ) );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $forceKnown ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
$link .= Linker::linkKnown( $rt, htmlspecialchars( $rt->getFullText(), array(), array( 'redirect' => 'no' ) ) );
|
2009-01-21 20:42:32 +00:00
|
|
|
} else {
|
2011-04-25 11:59:31 +00:00
|
|
|
$link .= Linker::link( $rt, htmlspecialchars( $rt->getFullText() ), array(), array( 'redirect' => 'no' ) );
|
2009-01-21 20:42:32 +00:00
|
|
|
}
|
2008-11-28 14:29:25 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-12-13 19:47:34 +00:00
|
|
|
$imageUrl = $wgStylePath . '/common/images/redirect' . $imageDir . '.png';
|
2010-11-19 21:23:50 +00:00
|
|
|
return '<div class="redirectMsg">' .
|
|
|
|
|
Html::element( 'img', array( 'src' => $imageUrl, 'alt' => '#REDIRECT' ) ) .
|
|
|
|
|
'<span class="redirectText">' . $link . '</span></div>';
|
2008-05-11 19:49:08 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Builds trackback links for article display if $wgUseTrackbacks is set to true
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function addTrackbacks() {
|
2011-04-03 03:59:47 +00:00
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$tbs = $dbr->select( 'trackbacks',
|
2010-02-14 22:07:30 +00:00
|
|
|
array( 'tb_id', 'tb_title', 'tb_url', 'tb_ex', 'tb_name' ),
|
|
|
|
|
array( 'tb_page' => $this->getID() )
|
2005-07-23 05:47:25 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
|
|
|
|
if ( !$dbr->numRows( $tbs ) ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2005-07-23 05:47:25 +00:00
|
|
|
|
2011-01-04 06:12:33 +00:00
|
|
|
$wgOut->preventClickjacking();
|
|
|
|
|
|
2005-07-23 05:47:25 +00:00
|
|
|
$tbtext = "";
|
2010-10-13 23:11:40 +00:00
|
|
|
foreach ( $tbs as $o ) {
|
2005-08-02 13:35:19 +00:00
|
|
|
$rmvtxt = "";
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-03 03:59:47 +00:00
|
|
|
if ( $wgOut->getUser()->isAllowed( 'trackback' ) ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
$delurl = $this->mTitle->getFullURL( "action=deletetrackback&tbid=" .
|
2011-04-03 03:59:47 +00:00
|
|
|
$o->tb_id . "&token=" . urlencode( $wgOut->getUser()->editToken() ) );
|
2007-06-23 10:15:10 +00:00
|
|
|
$rmvtxt = wfMsg( 'trackbackremove', htmlspecialchars( $delurl ) );
|
2005-07-23 06:30:26 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-03-25 21:50:23 +00:00
|
|
|
$tbtext .= "\n";
|
2010-06-28 07:17:16 +00:00
|
|
|
$tbtext .= wfMsgNoTrans( strlen( $o->tb_ex ) ? 'trackbackexcerpt' : 'trackback',
|
2005-07-23 05:47:25 +00:00
|
|
|
$o->tb_title,
|
|
|
|
|
$o->tb_url,
|
|
|
|
|
$o->tb_ex,
|
2005-07-23 06:30:26 +00:00
|
|
|
$o->tb_name,
|
2010-02-14 22:07:30 +00:00
|
|
|
$rmvtxt );
|
2005-07-23 05:47:25 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-05-28 21:22:45 +00:00
|
|
|
$wgOut->wrapWikiMsg( "<div id='mw_trackbacks'>\n$1\n</div>\n", array( 'trackbackbox', $tbtext ) );
|
2005-07-23 05:47:25 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Removes trackback record for current article from trackbacks table
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function deletetrackback() {
|
2011-04-03 03:59:47 +00:00
|
|
|
global $wgRequest, $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-03 03:59:47 +00:00
|
|
|
if ( !$wgOut->getUser()->matchEditToken( $wgRequest->getVal( 'token' ) ) ) {
|
2008-02-18 07:25:35 +00:00
|
|
|
$wgOut->addWikiMsg( 'sessionfailure' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-07-23 06:30:26 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-03 03:59:47 +00:00
|
|
|
$permission_errors = $this->mTitle->getUserPermissionsErrors( 'delete', $wgOut->getUser() );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( count( $permission_errors ) ) {
|
2007-09-09 08:11:58 +00:00
|
|
|
$wgOut->showPermissionsErrorPage( $permission_errors );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-07-23 06:30:26 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
$db = wfGetDB( DB_MASTER );
|
2010-02-14 22:07:30 +00:00
|
|
|
$db->delete( 'trackbacks', array( 'tb_id' => $wgRequest->getInt( 'tbid' ) ) );
|
2008-11-28 14:29:25 +00:00
|
|
|
|
|
|
|
|
$wgOut->addWikiMsg( 'trackbackdeleteok' );
|
|
|
|
|
$this->mTitle->invalidateCache();
|
2005-07-23 06:30:26 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-03-15 01:08:07 +00:00
|
|
|
/**
|
|
|
|
|
* Handle action=render
|
|
|
|
|
*/
|
2005-07-23 06:30:26 +00:00
|
|
|
|
2008-11-28 14:29:25 +00:00
|
|
|
public function render() {
|
2005-07-03 04:00:33 +00:00
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$wgOut->setArticleBodyOnly( true );
|
2005-07-03 04:00:33 +00:00
|
|
|
$this->view();
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-03-01 01:27:36 +00:00
|
|
|
/**
|
|
|
|
|
* Handle action=purge
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function purge() {
|
2011-04-14 10:38:29 +00:00
|
|
|
return Action::factory( 'purge', $this )->show();
|
2005-11-07 04:14:15 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-03-01 01:27:36 +00:00
|
|
|
/**
|
|
|
|
|
* Perform the actions of a page purging
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function doPurge() {
|
2006-03-01 01:27:36 +00:00
|
|
|
global $wgUseSquid;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-14 10:38:29 +00:00
|
|
|
if( !wfRunHooks( 'ArticlePurge', array( &$this ) ) ){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-01 01:27:36 +00:00
|
|
|
// Invalidate the cache
|
|
|
|
|
$this->mTitle->invalidateCache();
|
2010-12-28 18:16:46 +00:00
|
|
|
$this->clear();
|
2006-03-01 01:27:36 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgUseSquid ) {
|
2006-03-01 01:27:36 +00:00
|
|
|
// Commit the transaction before the purge is sent
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2009-12-14 23:05:35 +00:00
|
|
|
$dbw->commit();
|
2006-03-01 01:27:36 +00:00
|
|
|
|
|
|
|
|
// Send purge
|
|
|
|
|
$update = SquidUpdate::newSimplePurge( $this->mTitle );
|
|
|
|
|
$update->doUpdate();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
|
|
|
|
if ( $this->getID() == 0 ) {
|
2008-02-13 05:46:43 +00:00
|
|
|
$text = false;
|
|
|
|
|
} else {
|
2009-01-10 13:41:22 +00:00
|
|
|
$text = $this->getRawText();
|
2008-02-13 05:46:43 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-26 15:42:04 +00:00
|
|
|
MessageCache::singleton()->replace( $this->mTitle->getDBkey(), $text );
|
2008-02-09 10:01:35 +00:00
|
|
|
}
|
2006-03-01 01:27:36 +00:00
|
|
|
}
|
2005-07-03 04:00:33 +00:00
|
|
|
|
2005-03-11 08:38:24 +00:00
|
|
|
/**
|
|
|
|
|
* Insert a new empty page record for this article.
|
|
|
|
|
* This *must* be followed up by creating a revision
|
2010-05-01 10:56:52 +00:00
|
|
|
* and running $this->updateRevisionOn( ... );
|
2005-03-11 08:38:24 +00:00
|
|
|
* or else the record will be left in a funky state.
|
|
|
|
|
* Best if all done inside a transaction.
|
|
|
|
|
*
|
2011-05-13 16:16:44 +00:00
|
|
|
* @param $dbw DatabaseBase
|
2008-11-30 10:10:15 +00:00
|
|
|
* @return int The newly created page_id key, or false if the title already existed
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-03-11 08:38:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function insertOn( $dbw ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-03-11 08:38:24 +00:00
|
|
|
$page_id = $dbw->nextSequenceValue( 'page_page_id_seq' );
|
|
|
|
|
$dbw->insert( 'page', array(
|
|
|
|
|
'page_id' => $page_id,
|
|
|
|
|
'page_namespace' => $this->mTitle->getNamespace(),
|
|
|
|
|
'page_title' => $this->mTitle->getDBkey(),
|
|
|
|
|
'page_counter' => 0,
|
2007-01-19 09:50:19 +00:00
|
|
|
'page_restrictions' => '',
|
2005-03-11 08:38:24 +00:00
|
|
|
'page_is_redirect' => 0, # Will set this shortly...
|
|
|
|
|
'page_is_new' => 1,
|
|
|
|
|
'page_random' => wfRandom(),
|
|
|
|
|
'page_touched' => $dbw->timestamp(),
|
|
|
|
|
'page_latest' => 0, # Fill this in shortly...
|
2005-10-25 23:26:14 +00:00
|
|
|
'page_len' => 0, # Fill this in shortly...
|
2008-09-25 10:15:19 +00:00
|
|
|
), __METHOD__, 'IGNORE' );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
$affected = $dbw->affectedRows();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $affected ) {
|
2008-09-25 10:15:19 +00:00
|
|
|
$newid = $dbw->insertId();
|
2011-02-18 23:44:18 +00:00
|
|
|
$this->mTitle->resetArticleID( $newid );
|
2008-09-25 10:15:19 +00:00
|
|
|
}
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
return $affected ? $newid : false;
|
2005-03-11 08:38:24 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-03-11 08:38:24 +00:00
|
|
|
/**
|
|
|
|
|
* Update the page record to point to a newly saved revision.
|
|
|
|
|
*
|
2010-11-13 00:47:51 +00:00
|
|
|
* @param $dbw DatabaseBase: object
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $revision Revision: For ID number, and text used to set
|
2011-02-12 04:06:22 +00:00
|
|
|
length and redirect status fields
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $lastRevision Integer: if given, will not overwrite the page field
|
|
|
|
|
* when different from the currently set value.
|
|
|
|
|
* Giving 0 indicates the new page flag should be set
|
|
|
|
|
* on.
|
|
|
|
|
* @param $lastRevIsRedirect Boolean: if given, will optimize adding and
|
2009-12-26 20:03:33 +00:00
|
|
|
* removing rows in redirect table.
|
2005-03-11 08:38:24 +00:00
|
|
|
* @return bool true on success, false on failure
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2005-03-11 08:38:24 +00:00
|
|
|
*/
|
2011-04-15 23:28:13 +00:00
|
|
|
public function updateRevisionOn( &$dbw, $revision, $lastRevision = null, $lastRevIsRedirect = null ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-10-29 21:25:40 +00:00
|
|
|
$text = $revision->getText();
|
2010-07-08 10:49:36 +00:00
|
|
|
$rt = Title::newFromRedirectRecurse( $text );
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2005-03-12 10:50:51 +00:00
|
|
|
$conditions = array( 'page_id' => $this->getId() );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !is_null( $lastRevision ) ) {
|
2005-03-12 10:50:51 +00:00
|
|
|
# An extra check against threads stepping on each other
|
|
|
|
|
$conditions['page_latest'] = $lastRevision;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-11 08:38:24 +00:00
|
|
|
$dbw->update( 'page',
|
|
|
|
|
array( /* SET */
|
2005-03-13 07:49:15 +00:00
|
|
|
'page_latest' => $revision->getId(),
|
2005-03-11 08:38:24 +00:00
|
|
|
'page_touched' => $dbw->timestamp(),
|
2011-04-15 23:28:13 +00:00
|
|
|
'page_is_new' => ( $lastRevision === 0 ) ? 1 : 0,
|
2009-12-11 21:07:27 +00:00
|
|
|
'page_is_redirect' => $rt !== null ? 1 : 0,
|
2005-03-12 11:51:02 +00:00
|
|
|
'page_len' => strlen( $text ),
|
2005-03-12 10:50:51 +00:00
|
|
|
),
|
|
|
|
|
$conditions,
|
2006-06-20 09:50:57 +00:00
|
|
|
__METHOD__ );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-10-31 15:57:37 +00:00
|
|
|
$result = $dbw->affectedRows() != 0;
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $result ) {
|
2007-01-17 22:32:40 +00:00
|
|
|
$this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
|
2006-10-31 15:57:37 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-10-31 15:57:37 +00:00
|
|
|
return $result;
|
2005-03-11 08:38:24 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-10-29 21:25:40 +00:00
|
|
|
/**
|
2007-01-17 22:32:40 +00:00
|
|
|
* Add row to the redirect table if this is a redirect, remove otherwise.
|
2006-10-29 21:25:40 +00:00
|
|
|
*
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $dbw DatabaseBase
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $redirectTitle Title object pointing to the redirect target,
|
2009-12-26 20:03:33 +00:00
|
|
|
* or NULL if this is not a redirect
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $lastRevIsRedirect If given, will optimize adding and
|
2009-12-26 20:03:33 +00:00
|
|
|
* removing rows in redirect table.
|
2006-10-29 21:25:40 +00:00
|
|
|
* @return bool true on success, false on failure
|
|
|
|
|
* @private
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function updateRedirectOn( &$dbw, $redirectTitle, $lastRevIsRedirect = null ) {
|
2006-10-29 21:25:40 +00:00
|
|
|
// Always update redirects (target link might have changed)
|
|
|
|
|
// Update/Insert if we don't know if the last revision was a redirect or not
|
|
|
|
|
// Delete if changing from redirect to non-redirect
|
2010-02-14 22:07:30 +00:00
|
|
|
$isRedirect = !is_null( $redirectTitle );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-02-10 17:13:12 +00:00
|
|
|
if ( !$isRedirect && !is_null( $lastRevIsRedirect ) && $lastRevIsRedirect === $isRedirect ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-03-08 18:12:17 +00:00
|
|
|
|
2011-02-10 17:13:12 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
if ( $isRedirect ) {
|
|
|
|
|
$this->insertRedirectEntry( $redirectTitle );
|
|
|
|
|
} else {
|
|
|
|
|
// This is not a redirect, remove row from redirect table
|
|
|
|
|
$where = array( 'rd_from' => $this->getId() );
|
|
|
|
|
$dbw->delete( 'redirect', $where, __METHOD__ );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-02-10 17:13:12 +00:00
|
|
|
if ( $this->getTitle()->getNamespace() == NS_FILE ) {
|
|
|
|
|
RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $this->getTitle() );
|
2006-10-29 21:25:40 +00:00
|
|
|
}
|
2011-02-10 17:13:12 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-02-10 17:13:12 +00:00
|
|
|
return ( $dbw->affectedRows() != 0 );
|
2006-10-29 21:25:40 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-13 07:22:20 +00:00
|
|
|
/**
|
|
|
|
|
* If the given revision is newer than the currently set page_latest,
|
|
|
|
|
* update the page record. Otherwise, do nothing.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $dbw Database object
|
|
|
|
|
* @param $revision Revision object
|
2010-05-30 14:28:54 +00:00
|
|
|
* @return mixed
|
2005-03-13 07:22:20 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function updateIfNewerOn( &$dbw, $revision ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-03-13 07:22:20 +00:00
|
|
|
$row = $dbw->selectRow(
|
|
|
|
|
array( 'revision', 'page' ),
|
2006-10-29 21:25:40 +00:00
|
|
|
array( 'rev_id', 'rev_timestamp', 'page_is_redirect' ),
|
2005-03-13 07:22:20 +00:00
|
|
|
array(
|
|
|
|
|
'page_id' => $this->getId(),
|
|
|
|
|
'page_latest=rev_id' ),
|
2006-06-20 09:50:57 +00:00
|
|
|
__METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $row ) {
|
|
|
|
|
if ( wfTimestamp( TS_MW, $row->rev_timestamp ) >= $revision->getTimestamp() ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-03-13 07:22:20 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$prev = $row->rev_id;
|
2006-10-31 15:57:37 +00:00
|
|
|
$lastRevIsRedirect = (bool)$row->page_is_redirect;
|
2005-03-13 07:22:20 +00:00
|
|
|
} else {
|
|
|
|
|
# No or missing previous revision; mark the page as new
|
|
|
|
|
$prev = 0;
|
2006-10-29 21:25:40 +00:00
|
|
|
$lastRevIsRedirect = null;
|
2005-03-13 07:22:20 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-10-29 21:25:40 +00:00
|
|
|
$ret = $this->updateRevisionOn( $dbw, $revision, $prev, $lastRevIsRedirect );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-03-13 07:22:20 +00:00
|
|
|
return $ret;
|
|
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-10-28 07:07:21 +00:00
|
|
|
/**
|
2008-12-12 01:05:51 +00:00
|
|
|
* @param $section empty/null/false or a section number (0, 1, 2, T1, T2...)
|
2010-04-10 21:14:49 +00:00
|
|
|
* @param $text String: new text of the section
|
|
|
|
|
* @param $summary String: new section's subject, only if $section is 'new'
|
|
|
|
|
* @param $edittime String: revision timestamp or null to use the current revision
|
2005-10-28 07:07:21 +00:00
|
|
|
* @return string Complete article text, or null if error
|
|
|
|
|
*/
|
2009-12-11 21:07:27 +00:00
|
|
|
public function replaceSection( $section, $text, $summary = '', $edittime = null ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( strval( $section ) == '' ) {
|
2008-11-28 14:29:25 +00:00
|
|
|
// Whole-page edit; let the whole text through
|
2006-06-06 00:51:34 +00:00
|
|
|
} else {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_null( $edittime ) ) {
|
2005-04-26 09:52:11 +00:00
|
|
|
$rev = Revision::newFromTitle( $this->mTitle );
|
|
|
|
|
} else {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-04-26 09:52:11 +00:00
|
|
|
$rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$rev ) {
|
2005-10-28 07:07:21 +00:00
|
|
|
wfDebug( "Article::replaceSection asked for bogus section (page: " .
|
|
|
|
|
$this->getId() . "; section: $section; edittime: $edittime)\n" );
|
2011-02-10 16:39:53 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-10-28 07:07:21 +00:00
|
|
|
return null;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-04-26 09:52:11 +00:00
|
|
|
$oldtext = $rev->getText();
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $section == 'new' ) {
|
2006-12-18 19:30:26 +00:00
|
|
|
# Inserting a new section
|
2010-02-14 22:07:30 +00:00
|
|
|
$subject = $summary ? wfMsgForContent( 'newsectionheaderdefaultlevel', $summary ) . "\n\n" : '';
|
2006-12-18 19:30:26 +00:00
|
|
|
$text = strlen( trim( $oldtext ) ) > 0
|
|
|
|
|
? "{$oldtext}\n\n{$subject}{$text}"
|
2006-12-18 19:32:41 +00:00
|
|
|
: "{$subject}{$text}";
|
2003-07-21 07:36:52 +00:00
|
|
|
} else {
|
2006-12-18 19:30:26 +00:00
|
|
|
# Replacing an existing section; roll out the big guns
|
2006-06-06 00:51:34 +00:00
|
|
|
global $wgParser;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-06 00:51:34 +00:00
|
|
|
$text = $wgParser->replaceSection( $oldtext, $section, $text );
|
2003-07-21 07:36:52 +00:00
|
|
|
}
|
2003-06-30 00:19:35 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-03-14 22:28:52 +00:00
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-14 20:36:23 +00:00
|
|
|
/**
|
|
|
|
|
* Check flags and add EDIT_NEW or EDIT_UPDATE to them as needed.
|
|
|
|
|
* @param $flags Int
|
|
|
|
|
* @return Int updated $flags
|
|
|
|
|
*/
|
|
|
|
|
function checkFlags( $flags ) {
|
|
|
|
|
if ( !( $flags & EDIT_NEW ) && !( $flags & EDIT_UPDATE ) ) {
|
|
|
|
|
if ( $this->mTitle->getArticleID() ) {
|
|
|
|
|
$flags |= EDIT_UPDATE;
|
|
|
|
|
} else {
|
|
|
|
|
$flags |= EDIT_NEW;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $flags;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
/**
|
|
|
|
|
* Article::doEdit()
|
|
|
|
|
*
|
2007-01-17 22:32:40 +00:00
|
|
|
* Change an existing article or create a new article. Updates RC and all necessary caches,
|
2006-06-20 09:50:57 +00:00
|
|
|
* optionally via the deferred update array.
|
2004-09-11 11:39:24 +00:00
|
|
|
*
|
2006-06-20 09:50:57 +00:00
|
|
|
* $wgUser must be set before calling this function.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $text String: new text
|
|
|
|
|
* @param $summary String: edit summary
|
|
|
|
|
* @param $flags Integer bitfield:
|
2006-06-20 09:50:57 +00:00
|
|
|
* EDIT_NEW
|
|
|
|
|
* Article is known or assumed to be non-existent, create a new one
|
|
|
|
|
* EDIT_UPDATE
|
|
|
|
|
* Article is known or assumed to be pre-existing, update it
|
|
|
|
|
* EDIT_MINOR
|
|
|
|
|
* Mark this edit minor, if the user is allowed to do so
|
|
|
|
|
* EDIT_SUPPRESS_RC
|
|
|
|
|
* Do not log the change in recentchanges
|
|
|
|
|
* EDIT_FORCE_BOT
|
|
|
|
|
* Mark the edit a "bot" edit regardless of user rights
|
|
|
|
|
* EDIT_DEFER_UPDATES
|
|
|
|
|
* Defer some of the updates until the end of index.php
|
2006-11-08 08:06:51 +00:00
|
|
|
* EDIT_AUTOSUMMARY
|
|
|
|
|
* Fill in blank summaries with generated text where possible
|
2007-01-17 22:32:40 +00:00
|
|
|
*
|
|
|
|
|
* If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
|
2009-06-18 02:50:16 +00:00
|
|
|
* If EDIT_UPDATE is specified and the article doesn't exist, the function will an
|
|
|
|
|
* edit-gone-missing error. If EDIT_NEW is specified and the article does exist, an
|
|
|
|
|
* edit-already-exists error will be returned. These two conditions are also possible with
|
2008-09-25 10:15:19 +00:00
|
|
|
* auto-detection due to MediaWiki's performance-optimised locking strategy.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $baseRevId the revision ID this edit was based off, if any
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $user User (optional), $wgUser will be used if not passed
|
2006-06-20 09:50:57 +00:00
|
|
|
*
|
2008-09-25 10:15:19 +00:00
|
|
|
* @return Status object. Possible errors:
|
|
|
|
|
* edit-hook-aborted: The ArticleSave hook aborted the edit but didn't set the fatal flag of $status
|
|
|
|
|
* edit-gone-missing: In update mode, but the article didn't exist
|
|
|
|
|
* edit-conflict: In update mode, the article changed unexpectedly
|
|
|
|
|
* edit-no-change: Warning that the text was the same as before
|
|
|
|
|
* edit-already-exists: In creation mode, but the article already exists
|
|
|
|
|
*
|
|
|
|
|
* Extensions may define additional errors.
|
|
|
|
|
*
|
|
|
|
|
* $return->value will contain an associative array with members as follows:
|
|
|
|
|
* new: Boolean indicating if the function attempted to create a new article
|
|
|
|
|
* revision: The revision object for the inserted revision, or null
|
|
|
|
|
*
|
|
|
|
|
* Compatibility note: this function previously returned a boolean value indicating success/failure
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2010-08-09 08:33:42 +00:00
|
|
|
public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
|
2008-05-24 14:55:54 +00:00
|
|
|
global $wgUser, $wgDBtransactions, $wgUseAutomaticEditSummaries;
|
2008-08-21 00:45:13 +00:00
|
|
|
|
2008-09-21 02:53:24 +00:00
|
|
|
# Low-level sanity check
|
2010-06-28 07:17:16 +00:00
|
|
|
if ( $this->mTitle->getText() === '' ) {
|
2008-09-21 02:53:24 +00:00
|
|
|
throw new MWException( 'Something is trying to edit an article with an empty title' );
|
2008-08-16 13:34:43 +00:00
|
|
|
}
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2008-09-21 02:53:24 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$user = is_null( $user ) ? $wgUser : $user;
|
2008-09-25 10:15:19 +00:00
|
|
|
$status = Status::newGood( array() );
|
|
|
|
|
|
|
|
|
|
# Load $this->mTitle->getArticleID() and $this->mLatest if it's not already
|
2009-06-18 02:50:16 +00:00
|
|
|
$this->loadPageData();
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2010-05-14 20:36:23 +00:00
|
|
|
$flags = $this->checkFlags( $flags );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !wfRunHooks( 'ArticleSave', array( &$this, &$user, &$text, &$summary,
|
2010-08-09 08:33:42 +00:00
|
|
|
$flags & EDIT_MINOR, null, null, &$flags, &$status ) ) )
|
2006-06-20 09:50:57 +00:00
|
|
|
{
|
|
|
|
|
wfDebug( __METHOD__ . ": ArticleSave hook aborted save!\n" );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $status->isOK() ) {
|
|
|
|
|
$status->fatal( 'edit-hook-aborted' );
|
2008-09-25 10:15:19 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-02-10 16:39:53 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-09-25 10:15:19 +00:00
|
|
|
return $status;
|
2005-08-23 08:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Silently ignore EDIT_MINOR if not allowed
|
2010-02-14 22:07:30 +00:00
|
|
|
$isminor = ( $flags & EDIT_MINOR ) && $user->isAllowed( 'minoredit' );
|
2008-01-10 13:33:23 +00:00
|
|
|
$bot = $flags & EDIT_FORCE_BOT;
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2009-01-10 13:41:22 +00:00
|
|
|
$oldtext = $this->getRawText(); // current revision
|
2006-11-20 11:48:03 +00:00
|
|
|
$oldsize = strlen( $oldtext );
|
|
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
# Provide autosummaries if one is not provided and autosummaries are enabled.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '' ) {
|
2006-11-20 11:48:03 +00:00
|
|
|
$summary = $this->getAutosummary( $oldtext, $text, $flags );
|
2008-05-24 14:55:54 +00:00
|
|
|
}
|
2006-11-06 17:59:02 +00:00
|
|
|
|
2011-01-04 19:08:44 +00:00
|
|
|
$editInfo = $this->prepareTextForEdit( $text, null, $user );
|
2007-11-12 07:30:40 +00:00
|
|
|
$text = $editInfo->pst;
|
2006-12-20 00:06:15 +00:00
|
|
|
$newsize = strlen( $text );
|
2006-06-20 09:50:57 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-04-10 18:23:11 +00:00
|
|
|
$now = wfTimestampNow();
|
2010-02-14 22:07:30 +00:00
|
|
|
$this->mTimestamp = $now;
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $flags & EDIT_UPDATE ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
# Update article, but only if changed.
|
2008-09-25 10:15:19 +00:00
|
|
|
$status->value['new'] = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Make sure the revision is either completely inserted or not inserted at all
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgDBtransactions ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
$userAbort = ignore_user_abort( true );
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2008-09-12 15:03:46 +00:00
|
|
|
$changed = ( strcmp( $text, $oldtext ) != 0 );
|
2008-09-21 07:56:09 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $changed ) {
|
|
|
|
|
if ( !$this->mLatest ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
# Article gone missing
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n" );
|
2008-09-25 10:15:19 +00:00
|
|
|
$status->fatal( 'edit-gone-missing' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-09-25 10:15:19 +00:00
|
|
|
return $status;
|
2006-06-20 09:50:57 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
$revision = new Revision( array(
|
|
|
|
|
'page' => $this->getId(),
|
|
|
|
|
'comment' => $summary,
|
|
|
|
|
'minor_edit' => $isminor,
|
2008-04-07 23:53:57 +00:00
|
|
|
'text' => $text,
|
2008-09-25 10:15:19 +00:00
|
|
|
'parent_id' => $this->mLatest,
|
2008-08-28 20:20:52 +00:00
|
|
|
'user' => $user->getId(),
|
|
|
|
|
'user_text' => $user->getName(),
|
2010-12-08 07:10:43 +00:00
|
|
|
'timestamp' => $now
|
2010-05-30 14:28:54 +00:00
|
|
|
) );
|
2006-06-20 09:50:57 +00:00
|
|
|
|
2008-09-21 07:56:09 +00:00
|
|
|
$dbw->begin();
|
2008-05-17 15:53:58 +00:00
|
|
|
$revisionId = $revision->insertOn( $dbw );
|
2006-06-20 09:50:57 +00:00
|
|
|
|
|
|
|
|
# Update page
|
2008-09-25 10:15:19 +00:00
|
|
|
#
|
2009-06-18 02:50:16 +00:00
|
|
|
# Note that we use $this->mLatest instead of fetching a value from the master DB
|
|
|
|
|
# during the course of this function. This makes sure that EditPage can detect
|
|
|
|
|
# edit conflicts reliably, either by $ok here, or by $article->getTimestamp()
|
2008-09-25 10:15:19 +00:00
|
|
|
# before this function is called. A previous function used a separate query, this
|
|
|
|
|
# creates a window where concurrent edits can cause an ignored edit conflict.
|
|
|
|
|
$ok = $this->updateRevisionOn( $dbw, $revision, $this->mLatest );
|
2006-06-20 09:50:57 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$ok ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
/* Belated edit conflict! Run away!! */
|
2008-09-25 10:15:19 +00:00
|
|
|
$status->fatal( 'edit-conflict' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
# Delete the invalid revision if the DB is not transactional
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgDBtransactions ) {
|
2008-09-25 10:15:19 +00:00
|
|
|
$dbw->delete( 'revision', array( 'rev_id' => $revisionId ), __METHOD__ );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-23 18:20:50 +00:00
|
|
|
$revisionId = 0;
|
2006-06-20 09:50:57 +00:00
|
|
|
$dbw->rollback();
|
|
|
|
|
} else {
|
2008-11-27 18:55:47 +00:00
|
|
|
global $wgUseRCPatrol;
|
2010-02-14 22:07:30 +00:00
|
|
|
wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
|
2006-06-20 09:50:57 +00:00
|
|
|
# Update recentchanges
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
|
2008-11-27 18:55:47 +00:00
|
|
|
# Mark as patrolled if the user can do so
|
2010-12-14 19:40:27 +00:00
|
|
|
$patrolled = $wgUseRCPatrol && !count(
|
|
|
|
|
$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
|
2008-11-27 18:55:47 +00:00
|
|
|
# Add RC row to the DB
|
2008-09-19 00:11:41 +00:00
|
|
|
$rc = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $user, $summary,
|
2008-09-25 10:15:19 +00:00
|
|
|
$this->mLatest, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
|
2008-11-27 18:55:47 +00:00
|
|
|
$revisionId, $patrolled
|
|
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-27 18:55:47 +00:00
|
|
|
# Log auto-patrolled edits
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $patrolled ) {
|
2008-11-27 18:55:47 +00:00
|
|
|
PatrolLog::record( $rc, true );
|
2006-06-20 09:50:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-08-16 13:34:43 +00:00
|
|
|
$user->incEditCount();
|
2008-09-21 07:56:09 +00:00
|
|
|
$dbw->commit();
|
2006-06-20 09:50:57 +00:00
|
|
|
}
|
|
|
|
|
} else {
|
2008-09-25 10:15:19 +00:00
|
|
|
$status->warning( 'edit-no-change' );
|
2007-08-21 03:21:27 +00:00
|
|
|
$revision = null;
|
2006-06-20 09:50:57 +00:00
|
|
|
// Keep the same revision ID, but do some updates on it
|
2011-01-10 08:33:19 +00:00
|
|
|
$revisionId = $this->getLatest();
|
2006-06-20 09:50:57 +00:00
|
|
|
// Update page_touched, this is usually implicit in the page update
|
|
|
|
|
// Other cache updates are done in onArticleEdit()
|
|
|
|
|
$this->mTitle->invalidateCache();
|
|
|
|
|
}
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgDBtransactions ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
ignore_user_abort( $userAbort );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
// Now that ignore_user_abort is restored, we can respond to fatal errors
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$status->isOK() ) {
|
2008-09-25 10:15:19 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $status;
|
2006-06-20 09:50:57 +00:00
|
|
|
}
|
2008-09-25 10:15:19 +00:00
|
|
|
|
|
|
|
|
# Invalidate cache of this article and all pages using this article
|
2009-02-16 14:26:34 +00:00
|
|
|
# as a template. Partly deferred.
|
|
|
|
|
Article::onArticleEdit( $this->mTitle );
|
2008-09-25 10:15:19 +00:00
|
|
|
# Update links tables, site stats, etc.
|
2011-01-04 19:08:44 +00:00
|
|
|
$this->editUpdates( $text, $summary, $isminor, $now, $revisionId, $changed, $user );
|
2006-06-20 09:50:57 +00:00
|
|
|
} else {
|
|
|
|
|
# Create new article
|
2008-09-25 10:15:19 +00:00
|
|
|
$status->value['new'] = true;
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2008-09-24 18:00:25 +00:00
|
|
|
$dbw->begin();
|
2008-09-25 10:15:19 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Add the page record; stake our claim on this title!
|
2008-09-25 10:15:19 +00:00
|
|
|
# This will return false if the article already exists
|
2006-06-20 09:50:57 +00:00
|
|
|
$newid = $this->insertOn( $dbw );
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $newid === false ) {
|
2008-09-25 10:15:19 +00:00
|
|
|
$dbw->rollback();
|
|
|
|
|
$status->fatal( 'edit-already-exists' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $status;
|
|
|
|
|
}
|
|
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Save the revision text...
|
2005-03-11 06:00:05 +00:00
|
|
|
$revision = new Revision( array(
|
2006-06-20 09:50:57 +00:00
|
|
|
'page' => $newid,
|
2005-03-11 06:00:05 +00:00
|
|
|
'comment' => $summary,
|
2005-03-11 08:38:24 +00:00
|
|
|
'minor_edit' => $isminor,
|
2008-09-15 05:34:32 +00:00
|
|
|
'text' => $text,
|
|
|
|
|
'user' => $user->getId(),
|
|
|
|
|
'user_text' => $user->getName(),
|
2010-12-08 07:10:43 +00:00
|
|
|
'timestamp' => $now
|
|
|
|
|
) );
|
2008-05-17 15:53:58 +00:00
|
|
|
$revisionId = $revision->insertOn( $dbw );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
$this->mTitle->resetArticleID( $newid );
|
2011-05-17 22:03:20 +00:00
|
|
|
# Update the LinkCache. Resetting the Title ArticleID means it will rely on having that already cached
|
|
|
|
|
# @todo FIXME?
|
2011-02-18 23:44:18 +00:00
|
|
|
LinkCache::singleton()->addGoodLinkObj( $newid, $this->mTitle, strlen( $text ), (bool)Title::newFromRedirect( $text ), $revisionId );
|
2005-03-11 08:38:24 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Update the page record with revision data
|
|
|
|
|
$this->updateRevisionOn( $dbw, $revision, 0 );
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-27 18:55:47 +00:00
|
|
|
# Update recentchanges
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
|
2008-11-27 18:55:47 +00:00
|
|
|
global $wgUseRCPatrol, $wgUseNPPatrol;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-27 18:55:47 +00:00
|
|
|
# Mark as patrolled if the user can do so
|
2010-12-14 19:40:27 +00:00
|
|
|
$patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) && !count(
|
|
|
|
|
$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
|
2008-11-27 18:55:47 +00:00
|
|
|
# Add RC row to the DB
|
2008-09-19 00:11:41 +00:00
|
|
|
$rc = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $user, $summary, $bot,
|
2010-02-14 22:07:30 +00:00
|
|
|
'', strlen( $text ), $revisionId, $patrolled );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-11-27 18:55:47 +00:00
|
|
|
# Log auto-patrolled edits
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $patrolled ) {
|
2008-11-27 18:55:47 +00:00
|
|
|
PatrolLog::record( $rc, true );
|
2006-03-18 22:47:40 +00:00
|
|
|
}
|
2004-06-11 14:48:31 +00:00
|
|
|
}
|
2008-08-16 13:34:43 +00:00
|
|
|
$user->incEditCount();
|
2008-09-24 18:00:25 +00:00
|
|
|
$dbw->commit();
|
2003-11-28 09:42:13 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Update links, etc.
|
2011-05-14 17:11:32 +00:00
|
|
|
$this->editUpdates( $text, $summary, $isminor, $now, $revisionId, true, $user, true );
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
# Clear caches
|
|
|
|
|
Article::onArticleCreate( $this->mTitle );
|
2005-12-30 09:33:11 +00:00
|
|
|
|
2008-08-16 13:34:43 +00:00
|
|
|
wfRunHooks( 'ArticleInsertComplete', array( &$this, &$user, $text, $summary,
|
2010-08-09 08:33:42 +00:00
|
|
|
$flags & EDIT_MINOR, null, null, &$flags, $revision ) );
|
2004-07-10 03:09:26 +00:00
|
|
|
}
|
2006-06-20 09:50:57 +00:00
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
# Do updates right now unless deferral was requested
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !( $flags & EDIT_DEFER_UPDATES ) ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfDoUpdates();
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-25 10:15:19 +00:00
|
|
|
// Return the new revision (or null) to the caller
|
|
|
|
|
$status->value['revision'] = $revision;
|
|
|
|
|
|
|
|
|
|
wfRunHooks( 'ArticleSaveComplete', array( &$this, &$user, $text, $summary,
|
2010-08-09 08:33:42 +00:00
|
|
|
$flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2008-09-25 10:15:19 +00:00
|
|
|
return $status;
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
/**
|
|
|
|
|
* Output a redirect back to the article.
|
|
|
|
|
* This is typically used after an edit.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $noRedir Boolean: add redirect=no
|
|
|
|
|
* @param $sectionAnchor String: section to redirect to, including "#"
|
|
|
|
|
* @param $extraQuery String: extra query params
|
2006-06-18 12:42:16 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function doRedirect( $noRedir = false, $sectionAnchor = '', $extraQuery = '' ) {
|
2006-06-18 12:42:16 +00:00
|
|
|
global $wgOut;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $noRedir ) {
|
2006-06-18 12:42:16 +00:00
|
|
|
$query = 'redirect=no';
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $extraQuery )
|
2010-06-01 15:19:19 +00:00
|
|
|
$query .= "&$extraQuery";
|
2006-06-18 12:42:16 +00:00
|
|
|
} else {
|
2008-05-23 09:03:49 +00:00
|
|
|
$query = $extraQuery;
|
2006-06-18 12:42:16 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
$wgOut->redirect( $this->mTitle->getFullURL( $query ) . $sectionAnchor );
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2007-10-29 20:38:58 +00:00
|
|
|
* Mark this particular edit/page as patrolled
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function markpatrolled() {
|
2011-04-03 03:59:47 +00:00
|
|
|
global $wgOut, $wgRequest;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-12-22 19:43:20 +00:00
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2004-08-09 23:30:02 +00:00
|
|
|
|
2007-10-29 20:38:58 +00:00
|
|
|
# If we haven't been given an rc_id value, we can't do anything
|
2010-02-14 22:07:30 +00:00
|
|
|
$rcid = (int) $wgRequest->getVal( 'rcid' );
|
2010-08-01 15:50:30 +00:00
|
|
|
|
2011-04-03 03:59:47 +00:00
|
|
|
if ( !$wgOut->getUser()->matchEditToken( $wgRequest->getVal( 'token' ), $rcid ) ) {
|
2010-08-01 15:50:30 +00:00
|
|
|
$wgOut->showErrorPage( 'sessionfailure-title', 'sessionfailure' );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$rc = RecentChange::newFromId( $rcid );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_null( $rc ) ) {
|
2008-03-24 15:04:55 +00:00
|
|
|
$wgOut->showErrorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' );
|
2007-10-29 20:38:58 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
# It would be nice to see where the user had actually come from, but for now just guess
|
2009-02-21 10:41:17 +00:00
|
|
|
$returnto = $rc->getAttribute( 'rc_type' ) == RC_NEW ? 'Newpages' : 'Recentchanges';
|
2009-01-31 21:25:48 +00:00
|
|
|
$return = SpecialPage::getTitleFor( $returnto );
|
2008-09-04 15:17:51 +00:00
|
|
|
|
|
|
|
|
$errors = $rc->doMarkPatrolled();
|
2008-09-19 00:11:41 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( in_array( array( 'rcpatroldisabled' ), $errors ) ) {
|
2008-03-24 15:04:55 +00:00
|
|
|
$wgOut->showErrorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2004-08-09 23:30:02 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( in_array( array( 'hookaborted' ), $errors ) ) {
|
2008-09-04 15:17:51 +00:00
|
|
|
// The hook itself has handled any output
|
2007-09-27 18:20:06 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( in_array( array( 'markedaspatrollederror-noautopatrol' ), $errors ) ) {
|
2008-09-04 15:17:51 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'markedaspatrollederror' ) );
|
|
|
|
|
$wgOut->addWikiMsg( 'markedaspatrollederror-noautopatrol' );
|
2011-04-25 11:59:31 +00:00
|
|
|
$wgOut->returnToMain( null, $return );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-12-22 19:43:20 +00:00
|
|
|
return;
|
2004-08-09 05:38:11 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !empty( $errors ) ) {
|
2008-09-04 15:17:51 +00:00
|
|
|
$wgOut->showPermissionsErrorPage( $errors );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-04 15:17:51 +00:00
|
|
|
return;
|
2008-02-28 21:41:06 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-12-22 19:43:20 +00:00
|
|
|
# Inform the user
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'markedaspatrolled' ) );
|
2010-01-18 19:05:41 +00:00
|
|
|
$wgOut->addWikiMsg( 'markedaspatrolledtext', $rc->getTitle()->getPrefixedText() );
|
2011-04-25 11:59:31 +00:00
|
|
|
$wgOut->returnToMain( null, $return );
|
2004-08-09 05:38:11 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
WatchAction requires token (BREAKING CHANGE)
* (bug 27655) Require token for watching/unwatching pages
* Previously done for API (bug 29070) in r88522
* As with markpatrolled, the tokens are not compatible and made that way on purpose. The API requires the POST method and uses a universal token per-session. Since the front-end is all GET based (also per convention like in markpatrolled and rollback) they are stronger salted (title / action specific)
* ajax.watch used the API already and was switched in r88554.
* The actual watching/unwatching code was moved from WatchAction->onView to WatchAction::doWatch. This was done to allow the API to do the action without needing to generate a token like the front-end needs (or having to duplicate code). It is now similar to RecentChange::markPatrolled (in that it also a "central" function that does not care about tokens, it's called after the token-handling)
* JavaScript / Gadgets that utilize action=watch in their scripts:
** Effects should be minimal as they should be using the API (see r88522 and wikitech-l)
** If they use index.php and scrap the link from the page, they can continue to do so.
* There are links to the watch action all over the place. I've tried to catch most of them, but there may be some I miss. Migration in most cases is just a matter of adding an array item to the $query for:
'token' => WatchAction::getWatchToken( $title, $user [, $action] )
or changing:
Action::factory( 'watch', $article )->execute();
to:
WatchAction::doWatch( $title, $user );
While replacing the usages in some cases an instance of Article() no longer had to be created, in others $wgUser had to be retrieved from global (which was implied before but needs to be given directly now)
Other notes:
* Article->unwatch() and Article->watch(), which were deprecated as of 1.18 and are no longer used in core, may be broken in scenarios where the Request does not have a 'token' but is making a call to $article->watch()
* Some extensions need to be fixed, I'm currently running a grep search and will fix them a.s.a.p
[1] http://www.mediawiki.org/wiki/ResourceLoader/Default_modules?mw.user#tokens
2011-06-06 00:09:03 +00:00
|
|
|
* User-interface handler for the "watch" action.
|
|
|
|
|
* Requires Request to pass a token as of 1.19.
|
2011-04-14 10:38:29 +00:00
|
|
|
* @deprecated since 1.18
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function watch() {
|
2011-04-14 10:38:29 +00:00
|
|
|
Action::factory( 'watch', $this )->show();
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2006-03-11 07:55:42 +00:00
|
|
|
* Add this page to $wgUser's watchlist
|
2011-02-24 16:00:06 +00:00
|
|
|
*
|
|
|
|
|
* This is safe to be called multiple times
|
|
|
|
|
*
|
2006-03-11 07:55:42 +00:00
|
|
|
* @return bool true on successful watch operation
|
2011-04-14 10:38:29 +00:00
|
|
|
* @deprecated since 1.18
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function doWatch() {
|
WatchAction requires token (BREAKING CHANGE)
* (bug 27655) Require token for watching/unwatching pages
* Previously done for API (bug 29070) in r88522
* As with markpatrolled, the tokens are not compatible and made that way on purpose. The API requires the POST method and uses a universal token per-session. Since the front-end is all GET based (also per convention like in markpatrolled and rollback) they are stronger salted (title / action specific)
* ajax.watch used the API already and was switched in r88554.
* The actual watching/unwatching code was moved from WatchAction->onView to WatchAction::doWatch. This was done to allow the API to do the action without needing to generate a token like the front-end needs (or having to duplicate code). It is now similar to RecentChange::markPatrolled (in that it also a "central" function that does not care about tokens, it's called after the token-handling)
* JavaScript / Gadgets that utilize action=watch in their scripts:
** Effects should be minimal as they should be using the API (see r88522 and wikitech-l)
** If they use index.php and scrap the link from the page, they can continue to do so.
* There are links to the watch action all over the place. I've tried to catch most of them, but there may be some I miss. Migration in most cases is just a matter of adding an array item to the $query for:
'token' => WatchAction::getWatchToken( $title, $user [, $action] )
or changing:
Action::factory( 'watch', $article )->execute();
to:
WatchAction::doWatch( $title, $user );
While replacing the usages in some cases an instance of Article() no longer had to be created, in others $wgUser had to be retrieved from global (which was implied before but needs to be given directly now)
Other notes:
* Article->unwatch() and Article->watch(), which were deprecated as of 1.18 and are no longer used in core, may be broken in scenarios where the Request does not have a 'token' but is making a call to $article->watch()
* Some extensions need to be fixed, I'm currently running a grep search and will fix them a.s.a.p
[1] http://www.mediawiki.org/wiki/ResourceLoader/Default_modules?mw.user#tokens
2011-06-06 00:09:03 +00:00
|
|
|
global $wgUser;
|
2011-06-06 00:12:45 +00:00
|
|
|
return WatchAction::doWatch( $this->mTitle, $wgUser );
|
2006-03-11 07:55:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* User interface handler for the "unwatch" action.
|
WatchAction requires token (BREAKING CHANGE)
* (bug 27655) Require token for watching/unwatching pages
* Previously done for API (bug 29070) in r88522
* As with markpatrolled, the tokens are not compatible and made that way on purpose. The API requires the POST method and uses a universal token per-session. Since the front-end is all GET based (also per convention like in markpatrolled and rollback) they are stronger salted (title / action specific)
* ajax.watch used the API already and was switched in r88554.
* The actual watching/unwatching code was moved from WatchAction->onView to WatchAction::doWatch. This was done to allow the API to do the action without needing to generate a token like the front-end needs (or having to duplicate code). It is now similar to RecentChange::markPatrolled (in that it also a "central" function that does not care about tokens, it's called after the token-handling)
* JavaScript / Gadgets that utilize action=watch in their scripts:
** Effects should be minimal as they should be using the API (see r88522 and wikitech-l)
** If they use index.php and scrap the link from the page, they can continue to do so.
* There are links to the watch action all over the place. I've tried to catch most of them, but there may be some I miss. Migration in most cases is just a matter of adding an array item to the $query for:
'token' => WatchAction::getWatchToken( $title, $user [, $action] )
or changing:
Action::factory( 'watch', $article )->execute();
to:
WatchAction::doWatch( $title, $user );
While replacing the usages in some cases an instance of Article() no longer had to be created, in others $wgUser had to be retrieved from global (which was implied before but needs to be given directly now)
Other notes:
* Article->unwatch() and Article->watch(), which were deprecated as of 1.18 and are no longer used in core, may be broken in scenarios where the Request does not have a 'token' but is making a call to $article->watch()
* Some extensions need to be fixed, I'm currently running a grep search and will fix them a.s.a.p
[1] http://www.mediawiki.org/wiki/ResourceLoader/Default_modules?mw.user#tokens
2011-06-06 00:09:03 +00:00
|
|
|
* Requires Request to pass a token as of 1.19.
|
2011-04-14 10:38:29 +00:00
|
|
|
* @deprecated since 1.18
|
2006-03-11 07:55:42 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function unwatch() {
|
2011-04-14 10:38:29 +00:00
|
|
|
Action::factory( 'unwatch', $this )->show();
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-03-11 07:55:42 +00:00
|
|
|
/**
|
|
|
|
|
* Stop watching a page
|
|
|
|
|
* @return bool true on successful unwatch
|
2011-04-14 10:38:29 +00:00
|
|
|
* @deprecated since 1.18
|
2006-03-11 07:55:42 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function doUnwatch() {
|
WatchAction requires token (BREAKING CHANGE)
* (bug 27655) Require token for watching/unwatching pages
* Previously done for API (bug 29070) in r88522
* As with markpatrolled, the tokens are not compatible and made that way on purpose. The API requires the POST method and uses a universal token per-session. Since the front-end is all GET based (also per convention like in markpatrolled and rollback) they are stronger salted (title / action specific)
* ajax.watch used the API already and was switched in r88554.
* The actual watching/unwatching code was moved from WatchAction->onView to WatchAction::doWatch. This was done to allow the API to do the action without needing to generate a token like the front-end needs (or having to duplicate code). It is now similar to RecentChange::markPatrolled (in that it also a "central" function that does not care about tokens, it's called after the token-handling)
* JavaScript / Gadgets that utilize action=watch in their scripts:
** Effects should be minimal as they should be using the API (see r88522 and wikitech-l)
** If they use index.php and scrap the link from the page, they can continue to do so.
* There are links to the watch action all over the place. I've tried to catch most of them, but there may be some I miss. Migration in most cases is just a matter of adding an array item to the $query for:
'token' => WatchAction::getWatchToken( $title, $user [, $action] )
or changing:
Action::factory( 'watch', $article )->execute();
to:
WatchAction::doWatch( $title, $user );
While replacing the usages in some cases an instance of Article() no longer had to be created, in others $wgUser had to be retrieved from global (which was implied before but needs to be given directly now)
Other notes:
* Article->unwatch() and Article->watch(), which were deprecated as of 1.18 and are no longer used in core, may be broken in scenarios where the Request does not have a 'token' but is making a call to $article->watch()
* Some extensions need to be fixed, I'm currently running a grep search and will fix them a.s.a.p
[1] http://www.mediawiki.org/wiki/ResourceLoader/Default_modules?mw.user#tokens
2011-06-06 00:09:03 +00:00
|
|
|
global $wgUser;
|
2011-06-06 00:12:45 +00:00
|
|
|
return WatchAction::doUnwatch( $this->mTitle, $wgUser );
|
2006-03-11 07:55:42 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2005-12-22 05:41:06 +00:00
|
|
|
* action=protect handler
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function protect() {
|
2005-12-22 05:41:06 +00:00
|
|
|
$form = new ProtectionForm( $this );
|
2007-01-22 20:59:00 +00:00
|
|
|
$form->execute();
|
2005-12-22 05:41:06 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-22 05:41:06 +00:00
|
|
|
/**
|
|
|
|
|
* action=unprotect handler (alias)
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function unprotect() {
|
2005-12-22 05:41:06 +00:00
|
|
|
$this->protect();
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-22 05:41:06 +00:00
|
|
|
/**
|
|
|
|
|
* Update the article's restriction field, and leave a log entry.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $limit Array: set of restriction keys
|
|
|
|
|
* @param $reason String
|
2008-12-10 22:39:41 +00:00
|
|
|
* @param &$cascade Integer. Set to false if cascading protection isn't allowed.
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $expiry Array: per restriction type expiration
|
2005-12-22 05:41:06 +00:00
|
|
|
* @return bool true on success
|
|
|
|
|
*/
|
2008-12-10 22:39:41 +00:00
|
|
|
public function updateRestrictions( $limit = array(), $reason = '', &$cascade = 0, $expiry = array() ) {
|
2009-11-06 10:27:44 +00:00
|
|
|
global $wgUser, $wgContLang;
|
2009-12-26 20:03:33 +00:00
|
|
|
|
2009-11-09 12:05:30 +00:00
|
|
|
$restrictionTypes = $this->mTitle->getRestrictionTypes();
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2003-09-01 08:30:14 +00:00
|
|
|
$id = $this->mTitle->getArticleID();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-03-03 02:56:30 +00:00
|
|
|
if ( $id <= 0 ) {
|
2010-12-05 05:14:41 +00:00
|
|
|
wfDebug( "updateRestrictions failed: article id $id <= 0\n" );
|
2009-03-03 02:56:30 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2009-03-03 02:56:30 +00:00
|
|
|
if ( wfReadOnly() ) {
|
|
|
|
|
wfDebug( "updateRestrictions failed: read-only\n" );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2009-03-03 16:30:02 +00:00
|
|
|
if ( !$this->mTitle->userCan( 'protect' ) ) {
|
2009-03-03 02:56:30 +00:00
|
|
|
wfDebug( "updateRestrictions failed: insufficient permissions\n" );
|
2005-12-22 05:41:06 +00:00
|
|
|
return false;
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2004-04-21 16:17:49 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$cascade ) {
|
2007-01-11 01:17:19 +00:00
|
|
|
$cascade = false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-22 08:26:41 +00:00
|
|
|
// Take this opportunity to purge out expired restrictions
|
|
|
|
|
Title::purgeExpiredRestrictions();
|
|
|
|
|
|
2011-05-17 22:03:20 +00:00
|
|
|
# @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
|
2006-04-08 20:50:08 +00:00
|
|
|
# we expect a single selection, but the schema allows otherwise.
|
|
|
|
|
$current = array();
|
2008-09-13 05:33:24 +00:00
|
|
|
$updated = Article::flattenRestrictions( $limit );
|
|
|
|
|
$changed = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $restrictionTypes as $action ) {
|
|
|
|
|
if ( isset( $expiry[$action] ) ) {
|
2008-12-12 04:55:11 +00:00
|
|
|
# Get current restrictions on $action
|
|
|
|
|
$aLimits = $this->mTitle->getRestrictions( $action );
|
|
|
|
|
$current[$action] = implode( '', $aLimits );
|
|
|
|
|
# Are any actual restrictions being dealt with here?
|
2010-02-14 22:07:30 +00:00
|
|
|
$aRChanged = count( $aLimits ) || !empty( $limit[$action] );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-12 04:55:11 +00:00
|
|
|
# If something changed, we need to log it. Checking $aRChanged
|
|
|
|
|
# assures that "unprotecting" a page that is not protected does
|
|
|
|
|
# not log just because the expiry was "changed".
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $aRChanged && $this->mTitle->mRestrictionsExpiry[$action] != $expiry[$action] ) {
|
2008-12-12 04:55:11 +00:00
|
|
|
$changed = true;
|
|
|
|
|
}
|
2008-12-10 22:39:41 +00:00
|
|
|
}
|
2008-09-13 05:33:24 +00:00
|
|
|
}
|
2004-11-28 00:20:37 +00:00
|
|
|
|
2006-04-08 20:50:08 +00:00
|
|
|
$current = Article::flattenRestrictions( $current );
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$changed = ( $changed || $current != $updated );
|
|
|
|
|
$changed = $changed || ( $updated && $this->mTitle->areRestrictionsCascading() != $cascade );
|
2006-04-08 20:50:08 +00:00
|
|
|
$protect = ( $updated != '' );
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-04-08 20:50:08 +00:00
|
|
|
# If nothing's changed, do nothing
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $changed ) {
|
|
|
|
|
if ( wfRunHooks( 'ArticleProtect', array( &$this, &$wgUser, $limit, $reason ) ) ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2006-04-08 21:13:11 +00:00
|
|
|
# Prepare a null revision to be added to the history
|
2007-06-13 11:08:57 +00:00
|
|
|
$modified = $current != '' && $protect;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $protect ) {
|
2007-06-13 11:08:57 +00:00
|
|
|
$comment_type = $modified ? 'modifiedarticleprotection' : 'protectedarticle';
|
|
|
|
|
} else {
|
|
|
|
|
$comment_type = 'unprotectedarticle';
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-06-13 11:08:57 +00:00
|
|
|
$comment = $wgContLang->ucfirst( wfMsgForContent( $comment_type, $this->mTitle->getPrefixedText() ) );
|
2007-01-23 10:51:33 +00:00
|
|
|
|
2008-06-21 03:17:35 +00:00
|
|
|
# Only restrictions with the 'protect' right can cascade...
|
2008-06-19 20:40:41 +00:00
|
|
|
# Otherwise, people who cannot normally protect can "protect" pages via transclusion
|
2008-12-11 21:37:48 +00:00
|
|
|
$editrestriction = isset( $limit['edit'] ) ? array( $limit['edit'] ) : $this->mTitle->getRestrictions( 'edit' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-11 21:37:48 +00:00
|
|
|
# The schema allows multiple restrictions
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( !in_array( 'protect', $editrestriction ) && !in_array( 'sysop', $editrestriction ) ) {
|
2008-12-11 21:37:48 +00:00
|
|
|
$cascade = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-18 02:50:16 +00:00
|
|
|
$cascade_description = '';
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $cascade ) {
|
|
|
|
|
$cascade_description = ' [' . wfMsgForContent( 'protect-summary-cascade' ) . ']';
|
2008-09-10 21:03:57 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( $reason ) {
|
2006-04-08 21:13:11 +00:00
|
|
|
$comment .= ": $reason";
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-09-10 21:03:57 +00:00
|
|
|
$editComment = $comment;
|
2008-09-13 05:33:24 +00:00
|
|
|
$encodedExpiry = array();
|
|
|
|
|
$protect_description = '';
|
2010-05-30 14:28:54 +00:00
|
|
|
foreach ( $limit as $action => $restrictions ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !isset( $expiry[$action] ) )
|
2011-03-18 22:28:39 +00:00
|
|
|
$expiry[$action] = $dbw->getInfinity();
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2011-03-18 19:15:56 +00:00
|
|
|
$encodedExpiry[$action] = $dbw->encodeExpiry( $expiry[$action] );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $restrictions != '' ) {
|
2008-09-13 05:33:24 +00:00
|
|
|
$protect_description .= "[$action=$restrictions] (";
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $encodedExpiry[$action] != 'infinity' ) {
|
2009-06-18 02:50:16 +00:00
|
|
|
$protect_description .= wfMsgForContent( 'protect-expiring',
|
2009-01-04 14:37:35 +00:00
|
|
|
$wgContLang->timeanddate( $expiry[$action], false, false ) ,
|
|
|
|
|
$wgContLang->date( $expiry[$action], false, false ) ,
|
2009-06-18 02:50:16 +00:00
|
|
|
$wgContLang->time( $expiry[$action], false, false ) );
|
2008-09-13 05:33:24 +00:00
|
|
|
} else {
|
|
|
|
|
$protect_description .= wfMsgForContent( 'protect-expiry-indefinite' );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-19 13:49:10 +00:00
|
|
|
$protect_description .= ') ';
|
2008-09-13 05:33:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
$protect_description = trim( $protect_description );
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( $protect_description && $protect ) {
|
2008-09-13 15:04:41 +00:00
|
|
|
$editComment .= " ($protect_description)";
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $cascade ) {
|
2008-09-10 21:03:57 +00:00
|
|
|
$editComment .= "$cascade_description";
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2007-01-10 23:32:38 +00:00
|
|
|
# Update restrictions table
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $limit as $action => $restrictions ) {
|
|
|
|
|
if ( $restrictions != '' ) {
|
|
|
|
|
$dbw->replace( 'page_restrictions', array( array( 'pr_page', 'pr_type' ) ),
|
2009-06-18 02:50:16 +00:00
|
|
|
array( 'pr_page' => $id,
|
|
|
|
|
'pr_type' => $action,
|
|
|
|
|
'pr_level' => $restrictions,
|
2010-02-14 22:07:30 +00:00
|
|
|
'pr_cascade' => ( $cascade && $action == 'edit' ) ? 1 : 0,
|
2010-05-30 14:28:54 +00:00
|
|
|
'pr_expiry' => $encodedExpiry[$action]
|
|
|
|
|
),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
2007-01-10 23:32:38 +00:00
|
|
|
} else {
|
|
|
|
|
$dbw->delete( 'page_restrictions', array( 'pr_page' => $id,
|
|
|
|
|
'pr_type' => $action ), __METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-01-21 15:04:49 +00:00
|
|
|
|
|
|
|
|
# Insert a null revision
|
2008-09-10 21:03:57 +00:00
|
|
|
$nullRevision = Revision::newNullRevision( $dbw, $id, $editComment, true );
|
2008-01-21 15:04:49 +00:00
|
|
|
$nullRevId = $nullRevision->insertOn( $dbw );
|
2007-01-12 01:44:33 +00:00
|
|
|
|
2008-07-27 19:24:35 +00:00
|
|
|
$latest = $this->getLatest();
|
2007-01-14 12:03:56 +00:00
|
|
|
# Update page record
|
|
|
|
|
$dbw->update( 'page',
|
|
|
|
|
array( /* SET */
|
|
|
|
|
'page_touched' => $dbw->timestamp(),
|
|
|
|
|
'page_restrictions' => '',
|
|
|
|
|
'page_latest' => $nullRevId
|
|
|
|
|
), array( /* WHERE */
|
|
|
|
|
'page_id' => $id
|
2008-06-21 03:17:35 +00:00
|
|
|
), 'Article::protect'
|
2007-01-14 12:03:56 +00:00
|
|
|
);
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $wgUser ) );
|
2006-04-08 20:50:08 +00:00
|
|
|
wfRunHooks( 'ArticleProtectComplete', array( &$this, &$wgUser, $limit, $reason ) );
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-04-08 20:50:08 +00:00
|
|
|
# Update the protection log
|
|
|
|
|
$log = new LogPage( 'protect' );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $protect ) {
|
|
|
|
|
$params = array( $protect_description, $cascade ? 'cascade' : '' );
|
|
|
|
|
$log->addEntry( $modified ? 'modify' : 'protect', $this->mTitle, trim( $reason ), $params );
|
2006-04-08 20:50:08 +00:00
|
|
|
} else {
|
|
|
|
|
$log->addEntry( 'unprotect', $this->mTitle, $reason );
|
|
|
|
|
}
|
|
|
|
|
} # End hook
|
|
|
|
|
} # End "changed" check
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2005-12-22 05:41:06 +00:00
|
|
|
return true;
|
2004-04-21 16:17:49 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2005-12-22 05:41:06 +00:00
|
|
|
* Take an array of page restrictions and flatten it to a string
|
|
|
|
|
* suitable for insertion into the page_restrictions field.
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $limit Array
|
|
|
|
|
* @return String
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
protected static function flattenRestrictions( $limit ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !is_array( $limit ) ) {
|
2006-06-07 06:40:24 +00:00
|
|
|
throw new MWException( 'Article::flattenRestrictions given non-array restriction set' );
|
2005-12-22 05:41:06 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-22 05:41:06 +00:00
|
|
|
$bits = array();
|
2006-04-08 20:50:08 +00:00
|
|
|
ksort( $limit );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $limit as $action => $restrictions ) {
|
|
|
|
|
if ( $restrictions != '' ) {
|
2005-12-22 05:41:06 +00:00
|
|
|
$bits[] = "$action=$restrictions";
|
|
|
|
|
}
|
2005-12-15 21:25:52 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-22 05:41:06 +00:00
|
|
|
return implode( ':', $bits );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-11-07 19:06:15 +00:00
|
|
|
/**
|
|
|
|
|
* Auto-generates a deletion reason
|
2010-05-30 14:28:54 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param &$hasHistory Boolean: whether the page has a history
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return mixed String containing deletion reason or empty string, or boolean false
|
|
|
|
|
* if no revision occurred
|
2007-11-07 19:06:15 +00:00
|
|
|
*/
|
2008-09-21 02:53:16 +00:00
|
|
|
public function generateReason( &$hasHistory ) {
|
2011-04-13 23:36:27 +00:00
|
|
|
global $wgContLang;
|
|
|
|
|
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
// Get the last revision
|
|
|
|
|
$rev = Revision::newFromTitle( $this->mTitle );
|
|
|
|
|
|
|
|
|
|
if ( is_null( $rev ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the article's contents
|
|
|
|
|
$contents = $rev->getText();
|
|
|
|
|
$blank = false;
|
|
|
|
|
|
|
|
|
|
// If the page is blank, use the text from the previous revision,
|
|
|
|
|
// which can only be blank if there's a move/import/protect dummy revision involved
|
|
|
|
|
if ( $contents == '' ) {
|
|
|
|
|
$prev = $rev->getPrevious();
|
|
|
|
|
|
|
|
|
|
if ( $prev ) {
|
|
|
|
|
$contents = $prev->getText();
|
|
|
|
|
$blank = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find out if there was only one contributor
|
|
|
|
|
// Only scan the last 20 revisions
|
|
|
|
|
$res = $dbw->select( 'revision', 'rev_user_text',
|
|
|
|
|
array( 'rev_page' => $this->getID(), $dbw->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' ),
|
|
|
|
|
__METHOD__,
|
|
|
|
|
array( 'LIMIT' => 20 )
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ( $res === false ) {
|
|
|
|
|
// This page has no revisions, which is very weird
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$hasHistory = ( $res->numRows() > 1 );
|
|
|
|
|
$row = $dbw->fetchObject( $res );
|
|
|
|
|
|
|
|
|
|
if ( $row ) { // $row is false if the only contributor is hidden
|
|
|
|
|
$onlyAuthor = $row->rev_user_text;
|
|
|
|
|
// Try to find a second contributor
|
|
|
|
|
foreach ( $res as $row ) {
|
|
|
|
|
if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999
|
|
|
|
|
$onlyAuthor = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$onlyAuthor = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate the summary with a '$1' placeholder
|
|
|
|
|
if ( $blank ) {
|
|
|
|
|
// The current revision is blank and the one before is also
|
|
|
|
|
// blank. It's just not our lucky day
|
|
|
|
|
$reason = wfMsgForContent( 'exbeforeblank', '$1' );
|
|
|
|
|
} else {
|
|
|
|
|
if ( $onlyAuthor ) {
|
|
|
|
|
$reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor );
|
|
|
|
|
} else {
|
|
|
|
|
$reason = wfMsgForContent( 'excontent', '$1' );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $reason == '-' ) {
|
|
|
|
|
// Allow these UI messages to be blanked out cleanly
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Replace newlines with spaces to prevent uglyness
|
|
|
|
|
$contents = preg_replace( "/[\n\r]/", ' ', $contents );
|
|
|
|
|
// Calculate the maximum amount of chars to get
|
|
|
|
|
// Max content length = max comment length - length of the comment (excl. $1)
|
|
|
|
|
$maxLength = 255 - ( strlen( $reason ) - 2 );
|
|
|
|
|
$contents = $wgContLang->truncate( $contents, $maxLength );
|
|
|
|
|
// Remove possible unfinished links
|
|
|
|
|
$contents = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $contents );
|
|
|
|
|
// Now replace the '$1' placeholder
|
|
|
|
|
$reason = str_replace( '$1', $contents, $reason );
|
|
|
|
|
|
|
|
|
|
return $reason;
|
2007-11-07 19:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2011-05-21 19:35:16 +00:00
|
|
|
/**
|
2004-09-02 23:28:24 +00:00
|
|
|
* UI entry point for page deletion
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function delete() {
|
2011-04-13 23:36:27 +00:00
|
|
|
global $wgOut, $wgRequest;
|
|
|
|
|
|
|
|
|
|
$confirm = $wgRequest->wasPosted() &&
|
|
|
|
|
$wgOut->getUser()->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
|
|
|
|
|
|
|
|
|
|
$this->DeleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' );
|
|
|
|
|
$this->DeleteReason = $wgRequest->getText( 'wpReason' );
|
|
|
|
|
|
|
|
|
|
$reason = $this->DeleteReasonList;
|
|
|
|
|
|
|
|
|
|
if ( $reason != 'other' && $this->DeleteReason != '' ) {
|
|
|
|
|
// Entry from drop down menu + additional comment
|
|
|
|
|
$reason .= wfMsgForContent( 'colon-separator' ) . $this->DeleteReason;
|
|
|
|
|
} elseif ( $reason == 'other' ) {
|
|
|
|
|
$reason = $this->DeleteReason;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Flag to hide all contents of the archived revisions
|
|
|
|
|
$suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgOut->getUser()->isAllowed( 'suppressrevision' );
|
|
|
|
|
|
|
|
|
|
# This code desperately needs to be totally rewritten
|
|
|
|
|
|
|
|
|
|
# Read-only check...
|
|
|
|
|
if ( wfReadOnly() ) {
|
|
|
|
|
$wgOut->readOnlyPage();
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check permissions
|
|
|
|
|
$permission_errors = $this->mTitle->getUserPermissionsErrors( 'delete', $wgOut->getUser() );
|
|
|
|
|
|
|
|
|
|
if ( count( $permission_errors ) > 0 ) {
|
|
|
|
|
$wgOut->showPermissionsErrorPage( $permission_errors );
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wgOut->setPagetitle( wfMsg( 'delete-confirm', $this->mTitle->getPrefixedText() ) );
|
|
|
|
|
|
|
|
|
|
# Better double-check that it hasn't been deleted yet!
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
$conds = $this->mTitle->pageCond();
|
|
|
|
|
$latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
|
|
|
|
|
if ( $latest === false ) {
|
|
|
|
|
$wgOut->showFatalError(
|
|
|
|
|
Html::rawElement(
|
|
|
|
|
'div',
|
|
|
|
|
array( 'class' => 'error mw-error-cannotdelete' ),
|
|
|
|
|
wfMsgExt( 'cannotdelete', array( 'parse' ), $this->mTitle->getPrefixedText() )
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
$wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
|
|
|
|
|
LogEventsList::showLogExtract(
|
|
|
|
|
$wgOut,
|
|
|
|
|
'delete',
|
|
|
|
|
$this->mTitle->getPrefixedText()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Hack for big sites
|
|
|
|
|
$bigHistory = $this->isBigDeletion();
|
|
|
|
|
if ( $bigHistory && !$this->mTitle->userCan( 'bigdelete' ) ) {
|
|
|
|
|
global $wgLang, $wgDeleteRevisionsLimit;
|
|
|
|
|
|
|
|
|
|
$wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
|
|
|
|
|
array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $confirm ) {
|
|
|
|
|
$this->doDelete( $reason, $suppress );
|
|
|
|
|
|
|
|
|
|
if ( $wgRequest->getCheck( 'wpWatch' ) && $wgOut->getUser()->isLoggedIn() ) {
|
|
|
|
|
$this->doWatch();
|
|
|
|
|
} elseif ( $this->mTitle->userIsWatching() ) {
|
|
|
|
|
$this->doUnwatch();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate deletion reason
|
|
|
|
|
$hasHistory = false;
|
|
|
|
|
if ( !$reason ) {
|
|
|
|
|
$reason = $this->generateReason( $hasHistory );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the page has a history, insert a warning
|
|
|
|
|
if ( $hasHistory && !$confirm ) {
|
|
|
|
|
global $wgLang;
|
|
|
|
|
|
|
|
|
|
$revisions = $this->estimateRevisionCount();
|
2011-05-17 22:03:20 +00:00
|
|
|
// @todo FIXME: i18n issue/patchwork message
|
2011-04-13 23:36:27 +00:00
|
|
|
$wgOut->addHTML( '<strong class="mw-delete-warning-revisions">' .
|
|
|
|
|
wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) .
|
2011-04-25 11:59:31 +00:00
|
|
|
wfMsgHtml( 'word-separator' ) . Linker::link( $this->mTitle,
|
2011-04-13 23:36:27 +00:00
|
|
|
wfMsgHtml( 'history' ),
|
|
|
|
|
array( 'rel' => 'archives' ),
|
|
|
|
|
array( 'action' => 'history' ) ) .
|
|
|
|
|
'</strong>'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ( $bigHistory ) {
|
|
|
|
|
global $wgDeleteRevisionsLimit;
|
|
|
|
|
$wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
|
|
|
|
|
array( 'delete-warning-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->confirmDelete( $reason );
|
2003-09-01 09:59:53 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-01-16 23:08:19 +00:00
|
|
|
/**
|
|
|
|
|
* @return bool whether or not the page surpasses $wgDeleteRevisionsLimit revisions
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function isBigDeletion() {
|
2008-01-16 23:08:19 +00:00
|
|
|
global $wgDeleteRevisionsLimit;
|
2011-04-13 23:36:27 +00:00
|
|
|
|
|
|
|
|
if ( $wgDeleteRevisionsLimit ) {
|
|
|
|
|
$revCount = $this->estimateRevisionCount();
|
|
|
|
|
|
|
|
|
|
return $revCount > $wgDeleteRevisionsLimit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2008-01-16 23:08:19 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-01-16 23:08:19 +00:00
|
|
|
/**
|
|
|
|
|
* @return int approximate revision count
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function estimateRevisionCount() {
|
2008-09-21 08:44:20 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-16 23:08:19 +00:00
|
|
|
// For an exact count...
|
2010-02-14 22:07:30 +00:00
|
|
|
// return $dbr->selectField( 'revision', 'COUNT(*)',
|
2008-01-16 23:08:19 +00:00
|
|
|
// array( 'rev_page' => $this->getId() ), __METHOD__ );
|
|
|
|
|
return $dbr->estimateRowCount( 'revision', '*',
|
2009-12-26 20:03:33 +00:00
|
|
|
array( 'rev_page' => $this->getId() ), __METHOD__ );
|
2008-01-16 23:08:19 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2006-01-08 01:25:50 +00:00
|
|
|
/**
|
2006-03-11 17:13:49 +00:00
|
|
|
* Get the last N authors
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $num Integer: number of revisions to get
|
|
|
|
|
* @param $revLatest String: the latest rev_id, selected from the master (optional)
|
2006-01-08 01:25:50 +00:00
|
|
|
* @return array Array of authors, duplicates not removed
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getLastNAuthors( $num, $revLatest = 0 ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-01-08 01:25:50 +00:00
|
|
|
// First try the slave
|
|
|
|
|
// If that doesn't have the latest revision, try the master
|
|
|
|
|
$continue = 2;
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_SLAVE );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-01-08 01:25:50 +00:00
|
|
|
do {
|
|
|
|
|
$res = $db->select( array( 'page', 'revision' ),
|
|
|
|
|
array( 'rev_id', 'rev_user_text' ),
|
|
|
|
|
array(
|
|
|
|
|
'page_namespace' => $this->mTitle->getNamespace(),
|
|
|
|
|
'page_title' => $this->mTitle->getDBkey(),
|
|
|
|
|
'rev_page = page_id'
|
2011-04-13 00:50:44 +00:00
|
|
|
), __METHOD__,
|
|
|
|
|
array(
|
2006-01-08 01:25:50 +00:00
|
|
|
'ORDER BY' => 'rev_timestamp DESC',
|
|
|
|
|
'LIMIT' => $num
|
2011-04-13 00:50:44 +00:00
|
|
|
)
|
2006-01-08 01:25:50 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$res ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-01-08 01:25:50 +00:00
|
|
|
return array();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-01-08 01:25:50 +00:00
|
|
|
$row = $db->fetchObject( $res );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $continue == 2 && $revLatest && $row->rev_id != $revLatest ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_MASTER );
|
2006-01-08 01:25:50 +00:00
|
|
|
$continue--;
|
|
|
|
|
} else {
|
|
|
|
|
$continue = 0;
|
|
|
|
|
}
|
|
|
|
|
} while ( $continue );
|
|
|
|
|
|
|
|
|
|
$authors = array( $row->rev_user_text );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-10-13 23:11:40 +00:00
|
|
|
foreach ( $res as $row ) {
|
2006-01-08 01:25:50 +00:00
|
|
|
$authors[] = $row->rev_user_text;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-01-08 01:25:50 +00:00
|
|
|
return $authors;
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2011-04-13 23:36:27 +00:00
|
|
|
/**
|
|
|
|
|
* Output deletion confirmation dialog
|
2011-05-17 22:03:20 +00:00
|
|
|
* @todo FIXME: Move to another file?
|
2011-04-13 23:36:27 +00:00
|
|
|
* @param $reason String: prefilled reason
|
|
|
|
|
*/
|
|
|
|
|
public function confirmDelete( $reason ) {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
wfDebug( "Article::confirmDelete\n" );
|
|
|
|
|
|
2011-04-25 11:59:31 +00:00
|
|
|
$deleteBackLink = Linker::linkKnown( $this->mTitle );
|
2011-04-13 23:36:27 +00:00
|
|
|
$wgOut->setSubtitle( wfMsgHtml( 'delete-backlink', $deleteBackLink ) );
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
|
|
|
|
$wgOut->addWikiMsg( 'confirmdeletetext' );
|
|
|
|
|
|
|
|
|
|
wfRunHooks( 'ArticleConfirmDelete', array( $this, $wgOut, &$reason ) );
|
|
|
|
|
|
|
|
|
|
if ( $wgOut->getUser()->isAllowed( 'suppressrevision' ) ) {
|
|
|
|
|
$suppress = "<tr id=\"wpDeleteSuppressRow\">
|
|
|
|
|
<td></td>
|
|
|
|
|
<td class='mw-input'><strong>" .
|
|
|
|
|
Xml::checkLabel( wfMsg( 'revdelete-suppress' ),
|
|
|
|
|
'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) .
|
|
|
|
|
"</strong></td>
|
|
|
|
|
</tr>";
|
|
|
|
|
} else {
|
|
|
|
|
$suppress = '';
|
|
|
|
|
}
|
|
|
|
|
$checkWatch = $wgOut->getUser()->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching();
|
|
|
|
|
|
|
|
|
|
$form = Xml::openElement( 'form', array( 'method' => 'post',
|
|
|
|
|
'action' => $this->mTitle->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ) ) .
|
|
|
|
|
Xml::openElement( 'fieldset', array( 'id' => 'mw-delete-table' ) ) .
|
|
|
|
|
Xml::tags( 'legend', null, wfMsgExt( 'delete-legend', array( 'parsemag', 'escapenoentities' ) ) ) .
|
|
|
|
|
Xml::openElement( 'table', array( 'id' => 'mw-deleteconfirm-table' ) ) .
|
|
|
|
|
"<tr id=\"wpDeleteReasonListRow\">
|
|
|
|
|
<td class='mw-label'>" .
|
|
|
|
|
Xml::label( wfMsg( 'deletecomment' ), 'wpDeleteReasonList' ) .
|
|
|
|
|
"</td>
|
|
|
|
|
<td class='mw-input'>" .
|
|
|
|
|
Xml::listDropDown( 'wpDeleteReasonList',
|
|
|
|
|
wfMsgForContent( 'deletereason-dropdown' ),
|
|
|
|
|
wfMsgForContent( 'deletereasonotherlist' ), '', 'wpReasonDropDown', 1 ) .
|
|
|
|
|
"</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr id=\"wpDeleteReasonRow\">
|
|
|
|
|
<td class='mw-label'>" .
|
|
|
|
|
Xml::label( wfMsg( 'deleteotherreason' ), 'wpReason' ) .
|
|
|
|
|
"</td>
|
|
|
|
|
<td class='mw-input'>" .
|
|
|
|
|
Html::input( 'wpReason', $reason, 'text', array(
|
|
|
|
|
'size' => '60',
|
|
|
|
|
'maxlength' => '255',
|
|
|
|
|
'tabindex' => '2',
|
|
|
|
|
'id' => 'wpReason',
|
|
|
|
|
'autofocus'
|
|
|
|
|
) ) .
|
|
|
|
|
"</td>
|
|
|
|
|
</tr>";
|
|
|
|
|
|
|
|
|
|
# Disallow watching if user is not logged in
|
|
|
|
|
if ( $wgOut->getUser()->isLoggedIn() ) {
|
|
|
|
|
$form .= "
|
|
|
|
|
<tr>
|
|
|
|
|
<td></td>
|
|
|
|
|
<td class='mw-input'>" .
|
|
|
|
|
Xml::checkLabel( wfMsg( 'watchthis' ),
|
|
|
|
|
'wpWatch', 'wpWatch', $checkWatch, array( 'tabindex' => '3' ) ) .
|
|
|
|
|
"</td>
|
|
|
|
|
</tr>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form .= "
|
|
|
|
|
$suppress
|
|
|
|
|
<tr>
|
|
|
|
|
<td></td>
|
|
|
|
|
<td class='mw-submit'>" .
|
|
|
|
|
Xml::submitButton( wfMsg( 'deletepage' ),
|
|
|
|
|
array( 'name' => 'wpConfirmB', 'id' => 'wpConfirmB', 'tabindex' => '5' ) ) .
|
|
|
|
|
"</td>
|
|
|
|
|
</tr>" .
|
|
|
|
|
Xml::closeElement( 'table' ) .
|
|
|
|
|
Xml::closeElement( 'fieldset' ) .
|
|
|
|
|
Html::hidden( 'wpEditToken', $wgOut->getUser()->editToken() ) .
|
|
|
|
|
Xml::closeElement( 'form' );
|
|
|
|
|
|
|
|
|
|
if ( $wgOut->getUser()->isAllowed( 'editinterface' ) ) {
|
|
|
|
|
$title = Title::makeTitle( NS_MEDIAWIKI, 'Deletereason-dropdown' );
|
2011-04-25 11:59:31 +00:00
|
|
|
$link = Linker::link(
|
2011-04-13 23:36:27 +00:00
|
|
|
$title,
|
|
|
|
|
wfMsgHtml( 'delete-edit-reasonlist' ),
|
|
|
|
|
array(),
|
|
|
|
|
array( 'action' => 'edit' )
|
|
|
|
|
);
|
|
|
|
|
$form .= '<p class="mw-delete-editreasons">' . $link . '</p>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wgOut->addHTML( $form );
|
|
|
|
|
$wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
|
|
|
|
|
LogEventsList::showLogExtract( $wgOut, 'delete',
|
|
|
|
|
$this->mTitle->getPrefixedText()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Perform a deletion and output success or failure messages
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function doDelete( $reason, $suppress = false ) {
|
2011-04-13 23:36:27 +00:00
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
$id = $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
|
|
|
|
|
|
|
|
|
|
$error = '';
|
|
|
|
|
if ( $this->doDeleteArticle( $reason, $suppress, $id, $error ) ) {
|
|
|
|
|
$deleted = $this->mTitle->getPrefixedText();
|
|
|
|
|
|
|
|
|
|
$wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
|
|
|
|
|
|
|
|
|
$loglink = '[[Special:Log/delete|' . wfMsgNoTrans( 'deletionlog' ) . ']]';
|
|
|
|
|
|
|
|
|
|
$wgOut->addWikiMsg( 'deletedtext', $deleted, $loglink );
|
|
|
|
|
$wgOut->returnToMain( false );
|
|
|
|
|
} else {
|
|
|
|
|
if ( $error == '' ) {
|
|
|
|
|
$wgOut->showFatalError(
|
|
|
|
|
Html::rawElement(
|
|
|
|
|
'div',
|
|
|
|
|
array( 'class' => 'error mw-error-cannotdelete' ),
|
|
|
|
|
wfMsgExt( 'cannotdelete', array( 'parse' ), $this->mTitle->getPrefixedText() )
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
|
|
|
|
|
|
|
|
|
|
LogEventsList::showLogExtract(
|
|
|
|
|
$wgOut,
|
|
|
|
|
'delete',
|
|
|
|
|
$this->mTitle->getPrefixedText()
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
$wgOut->showFatalError( $error );
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Back-end article deletion
|
|
|
|
|
* Deletes the article with database consistency, writes logs, purges caches
|
2010-03-15 12:04:24 +00:00
|
|
|
*
|
|
|
|
|
* @param $reason string delete reason for deletion log
|
|
|
|
|
* @param suppress bitfield
|
|
|
|
|
* Revision::DELETED_TEXT
|
|
|
|
|
* Revision::DELETED_COMMENT
|
|
|
|
|
* Revision::DELETED_USER
|
|
|
|
|
* Revision::DELETED_RESTRICTED
|
|
|
|
|
* @param $id int article ID
|
|
|
|
|
* @param $commit boolean defaults to true, triggers transaction end
|
|
|
|
|
* @return boolean true if successful
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2011-03-24 21:32:08 +00:00
|
|
|
public function doDeleteArticle( $reason, $suppress = false, $id = 0, $commit = true, &$error = '' ) {
|
2011-04-13 23:36:27 +00:00
|
|
|
global $wgDeferredUpdateList, $wgUseTrackbacks;
|
|
|
|
|
global $wgUser;
|
|
|
|
|
|
|
|
|
|
wfDebug( __METHOD__ . "\n" );
|
|
|
|
|
|
|
|
|
|
if ( ! wfRunHooks( 'ArticleDelete', array( &$this, &$wgUser, &$reason, &$error ) ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
$t = $this->mTitle->getDBkey();
|
|
|
|
|
$id = $id ? $id : $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
|
|
|
|
|
|
|
|
|
|
if ( $t === '' || $id == 0 ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-14 17:11:32 +00:00
|
|
|
$u = new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 );
|
2011-04-13 23:36:27 +00:00
|
|
|
array_push( $wgDeferredUpdateList, $u );
|
|
|
|
|
|
|
|
|
|
// Bitfields to further suppress the content
|
|
|
|
|
if ( $suppress ) {
|
|
|
|
|
$bitfield = 0;
|
|
|
|
|
// This should be 15...
|
|
|
|
|
$bitfield |= Revision::DELETED_TEXT;
|
|
|
|
|
$bitfield |= Revision::DELETED_COMMENT;
|
|
|
|
|
$bitfield |= Revision::DELETED_USER;
|
|
|
|
|
$bitfield |= Revision::DELETED_RESTRICTED;
|
|
|
|
|
} else {
|
|
|
|
|
$bitfield = 'rev_deleted';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dbw->begin();
|
|
|
|
|
// For now, shunt the revision data into the archive table.
|
|
|
|
|
// Text is *not* removed from the text table; bulk storage
|
|
|
|
|
// is left intact to avoid breaking block-compression or
|
|
|
|
|
// immutable storage schemes.
|
|
|
|
|
//
|
|
|
|
|
// For backwards compatibility, note that some older archive
|
|
|
|
|
// table entries will have ar_text and ar_flags fields still.
|
|
|
|
|
//
|
|
|
|
|
// In the future, we may keep revisions and mark them with
|
|
|
|
|
// the rev_deleted field, which is reserved for this purpose.
|
|
|
|
|
$dbw->insertSelect( 'archive', array( 'page', 'revision' ),
|
2004-07-10 03:09:26 +00:00
|
|
|
array(
|
2011-04-13 23:36:27 +00:00
|
|
|
'ar_namespace' => 'page_namespace',
|
|
|
|
|
'ar_title' => 'page_title',
|
|
|
|
|
'ar_comment' => 'rev_comment',
|
|
|
|
|
'ar_user' => 'rev_user',
|
|
|
|
|
'ar_user_text' => 'rev_user_text',
|
|
|
|
|
'ar_timestamp' => 'rev_timestamp',
|
|
|
|
|
'ar_minor_edit' => 'rev_minor_edit',
|
|
|
|
|
'ar_rev_id' => 'rev_id',
|
|
|
|
|
'ar_text_id' => 'rev_text_id',
|
|
|
|
|
'ar_text' => '\'\'', // Be explicit to appease
|
|
|
|
|
'ar_flags' => '\'\'', // MySQL's "strict mode"...
|
|
|
|
|
'ar_len' => 'rev_len',
|
|
|
|
|
'ar_page_id' => 'page_id',
|
|
|
|
|
'ar_deleted' => $bitfield
|
|
|
|
|
), array(
|
|
|
|
|
'page_id' => $id,
|
|
|
|
|
'page_id = rev_page'
|
|
|
|
|
), __METHOD__
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
2011-04-13 23:36:27 +00:00
|
|
|
|
|
|
|
|
# Delete restrictions for it
|
|
|
|
|
$dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
|
|
|
|
|
|
|
|
|
|
# Now that it's safely backed up, delete it
|
|
|
|
|
$dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__ );
|
|
|
|
|
$ok = ( $dbw->affectedRows() > 0 ); // getArticleId() uses slave, could be laggy
|
|
|
|
|
|
|
|
|
|
if ( !$ok ) {
|
|
|
|
|
$dbw->rollback();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Fix category table counts
|
|
|
|
|
$cats = array();
|
|
|
|
|
$res = $dbw->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
|
|
|
|
|
|
|
|
|
|
foreach ( $res as $row ) {
|
|
|
|
|
$cats [] = $row->cl_to;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->updateCategoryCounts( array(), $cats );
|
|
|
|
|
|
|
|
|
|
# If using cascading deletes, we can skip some explicit deletes
|
|
|
|
|
if ( !$dbw->cascadingDeletes() ) {
|
|
|
|
|
$dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
|
|
|
|
|
|
|
|
|
|
if ( $wgUseTrackbacks )
|
|
|
|
|
$dbw->delete( 'trackbacks', array( 'tb_page' => $id ), __METHOD__ );
|
|
|
|
|
|
|
|
|
|
# Delete outgoing links
|
|
|
|
|
$dbw->delete( 'pagelinks', array( 'pl_from' => $id ) );
|
|
|
|
|
$dbw->delete( 'imagelinks', array( 'il_from' => $id ) );
|
|
|
|
|
$dbw->delete( 'categorylinks', array( 'cl_from' => $id ) );
|
|
|
|
|
$dbw->delete( 'templatelinks', array( 'tl_from' => $id ) );
|
|
|
|
|
$dbw->delete( 'externallinks', array( 'el_from' => $id ) );
|
|
|
|
|
$dbw->delete( 'langlinks', array( 'll_from' => $id ) );
|
2011-04-16 07:46:47 +00:00
|
|
|
$dbw->delete( 'iwlinks', array( 'iwl_from' => $id ) );
|
2011-04-13 23:36:27 +00:00
|
|
|
$dbw->delete( 'redirect', array( 'rd_from' => $id ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# If using cleanup triggers, we can skip some manual deletes
|
|
|
|
|
if ( !$dbw->cleanupTriggers() ) {
|
|
|
|
|
# Clean up recentchanges entries...
|
|
|
|
|
$dbw->delete( 'recentchanges',
|
|
|
|
|
array( 'rc_type != ' . RC_LOG,
|
|
|
|
|
'rc_namespace' => $this->mTitle->getNamespace(),
|
|
|
|
|
'rc_title' => $this->mTitle->getDBkey() ),
|
|
|
|
|
__METHOD__ );
|
|
|
|
|
$dbw->delete( 'recentchanges',
|
|
|
|
|
array( 'rc_type != ' . RC_LOG, 'rc_cur_id' => $id ),
|
|
|
|
|
__METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Clear caches
|
|
|
|
|
Article::onArticleDelete( $this->mTitle );
|
|
|
|
|
|
|
|
|
|
# Clear the cached article id so the interface doesn't act like we exist
|
|
|
|
|
$this->mTitle->resetArticleID( 0 );
|
|
|
|
|
|
|
|
|
|
# Log the deletion, if the page was suppressed, log it at Oversight instead
|
|
|
|
|
$logtype = $suppress ? 'suppress' : 'delete';
|
|
|
|
|
$log = new LogPage( $logtype );
|
|
|
|
|
|
|
|
|
|
# Make sure logging got through
|
|
|
|
|
$log->addEntry( 'delete', $this->mTitle, $reason, array() );
|
|
|
|
|
|
|
|
|
|
if ( $commit ) {
|
|
|
|
|
$dbw->commit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$wgUser, $reason, $id ) );
|
|
|
|
|
return true;
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2007-07-09 08:12:44 +00:00
|
|
|
/**
|
2008-01-14 20:17:05 +00:00
|
|
|
* Roll back the most recent consecutive set of edits to a page
|
|
|
|
|
* from the same user; fails if there are no eligible edits to
|
2008-01-15 17:31:07 +00:00
|
|
|
* roll back to, e.g. user is the sole contributor. This function
|
|
|
|
|
* performs permissions checks on $wgUser, then calls commitRollback()
|
|
|
|
|
* to do the dirty work
|
2007-07-09 08:12:44 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $fromP String: Name of the user whose edits to rollback.
|
|
|
|
|
* @param $summary String: Custom summary. Set to default summary if empty.
|
|
|
|
|
* @param $token String: Rollback token.
|
|
|
|
|
* @param $bot Boolean: If true, mark all reverted edits as bot.
|
2008-04-14 07:45:50 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $resultDetails Array: contains result-specific array of additional values
|
2008-01-15 17:31:07 +00:00
|
|
|
* 'alreadyrolled' : 'current' (rev)
|
|
|
|
|
* success : 'summary' (str), 'current' (rev), 'target' (rev)
|
2008-04-14 07:45:50 +00:00
|
|
|
*
|
2008-01-16 00:06:42 +00:00
|
|
|
* @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
|
2008-01-18 15:52:40 +00:00
|
|
|
* OutputPage::showPermissionsErrorPage().
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2007-07-09 08:12:44 +00:00
|
|
|
public function doRollback( $fromP, $summary, $token, $bot, &$resultDetails ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
global $wgUser;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-07-07 07:32:34 +00:00
|
|
|
$resultDetails = null;
|
2007-09-10 07:48:20 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
# Check permissions
|
2008-12-06 21:16:55 +00:00
|
|
|
$editErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser );
|
|
|
|
|
$rollbackErrors = $this->mTitle->getUserPermissionsErrors( 'rollback', $wgUser );
|
|
|
|
|
$errors = array_merge( $editErrors, wfArrayDiff2( $rollbackErrors, $editErrors ) );
|
|
|
|
|
|
2010-12-20 19:03:00 +00:00
|
|
|
if ( !$wgUser->matchEditToken( $token, array( $this->mTitle->getPrefixedText(), $fromP ) ) ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
$errors[] = array( 'sessionfailure' );
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2007-06-29 20:02:26 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgUser->pingLimiter( 'rollback' ) || $wgUser->pingLimiter() ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
$errors[] = array( 'actionthrottledtext' );
|
2007-11-20 08:34:59 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
# If there were errors, bail out now
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( !empty( $errors ) ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
return $errors;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
return $this->commitRollback( $fromP, $summary, $bot, $resultDetails );
|
2008-01-15 17:31:07 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
/**
|
2008-01-16 00:06:42 +00:00
|
|
|
* Backend implementation of doRollback(), please refer there for parameter
|
|
|
|
|
* and return value documentation
|
2008-01-15 17:31:07 +00:00
|
|
|
*
|
2008-01-16 00:06:42 +00:00
|
|
|
* 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.
|
2008-04-14 07:45:50 +00:00
|
|
|
*/
|
2010-02-14 22:07:30 +00:00
|
|
|
public function commitRollback( $fromP, $summary, $bot, &$resultDetails ) {
|
2008-05-03 16:07:57 +00:00
|
|
|
global $wgUseRCPatrol, $wgUser, $wgLang;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-07-09 08:12:44 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2007-06-29 20:02:26 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( wfReadOnly() ) {
|
2008-01-16 00:06:42 +00:00
|
|
|
return array( array( 'readonlytext' ) );
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-29 20:02:26 +00:00
|
|
|
# Get the last editor
|
|
|
|
|
$current = Revision::newFromTitle( $this->mTitle );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_null( $current ) ) {
|
2007-06-29 20:02:26 +00:00
|
|
|
# Something wrong... no page?
|
2010-02-14 22:07:30 +00:00
|
|
|
return array( array( 'notanarticle' ) );
|
2007-06-29 20:02:26 +00:00
|
|
|
}
|
|
|
|
|
|
2007-07-07 07:32:34 +00:00
|
|
|
$from = str_replace( '_', ' ', $fromP );
|
2009-09-02 22:16:24 +00:00
|
|
|
# User name given should match up with the top revision.
|
|
|
|
|
# If the user was deleted then $from should be empty.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $from != $current->getUserText() ) {
|
2007-07-09 08:12:44 +00:00
|
|
|
$resultDetails = array( 'current' => $current );
|
2010-02-14 22:07:30 +00:00
|
|
|
return array( array( 'alreadyrolled',
|
|
|
|
|
htmlspecialchars( $this->mTitle->getPrefixedText() ),
|
|
|
|
|
htmlspecialchars( $fromP ),
|
|
|
|
|
htmlspecialchars( $current->getUserText() )
|
|
|
|
|
) );
|
2007-06-29 20:02:26 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-02 22:16:24 +00:00
|
|
|
# Get the last edit not by this guy...
|
|
|
|
|
# Note: these may not be public values
|
|
|
|
|
$user = intval( $current->getRawUser() );
|
|
|
|
|
$user_text = $dbw->addQuotes( $current->getRawUserText() );
|
2007-06-29 20:02:26 +00:00
|
|
|
$s = $dbw->selectRow( 'revision',
|
2008-03-09 02:18:50 +00:00
|
|
|
array( 'rev_id', 'rev_timestamp', 'rev_deleted' ),
|
2009-12-26 20:03:33 +00:00
|
|
|
array( 'rev_page' => $current->getPage(),
|
2008-11-28 14:29:25 +00:00
|
|
|
"rev_user != {$user} OR rev_user_text != {$user_text}"
|
2006-06-20 09:50:57 +00:00
|
|
|
), __METHOD__,
|
2009-12-26 20:03:33 +00:00
|
|
|
array( 'USE INDEX' => 'page_timestamp',
|
2010-05-30 14:28:54 +00:00
|
|
|
'ORDER BY' => 'rev_timestamp DESC' )
|
2007-06-29 20:02:26 +00:00
|
|
|
);
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $s === false ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
# No one else ever edited this page
|
2010-02-14 22:07:30 +00:00
|
|
|
return array( array( 'cantrollback' ) );
|
2010-07-27 18:33:04 +00:00
|
|
|
} else if ( $s->rev_deleted & Revision::DELETED_TEXT || $s->rev_deleted & Revision::DELETED_USER ) {
|
2008-03-09 02:18:50 +00:00
|
|
|
# Only admins can see this text
|
2010-02-14 22:07:30 +00:00
|
|
|
return array( array( 'notvisiblerev' ) );
|
2007-06-29 20:02:26 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2005-12-17 00:44:23 +00:00
|
|
|
$set = array();
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $bot && $wgUser->isAllowed( 'markbotedits' ) ) {
|
2007-06-29 20:02:26 +00:00
|
|
|
# Mark all reverted edits as bot
|
2005-12-17 00:44:23 +00:00
|
|
|
$set['rc_bot'] = 1;
|
2007-06-29 20:02:26 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgUseRCPatrol ) {
|
2007-06-29 20:02:26 +00:00
|
|
|
# Mark all reverted edits as patrolled
|
2005-12-17 00:44:23 +00:00
|
|
|
$set['rc_patrolled'] = 1;
|
2007-06-29 20:02:26 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( count( $set ) ) {
|
2007-06-29 20:02:26 +00:00
|
|
|
$dbw->update( 'recentchanges', $set,
|
2009-09-02 22:16:24 +00:00
|
|
|
array( /* WHERE */
|
|
|
|
|
'rc_cur_id' => $current->getPage(),
|
|
|
|
|
'rc_user_text' => $current->getUserText(),
|
|
|
|
|
"rc_timestamp > '{$s->rev_timestamp}'",
|
|
|
|
|
), __METHOD__
|
|
|
|
|
);
|
2007-06-29 19:55:46 +00:00
|
|
|
}
|
2007-06-29 20:02:26 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
# Generate the edit summary if necessary
|
2007-10-01 19:50:25 +00:00
|
|
|
$target = Revision::newFromId( $s->rev_id );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( empty( $summary ) ) {
|
|
|
|
|
if ( $from == '' ) { // no public user name
|
2009-09-02 22:16:24 +00:00
|
|
|
$summary = wfMsgForContent( 'revertpage-nouser' );
|
|
|
|
|
} else {
|
|
|
|
|
$summary = wfMsgForContent( 'revertpage' );
|
|
|
|
|
}
|
2008-01-15 15:38:30 +00:00
|
|
|
}
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2008-05-03 16:07:57 +00:00
|
|
|
# Allow the custom summary to use the same args as the default message
|
|
|
|
|
$args = array(
|
|
|
|
|
$target->getUserText(), $from, $s->rev_id,
|
2010-02-14 22:07:30 +00:00
|
|
|
$wgLang->timeanddate( wfTimestamp( TS_MW, $s->rev_timestamp ), true ),
|
|
|
|
|
$current->getId(), $wgLang->timeanddate( $current->getTimestamp() )
|
2008-05-03 16:07:57 +00:00
|
|
|
);
|
2008-08-08 00:01:53 +00:00
|
|
|
$summary = wfMsgReplaceArgs( $summary, $args );
|
2007-06-29 20:02:26 +00:00
|
|
|
|
2007-07-07 00:17:51 +00:00
|
|
|
# Save
|
2007-12-07 09:44:47 +00:00
|
|
|
$flags = EDIT_UPDATE;
|
|
|
|
|
|
2010-05-30 14:28:54 +00:00
|
|
|
if ( $wgUser->isAllowed( 'minoredit' ) ) {
|
2007-12-07 09:44:47 +00:00
|
|
|
$flags |= EDIT_MINOR;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
2007-12-07 09:44:47 +00:00
|
|
|
|
2011-03-18 21:07:05 +00:00
|
|
|
if ( $bot && ( $wgUser->isAllowedAny( 'markbotedits', 'bot' ) ) ) {
|
2007-07-06 09:06:55 +00:00
|
|
|
$flags |= EDIT_FORCE_BOT;
|
2010-05-30 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-23 18:20:50 +00:00
|
|
|
# Actually store the edit
|
2008-09-25 10:15:19 +00:00
|
|
|
$status = $this->doEdit( $target->getText(), $summary, $flags, $target->getId() );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !empty( $status->value['revision'] ) ) {
|
2008-09-25 10:15:19 +00:00
|
|
|
$revId = $status->value['revision']->getId();
|
|
|
|
|
} else {
|
|
|
|
|
$revId = false;
|
|
|
|
|
}
|
2007-07-07 00:17:51 +00:00
|
|
|
|
2009-01-04 12:27:08 +00:00
|
|
|
wfRunHooks( 'ArticleRollbackComplete', array( $this, $wgUser, $target, $current ) );
|
2007-10-30 07:58:15 +00:00
|
|
|
|
2007-07-07 07:32:34 +00:00
|
|
|
$resultDetails = array(
|
|
|
|
|
'summary' => $summary,
|
|
|
|
|
'current' => $current,
|
2009-09-02 22:16:24 +00:00
|
|
|
'target' => $target,
|
|
|
|
|
'newid' => $revId
|
2007-07-09 08:12:44 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
return array();
|
2007-07-07 07:32:34 +00:00
|
|
|
}
|
2007-06-29 20:02:26 +00:00
|
|
|
|
2007-07-09 08:12:44 +00:00
|
|
|
/**
|
|
|
|
|
* User interface for rollback operations
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function rollback() {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgUser, $wgOut, $wgRequest;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-07-09 08:12:44 +00:00
|
|
|
$details = null;
|
2007-09-10 07:48:20 +00:00
|
|
|
|
2007-07-09 08:12:44 +00:00
|
|
|
$result = $this->doRollback(
|
|
|
|
|
$wgRequest->getVal( 'from' ),
|
|
|
|
|
$wgRequest->getText( 'summary' ),
|
|
|
|
|
$wgRequest->getVal( 'token' ),
|
2008-01-10 07:52:09 +00:00
|
|
|
$wgRequest->getBool( 'bot' ),
|
2007-07-09 08:12:44 +00:00
|
|
|
$details
|
|
|
|
|
);
|
2008-01-16 00:06:42 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( in_array( array( 'actionthrottledtext' ), $result ) ) {
|
2008-01-15 17:31:07 +00:00
|
|
|
$wgOut->rateLimited();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $result[0][0] ) && ( $result[0][0] == 'alreadyrolled' || $result[0][0] == 'cantrollback' ) ) {
|
2008-03-05 13:50:17 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
|
|
|
|
|
$errArray = $result[0];
|
|
|
|
|
$errMsg = array_shift( $errArray );
|
|
|
|
|
$wgOut->addWikiMsgArray( $errMsg, $errArray );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( isset( $details['current'] ) ) {
|
2008-03-05 13:50:17 +00:00
|
|
|
$current = $details['current'];
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $current->getComment() != '' ) {
|
2009-06-18 02:50:16 +00:00
|
|
|
$wgOut->addWikiMsgArray( 'editcomment', array(
|
2011-04-25 11:59:31 +00:00
|
|
|
Linker::formatComment( $current->getComment() ) ), array( 'replaceafter' ) );
|
2008-03-05 13:50:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-03-05 13:50:17 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-16 00:06:42 +00:00
|
|
|
# Display permissions errors before read-only message -- there's no
|
|
|
|
|
# point in misleading the user into thinking the inability to rollback
|
|
|
|
|
# is only temporary.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !empty( $result ) && $result !== array( array( 'readonlytext' ) ) ) {
|
2010-05-30 14:28:54 +00:00
|
|
|
# array_diff is completely broken for arrays of arrays, sigh.
|
|
|
|
|
# Remove any 'readonlytext' error manually.
|
2008-01-16 00:06:42 +00:00
|
|
|
$out = array();
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $result as $error ) {
|
|
|
|
|
if ( $error != array( 'readonlytext' ) ) {
|
|
|
|
|
$out [] = $error;
|
2008-01-16 00:06:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$wgOut->showPermissionsErrorPage( $out );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-16 00:06:42 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $result == array( array( 'readonlytext' ) ) ) {
|
2008-01-16 00:06:42 +00:00
|
|
|
$wgOut->readOnlyPage();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
return;
|
2007-07-07 07:32:34 +00:00
|
|
|
}
|
2007-07-09 08:12:44 +00:00
|
|
|
|
2008-01-15 17:31:07 +00:00
|
|
|
$current = $details['current'];
|
|
|
|
|
$target = $details['target'];
|
2008-09-23 18:20:50 +00:00
|
|
|
$newId = $details['newid'];
|
2008-01-15 17:31:07 +00:00
|
|
|
$wgOut->setPageTitle( wfMsg( 'actioncomplete' ) );
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-12-15 07:26:40 +00:00
|
|
|
if ( $current->getUserText() === '' ) {
|
|
|
|
|
$old = wfMsg( 'rev-deleted-user' );
|
|
|
|
|
} else {
|
2011-04-25 11:59:31 +00:00
|
|
|
$old = Linker::userLink( $current->getUser(), $current->getUserText() )
|
|
|
|
|
. Linker::userToolLinks( $current->getUser(), $current->getUserText() );
|
2009-12-15 07:26:40 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-25 11:59:31 +00:00
|
|
|
$new = Linker::userLink( $target->getUser(), $target->getUserText() )
|
|
|
|
|
. Linker::userToolLinks( $target->getUser(), $target->getUserText() );
|
2008-11-06 22:20:29 +00:00
|
|
|
$wgOut->addHTML( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) );
|
2008-01-15 17:31:07 +00:00
|
|
|
$wgOut->returnToMain( false, $this->mTitle );
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgRequest->getBool( 'hidediff', false ) && !$wgUser->getBoolOption( 'norollbackdiff', false ) ) {
|
2008-09-23 18:20:50 +00:00
|
|
|
$de = new DifferenceEngine( $this->mTitle, $current->getId(), $newId, false, true );
|
2008-06-02 00:13:08 +00:00
|
|
|
$de->showDiff( '', '' );
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Do standard deferred updates after page view
|
|
|
|
|
*/
|
2008-12-11 14:29:16 +00:00
|
|
|
public function viewUpdates() {
|
|
|
|
|
global $wgDeferredUpdateList, $wgDisableCounters, $wgUser;
|
* Converted BagOStuff.php from the style of memcached-client.php to the standard MediaWiki style, including camel case, using protected visibility instead of initial underscore, abstract functions instead of stubs, stylize.php.
* In SqlBagOStuff, ignore errors due to a read-only database, per my comments on CR r42796. Same for LocalisationCache.
* Merged SqlBagOStuff and MediaWikiBagOStuff, that proved to be an awkward and unnecessary generalisation. Use the standard quoting wrapper functions instead of $db->query().
* Implemented atomic incr() and decr() functions for SqlBagOStuff.
* Made incr() and decr() generally work roughly the same as it does in memcached, respecting negative steps instead of ignoring such operations. This allows decr() to be implemented in terms of incr().
* Per bug 11533, in MessageCache.php, don't retry 20 times on a cache failure, that's really memcached-specific and won't be useful for other cache types. It's not really very useful for memcached either.
* Moved MySQL-specific implementations of wasDeadlock() and wasErrorReissuable() to DatabaseMysql.
* Briefly tested page views with $wgReadOnly=read_only=1, fixed an error from Article::viewUpdates(). A CentralAuth fix will be in a subsequent commit.
2009-08-15 03:45:19 +00:00
|
|
|
if ( wfReadOnly() ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-12-11 14:29:16 +00:00
|
|
|
# Don't update page view counters on views from bot users (bug 14044)
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgDisableCounters && !$wgUser->isAllowed( 'bot' ) && $this->getID() ) {
|
2011-01-01 16:58:00 +00:00
|
|
|
$wgDeferredUpdateList[] = new ViewCountUpdate( $this->getID() );
|
|
|
|
|
$wgDeferredUpdateList[] = new SiteStatsUpdate( 1, 0, 0 );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-07 11:52:34 +00:00
|
|
|
# Update newtalk / watchlist notification status
|
|
|
|
|
$wgUser->clearNotification( $this->mTitle );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
/**
|
|
|
|
|
* Prepare text which is about to be saved.
|
2008-06-11 02:51:30 +00:00
|
|
|
* Returns a stdclass with source, pst and output members
|
2007-11-12 07:30:40 +00:00
|
|
|
*/
|
2011-01-04 19:08:44 +00:00
|
|
|
public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mPreparedEdit && $this->mPreparedEdit->newText == $text && $this->mPreparedEdit->revid == $revid ) {
|
2007-11-12 07:30:40 +00:00
|
|
|
// Already prepared
|
|
|
|
|
return $this->mPreparedEdit;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
global $wgParser;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-16 21:12:26 +00:00
|
|
|
if( $user === null ) {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
$user = $wgUser;
|
|
|
|
|
}
|
|
|
|
|
$popts = ParserOptions::newFromUser( $user );
|
|
|
|
|
wfRunHooks( 'ArticlePrepareTextForEdit', array( $this, $popts ) );
|
|
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
$edit = (object)array();
|
2007-11-15 02:54:28 +00:00
|
|
|
$edit->revid = $revid;
|
2007-11-12 07:30:40 +00:00
|
|
|
$edit->newText = $text;
|
2011-01-16 21:12:26 +00:00
|
|
|
$edit->pst = $this->preSaveTransform( $text, $user, $popts );
|
2011-06-07 22:28:57 +00:00
|
|
|
$edit->popts = $this->getParserOptions( true );
|
2010-08-09 21:53:21 +00:00
|
|
|
$edit->output = $wgParser->parse( $edit->pst, $this->mTitle, $edit->popts, true, true, $revid );
|
2011-01-09 11:46:15 +00:00
|
|
|
$edit->oldText = $this->getRawText();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
$this->mPreparedEdit = $edit;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-11-12 07:30:40 +00:00
|
|
|
return $edit;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Do standard deferred updates after page edit.
|
2006-06-18 12:42:16 +00:00
|
|
|
* Update links tables, site stats, search index and message cache.
|
2008-09-20 22:48:55 +00:00
|
|
|
* Purges pages that include this page if the text was changed here.
|
2007-09-02 18:23:43 +00:00
|
|
|
* Every 100th edit, prune the recent changes table.
|
2007-01-17 22:32:40 +00:00
|
|
|
*
|
2006-04-19 15:46:24 +00:00
|
|
|
* @private
|
2010-11-13 00:47:51 +00:00
|
|
|
* @param $text String: New text of the article
|
|
|
|
|
* @param $summary String: Edit summary
|
|
|
|
|
* @param $minoredit Boolean: Minor edit
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $timestamp_of_pagechange String timestamp associated with the page change
|
2010-11-13 00:47:51 +00:00
|
|
|
* @param $newid Integer: rev_id value of the new revision
|
|
|
|
|
* @param $changed Boolean: Whether or not the content actually changed
|
2011-01-04 19:08:44 +00:00
|
|
|
* @param $user User object: User doing the edit
|
2011-05-14 17:11:32 +00:00
|
|
|
* @param $created Boolean: Whether the edit created the page
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2011-05-14 17:11:32 +00:00
|
|
|
public function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange, $newid,
|
|
|
|
|
$changed = true, User $user = null, $created = false )
|
|
|
|
|
{
|
2011-01-26 15:42:04 +00:00
|
|
|
global $wgDeferredUpdateList, $wgUser, $wgEnableParserCache;
|
2005-12-30 09:33:11 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
# Parse the text
|
2007-11-12 07:30:40 +00:00
|
|
|
# Be careful not to double-PST: $text is usually already PST-ed once
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) {
|
2007-11-15 02:54:28 +00:00
|
|
|
wfDebug( __METHOD__ . ": No prepared edit or vary-revision is set...\n" );
|
2011-01-04 19:08:44 +00:00
|
|
|
$editInfo = $this->prepareTextForEdit( $text, $newid, $user );
|
2007-11-12 07:30:40 +00:00
|
|
|
} else {
|
2007-11-15 02:54:28 +00:00
|
|
|
wfDebug( __METHOD__ . ": No vary-revision, using prepared edit...\n" );
|
2007-11-12 07:30:40 +00:00
|
|
|
$editInfo = $this->mPreparedEdit;
|
|
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
|
|
|
|
|
# Save it to the parser cache
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgEnableParserCache ) {
|
2008-04-09 18:23:34 +00:00
|
|
|
$parserCache = ParserCache::singleton();
|
2010-08-09 21:53:21 +00:00
|
|
|
$parserCache->save( $editInfo->output, $this, $editInfo->popts );
|
2008-01-16 02:20:49 +00:00
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
|
|
|
|
|
# Update the links tables
|
2009-02-16 14:26:34 +00:00
|
|
|
$u = new LinksUpdate( $this->mTitle, $editInfo->output );
|
2005-12-30 09:33:11 +00:00
|
|
|
$u->doUpdate();
|
2009-06-18 02:50:16 +00:00
|
|
|
|
2008-09-27 10:52:49 +00:00
|
|
|
wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $changed ) );
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( wfRunHooks( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
|
|
|
|
|
if ( 0 == mt_rand( 0, 99 ) ) {
|
2007-08-22 07:24:30 +00:00
|
|
|
// Flush old entries from the `recentchanges` table; we do this on
|
|
|
|
|
// random requests so as to avoid an increase in writes for no good reason
|
2005-10-08 19:24:47 +00:00
|
|
|
global $wgRCMaxAge;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-10-08 19:24:47 +00:00
|
|
|
$cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
|
2011-04-12 12:09:11 +00:00
|
|
|
$dbw->delete(
|
|
|
|
|
'recentchanges',
|
|
|
|
|
array( "rc_timestamp < '$cutoff'" ),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
2005-10-08 19:24:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-31 16:59:08 +00:00
|
|
|
$id = $this->getID();
|
|
|
|
|
$title = $this->mTitle->getPrefixedDBkey();
|
|
|
|
|
$shortTitle = $this->mTitle->getDBkey();
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( 0 == $id ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-12-30 09:33:11 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2011-05-14 17:11:32 +00:00
|
|
|
if ( !$changed ) {
|
|
|
|
|
$good = 0;
|
|
|
|
|
$total = 0;
|
|
|
|
|
} elseif ( $created ) {
|
|
|
|
|
$good = (int)$this->isCountable( $editInfo );
|
|
|
|
|
$total = 1;
|
|
|
|
|
} else {
|
|
|
|
|
$good = (int)$this->isCountable( $editInfo ) - (int)$this->isCountable();
|
|
|
|
|
$total = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wgDeferredUpdateList[] = new SiteStatsUpdate( 0, 1, $good, $total );
|
|
|
|
|
$wgDeferredUpdateList[] = new SearchUpdate( $id, $title, $text );
|
2005-12-30 09:33:11 +00:00
|
|
|
|
|
|
|
|
# If this is another user's talk page, update newtalk
|
2006-06-24 13:08:48 +00:00
|
|
|
# Don't do this if $changed = false otherwise some idiot can null-edit a
|
2006-10-29 12:11:58 +00:00
|
|
|
# load of user talk pages and piss people off, nor if it's a minor edit
|
|
|
|
|
# by a properly-flagged bot.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_USER_TALK && $shortTitle != $wgUser->getTitleKey() && $changed
|
2010-05-30 14:28:54 +00:00
|
|
|
&& !( $minoredit && $wgUser->isAllowed( 'nominornewtalk' ) )
|
|
|
|
|
) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( wfRunHooks( 'ArticleEditUpdateNewTalk', array( &$this ) ) ) {
|
2008-09-04 23:25:53 +00:00
|
|
|
$other = User::newFromName( $shortTitle, false );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$other ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": invalid username\n" );
|
|
|
|
|
} elseif ( User::isIP( $shortTitle ) ) {
|
2006-02-14 21:10:31 +00:00
|
|
|
// An anonymous user
|
|
|
|
|
$other->setNewtalk( true );
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $other->isLoggedIn() ) {
|
2008-08-07 10:39:19 +00:00
|
|
|
$other->setNewtalk( true );
|
|
|
|
|
} else {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ": don't need to notify a nonexistent user\n" );
|
2006-02-14 21:10:31 +00:00
|
|
|
}
|
2004-01-31 16:59:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-12-30 09:33:11 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
|
2011-01-26 15:42:04 +00:00
|
|
|
MessageCache::singleton()->replace( $shortTitle, $text );
|
2005-12-30 09:33:11 +00:00
|
|
|
}
|
|
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-01-31 16:59:08 +00:00
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-10-09 02:15:12 +00:00
|
|
|
/**
|
|
|
|
|
* Perform article updates on a special page creation.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $rev Revision object
|
2006-10-09 02:15:12 +00:00
|
|
|
*
|
2007-09-07 13:30:28 +00:00
|
|
|
* @todo This is a shitty interface function. Kill it and replace the
|
|
|
|
|
* other shitty functions like editUpdates and such so it's not needed
|
2006-10-09 02:15:12 +00:00
|
|
|
* anymore.
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function createUpdates( $rev ) {
|
2006-10-09 02:15:12 +00:00
|
|
|
$this->editUpdates( $rev->getText(), $rev->getComment(),
|
2011-05-14 17:11:32 +00:00
|
|
|
$rev->isMinor(), wfTimestamp(), $rev->getId(), true, null, true );
|
2006-10-09 02:15:12 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2006-01-16 18:34:11 +00:00
|
|
|
* Generate the navigation links when browsing through an article revisions
|
|
|
|
|
* It shows the information as:
|
2006-04-19 15:46:24 +00:00
|
|
|
* Revision as of \<date\>; view current revision
|
|
|
|
|
* \<- Previous version | Next Version -\>
|
2006-01-16 18:34:11 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $oldid String: revision ID of this article revision
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-12-22 18:30:13 +00:00
|
|
|
public function setOldSubtitle( $oldid = 0 ) {
|
2009-02-09 22:27:25 +00:00
|
|
|
global $wgLang, $wgOut, $wgUser, $wgRequest;
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !wfRunHooks( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
|
2008-11-28 14:29:25 +00:00
|
|
|
return;
|
2007-01-17 22:32:40 +00:00
|
|
|
}
|
2006-07-27 18:51:52 +00:00
|
|
|
|
2010-05-24 18:15:52 +00:00
|
|
|
$unhide = $wgRequest->getInt( 'unhide' ) == 1;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-10-28 06:37:51 +00:00
|
|
|
# Cascade unhide param in links for easy deletion browsing
|
|
|
|
|
$extraParams = array();
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $wgRequest->getVal( 'unhide' ) ) {
|
2009-10-28 06:37:51 +00:00
|
|
|
$extraParams['unhide'] = 1;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 15:19:13 +00:00
|
|
|
$revision = Revision::newFromId( $oldid );
|
2011-04-18 17:59:32 +00:00
|
|
|
$timestamp = $revision->getTimestamp();
|
2006-06-20 15:19:13 +00:00
|
|
|
|
2005-06-29 23:44:03 +00:00
|
|
|
$current = ( $oldid == $this->mLatest );
|
2011-04-18 17:59:32 +00:00
|
|
|
$td = $wgLang->timeanddate( $timestamp, true );
|
|
|
|
|
$tddate = $wgLang->date( $timestamp, true );
|
|
|
|
|
$tdtime = $wgLang->time( $timestamp, true );
|
2011-04-25 11:59:31 +00:00
|
|
|
|
2005-06-29 23:44:03 +00:00
|
|
|
$lnk = $current
|
2008-12-22 18:30:13 +00:00
|
|
|
? wfMsgHtml( 'currentrevisionlink' )
|
2011-04-25 11:59:31 +00:00
|
|
|
: Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'currentrevisionlink' ),
|
|
|
|
|
array(),
|
2009-10-28 06:37:51 +00:00
|
|
|
$extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
2006-11-16 05:44:59 +00:00
|
|
|
$curdiff = $current
|
2008-12-22 18:30:13 +00:00
|
|
|
? wfMsgHtml( 'diff' )
|
2011-04-25 11:59:31 +00:00
|
|
|
: Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'diff' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'diff' => 'cur',
|
|
|
|
|
'oldid' => $oldid
|
2009-10-28 06:37:51 +00:00
|
|
|
) + $extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
2006-01-16 18:34:11 +00:00
|
|
|
$prev = $this->mTitle->getPreviousRevisionID( $oldid ) ;
|
|
|
|
|
$prevlink = $prev
|
2011-04-25 11:59:31 +00:00
|
|
|
? Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'previousrevision' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'direction' => 'prev',
|
|
|
|
|
'oldid' => $oldid
|
2009-10-28 06:37:51 +00:00
|
|
|
) + $extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
)
|
2008-12-22 18:30:13 +00:00
|
|
|
: wfMsgHtml( 'previousrevision' );
|
2006-07-01 18:47:36 +00:00
|
|
|
$prevdiff = $prev
|
2011-04-25 11:59:31 +00:00
|
|
|
? Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'diff' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'diff' => 'prev',
|
|
|
|
|
'oldid' => $oldid
|
2009-10-28 06:37:51 +00:00
|
|
|
) + $extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
)
|
2008-12-22 18:30:13 +00:00
|
|
|
: wfMsgHtml( 'diff' );
|
2005-06-29 23:44:03 +00:00
|
|
|
$nextlink = $current
|
2008-12-22 18:30:13 +00:00
|
|
|
? wfMsgHtml( 'nextrevision' )
|
2011-04-25 11:59:31 +00:00
|
|
|
: Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'nextrevision' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'direction' => 'next',
|
|
|
|
|
'oldid' => $oldid
|
2009-10-28 06:37:51 +00:00
|
|
|
) + $extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
2006-07-01 18:47:36 +00:00
|
|
|
$nextdiff = $current
|
2008-12-22 18:30:13 +00:00
|
|
|
? wfMsgHtml( 'diff' )
|
2011-04-25 11:59:31 +00:00
|
|
|
: Linker::link(
|
2009-06-06 22:42:48 +00:00
|
|
|
$this->mTitle,
|
|
|
|
|
wfMsgHtml( 'diff' ),
|
|
|
|
|
array(),
|
|
|
|
|
array(
|
|
|
|
|
'diff' => 'next',
|
|
|
|
|
'oldid' => $oldid
|
2009-10-28 06:37:51 +00:00
|
|
|
) + $extraParams,
|
2009-06-06 22:42:48 +00:00
|
|
|
array( 'known', 'noclasses' )
|
|
|
|
|
);
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2009-10-30 02:14:22 +00:00
|
|
|
$cdel = '';
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-10-30 02:14:22 +00:00
|
|
|
// User can delete revisions or view deleted revisions...
|
2009-10-30 02:23:58 +00:00
|
|
|
$canHide = $wgUser->isAllowed( 'deleterevision' );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $canHide || ( $revision->getVisibility() && $wgUser->isAllowed( 'deletedhistory' ) ) ) {
|
|
|
|
|
if ( !$revision->userCan( Revision::DELETED_RESTRICTED ) ) {
|
2011-04-25 11:59:31 +00:00
|
|
|
$cdel = Linker::revDeleteLinkDisabled( $canHide ); // rev was hidden from Sysops
|
2008-03-09 02:18:50 +00:00
|
|
|
} else {
|
2009-10-29 06:11:03 +00:00
|
|
|
$query = array(
|
|
|
|
|
'type' => 'revision',
|
2009-10-31 19:42:11 +00:00
|
|
|
'target' => $this->mTitle->getPrefixedDbkey(),
|
|
|
|
|
'ids' => $oldid
|
2009-06-06 22:42:48 +00:00
|
|
|
);
|
2011-04-25 11:59:31 +00:00
|
|
|
$cdel = Linker::revDeleteLink( $query, $revision->isDeleted( File::DELETED_RESTRICTED ), $canHide );
|
2008-03-09 02:18:50 +00:00
|
|
|
}
|
2009-10-29 06:11:03 +00:00
|
|
|
$cdel .= ' ';
|
2008-03-09 02:18:50 +00:00
|
|
|
}
|
2009-10-30 02:14:22 +00:00
|
|
|
|
2009-02-09 22:27:25 +00:00
|
|
|
# Show user links if allowed to see them. If hidden, then show them only if requested...
|
2011-04-25 11:59:31 +00:00
|
|
|
$userlinks = Linker::revUserTools( $revision, !$unhide );
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2011-01-14 10:51:05 +00:00
|
|
|
$infomsg = $current && !wfMessage( 'revision-info-current' )->isDisabled()
|
2007-06-20 07:28:45 +00:00
|
|
|
? 'revision-info-current'
|
|
|
|
|
: 'revision-info';
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2009-06-07 23:51:19 +00:00
|
|
|
$r = "\n\t\t\t\t<div id=\"mw-{$infomsg}\">" .
|
|
|
|
|
wfMsgExt(
|
|
|
|
|
$infomsg,
|
2009-12-26 20:03:33 +00:00
|
|
|
array( 'parseinline', 'replaceafter' ),
|
2009-06-07 23:51:19 +00:00
|
|
|
$td,
|
|
|
|
|
$userlinks,
|
|
|
|
|
$revision->getID(),
|
|
|
|
|
$tddate,
|
2009-07-20 00:44:39 +00:00
|
|
|
$tdtime,
|
|
|
|
|
$revision->getUser()
|
2009-06-07 23:51:19 +00:00
|
|
|
) .
|
|
|
|
|
"</div>\n" .
|
|
|
|
|
"\n\t\t\t\t<div id=\"mw-revision-nav\">" . $cdel . wfMsgExt( 'revision-nav', array( 'escapenoentities', 'parsemag', 'replaceafter' ),
|
|
|
|
|
$prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-04 11:46:18 +00:00
|
|
|
$wgOut->addHTML( $r );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* This function is called right before saving the wikitext,
|
|
|
|
|
* so we can do things like signatures and links-in-context.
|
2004-09-03 00:20:26 +00:00
|
|
|
*
|
2010-03-15 12:04:24 +00:00
|
|
|
* @param $text String article contents
|
2011-01-04 19:08:44 +00:00
|
|
|
* @param $user User object: user doing the edit, $wgUser will be used if
|
|
|
|
|
* null is given
|
2011-01-16 21:12:26 +00:00
|
|
|
* @param $popts ParserOptions object: parser options, default options for
|
|
|
|
|
* the user loaded if null given
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return string article contents with altered wikitext markup (signatures
|
|
|
|
|
* converted, {{subst:}}, templates, etc.)
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2011-01-16 21:12:26 +00:00
|
|
|
public function preSaveTransform( $text, User $user = null, ParserOptions $popts = null ) {
|
2011-01-04 19:08:44 +00:00
|
|
|
global $wgParser;
|
|
|
|
|
|
|
|
|
|
if ( $user === null ) {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
$user = $wgUser;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-01-16 21:12:26 +00:00
|
|
|
if ( $popts === null ) {
|
|
|
|
|
$popts = ParserOptions::newFromUser( $user );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $wgParser->preSaveTransform( $text, $this->mTitle, $user, $popts );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2003-05-16 13:39:22 +00:00
|
|
|
/* Caching functions */
|
2003-12-11 20:16:34 +00:00
|
|
|
|
2004-09-03 00:20:26 +00:00
|
|
|
/**
|
|
|
|
|
* checkLastModified returns true if it has taken care of all
|
|
|
|
|
* output to the client that is necessary for this request.
|
|
|
|
|
* (that is, it has sent a cached version of the page)
|
2010-03-15 12:04:24 +00:00
|
|
|
*
|
|
|
|
|
* @return boolean true if cached version send, false otherwise
|
2004-09-03 00:20:26 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
protected function tryFileCache() {
|
2003-11-24 08:41:40 +00:00
|
|
|
static $called = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $called ) {
|
2006-07-03 16:45:51 +00:00
|
|
|
wfDebug( "Article::tryFileCache(): called twice!?\n" );
|
2008-09-25 23:02:35 +00:00
|
|
|
return false;
|
2003-11-24 08:41:40 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2003-11-24 08:41:40 +00:00
|
|
|
$called = true;
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->isFileCacheable() ) {
|
2006-10-11 08:25:26 +00:00
|
|
|
$cache = new HTMLFileCache( $this->mTitle );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $cache->isFileCacheGood( $this->mTouched ) ) {
|
2006-07-03 16:45:51 +00:00
|
|
|
wfDebug( "Article::tryFileCache(): about to load file\n" );
|
2003-08-02 10:13:27 +00:00
|
|
|
$cache->loadFromFileCache();
|
2003-12-11 20:16:34 +00:00
|
|
|
return true;
|
2003-05-16 13:39:22 +00:00
|
|
|
} else {
|
2006-07-03 16:45:51 +00:00
|
|
|
wfDebug( "Article::tryFileCache(): starting buffer\n" );
|
2010-02-14 22:07:30 +00:00
|
|
|
ob_start( array( &$cache, 'saveToFileCache' ) );
|
2003-05-16 13:39:22 +00:00
|
|
|
}
|
|
|
|
|
} else {
|
2006-07-03 16:45:51 +00:00
|
|
|
wfDebug( "Article::tryFileCache(): not cacheable\n" );
|
2003-05-16 13:39:22 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 23:02:35 +00:00
|
|
|
return false;
|
2003-05-16 13:39:22 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2004-09-03 00:20:26 +00:00
|
|
|
/**
|
|
|
|
|
* Check if the page can be cached
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function isFileCacheable() {
|
2008-12-11 14:29:16 +00:00
|
|
|
$cacheable = false;
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( HTMLFileCache::useFileCache() ) {
|
2010-12-06 01:08:17 +00:00
|
|
|
$cacheable = $this->getID() && !$this->mRedirectedFrom && !$this->mTitle->isRedirect();
|
2008-12-11 14:29:16 +00:00
|
|
|
// Extension may have reason to disable file caching on some pages.
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $cacheable ) {
|
2008-12-11 14:29:16 +00:00
|
|
|
$cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) );
|
2008-09-25 23:02:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-04-25 13:07:29 +00:00
|
|
|
return $cacheable;
|
2003-05-16 13:39:22 +00:00
|
|
|
}
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2004-09-03 00:20:26 +00:00
|
|
|
/**
|
2005-12-30 09:33:11 +00:00
|
|
|
* Loads page_touched and returns a value indicating if it should be used
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return boolean true if not a redirect
|
2004-09-03 00:20:26 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function checkTouched() {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mDataLoaded ) {
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->loadPageData();
|
2003-11-09 11:45:12 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-03-18 08:37:50 +00:00
|
|
|
return !$this->mIsRedirect;
|
2003-11-09 11:45:12 +00:00
|
|
|
}
|
2004-05-27 15:24:04 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
/**
|
|
|
|
|
* Get the page_touched field
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return string containing GMT timestamp
|
2005-12-30 09:33:11 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getTouched() {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mDataLoaded ) {
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->loadPageData();
|
2005-12-30 09:33:11 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-12-30 09:33:11 +00:00
|
|
|
return $this->mTouched;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-16 02:32:30 +00:00
|
|
|
/**
|
|
|
|
|
* Get the page_latest field
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return integer rev_id of current revision
|
2006-03-16 02:32:30 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function getLatest() {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mDataLoaded ) {
|
2006-03-16 02:32:30 +00:00
|
|
|
$this->loadPageData();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-03-05 23:04:13 +00:00
|
|
|
return (int)$this->mLatest;
|
2006-03-16 02:32:30 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-03 00:20:26 +00:00
|
|
|
/**
|
|
|
|
|
* Edit an article without doing all that other stuff
|
2005-03-12 10:50:51 +00:00
|
|
|
* The article must already exist; link tables etc
|
|
|
|
|
* are not updated, caches are not flushed.
|
2004-09-03 00:20:26 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $text String: text submitted
|
|
|
|
|
* @param $comment String: comment submitted
|
|
|
|
|
* @param $minor Boolean: whereas it's a minor modification
|
2004-09-03 00:20:26 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function quickEdit( $text, $comment = '', $minor = 0 ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2004-06-02 13:14:40 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-03-12 10:50:51 +00:00
|
|
|
$revision = new Revision( array(
|
|
|
|
|
'page' => $this->getId(),
|
|
|
|
|
'text' => $text,
|
|
|
|
|
'comment' => $comment,
|
|
|
|
|
'minor_edit' => $minor ? 1 : 0,
|
|
|
|
|
) );
|
2006-11-23 08:25:56 +00:00
|
|
|
$revision->insertOn( $dbw );
|
2005-03-13 07:49:15 +00:00
|
|
|
$this->updateRevisionOn( $dbw, $revision );
|
2008-08-08 00:01:53 +00:00
|
|
|
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgUser;
|
2010-02-14 22:07:30 +00:00
|
|
|
wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $wgUser ) );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-06-02 13:14:40 +00:00
|
|
|
}
|
|
|
|
|
|
2011-01-06 15:55:56 +00:00
|
|
|
/**
|
2004-09-02 23:28:24 +00:00
|
|
|
* The onArticle*() functions are supposed to be a kind of hooks
|
|
|
|
|
* which should be called whenever any of the specified actions
|
|
|
|
|
* are done.
|
2005-07-01 00:03:31 +00:00
|
|
|
*
|
2004-09-02 23:28:24 +00:00
|
|
|
* This is a good place to put code to clear caches, for instance.
|
2005-07-01 00:03:31 +00:00
|
|
|
*
|
2004-09-02 23:28:24 +00:00
|
|
|
* This is called on page move and undelete, as well as edit
|
2008-11-30 10:10:15 +00:00
|
|
|
*
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $title Title object
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-09-20 22:48:55 +00:00
|
|
|
public static function onArticleCreate( $title ) {
|
|
|
|
|
# Update existence markers on article/talk tabs...
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $title->isTalkPage() ) {
|
2006-06-20 09:50:57 +00:00
|
|
|
$other = $title->getSubjectPage();
|
|
|
|
|
} else {
|
|
|
|
|
$other = $title->getTalkPage();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-06-20 09:50:57 +00:00
|
|
|
$other->invalidateCache();
|
|
|
|
|
$other->purgeSquid();
|
|
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
$title->touchLinks();
|
|
|
|
|
$title->purgeSquid();
|
2007-12-11 09:51:56 +00:00
|
|
|
$title->deleteTitleProtection();
|
2004-01-05 23:32:39 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-03-15 12:04:24 +00:00
|
|
|
/**
|
|
|
|
|
* Clears caches when article is deleted
|
2011-04-25 11:59:31 +00:00
|
|
|
*
|
|
|
|
|
* @param $title Title
|
2010-03-15 12:04:24 +00:00
|
|
|
*/
|
2008-09-20 14:19:42 +00:00
|
|
|
public static function onArticleDelete( $title ) {
|
2008-09-20 22:48:55 +00:00
|
|
|
# Update existence markers on article/talk tabs...
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $title->isTalkPage() ) {
|
2008-03-25 00:14:32 +00:00
|
|
|
$other = $title->getSubjectPage();
|
|
|
|
|
} else {
|
|
|
|
|
$other = $title->getTalkPage();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-03-25 00:14:32 +00:00
|
|
|
$other->invalidateCache();
|
|
|
|
|
$other->purgeSquid();
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2005-10-05 01:32:55 +00:00
|
|
|
$title->touchLinks();
|
2006-06-18 12:42:16 +00:00
|
|
|
$title->purgeSquid();
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
# File cache
|
2008-12-28 14:19:39 +00:00
|
|
|
HTMLFileCache::clearFileCache( $title );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-05-21 05:23:20 +00:00
|
|
|
# Messages
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $title->getNamespace() == NS_MEDIAWIKI ) {
|
2011-01-26 15:42:04 +00:00
|
|
|
MessageCache::singleton()->replace( $title->getDBkey(), false );
|
2005-10-05 01:32:55 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-05-21 05:23:20 +00:00
|
|
|
# Images
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $title->getNamespace() == NS_FILE ) {
|
2008-01-26 18:45:54 +00:00
|
|
|
$update = new HTMLCacheUpdate( $title, 'imagelinks' );
|
|
|
|
|
$update->doUpdate();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-05-21 05:23:20 +00:00
|
|
|
# User talk pages
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $title->getNamespace() == NS_USER_TALK ) {
|
2008-05-21 05:23:20 +00:00
|
|
|
$user = User::newFromName( $title->getText(), false );
|
|
|
|
|
$user->setNewtalk( false );
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-03-17 18:15:40 +00:00
|
|
|
# Image redirects
|
|
|
|
|
RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $title );
|
2004-01-05 23:32:39 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-12-08 01:36:33 +00:00
|
|
|
/**
|
|
|
|
|
* Purge caches on page update etc
|
2010-03-15 13:35:00 +00:00
|
|
|
*
|
|
|
|
|
* @param $title Title object
|
2010-03-15 13:40:51 +00:00
|
|
|
* @todo: verify that $title is always a Title object (and never false or null), add Title hint to parameter $title
|
2005-12-08 01:36:33 +00:00
|
|
|
*/
|
2010-03-15 13:35:00 +00:00
|
|
|
public static function onArticleEdit( $title ) {
|
2008-12-28 14:19:39 +00:00
|
|
|
global $wgDeferredUpdateList;
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
// Invalidate caches of articles which include this page
|
2009-02-16 14:26:34 +00:00
|
|
|
$wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'templatelinks' );
|
2005-12-08 01:36:33 +00:00
|
|
|
|
2008-01-17 12:31:54 +00:00
|
|
|
// Invalidate the caches of all pages which redirect here
|
|
|
|
|
$wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'redirect' );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-06-18 12:42:16 +00:00
|
|
|
# Purge squid for this page only
|
|
|
|
|
$title->purgeSquid();
|
2005-12-08 01:36:33 +00:00
|
|
|
|
2008-09-20 14:19:42 +00:00
|
|
|
# Clear file cache for this page only
|
2008-12-28 14:19:39 +00:00
|
|
|
HTMLFileCache::clearFileCache( $title );
|
2004-01-05 23:32:39 +00:00
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2004-09-03 00:20:26 +00:00
|
|
|
/**#@-*/
|
2004-08-12 14:27:38 +00:00
|
|
|
|
2008-03-01 15:54:07 +00:00
|
|
|
/**
|
|
|
|
|
* Overriden by ImagePage class, only present here to avoid a fatal error
|
|
|
|
|
* Called for ?action=revert
|
|
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function revert() {
|
2008-03-01 15:54:07 +00:00
|
|
|
global $wgOut;
|
|
|
|
|
$wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* Info about this page
|
2005-02-28 04:52:37 +00:00
|
|
|
* Called for ?action=info when $wgAllowPageInfo is on.
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-11-28 14:29:25 +00:00
|
|
|
public function info() {
|
2005-10-06 14:20:45 +00:00
|
|
|
global $wgLang, $wgOut, $wgAllowPageInfo, $wgUser;
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$wgAllowPageInfo ) {
|
2006-06-07 06:40:24 +00:00
|
|
|
$wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
|
2004-07-09 11:42:24 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
$page = $this->mTitle->getSubjectPage();
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
$wgOut->setPagetitle( $page->getPrefixedText() );
|
2007-07-22 14:45:12 +00:00
|
|
|
$wgOut->setPageTitleActionText( wfMsg( 'info_short' ) );
|
2008-12-22 18:30:13 +00:00
|
|
|
$wgOut->setSubtitle( wfMsgHtml( 'infosubtitle' ) );
|
2007-08-01 01:23:44 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mTitle->exists() ) {
|
2008-11-06 22:20:29 +00:00
|
|
|
$wgOut->addHTML( '<div class="noarticletext">' );
|
2011-05-17 08:17:44 +00:00
|
|
|
$msg = $wgUser->isLoggedIn()
|
|
|
|
|
? 'noarticletext'
|
|
|
|
|
: 'noarticletextanon';
|
|
|
|
|
$wgOut->addWikiMsg( $msg );
|
2008-11-06 22:20:29 +00:00
|
|
|
$wgOut->addHTML( '</div>' );
|
2004-07-08 14:53:54 +00:00
|
|
|
} else {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2005-02-28 04:52:37 +00:00
|
|
|
$wl_clause = array(
|
|
|
|
|
'wl_title' => $page->getDBkey(),
|
|
|
|
|
'wl_namespace' => $page->getNamespace() );
|
|
|
|
|
$numwatchers = $dbr->selectField(
|
|
|
|
|
'watchlist',
|
|
|
|
|
'COUNT(*)',
|
|
|
|
|
$wl_clause,
|
2011-04-13 00:50:44 +00:00
|
|
|
__METHOD__ );
|
2004-07-08 14:53:54 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
$pageInfo = $this->pageCountInfo( $page );
|
|
|
|
|
$talkInfo = $this->pageCountInfo( $page->getTalkPage() );
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2011-05-17 08:17:44 +00:00
|
|
|
// @todo FIXME: unescaped messages
|
2010-02-14 22:07:30 +00:00
|
|
|
$wgOut->addHTML( "<ul><li>" . wfMsg( "numwatchers", $wgLang->formatNum( $numwatchers ) ) . '</li>' );
|
|
|
|
|
$wgOut->addHTML( "<li>" . wfMsg( 'numedits', $wgLang->formatNum( $pageInfo['edits'] ) ) . '</li>' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $talkInfo ) {
|
|
|
|
|
$wgOut->addHTML( '<li>' . wfMsg( "numtalkedits", $wgLang->formatNum( $talkInfo['edits'] ) ) . '</li>' );
|
2004-07-08 14:53:54 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$wgOut->addHTML( '<li>' . wfMsg( "numauthors", $wgLang->formatNum( $pageInfo['authors'] ) ) . '</li>' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $talkInfo ) {
|
|
|
|
|
$wgOut->addHTML( '<li>' . wfMsg( 'numtalkauthors', $wgLang->formatNum( $talkInfo['authors'] ) ) . '</li>' );
|
2004-07-08 14:53:54 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
$wgOut->addHTML( '</ul>' );
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-07-01 00:03:31 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
/**
|
|
|
|
|
* Return the total number of edits and number of unique editors
|
|
|
|
|
* on a given page. If page does not exist, returns false.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $title Title object
|
2010-03-15 12:04:24 +00:00
|
|
|
* @return mixed array or boolean false
|
2005-02-28 04:52:37 +00:00
|
|
|
*/
|
2009-04-07 03:06:36 +00:00
|
|
|
public function pageCountInfo( $title ) {
|
2005-02-28 04:52:37 +00:00
|
|
|
$id = $title->getArticleId();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $id == 0 ) {
|
2005-02-28 04:52:37 +00:00
|
|
|
return false;
|
2004-07-08 14:53:54 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2005-02-28 04:52:37 +00:00
|
|
|
$rev_clause = array( 'rev_page' => $id );
|
|
|
|
|
$edits = $dbr->selectField(
|
|
|
|
|
'revision',
|
|
|
|
|
'COUNT(rev_page)',
|
|
|
|
|
$rev_clause,
|
2011-04-13 00:50:44 +00:00
|
|
|
__METHOD__
|
2008-11-28 14:29:25 +00:00
|
|
|
);
|
2005-02-28 04:52:37 +00:00
|
|
|
$authors = $dbr->selectField(
|
|
|
|
|
'revision',
|
|
|
|
|
'COUNT(DISTINCT rev_user_text)',
|
|
|
|
|
$rev_clause,
|
2011-04-13 00:50:44 +00:00
|
|
|
__METHOD__
|
2008-11-28 14:29:25 +00:00
|
|
|
);
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-02-28 04:52:37 +00:00
|
|
|
return array( 'edits' => $edits, 'authors' => $authors );
|
2004-07-08 14:53:54 +00:00
|
|
|
}
|
2005-04-03 07:01:29 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return a list of templates used by this article.
|
2005-12-30 09:33:11 +00:00
|
|
|
* Uses the templatelinks table
|
2005-04-03 07:01:29 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @return Array of Title objects
|
2005-04-03 07:01:29 +00:00
|
|
|
*/
|
2008-09-20 14:19:42 +00:00
|
|
|
public function getUsedTemplates() {
|
2005-04-03 07:01:29 +00:00
|
|
|
$result = array();
|
|
|
|
|
$id = $this->mTitle->getArticleID();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $id == 0 ) {
|
2006-03-07 04:23:09 +00:00
|
|
|
return array();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2005-12-30 09:33:11 +00:00
|
|
|
$res = $dbr->select( array( 'templatelinks' ),
|
|
|
|
|
array( 'tl_namespace', 'tl_title' ),
|
|
|
|
|
array( 'tl_from' => $id ),
|
2008-07-25 19:36:13 +00:00
|
|
|
__METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $res !== false ) {
|
|
|
|
|
foreach ( $res as $row ) {
|
2008-07-27 18:59:46 +00:00
|
|
|
$result[] = Title::makeTitle( $row->tl_namespace, $row->tl_title );
|
2005-04-03 07:01:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2005-04-03 07:01:29 +00:00
|
|
|
return $result;
|
|
|
|
|
}
|
2007-01-17 22:32:40 +00:00
|
|
|
|
2008-02-25 13:38:21 +00:00
|
|
|
/**
|
|
|
|
|
* Returns a list of hidden categories this page is a member of.
|
|
|
|
|
* Uses the page_props and categorylinks tables.
|
|
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @return Array of Title objects
|
2008-02-25 13:38:21 +00:00
|
|
|
*/
|
2008-09-20 14:19:42 +00:00
|
|
|
public function getHiddenCategories() {
|
2008-02-25 13:38:21 +00:00
|
|
|
$result = array();
|
|
|
|
|
$id = $this->mTitle->getArticleID();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $id == 0 ) {
|
2008-02-25 13:38:21 +00:00
|
|
|
return array();
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-02-25 13:38:21 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$res = $dbr->select( array( 'categorylinks', 'page_props', 'page' ),
|
|
|
|
|
array( 'cl_to' ),
|
2008-04-14 07:45:50 +00:00
|
|
|
array( 'cl_from' => $id, 'pp_page=page_id', 'pp_propname' => 'hiddencat',
|
2010-02-14 22:07:30 +00:00
|
|
|
'page_namespace' => NS_CATEGORY, 'page_title=cl_to' ),
|
2008-07-25 19:36:13 +00:00
|
|
|
__METHOD__ );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $res !== false ) {
|
|
|
|
|
foreach ( $res as $row ) {
|
2008-07-27 18:59:46 +00:00
|
|
|
$result[] = Title::makeTitle( NS_CATEGORY, $row->cl_to );
|
2008-02-25 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-02-25 13:38:21 +00:00
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-20 11:48:03 +00:00
|
|
|
/**
|
|
|
|
|
* Return an applicable autosummary if one exists for the given edit.
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $oldtext String: the previous text of the page.
|
|
|
|
|
* @param $newtext String: The submitted text of the page.
|
2011-01-06 15:55:56 +00:00
|
|
|
* @param $flags Int bitmask: a bitmask of flags submitted for the edit.
|
2006-11-20 11:48:03 +00:00
|
|
|
* @return string An appropriate autosummary, or an empty string.
|
|
|
|
|
*/
|
|
|
|
|
public static function getAutosummary( $oldtext, $newtext, $flags ) {
|
2010-07-25 17:56:23 +00:00
|
|
|
global $wgContLang;
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
# Decide what kind of autosummary is needed.
|
2006-11-20 11:48:03 +00:00
|
|
|
|
2009-01-29 00:29:52 +00:00
|
|
|
# Redirect autosummaries
|
|
|
|
|
$ot = Title::newFromRedirect( $oldtext );
|
|
|
|
|
$rt = Title::newFromRedirect( $newtext );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_object( $rt ) && ( !is_object( $ot ) || !$rt->equals( $ot ) || $ot->getFragment() != $rt->getFragment() ) ) {
|
2008-05-24 14:55:54 +00:00
|
|
|
return wfMsgForContent( 'autoredircomment', $rt->getFullText() );
|
|
|
|
|
}
|
2006-11-20 11:48:03 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
# New page autosummaries
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $flags & EDIT_NEW && strlen( $newtext ) ) {
|
2008-05-24 14:55:54 +00:00
|
|
|
# If they're making a new article, give its text, truncated, in the summary.
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2006-12-22 19:58:25 +00:00
|
|
|
$truncatedtext = $wgContLang->truncate(
|
2010-02-14 22:07:30 +00:00
|
|
|
str_replace( "\n", ' ', $newtext ),
|
2009-02-13 19:13:48 +00:00
|
|
|
max( 0, 200 - strlen( wfMsgForContent( 'autosumm-new' ) ) ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
return wfMsgForContent( 'autosumm-new', $truncatedtext );
|
2006-11-23 09:32:28 +00:00
|
|
|
}
|
|
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
# Blanking autosummaries
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $oldtext != '' && $newtext == '' ) {
|
2008-11-08 20:36:21 +00:00
|
|
|
return wfMsgForContent( 'autosumm-blank' );
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( strlen( $oldtext ) > 10 * strlen( $newtext ) && strlen( $newtext ) < 500 ) {
|
2008-05-24 14:55:54 +00:00
|
|
|
# Removing more than 90% of the article
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
$truncatedtext = $wgContLang->truncate(
|
|
|
|
|
$newtext,
|
2009-02-13 19:13:48 +00:00
|
|
|
max( 0, 200 - strlen( wfMsgForContent( 'autosumm-replace' ) ) ) );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
return wfMsgForContent( 'autosumm-replace', $truncatedtext );
|
|
|
|
|
}
|
2006-11-20 11:48:03 +00:00
|
|
|
|
2008-05-24 14:55:54 +00:00
|
|
|
# If we reach this point, there's no applicable autosummary for our case, so our
|
|
|
|
|
# autosummary is empty.
|
|
|
|
|
return '';
|
2006-11-20 11:48:03 +00:00
|
|
|
}
|
2007-01-10 23:32:38 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add the primary page-view wikitext to the output buffer
|
|
|
|
|
* Saves the text into the parser cache if possible.
|
2007-01-11 00:31:04 +00:00
|
|
|
* Updates templatelinks if it is out of date.
|
2007-01-10 23:32:38 +00:00
|
|
|
*
|
2008-11-30 10:10:15 +00:00
|
|
|
* @param $text String
|
|
|
|
|
* @param $cache Boolean
|
2010-03-15 12:04:24 +00:00
|
|
|
* @param $parserOptions mixed ParserOptions object, or boolean false
|
2007-01-10 23:32:38 +00:00
|
|
|
*/
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
public function outputWikiText( $text, $cache = true, $parserOptions = false ) {
|
2009-06-23 21:52:39 +00:00
|
|
|
global $wgOut;
|
2009-08-31 19:19:12 +00:00
|
|
|
|
|
|
|
|
$this->mParserOutput = $this->getOutputFromWikitext( $text, $cache, $parserOptions );
|
|
|
|
|
$wgOut->addParserOutput( $this->mParserOutput );
|
2009-06-23 21:52:39 +00:00
|
|
|
}
|
2009-12-26 20:03:33 +00:00
|
|
|
|
2009-06-23 21:52:39 +00:00
|
|
|
/**
|
|
|
|
|
* This does all the heavy lifting for outputWikitext, except it returns the parser
|
|
|
|
|
* output instead of sending it straight to $wgOut. Makes things nice and simple for,
|
|
|
|
|
* say, embedding thread pages within a discussion system (LiquidThreads)
|
2010-03-15 12:04:24 +00:00
|
|
|
*
|
|
|
|
|
* @param $text string
|
|
|
|
|
* @param $cache boolean
|
|
|
|
|
* @param $parserOptions parsing options, defaults to false
|
|
|
|
|
* @return string containing parsed output
|
2009-06-23 21:52:39 +00:00
|
|
|
*/
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
public function getOutputFromWikitext( $text, $cache = true, $parserOptions = false ) {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgParser, $wgEnableParserCache, $wgUseFileCache;
|
2007-01-10 23:32:38 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
if ( !$parserOptions ) {
|
2010-12-26 19:23:11 +00:00
|
|
|
$parserOptions = $this->getParserOptions();
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$time = - wfTime();
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->mParserOutput = $wgParser->parse( $text, $this->mTitle,
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$parserOptions, true, true, $this->getRevIdFetched() );
|
|
|
|
|
$time += wfTime();
|
|
|
|
|
|
|
|
|
|
# Timing hack
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $time > 3 ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
wfDebugLog( 'slow-parse', sprintf( "%-5.2f %s", $time,
|
2010-02-14 22:07:30 +00:00
|
|
|
$this->mTitle->getPrefixedDBkey() ) );
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-10 15:37:04 +00:00
|
|
|
if ( $wgEnableParserCache && $cache && $this->mParserOutput->isCacheable() ) {
|
2008-04-09 18:23:34 +00:00
|
|
|
$parserCache = ParserCache::singleton();
|
2009-08-31 19:19:12 +00:00
|
|
|
$parserCache->save( $this->mParserOutput, $this, $parserOptions );
|
2007-01-10 23:32:38 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2008-09-25 23:02:35 +00:00
|
|
|
// Make sure file cache is not used on uncacheable content.
|
2008-09-26 13:55:42 +00:00
|
|
|
// Output that has magic words in it can still use the parser cache
|
|
|
|
|
// (if enabled), though it will generally expire sooner.
|
2010-06-01 14:28:51 +00:00
|
|
|
if ( !$this->mParserOutput->isCacheable() || $this->mParserOutput->containsOldMagic() ) {
|
2008-09-25 23:02:35 +00:00
|
|
|
$wgUseFileCache = false;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
$this->doCascadeProtectionUpdates( $this->mParserOutput );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2009-08-31 19:19:12 +00:00
|
|
|
return $this->mParserOutput;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2007-01-10 23:32:38 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
/**
|
|
|
|
|
* Get parser options suitable for rendering the primary article wikitext
|
2011-06-07 22:28:57 +00:00
|
|
|
* @param $canonical boolean Determines that the generated options must not depend on user preferences (see bug 14404)
|
|
|
|
|
* @return mixed ParserOptions object or boolean false
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
*/
|
2011-06-07 22:28:57 +00:00
|
|
|
public function getParserOptions( $canonical = false ) {
|
|
|
|
|
global $wgUser, $wgLanguageCode;
|
|
|
|
|
|
|
|
|
|
if ( !$this->mParserOptions || $canonical ) {
|
|
|
|
|
$user = !$canonical ? $wgUser : new User;
|
|
|
|
|
$parserOptions = new ParserOptions( $user );
|
|
|
|
|
$parserOptions->setTidy( true );
|
|
|
|
|
$parserOptions->enableLimitReport();
|
|
|
|
|
|
|
|
|
|
if ( $canonical ) {
|
|
|
|
|
$parserOptions->setUserLang( $wgLanguageCode ); # Must be set explicitely
|
|
|
|
|
return $parserOptions;
|
|
|
|
|
}
|
|
|
|
|
$this->mParserOptions = $parserOptions;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2011-04-15 18:40:25 +00:00
|
|
|
// Clone to allow modifications of the return value without affecting cache
|
2010-08-09 07:41:25 +00:00
|
|
|
return clone $this->mParserOptions;
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2011-04-15 18:40:25 +00:00
|
|
|
/**
|
|
|
|
|
* Get parser options suitable for rendering the primary article wikitext
|
|
|
|
|
* @param User $user
|
|
|
|
|
* @return ParserOptions
|
|
|
|
|
*/
|
|
|
|
|
public function makeParserOptions( User $user ) {
|
|
|
|
|
$options = ParserOptions::newFromUser( $user );
|
|
|
|
|
$options->enableLimitReport(); // show inclusion/loop reports
|
|
|
|
|
$options->setTidy( true ); // fix bad HTML
|
|
|
|
|
return $options;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-15 12:04:24 +00:00
|
|
|
/**
|
|
|
|
|
* Updates cascading protections
|
|
|
|
|
*
|
2011-04-25 11:59:31 +00:00
|
|
|
* @param $parserOutput ParserOutput object, or boolean false
|
2010-03-15 12:04:24 +00:00
|
|
|
**/
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
protected function doCascadeProtectionUpdates( $parserOutput ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->isCurrent() || wfReadOnly() || !$this->mTitle->areRestrictionsCascading() ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2007-01-11 00:31:04 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
// templatelinks table may have become out of sync,
|
|
|
|
|
// especially if using variable-based transclusions.
|
|
|
|
|
// For paranoia, check if things have changed and if
|
|
|
|
|
// so apply updates to the database. This will ensure
|
|
|
|
|
// that cascaded protections apply as soon as the changes
|
|
|
|
|
// are visible.
|
2007-01-10 23:32:38 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Get templates from templatelinks
|
|
|
|
|
$id = $this->mTitle->getArticleID();
|
2007-01-11 00:31:04 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$tlTemplates = array();
|
2007-01-10 23:32:38 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$res = $dbr->select( array( 'templatelinks' ),
|
|
|
|
|
array( 'tl_namespace', 'tl_title' ),
|
|
|
|
|
array( 'tl_from' => $id ),
|
2010-05-30 14:28:54 +00:00
|
|
|
__METHOD__
|
|
|
|
|
);
|
2007-01-10 23:32:38 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $res as $row ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$tlTemplates["{$row->tl_namespace}:{$row->tl_title}"] = true;
|
|
|
|
|
}
|
2007-01-10 23:32:38 +00:00
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Get templates from parser output.
|
|
|
|
|
$poTemplates = array();
|
|
|
|
|
foreach ( $parserOutput->getTemplates() as $ns => $templates ) {
|
|
|
|
|
foreach ( $templates as $dbk => $id ) {
|
|
|
|
|
$poTemplates["$ns:$dbk"] = true;
|
2007-01-10 23:32:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
|
|
|
|
|
# Get the diff
|
|
|
|
|
$templates_diff = array_diff_key( $poTemplates, $tlTemplates );
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( count( $templates_diff ) > 0 ) {
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
# Whee, link updates time.
|
|
|
|
|
$u = new LinksUpdate( $this->mTitle, $parserOutput, false );
|
|
|
|
|
$u->doUpdate();
|
|
|
|
|
}
|
2007-01-10 23:32:38 +00:00
|
|
|
}
|
|
|
|
|
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
/**
|
|
|
|
|
* Update all the appropriate counts in the category table, given that
|
|
|
|
|
* we've added the categories $added and deleted the categories $deleted.
|
|
|
|
|
*
|
|
|
|
|
* @param $added array The names of categories that were added
|
|
|
|
|
* @param $deleted array The names of categories that were deleted
|
|
|
|
|
*/
|
2008-03-19 13:36:33 +00:00
|
|
|
public function updateCategoryCounts( $added, $deleted ) {
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
$ns = $this->mTitle->getNamespace();
|
2011-04-11 18:46:35 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
|
|
|
|
|
# First make sure the rows exist. If one of the "deleted" ones didn't
|
|
|
|
|
# exist, we might legitimately not create it, but it's simpler to just
|
|
|
|
|
# create it and then give it a negative value, since the value is bogus
|
|
|
|
|
# anyway.
|
|
|
|
|
#
|
|
|
|
|
# Sometimes I wish we had INSERT ... ON DUPLICATE KEY UPDATE.
|
|
|
|
|
$insertCats = array_merge( $added, $deleted );
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$insertCats ) {
|
2008-03-20 17:33:32 +00:00
|
|
|
# Okay, nothing to do
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
$insertRows = array();
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $insertCats as $cat ) {
|
2009-12-26 20:03:33 +00:00
|
|
|
$insertRows[] = array(
|
|
|
|
|
'cat_id' => $dbw->nextSequenceValue( 'category_cat_id_seq' ),
|
|
|
|
|
'cat_title' => $cat
|
|
|
|
|
);
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
}
|
2008-03-21 02:16:28 +00:00
|
|
|
$dbw->insert( 'category', $insertRows, __METHOD__, 'IGNORE' );
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
|
|
|
|
|
$addFields = array( 'cat_pages = cat_pages + 1' );
|
|
|
|
|
$removeFields = array( 'cat_pages = cat_pages - 1' );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $ns == NS_CATEGORY ) {
|
2008-03-19 11:19:00 +00:00
|
|
|
$addFields[] = 'cat_subcats = cat_subcats + 1';
|
|
|
|
|
$removeFields[] = 'cat_subcats = cat_subcats - 1';
|
2010-02-14 22:07:30 +00:00
|
|
|
} elseif ( $ns == NS_FILE ) {
|
2008-03-19 11:19:00 +00:00
|
|
|
$addFields[] = 'cat_files = cat_files + 1';
|
|
|
|
|
$removeFields[] = 'cat_files = cat_files - 1';
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
}
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $added ) {
|
2008-03-19 11:19:00 +00:00
|
|
|
$dbw->update(
|
|
|
|
|
'category',
|
|
|
|
|
$addFields,
|
|
|
|
|
array( 'cat_title' => $added ),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
|
|
|
|
}
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $deleted ) {
|
2008-03-19 11:19:00 +00:00
|
|
|
$dbw->update(
|
|
|
|
|
'category',
|
|
|
|
|
$removeFields,
|
|
|
|
|
array( 'cat_title' => $deleted ),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
|
|
|
|
}
|
This is a schema change. It's only a table creation, but the table must be created on Wikimedia servers before this revision goes live. The maintenance script populateCategory.php should be run when convenient. If it's not run, there's only one substantial case where display will be harmed: the page of a category with more than 200 net pages added since the patch goes live will give an erroneously low count. In other cases category pages will just be better-worded, and it will recognize the count in the table is bogus.
* Adds Category and CategoryList classes to represent categories themselves.
* Adds a category table, giving each category a name, ID, and counts of all members, subcats only, and files.
* Adds a maintenance script to populate the category table efficiently. This script is careful to wait for slaves and should be safe to run on a live database. The maintenance script's includes file is called by update.php.
* Until the category table is populated, the patch handles weird category table rows gracefully. It detects whether they're obviously impossible, and if so, it outputs appropriate messages.
2008-03-18 00:17:28 +00:00
|
|
|
}
|
2009-12-26 20:03:33 +00:00
|
|
|
|
2010-03-15 12:04:24 +00:00
|
|
|
/**
|
|
|
|
|
* Lightweight method to get the parser output for a page, checking the parser cache
|
2009-12-26 20:03:33 +00:00
|
|
|
* and so on. Doesn't consider most of the stuff that Article::view is forced to
|
|
|
|
|
* consider, so it's not appropriate to use there.
|
2010-03-15 12:04:24 +00:00
|
|
|
*
|
2010-08-07 22:17:00 +00:00
|
|
|
* @since 1.16 (r52326) for LiquidThreads
|
2010-12-13 19:47:34 +00:00
|
|
|
*
|
2010-03-15 12:04:24 +00:00
|
|
|
* @param $oldid mixed integer Revision ID or null
|
2011-03-05 17:55:21 +00:00
|
|
|
* @return ParserOutput or false if the given revsion ID is not found
|
2009-12-26 20:03:33 +00:00
|
|
|
*/
|
2010-03-15 12:04:24 +00:00
|
|
|
public function getParserOutput( $oldid = null ) {
|
2010-07-24 19:11:34 +00:00
|
|
|
global $wgEnableParserCache, $wgUser;
|
2009-06-23 21:52:39 +00:00
|
|
|
|
|
|
|
|
// Should the parser cache be used?
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
$useParserCache = $wgEnableParserCache &&
|
2010-08-03 22:32:09 +00:00
|
|
|
$wgUser->getStubThreshold() == 0 &&
|
2010-05-30 14:28:54 +00:00
|
|
|
$this->exists() &&
|
|
|
|
|
$oldid === null;
|
2009-12-26 20:03:33 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( __METHOD__ . ': using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" );
|
2010-05-30 14:28:54 +00:00
|
|
|
|
2010-08-03 22:32:09 +00:00
|
|
|
if ( $wgUser->getStubThreshold() ) {
|
2009-06-23 21:52:39 +00:00
|
|
|
wfIncrStats( 'pcache_miss_stub' );
|
|
|
|
|
}
|
|
|
|
|
|
Implemented the PoolCounter feature and did some general refactoring in the areas that it touched.
* Renamed Article::outputFromWikitext() to Article::getOutputFromWikitext()
* Factored out cascade protection updates
* Removed recently-added Article::tryParserCache(): misnamed, can be done in one line of code in the caller. Deprecated OutputPage::tryParserCache().
* Made some functions public instead of protected when they could be useful from hooks.
* In ParserCache, removed PHP 4-style ampersands
In Article::view():
* Factored out robot policy logic, "redirected from" header, patrol footer, diff page, revdelete header, CSS/JS formatting, footer, namespace header, missing article error
* Removed some variables, renamed some others, fixed incorrect use of empty()
* Used the refactored footer section to do a couple of early returns and unindent a massive if(!$outputDone) block
* Removed fantasy interpretation of $this->getContent()===false in comment
* Don't try the parser cache when ArticleViewHeader specified $outputDone=true
* Move timing hack to getOutputFromWikitext()
* Stop using $wgOut->parserOptions() with save/restore nonsense every time you want to change something in it. This is meant to be OOP.
* Don't overwrite the article text with an error message and then pretend to write it to the cache, that's confusing
2009-07-08 08:12:35 +00:00
|
|
|
if ( $useParserCache ) {
|
|
|
|
|
$parserOutput = ParserCache::singleton()->get( $this, $this->getParserOptions() );
|
2011-03-04 20:16:35 +00:00
|
|
|
if ( $parserOutput !== false ) {
|
|
|
|
|
return $parserOutput;
|
|
|
|
|
}
|
2009-06-23 21:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-04 20:16:35 +00:00
|
|
|
// Cache miss; parse and output it.
|
2011-03-05 17:55:21 +00:00
|
|
|
if ( $oldid === null ) {
|
|
|
|
|
$text = $this->getRawText();
|
|
|
|
|
} else {
|
2009-06-23 21:52:39 +00:00
|
|
|
$rev = Revision::newFromTitle( $this->getTitle(), $oldid );
|
2011-03-05 17:55:21 +00:00
|
|
|
if ( $rev === null ) {
|
|
|
|
|
return false;
|
2011-03-04 20:16:35 +00:00
|
|
|
}
|
2011-03-05 17:55:21 +00:00
|
|
|
$text = $rev->getText();
|
2011-03-04 20:16:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->getOutputFromWikitext( $text, $useParserCache );
|
2009-06-23 21:52:39 +00:00
|
|
|
}
|
2010-06-28 07:17:16 +00:00
|
|
|
|
2011-04-12 23:00:49 +00:00
|
|
|
/**
|
|
|
|
|
* Sets the context this Article is executed in
|
|
|
|
|
*
|
|
|
|
|
* @param $context RequestContext
|
|
|
|
|
* @since 1.18
|
|
|
|
|
*/
|
|
|
|
|
public function setContext( $context ) {
|
|
|
|
|
$this->mContext = $context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the context this Article is executed in
|
|
|
|
|
*
|
|
|
|
|
* @return RequestContext
|
|
|
|
|
* @since 1.18
|
|
|
|
|
*/
|
|
|
|
|
public function getContext() {
|
|
|
|
|
if ( $this->mContext instanceof RequestContext ) {
|
|
|
|
|
return $this->mContext;
|
|
|
|
|
} else {
|
|
|
|
|
wfDebug( __METHOD__ . " called and \$mContext is null. Return RequestContext::getMain(); for sanity\n" );
|
|
|
|
|
return RequestContext::getMain();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-22 14:45:12 +00:00
|
|
|
}
|
2010-08-27 20:57:32 +00:00
|
|
|
|
|
|
|
|
class PoolWorkArticleView extends PoolCounterWork {
|
2011-04-25 11:59:31 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Article
|
|
|
|
|
*/
|
2010-08-27 20:57:32 +00:00
|
|
|
private $mArticle;
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
function __construct( $article, $key, $useParserCache, $parserOptions ) {
|
2010-09-15 19:49:40 +00:00
|
|
|
parent::__construct( 'ArticleView', $key );
|
2010-08-27 20:57:32 +00:00
|
|
|
$this->mArticle = $article;
|
|
|
|
|
$this->cacheable = $useParserCache;
|
|
|
|
|
$this->parserOptions = $parserOptions;
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
function doWork() {
|
|
|
|
|
return $this->mArticle->doViewParse();
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
function getCachedWork() {
|
|
|
|
|
global $wgOut;
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
$parserCache = ParserCache::singleton();
|
|
|
|
|
$this->mArticle->mParserOutput = $parserCache->get( $this->mArticle, $this->parserOptions );
|
|
|
|
|
|
|
|
|
|
if ( $this->mArticle->mParserOutput !== false ) {
|
|
|
|
|
wfDebug( __METHOD__ . ": showing contents parsed by someone else\n" );
|
|
|
|
|
$wgOut->addParserOutput( $this->mArticle->mParserOutput );
|
|
|
|
|
# Ensure that UI elements requiring revision ID have
|
|
|
|
|
# the correct version information.
|
|
|
|
|
$wgOut->setRevisionId( $this->mArticle->getLatest() );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
function fallback() {
|
|
|
|
|
return $this->mArticle->tryDirtyCache();
|
|
|
|
|
}
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2011-04-25 11:59:31 +00:00
|
|
|
/**
|
|
|
|
|
* @param $status Status
|
|
|
|
|
*/
|
2010-08-27 20:57:32 +00:00
|
|
|
function error( $status ) {
|
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
|
|
$wgOut->clearHTML(); // for release() errors
|
|
|
|
|
$wgOut->enableClientCache( false );
|
|
|
|
|
$wgOut->setRobotPolicy( 'noindex,nofollow' );
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-09-15 21:03:07 +00:00
|
|
|
$errortext = $status->getWikiText( false, 'view-pool-error' );
|
2010-08-27 20:57:32 +00:00
|
|
|
$wgOut->addWikiText( '<div class="errorbox">' . $errortext . '</div>' );
|
2010-12-13 19:47:34 +00:00
|
|
|
|
2010-08-27 20:57:32 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|