https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113044
Revision: 113044
Author: daniel
Date: 2012-03-05 15:53:25 +0000 (Mon, 05 Mar 2012)
Log Message:
-----------
adapted WikiPage and Article (work in progress)
Modified Paths:
--------------
branches/Wikidata/phase3/includes/Article.php
branches/Wikidata/phase3/includes/Content.php
branches/Wikidata/phase3/includes/ContentHandler.php
branches/Wikidata/phase3/includes/Revision.php
branches/Wikidata/phase3/includes/WikiPage.php
branches/Wikidata/phase3/includes/specials/SpecialUndelete.php
Modified: branches/Wikidata/phase3/includes/Article.php
===================================================================
--- branches/Wikidata/phase3/includes/Article.php 2012-03-05 15:34:27 UTC
(rev 113043)
+++ branches/Wikidata/phase3/includes/Article.php 2012-03-05 15:53:25 UTC
(rev 113044)
@@ -38,6 +38,7 @@
public $mParserOptions;
var $mContent; // !< #FIXME: use Content object!
+ var $mContentObject; // !<
var $mContentLoaded = false; // !<
var $mOldId; // !<
@@ -189,8 +190,25 @@
* 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() {
+ public function getContent() { #FIXME: deprecated! replace usage! use
content object!
+ 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__ );
@@ -208,12 +226,12 @@
}
wfProfileOut( __METHOD__ );
- return $text;
+ return new WikitextContent( $text, $this->getTitle() );
} else {
- $this->fetchContent();
+ $this->fetchContentObject();
wfProfileOut( __METHOD__ );
- return $this->mContent;
+ return $this->mContentObject;
}
}
@@ -292,61 +310,89 @@
* 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 ) {
+ function fetchContent() { #BC cruft! #FIXME: deprecated, replace usage
+ 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 );
+ 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
+ */
+ 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
Modified: branches/Wikidata/phase3/includes/Content.php
===================================================================
--- branches/Wikidata/phase3/includes/Content.php 2012-03-05 15:34:27 UTC
(rev 113043)
+++ branches/Wikidata/phase3/includes/Content.php 2012-03-05 15:53:25 UTC
(rev 113044)
@@ -68,6 +68,8 @@
$html = $this->getHtml( $options );
$po = new ParserOutput( $html );
+ if ( $this->mTitle ) $po->setTitleText( $this->mTitle->getText() );
+
#TODO: cache settings, etc?
return $po;
@@ -84,8 +86,6 @@
public function getRawData( ) {
- global $wgParser, $wgUser;
-
$text = $this->mText;
return $text;
}
@@ -128,7 +128,36 @@
}
+class MessageContent extends TextContent {
+ public function __construct( $msg_key, $params = null, $options = null ) {
+ parent::__construct(null, null, null, CONTENT_MODEL_WIKITEXT);
+ $this->mMessageKey = $msg_key;
+
+ $this->mParameters = $params;
+
+ if ( !$options ) $options = array();
+ $this->mOptions = $options;
+
+ $this->mHtmlOptions = null;
+ }
+
+
+ public function getHtml( ParserOptions $options ) {
+ $opt = array_merge( $this->mOptions, array('parse') );
+ return wfMsgExt( $this->mMessageKey, $this->mParameters, $opt );
+ }
+
+
+ public function getRawData( ) {
+ $opt = array_diff( $this->mOptions, array('parse', 'parseinline') );
+
+ return wfMsgExt( $this->mMessageKey, $this->mParameters, $opt );
+ }
+
+}
+
+
class JavaScriptContent extends TextContent {
public function __construct( $text, Title $title, $revId = null ) {
parent::__construct($text, $title, $revId, CONTENT_MODEL_JAVASCRIPT);
@@ -160,6 +189,9 @@
}
}
+#FIXME: special type for redirects?!
+#FIXME: special type for message-based pseudo-content? with raw html?
+
#TODO: MultipartMultipart < WikipageContent (Main + Links + X)
#TODO: LinksContent < LanguageLinksContent, CategoriesContent
#EXAMPLE: CoordinatesContent
Modified: branches/Wikidata/phase3/includes/ContentHandler.php
===================================================================
--- branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-05
15:34:27 UTC (rev 113043)
+++ branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-05
15:53:25 UTC (rev 113044)
@@ -13,6 +13,18 @@
*/
abstract class ContentHandler {
+ public static function getContentText( Content $content ) {
+ if ( !$content ) return '';
+
+ if ( $content instanceof TextContent ) {
+ #XXX: or check by model name?
+ #XXX: or define $content->allowRawData()?
+ return $content->getRawData();
+ }
+
+ return null;
+ }
+
public static function getDefaultModelFor( Title $title ) {
global $wgNamespaceContentModels;
Modified: branches/Wikidata/phase3/includes/Revision.php
===================================================================
--- branches/Wikidata/phase3/includes/Revision.php 2012-03-05 15:34:27 UTC
(rev 113043)
+++ branches/Wikidata/phase3/includes/Revision.php 2012-03-05 15:53:25 UTC
(rev 113044)
@@ -21,7 +21,9 @@
protected $mTitle;
protected $mCurrent;
protected $mContentModelName;
- protected $mContentType;
+ protected $mContentFormat;
+ protected $mContent;
+ protected $mContentHandler;
const DELETED_TEXT = 1;
const DELETED_COMMENT = 2;
@@ -128,7 +130,7 @@
'len' => $row->ar_len,
'sha1' => isset( $row->ar_sha1 ) ? $row->ar_sha1
: null,
'content_model' => isset( $row->ar_content_model ) ?
$row->ar_content_model : null,
- 'content_type' => isset( $row->ar_content_type ) ?
$row->ar_content_type : null,
+ 'content_format' => isset( $row->ar_content_format ) ?
$row->ar_content_format : null,
);
if ( isset( $row->ar_text ) && !$row->ar_text_id ) {
// Pre-1.5 ar_text row
@@ -339,7 +341,9 @@
'rev_deleted',
'rev_len',
'rev_parent_id',
- 'rev_sha1'
+ 'rev_sha1',
+ 'rev_content_format',
+ 'rev_content_model'
);
}
@@ -422,10 +426,10 @@
$this->mContentModelName = strval( $row->rev_content_model );
}
- if( !isset( $row->rev_content_type ) || is_null(
$row->rev_content_type ) ) {
- $this->mContentType = null; # determine on demand if needed
+ if( !isset( $row->rev_content_format ) || is_null(
$row->rev_content_format ) ) {
+ $this->mContentFormat = null; # determine on demand if needed
} else {
- $this->mContentType = strval( $row->rev_content_type );
+ $this->mContentFormat = strval( $row->rev_content_format );
}
// Lazy extraction...
@@ -449,6 +453,19 @@
// Build a new revision to be saved...
global $wgUser; // ugh
+
+ # if we have a content object, use it to set the model and type
+ if ( !empty( $row['content'] ) ) {
+ if ( !empty( $row['text_id'] ) ) { #FIXME: when is that set?
test with external store setup! check out insertOn()
+ throw new MWException( "Text already stored in external
store (id {$row['text_id']}), can't serialize content object" );
+ }
+
+ $row['content_model'] = $row['content']->getModelName();
+ # note: mContentFormat is initializes later accordingly
+ # note: content is serialized later in this method!
+ # also set text to null?
+ }
+
$this->mId = isset( $row['id'] ) ?
intval( $row['id'] ) : null;
$this->mPage = isset( $row['page'] ) ?
intval( $row['page'] ) : null;
$this->mTextId = isset( $row['text_id'] ) ?
intval( $row['text_id'] ) : null;
@@ -462,12 +479,12 @@
$this->mSha1 = isset( $row['sha1'] ) ?
strval( $row['sha1'] ) : null;
$this->mContentModelName = isset( $row['content_model'] ) ?
strval( $row['content_model'] ) : null;
- $this->mContentType = isset( $row['content_type'] ) ?
strval( $row['content_type'] ) : null;
+ $this->mContentFormat = isset( $row['content_format'] ) ?
strval( $row['content_format'] ) : null;
- if( !isset( $row->rev_content_type ) || is_null(
$row->rev_content_type ) ) {
- $this->mContentType = null; # determine on demand if needed
+ if( !isset( $row->rev_content_format ) || is_null(
$row->rev_content_format ) ) {
+ $this->mContentFormat = null; # determine on demand if needed
} else {
- $this->mContentType = $row->rev_content_type;
+ $this->mContentFormat = $row->rev_content_format;
}
// Enforce spacing trimming on supplied text
@@ -487,11 +504,20 @@
}
$this->getContentModelName(); # force lazy init
- $this->getContentType(); # force lazy init
+ $this->getContentFormat(); # force lazy init
+
+ # if we have a content object, serialize it, overriding mText
+ if ( !empty( $row['content'] ) ) {
+ $handler = $this->getContentHandler();
+ $this->mText = $handler->serialize( $row['content'],
$this->getContentFormat() );
+ }
} else {
throw new MWException( 'Revision constructor passed
invalid row format.' );
}
$this->mUnpatrolled = null;
+
+ #FIXME: add patch for ar_content_format, ar_content_model,
rev_content_format, rev_content_model to installer
+ #FIXME: add support for ar_content_format, ar_content_model,
rev_content_format, rev_content_model to API
}
/**
@@ -755,19 +781,9 @@
*/
public function getText( $audience = self::FOR_PUBLIC, User $user =
null ) { #FIXME: deprecated, replace usage!
wfDeprecated( __METHOD__, '1.20' );
+
$content = $this->getContent();
-
- if ( $content == null ) {
- return ""; # not allowed
- }
-
- if ( $content instanceof TextContent ) {
- #FIXME: or check by model name? or define $content->allowRawData()?
- return $content->getRawData();
- }
-
- #TODO: log this failure!
- return null;
+ return ContentHandler::getContentText( $content ); # returns the raw
content text, if applicable
}
/**
@@ -818,14 +834,14 @@
// Revision is immutable. Load on demand:
$handler = $this->getContentHandler();
- $type = $this->getContentType();
+ $format = $this->getContentFormat();
if( is_null( $this->mText ) ) {
// Load text on demand:
$this->mText = $this->loadText();
}
- $this->mContent = $handler->unserialize( $this->mText, $type );
+ $this->mContent = $handler->unserialize( $this->mText, $format );
}
return $this->mContent;
@@ -840,19 +856,22 @@
return $this->mContentModelName;
}
- public function getContentType() {
- if ( !$this->mContentType ) {
+ public function getContentFormat() {
+ if ( !$this->mContentFormat ) {
$handler = $this->getContentHandler();
- $this->mContentType = $handler->getDefaultFormat();
+ $this->mContentFormat = $handler->getDefaultFormat();
}
- return $this->mContentType;
+ return $this->mContentFormat;
}
public function getContentHandler() {
if ( !$this->mContentHandler ) {
$m = $this->getModelName();
$this->mContentHandler = ContentHandler::getForModelName( $m );
+
+ #XXX: do we need to verify that mContentHandler supports
mContentFormat?
+ # otherwise, a fixed content format may cause problems on
insert.
}
return $this->mContentHandler;
@@ -1098,7 +1117,7 @@
? Revision::base36Sha1( $this->mText )
: $this->mSha1,
'rev_content_model' => $this->getContentModelName(),
- 'rev_content_type' => $this->getContentType(),
+ 'rev_content_format' => $this->getContentFormat(),
), __METHOD__
);
@@ -1199,7 +1218,7 @@
$current = $dbw->selectRow(
array( 'page', 'revision' ),
array( 'page_latest', 'rev_text_id', 'rev_len',
'rev_sha1',
- 'rev_content_model', 'rev_content_type' ),
+ 'rev_content_model', 'rev_content_format' ),
array(
'page_id' => $pageId,
'page_latest=rev_id',
@@ -1216,7 +1235,7 @@
'len' => $current->rev_len,
'sha1' => $current->rev_sha1,
'content_model' => $current->rev_content_model,
- 'content_type' => $current->rev_content_type
+ 'content_format' =>
$current->rev_content_format
) );
} else {
$revision = null;
Modified: branches/Wikidata/phase3/includes/WikiPage.php
===================================================================
--- branches/Wikidata/phase3/includes/WikiPage.php 2012-03-05 15:34:27 UTC
(rev 113043)
+++ branches/Wikidata/phase3/includes/WikiPage.php 2012-03-05 15:53:25 UTC
(rev 113044)
@@ -161,6 +161,7 @@
'page_touched',
'page_latest',
'page_len',
+ 'page_content_model',
);
}
@@ -383,6 +384,23 @@
return null;
}
+ /**
+ * Get the content of the current revision. No side-effects...
+ *
+ * @param $audience Integer: one of:
+ * Revision::FOR_PUBLIC to be displayed to all users
+ * Revision::FOR_THIS_USER to be displayed to $wgUser
+ * Revision::RAW get the text regardless of permissions
+ * @return String|null The content of the current revision
+ */
+ public function getContent( $audience = Revision::FOR_PUBLIC ) {
+ $this->loadLastEdit();
+ if ( $this->mLastRevision ) {
+ return $this->mLastRevision->getContent( $audience );
+ }
+ return false;
+ }
+
/**
* Get the text of the current revision. No side-effects...
*
@@ -391,8 +409,10 @@
* Revision::FOR_THIS_USER to be displayed to $wgUser
* Revision::RAW get the text regardless of
permissions
* @return String|false The text of the current revision
+ * @deprecated as of 1.20, getContent() should be used instead.
*/
- public function getText( $audience = Revision::FOR_PUBLIC ) {
+ public function getText( $audience = Revision::FOR_PUBLIC ) { #FIXME:
deprecated, replace usage!
+ wfDeprecated( __METHOD__, '1.20' );
$this->loadLastEdit();
if ( $this->mLastRevision ) {
return $this->mLastRevision->getText( $audience );
@@ -405,12 +425,8 @@
*
* @return String|false The text of the current revision
*/
- public function getRawText() {
- $this->loadLastEdit();
- if ( $this->mLastRevision ) {
- return $this->mLastRevision->getRawText();
- }
- return false;
+ public function getRawText() { #FIXME: deprecated, replace usage!
+ return $this->getText( Revision::RAW );
}
/**
@@ -1293,7 +1309,7 @@
'page' => $this->getId(),
'comment' => $summary,
'minor_edit' => $isminor,
- 'text' => $text,
+ 'text' => $text, #FIXME: set content
instead, leavfe serialization to revision?!
'parent_id' => $oldid,
'user' => $user->getId(),
'user_text' => $user->getName(),
@@ -1963,7 +1979,9 @@
'ar_len' => 'rev_len',
'ar_page_id' => 'page_id',
'ar_deleted' => $bitfield,
- 'ar_sha1' => 'rev_sha1'
+ 'ar_sha1' => 'rev_content_model',
+ 'ar_content_format' =>
'rev_content_format',
+ 'ar_content_format' => 'rev_sha1'
), array(
'page_id' => $id,
'page_id = rev_page'
Modified: branches/Wikidata/phase3/includes/specials/SpecialUndelete.php
===================================================================
--- branches/Wikidata/phase3/includes/specials/SpecialUndelete.php
2012-03-05 15:34:27 UTC (rev 113043)
+++ branches/Wikidata/phase3/includes/specials/SpecialUndelete.php
2012-03-05 15:53:25 UTC (rev 113044)
@@ -116,7 +116,8 @@
$res = $dbr->select( 'archive',
array(
'ar_minor_edit', 'ar_timestamp', 'ar_user',
'ar_user_text',
- 'ar_comment', 'ar_len', 'ar_deleted',
'ar_rev_id', 'ar_sha1'
+ 'ar_comment', 'ar_len', 'ar_deleted',
'ar_rev_id', 'ar_sha1',
+ 'ar_content_format', 'ar_content_model'
),
array( 'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey() ),
@@ -189,6 +190,8 @@
'ar_deleted',
'ar_len',
'ar_sha1',
+ 'ar_content_format',
+ 'ar_content_model',
),
array( 'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey(),
@@ -463,7 +466,9 @@
'ar_deleted',
'ar_page_id',
'ar_len',
- 'ar_sha1' ),
+ 'ar_sha1',
+ 'ar_content_format',
+ 'ar_content_model' ),
/* WHERE */ array(
'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey(),
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs