Merge "MCR: Deprecate and gut Revision class"
[lhc/web/wiklou.git] / includes / page / WikiPage.php
index 1047a93..6af7945 100644 (file)
@@ -23,6 +23,7 @@
 use MediaWiki\Edit\PreparedEdit;
 use \MediaWiki\Logger\LoggerFactory;
 use \MediaWiki\MediaWikiServices;
+use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DBError;
@@ -194,15 +195,15 @@ class WikiPage implements Page, IDBAccessObject {
         */
        private static function convertSelectType( $type ) {
                switch ( $type ) {
-               case 'fromdb':
-                       return self::READ_NORMAL;
-               case 'fromdbmaster':
-                       return self::READ_LATEST;
-               case 'forupdate':
-                       return self::READ_LOCKING;
-               default:
-                       // It may already be an integer or whatever else
-                       return $type;
+                       case 'fromdb':
+                               return self::READ_NORMAL;
+                       case 'fromdbmaster':
+                               return self::READ_LATEST;
+                       case 'forupdate':
+                               return self::READ_LOCKING;
+                       default:
+                               // It may already be an integer or whatever else
+                               return $type;
                }
        }
 
@@ -671,7 +672,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $revision = Revision::newFromPageId( $this->getId(), $latest, $flags );
                } else {
                        $dbr = wfGetDB( DB_REPLICA );
-                       $revision = Revision::newKnownCurrent( $dbr, $this->getId(), $latest );
+                       $revision = Revision::newKnownCurrent( $dbr, $this->getTitle(), $latest );
                }
 
                if ( $revision ) { // sanity
@@ -1264,8 +1265,11 @@ class WikiPage implements Page, IDBAccessObject {
                        $conditions['page_latest'] = $lastRevision;
                }
 
+               $revId = $revision->getId();
+               Assert::parameter( $revId > 0, '$revision->getId()', 'must be > 0' );
+
                $row = [ /* SET */
-                       'page_latest'      => $revision->getId(),
+                       'page_latest'      => $revId,
                        'page_touched'     => $dbw->timestamp( $revision->getTimestamp() ),
                        'page_is_new'      => ( $lastRevision === 0 ) ? 1 : 0,
                        'page_is_redirect' => $rt !== null ? 1 : 0,
@@ -1305,7 +1309,7 @@ class WikiPage implements Page, IDBAccessObject {
         * Add row to the redirect table if this is a redirect, remove otherwise.
         *
         * @param IDatabase $dbw
-        * @param Title $redirectTitle Title object pointing to the redirect target,
+        * @param Title|null $redirectTitle Title object pointing to the redirect target,
         *   or NULL if this is not a redirect
         * @param null|bool $lastRevIsRedirect If given, will optimize adding and
         *   removing rows in redirect table.
@@ -1617,13 +1621,20 @@ class WikiPage implements Page, IDBAccessObject {
                $old_revision = $this->getRevision(); // current revision
                $old_content = $this->getContent( Revision::RAW ); // current revision's content
 
-               if ( $old_content && $old_content->getModel() !== $content->getModel() ) {
-                       $tags[] = 'mw-contentmodelchange';
+               $handler = $content->getContentHandler();
+               $tag = $handler->getChangeTag( $old_content, $content, $flags );
+               // If there is no applicable tag, null is returned, so we need to check
+               if ( $tag ) {
+                       $tags[] = $tag;
+               }
+
+               // Check for undo tag
+               if ( $undidRevId !== 0 && in_array( 'mw-undo', ChangeTags::getSoftwareTags() ) ) {
+                       $tags[] = 'mw-undo';
                }
 
-               // Provide autosummaries if one is not provided and autosummaries are enabled
+               // Provide autosummaries if summary is not provided and autosummaries are enabled
                if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) {
-                       $handler = $content->getContentHandler();
                        $summary = $handler->getAutosummary( $old_content, $content, $flags );
                }
 
@@ -1705,27 +1716,27 @@ class WikiPage implements Page, IDBAccessObject {
                        throw new MWException( "Could not find text for current revision {$oldid}." );
                }
 
-               // @TODO: pass content object?!
-               $revision = new Revision( [
-                       'page'       => $this->getId(),
-                       'title'      => $this->mTitle, // for determining the default content model
-                       'comment'    => $summary,
-                       'minor_edit' => $meta['minor'],
-                       'text'       => $meta['serialized'],
-                       'len'        => $newsize,
-                       'parent_id'  => $oldid,
-                       'user'       => $user->getId(),
-                       'user_text'  => $user->getName(),
-                       'timestamp'  => $now,
-                       'content_model' => $content->getModel(),
-                       'content_format' => $meta['serialFormat'],
-               ] );
-
                $changed = !$content->equals( $oldContent );
 
                $dbw = wfGetDB( DB_MASTER );
 
                if ( $changed ) {
+                       // @TODO: pass content object?!
+                       $revision = new Revision( [
+                               'page'       => $this->getId(),
+                               'title'      => $this->mTitle, // for determining the default content model
+                               'comment'    => $summary,
+                               'minor_edit' => $meta['minor'],
+                               'text'       => $meta['serialized'],
+                               'len'        => $newsize,
+                               'parent_id'  => $oldid,
+                               'user'       => $user->getId(),
+                               'user_text'  => $user->getName(),
+                               'timestamp'  => $now,
+                               'content_model' => $content->getModel(),
+                               'content_format' => $meta['serialFormat'],
+                       ] );
+
                        $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
                        $status->merge( $prepStatus );
                        if ( !$status->isOK() ) {
@@ -1791,11 +1802,9 @@ class WikiPage implements Page, IDBAccessObject {
                } else {
                        // T34948: revision ID must be set to page {{REVISIONID}} and
                        // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
-                       $revision->setId( $this->getLatest() );
-                       $revision->setUserIdAndName(
-                               $this->getUser( Revision::RAW ),
-                               $this->getUserText( Revision::RAW )
-                       );
+                       // Since we don't insert a new revision into the database, the least
+                       // error-prone way is to reuse given old revision.
+                       $revision = $meta['oldRevision'];
                }
 
                if ( $changed ) {
@@ -3213,6 +3222,10 @@ class WikiPage implements Page, IDBAccessObject {
                $targetContent = $target->getContent();
                $changingContentModel = $targetContent->getModel() !== $current->getContentModel();
 
+               if ( in_array( 'mw-rollback', ChangeTags::getSoftwareTags() ) ) {
+                       $tags[] = 'mw-rollback';
+               }
+
                // Actually store the edit
                $status = $this->doEditContent(
                        $targetContent,
@@ -3289,7 +3302,8 @@ class WikiPage implements Page, IDBAccessObject {
                        'summary' => $summary,
                        'current' => $current,
                        'target' => $target,
-                       'newid' => $revId
+                       'newid' => $revId,
+                       'tags' => $tags
                ];
 
                return [];
@@ -3319,7 +3333,9 @@ class WikiPage implements Page, IDBAccessObject {
                MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title );
 
                // Invalidate caches of articles which include this page
-               DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) );
+               DeferredUpdates::addUpdate(
+                       new HTMLCacheUpdate( $title, 'templatelinks', 'page-create' )
+               );
 
                if ( $title->getNamespace() == NS_CATEGORY ) {
                        // Load the Category object, which will schedule a job to create
@@ -3357,7 +3373,9 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Images
                if ( $title->getNamespace() == NS_FILE ) {
-                       DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'imagelinks' ) );
+                       DeferredUpdates::addUpdate(
+                               new HTMLCacheUpdate( $title, 'imagelinks', 'page-delete' )
+                       );
                }
 
                // User talk pages
@@ -3380,10 +3398,14 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public static function onArticleEdit( Title $title, Revision $revision = null ) {
                // Invalidate caches of articles which include this page
-               DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) );
+               DeferredUpdates::addUpdate(
+                       new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' )
+               );
 
                // Invalidate the caches of all pages which redirect here
-               DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'redirect' ) );
+               DeferredUpdates::addUpdate(
+                       new HTMLCacheUpdate( $title, 'redirect', 'page-edit' )
+               );
 
                MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title );