Don't show patrol links if RCP/NPP are disabled, but file patrol isn't
[lhc/web/wiklou.git] / includes / page / Article.php
index c9af075..6ce8cc1 100644 (file)
@@ -118,7 +118,7 @@ class Article implements Page {
                }
 
                $page = null;
-               Hooks::run( 'ArticleFromTitle', array( &$title, &$page, $context ) );
+               Hooks::run( 'ArticleFromTitle', [ &$title, &$page, $context ] );
                if ( !$page ) {
                        switch ( $title->getNamespace() ) {
                                case NS_FILE:
@@ -283,7 +283,7 @@ class Article implements Page {
                                if ( $this->mRevision !== null ) {
                                        // Revision title doesn't match the page title given?
                                        if ( $this->mPage->getID() != $this->mRevision->getPage() ) {
-                                               $function = array( get_class( $this->mPage ), 'newFromID' );
+                                               $function = [ get_class( $this->mPage ), 'newFromID' ];
                                                $this->mPage = call_user_func( $function, $this->mRevision->getPage() );
                                        }
                                }
@@ -340,7 +340,7 @@ class Article implements Page {
 
                // @todo Get rid of mContent everywhere!
                $this->mContent = ContentHandler::getContentText( $content );
-               ContentHandler::runLegacyHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) );
+               ContentHandler::runLegacyHooks( 'ArticleAfterFetchContent', [ &$this, &$this->mContent ] );
 
                return $this->mContent;
        }
@@ -370,7 +370,7 @@ class Article implements Page {
                # Pre-fill content with error message so that if something
                # fails we'll have something telling us what we intended.
                // XXX: this isn't page content but a UI message. horrible.
-               $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ) );
+               $this->mContentObject = new MessageContent( 'missing-revision', [ $oldid ] );
 
                if ( $oldid ) {
                        # $this->mRevision might already be fetched by getOldIDFromRequest()
@@ -390,7 +390,7 @@ class Article implements Page {
                        }
 
                        # Update error message with correct oldid
-                       $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ) );
+                       $this->mContentObject = new MessageContent( 'missing-revision', [ $oldid ] );
 
                        $this->mRevision = $this->mPage->getRevision();
 
@@ -417,7 +417,7 @@ class Article implements Page {
                $this->mContentObject = $content;
                $this->mRevIdFetched = $this->mRevision->getId();
 
-               Hooks::run( 'ArticleAfterFetchContentObject', array( &$this, &$this->mContentObject ) );
+               Hooks::run( 'ArticleAfterFetchContentObject', [ &$this, &$this->mContentObject ] );
 
                return $this->mContentObject;
        }
@@ -521,7 +521,7 @@ class Article implements Page {
                # Try client and file cache
                if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
                        if ( $wgUseETag ) {
-                               $outputPage->setETag( $parserCache->getETag( $this, $parserOptions ) );
+                               $outputPage->setETag( $parserCache->getETag( $this->mPage, $parserOptions ) );
                        }
 
                        # Use the greatest of the page's timestamp or the timestamp of any
@@ -582,7 +582,7 @@ class Article implements Page {
                while ( !$outputDone && ++$pass ) {
                        switch ( $pass ) {
                                case 1:
-                                       Hooks::run( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
+                                       Hooks::run( 'ArticleViewHeader', [ &$this, &$outputDone, &$useParserCache ] );
                                        break;
                                case 2:
                                        # Early abort if the page doesn't exist
@@ -595,7 +595,7 @@ class Article implements Page {
 
                                        # Try the parser cache
                                        if ( $useParserCache ) {
-                                               $this->mParserOutput = $parserCache->get( $this, $parserOptions );
+                                               $this->mParserOutput = $parserCache->get( $this->mPage, $parserOptions );
 
                                                if ( $this->mParserOutput !== false ) {
                                                        if ( $oldid ) {
@@ -644,12 +644,12 @@ class Article implements Page {
                                                $this->showCssOrJsPage();
                                                $outputDone = true;
                                        } elseif ( !Hooks::run( 'ArticleContentViewCustom',
-                                                       array( $this->fetchContentObject(), $this->getTitle(), $outputPage ) ) ) {
+                                                       [ $this->fetchContentObject(), $this->getTitle(), $outputPage ] ) ) {
 
                                                # Allow extensions do their own custom view for certain pages
                                                $outputDone = true;
                                        } elseif ( !ContentHandler::runLegacyHooks( 'ArticleViewCustom',
-                                                       array( $this->fetchContentObject(), $this->getTitle(), $outputPage ) ) ) {
+                                                       [ $this->fetchContentObject(), $this->getTitle(), $outputPage ] ) ) {
 
                                                # Allow extensions do their own custom view for certain pages
                                                $outputDone = true;
@@ -823,7 +823,7 @@ class Article implements Page {
                        // Give hooks a chance to customise the output
                        if ( ContentHandler::runLegacyHooks(
                                'ShowRawCssJs',
-                               array( $this->mContentObject, $this->getTitle(), $outputPage ) )
+                               [ $this->mContentObject, $this->getTitle(), $outputPage ] )
                        ) {
                                // If no legacy hooks ran, display the content of the parser output, including RL modules,
                                // but excluding metadata like categories and language links
@@ -856,31 +856,31 @@ class Article implements Page {
                                $specificTarget = $titleText;
                        }
                        if ( Block::newFromTarget( $specificTarget, $vagueTarget ) instanceof Block ) {
-                               return array(
+                               return [
                                        'index' => 'noindex',
                                        'follow' => 'nofollow'
-                               );
+                               ];
                        }
                }
 
                if ( $this->mPage->getID() === 0 || $this->getOldID() ) {
                        # Non-articles (special pages etc), and old revisions
-                       return array(
+                       return [
                                'index' => 'noindex',
                                'follow' => 'nofollow'
-                       );
+                       ];
                } elseif ( $this->getContext()->getOutput()->isPrintable() ) {
                        # Discourage indexing of printable versions, but encourage following
-                       return array(
+                       return [
                                'index' => 'noindex',
                                'follow' => 'follow'
-                       );
+                       ];
                } elseif ( $this->getContext()->getRequest()->getInt( 'curid' ) ) {
                        # For ?curid=x urls, disallow indexing
-                       return array(
+                       return [
                                'index' => 'noindex',
                                'follow' => 'follow'
-                       );
+                       ];
                }
 
                # Otherwise, construct the policy based on the various config variables.
@@ -898,7 +898,7 @@ class Article implements Page {
                        # a final sanity check that we have really got the parser output.
                        $policy = array_merge(
                                $policy,
-                               array( 'index' => $pOutput->getIndexPolicy() )
+                               [ 'index' => $pOutput->getIndexPolicy() ]
                        );
                }
 
@@ -924,17 +924,17 @@ class Article implements Page {
                if ( is_array( $policy ) ) {
                        return $policy;
                } elseif ( !$policy ) {
-                       return array();
+                       return [];
                }
 
                $policy = explode( ',', $policy );
                $policy = array_map( 'trim', $policy );
 
-               $arr = array();
+               $arr = [];
                foreach ( $policy as $var ) {
-                       if ( in_array( $var, array( 'index', 'noindex' ) ) ) {
+                       if ( in_array( $var, [ 'index', 'noindex' ] ) ) {
                                $arr['index'] = $var;
-                       } elseif ( in_array( $var, array( 'follow', 'nofollow' ) ) ) {
+                       } elseif ( in_array( $var, [ 'follow', 'nofollow' ] ) ) {
                                $arr['follow'] = $var;
                        }
                }
@@ -970,12 +970,12 @@ class Article implements Page {
                if ( isset( $this->mRedirectedFrom ) ) {
                        // This is an internally redirected page view.
                        // We'll need a backlink to the source page for navigation.
-                       if ( Hooks::run( 'ArticleViewRedirect', array( &$this ) ) ) {
+                       if ( Hooks::run( 'ArticleViewRedirect', [ &$this ] ) ) {
                                $redir = Linker::linkKnown(
                                        $this->mRedirectedFrom,
                                        null,
-                                       array(),
-                                       array( 'redirect' => 'no' )
+                                       [],
+                                       [ 'redirect' => 'no' ]
                                );
 
                                $outputPage->addSubtitle( "<span class=\"mw-redirectedfrom\">" .
@@ -984,9 +984,9 @@ class Article implements Page {
 
                                // Add the script to update the displayed URL and
                                // set the fragment if one was specified in the redirect
-                               $outputPage->addJsConfigVars( array(
+                               $outputPage->addJsConfigVars( [
                                        'wgInternalRedirectTargetUrl' => $redirectTargetUrl,
-                               ) );
+                               ] );
                                $outputPage->addModules( 'mediawiki.action.view.redirect' );
 
                                // Add a <link rel="canonical"> tag
@@ -1007,9 +1007,9 @@ class Article implements Page {
                                . "</span>" );
 
                                // Add the script to update the displayed URL
-                               $outputPage->addJsConfigVars( array(
+                               $outputPage->addJsConfigVars( [
                                        'wgInternalRedirectTargetUrl' => $redirectTargetUrl,
-                               ) );
+                               ] );
                                $outputPage->addModules( 'mediawiki.action.view.redirect' );
 
                                return true;
@@ -1028,7 +1028,7 @@ class Article implements Page {
                        if ( !wfMessage( 'talkpageheader' )->isDisabled() ) {
                                $this->getContext()->getOutput()->wrapWikiMsg(
                                        "<div class=\"mw-talkpageheader\">\n$1\n</div>",
-                                       array( 'talkpageheader' )
+                                       [ 'talkpageheader' ]
                                );
                        }
                }
@@ -1048,7 +1048,7 @@ class Article implements Page {
                // Show a footer allowing the user to patrol the shown revision or page if possible
                $patrolFooterShown = $this->showPatrolFooter();
 
-               Hooks::run( 'ArticleViewFooter', array( $this, $patrolFooterShown ) );
+               Hooks::run( 'ArticleViewFooter', [ $this, $patrolFooterShown ] );
        }
 
        /**
@@ -1065,21 +1065,17 @@ class Article implements Page {
 
                $outputPage = $this->getContext()->getOutput();
                $user = $this->getContext()->getUser();
+               $title = $this->getTitle();
                $rc = false;
 
-               if ( !$this->getTitle()->quickUserCan( 'patrol', $user )
-                       || !( $wgUseRCPatrol || $wgUseNPPatrol || $wgUseFilePatrol )
+               if ( !$title->quickUserCan( 'patrol', $user )
+                       || !( $wgUseRCPatrol || $wgUseNPPatrol
+                               || ( $wgUseFilePatrol && $title->inNamespace( NS_FILE ) ) )
                ) {
                        // Patrolling is disabled or the user isn't allowed to
                        return false;
                }
 
-               // New page patrol: Get the timestamp of the oldest revison which
-               // the revision table holds for the given page. Then we look
-               // whether it's within the RC lifespan and if it is, we try
-               // to get the recentchanges row belonging to that entry
-               // (with rc_new = 1).
-
                if ( $this->mRevision
                        && !RecentChange::isInRCLifespan( $this->mRevision->getTimestamp(), 21600 )
                ) {
@@ -1089,7 +1085,7 @@ class Article implements Page {
                }
 
                // Check for cached results
-               $key = wfMemcKey( 'unpatrollable-page', $this->getTitle()->getArticleID() );
+               $key = wfMemcKey( 'unpatrollable-page', $title->getArticleID() );
                $cache = ObjectCache::getMainWANInstance();
                if ( $cache->get( $key ) ) {
                        return false;
@@ -1099,80 +1095,87 @@ class Article implements Page {
                $oldestRevisionTimestamp = $dbr->selectField(
                        'revision',
                        'MIN( rev_timestamp )',
-                       array( 'rev_page' => $this->getTitle()->getArticleID() ),
+                       [ 'rev_page' => $title->getArticleID() ],
                        __METHOD__
                );
 
-               $cantPatrolNewPage = false;
-               $cantPatrolFile = false;
-
+               // New page patrol: Get the timestamp of the oldest revison which
+               // the revision table holds for the given page. Then we look
+               // whether it's within the RC lifespan and if it is, we try
+               // to get the recentchanges row belonging to that entry
+               // (with rc_new = 1).
+               $recentPageCreation = false;
                if ( $oldestRevisionTimestamp
                        && RecentChange::isInRCLifespan( $oldestRevisionTimestamp, 21600 )
                ) {
                        // 6h tolerance because the RC might not be cleaned out regularly
+                       $recentPageCreation = true;
                        $rc = RecentChange::newFromConds(
-                               array(
+                               [
                                        'rc_new' => 1,
                                        'rc_timestamp' => $oldestRevisionTimestamp,
-                                       'rc_namespace' => $this->getTitle()->getNamespace(),
-                                       'rc_cur_id' => $this->getTitle()->getArticleID()
-                               ),
+                                       'rc_namespace' => $title->getNamespace(),
+                                       'rc_cur_id' => $title->getArticleID()
+                               ],
                                __METHOD__
                        );
                        if ( $rc ) {
                                // Use generic patrol message for new pages
                                $markPatrolledMsg = wfMessage( 'markaspatrolledtext' );
                        }
-               } else {
-                       $cantPatrolNewPage = true;
                }
 
-               // Allow patrolling of latest file upload
-               if ( !$rc && $wgUseFilePatrol && $this->getTitle()->getNamespace() === NS_FILE ) {
+               // File patrol: Get the timestamp of the latest upload for this page,
+               // check whether it is within the RC lifespan and if it is, we try
+               // to get the recentchanges row belonging to that entry
+               // (with rc_type = RC_LOG, rc_log_type = upload).
+               $recentFileUpload = false;
+               if ( ( !$rc || $rc->getAttribute( 'rc_patrolled' ) ) && $wgUseFilePatrol
+                       && $title->getNamespace() === NS_FILE ) {
                        // Retrieve timestamp of most recent upload
                        $newestUploadTimestamp = $dbr->selectField(
                                'image',
                                'MAX( img_timestamp )',
-                               array( 'img_name' => $this->getTitle()->getDBkey() ),
+                               [ 'img_name' => $title->getDBkey() ],
                                __METHOD__
                        );
                        if ( $newestUploadTimestamp
                                && RecentChange::isInRCLifespan( $newestUploadTimestamp, 21600 )
                        ) {
                                // 6h tolerance because the RC might not be cleaned out regularly
+                               $recentFileUpload = true;
                                $rc = RecentChange::newFromConds(
-                                       array(
+                                       [
                                                'rc_type' => RC_LOG,
                                                'rc_log_type' => 'upload',
                                                'rc_timestamp' => $newestUploadTimestamp,
                                                'rc_namespace' => NS_FILE,
-                                               'rc_cur_id' => $this->getTitle()->getArticleID(),
-                                               'rc_patrolled' => 0
-                                       ),
+                                               'rc_cur_id' => $title->getArticleID()
+                                       ],
                                        __METHOD__,
-                                       array( 'USE INDEX' => 'rc_timestamp' )
+                                       [ 'USE INDEX' => 'rc_timestamp' ]
                                );
                                if ( $rc ) {
                                        // Use patrol message specific to files
                                        $markPatrolledMsg = wfMessage( 'markaspatrolledtext-file' );
                                }
-                       } else {
-                               $cantPatrolFile = true;
                        }
-               } else {
-                       $cantPatrolFile = true;
                }
 
-               if ( $cantPatrolFile && $cantPatrolNewPage ) {
-                       // Cache the information we gathered above in case we can't patrol
-                       // Don't cache in case we can patrol as this could change
+               if ( !$recentPageCreation && !$recentFileUpload ) {
+                       // Page creation and latest upload (for files) is too old to be in RC
+
+                       // We definitely can't patrol so cache the information
+                       // When a new file version is uploaded, the cache is cleared
                        $cache->set( $key, '1' );
+
+                       return false;
                }
 
                if ( !$rc ) {
                        // 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.
+                       // its creation / latest upload or in case we have high slave lag. In case
+                       // the revision is too old, we will already return above.
                        return false;
                }
 
@@ -1187,7 +1190,7 @@ class Article implements Page {
                }
 
                if ( $rc->getPerformer()->equals( $user ) ) {
-                       // Don't show a patrol link for own creations. If the user could
+                       // Don't show a patrol link for own creations/uploads. If the user could
                        // patrol them, they already would be patrolled
                        return false;
                }
@@ -1202,14 +1205,14 @@ class Article implements Page {
                }
 
                $link = Linker::linkKnown(
-                       $this->getTitle(),
+                       $title,
                        $markPatrolledMsg->escaped(),
-                       array(),
-                       array(
+                       [],
+                       [
                                'action' => 'markpatrolled',
                                'rcid' => $rcid,
                                'token' => $token,
-                       )
+                       ]
                );
 
                $outputPage->addHTML(
@@ -1257,7 +1260,7 @@ class Article implements Page {
 
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
                                $outputPage->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
-                                       array( 'userpage-userdoesnotexist-view', wfEscapeWikiText( $rootPart ) ) );
+                                       [ 'userpage-userdoesnotexist-view', wfEscapeWikiText( $rootPart ) ] );
                        } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) {
                                # Show log extract if the user is currently blocked
                                LogEventsList::showLogExtract(
@@ -1265,14 +1268,14 @@ class Article implements Page {
                                        'block',
                                        MWNamespace::getCanonicalName( NS_USER ) . ':' . $block->getTarget(),
                                        '',
-                                       array(
+                                       [
                                                'lim' => 1,
                                                'showIfEmpty' => false,
-                                               'msgKey' => array(
+                                               'msgKey' => [
                                                        'blocked-notice-logextract',
                                                        $user->getName() # Support GENDER in notice
-                                               )
-                                       )
+                                               ]
+                                       ]
                                );
                                $validUserPage = !$title->isSubpage();
                        } else {
@@ -1280,7 +1283,7 @@ class Article implements Page {
                        }
                }
 
-               Hooks::run( 'ShowMissingArticle', array( $this ) );
+               Hooks::run( 'ShowMissingArticle', [ $this ] );
 
                # Show delete and move logs if there were any such events.
                # The logging query can DOS the site when bots/crawlers cause 404 floods,
@@ -1289,24 +1292,24 @@ class Article implements Page {
                $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'" );
+                       $logTypes = [ 'delete', 'move' ];
+                       $conds = [ "log_action != 'revision'" ];
                        // Give extensions a chance to hide their (unrelated) log entries
-                       Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) );
+                       Hooks::run( 'Article::MissingArticleConditions', [ &$conds, $logTypes ] );
                        LogEventsList::showLogExtract(
                                $outputPage,
                                $logTypes,
                                $title,
                                '',
-                               array(
+                               [
                                        'lim' => 10,
                                        'conds' => $conds,
                                        'showIfEmpty' => false,
-                                       'msgKey' => array( $loggedIn
+                                       'msgKey' => [ $loggedIn
                                                ? 'moveddeleted-notice'
                                                : 'moveddeleted-notice-recent'
-                                       )
-                               )
+                                       ]
+                               ]
                        );
                }
 
@@ -1321,7 +1324,7 @@ class Article implements Page {
                $outputPage->setIndexPolicy( $policy['index'] );
                $outputPage->setFollowPolicy( $policy['follow'] );
 
-               $hookResult = Hooks::run( 'BeforeDisplayNoArticleText', array( $this ) );
+               $hookResult = Hooks::run( 'BeforeDisplayNoArticleText', [ $this ] );
 
                if ( !$hookResult ) {
                        return;
@@ -1345,11 +1348,11 @@ class Article implements Page {
 
                        $dir = $this->getContext()->getLanguage()->getDir();
                        $lang = $this->getContext()->getLanguage()->getCode();
-                       $outputPage->addWikiText( Xml::openElement( 'div', array(
+                       $outputPage->addWikiText( Xml::openElement( 'div', [
                                'class' => "noarticletext mw-content-$dir",
                                'dir' => $dir,
                                'lang' => $lang,
-                       ) ) . "\n$text\n</div>" );
+                       ] ) . "\n$text\n</div>" );
                }
        }
 
@@ -1381,7 +1384,7 @@ class Article implements Page {
                        $msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
                                'rev-suppressed-text-unhide' : 'rev-deleted-text-unhide';
                        $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
-                               array( $msg, $link ) );
+                               [ $msg, $link ] );
 
                        return false;
                // We are allowed to see...
@@ -1403,7 +1406,7 @@ class Article implements Page {
         * @param int $oldid Revision ID of this article revision
         */
        public function setOldSubtitle( $oldid = 0 ) {
-               if ( !Hooks::run( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
+               if ( !Hooks::run( 'DisplayOldSubtitle', [ &$this, &$oldid ] ) ) {
                        return;
                }
 
@@ -1411,7 +1414,7 @@ class Article implements Page {
                $unhide = $context->getRequest()->getInt( 'unhide' ) == 1;
 
                # Cascade unhide param in links for easy deletion browsing
-               $extraParams = array();
+               $extraParams = [];
                if ( $unhide ) {
                        $extraParams['unhide'] = 1;
                }
@@ -1454,7 +1457,7 @@ class Article implements Page {
                        : Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'currentrevisionlink' )->escaped(),
-                               array(),
+                               [],
                                $extraParams
                        );
                $curdiff = $current
@@ -1462,33 +1465,33 @@ class Article implements Page {
                        : Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'diff' )->escaped(),
-                               array(),
-                               array(
+                               [],
+                               [
                                        'diff' => 'cur',
                                        'oldid' => $oldid
-                               ) + $extraParams
+                               ] + $extraParams
                        );
                $prev = $this->getTitle()->getPreviousRevisionID( $oldid );
                $prevlink = $prev
                        ? Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'previousrevision' )->escaped(),
-                               array(),
-                               array(
+                               [],
+                               [
                                        'direction' => 'prev',
                                        'oldid' => $oldid
-                               ) + $extraParams
+                               ] + $extraParams
                        )
                        : $context->msg( 'previousrevision' )->escaped();
                $prevdiff = $prev
                        ? Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'diff' )->escaped(),
-                               array(),
-                               array(
+                               [],
+                               [
                                        'diff' => 'prev',
                                        'oldid' => $oldid
-                               ) + $extraParams
+                               ] + $extraParams
                        )
                        : $context->msg( 'diff' )->escaped();
                $nextlink = $current
@@ -1496,22 +1499,22 @@ class Article implements Page {
                        : Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'nextrevision' )->escaped(),
-                               array(),
-                               array(
+                               [],
+                               [
                                        'direction' => 'next',
                                        'oldid' => $oldid
-                               ) + $extraParams
+                               ] + $extraParams
                        );
                $nextdiff = $current
                        ? $context->msg( 'diff' )->escaped()
                        : Linker::linkKnown(
                                $this->getTitle(),
                                $context->msg( 'diff' )->escaped(),
-                               array(),
-                               array(
+                               [],
+                               [
                                        'diff' => 'next',
                                        'oldid' => $oldid
-                               ) + $extraParams
+                               ] + $extraParams
                        );
 
                $cdel = Linker::getRevDeleteLink( $user, $revision, $this->getTitle() );
@@ -1560,7 +1563,7 @@ class Article implements Page {
         */
        public static function getRedirectHeaderHtml( Language $lang, $target, $forceKnown = false ) {
                if ( !is_array( $target ) ) {
-                       $target = array( $target );
+                       $target = [ $target ];
                }
 
                $html = '<ul class="redirectText">';
@@ -1569,11 +1572,11 @@ class Article implements Page {
                        $html .= '<li>' . Linker::link(
                                $title,
                                htmlspecialchars( $title->getFullText() ),
-                               array(),
+                               [],
                                // Automatically append redirect=no to each link, since most of them are
                                // redirect pages themselves.
-                               array( 'redirect' => 'no' ),
-                               ( $forceKnown ? array( 'known', 'noclasses' ) : array() )
+                               [ 'redirect' => 'no' ],
+                               ( $forceKnown ? [ 'known', 'noclasses' ] : [] )
                        ) . '</li>';
                }
                $html .= '</ul>';
@@ -1661,7 +1664,7 @@ class Article implements Page {
                        $outputPage = $context->getOutput();
                        $outputPage->setPageTitle( $context->msg( 'cannotdelete-title', $title->getPrefixedText() ) );
                        $outputPage->wrapWikiMsg( "<div class=\"error mw-error-cannotdelete\">\n$1\n</div>",
-                                       array( 'cannotdelete', wfEscapeWikiText( $title->getPrefixedText() ) )
+                                       [ 'cannotdelete', wfEscapeWikiText( $title->getPrefixedText() ) ]
                                );
                        $outputPage->addHTML(
                                Xml::element( 'h2', null, $deleteLogPage->getName()->text() )
@@ -1690,7 +1693,7 @@ class Article implements Page {
                }
 
                if ( $request->wasPosted() && $user->matchEditToken( $request->getVal( 'wpEditToken' ),
-                       array( 'delete', $this->getTitle()->getPrefixedText() ) )
+                       [ 'delete', $this->getTitle()->getPrefixedText() ] )
                ) {
                        # Flag to hide all contents of the archived revisions
                        $suppress = $request->getVal( 'wpSuppress' ) && $user->isAllowed( 'suppressrevision' );
@@ -1728,7 +1731,7 @@ class Article implements Page {
                        $revisions = $edits = (int)$dbr->selectField(
                                'revision',
                                'COUNT(rev_page)',
-                               array( 'rev_page' => $title->getArticleID() ),
+                               [ 'rev_page' => $title->getArticleID() ],
                                __METHOD__
                        );
 
@@ -1738,18 +1741,18 @@ class Article implements Page {
                                $context->msg( 'historywarning' )->numParams( $revisions )->parse() .
                                $context->msg( 'word-separator' )->escaped() . Linker::linkKnown( $title,
                                        $context->msg( 'history' )->escaped(),
-                                       array(),
-                                       array( 'action' => 'history' ) ) .
+                                       [],
+                                       [ 'action' => 'history' ] ) .
                                '</strong>'
                        );
 
                        if ( $title->isBigDeletion() ) {
                                global $wgDeleteRevisionsLimit;
                                $context->getOutput()->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
-                                       array(
+                                       [
                                                'delete-warning-toobig',
                                                $context->getLanguage()->formatNum( $wgDeleteRevisionsLimit )
-                                       )
+                                       ]
                                );
                        }
                }
@@ -1779,26 +1782,26 @@ class Article implements Page {
                }
                $outputPage->addWikiMsg( 'confirmdeletetext' );
 
-               Hooks::run( 'ArticleConfirmDelete', array( $this, $outputPage, &$reason ) );
+               Hooks::run( 'ArticleConfirmDelete', [ $this, $outputPage, &$reason ] );
 
                $user = $this->getContext()->getUser();
 
                if ( $user->isAllowed( 'suppressrevision' ) ) {
-                       $suppress = Html::openElement( 'div', array( 'id' => 'wpDeleteSuppressRow' ) ) .
+                       $suppress = Html::openElement( 'div', [ 'id' => 'wpDeleteSuppressRow' ] ) .
                                Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(),
-                                       'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) .
+                                       'wpSuppress', 'wpSuppress', false, [ 'tabindex' => '4' ] ) .
                                Html::closeElement( 'div' );
                } else {
                        $suppress = '';
                }
                $checkWatch = $user->getBoolOption( 'watchdeletion' ) || $user->isWatched( $title );
 
-               $form = Html::openElement( 'form', array( 'method' => 'post',
-                       'action' => $title->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ) ) .
-                       Html::openElement( 'fieldset', array( 'id' => 'mw-delete-table' ) ) .
+               $form = Html::openElement( 'form', [ 'method' => 'post',
+                       'action' => $title->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ] ) .
+                       Html::openElement( 'fieldset', [ 'id' => 'mw-delete-table' ] ) .
                        Html::element( 'legend', null, wfMessage( 'delete-legend' )->text() ) .
-                       Html::openElement( 'div', array( 'id' => 'mw-deleteconfirm-table' ) ) .
-                       Html::openElement( 'div', array( 'id' => 'wpDeleteReasonListRow' ) ) .
+                       Html::openElement( 'div', [ 'id' => 'mw-deleteconfirm-table' ] ) .
+                       Html::openElement( 'div', [ 'id' => 'wpDeleteReasonListRow' ] ) .
                        Html::label( wfMessage( 'deletecomment' )->text(), 'wpDeleteReasonList' ) .
                        '&nbsp;' .
                        Xml::listDropDown(
@@ -1810,43 +1813,43 @@ class Article implements Page {
                                1
                        ) .
                        Html::closeElement( 'div' ) .
-                       Html::openElement( 'div', array( 'id' => 'wpDeleteReasonRow' ) ) .
+                       Html::openElement( 'div', [ 'id' => 'wpDeleteReasonRow' ] ) .
                        Html::label( wfMessage( 'deleteotherreason' )->text(), 'wpReason' ) .
                        '&nbsp;' .
-                       Html::input( 'wpReason', $reason, 'text', array(
+                       Html::input( 'wpReason', $reason, 'text', [
                                'size' => '60',
                                'maxlength' => '255',
                                'tabindex' => '2',
                                'id' => 'wpReason',
                                'class' => 'mw-ui-input-inline',
                                'autofocus'
-                       ) ) .
+                       ] ) .
                        Html::closeElement( 'div' );
 
                # Disallow watching if user is not logged in
                if ( $user->isLoggedIn() ) {
                        $form .=
                                        Xml::checkLabel( wfMessage( 'watchthis' )->text(),
-                                               'wpWatch', 'wpWatch', $checkWatch, array( 'tabindex' => '3' ) );
+                                               'wpWatch', 'wpWatch', $checkWatch, [ 'tabindex' => '3' ] );
                }
 
                $form .=
                                Html::openElement( 'div' ) .
                                $suppress .
                                        Xml::submitButton( wfMessage( 'deletepage' )->text(),
-                                               array(
+                                               [
                                                        'name' => 'wpConfirmB',
                                                        'id' => 'wpConfirmB',
                                                        'tabindex' => '5',
                                                        'class' => $useMediaWikiUIEverywhere ? 'mw-ui-button mw-ui-destructive' : '',
-                                               )
+                                               ]
                                        ) .
                                Html::closeElement( 'div' ) .
                        Html::closeElement( 'div' ) .
                        Xml::closeElement( 'fieldset' ) .
                        Html::hidden(
                                'wpEditToken',
-                               $user->getEditToken( array( 'delete', $title->getPrefixedText() ) )
+                               $user->getEditToken( [ 'delete', $title->getPrefixedText() ] )
                        ) .
                        Xml::closeElement( 'form' );
 
@@ -1854,8 +1857,8 @@ class Article implements Page {
                                $link = Linker::linkKnown(
                                        $ctx->msg( 'deletereason-dropdown' )->inContentLanguage()->getTitle(),
                                        wfMessage( 'delete-edit-reasonlist' )->escaped(),
-                                       array(),
-                                       array( 'action' => 'edit' )
+                                       [],
+                                       [ 'action' => 'edit' ]
                                );
                                $form .= '<p class="mw-delete-editreasons">' . $link . '</p>';
                        }
@@ -1889,7 +1892,7 @@ class Article implements Page {
 
                        $outputPage->addWikiMsg( 'deletedtext', wfEscapeWikiText( $deleted ), $loglink );
 
-                       Hooks::run( 'ArticleDeleteAfterSuccess', array( $this->getTitle(), $outputPage ) );
+                       Hooks::run( 'ArticleDeleteAfterSuccess', [ $this->getTitle(), $outputPage ] );
 
                        $outputPage->returnToMain( false );
                } else {
@@ -1942,7 +1945,7 @@ class Article implements Page {
                                return true;
                        } else {
                                wfDebug( "Article::tryFileCache(): starting buffer\n" );
-                               ob_start( array( &$cache, 'saveToFileCache' ) );
+                               ob_start( [ &$cache, 'saveToFileCache' ] );
                        }
                } else {
                        wfDebug( "Article::tryFileCache(): not cacheable\n" );
@@ -1963,7 +1966,7 @@ class Article implements Page {
                                && !$this->mRedirectedFrom && !$this->getTitle()->isRedirect();
                        // Extension may have reason to disable file caching on some pages.
                        if ( $cacheable ) {
-                               $cacheable = Hooks::run( 'IsFileCacheable', array( &$this ) );
+                               $cacheable = Hooks::run( 'IsFileCacheable', [ &$this ] );
                        }
                }
 
@@ -2075,7 +2078,7 @@ class Article implements Page {
                        # wfWarn( "Access to raw $fname field of " . __CLASS__ );
                        $this->mPage->$fname = $fvalue;
                // Note: extensions may want to toss on new fields
-               } elseif ( !in_array( $fname, array( 'mContext', 'mPage' ) ) ) {
+               } elseif ( !in_array( $fname, [ 'mContext', 'mPage' ] ) ) {
                        $this->mPage->$fname = $fvalue;
                } else {
                        trigger_error( 'Inaccessible property via __set(): ' . $fname, E_USER_NOTICE );
@@ -2083,22 +2086,575 @@ class Article implements Page {
        }
 
        /**
-        * Use PHP's magic __call handler to transform instance calls to
-        * WikiPage functions for backwards compatibility.
-        *
-        * @param string $fname Name of called method
-        * @param array $args Arguments to the method
-        * @return mixed
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::checkFlags
         */
-       public function __call( $fname, $args ) {
-               if ( is_callable( array( $this->mPage, $fname ) ) ) {
-                       # wfWarn( "Call to " . __CLASS__ . "::$fname; please use WikiPage instead" );
-                       return call_user_func_array( array( $this->mPage, $fname ), $args );
-               }
-               trigger_error( 'Inaccessible function via __call(): ' . $fname, E_USER_ERROR );
+       public function checkFlags( $flags ) {
+               return $this->mPage->checkFlags( $flags );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::checkTouched
+        */
+       public function checkTouched() {
+               return $this->mPage->checkTouched();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::clearPreparedEdit
+        */
+       public function clearPreparedEdit() {
+               $this->mPage->clearPreparedEdit();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doDeleteArticleReal
+        */
+       public function doDeleteArticleReal(
+               $reason, $suppress = false, $u1 = null, $u2 = null, &$error = '', User $user = null
+       ) {
+               return $this->mPage->doDeleteArticleReal(
+                       $reason, $suppress, $u1, $u2, $error, $user
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doDeleteUpdates
+        */
+       public function doDeleteUpdates( $id, Content $content = null ) {
+               return $this->mPage->doDeleteUpdates( $id, $content );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEdit
+        */
+       public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->doEdit( $text, $summary, $flags, $baseRevId, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEditContent
+        */
+       public function doEditContent( Content $content, $summary, $flags = 0, $baseRevId = false,
+               User $user = null, $serialFormat = null
+       ) {
+               return $this->mPage->doEditContent( $content, $summary, $flags, $baseRevId,
+                       $user, $serialFormat
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEditUpdates
+        */
+       public function doEditUpdates( Revision $revision, User $user, array $options = [] ) {
+               return $this->mPage->doEditUpdates( $revision, $user, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doPurge
+        */
+       public function doPurge() {
+               return $this->mPage->doPurge();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doQuickEditContent
+        */
+       public function doQuickEditContent(
+               Content $content, User $user, $comment = '', $minor = false, $serialFormat = null
+       ) {
+               return $this->mPage->doQuickEditContent(
+                       $content, $user, $comment, $minor, $serialFormat
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doViewUpdates
+        */
+       public function doViewUpdates( User $user, $oldid = 0 ) {
+               $this->mPage->doViewUpdates( $user, $oldid );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::exists
+        */
+       public function exists() {
+               return $this->mPage->exists();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::followRedirect
+        */
+       public function followRedirect() {
+               return $this->mPage->followRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getActionOverrides
+        */
+       public function getActionOverrides() {
+               return $this->mPage->getActionOverrides();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getAutoDeleteReason
+        */
+       public function getAutoDeleteReason( &$hasHistory ) {
+               return $this->mPage->getAutoDeleteReason( $hasHistory );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getCategories
+        */
+       public function getCategories() {
+               return $this->mPage->getCategories();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getComment
+        */
+       public function getComment( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getComment( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContentHandler
+        */
+       public function getContentHandler() {
+               return $this->mPage->getContentHandler();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContentModel
+        */
+       public function getContentModel() {
+               return $this->mPage->getContentModel();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContributors
+        */
+       public function getContributors() {
+               return $this->mPage->getContributors();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getCreator
+        */
+       public function getCreator( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getCreator( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getDeletionUpdates
+        */
+       public function getDeletionUpdates( Content $content = null ) {
+               return $this->mPage->getDeletionUpdates( $content );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getHiddenCategories
+        */
+       public function getHiddenCategories() {
+               return $this->mPage->getHiddenCategories();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getId
+        */
+       public function getId() {
+               return $this->mPage->getId();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getLatest
+        */
+       public function getLatest() {
+               return $this->mPage->getLatest();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getLinksTimestamp
+        */
+       public function getLinksTimestamp() {
+               return $this->mPage->getLinksTimestamp();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getMinorEdit
+        */
+       public function getMinorEdit() {
+               return $this->mPage->getMinorEdit();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getOldestRevision
+        */
+       public function getOldestRevision() {
+               return $this->mPage->getOldestRevision();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRedirectTarget
+        */
+       public function getRedirectTarget() {
+               return $this->mPage->getRedirectTarget();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRedirectURL
+        */
+       public function getRedirectURL( $rt ) {
+               return $this->mPage->getRedirectURL( $rt );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRevision
+        */
+       public function getRevision() {
+               return $this->mPage->getRevision();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getText
+        */
+       public function getText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->getText( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getTimestamp
+        */
+       public function getTimestamp() {
+               return $this->mPage->getTimestamp();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getTouched
+        */
+       public function getTouched() {
+               return $this->mPage->getTouched();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUndoContent
+        */
+       public function getUndoContent( Revision $undo, Revision $undoafter = null ) {
+               return $this->mPage->getUndoContent( $undo, $undoafter );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUndoText
+        */
+       public function getUndoText( Revision $undo, Revision $undoafter = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->getUndoText( $undo, $undoafter );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUser
+        */
+       public function getUser( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getUser( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUserText
+        */
+       public function getUserText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getUserText( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::hasViewableContent
+        */
+       public function hasViewableContent() {
+               return $this->mPage->hasViewableContent();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertOn
+        */
+       public function insertOn( $dbw, $pageId = null ) {
+               return $this->mPage->insertOn( $dbw, $pageId );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertProtectNullRevision
+        */
+       public function insertProtectNullRevision( $revCommentMsg, array $limit,
+               array $expiry, $cascade, $reason, $user = null
+       ) {
+               return $this->mPage->insertProtectNullRevision( $revCommentMsg, $limit,
+                       $expiry, $cascade, $reason, $user
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertRedirect
+        */
+       public function insertRedirect() {
+               return $this->mPage->insertRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertRedirectEntry
+        */
+       public function insertRedirectEntry( Title $rt, $oldLatest = null ) {
+               return $this->mPage->insertRedirectEntry( $rt, $oldLatest );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::isCountable
+        */
+       public function isCountable( $editInfo = false ) {
+               return $this->mPage->isCountable( $editInfo );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::isRedirect
+        */
+       public function isRedirect() {
+               return $this->mPage->isRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::loadFromRow
+        */
+       public function loadFromRow( $data, $from ) {
+               return $this->mPage->loadFromRow( $data, $from );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::loadPageData
+        */
+       public function loadPageData( $from = 'fromdb' ) {
+               $this->mPage->loadPageData( $from );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::lockAndGetLatest
+        */
+       public function lockAndGetLatest() {
+               return $this->mPage->lockAndGetLatest();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::makeParserOptions
+        */
+       public function makeParserOptions( $context ) {
+               return $this->mPage->makeParserOptions( $context );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::pageDataFromId
+        */
+       public function pageDataFromId( $dbr, $id, $options = [] ) {
+               return $this->mPage->pageDataFromId( $dbr, $id, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::pageDataFromTitle
+        */
+       public function pageDataFromTitle( $dbr, $title, $options = [] ) {
+               return $this->mPage->pageDataFromTitle( $dbr, $title, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::prepareContentForEdit
+        */
+       public function prepareContentForEdit(
+               Content $content, $revision = null, User $user = null,
+               $serialFormat = null, $useCache = true
+       ) {
+               return $this->mPage->prepareContentForEdit(
+                       $content, $revision, $user,
+                       $serialFormat, $useCache
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::prepareTextForEdit
+        */
+       public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
+               return $this->mPage->prepareTextForEdit( $text, $revid, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::protectDescription
+        */
+       public function protectDescription( array $limit, array $expiry ) {
+               return $this->mPage->protectDescription( $limit, $expiry );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::protectDescriptionLog
+        */
+       public function protectDescriptionLog( array $limit, array $expiry ) {
+               return $this->mPage->protectDescriptionLog( $limit, $expiry );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSection
+        */
+       public function replaceSection( $sectionId, $text, $sectionTitle = '',
+               $edittime = null
+       ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->replaceSection( $sectionId, $text, $sectionTitle,
+                       $edittime
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSectionAtRev
+        */
+       public function replaceSectionAtRev( $sectionId, Content $sectionContent,
+               $sectionTitle = '', $baseRevId = null
+       ) {
+               return $this->mPage->replaceSectionAtRev( $sectionId, $sectionContent,
+                       $sectionTitle, $baseRevId
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSectionContent
+        */
+       public function replaceSectionContent(
+               $sectionId, Content $sectionContent, $sectionTitle = '', $edittime = null
+       ) {
+               return $this->mPage->replaceSectionContent(
+                       $sectionId, $sectionContent, $sectionTitle, $edittime
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::setTimestamp
+        */
+       public function setTimestamp( $ts ) {
+               return $this->mPage->setTimestamp( $ts );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::shouldCheckParserCache
+        */
+       public function shouldCheckParserCache( ParserOptions $parserOptions, $oldId ) {
+               return $this->mPage->shouldCheckParserCache( $parserOptions, $oldId );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::supportsSections
+        */
+       public function supportsSections() {
+               return $this->mPage->supportsSections();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::triggerOpportunisticLinksUpdate
+        */
+       public function triggerOpportunisticLinksUpdate( ParserOutput $parserOutput ) {
+               return $this->mPage->triggerOpportunisticLinksUpdate( $parserOutput );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateCategoryCounts
+        */
+       public function updateCategoryCounts( array $added, array $deleted ) {
+               return $this->mPage->updateCategoryCounts( $added, $deleted );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateIfNewerOn
+        */
+       public function updateIfNewerOn( $dbw, $revision ) {
+               return $this->mPage->updateIfNewerOn( $dbw, $revision );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateRedirectOn
+        */
+       public function updateRedirectOn( $dbw, $redirectTitle, $lastRevIsRedirect = null ) {
+               return $this->mPage->updateRedirectOn( $dbw, $redirectTitle, $lastRevIsRedirect = null );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateRevisionOn
+        */
+       public function updateRevisionOn( $dbw, $revision, $lastRevision = null,
+               $lastRevIsRedirect = null
+       ) {
+               return $this->mPage->updateRevisionOn( $dbw, $revision, $lastRevision,
+                       $lastRevIsRedirect
+               );
        }
 
-       // ****** B/C functions to work-around PHP silliness with __call and references ****** //
 
        /**
         * @param array $limit
@@ -2121,8 +2677,8 @@ class Article implements Page {
         * @param array $expiry
         * @return bool
         */
-       public function updateRestrictions( $limit = array(), $reason = '',
-               &$cascade = 0, $expiry = array()
+       public function updateRestrictions( $limit = [], $reason = '',
+               &$cascade = 0, $expiry = []
        ) {
                return $this->mPage->doUpdateRestrictions(
                        $limit,
@@ -2184,8 +2740,6 @@ class Article implements Page {
                return $handler->getAutoDeleteReason( $title, $hasHistory );
        }
 
-       // ****** B/C functions for static methods ( __callStatic is PHP>=5.3 ) ****** //
-
        /**
         * @return array
         *