Call new Content::prepareSave from WikiPage::doEditContent.
authordaniel <daniel.kinzler@wikimedia.de>
Wed, 27 Jun 2012 07:42:49 +0000 (09:42 +0200)
committerdaniel <daniel.kinzler@wikimedia.de>
Wed, 27 Jun 2012 07:42:49 +0000 (09:42 +0200)
Content::prepareSave() is called  by WikiPage::doEditContent() inside the
transaction bracket for saving the new content, but before anything is actually
saved. This allows the content to first be normalized and checked against the
current database content; it also allows for some data to be written to the
database up front.

Change-Id: I78946ea5ec34dce08068692e2d77a8a0b7c11777

includes/Content.php
includes/ContentHandler.php
includes/SqlDataUpdate.php
includes/WikiPage.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php

index 161289c..f7f0346 100644 (file)
@@ -357,6 +357,27 @@ interface Content {
         */
        public function preloadTransform( Title $title, ParserOptions $popts );
 
+       /**
+        * Prepare Content for saving. Called before Content is saved by WikiPage::doEditContent().
+        * This may be used to store additional information in the database, or check the content's
+        * consistency with global state.
+        *
+        * Note that this method will be called inside the same transaction bracket that will be used
+        * to save the new revision.
+        *
+        * @param WikiPage $page The page to be saved.
+        * @param int      $flags bitfield for use with EDIT_XXX constants, see WikiPage::doEditContent()
+        * @param int      $baseRevId the ID of the current revision
+        * @param User     $user
+        *
+        * @return Status A status object indicating whether the content was successfully prepared for saving.
+        *                If the returned status indicates an error, a rollback will be performed and the
+        *                transaction aborted.
+        *
+        * @see see WikiPage::doEditContent()
+        */
+       public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user );
+
        # TODO: handle ImagePage and CategoryPage
        # TODO: make sure we cover lucene search / wikisearch.
        # TODO: make sure ReplaceTemplates still works
@@ -611,6 +632,17 @@ abstract class AbstractContent implements Content {
        public function preloadTransform( Title $title, ParserOptions $popts ) {
                return $this;
        }
+
+       /**
+        * @see  Content::prepareSave()
+        */
+       public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user ) {
+               if ( $this->isValid() ) {
+                       return Status::newGood();
+               } else {
+                       return Status::newFatal( "invalid-content-data" );
+               }
+       }
 }
 
 /**
index 99468e0..c90e140 100644 (file)
@@ -498,24 +498,6 @@ abstract class ContentHandler {
                }
        }
 
-       /**
-        * Returns true if the content is consistent with the database, that is if
-        * saving it to the database would not violate any global constraints.
-        *
-        * Content needs to be valid using this method before it can be saved.
-        *
-        * This default implementation always returns true.
-        *
-        * @since WD.1
-        *
-        * @param $content \Content
-        *
-        * @return boolean
-        */
-       public function isConsistentWithDatabase( Content $content ) {
-               return true;
-       }
-
        /**
         * Returns overrides for action handlers.
         * Classes listed here will be used instead of the default one when
index a56a454..f6b183f 100644 (file)
@@ -78,7 +78,7 @@ abstract class SqlDataUpdate extends DataUpdate {
         * Abort the database transaction started via beginTransaction (if any).
         */
        public function abortTransaction() {
-               if ( $this->mHasTransaction ) {
+               if ( $this->mHasTransaction ) { //XXX: actually... maybe always?
                        $this->mDb->rollback( get_class( $this ) . '::abortTransaction' );
                }
        }
index b30f1bc..ad1fded 100644 (file)
@@ -1729,6 +1729,17 @@ class WikiPage extends Page {
                                }
 
                                $dbw->begin( __METHOD__ );
+
+                               $prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
+                               $status->merge( $prepStatus );
+
+                               if ( !$status->isOK() ) {
+                                       $dbw->rollback();
+
+                                       wfProfileOut( __METHOD__ );
+                                       return $status;
+                               }
+
                                $revisionId = $revision->insertOn( $dbw );
 
                                # Update page
@@ -1803,6 +1814,18 @@ class WikiPage extends Page {
 
                        $dbw->begin( __METHOD__ );
 
+                       $prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
+                       $status->merge( $prepStatus );
+
+                       if ( !$status->isOK() ) {
+                               $dbw->rollback();
+
+                               wfProfileOut( __METHOD__ );
+                               return $status;
+                       }
+
+                       $status->merge( $prepStatus );
+
                        # Add the page record; stake our claim on this title!
                        # This will return false if the article already exists
                        $newid = $this->insertOn( $dbw );
index 8b3cde5..fd1f6d5 100644 (file)
@@ -1413,7 +1413,7 @@ If you save it, any changes made since this revision will be lost.",
 'yourdiff'                         => 'Differences',
 'copyrightwarning'                 => "Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details).
 If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.<br />
-You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
+You are also promising us that you wrote this yourself, or copied editpageit from a public domain or similar free resource.
 '''Do not submit copyrighted work without permission!'''",
 'copyrightwarning2'                => "Please note that all contributions to {{SITENAME}} may be edited, altered, or removed by other contributors.
 If you do not want your writing to be edited mercilessly, then do not submit it here.<br />
@@ -1469,6 +1469,7 @@ It already exists.',
 'addsection-preload'               => '', # do not translate or duplicate this message to other languages
 'addsection-editintro'             => '', # do not translate or duplicate this message to other languages
 'defaultmessagetext'               => 'Default message text',
+'invalid-content-data'             => 'Invalid content data',
 
 # Parser/template warnings
 'expensive-parserfunction-warning'        => "'''Warning:''' This page contains too many expensive parser function calls.
index c8e4357..ab7f7a3 100644 (file)
@@ -1023,6 +1023,7 @@ Please report at [[Support]] if you are unable to properly translate this messag
 'moveddeleted-notice' => 'Shown on top of a deleted page in normal view modus ([http://translatewiki.net/wiki/Test example]).',
 'edit-conflict' => "An 'Edit conflict' happens when more than one edit is being made to a page at the same time. This would usually be caused by separate individuals working on the same page. However, if the system is slow, several edits from one individual could back up and attempt to apply simultaneously - causing the conflict.",
 'defaultmessagetext' => 'Caption above the default message text shown on the left-hand side of a diff displayed after clicking “Show changes” when creating a new page in the MediaWiki: namespace',
+'invalid-content-data'             => 'Error message indicating that the page\'s content can not be saved because it is invalid. This may occurr for some non-text content types.',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'On some (expensive) [[MetaWikipedia:Help:ParserFunctions|parser functions]] (e.g. <code><nowiki>{{#ifexist:}}</nowiki></code>) there is a limit of how many times it may be used. This is an error message shown when the limit is exceeded.