https://www.mediawiki.org/wiki/Special:Code/MediaWiki/114275
Revision: 114275
Author: daniel
Date: 2012-03-20 15:00:26 +0000 (Tue, 20 Mar 2012)
Log Message:
-----------
doEdit(), etc
Modified Paths:
--------------
branches/Wikidata/phase3/includes/Content.php
branches/Wikidata/phase3/includes/ContentHandler.php
branches/Wikidata/phase3/includes/EditPage.php
branches/Wikidata/phase3/includes/WikiPage.php
Modified: branches/Wikidata/phase3/includes/Content.php
===================================================================
--- branches/Wikidata/phase3/includes/Content.php 2012-03-20 14:45:28 UTC
(rev 114274)
+++ branches/Wikidata/phase3/includes/Content.php 2012-03-20 15:00:26 UTC
(rev 114275)
@@ -16,6 +16,14 @@
return $this->mModelName;
}
+ public function getContentHandler() {
+ return ContentHandler::getForContent( $this );
+ }
+
+ public function serialize( $format = null ) {
+ return $this->getContentHandler()->serialize( $this, $format );
+ }
+
public abstract function getTextForSearchIndex( );
public abstract function getWikitextForTransclusion( );
@@ -33,8 +41,10 @@
/**
* returns the content's nominal size in bogo-bytes.
+ *
+ * @return int
*/
- public abstract function getSize( ); #XXX: do we really need/want this
here? we could just use the byte syse of the serialized form...
+ public abstract function getSize( );
public function isEmpty() {
return $this->getSize() == 0;
@@ -95,6 +105,18 @@
return $this;
}
+ /**
+ * Returns a Content object with pre-save transformations applied (or this
object if no transformations apply).
+ *
+ * @param Title $title
+ * @param User $user
+ * @param null|ParserOptions $popts
+ * @return Content
+ */
+ public function preSaveTransform( Title $title, User $user, ParserOptions
$popts = null ) {
+ return $this;
+ }
+
#TODO: implement specialized ParserOutput for Wikidata model
#TODO: provide "combined" ParserOutput for Multipart... somehow.
@@ -102,7 +124,7 @@
# TODO: EditPage::getPreloadedText( $preload ) // $wgParser->getPreloadText
# TODO: tie into EditPage, make it use Content-objects throughout, make
edit form aware of content model and format
- # TODO: tie into WikiPage, make it use Content-objects throughout,
especially in doEdit(), doDelete(), updateRevisionOn(), etc
+ # TODO: tie into WikiPage, make it use Content-objects throughout,
especially in doEditUpdates(), doDelete(), updateRevisionOn(), etc
# TODO: make model-aware diff view!
# TODO: handle ImagePage and CategoryPage
@@ -307,6 +329,23 @@
return $newContent;
}
+ /**
+ * Returns a Content object with pre-save transformations applied (or this
object if no transformations apply).
+ *
+ * @param Title $title
+ * @param User $user
+ * @param null|ParserOptions $popts
+ * @return Content
+ */
+ public function preSaveTransform( Title $title, User $user, ParserOptions
$popts = null ) {
+ global $wgParser;
+
+ $text = $this->getNativeData();
+ $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts );
+
+ return new WikitextContent( $pst );
+ }
+
public function getRedirectChain() {
$text = $this->getNativeData();
return Title::newFromRedirectArray( $text );
Modified: branches/Wikidata/phase3/includes/ContentHandler.php
===================================================================
--- branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-20
14:45:28 UTC (rev 114274)
+++ branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-20
15:00:26 UTC (rev 114275)
@@ -13,7 +13,7 @@
*/
abstract class ContentHandler {
- public static function getContentText( Content $content ) {
+ public static function getContentText( Content $content = null ) {
if ( !$content ) return '';
if ( $content instanceof TextContent ) {
@@ -26,6 +26,7 @@
#XXX: this must not be used for editing, otherwise we may loose data:
#XXX: e.g. if this returns the "main" text from a multipart page,
all attachments would be lost
+ #TODO: log this incident!
return null;
}
@@ -167,8 +168,6 @@
public abstract function emptyContent();
- # public abstract function doPreSaveTransform( $title, $obj ); #TODO...
-
/**
* Return an Article object suitable for viewing the given object
*
@@ -385,10 +384,10 @@
* between $undo and $undoafter. Revisions must belong to the same page,
* must exist and must not be deleted
* @param $undo Revision
- * @param $undoafter Revision Must be an earlier revision than $undo
+ * @param $undoafter null|Revision Must be an earlier revision than $undo
* @return mixed string on success, false on failure
*/
- public function getUndoContent( Revision $current, Revision $undo,
Revision $undoafter ) {
+ public function getUndoContent( Revision $current, Revision $undo,
Revision $undoafter = null ) {
$cur_content = $current->getContent();
if ( empty( $cur_content ) ) {
Modified: branches/Wikidata/phase3/includes/EditPage.php
===================================================================
--- branches/Wikidata/phase3/includes/EditPage.php 2012-03-20 14:45:28 UTC
(rev 114274)
+++ branches/Wikidata/phase3/includes/EditPage.php 2012-03-20 15:00:26 UTC
(rev 114275)
@@ -1433,7 +1433,7 @@
( ( $this->minoredit && !$this->isNew ) ? EDIT_MINOR :
0 ) |
( $bot ? EDIT_FORCE_BOT : 0 );
- $doEditStatus = $this->mArticle->doEdit( $text, $this->summary,
$flags );
+ $doEditStatus = $this->mArticle->doEdit( $text, $this->summary,
$flags ); # FIXME: use WikiPage::doEditContent()
if ( $doEditStatus->isOK() ) {
$result['redirect'] = Title::newFromRedirect( $text )
!== null;
Modified: branches/Wikidata/phase3/includes/WikiPage.php
===================================================================
--- branches/Wikidata/phase3/includes/WikiPage.php 2012-03-20 14:45:28 UTC
(rev 114274)
+++ branches/Wikidata/phase3/includes/WikiPage.php 2012-03-20 15:00:26 UTC
(rev 114275)
@@ -1231,8 +1231,64 @@
* revision: The revision object for the inserted
revision, or null
*
* Compatibility note: this function previously returned a boolean
value indicating success/failure
+ * @deprecated since 1.20: use doEditContent() instead.
*/
- public function doEdit( $text, $summary, $flags = 0, $baseRevId =
false, $user = null ) { #FIXME: change $text to $content
+ public function doEdit( $text, $summary, $flags = 0, $baseRevId = false,
$user = null ) { #FIXME: use doEditContent() instead
+ #TODO: log use of deprecated function
+ $content = ContentHandler::makeContent( $text, $this->getTitle() );
+
+ return $this->doEditContent( $content, $summary, $flags, $baseRevId,
$user );
+ }
+
+ /**
+ * Change an existing article or create a new article. Updates RC and all
necessary caches,
+ * optionally via the deferred update array.
+ *
+ * @param $content Content: new content
+ * @param $summary String: edit summary
+ * @param $flags Integer bitfield:
+ * EDIT_NEW
+ * Article is known or assumed to be non-existent, create a new
one
+ * EDIT_UPDATE
+ * Article is known or assumed to be pre-existing, update it
+ * EDIT_MINOR
+ * Mark this edit minor, if the user is allowed to do so
+ * EDIT_SUPPRESS_RC
+ * Do not log the change in recentchanges
+ * EDIT_FORCE_BOT
+ * Mark the edit a "bot" edit regardless of user rights
+ * EDIT_DEFER_UPDATES
+ * Defer some of the updates until the end of index.php
+ * EDIT_AUTOSUMMARY
+ * Fill in blank summaries with generated text where possible
+ *
+ * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the
article will be detected.
+ * If EDIT_UPDATE is specified and the article doesn't exist, the function
will return an
+ * edit-gone-missing error. If EDIT_NEW is specified and the article does
exist, an
+ * edit-already-exists error will be returned. These two conditions are
also possible with
+ * auto-detection due to MediaWiki's performance-optimised locking
strategy.
+ *
+ * @param $baseRevId the revision ID this edit was based off, if any
+ * @param $user User the user doing the edit
+ * @param $serialisation_format String: format for storing the content in
the database
+ *
+ * @return Status object. Possible errors:
+ * edit-hook-aborted: The ArticleSave hook aborted the edit but
didn't set the fatal flag of $status
+ * edit-gone-missing: In update mode, but the article didn't
exist
+ * edit-conflict: In update mode, the article changed
unexpectedly
+ * edit-no-change: Warning that the text was the same as
before
+ * edit-already-exists: In creation mode, but the article already
exists
+ *
+ * Extensions may define additional errors.
+ *
+ * $return->value will contain an associative array with members as
follows:
+ * new: Boolean indicating if the function
attempted to create a new article
+ * revision: The revision object for the inserted
revision, or null
+ *
+ * Compatibility note: this function previously returned a boolean value
indicating success/failure
+ */
+ public function doEditContent( Content $content, $summary, $flags = 0,
$baseRevId = false,
+ User $user = null, $serialisation_format =
null ) { #FIXME: use this
global $wgUser, $wgDBtransactions, $wgUseAutomaticEditSummaries;
# Low-level sanity check
@@ -1250,11 +1306,26 @@
$flags = $this->checkFlags( $flags );
- if ( !wfRunHooks( 'ArticleSave', array( &$this, &$user, &$text,
&$summary,
- $flags & EDIT_MINOR, null, null, &$flags, &$status ) ) )
- {
- wfDebug( __METHOD__ . ": ArticleSave hook aborted
save!\n" );
+ # call legacy hook
+ $hook_ok = wfRunHooks( 'ArticleContentSave', array( &$this, &$user,
&$content, &$summary, #FIXME: document new hook!
+ $flags & EDIT_MINOR, null, null, &$flags, &$status ) );
+ if ( $hook_ok && !empty( $wgHooks['ArticleSave'] ) ) { # avoid
serialization overhead if the hook isn't present
+ $content_text = $content->serialize();
+ $txt = $content_text; # clone
+
+ $hook_ok = wfRunHooks( 'ArticleSave', array( &$this, &$user,
&$txt, &$summary, #FIXME: deprecate legacy hook!
+ $flags & EDIT_MINOR, null, null, &$flags, &$status ) );
+
+ if ( $txt !== $content_text ) {
+ # if the text changed, unserialize the new version to create
an updated Content object.
+ $content = $content->getContentHandler()->unserialize( $txt );
+ }
+ }
+
+ if ( !$hook_ok ) {
+ wfDebug( __METHOD__ . ": ArticleSave or
ArticleSaveContent hook aborted save!\n" );
+
if ( $status->isOK() ) {
$status->fatal( 'edit-hook-aborted' );
}
@@ -1267,20 +1338,24 @@
$isminor = ( $flags & EDIT_MINOR ) && $user->isAllowed(
'minoredit' );
$bot = $flags & EDIT_FORCE_BOT;
- $oldtext = $this->getNativeData(); // current revision #FIXME:
may not be a string. check Content model!
- $oldsize = strlen( $oldtext );
+ $old_content = $this->getContent( Revision::RAW ); // current
revision's content
+
+ $oldsize = $old_content ? $old_content->getSize() : 0;
$oldid = $this->getLatest();
$oldIsRedirect = $this->isRedirect();
$oldcountable = $this->isCountable();
+ $handler = $content->getContentHandler();
+
# Provide autosummaries if one is not provided and
autosummaries are enabled.
if ( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY
&& $summary == '' ) {
- $summary = self::getAutosummary( $oldtext, $text,
$flags ); #FIXME: ContentHandler::getAutosummary()
+ $summary = $handler->getAutosummary( $old_content,
$content, $flags );
}
- $editInfo = $this->prepareTextForEdit( $text, null, $user );
- $text = $editInfo->pst;
- $newsize = strlen( $text );
+ $editInfo = $this->prepareContentForEdit( $content, null,
$user, $serialisation_format );
+ $serialized = $editInfo->pst;
+ $content = $editInfo->pstContent;
+ $newsize = $content->getSize();
$dbw = wfGetDB( DB_MASTER );
$now = wfTimestampNow();
@@ -1308,14 +1383,15 @@
'page' => $this->getId(),
'comment' => $summary,
'minor_edit' => $isminor,
- 'text' => $text, #FIXME: set content
instead, leave serialization to revision?!
+ 'text' => $serialized,
+ 'len' => $newsize,
'parent_id' => $oldid,
'user' => $user->getId(),
'user_text' => $user->getName(),
'timestamp' => $now
) );
- $changed = ( strcmp( $text, $oldtext ) != 0 );
+ $changed = !$content->equals( $old_content );
if ( $changed ) {
$dbw->begin();
@@ -1413,7 +1489,8 @@
'page' => $newid,
'comment' => $summary,
'minor_edit' => $isminor,
- 'text' => $text,
+ 'text' => $serialized,
+ 'len' => $newsize,
'user' => $user->getId(),
'user_text' => $user->getName(),
'timestamp' => $now
@@ -1434,7 +1511,7 @@
$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
# Add RC row to the DB
$rc = RecentChange::notifyNew( $now,
$this->mTitle, $isminor, $user, $summary, $bot,
- '', strlen( $text ), $revisionId,
$patrolled );
+ '', $content->getSize(), $revisionId,
$patrolled );
# Log auto-patrolled edits
if ( $patrolled ) {
@@ -1447,8 +1524,11 @@
# Update links, etc.
$this->doEditUpdates( $revision, $user, array(
'created' => true ) );
- wfRunHooks( 'ArticleInsertComplete', array( &$this,
&$user, $text, $summary,
+ wfRunHooks( 'ArticleInsertComplete', array( &$this,
&$user, $serialized, $summary, #FIXME: deprecate legacy hook
$flags & EDIT_MINOR, null, null, &$flags,
$revision ) );
+
+ wfRunHooks( 'ArticleContentInsertComplete', array( &$this, &$user,
$content, $summary, #FIXME: document new hook
+ $flags & EDIT_MINOR, null, null, &$flags, $revision ) );
}
# Do updates right now unless deferral was requested
@@ -1459,9 +1539,12 @@
// Return the new revision (or null) to the caller
$status->value['revision'] = $revision;
- wfRunHooks( 'ArticleSaveComplete', array( &$this, &$user,
$text, $summary,
+ wfRunHooks( 'ArticleSaveComplete', array( &$this, &$user,
$serialized, $summary, #FIXME: deprecate legacy hook
$flags & EDIT_MINOR, null, null, &$flags, $revision,
&$status, $baseRevId ) );
+ wfRunHooks( 'ArticleContentSaveComplete', array( &$this, &$user,
$content, $summary, #FIXME: document new hook
+ $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status,
$baseRevId ) );
+
# Promote user to any groups they meet the criteria for
$user->addAutopromoteOnceGroups( 'onEdit' );
@@ -1489,14 +1572,35 @@
/**
* Prepare text which is about to be saved.
* Returns a stdclass with source, pst and output members
+ * @deprecated in 1.20: use prepareContentForEdit instead.
*/
- public function prepareTextForEdit( $text, $revid = null, User $user =
null ) {
+ public function prepareTextForEdit( $text, $revid = null, User $user =
null ) { #FIXME: use prepareContentForEdit() instead #XXX: who uses this?!
+ #TODO: log use of deprecated function
+ $content = ContentHandler::makeContent( $text, $this->getTitle() );
+ return $this->prepareContentForEdit( $content, $revid , $user );
+ }
+
+ /**
+ * Prepare content which is about to be saved.
+ * Returns a stdclass with source, pst and output members
+ *
+ * @param \Content $content
+ * @param null $revid
+ * @param null|\User $user
+ * @param null $serialization_format
+ * @return bool|object
+ */
+ public function prepareContentForEdit( Content $content, $revid = null,
User $user = null, $serialization_format = null ) { #FIXME: use this #XXX:
really public?!
global $wgParser, $wgContLang, $wgUser;
$user = is_null( $user ) ? $wgUser : $user;
// @TODO fixme: check $user->getId() here???
+
if ( $this->mPreparedEdit
- && $this->mPreparedEdit->newText == $text
+ && $this->mPreparedEdit->newContent
+ && $this->mPreparedEdit->newContent->equals( $content )
&& $this->mPreparedEdit->revid == $revid
+ && $this->mPreparedEdit->format == $serialization_format
+ #XXX: also check $user here?
) {
// Already prepared
return $this->mPreparedEdit;
@@ -1507,12 +1611,20 @@
$edit = (object)array();
$edit->revid = $revid;
- $edit->newText = $text;
- $edit->pst = $wgParser->preSaveTransform( $text, $this->mTitle,
$user, $popts );
+
+ $edit->pstContent = $content->preSaveTransform( $this->mTitle,
$user, $popts );
+ $edit->pst = $edit->pstContent->serialize( $serialization_format );
+ $edit->format = $serialization_format;
+
$edit->popts = $this->makeParserOptions( 'canonical' );
- $edit->output = $wgParser->parse( $edit->pst, $this->mTitle,
$edit->popts, true, true, $revid );
- $edit->oldText = $this->getRawText(); #FIXME: $oldcontent
instead?!
+ $edit->output = $edit->pstContent->getParserOutput(
$this->mTitle, $revid, $edit->popts );
+ $edit->newContent = $content;
+ $edit->oldContent = $this->getContent( Revision::RAW );
+
+ $edit->newText = ContentHandler::getContentText( $edit->newContent );
#FIXME: B/C only! don't use this field!
+ $edit->oldText = $edit->oldContent ? ContentHandler::getContentText(
$edit->oldContent ) : ''; #FIXME: B/C only! don't use this field!
+
$this->mPreparedEdit = $edit;
return $edit;
@@ -1653,13 +1765,33 @@
* @param $comment String: comment submitted
* @param $minor Boolean: whereas it's a minor modification
*/
- public function doQuickEdit( $text, User $user, $comment = '', $minor =
0 ) {
+ public function doQuickEdit( $text, User $user, $comment = '', $minor = 0
) {
+ #TODO: log use of deprecated function
+ $content = ContentHandler::makeContent( $text, $this->getTitle() );
+ return $this->doQuickEdit( $content, $user, $comment , $minor );
+ }
+
+ /**
+ * Edit an article without doing all that other stuff
+ * The article must already exist; link tables etc
+ * are not updated, caches are not flushed.
+ *
+ * @param $content Content: content submitted
+ * @param $user User The relevant user
+ * @param $comment String: comment submitted
+ * @param $serialisation_format String: format for storing the content in
the database
+ * @param $minor Boolean: whereas it's a minor modification
+ */
+ public function doQuickEditContent( Content $content, User $user,
$comment = '', $minor = 0, $serialisation_format = null ) {
wfProfileIn( __METHOD__ );
+ $serialized = $content->serialize( $serialisation_format );
+
$dbw = wfGetDB( DB_MASTER );
$revision = new Revision( array(
'page' => $this->getId(),
- 'text' => $text,
+ 'text' => $serialized,
+ 'length' => $content->getSize(),
'comment' => $comment,
'minor_edit' => $minor ? 1 : 0,
) );
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs