catch exceptions while generating auto delete reason
[lhc/web/wiklou.git] / includes / Article.php
index bb3ac37..5470dbc 100644 (file)
@@ -37,7 +37,8 @@ class Article extends Page {
         */
        public $mParserOptions;
 
-       var $mContent;                    // !<
+       var $mContent;                    // !< #BC cruft
+    var $mContentObject;              // !<
        var $mContentLoaded = false;      // !<
        var $mOldId;                      // !<
 
@@ -112,13 +113,14 @@ class Article extends Page {
                if ( !$page ) {
                        switch( $title->getNamespace() ) {
                                case NS_FILE:
-                                       $page = new ImagePage( $title );
+                                       $page = new ImagePage( $title ); #FIXME: teach ImagePage to use ContentHandler
                                        break;
                                case NS_CATEGORY:
-                                       $page = new CategoryPage( $title );
+                                       $page = new CategoryPage( $title ); #FIXME: teach ImagePage to use ContentHandler
                                        break;
                                default:
-                                       $page = new Article( $title );
+                    $handler = ContentHandler::getForTitle( $title );
+                                       $page = $handler->createArticle( $title );
                        }
                }
                $page->setContext( $context );
@@ -150,12 +152,23 @@ class Article extends Page {
 
        /**
         * Get the title object of the article
+        *
         * @return Title object of this page
         */
        public function getTitle() {
                return $this->mPage->getTitle();
        }
 
+       /**
+        * Get the WikiPage object of this instance
+        *
+        * @since 1.19
+        * @return WikiPage
+        */
+       public function getPage() {
+               return $this->mPage;
+       }
+
        /**
         * Clear the object
         */
@@ -172,14 +185,31 @@ class Article extends Page {
        /**
         * Note that getContent/loadContent do not follow redirects anymore.
         * If you need to fetch redirectable content easily, try
-        * the shortcut in Article::followRedirect()
+        * the shortcut in WikiPage::getRedirectTarget()
         *
         * This function has side effects! Do not use this function if you
         * only want the real revision text if any.
         *
         * @return Return the text of this revision
+     * @deprecated in 1.20; use getContentObject() instead
         */
        public function getContent() {
+        wfDeprecated( __METHOD__, '1.20' );
+        $content = $this->getContentObject();
+        return ContentHandler::getContentText( $content );
+    }
+
+    /**
+     * Note that getContent/loadContent do not follow redirects anymore.
+     * If you need to fetch redirectable content easily, try
+     * the shortcut in WikiPage::getRedirectTarget()
+     *
+     * This function has side effects! Do not use this function if you
+     * only want the real revision text if any.
+     *
+     * @return Return the content of this revision
+     */
+   public function getContentObject() {
                global $wgUser;
 
                wfProfileIn( __METHOD__ );
@@ -197,12 +227,12 @@ class Article extends Page {
                        }
                        wfProfileOut( __METHOD__ );
 
-                       return $text;
+                       return ContentHandler::makeContent( $text, $this->getTitle() );
                } else {
-                       $this->fetchContent();
+                       $this->fetchContentObject();
                        wfProfileOut( __METHOD__ );
 
-                       return $this->mContent;
+                       return $this->mContentObject;
                }
        }
 
@@ -251,6 +281,7 @@ class Article extends Page {
                        $nextid = $this->getTitle()->getNextRevisionID( $oldid );
                        if ( $nextid ) {
                                $oldid = $nextid;
+                               $this->mRevision = null;
                        } else {
                                $this->mRedirectUrl = $this->getTitle()->getFullURL( 'redirect=no' );
                        }
@@ -258,6 +289,7 @@ class Article extends Page {
                        $previd = $this->getTitle()->getPreviousRevisionID( $oldid );
                        if ( $previd ) {
                                $oldid = $previd;
+                               $this->mRevision = null;
                        }
                }
 
@@ -270,6 +302,7 @@ class Article extends Page {
         * @deprecated in 1.19; use fetchContent()
         */
        function loadContent() {
+               wfDeprecated( __METHOD__, '1.19' );
                $this->fetchContent();
        }
 
@@ -278,67 +311,96 @@ class Article extends Page {
         * Does *NOT* follow redirects.
         *
         * @return mixed string containing article contents, or false if null
+     * @deprecated in 1.20, use getContentObject() instead
         */
-       function fetchContent() {
-               if ( $this->mContentLoaded ) {
+       protected function fetchContent() { #BC cruft!
+        wfDeprecated( __METHOD__, '1.20' );
+
+               if ( $this->mContentLoaded && $this->mContent ) {
                        return $this->mContent;
                }
 
                wfProfileIn( __METHOD__ );
 
-               $this->mContentLoaded = true;
+        $content = $this->fetchContentObject();
 
-               $oldid = $this->getOldID();
+        $this->mContent = ContentHandler::getContentText( $content ); #FIXME: get rid of mContent everywhere!
+               wfRunHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) ); #BC cruft!
 
-               # Pre-fill content with error message so that if something
-               # fails we'll have something telling us what we intended.
-               $t = $this->getTitle()->getPrefixedText();
-               $d = $oldid ? wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ) : '';
-               $this->mContent = wfMsgNoTrans( 'missing-article', $t, $d ) ;
+               wfProfileOut( __METHOD__ );
 
-               if ( $oldid ) {
-                       # $this->mRevision might already be fetched by getOldIDFromRequest()
-                       if ( !$this->mRevision ) {
-                               $this->mRevision = Revision::newFromId( $oldid );
-                               if ( !$this->mRevision ) {
-                                       wfDebug( __METHOD__ . " failed to retrieve specified revision, id $oldid\n" );
-                                       wfProfileOut( __METHOD__ );
-                                       return false;
-                               }
-                       }
-               } else {
-                       if ( !$this->mPage->getLatest() ) {
-                               wfDebug( __METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n" );
-                               wfProfileOut( __METHOD__ );
-                               return false;
-                       }
+               return $this->mContent;
+       }
 
-                       $this->mRevision = $this->mPage->getRevision();
-                       if ( !$this->mRevision ) {
-                               wfDebug( __METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n" );
-                               wfProfileOut( __METHOD__ );
-                               return false;
-                       }
-               }
 
-               // @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
-               // We should instead work with the Revision object when we need it...
-               $this->mContent = $this->mRevision->getText( Revision::FOR_THIS_USER ); // Loads if user is allowed
-               $this->mRevIdFetched = $this->mRevision->getId();
+    /**
+     * Get text content object
+     * Does *NOT* follow redirects.
+     *
+     * @return Content object containing article contents, or null
+     */
+    protected function fetchContentObject() {
+        if ( $this->mContentLoaded ) {
+            return $this->mContentObject;
+        }
 
-               wfRunHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) );
+        wfProfileIn( __METHOD__ );
 
-               wfProfileOut( __METHOD__ );
+        $this->mContentLoaded = true;
+        $this->mContent = null;
 
-               return $this->mContent;
-       }
+        $oldid = $this->getOldID();
+
+        # Pre-fill content with error message so that if something
+        # fails we'll have something telling us what we intended.
+        $t = $this->getTitle()->getPrefixedText();
+        $d = $oldid ? wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ) : '';
+        $this->mContentObject = new MessageContent( 'missing-article', array($t, $d), array() ) ;
+
+        if ( $oldid ) {
+            # $this->mRevision might already be fetched by getOldIDFromRequest()
+            if ( !$this->mRevision ) {
+                $this->mRevision = Revision::newFromId( $oldid );
+                if ( !$this->mRevision ) {
+                    wfDebug( __METHOD__ . " failed to retrieve specified revision, id $oldid\n" );
+                    wfProfileOut( __METHOD__ );
+                    return false;
+                }
+            }
+        } else {
+            if ( !$this->mPage->getLatest() ) {
+                wfDebug( __METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n" );
+                wfProfileOut( __METHOD__ );
+                return false;
+            }
+
+            $this->mRevision = $this->mPage->getRevision();
+
+            if ( !$this->mRevision ) {
+                wfDebug( __METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n" );
+                wfProfileOut( __METHOD__ );
+                return false;
+            }
+        }
+
+        // @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
+        // We should instead work with the Revision object when we need it...
+        $this->mContentObject = $this->mRevision->getContent( Revision::FOR_THIS_USER ); // Loads if user is allowed
+        $this->mRevIdFetched = $this->mRevision->getId();
+
+        wfRunHooks( 'ArticleAfterFetchContentObject', array( &$this, &$this->mContentObject ) ); #FIXME: register new hook
+
+        wfProfileOut( __METHOD__ );
+
+        return $this->mContentObject;
+    }
 
        /**
         * No-op
         * @deprecated since 1.18
         */
        public function forUpdate() {
-               wfDeprecated( __METHOD__ );
+               wfDeprecated( __METHOD__, '1.18' );
        }
 
        /**
@@ -355,6 +417,19 @@ class Article extends Page {
                return $this->mPage->exists() && $this->mRevision && $this->mRevision->isCurrent();
        }
 
+       /**
+        * Get the fetched Revision object depending on request parameters or null
+        * on failure.
+        *
+        * @since 1.19
+        * @return Revision|null
+        */
+       public function getRevisionFetched() {
+               $this->fetchContentObject();
+
+               return $this->mRevision;
+       }
+
        /**
         * Use this to fetch the rev ID used on page views
         *
@@ -374,7 +449,7 @@ class Article extends Page {
         */
        public function view() {
                global $wgUser, $wgOut, $wgRequest, $wgParser;
-               global $wgUseFileCache, $wgUseETag;
+               global $wgUseFileCache, $wgUseETag, $wgDebugToolbar;
 
                wfProfileIn( __METHOD__ );
 
@@ -429,7 +504,7 @@ class Article extends Page {
                }
 
                # Try client and file cache
-               if ( $oldid === 0 && $this->mPage->checkTouched() ) {
+               if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
                        if ( $wgUseETag ) {
                                $wgOut->setETag( $parserCache->getETag( $this, $parserOptions ) );
                        }
@@ -445,7 +520,7 @@ class Article extends Page {
                                wfDebug( __METHOD__ . ": done file cache\n" );
                                # tell wgOut that output is taken care of
                                $wgOut->disable();
-                               $this->mPage->viewUpdates();
+                               $this->mPage->doViewUpdates( $wgUser );
                                wfProfileOut( __METHOD__ );
 
                                return;
@@ -497,17 +572,19 @@ class Article extends Page {
                                                        # Ensure that UI elements requiring revision ID have
                                                        # the correct version information.
                                                        $wgOut->setRevisionId( $this->mPage->getLatest() );
-                                                       $outputDone = true;
                                                        # Preload timestamp to avoid a DB hit
-                                                       if ( isset( $this->mParserOutput->mTimestamp ) ) {
-                                                               $this->mPage->setTimestamp( $this->mParserOutput->mTimestamp );
+                                                       $cachedTimestamp = $this->mParserOutput->getTimestamp();
+                                                       if ( $cachedTimestamp !== null ) {
+                                                               $wgOut->setRevisionTimestamp( $cachedTimestamp );
+                                                               $this->mPage->setTimestamp( $cachedTimestamp );
                                                        }
+                                                       $outputDone = true;
                                                }
                                        }
                                        break;
                                case 3:
                                        # This will set $this->mRevision if needed
-                                       $this->fetchContent();
+                                       $this->fetchContentObject();
 
                                        # Are we looking at an old revision
                                        if ( $oldid && $this->mRevision ) {
@@ -523,24 +600,30 @@ class Article extends Page {
                                        # Ensure that UI elements requiring revision ID have
                                        # the correct version information.
                                        $wgOut->setRevisionId( $this->getRevIdFetched() );
+                                       # Preload timestamp to avoid a DB hit
+                                       $wgOut->setRevisionTimestamp( $this->getTimestamp() );
 
                                        # Pages containing custom CSS or JavaScript get special treatment
                                        if ( $this->getTitle()->isCssOrJsPage() || $this->getTitle()->isCssJsSubpage() ) {
+                        #FIXME: use ContentHandler for specialized actions insetad.
                                                wfDebug( __METHOD__ . ": showing CSS/JS source\n" );
                                                $this->showCssOrJsPage();
                                                $outputDone = true;
-                                       } elseif( !wfRunHooks( 'ArticleViewCustom', array( $this->mContent, $this->getTitle(), $wgOut ) ) ) {
+                    } elseif( !wfRunHooks( 'ArticleContentViewCustom', array( $this->fetchContentObject(), $this->getTitle(), $wgOut ) ) ) { #FIXME: document new hook!
+                        # Allow extensions do their own custom view for certain pages
+                        $outputDone = true;
+                                       } elseif( Hooks::isRegistered( 'ArticleViewCustom' ) && !wfRunHooks( 'ArticleViewCustom', array( $this->fetchContent(), $this->getTitle(), $wgOut ) ) ) { #FIXME: fetchContent() is deprecated! #FIXME: deprecate hook!
                                                # Allow extensions do their own custom view for certain pages
                                                $outputDone = true;
                                        } else {
-                                               $text = $this->getContent();
-                                               $rt = Title::newFromRedirectArray( $text );
+                                               $content = $this->getContentObject();
+                                               $rt = $content->getRedirectChain();
                                                if ( $rt ) {
                                                        wfDebug( __METHOD__ . ": showing redirect=no page\n" );
                                                        # Viewing a redirect page (e.g. with parameter redirect=no)
                                                        $wgOut->addHTML( $this->viewRedirect( $rt ) );
                                                        # Parse just to get categories, displaytitle, etc.
-                                                       $this->mParserOutput = $wgParser->parse( $text, $this->getTitle(), $parserOptions );
+                                                       $this->mParserOutput = $content->getParserOutput( $this->getTitle(), $oldid, $parserOptions );
                                                        $wgOut->addParserOutputNoText( $this->mParserOutput );
                                                        $outputDone = true;
                                                }
@@ -551,7 +634,7 @@ class Article extends Page {
                                        wfDebug( __METHOD__ . ": doing uncached parse\n" );
 
                                        $poolArticleView = new PoolWorkArticleView( $this, $parserOptions,
-                                               $this->getRevIdFetched(), $useParserCache, $this->getContent() );
+                                               $this->getRevIdFetched(), $useParserCache, $this->getContentObject() );
 
                                        if ( !$poolArticleView->execute() ) {
                                                $error = $poolArticleView->getError();
@@ -613,7 +696,7 @@ class Article extends Page {
                $wgOut->setFollowPolicy( $policy['follow'] );
 
                $this->showViewFooter();
-               $this->mPage->viewUpdates();
+               $this->mPage->doViewUpdates( $wgUser );
 
                wfProfileOut( __METHOD__ );
        }
@@ -645,14 +728,16 @@ class Article extends Page {
                $unhide = $wgRequest->getInt( 'unhide' ) == 1;
                $oldid = $this->getOldID();
 
-               $de = new DifferenceEngine( $this->getContext(), $oldid, $diff, $rcid, $purge, $unhide );
+        $contentHandler = ContentHandler::getForTitle( $this->getTitle() );
+               $de = $contentHandler->getDifferenceEngine( $this->getContext(), $oldid, $diff, $rcid, $purge, $unhide );
+
                // DifferenceEngine directly fetched the revision:
                $this->mRevIdFetched = $de->mNewid;
                $de->showDiffPage( $diffOnly );
 
                if ( $diff == 0 || $diff == $this->mPage->getLatest() ) {
                        # Run view updates for current revision only
-                       $this->mPage->viewUpdates();
+                       $this->mPage->doViewUpdates( $wgUser );
                }
        }
 
@@ -673,13 +758,9 @@ class Article extends Page {
                        'clearyourcache' );
 
                // Give hooks a chance to customise the output
-               if ( wfRunHooks( 'ShowRawCssJs', array( $this->mContent, $this->getTitle(), $wgOut ) ) ) {
-                       // Wrap the whole lot in a <pre> and don't parse
-                       $m = array();
-                       preg_match( '!\.(css|js)$!u', $this->getTitle()->getText(), $m );
-                       $wgOut->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
-                       $wgOut->addHTML( htmlspecialchars( $this->mContent ) );
-                       $wgOut->addHTML( "\n</pre>\n" );
+               if ( !Hooks::isRegistered('ShowRawCssJs') || wfRunHooks( 'ShowRawCssJs', array( $this->fetchContent(), $this->getTitle(), $wgOut ) ) ) { #FIXME: fetchContent() is deprecated #FIXME: hook is deprecated
+            $po = $this->mContentObject->getParserOutput();
+                       $wgOut->addHTML( $po->getText() );
                }
        }
 
@@ -823,6 +904,9 @@ class Article extends Page {
                                        'href' => $this->getTitle()->getLocalURL() )
                                );
 
+                               // Tell $wgOut the user arrived at this article through a redirect
+                               $wgOut->setRedirectedFrom( $this->mRedirectedFrom );
+
                                return true;
                        }
                } elseif ( $rdfrom ) {
@@ -914,7 +998,7 @@ class Article extends Page {
         * namespace, show the default message text. To be called from Article::view().
         */
        public function showMissingArticle() {
-               global $wgOut, $wgRequest, $wgUser;
+               global $wgOut, $wgRequest, $wgUser, $wgSend404Code;
 
                # Show info in user (talk) namespace. Does the user exist? Is he blocked?
                if ( $this->getTitle()->getNamespace() == NS_USER || $this->getTitle()->getNamespace() == NS_USER_TALK ) {
@@ -976,7 +1060,7 @@ class Article extends Page {
                }
                $text = "<div class='noarticletext'>\n$text\n</div>";
 
-               if ( !$this->mPage->hasViewableContent() ) {
+               if ( !$this->mPage->hasViewableContent() && $wgSend404Code ) {
                        // If there's no backing content, send a 404 Not Found
                        // for better machine handling of broken links.
                        $wgRequest->response()->header( "HTTP/1.1 404 Not Found" );
@@ -1139,21 +1223,8 @@ class Article extends Page {
                                array( 'known', 'noclasses' )
                        );
 
-               $cdel = '';
-
-               // User can delete revisions or view deleted revisions...
-               $canHide = $wgUser->isAllowed( 'deleterevision' );
-               if ( $canHide || ( $revision->getVisibility() && $wgUser->isAllowed( 'deletedhistory' ) ) ) {
-                       if ( !$revision->userCan( Revision::DELETED_RESTRICTED ) ) {
-                               $cdel = Linker::revDeleteLinkDisabled( $canHide ); // rev was hidden from Sysops
-                       } else {
-                               $query = array(
-                                       'type'   => 'revision',
-                                       'target' => $this->getTitle()->getPrefixedDbkey(),
-                                       'ids'    => $oldid
-                               );
-                               $cdel = Linker::revDeleteLink( $query, $revision->isDeleted( File::DELETED_RESTRICTED ), $canHide );
-                       }
+               $cdel = Linker::getRevDeleteLink( $wgUser, $revision, $this->getTitle() );
+               if ( $cdel !== '' ) {
                        $cdel .= ' ';
                }
 
@@ -1281,18 +1352,6 @@ class Article extends Page {
                        return;
                }
 
-               # Hack for big sites
-               $bigHistory = $this->mPage->isBigDeletion();
-               if ( $bigHistory && !$title->userCan( 'bigdelete' ) ) {
-                       global $wgDeleteRevisionsLimit;
-
-                       $wgOut->setPageTitle( wfMessage( 'cannotdelete-title', $title->getPrefixedText() ) );
-                       $wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
-                               array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
-
-                       return;
-               }
-
                $deleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' );
                $deleteReason = $wgRequest->getText( 'wpReason' );
 
@@ -1325,12 +1384,18 @@ class Article extends Page {
                // Generate deletion reason
                $hasHistory = false;
                if ( !$reason ) {
-                       $reason = $this->generateReason( $hasHistory );
+            try {
+                $reason = $this->generateReason( $hasHistory );
+            } catch (MWException $e) {
+                # if a page is horribly broken, we still want to be able to delete it. so be lenient about errors here.
+                wfDebug("Error while building auto delete summary: $e");
+                $reason = '';
+            }
                }
 
                // If the page has a history, insert a warning
                if ( $hasHistory ) {
-                       $revisions = $this->mPage->estimateRevisionCount();
+                       $revisions = $this->mTitle->estimateRevisionCount();
                        // @todo FIXME: i18n issue/patchwork message
                        $wgOut->addHTML( '<strong class="mw-delete-warning-revisions">' .
                                wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) .
@@ -1341,7 +1406,7 @@ class Article extends Page {
                                '</strong>'
                        );
 
-                       if ( $bigHistory ) {
+                       if ( $this->mTitle->isBigDeletion() ) {
                                global $wgDeleteRevisionsLimit;
                                $wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
                                        array( 'delete-warning-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
@@ -1465,10 +1530,8 @@ class Article extends Page {
        public function doDelete( $reason, $suppress = false ) {
                global $wgOut;
 
-               $id = $this->getTitle()->getArticleID( Title::GAID_FOR_UPDATE );
-
                $error = '';
-               if ( $this->mPage->doDeleteArticle( $reason, $suppress, $id, true, $error ) ) {
+               if ( $this->mPage->doDeleteArticle( $reason, $suppress, 0, true, $error ) ) {
                        $deleted = $this->getTitle()->getPrefixedText();
 
                        $wgOut->setPageTitle( wfMessage( 'actioncomplete' ) );
@@ -1616,6 +1679,7 @@ class Article extends Page {
         * @deprecated since 1.19
         */
        public function info() {
+               wfDeprecated( __METHOD__, '1.19' );
                Action::factory( 'info', $this )->show();
        }
 
@@ -1624,6 +1688,7 @@ class Article extends Page {
         * @deprecated since 1.18
         */
        public function markpatrolled() {
+               wfDeprecated( __METHOD__, '1.18' );
                Action::factory( 'markpatrolled', $this )->show();
        }
 
@@ -1640,6 +1705,7 @@ class Article extends Page {
         * @deprecated since 1.19
         */
        public function revert() {
+               wfDeprecated( __METHOD__, '1.19' );
                Action::factory( 'revert', $this )->show();
        }
 
@@ -1648,6 +1714,7 @@ class Article extends Page {
         * @deprecated since 1.19
         */
        public function rollback() {
+               wfDeprecated( __METHOD__, '1.19' );
                Action::factory( 'rollback', $this )->show();
        }
 
@@ -1657,6 +1724,7 @@ class Article extends Page {
         * @deprecated since 1.18
         */
        public function watch() {
+               wfDeprecated( __METHOD__, '1.18' );
                Action::factory( 'watch', $this )->show();
        }
 
@@ -1670,6 +1738,7 @@ class Article extends Page {
         */
        public function doWatch() {
                global $wgUser;
+               wfDeprecated( __METHOD__, '1.18' );
                return WatchAction::doWatch( $this->getTitle(), $wgUser );
        }
 
@@ -1679,6 +1748,7 @@ class Article extends Page {
         * @deprecated since 1.18
         */
        public function unwatch() {
+               wfDeprecated( __METHOD__, '1.18' );
                Action::factory( 'unwatch', $this )->show();
        }
 
@@ -1689,6 +1759,7 @@ class Article extends Page {
         */
        public function doUnwatch() {
                global $wgUser;
+               wfDeprecated( __METHOD__, '1.18' );
                return WatchAction::doUnwatch( $this->getTitle(), $wgUser );
        }
 
@@ -1702,7 +1773,7 @@ class Article extends Page {
         * @param $extraQuery String: extra query params
         */
        public function doRedirect( $noRedir = false, $sectionAnchor = '', $extraQuery = '' ) {
-               wfDeprecated( __METHOD__ );
+               wfDeprecated( __METHOD__, '1.18' );
                global $wgOut;
 
                if ( $noRedir ) {
@@ -1766,6 +1837,18 @@ class Article extends Page {
 
        // ****** B/C functions to work-around PHP silliness with __call and references ****** //
 
+       /**
+        * @param $limit array
+        * @param $expiry array
+        * @param $cascade bool
+        * @param $reason string
+        * @param $user User
+        * @return Status
+        */
+       public function doUpdateRestrictions( array $limit, array $expiry, &$cascade, $reason, User $user ) {
+               return $this->mPage->doUpdateRestrictions( $limit, $expiry, $cascade, $reason, $user );
+       }
+
        /**
         * @param $limit array
         * @param $reason string
@@ -1823,7 +1906,9 @@ class Article extends Page {
         * @return mixed
         */
        public function generateReason( &$hasHistory ) {
-               return $this->mPage->getAutoDeleteReason( $hasHistory );
+        $title = $this->mPage->getTitle();
+        $handler = ContentHandler::getForTitle( $title );
+               return $handler->getAutoDeleteReason( $title, $hasHistory );
        }
 
        // ****** B/C functions for static methods ( __callStatic is PHP>=5.3 ) ****** //
@@ -1861,6 +1946,7 @@ class Article extends Page {
         * @param $newtext
         * @param $flags
         * @return string
+     * @deprecated since 1.20, use ContentHandler::getAutosummary() instead
         */
        public static function getAutosummary( $oldtext, $newtext, $flags ) {
                return WikiPage::getAutosummary( $oldtext, $newtext, $flags );