Page MenuHomePhabricator

bug14900-2.txt

Authored By
bzimport
Nov 21 2014, 10:13 PM
Size
20 KB
Referenced Files
None
Subscribers
None

bug14900-2.txt

Index: trunk/phase3/includes/Article.php
===================================================================
--- trunk/phase3/includes/Article.php (revision 53416)
+++ trunk/phase3/includes/Article.php (working copy)
@@ -41,6 +41,7 @@
var $mUser = -1; //!< Not loaded
var $mUserText = ''; //!<
var $mParserOptions; //!<
+ var $mParserOutput; //!<
/**@}}*/
/**
@@ -772,7 +773,6 @@
}
$wgOut->setArticleFlag( true );
- $wgOut->setRobotPolicy( $this->getRobotPolicyForView() );
# Set page title (may be overridden by DISPLAYTITLE)
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
@@ -804,108 +804,121 @@
$this->showNamespaceHeader();
$outputDone = false;
- wfRunHooks( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
- # Try the parser cache
- if( !$outputDone && $useParserCache ) {
- $parserOutput = $parserCache->get( $this, $parserOptions );
- if ( $parserOutput !== false ) {
- wfDebug( __METHOD__.": showing parser cache contents\n" );
- $wgOut->addParserOutput( $parserOutput );
- // Ensure that UI elements requiring revision ID have
- // the correct version information.
- $wgOut->setRevisionId( $this->mLatest );
- $outputDone = true;
- }
- }
+ # Iterate through the possible ways of constructing the output text
+ $pass = 0;
+ while( !$outputDone && ++$pass ){
+ switch( $pass ){
- if ( $outputDone ) {
- $this->showViewFooter();
- $this->viewUpdates();
- wfProfileOut( __METHOD__ );
- return;
- }
+ case 1:
+ wfRunHooks( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
+ break;
- $text = $this->getContent();
- if( $text === false || $this->getID() == 0 ) {
- wfDebug( __METHOD__.": showing missing article\n" );
- $this->showMissingArticle();
- wfProfileOut( __METHOD__ );
- return;
- }
+ case 2:
+ # Try the parser cache
+ if( $useParserCache ) {
+ $this->mParserOutput = $parserCache->get( $this, $parserOptions );
+ if ( $this->mParserOutput !== false ) {
+ wfDebug( __METHOD__.": showing parser cache contents\n" );
+ $wgOut->addParserOutput( $this->mParserOutput );
+ // Ensure that UI elements requiring revision ID have
+ // the correct version information.
+ $wgOut->setRevisionId( $this->mLatest );
+ $outputDone = true;
+ }
+ }
+ break;
- # Another whitelist check in case oldid is altering the title
- if( !$this->mTitle->userCanRead() ) {
- wfDebug( __METHOD__.": denied on secondary read check\n" );
- $wgOut->loginToUse();
- $wgOut->output();
- $wgOut->disable();
- wfProfileOut( __METHOD__ );
- return;
- }
+ case 3:
+ $text = $this->getContent();
+ if( $text === false || $this->getID() == 0 ) {
+ wfDebug( __METHOD__.": showing missing article\n" );
+ $this->showMissingArticle();
+ wfProfileOut( __METHOD__ );
+ return;
+ }
- # We're looking at an old revision
- if( $oldid && !is_null( $this->mRevision ) ) {
- $this->setOldSubtitle( $oldid );
- if ( !$this->showDeletedRevisionHeader() ) {
- wfDebug( __METHOD__.": cannot view deleted revision\n" );
- wfProfileOut( __METHOD__ );
- return;
- }
+ # Another whitelist check in case oldid is altering the title
+ if( !$this->mTitle->userCanRead() ) {
+ wfDebug( __METHOD__.": denied on secondary read check\n" );
+ $wgOut->loginToUse();
+ $wgOut->output();
+ $wgOut->disable();
+ wfProfileOut( __METHOD__ );
+ return;
+ }
- if ( $oldid === $this->getLatest() && $this->useParserCache( false ) ) {
- $parserOutput = $parserCache->get( $this, $parserOptions );
- if ( $parserOutput ) {
- wfDebug( __METHOD__.": showing parser cache for current rev permalink\n" );
- $wgOut->addParserOutput( $parserOutput );
- $this->showViewFooter();
- $this->viewUpdates();
- wfProfileOut( __METHOD__ );
- return;
- }
- }
- }
+ # We're looking at an old revision
+ if( $oldid && !is_null( $this->mRevision ) ) {
+ $this->setOldSubtitle( $oldid );
+ if ( !$this->showDeletedRevisionHeader() ) {
+ wfDebug( __METHOD__.": cannot view deleted revision\n" );
+ wfProfileOut( __METHOD__ );
+ return;
+ }
- // Ensure that UI elements requiring revision ID have
- // the correct version information.
- $wgOut->setRevisionId( $this->getRevIdFetched() );
+ if ( $oldid === $this->getLatest() && $this->useParserCache( false ) ) {
+ $this->mParserOutput = $parserCache->get( $this, $parserOptions );
+ if ( $this->mParserOutput ) {
+ wfDebug( __METHOD__.": showing parser cache for current rev permalink\n" );
+ $wgOut->addParserOutput( $this->mParserOutput );
+ $this->showViewFooter();
+ $this->viewUpdates();
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+ }
+ }
- // Pages containing custom CSS or JavaScript get special treatment
- if( $this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage() ) {
- wfDebug( __METHOD__.": showing CSS/JS source\n" );
- $this->showCssOrJsPage();
- $outputDone = true;
- } else if( $rt = Title::newFromRedirectArray( $text ) ) {
- 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.
- $parserOutput = $wgParser->parse( $text, $this->mTitle, $parserOptions );
- $wgOut->addParserOutputNoText( $parserOutput );
- $outputDone = true;
- }
- if ( $outputDone ) {
- $this->showViewFooter();
- $this->viewUpdates();
- wfProfileOut( __METHOD__ );
- return;
- }
+ // Ensure that UI elements requiring revision ID have
+ // the correct version information.
+ $wgOut->setRevisionId( $this->getRevIdFetched() );
- # Run the parse, protected by a pool counter
- wfDebug( __METHOD__.": doing uncached parse\n" );
- $key = $parserCache->getKey( $this, $parserOptions );
- $poolCounter = PoolCounter::factory( 'Article::view', $key );
- $dirtyCallback = $useParserCache ? array( $this, 'tryDirtyCache' ) : false;
- $status = $poolCounter->executeProtected( array( $this, 'doViewParse' ), $dirtyCallback );
+ // Pages containing custom CSS or JavaScript get special treatment
+ if( $this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage() ) {
+ wfDebug( __METHOD__.": showing CSS/JS source\n" );
+ $this->showCssOrJsPage();
+ $outputDone = true;
+ } else if( $rt = Title::newFromRedirectArray( $text ) ) {
+ 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;
+ }
+ break;
- if ( !$status->isOK() ) {
- # Connection or timeout error
- $this->showPoolError( $status );
- wfProfileOut( __METHOD__ );
- return;
+ case 4:
+ # Run the parse, protected by a pool counter
+ wfDebug( __METHOD__.": doing uncached parse\n" );
+ $key = $parserCache->getKey( $this, $parserOptions );
+ $poolCounter = PoolCounter::factory( 'Article::view', $key );
+ $dirtyCallback = $useParserCache ? array( $this, 'tryDirtyCache' ) : false;
+ $status = $poolCounter->executeProtected( array( $this, 'doViewParse' ), $dirtyCallback );
+
+ if ( !$status->isOK() ) {
+ # Connection or timeout error
+ $this->showPoolError( $status );
+ wfProfileOut( __METHOD__ );
+ return;
+ } else {
+ $outputDone = true;
+ }
+ break;
+
+ # Should be unreachable, but just in case...
+ default:
+ break 2;
+ }
}
+ # Now that we've filled $this->mParserOutput, we know whether
+ # there are any __NOINDEX__ tags on the page
+ $this->setRobotPolicyForView();
+
$this->showViewFooter();
$this->viewUpdates();
wfProfileOut( __METHOD__ );
@@ -961,9 +974,10 @@
}
/**
- * Get the robot policy to be used for the current action=view request.
+ * Set the robot policy to be used for the current action=view request.
+ * @return String the policy that was set
*/
- public function getRobotPolicyForView() {
+ public function setRobotPolicyForView() {
global $wgOut, $wgArticleRobotPolicies, $wgNamespaceRobotPolicies;
global $wgDefaultRobotPolicy, $wgRequest;
@@ -973,32 +987,92 @@
if( !$this->mTitle->isSubpage() ) {
$block = new Block();
if( $block->load( $this->mTitle->getText() ) ) {
- return 'noindex,nofollow';
+ $wgOut->setIndexPolicy( 'noindex' );
+ $wgOut->setFollowPolicy( 'nofollow' );
+ return array( 'index' => 'noindex',
+ 'follow' => 'nofollow' );
}
}
}
if( $this->getID() === 0 || $this->getOldID() ) {
- return 'noindex,nofollow';
+ # Non-articles (special pages etc), and old revisions
+ $wgOut->setIndexPolicy( 'noindex' );
+ $wgOut->setFollowPolicy( 'nofollow' );
+ return array( 'index' => 'noindex',
+ 'follow' => 'nofollow' );
} elseif( $wgOut->isPrintable() ) {
# Discourage indexing of printable versions, but encourage following
- return 'noindex,follow';
+ $wgOut->setIndexPolicy( 'noindex' );
+ $wgOut->setFollowPolicy( 'follow' );
+ return array( 'index' => 'noindex',
+ 'follow' => 'follow' );
} elseif( $wgRequest->getInt('curid') ) {
# For ?curid=x urls, disallow indexing
- return 'noindex,follow';
- } elseif( isset( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] ) ) {
- return $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()];
- } elseif( isset( $wgNamespaceRobotPolicies[$ns] ) ) {
+ $wgOut->setIndexPolicy( 'noindex' );
+ $wgOut->setFollowPolicy( 'follow' );
+ return array( 'index' => 'noindex',
+ 'follow' => 'follow' );
+ }
+
+ # Otherwise, construct the policy based on the various config variables.
+ $policy = self::formatRobotPolicy( $wgDefaultRobotPolicy );
+
+ if( isset( $wgNamespaceRobotPolicies[$ns] ) ){
# Honour customised robot policies for this namespace
- return $wgNamespaceRobotPolicies[$ns];
- } else {
- return $wgDefaultRobotPolicy;
+ $policy = array_merge( $policy,
+ self::formatRobotPolicy( $wgNamespaceRobotPolicies[$ns] ) );
}
+
+ if( $this->mTitle->canUseNoindex() && $this->mParserOutput->getIndexPolicy() ){
+ # __INDEX__ and __NOINDEX__ magic words, if allowed.
+ $policy = array_merge( $policy,
+ array( 'index' => $this->mParserOutput->getIndexPolicy() ) );
+ }
+
+ if( isset( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] ) ){
+ # (bug 14900) site config can override user-defined __INDEX__ or __NOINDEX__
+ $policy = array_merge( $policy,
+ self::formatRobotPolicy( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] ) );
+ }
+
+ $wgOut->setIndexPolicy( $policy['index'] );
+ $wgOut->setFollowPolicy( $policy['follow'] );
+ return $policy;
+
}
/**
- * 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
+ * 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.
+ * @return associative Array: 'index' => <indexpolicy>, 'follow' => <followpolicy>
+ */
+ public static function formatRobotPolicy( $policy ){
+ if( is_array( $policy ) ){
+ return $policy;
+ } elseif( !$policy ){
+ return array();
+ }
+
+ $policy = explode( ',', $policy );
+ $policy = array_map( 'trim', $policy );
+
+ $arr = array();
+ foreach( $policy as $var ){
+ if( in_array( $var, array('index','noindex') ) ){
+ $arr['index'] = $var;
+ } elseif( in_array( $var, array('follow','nofollow') ) ){
+ $arr['follow'] = $var;
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * 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
* redirect view. Handles both local and remote redirects.
*/
public function showRedirectedFromHeader() {
@@ -3835,11 +3909,11 @@
*/
public function outputWikiText( $text, $cache = true, $parserOptions = false ) {
global $wgOut;
-
- $parserOutput = $this->getOutputFromWikitext( $text, $cache, $parserOptions );
- $wgOut->addParserOutput( $parserOutput );
+
+ $this->mParserOutput = $this->getOutputFromWikitext( $text, $cache, $parserOptions );
+ $wgOut->addParserOutput( $this->mParserOutput );
}
-
+
/**
* 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,
@@ -3853,7 +3927,7 @@
}
$time = -wfTime();
- $parserOutput = $wgParser->parse( $text, $this->mTitle,
+ $this->mParserOutput = $wgParser->parse( $text, $this->mTitle,
$parserOptions, true, true, $this->getRevIdFetched() );
$time += wfTime();
@@ -3863,18 +3937,18 @@
$this->mTitle->getPrefixedDBkey()));
}
- if( $wgEnableParserCache && $cache && $this && $parserOutput->getCacheTime() != -1 ) {
+ if( $wgEnableParserCache && $cache && $this && $this->mParserOutput->getCacheTime() != -1 ) {
$parserCache = ParserCache::singleton();
- $parserCache->save( $parserOutput, $this, $parserOptions );
+ $parserCache->save( $this->mParserOutput, $this, $parserOptions );
}
// Make sure file cache is not used on uncacheable content.
// Output that has magic words in it can still use the parser cache
// (if enabled), though it will generally expire sooner.
- if( $parserOutput->getCacheTime() == -1 || $parserOutput->containsOldMagic() ) {
+ if( $this->mParserOutput->getCacheTime() == -1 || $this->mParserOutput->containsOldMagic() ) {
$wgUseFileCache = false;
}
- $this->doCascadeProtectionUpdates( $parserOutput );
- return $parserOutput;
+ $this->doCascadeProtectionUpdates( $this->mParserOutput );
+ return $this->mParserOutput;
}
/**
Index: trunk/phase3/includes/parser/Parser.php
===================================================================
--- trunk/phase3/includes/parser/Parser.php (revision 53416)
+++ trunk/phase3/includes/parser/Parser.php (working copy)
@@ -3393,28 +3393,43 @@
}
if ( isset( $this->mDoubleUnderscores['hiddencat'] ) && $this->mTitle->getNamespace() == NS_CATEGORY ) {
$this->mOutput->setProperty( 'hiddencat', 'y' );
-
- $containerCategory = Title::makeTitleSafe( NS_CATEGORY, wfMsgForContent( 'hidden-category-category' ) );
- if ( $containerCategory ) {
- $this->mOutput->addCategory( $containerCategory->getDBkey(), $this->getDefaultSort() );
- } else {
- wfDebug( __METHOD__.": [[MediaWiki:hidden-category-category]] is not a valid title!\n" );
- }
+ $this->addTrackingCategory( 'hidden-category-category' );
}
# (bug 8068) Allow control over whether robots index a page.
#
# FIXME (bug 14899): __INDEX__ always overrides __NOINDEX__ here! This
# is not desirable, the last one on the page should win.
- if( isset( $this->mDoubleUnderscores['noindex'] ) ) {
+ if( isset( $this->mDoubleUnderscores['noindex'] ) && $this->mTitle->canUseNoindex() ){
$this->mOutput->setIndexPolicy( 'noindex' );
- } elseif( isset( $this->mDoubleUnderscores['index'] ) ) {
+ $this->addTrackingCategory( 'noindex-category' );
+ }
+ if( isset( $this->mDoubleUnderscores['index'] ) && $this->mTitle->canUseNoindex() ){
$this->mOutput->setIndexPolicy( 'index' );
+ $this->addTrackingCategory( 'index-category' );
}
+
wfProfileOut( __METHOD__ );
return $text;
}
/**
+ * Add a tracking category, getting the title from a system message,
+ * or print a debug message if the title is invalid.
+ * @param $msg String message key
+ * @return Bool whether the addition was successful
+ */
+ protected function addTrackingCategory( $msg ){
+ $containerCategory = Title::makeTitleSafe( NS_CATEGORY, wfMsgForContent( $msg ) );
+ if ( $containerCategory ) {
+ $this->mOutput->addCategory( $containerCategory->getDBkey(), $this->getDefaultSort() );
+ return true;
+ } else {
+ wfDebug( __METHOD__.": [[MediaWiki:$msg]] is not a valid title!\n" );
+ return false;
+ }
+ }
+
+ /**
* This function accomplishes several tasks:
* 1) Auto-number headings if that option is enabled
* 2) Add an [edit] link to sections for users who have enabled the option and can edit the page
Index: trunk/phase3/includes/OutputPage.php
===================================================================
--- trunk/phase3/includes/OutputPage.php (revision 53416)
+++ trunk/phase3/includes/OutputPage.php (working copy)
@@ -451,21 +451,13 @@
* @return null
*/
public function setRobotPolicy( $policy ) {
- $policy = explode( ',', $policy );
- $policy = array_map( 'trim', $policy );
+ $policy = Article::formatRobotPolicy( $policy );
- # The default policy is follow, so if nothing is said explicitly, we
- # do that.
- if( in_array( 'nofollow', $policy ) ) {
- $this->mFollowPolicy = 'nofollow';
- } else {
- $this->mFollowPolicy = 'follow';
+ if( isset( $policy['index'] ) ){
+ $this->setIndexPolicy( $policy['index'] );
}
-
- if( in_array( 'noindex', $policy ) ) {
- $this->mIndexPolicy = 'noindex';
- } else {
- $this->mIndexPolicy = 'index';
+ if( isset( $policy['follow'] ) ){
+ $this->setFollowPolicy( $policy['follow'] );
}
}
@@ -738,17 +730,6 @@
$this->mNewSectionLink = $parserOutput->getNewSection();
$this->mHideNewSectionLink = $parserOutput->getHideNewSection();
- if( is_null( $wgExemptFromUserRobotsControl ) ) {
- $bannedNamespaces = $wgContentNamespaces;
- } else {
- $bannedNamespaces = $wgExemptFromUserRobotsControl;
- }
- if( !in_array( $this->getTitle()->getNamespace(), $bannedNamespaces ) ) {
- # FIXME (bug 14900): This overrides $wgArticleRobotPolicies, and it
- # shouldn't
- $this->setIndexPolicy( $parserOutput->getIndexPolicy() );
- }
-
$this->addKeywords( $parserOutput );
$this->mParseWarnings = $parserOutput->getWarnings();
if ( $parserOutput->getCacheTime() == -1 ) {
Index: trunk/phase3/includes/Title.php
===================================================================
--- trunk/phase3/includes/Title.php (revision 53416)
+++ trunk/phase3/includes/Title.php (working copy)
@@ -3646,4 +3646,21 @@
}
return $this->mBacklinkCache;
}
+
+ /**
+ * Whether the magic words __INDEX__ and __NOINDEX__ function for
+ * this page.
+ * @return Bool
+ */
+ public function canUseNoindex(){
+ global $wgArticleRobotPolicies, $wgContentNamespaces,
+ $wgExemptFromUserRobotsControl;
+
+ $bannedNamespaces = is_null( $wgExemptFromUserRobotsControl )
+ ? $wgContentNamespaces
+ : $wgExemptFromUserRobotsControl;
+
+ return !in_array( $this->mNamespace, $bannedNamespaces );
+
+ }
}
Index: trunk/phase3/includes/DefaultSettings.php
===================================================================
--- trunk/phase3/includes/DefaultSettings.php (revision 53416)
+++ trunk/phase3/includes/DefaultSettings.php (working copy)
@@ -3875,8 +3875,11 @@
$wgExceptionHooks = array();
/**
- * Page property link table invalidation lists. Should only be set by exten-
- * sions.
+ * Page property link table invalidation lists. When a page property
+ * changes, this may require other link tables to be updated (eg
+ * adding __HIDDENCAT__ means the hiddencat tracking category will
+ * have been added, so the categorylinks table needs to be rebuilt).
+ * This array can be added to by extensions.
*/
$wgPagePropLinkInvalidations = array(
'hiddencat' => 'categorylinks',

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4520
Default Alt Text
bug14900-2.txt (20 KB)

Event Timeline