https://www.mediawiki.org/wiki/Special:Code/MediaWiki/114155
Revision: 114155
Author: daniel
Date: 2012-03-19 17:10:15 +0000 (Mon, 19 Mar 2012)
Log Message:
-----------
messing with replaceSection()
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-19 17:09:23 UTC
(rev 114154)
+++ branches/Wikidata/phase3/includes/Content.php 2012-03-19 17:10:15 UTC
(rev 114155)
@@ -2,47 +2,33 @@
/**
* A content object represents page content, e.g. the text to show on a page.
+ * Content objects have no knowledge about how they relate to Wiki pages.
+ * Content objects are imutable.
*
*/
abstract class Content {
- public function __construct( Title $title = null, $revId = null,
$modelName = null ) { #FIXME: really need revId? annoying! #FIXME: really
$title? or just when parsing, every time?
+ public function __construct( $modelName = null ) { #FIXME: really need
revId? annoying! #FIXME: really $title? or just when parsing, every time?
$this->mModelName = $modelName;
- $this->mTitle = $title;
- $this->mRevId = $revId;
}
public function getModelName() {
return $this->mModelName;
}
- public function getTitle() {
- return $this->mTitle;
- }
+ public abstract function getSearchText( );
- public function getRevId() {
- return $this->mRevId;
- }
+ public abstract function getWikitextForTransclusion( );
- public abstract function getSearchText( $obj );
-
- public abstract function getWikitextForTransclusion( $obj );
-
- public abstract function getParserOutput( ParserOptions $options = NULL );
-
+ /**
+ * Returns native represenation of the data. Interpretation depends on the
data model used,
+ * as given by getDataModel().
+ *
+ */
public abstract function getRawData( );
- public function getHtml( ParserOptions $options ) {
- $po = $this->getParserOutput( $options );
- return $po->getText();
- }
+ public abstract function getParserOutput( Title $title = null, $revId =
null, ParserOptions $options = NULL );
- public function getIndexUpdateJobs( ParserOptions $options , $recursive =
true ) {
- $po = $this->getParserOutput( $options );
- $update = new LinksUpdate( $this->mTitle, $po, $recursive );
- return $update;
- }
-
public function getRedirectChain() {
return null;
}
@@ -60,20 +46,20 @@
}
/**
- * Replaces the section with the given id.
+ * Replaces a section of the content.
*
- * The default implementation returns $this.
- *
- * @param String $sectionId the section's id
- * @param Content $with the section's new content
- * @return Content a new content object with the section replaced, or this
content object if the section couldn't be replaced.
+ * @param $section empty/null/false or a section number (0, 1, 2, T1,
T2...), or "new"
+ * @param $with Content: new content of the section
+ * @param $sectionTitle String: new section's subject, only if $section is
'new'
+ * @return string Complete article text, or null if error
*/
- public function replaceSection( $sectionId ) {
+ public function replaceSection( $section, Content $with, $sectionTitle =
'' ) {
+ return $this;
}
- #XXX: is the native model for wikitext a string or the parser output?
parse early or parse late?
+ #TODO: implement specialized ParserOutput for Wikidata model
+ #TODO: provide addToParserOutput fule Multipart... somehow.
-
# TODO: EditPage::mergeChanges( Content $a, Content $b )
# TODO: Wikipage::isCountable(Content $a)
# TODO: Title::newFromRedirectRecurse( $this->getRawText() );
@@ -82,7 +68,6 @@
# TODO: getSize( )
# TODO: WikiPage::getUndoText( Revision $undo, Revision $undoafter = null )
- # TODO: WikiPage::replaceSection( $section, $text, $sectionTitle = '',
$edittime = null )
# TODO: WikiPage::getAutosummary( $oldtext, $text, $flags )
# TODO: EditPage::getPreloadedText( $preload ) // $wgParser->getPreloadText
@@ -94,23 +79,50 @@
}
-class TextContent extends Content {
- public function __construct( $text, Title $title = null, $revId = null,
$modelName = null ) {
- parent::__construct($title, $revId, $modelName);
+/**
+ * Content object implementation for representing flat text. The
+ */
+abstract class TextContent extends Content {
+ public function __construct( $text, $modelName = null ) {
+ parent::__construct($modelName);
$this->mText = $text;
}
- public function getSearchText( $obj ) {
+ /**
+ * Returns the text represented by this Content object, as a string.
+ *
+ * @return String the raw text
+ */
+ public function getRawData( ) {
+ $text = $this->mText;
+ return $text;
+ }
+
+ /**
+ * Returns the text represented by this Content object, as a string.
+ *
+ * @return String the raw text
+ */
+ public function getSearchText( ) { #FIXME: use!
return $this->getRawData();
}
- public function getWikitextForTransclusion( $obj ) {
+ /**
+ * Returns the text represented by this Content object, as a string.
+ *
+ * @return String the raw text
+ */
+ public function getWikitextForTransclusion( ) { #FIXME: use!
return $this->getRawData();
}
-
- public function getParserOutput( ParserOptions $options = null ) {
+ /**
+ * Returns a generic ParserOutput object, wrapping the HTML returned by
getHtml().
+ *
+ * @return ParserOutput representing the HTML form of the text
+ */
+ public function getParserOutput( Title $title = null, $revId = null,
ParserOptions $options = null ) {
# generic implementation, relying on $this->getHtml()
$html = $this->getHtml( $options );
@@ -123,53 +135,39 @@
return $po;
}
- public function getHtml( ParserOptions $options ) {
- $html = "";
- $html .= "<pre class=\"mw-code\" dir=\"ltr\">\n";
- $html .= htmlspecialchars( $this->getRawData() );
- $html .= "\n</pre>\n";
+ protected abstract function getHtml( );
- return $html;
- }
-
-
- public function getRawData( ) {
- $text = $this->mText;
- return $text;
- }
-
- public function getRedirectChain() {
- #XXX: really do this for all text, or just in WikitextContent?
- $text = $this->getRawData();
- return Title::newFromRedirectArray( $text );
- }
}
class WikitextContent extends TextContent {
- public function __construct( $text, Title $title, $revId = null) {
- parent::__construct($text, $title, $revId, CONTENT_MODEL_WIKITEXT);
+ public function __construct( $text ) {
+ parent::__construct($text, CONTENT_MODEL_WIKITEXT);
- $this->mDefaultParserOptions = null;
+ $this->mDefaultParserOptions = null; #TODO: use per-class static
member?!
}
+ protected function getHtml( ) {
+ throw new MWException( "getHtml() not implemented for wikitext. Use
getParserOutput()->getText()." );
+ }
+
public function getDefaultParserOptions() {
global $wgUser, $wgContLang;
- if ( !$this->mDefaultParserOptions ) {
- #TODO: use static member?!
+ if ( !$this->mDefaultParserOptions ) { #TODO: use per-class static
member?!
$this->mDefaultParserOptions = ParserOptions::newFromUserAndLang(
$wgUser, $wgContLang );
}
return $this->mDefaultParserOptions;
}
- public function getParserOutput( ParserOptions $options = null ) {
+ /**
+ * Returns a ParserOutput object reesulting from parsing the content's
text using $wgParser
+ *
+ * @return ParserOutput representing the HTML form of the text
+ */
+ public function getParserOutput( Title $title = null, $revId = null,
ParserOptions $options = null ) {
global $wgParser;
- #TODO: quick local cache: if $options is NULL, use ->mParserOutput!
- #FIXME: need setParserOutput, so we can use stuff from the parser
cache??
- #FIXME: ...or we somehow need to know the parser cache key??
-
if ( !$options ) {
$options = $this->getDefaultParserOptions();
}
@@ -190,80 +188,64 @@
$text = $this->getRawData();
$sect = $wgParser->getSection( $text, $section, false );
- $title = Title::newFromDBkey( $this->mTitle->getText() . '#' .
$section, $this->mTitle->getNamespace() ); #FIXME: get rid of titles here
- return new WikitextContent( $sect, $title );
+ return new WikitextContent( $sect );
}
/**
- * Replaces the section with the given id.
+ * Replaces a section in the wikitext
*
- * @param String $sectionId the section's id
- * @param Content $with the section's new content
- * @return Boolean true if te section was replaced sucessfully, false
otherwise
- */
- #FIXME: implement replaceSection(), use in WikiPage
-
- /**
- * @param $section empty/null/false or a section number (0, 1, 2, T1,
T2...)
- * @param $text String: new text of the section
+ * @param $section empty/null/false or a section number (0, 1, 2, T1,
T2...), or "new"
+ * @param $with Content: new content of the section
* @param $sectionTitle String: new section's subject, only if $section is
'new'
- * @param $edittime String: revision timestamp or null to use the current
revision
* @return string Complete article text, or null if error
*/
- /*public function replaceSection( $section, $text, $sectionTitle = '',
$edittime = null ) { #FIXME: adopt this!
+ public function replaceSection( $section, Content $with, $sectionTitle =
'' ) {
+ global $wgParser;
+
wfProfileIn( __METHOD__ );
- if ( strval( $section ) == '' ) {
- // Whole-page edit; let the whole text through
- } else {
- // Bug 30711: always use current version when adding a new section
- if ( is_null( $edittime ) || $section == 'new' ) {
- $oldtext = $this->getRawText();
- if ( $oldtext === false ) {
- wfDebug( __METHOD__ . ": no page text\n" );
- wfProfileOut( __METHOD__ );
- return null;
- }
- } else {
- $dbw = wfGetDB( DB_MASTER );
- $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle,
$edittime );
+ $myModelName = $this->getModelName();
+ $sectionModelName = $with->getModelName();
- if ( !$rev ) {
- wfDebug( "WikiPage::replaceSection asked for bogus section
(page: " .
- $this->getId() . "; section: $section; edittime:
$edittime)\n" );
- wfProfileOut( __METHOD__ );
- return null;
- }
+ if ( $sectionModelName != $myModelName ) {
+ throw new MWException( "Incompatible content model for section:
document uses $myModelName, section uses $sectionModelName." );
+ }
- $oldtext = $rev->getText();
- }
+ $oldtext = $this->getRawData();
+ $text = $with->getRawData();
- if ( $section == 'new' ) {
- # Inserting a new section
- $subject = $sectionTitle ? wfMsgForContent(
'newsectionheaderdefaultlevel', $sectionTitle ) . "\n\n" : '';
- if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext,
$subject, &$text ) ) ) {
- $text = strlen( trim( $oldtext ) ) > 0
- ? "{$oldtext}\n\n{$subject}{$text}"
- : "{$subject}{$text}";
- }
- } else {
- # Replacing an existing section; roll out the big guns
- global $wgParser;
-
- $text = $wgParser->replaceSection( $oldtext, $section, $text );
+ if ( $section == 'new' ) {
+ # Inserting a new section
+ $subject = $sectionTitle ? wfMsgForContent(
'newsectionheaderdefaultlevel', $sectionTitle ) . "\n\n" : '';
+ if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext,
$subject, &$text ) ) ) {
+ $text = strlen( trim( $oldtext ) ) > 0
+ ? "{$oldtext}\n\n{$subject}{$text}"
+ : "{$subject}{$text}";
}
+ } else {
+ # Replacing an existing section; roll out the big guns
+ global $wgParser;
+
+ $text = $wgParser->replaceSection( $oldtext, $section, $text );
}
+ $newContent = new WikitextContent( $text );
+
wfProfileOut( __METHOD__ );
- return $text;
- } */
+ return $newContent;
+ }
+ public function getRedirectChain() {
+ $text = $this->getRawData();
+ return Title::newFromRedirectArray( $text );
+ }
+
}
class MessageContent extends TextContent {
public function __construct( $msg_key, $params = null, $options = null ) {
- parent::__construct(null, null, null, CONTENT_MODEL_WIKITEXT);
+ parent::__construct(null, CONTENT_MODEL_WIKITEXT);
$this->mMessageKey = $msg_key;
@@ -275,13 +257,19 @@
$this->mHtmlOptions = null;
}
-
- public function getHtml( ParserOptions $options ) {
+ /**
+ * Returns the message as rendered HTML, using the options supplied to the
constructor plus "parse".
+ */
+ protected function getHtml( ) {
$opt = array_merge( $this->mOptions, array('parse') );
+
return wfMsgExt( $this->mMessageKey, $this->mParameters, $opt );
}
+ /**
+ * Returns the message as raw text, using the options supplied to the
constructor minus "parse" and "parseinline".
+ */
public function getRawData( ) {
$opt = array_diff( $this->mOptions, array('parse', 'parseinline') );
@@ -292,11 +280,11 @@
class JavaScriptContent extends TextContent {
- public function __construct( $text, Title $title, $revId = null ) {
- parent::__construct($text, $title, $revId, CONTENT_MODEL_JAVASCRIPT);
+ public function __construct( $text ) {
+ parent::__construct($text, CONTENT_MODEL_JAVASCRIPT);
}
- public function getHtml( ParserOptions $options ) {
+ protected function getHtml( ) {
$html = "";
$html .= "<pre class=\"mw-code mw-js\" dir=\"ltr\">\n";
$html .= htmlspecialchars( $this->getRawData() );
@@ -308,11 +296,11 @@
}
class CssContent extends TextContent {
- public function __construct( $text, Title $title, $revId = null ) {
- parent::__construct($text, $title, $revId, CONTENT_MODEL_CSS);
+ public function __construct( $text ) {
+ parent::__construct($text, CONTENT_MODEL_CSS);
}
- public function getHtml( ParserOptions $options ) {
+ protected function getHtml( ) {
$html = "";
$html .= "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n";
$html .= htmlspecialchars( $this->getRawData() );
@@ -322,10 +310,8 @@
}
}
-#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
+#FUTURE: special type for redirects?!
+#FUTURE: MultipartMultipart < WikipageContent (Main + Links + X)
+#FUTURE: LinksContent < LanguageLinksContent, CategoriesContent
#EXAMPLE: CoordinatesContent
#EXAMPLE: WikidataContent
Modified: branches/Wikidata/phase3/includes/ContentHandler.php
===================================================================
--- branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-19
17:09:23 UTC (rev 114154)
+++ branches/Wikidata/phase3/includes/ContentHandler.php 2012-03-19
17:10:15 UTC (rev 114155)
@@ -29,11 +29,13 @@
return null;
}
- public static function makeContent( $text, Title $title, $format = null,
$revId = null ) {
- $handler = ContentHandler::getForTitle( $title );
+ public static function makeContent( $text, Title $title, $modelName =
null, $format = null ) {
+ if ( !$modelName ) {
+ $modelName = $title->getContentModelName();
+ }
- #FIXME: pass revid?
- return $handler->unserialize( $text, $title, $format );
+ $handler = ContentHandler::getForModelName( $modelName );
+ return $handler->unserialize( $text, $format );
}
public static function getDefaultModelFor( Title $title ) {
@@ -141,11 +143,11 @@
return $this->mSupportedFormats[0];
}
- public abstract function serialize( Content $content, Title $title,
$format = null );
+ public abstract function serialize( Content $content, $format = null );
- public abstract function unserialize( $blob, Title $title, $format = null
); #FIXME: ...and revId?
+ public abstract function unserialize( $blob, $format = null );
- public abstract function newContent( Title $title );
+ public abstract function emptyContent();
# public abstract function doPreSaveTransform( $title, $obj ); #TODO...
@@ -199,13 +201,6 @@
return $de;
}
- public function getIndexUpdateJobs( Title $title, ParserOutput
$parserOutput, $recursive = true ) {
- # for wikitext, create a LinksUpdate object
- # for wikidata: serialize arrays to json
- $update = new LinksUpdate( $title, $parserOutput, $recursive );
- return $update;
- }
-
#XXX: is the native model for wikitext a string or the parser output?
parse early or parse late?
#TODO: how to handle extra message for JS/CSS previews??
@@ -221,7 +216,8 @@
parent::__construct( $modelName, $formats );
}
- public function serialize( Content $content, Title $title, $format = null
) {
+ public function serialize( Content $content, $format = null ) {
+ #FIXME: assert format
return $content->getRawData();
}
@@ -232,12 +228,13 @@
parent::__construct( $modelName, array( 'application/x-wikitext' ) );
#FIXME: mime
}
- public function unserialize( $text, Title $title, $format = null ) {
- return new WikitextContent($text, $title);
+ public function unserialize( $text, $format = null ) {
+ #FIXME: assert format
+ return new WikitextContent($text);
}
- public function newContent( Title $title) {
- return new WikitextContent("", $title);
+ public function emptyContent() {
+ return new WikitextContent("");
}
}
@@ -248,12 +245,12 @@
parent::__construct( $modelName, array( 'text/javascript' ) );
}
- public function unserialize( $text, Title $title, $format = null ) {
- return new JavaScriptContent($text, $title);
+ public function unserialize( $text, $format = null ) {
+ return new JavaScriptContent($text);
}
- public function newContent( Title $title) {
- return new JavaScriptContent("", $title);
+ public function emptyContent() {
+ return new JavaScriptContent("");
}
}
@@ -263,12 +260,12 @@
parent::__construct( $modelName, array( 'text/css' ) );
}
- public function unserialize( $text, Title $title, $format = null ) {
- return new CssContent($text, $title);
+ public function unserialize( $text, $format = null ) {
+ return new CssContent($text);
}
- public function newContent( Title $title) {
- return new CssContent("", $title);
+ public function emptyContent() {
+ return new CssContent("");
}
}
Modified: branches/Wikidata/phase3/includes/EditPage.php
===================================================================
--- branches/Wikidata/phase3/includes/EditPage.php 2012-03-19 17:09:23 UTC
(rev 114154)
+++ branches/Wikidata/phase3/includes/EditPage.php 2012-03-19 17:10:15 UTC
(rev 114155)
@@ -1299,10 +1299,12 @@
if ( $this->isConflict ) {
wfDebug( __METHOD__ . ": conflict! getting
section '$this->section' for time '$this->edittime' (article time
'{$timestamp}')\n" );
- $text = $this->mArticle->replaceSection(
$this->section, $this->textbox1, $sectionTitle, $this->edittime );
+ $cnt = $this->mArticle->replaceSection(
$this->section, $this->textbox1, $sectionTitle, $this->edittime );
+ $text = ContentHandler::getContentText($cnt); #FIXME: use
Content object throughout, make edit form aware of content model and
serialization format
} else {
wfDebug( __METHOD__ . ": getting section
'$this->section'\n" );
- $text = $this->mArticle->replaceSection(
$this->section, $this->textbox1, $sectionTitle );
+ $cnt = $this->mArticle->replaceSection( $this->section,
$this->textbox1, $sectionTitle );
+ $text = ContentHandler::getContentText($cnt); #FIXME: use
Content object throughout, make edit form aware of content model and
serialization format
}
if ( is_null( $text ) ) {
wfDebug( __METHOD__ . ": activating conflict;
section replace failed.\n" );
Modified: branches/Wikidata/phase3/includes/WikiPage.php
===================================================================
--- branches/Wikidata/phase3/includes/WikiPage.php 2012-03-19 17:09:23 UTC
(rev 114154)
+++ branches/Wikidata/phase3/includes/WikiPage.php 2012-03-19 17:10:15 UTC
(rev 114155)
@@ -1127,18 +1127,21 @@
* @param $text String: new text of the section
* @param $sectionTitle String: new section's subject, only if $section
is 'new'
* @param $edittime String: revision timestamp or null to use the
current revision
- * @return string Complete article text, or null if error
+ * @return Content new complete article content, or null if error
*/
- public function replaceSection( $section, $text, $sectionTitle = '',
$edittime = null ) { #FIXME: move to Content object!
+ public function replaceSection( $section, $text, $sectionTitle = '',
$edittime = null ) {
wfProfileIn( __METHOD__ );
+ $sectionContent = ContentHandler::makeContent( $text,
$this->getTitle() ); #XXX: could make section title, but that's not required.
+
if ( strval( $section ) == '' ) {
// Whole-page edit; let the whole text through
+ $newContent = $sectionContent;
} else {
// Bug 30711: always use current version when adding a
new section
if ( is_null( $edittime ) || $section == 'new' ) {
- $oldtext = $this->getRawText();
- if ( $oldtext === false ) {
+ $oldContent = $this->getContent();
+ if ( ! $oldContent ) {
wfDebug( __METHOD__ . ": no page
text\n" );
wfProfileOut( __METHOD__ );
return null;
@@ -1154,27 +1157,14 @@
return null;
}
- $oldtext = $rev->getText();
+ $oldContent = $rev->getContent();
}
- if ( $section == 'new' ) {
- # Inserting a new section
- $subject = $sectionTitle ? wfMsgForContent(
'newsectionheaderdefaultlevel', $sectionTitle ) . "\n\n" : '';
- if ( wfRunHooks( 'PlaceNewSection', array(
$this, $oldtext, $subject, &$text ) ) ) {
- $text = strlen( trim( $oldtext ) ) > 0
- ?
"{$oldtext}\n\n{$subject}{$text}"
- : "{$subject}{$text}";
- }
- } else {
- # Replacing an existing section; roll out the
big guns
- global $wgParser;
-
- $text = $wgParser->replaceSection( $oldtext,
$section, $text );
- }
+ $newContent = $oldContent->replaceSection( $section,
$sectionContent, $sectionTitle );
}
wfProfileOut( __METHOD__ );
- return $text;
+ return $newContent;
}
/**
@@ -2831,7 +2821,9 @@
*/
function __construct( Page $page, ParserOptions $parserOptions, $revid,
$useParserCache, $content = null ) {
if ( is_string($content) ) { #BC: old style call
- $content = ContentHandler::makeContent( $content,
$page->getTitle(), null, $this->revid ); #FIXME: format? from revision?
+ $modelName = $page->getRevision()->getContentModelName();
+ $format = $page->getRevision()->getContentFormat();
+ $content = ContentHandler::makeContent( $content,
$page->getTitle(), $modelName, $format );
}
$this->page = $page;
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs