From a1789ddde42033f1b05cc4929491214ee6e79383 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Thu, 17 Dec 2015 09:15:42 +0100 Subject: Update to MediaWiki 1.26.0 --- includes/page/Article.php | 129 +++++++++----- includes/page/ImagePage.php | 35 +++- includes/page/WikiPage.php | 417 +++++++++++++++++++++++--------------------- 3 files changed, 322 insertions(+), 259 deletions(-) (limited to 'includes/page') diff --git a/includes/page/Article.php b/includes/page/Article.php index 4cde5ad8..56b9520a 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -333,7 +333,9 @@ class Article implements Page { * @return string|bool String containing article contents, or false if null * @deprecated since 1.21, use WikiPage::getContent() instead */ - function fetchContent() { #BC cruft! + function fetchContent() { + // BC cruft! + ContentHandler::deprecated( __METHOD__, '1.21' ); if ( $this->mContentLoaded && $this->mContent ) { @@ -572,7 +574,7 @@ class Article implements Page { } # Should the parser cache be used? - $useParserCache = $this->mPage->isParserCacheUsed( $parserOptions, $oldid ); + $useParserCache = $this->mPage->shouldCheckParserCache( $parserOptions, $oldid ); wfDebug( 'Article::view using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" ); if ( $user->getStubThreshold() ) { $this->getContext()->getStats()->increment( 'pcache_miss_stub' ); @@ -998,7 +1000,7 @@ class Article implements Page { $outputPage->addModules( 'mediawiki.action.view.redirect' ); // Add a tag - $outputPage->setCanonicalUrl( $this->getTitle()->getLocalURL() ); + $outputPage->setCanonicalUrl( $this->getTitle()->getCanonicalURL() ); // Tell the output object that the user arrived at this article through a redirect $outputPage->setRedirectedFrom( $this->mRedirectedFrom ); @@ -1089,11 +1091,6 @@ class Article implements Page { // to get the recentchanges row belonging to that entry // (with rc_new = 1). - // Check for cached results - if ( $cache->get( wfMemcKey( 'NotPatrollablePage', $this->getTitle()->getArticleID() ) ) ) { - return false; - } - if ( $this->mRevision && !RecentChange::isInRCLifespan( $this->mRevision->getTimestamp(), 21600 ) ) { @@ -1102,6 +1099,12 @@ class Article implements Page { return false; } + // Check for cached results + $key = wfMemcKey( 'NotPatrollablePage', $this->getTitle()->getArticleID() ); + if ( $cache->get( $key ) ) { + return false; + } + $dbr = wfGetDB( DB_SLAVE ); $oldestRevisionTimestamp = $dbr->selectField( 'revision', @@ -1119,20 +1122,30 @@ class Article implements Page { 'rc_new' => 1, 'rc_timestamp' => $oldestRevisionTimestamp, 'rc_namespace' => $this->getTitle()->getNamespace(), - 'rc_cur_id' => $this->getTitle()->getArticleID(), - 'rc_patrolled' => 0 + 'rc_cur_id' => $this->getTitle()->getArticleID() ), __METHOD__, array( 'USE INDEX' => 'new_name_timestamp' ) ); + } else { + // Cache the information we gathered above in case we can't patrol + // Don't cache in case we can patrol as this could change + $cache->set( $key, '1' ); } if ( !$rc ) { - // No RC entry around + // Don't cache: This can be hit if the page gets accessed very fast after + // its creation or in case we have high slave lag. In case the revision is + // too old, we will already return above. + return false; + } + + if ( $rc->getAttribute( 'rc_patrolled' ) ) { + // Patrolled RC entry around // Cache the information we gathered above in case we can't patrol // Don't cache in case we can patrol as this could change - $cache->set( wfMemcKey( 'NotPatrollablePage', $this->getTitle()->getArticleID() ), '1' ); + $cache->set( $key, '1' ); return false; } @@ -1222,23 +1235,38 @@ class Article implements Page { Hooks::run( 'ShowMissingArticle', array( $this ) ); - // Give extensions a chance to hide their (unrelated) log entries - $logTypes = array( 'delete', 'move' ); - $conds = array( "log_action != 'revision'" ); - Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) ); - - # Show delete and move logs - LogEventsList::showLogExtract( $outputPage, $logTypes, $title, '', - array( 'lim' => 10, - 'conds' => $conds, - 'showIfEmpty' => false, - 'msgKey' => array( 'moveddeleted-notice' ) ) - ); + # Show delete and move logs if there were any such events. + # The logging query can DOS the site when bots/crawlers cause 404 floods, + # so be careful showing this. 404 pages must be cheap as they are hard to cache. + $cache = ObjectCache::getMainStashInstance(); + $key = wfMemcKey( 'page-recent-delete', md5( $title->getPrefixedText() ) ); + $loggedIn = $this->getContext()->getUser()->isLoggedIn(); + if ( $loggedIn || $cache->get( $key ) ) { + $logTypes = array( 'delete', 'move' ); + $conds = array( "log_action != 'revision'" ); + // Give extensions a chance to hide their (unrelated) log entries + Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) ); + LogEventsList::showLogExtract( + $outputPage, + $logTypes, + $title, + '', + array( + 'lim' => 10, + 'conds' => $conds, + 'showIfEmpty' => false, + 'msgKey' => array( $loggedIn + ? 'moveddeleted-notice' + : 'moveddeleted-notice-recent' + ) + ) + ); + } if ( !$this->mPage->hasViewableContent() && $wgSend404Code && !$validUserPage ) { // If there's no backing content, send a 404 Not Found // for better machine handling of broken links. - $this->getContext()->getRequest()->response()->header( "HTTP/1.1 404 Not Found" ); + $this->getContext()->getRequest()->response()->statusHeader( 404 ); } // Also apply the robot policy for nonexisting pages (even if a 404 was used for sanity) @@ -1254,22 +1282,28 @@ class Article implements Page { # Show error message $oldid = $this->getOldID(); - if ( $oldid ) { - $text = wfMessage( 'missing-revision', $oldid )->plain(); - } elseif ( $title->getNamespace() === NS_MEDIAWIKI ) { - // Use the default message text - $text = $title->getDefaultMessageText(); - } elseif ( $title->quickUserCan( 'create', $this->getContext()->getUser() ) - && $title->quickUserCan( 'edit', $this->getContext()->getUser() ) - ) { - $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon'; - $text = wfMessage( $message )->plain(); + if ( !$oldid && $title->getNamespace() === NS_MEDIAWIKI && $title->hasSourceText() ) { + $outputPage->addParserOutput( $this->getContentObject()->getParserOutput( $title ) ); } else { - $text = wfMessage( 'noarticletext-nopermission' )->plain(); - } - $text = "
\n$text\n
"; + if ( $oldid ) { + $text = wfMessage( 'missing-revision', $oldid )->plain(); + } elseif ( $title->quickUserCan( 'create', $this->getContext()->getUser() ) + && $title->quickUserCan( 'edit', $this->getContext()->getUser() ) + ) { + $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon'; + $text = wfMessage( $message )->plain(); + } else { + $text = wfMessage( 'noarticletext-nopermission' )->plain(); + } - $outputPage->addWikiText( $text ); + $dir = $this->getContext()->getLanguage()->getDir(); + $lang = $this->getContext()->getLanguage()->getCode(); + $outputPage->addWikiText( Xml::openElement( 'div', array( + 'class' => "noarticletext mw-content-$dir", + 'dir' => $dir, + 'lang' => $lang, + ) ) . "\n$text\n" ); + } } /** @@ -1704,10 +1738,8 @@ class Article implements Page { if ( $user->isAllowed( 'suppressrevision' ) ) { $suppress = Html::openElement( 'div', array( 'id' => 'wpDeleteSuppressRow' ) ) . - "" . - Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(), - 'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) . - "" . + Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(), + 'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) . Html::closeElement( 'div' ); } else { $suppress = ''; @@ -1772,9 +1804,8 @@ class Article implements Page { Xml::closeElement( 'form' ); if ( $user->isAllowed( 'editinterface' ) ) { - $dropdownTitle = Title::makeTitle( NS_MEDIAWIKI, 'Deletereason-dropdown' ); - $link = Linker::link( - $dropdownTitle, + $link = Linker::linkKnown( + $ctx->msg( 'deletereason-dropdown' )->inContentLanguage()->getTitle(), wfMessage( 'delete-edit-reasonlist' )->escaped(), array(), array( 'action' => 'edit' ) @@ -1796,8 +1827,10 @@ class Article implements Page { */ public function doDelete( $reason, $suppress = false ) { $error = ''; - $outputPage = $this->getContext()->getOutput(); - $status = $this->mPage->doDeleteArticleReal( $reason, $suppress, 0, true, $error ); + $context = $this->getContext(); + $outputPage = $context->getOutput(); + $user = $context->getUser(); + $status = $this->mPage->doDeleteArticleReal( $reason, $suppress, 0, true, $error, $user ); if ( $status->isGood() ) { $deleted = $this->getTitle()->getPrefixedText(); diff --git a/includes/page/ImagePage.php b/includes/page/ImagePage.php index 8f635cfa..9b9e3cbd 100644 --- a/includes/page/ImagePage.php +++ b/includes/page/ImagePage.php @@ -219,6 +219,9 @@ class ImagePage extends Article { } // always show the local local Filepage.css, bug 29277 $out->addModuleStyles( 'filepage' ); + + // Add MediaWiki styles for a file page + $out->addModuleStyles( 'mediawiki.action.view.filepage' ); } /** @@ -296,7 +299,7 @@ class ImagePage extends Article { } protected function openShowImage() { - global $wgEnableUploads, $wgSend404Code; + global $wgEnableUploads, $wgSend404Code, $wgSVGMaxSize; $this->loadFile(); $out = $this->getContext()->getOutput(); @@ -351,7 +354,7 @@ class ImagePage extends Article { ); $linktext = $this->getContext()->msg( 'show-big-image' )->escaped(); - $thumbSizes = $this->getThumbSizes( $width, $height, $width_orig, $height_orig ); + $thumbSizes = $this->getThumbSizes( $width_orig, $height_orig ); # Generate thumbnails or thumbnail links as needed... $otherSizes = array(); foreach ( $thumbSizes as $size ) { @@ -361,10 +364,12 @@ class ImagePage extends Article { // the current thumbnail's size ($width/$height) // since that is added to the message separately, so // it can be denoted as the current size being shown. - // Vectorized images are "infinitely" big, so all thumb - // sizes are shown. + // Vectorized images are limited by $wgSVGMaxSize big, + // so all thumbs less than or equal that are shown. if ( ( ( $size[0] <= $width_orig && $size[1] <= $height_orig ) - || $this->displayImg->isVectorized() ) + || ( $this->displayImg->isVectorized() + && max( $size[0], $size[1] ) <= $wgSVGMaxSize ) + ) && $size[0] != $width && $size[1] != $height ) { $sizeLink = $this->makeSizeLink( $params, $size[0], $size[1] ); @@ -614,8 +619,8 @@ EOT $out->wrapWikiMsg( "", $nofile ); if ( !$this->getID() && $wgSend404Code ) { // If there is no image, no shared image, and no description page, - // output a 404, to be consistent with articles. - $request->response()->header( 'HTTP/1.1 404 Not Found' ); + // output a 404, to be consistent with Article::showMissingArticle. + $request->response()->statusHeader( 404 ); } } $out->setFileVersion( $this->displayImg ); @@ -704,10 +709,10 @@ EOT $out->addHTML( "