Use integers for content_model and content_format.

Representing content_model and content_format as integers in the
database was suggested by Asher mainly to save space.

This change entails some refactoring and renaming, but no big
change in logic.
This commit is contained in:
daniel 2012-05-14 00:02:29 +02:00
parent 060b6c74c6
commit cbc2014b2d
33 changed files with 522 additions and 252 deletions

View file

@ -739,7 +739,7 @@ for a given title. May be used to assign a different model for that title.
$title: the Title in question
&$model: the model name. Use with CONTENT_MODEL_XXX constants.
'ContentHandlerForModelName': Called when a ContentHandler is requested for a given
'ContentHandlerForModelID': Called when a ContentHandler is requested for a given
cointent model name, but no entry for that model exists in $wgContentHandlers.
$modeName: the requested content model name
&$handler: set this to a ContentHandler object, if desired.

View file

@ -12,9 +12,9 @@ abstract class Content {
* Name of the content model this Content object represents.
* Use with CONTENT_MODEL_XXX constants
*
* @var String $model_name
* @var String $model_id
*/
protected $model_name;
protected $model_id;
/**
* @return String a string representing the content in a way useful for building a full text search index.
@ -58,31 +58,34 @@ abstract class Content {
public abstract function getSize( );
/**
* @param $model_name
* @param int $model_id
*/
public function __construct( $model_name = null ) {
$this->model_name = $model_name;
public function __construct( $model_id = null ) {
$this->model_id = $model_id;
}
/**
* Returns the name of the content model used by this content objects.
* Returns the id of the content model used by this content objects.
* Corresponds to the CONTENT_MODEL_XXX constants.
*
* @return String the model name
* @return int the model id
*/
public function getModelName() {
return $this->model_name;
public function getModel() {
return $this->model_id;
}
/**
* Throws an MWException if $model_name is not the name of the content model
* Throws an MWException if $model_id is not the id of the content model
* supported by this Content object.
*
* @param String $model_name the model to check
* @param int $model_id the model to check
*/
protected function checkModelName( $model_name ) {
if ( $model_name !== $this->model_name ) {
throw new MWException( "Bad content model: expected " . $this->model_name . " but got found " . $model_name );
protected function checkModelID( $model_id ) {
if ( $model_id !== $this->model_id ) {
$model_name = ContentHandler::getContentModelName( $model_id );
$own_model_name = ContentHandler::getContentModelName( $this->model_id );
throw new MWException( "Bad content model: expected {$this->model_id} ($own_model_name) but got found $model_id ($model_name)." );
}
}
@ -150,7 +153,7 @@ abstract class Content {
*/
protected function checkFormat( $format ) {
if ( !$this->isSupportedFormat( $format ) ) {
throw new MWException( "Format $format is not supported for content model " . $this->getModelName() );
throw new MWException( "Format $format is not supported for content model " . $this->getModel() );
}
}
@ -180,7 +183,7 @@ abstract class Content {
*
* Will returns false if $that is null.
* Will return true if $that === $this.
* Will return false if $that->getModleName() != $this->getModelName().
* Will return false if $that->getModleName() != $this->getModel().
* Will return false if $that->getNativeData() is not equal to $this->getNativeData(),
* where the meaning of "equal" depends on the actual data model.
*
@ -201,7 +204,7 @@ abstract class Content {
return true;
}
if ( $that->getModelName() !== $this->getModelName() ) {
if ( $that->getModel() !== $this->getModel() ) {
return false;
}
@ -213,7 +216,7 @@ abstract class Content {
* if $copy = $original->copy()
*
* * get_class($original) === get_class($copy)
* * $original->getModelName() === $copy->getModelName()
* * $original->getModel() === $copy->getModel()
* * $original->equals( $copy )
*
* If and only if the Content object is imutable, the copy() method can and should
@ -370,8 +373,8 @@ abstract class Content {
*/
abstract class TextContent extends Content {
public function __construct( $text, $model_name = null ) {
parent::__construct( $model_name );
public function __construct( $text, $model_id = null ) {
parent::__construct( $model_id );
$this->mText = $text;
}
@ -532,11 +535,15 @@ class WikitextContent extends TextContent {
public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
wfProfileIn( __METHOD__ );
$myModelName = $this->getModelName();
$sectionModelName = $with->getModelName();
$myModelId = $this->getModel();
$sectionModelId = $with->getModel();
if ( $sectionModelName != $myModelName ) {
throw new MWException( "Incompatible content model for section: document uses $myModelName, section uses $sectionModelName." );
if ( $sectionModelId != $myModelId ) {
$myModelName = ContentHandler::getContentModelName( $myModelId );
$sectionModelName = ContentHandler::getContentModelName( $sectionModelId );
throw new MWException( "Incompatible content model for section: document uses $myModelId ($myModelName), "
. "section uses $sectionModelId ($sectionModelName)." );
}
$oldtext = $this->getNativeData();

View file

@ -57,7 +57,7 @@ abstract class ContentHandler {
}
if ( $wgContentHandlerTextFallback == 'fail' ) {
throw new MWException( "Attempt to get text from Content with model " . $content->getModelName() );
throw new MWException( "Attempt to get text from Content with model " . $content->getModel() );
}
if ( $wgContentHandlerTextFallback == 'serialize' ) {
@ -70,25 +70,25 @@ abstract class ContentHandler {
/**
* Conveniance function for creating a Content object from a given textual representation.
*
* $text will be deserialized into a Content object of the model specified by $modelName (or,
* if that is not given, $title->getContentModelName()) using the given format.
* $text will be deserialized into a Content object of the model specified by $modelId (or,
* if that is not given, $title->getContentModel()) using the given format.
*
* @static
* @param string $text the textual represenation, will be unserialized to create the Content object
* @param Title $title the title of the page this text belongs to, required as a context for deserialization
* @param null|String $modelName the model to deserialize to. If not provided, $title->getContentModelName() is used.
* @param null|String $modelId the model to deserialize to. If not provided, $title->getContentModel() is used.
* @param null|String $format the format to use for deserialization. If not given, the model's default format is used.
*
* @return Content a Content object representing $text
* @throw MWException if $model or $format is not supported or if $text can not be unserialized using $format.
*/
public static function makeContent( $text, Title $title, $modelName = null, $format = null ) {
public static function makeContent( $text, Title $title, $modelId = null, $format = null ) {
if ( is_null( $modelName ) ) {
$modelName = $title->getContentModelName();
if ( is_null( $modelId ) ) {
$modelId = $title->getContentModel();
}
$handler = ContentHandler::getForModelName( $modelName );
$handler = ContentHandler::getForModelID( $modelId );
return $handler->unserializeContent( $text, $format );
}
@ -96,7 +96,7 @@ abstract class ContentHandler {
* Returns the name of the default content model to be used for the page with the given title.
*
* Note: There should rarely be need to call this method directly.
* To determine the actual content model for a given page, use Title::getContentModelName().
* To determine the actual content model for a given page, use Title::getContentModel().
*
* Which model is to be used per default for the page is determined based on several factors:
* * The global setting $wgNamespaceContentModels specifies a content model per namespace.
@ -108,7 +108,7 @@ abstract class ContentHandler {
*
* If none of the above applies, the wikitext model is used.
*
* Note: this is used by, and may thus not use, Title::getContentModelName()
* Note: this is used by, and may thus not use, Title::getContentModel()
*
* @static
* @param Title $title
@ -117,8 +117,8 @@ abstract class ContentHandler {
public static function getDefaultModelFor( Title $title ) {
global $wgNamespaceContentModels;
// NOTE: this method must not rely on $title->getContentModelName() directly or indirectly,
// because it is used to initialized the mContentModelName memebr.
// NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
// because it is used to initialized the mContentModel memebr.
$ns = $title->getNamespace();
@ -183,8 +183,8 @@ abstract class ContentHandler {
* @return ContentHandler
*/
public static function getForTitle( Title $title ) {
$modelName = $title->getContentModelName();
return ContentHandler::getForModelName( $modelName );
$modelId = $title->getContentModel();
return ContentHandler::getForModelID( $modelId );
}
/**
@ -195,12 +195,12 @@ abstract class ContentHandler {
* @return ContentHandler
*/
public static function getForContent( Content $content ) {
$modelName = $content->getModelName();
return ContentHandler::getForModelName( $modelName );
$modelId = $content->getModel();
return ContentHandler::getForModelID( $modelId );
}
/**
* returns the ContentHandler singleton for the given model name. Use the CONTENT_MODEL_XXX constants to
* returns the ContentHandler singleton for the given model id. Use the CONTENT_MODEL_XXX constants to
* identify the desired content model.
*
* ContentHandler singletons are take from the global $wgContentHandlers array. Keys in that array are
@ -210,48 +210,120 @@ abstract class ContentHandler {
* If a class name in encountered when looking up the singleton for a given model name, the class is
* instantiated and the class name is replaced by te resulting singleton in $wgContentHandlers.
*
* If no ContentHandler is defined for the desired $modelName, the ContentHandler may be provided by the
* a ContentHandlerForModelName hook. if no Contenthandler can be determined, an MWException is raised.
* If no ContentHandler is defined for the desired $modelId, the ContentHandler may be provided by the
* a ContentHandlerForModelID hook. if no Contenthandler can be determined, an MWException is raised.
*
* @static
* @param $modelName String the name of the content model for which to get a handler. Use CONTENT_MODEL_XXX constants.
* @return ContentHandler the ContentHandler singleton for handling the model given by $modelName
* @throws MWException if no handler is known for $modelName.
* @param $modelId int the id of the content model for which to get a handler. Use CONTENT_MODEL_XXX constants.
* @return ContentHandler the ContentHandler singleton for handling the model given by $modelId
* @throws MWException if no handler is known for $modelId.
*/
public static function getForModelName( $modelName ) {
public static function getForModelID( $modelId ) {
global $wgContentHandlers;
if ( empty( $wgContentHandlers[$modelName] ) ) {
if ( empty( $wgContentHandlers[$modelId] ) ) {
$handler = null;
wfRunHooks( 'ContentHandlerForModelName', array( $modelName, &$handler ) );
wfRunHooks( 'ContentHandlerForModelID', array( $modelId, &$handler ) );
if ( $handler ) { // NOTE: may be a string or an object, either is fine!
$wgContentHandlers[$modelName] = $handler;
$wgContentHandlers[$modelId] = $handler;
} else {
throw new MWException( "No handler for model $modelName registered in \$wgContentHandlers" );
throw new MWException( "No handler for model #$modelId registered in \$wgContentHandlers" );
}
}
if ( is_string( $wgContentHandlers[$modelName] ) ) {
$class = $wgContentHandlers[$modelName];
$wgContentHandlers[$modelName] = new $class( $modelName );
if ( is_string( $wgContentHandlers[$modelId] ) ) {
$class = $wgContentHandlers[$modelId];
$wgContentHandlers[$modelId] = new $class( $modelId );
}
return $wgContentHandlers[$modelName];
return $wgContentHandlers[$modelId];
}
/**
* Returns the appropriate mime type for a given content format,
* or null if no mime type is known for this format.
*
* Mime types can be registered in the global array $wgContentFormatMimeTypes.
*
* @static
* @param int $id the content format id, as given by a CONTENT_FORMAT_XXX constant
* or returned by Revision::getContentFormat().
*
* @return String|null the content format's mime type.
*/
public static function getContentFormatMimeType( $id ) {
global $wgContentFormatMimeTypes;
if ( !isset( $wgContentFormatMimeTypes[ $id ] ) ) {
return null;
}
return $wgContentFormatMimeTypes[ $id ];
}
/**
* Returns the content format if for a given mime type,
* or null if no format id if known for this mime type.
*
* Mime types can be registered in the global array $wgContentFormatMimeTypes.
*
* @static
* @param String $mime the mime type
*
* @return int|null the format id, as defined by a CONTENT_FORMAT_XXX constant
*/
public static function getContentFormatID( $mime ) {
global $wgContentFormatMimeTypes;
static $format_ids = null;
if ( $format_ids === null ) {
$format_ids = array_flip( $wgContentFormatMimeTypes );
}
if ( !isset( $format_ids[ $mime ] ) ) {
return null;
}
return $format_ids[ $mime ];
}
/**
* Returns the localized name for a given content model,
* or null of no mime type is known.
*
* Model names are localized using system messages. Message keys
* have the form conent-model-$id.
*
* @static
* @param int $id the content model id, as given by a CONTENT_MODEL_XXX constant
* or returned by Revision::getContentModel().
*
* @return String|null the content format's mime type.
*/
public static function getContentModelName( $id ) {
$key = "content-model-$id";
if ( wfEmptyMsg( $key ) ) return null;
else return wfMsg( $key );
}
// ----------------------------------------------------------------------------------------------------------
protected $mModelID;
protected $mSupportedFormats;
/**
* Constructor, initializing the ContentHandler instance with it's model name and a list of supported formats.
* Constructor, initializing the ContentHandler instance with it's model id and a list of supported formats.
* Values for the parameters are typically provided as literals by subclasses' constructors.
*
* @param String $modelName (use CONTENT_MODEL_XXX constants).
* @param int $modelId (use CONTENT_MODEL_XXX constants).
* @param array $formats list for supported serialization formats (typically as MIME types)
*/
public function __construct( $modelName, $formats ) {
$this->mModelName = $modelName;
public function __construct( $modelId, $formats ) {
$this->mModelID = $modelId;
$this->mSupportedFormats = $formats;
}
@ -284,23 +356,27 @@ abstract class ContentHandler {
public abstract function makeEmptyContent();
/**
* Returns the model name that identifies the content model this ContentHandler can handle.
* Returns the model id that identifies the content model this ContentHandler can handle.
* Use with the CONTENT_MODEL_XXX constants.
*
* @return String the model name
* @return int the model id
*/
public function getModelName() {
return $this->mModelName;
public function getModelID() {
return $this->mModelID;
}
/**
* Throws an MWException if $modelName is not the content model handeled by this ContentHandler.
* Throws an MWException if $model_id is not the id of the content model
* supported by this ContentHandler.
*
* @param String $modelName the model name to check
* @param int $model_id the model to check
*/
protected function checkModelName( $modelName ) {
if ( $modelName !== $this->mModelName ) {
throw new MWException( "Bad content model: expected " . $this->mModelName . " but got found " . $modelName );
protected function checkModelID( $model_id ) {
if ( $model_id !== $this->mModelID ) {
$model_name = ContentHandler::getContentModelName( $model_id );
$own_model_name = ContentHandler::getContentModelName( $this->mModelID );
throw new MWException( "Bad content model: expected {$this->mModelID} ($own_model_name) but got found $model_id ($model_name)." );
}
}
@ -353,7 +429,7 @@ abstract class ContentHandler {
*/
protected function checkFormat( $format ) {
if ( !$this->isSupportedFormat( $format ) ) {
throw new MWException( "Format $format is not supported for content model " . $this->getModelName() );
throw new MWException( "Format $format is not supported for content model " . $this->getModelID() );
}
}
@ -381,7 +457,7 @@ abstract class ContentHandler {
* @todo Article really defines the view of the content... rename this method to createViewPage ?
*/
public function createArticle( Title $title ) {
$this->checkModelName( $title->getContentModelName() );
$this->checkModelID( $title->getContentModel() );
$article = new Article($title);
return $article;
@ -394,7 +470,7 @@ abstract class ContentHandler {
* @return EditPage
*/
public function createEditPage( Article $article ) {
$this->checkModelName( $article->getContentModelName() );
$this->checkModelID( $article->getPage()->getContentModel() );
$editPage = new EditPage( $article );
return $editPage;
@ -408,7 +484,7 @@ abstract class ContentHandler {
* @todo does anyone or anythign actually use the external edit facility? Can we just deprecate and ignore it?
*/
public function createExternalEdit( IContextSource $context ) {
$this->checkModelName( $context->getTitle()->getContentModelName() );
$this->checkModelID( $context->getTitle()->getContentModel() );
$externalEdit = new ExternalEdit( $context );
return $externalEdit;
@ -428,7 +504,7 @@ abstract class ContentHandler {
public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0, $rcid = 0, #FIMXE: use everywhere!
$refreshCache = false, $unhide = false ) {
$this->checkModelName( $context->getTitle()->getContentModelName() );
$this->checkModelID( $context->getTitle()->getContentModel() );
$diffEngineClass = $this->getDiffEngineClass();
@ -671,8 +747,8 @@ abstract class ContentHandler {
abstract class TextContentHandler extends ContentHandler {
public function __construct( $modelName, $formats ) {
parent::__construct( $modelName, $formats );
public function __construct( $modelId, $formats ) {
parent::__construct( $modelId, $formats );
}
public function serializeContent( Content $content, $format = null ) {
@ -694,9 +770,9 @@ abstract class TextContentHandler extends ContentHandler {
* @return Content|Bool
*/
public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
$this->checkModelName( $oldContent->getModelName() );
$this->checkModelName( $myContent->getModelName() );
$this->checkModelName( $yourContent->getModelName() );
$this->checkModelID( $oldContent->getModel() );
$this->checkModelID( $myContent->getModel() );
$this->checkModelID( $yourContent->getModel() );
$format = $this->getDefaultFormat();
@ -722,8 +798,8 @@ abstract class TextContentHandler extends ContentHandler {
}
class WikitextContentHandler extends TextContentHandler {
public function __construct( $modelName = CONTENT_MODEL_WIKITEXT ) {
parent::__construct( $modelName, array( 'text/x-wiki' ) );
public function __construct( $modelId = CONTENT_MODEL_WIKITEXT ) {
parent::__construct( $modelId, array( CONTENT_FORMAT_WIKITEXT ) );
}
public function unserializeContent( $text, $format = null ) {
@ -743,8 +819,8 @@ class WikitextContentHandler extends TextContentHandler {
class JavaScriptContentHandler extends TextContentHandler {
public function __construct( $modelName = CONTENT_MODEL_WIKITEXT ) {
parent::__construct( $modelName, array( 'text/javascript' ) ); #XXX: or use $wgJsMimeType? this is for internal storage, not HTTP...
public function __construct( $modelId = CONTENT_MODEL_JAVASCRIPT ) {
parent::__construct( $modelId, array( CONTENT_FORMAT_JAVASCRIPT ) );
}
public function unserializeContent( $text, $format = null ) {
@ -760,8 +836,8 @@ class JavaScriptContentHandler extends TextContentHandler {
class CssContentHandler extends TextContentHandler {
public function __construct( $modelName = CONTENT_MODEL_WIKITEXT ) {
parent::__construct( $modelName, array( 'text/css' ) );
public function __construct( $modelId = CONTENT_MODEL_CSS ) {
parent::__construct( $modelId, array( CONTENT_FORMAT_CSS ) );
}
public function unserializeContent( $text, $format = null ) {

View file

@ -642,7 +642,7 @@ $wgMediaHandlers = array(
/**
* Plugins for page content model handling.
* Each entry in the array maps a model name type to a class name
* Each entry in the array maps a model id to a class name
*/
$wgContentHandlers = array(
CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler', // the usual case
@ -651,6 +651,29 @@ $wgContentHandlers = array(
CONTENT_MODEL_TEXT => 'TextContentHandler', // dumb plain text in <pre>
);
/**
* Mime types for content formats.
* Each entry in the array maps a content format to a mime type.
*
* Extensions that define their own content formats can register
* the appropriate mime types in this array.
*
* Such extensions shall use content format IDs
* larger than 100 and register the ids they use at
* <http://mediawiki.org/ContentHandler/registry>
* to avoid conflicts with other extensions.
*/
$wgContentFormatMimeTypes = array(
CONTENT_FORMAT_WIKITEXT => 'text/x-wiki',
CONTENT_FORMAT_JAVASCRIPT => 'text/javascript',
CONTENT_FORMAT_CSS => 'text/css',
CONTENT_FORMAT_TEXT => 'text/plain',
CONTENT_FORMAT_HTML => 'text/html',
CONTENT_FORMAT_XML => 'application/xml',
CONTENT_FORMAT_JSON => 'application/json',
CONTENT_FORMAT_SERIALIZED => 'application/vnd.php.serialized',
);
/**
* Resizing can be done using PHP's internal image libraries or using
* ImageMagick or another third-party converter, e.g. GraphicMagick.

View file

@ -244,7 +244,7 @@ define( 'APCOND_BLOCKED', 8 );
define( 'APCOND_ISBOT', 9 );
/**@}*/
/**
/** @{
* Protocol constants for wfExpandUrl()
*/
define( 'PROTO_HTTP', 'http://' );
@ -253,12 +253,40 @@ define( 'PROTO_RELATIVE', '//' );
define( 'PROTO_CURRENT', null );
define( 'PROTO_CANONICAL', 1 );
define( 'PROTO_INTERNAL', 2 );
/**@}*/
/**
* Content model names, used by Content and ContentHandler
/**@{
* Content model ids, used by Content and ContentHandler
*
* Extensions that define their own content models shall use IDs
* larger than 100 and register the ids they use at
* <http://mediawiki.org/ContentHandler/registry>
* to avoid conflicts with other extensions.
*/
define('CONTENT_MODEL_WIKITEXT', 'wikitext');
define('CONTENT_MODEL_JAVASCRIPT', 'javascript');
define('CONTENT_MODEL_CSS', 'css');
define('CONTENT_MODEL_TEXT', 'text');
define( 'CONTENT_MODEL_WIKITEXT', 1 );
define( 'CONTENT_MODEL_JAVASCRIPT', 2 );
define( 'CONTENT_MODEL_CSS', 3 );
define( 'CONTENT_MODEL_TEXT', 4 );
/**@}*/
/**@{
* Content format ids, used by Content and ContentHandler.
* Use ContentHander::getFormatMimeType() to get the associated mime type.
* Register mime types in $wgContentFormatMimeTypes.
*
* Extensions that define their own content formats shall use IDs
* larger than 100 and register the ids they use at
* <http://mediawiki.org/ContentHandler/registry>
* to avoid conflicts with other extensions.
*/
define( 'CONTENT_FORMAT_WIKITEXT', 1 ); // wikitext
define( 'CONTENT_FORMAT_JAVASCRIPT', 2 ); // for js pages
define( 'CONTENT_FORMAT_CSS', 3 ); // for css pages
define( 'CONTENT_FORMAT_TEXT', 4 ); // for future use, e.g. with some plain-html messages.
define( 'CONTENT_FORMAT_HTML', 5 ); // for future use, e.g. with some plain-html messages.
define( 'CONTENT_FORMAT_SERIALIZED', 11 ); // for future use with the api, and for use by extensions
define( 'CONTENT_FORMAT_JSON', 12 ); // for future use with the api, and for use by extensions
define( 'CONTENT_FORMAT_XML', 13 ); // for future use with the api, and for use by extensions
/**@}*/

View file

@ -230,9 +230,9 @@ class EditPage {
$this->mArticle = $article;
$this->mTitle = $article->getTitle();
$this->content_model = $this->mTitle->getContentModelName();
$this->content_model = $this->mTitle->getContentModel();
$handler = ContentHandler::getForModelName( $this->content_model );
$handler = ContentHandler::getForModelID( $this->content_model );
$this->content_format = $handler->getDefaultFormat(); #NOTE: should be overridden by format of actual revision
}
@ -713,7 +713,7 @@ class EditPage {
$this->nosummary = $request->getBool( 'nosummary' );
$content_handler = ContentHandler::getForTitle( $this->mTitle );
$this->content_model = $request->getText( 'model', $content_handler->getModelName() ); #may be overridden by revision
$this->content_model = $request->getText( 'model', $content_handler->getModelID() ); #may be overridden by revision
$this->content_format = $request->getText( 'format', $content_handler->getDefaultFormat() ); #may be overridden by revision
#TODO: check if the desired model is allowed in this namespace, and if a transition from the page's current model to the new model is allowed
@ -916,8 +916,8 @@ class EditPage {
}
$revision = $this->mArticle->getRevisionFetched();
if ( $revision === null ) {
if ( !$this->content_model ) $this->content_model = $this->getTitle()->getContentModelName();
$handler = ContentHandler::getForModelName( $this->content_model );
if ( !$this->content_model ) $this->content_model = $this->getTitle()->getContentModel();
$handler = ContentHandler::getForModelID( $this->content_model );
return $handler->makeEmptyContent();
}
@ -938,13 +938,13 @@ class EditPage {
$content = $rev ? $rev->getContent( Revision::RAW ) : null;
if ( $content === false || $content === null ) {
if ( !$this->content_model ) $this->content_model = $this->getTitle()->getContentModelName();
$handler = ContentHandler::getForModelName( $this->content_model );
if ( !$this->content_model ) $this->content_model = $this->getTitle()->getContentModel();
$handler = ContentHandler::getForModelID( $this->content_model );
return $handler->makeEmptyContent();
} else {
#FIXME: nasty side-effect!
$this->content_model = $rev->getContentModelName();
$this->content_model = $rev->getContentModel();
$this->content_format = $rev->getContentFormat();
return $content;
@ -1657,7 +1657,7 @@ class EditPage {
}
$currentContent = $currentRevision->getContent();
$handler = ContentHandler::getForModelName( $baseContent->getModelName() );
$handler = ContentHandler::getForModelID( $baseContent->getModel() );
$result = $handler->merge3( $baseContent, $editContent, $currentContent );
@ -2509,7 +2509,7 @@ HTML
if ( $newtext != $newtext_orig ) {
#if the hook changed the text, create a new Content object accordingly.
$newContent = ContentHandler::makeContent( $newtext, $this->getTitle(), $newContent->getModelName() ); #XXX: handle parse errors ?
$newContent = ContentHandler::makeContent( $newtext, $this->getTitle(), $newContent->getModel() ); #XXX: handle parse errors ?
}
wfRunHooks( 'EditPageGetDiffContent', array( $this, &$newContent ) );
@ -2616,7 +2616,7 @@ HTML
$content1 = ContentHandler::makeContent( $this->textbox1, $this->getTitle(), $this->content_model, $this->content_format ); #XXX: handle parse errors?
$content2 = ContentHandler::makeContent( $this->textbox2, $this->getTitle(), $this->content_model, $this->content_format ); #XXX: handle parse errors?
$handler = ContentHandler::getForModelName( $this->content_model );
$handler = ContentHandler::getForModelID( $this->content_model );
$de = $handler->createDifferenceEngine( $this->mArticle->getContext() );
$de->setContent( $content2, $content1 );
$de->showDiff( wfMsgExt( 'yourtext', 'parseinline' ), wfMsg( 'storedversion' ) );
@ -2772,9 +2772,9 @@ HTML
$level = false;
}
if ( $content->getModelName() == CONTENT_MODEL_CSS ) {
if ( $content->getModel() == CONTENT_MODEL_CSS ) {
$format = 'css';
} elseif ( $content->getModelName() == CONTENT_MODEL_JAVASCRIPT ) {
} elseif ( $content->getModel() == CONTENT_MODEL_JAVASCRIPT ) {
$format = 'js';
} else {
$format = false;

View file

@ -595,11 +595,13 @@ class XmlDumpWriter {
}
if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
$out .= " " . Xml::element('model', null, strval( $row->rev_content_model ) ) . "\n";
$name = ContentHandler::getContentModelName( $row->rev_content_model );
$out .= " " . Xml::element('model', array( 'name' => $name ), strval( $row->rev_content_model ) ) . "\n";
}
if ( isset( $row->rev_content_format ) && !is_null( $row->rev_content_format ) ) {
$out .= " " . Xml::element('format', null, strval( $row->rev_content_format ) ) . "\n";
$mime = ContentHandler::getContentFormatMimeType( $row->rev_content_format );
$out .= " " . Xml::element('format', array( 'mime' => $mime ), strval( $row->rev_content_format ) ) . "\n";
}
$text = '';

View file

@ -1179,18 +1179,18 @@ class WikiRevision {
}
/**
* @return string
* @return int
*/
function getModel() {
if ( is_null( $this->model ) ) {
$this->model = $this->getTitle()->getContentModelName();
$this->model = $this->getTitle()->getContentModel();
}
return $this->model;
}
/**
* @return string
* @return int
*/
function getFormat() {
if ( is_null( $this->model ) ) {

View file

@ -20,7 +20,7 @@ class Revision {
protected $mTextRow;
protected $mTitle;
protected $mCurrent;
protected $mContentModelName;
protected $mContentModel;
protected $mContentFormat;
protected $mContent;
protected $mContentHandler;
@ -440,15 +440,15 @@ class Revision {
}
if( !isset( $row->rev_content_model ) || is_null( $row->rev_content_model ) ) {
$this->mContentModelName = null; # determine on demand if needed
$this->mContentModel = null; # determine on demand if needed
} else {
$this->mContentModelName = strval( $row->rev_content_model );
$this->mContentModel = intval( $row->rev_content_model );
}
if( !isset( $row->rev_content_format ) || is_null( $row->rev_content_format ) ) {
$this->mContentFormat = null; # determine on demand if needed
} else {
$this->mContentFormat = strval( $row->rev_content_format );
$this->mContentFormat = intval( $row->rev_content_format );
}
// Lazy extraction...
@ -479,7 +479,7 @@ class Revision {
throw new MWException( "Text already stored in external store (id {$row['text_id']}), can't serialize content object" );
}
$row['content_model'] = $row['content']->getModelName();
$row['content_model'] = $row['content']->getModel();
# note: mContentFormat is initializes later accordingly
# note: content is serialized later in this method!
# also set text to null?
@ -497,20 +497,20 @@ class Revision {
$this->mParentId = isset( $row['parent_id'] ) ? intval( $row['parent_id'] ) : null;
$this->mSha1 = isset( $row['sha1'] ) ? strval( $row['sha1'] ) : null;
$this->mContentModelName = isset( $row['content_model'] ) ? strval( $row['content_model'] ) : null;
$this->mContentFormat = isset( $row['content_format'] ) ? strval( $row['content_format'] ) : null;
$this->mContentModel = isset( $row['content_model'] ) ? intval( $row['content_model'] ) : null;
$this->mContentFormat = isset( $row['content_format'] ) ? intval( $row['content_format'] ) : null;
// Enforce spacing trimming on supplied text
$this->mComment = isset( $row['comment'] ) ? trim( strval( $row['comment'] ) ) : null;
$this->mText = isset( $row['text'] ) ? rtrim( strval( $row['text'] ) ) : null;
$this->mTextRow = null;
# if we have a content object, override mText and mContentModelName
# if we have a content object, override mText and mContentModel
if ( !empty( $row['content'] ) ) {
$handler = $this->getContentHandler();
$this->mContent = $row['content'];
$this->mContentModelName = $this->mContent->getModelName();
$this->mContentModel = $this->mContent->getModel();
$this->mContentHandler = null;
$this->mText = $handler->serializeContent( $row['content'], $this->getContentFormat() );
@ -538,7 +538,7 @@ class Revision {
$this->mSha1 = is_null( $this->mText ) ? null : self::base36Sha1( $this->mText );
}
$this->getContentModelName(); # force lazy init
$this->getContentModel(); # force lazy init
$this->getContentFormat(); # force lazy init
} else {
throw new MWException( 'Revision constructor passed invalid row format.' );
@ -879,31 +879,54 @@ class Revision {
return $this->mContent;
}
public function getContentModelName() {
if ( !$this->mContentModelName ) {
/**
* Returns the content model for this revision.
*
* If no content model was stored in the database, $this->getTitle()->getContentModel() is
* used to determine the content model to use. If no title is know, CONTENT_MODEL_WIKITEXT
* is used as a last resort.
*
* @return int the content model id associated with this revision, see the CONTENT_MODEL_XXX constants.
**/
public function getContentModel() {
if ( !$this->mContentModel ) {
$title = $this->getTitle();
$this->mContentModelName = ( $title ? $title->getContentModelName() : CONTENT_MODEL_WIKITEXT );
$this->mContentModel = ( $title ? $title->getContentModel() : CONTENT_MODEL_WIKITEXT );
assert( !empty( $this->mContentModel ) );
}
return $this->mContentModelName;
return $this->mContentModel;
}
/**
* Returns the content format for this revision.
*
* If no content format was stored in the database, the default format for this
* revision's content model is returned.
*
* @return int the content format id associated with this revision, see the CONTENT_FORMAT_XXX constants.
**/
public function getContentFormat() {
if ( !$this->mContentFormat ) {
$handler = $this->getContentHandler();
$this->mContentFormat = $handler->getDefaultFormat();
assert( !empty( $this->mContentFormat ) );
}
return $this->mContentFormat;
}
/**
* Returns the content handler appropriate for this revision's content model.
*
* @return ContentHandler
*/
public function getContentHandler() {
if ( !$this->mContentHandler ) {
$model = $this->getContentModelName();
$this->mContentHandler = ContentHandler::getForModelName( $model );
$model = $this->getContentModel();
$this->mContentHandler = ContentHandler::getForModelID( $model );
assert( $this->mContentHandler->isSupportedFormat( $this->getContentFormat() ) );
}
@ -1153,7 +1176,7 @@ class Revision {
);
if ( $wgContentHandlerUseDB ) {
$row[ 'rev_content_model' ] = $this->getContentModelName();
$row[ 'rev_content_model' ] = $this->getContentModel();
$row[ 'rev_content_format' ] = $this->getContentFormat();
}

View file

@ -63,6 +63,7 @@ class Title {
var $mFragment; // /< Title fragment (i.e. the bit after the #)
var $mArticleID = -1; // /< Article ID, fetched from the link cache on demand
var $mLatestID = false; // /< ID of most recent revision
var $mContentModel = false; // /< ID of the page's content model, i.e. one of the CONTENT_MODEL_XXX constants
private $mEstimateRevisions; // /< Estimated number of revisions; null of not loaded
var $mRestrictions = array(); // /< Array of groups allowed to edit this article
var $mOldRestrictions = false;
@ -273,15 +274,15 @@ class Title {
if ( isset( $row->page_latest ) )
$this->mLatestID = (int)$row->page_latest; # FIXME: whene3ver page_latest is updated, also update page_content_model
if ( isset( $row->page_content_model ) )
$this->mContentModelName = $row->page_content_model;
$this->mContentModel = $row->page_content_model;
else
$this->mContentModelName = null; # initialized lazily in getContentModelName()
$this->mContentModel = null; # initialized lazily in getContentModel()
} else { // page not found
$this->mArticleID = 0;
$this->mLength = 0;
$this->mRedirect = false;
$this->mLatestID = 0;
$this->mContentModelName = null; # initialized lazily in getContentModelName()
$this->mContentModel = null; # initialized lazily in getContentModel()
}
}
@ -307,7 +308,7 @@ class Title {
$t->mArticleID = ( $ns >= 0 ) ? -1 : 0;
$t->mUrlform = wfUrlencode( $t->mDbkeyform );
$t->mTextform = str_replace( '_', ' ', $title );
$t->mContentModelName = null; # initialized lazily in getContentModelName()
$t->mContentModel = null; # initialized lazily in getContentModel()
return $t;
}
@ -698,26 +699,27 @@ class Title {
}
/**
* Get the page's content model name
* Get the page's content model id, see the CONTENT_MODEL_XXX constants.
*
* @return Integer: Namespace index
* @return Integer: Content model id
*/
public function getContentModelName() {
if ( empty( $this->mContentModelName ) ) {
$this->mContentModelName = ContentHandler::getDefaultModelFor( $this );
public function getContentModel() {
if ( empty( $this->mContentModel ) ) {
$this->mContentModel = ContentHandler::getDefaultModelFor( $this );
}
return $this->mContentModelName;
assert( !empty( $this->mContentModel ) );
return $this->mContentModel;
}
/**
* Conveniance method for checking a title's content model name
*
* @param $name
* @return true if $this->getContentModelName() == $name
* @param int $id
* @return true if $this->getContentModel() == $id
*/
public function hasContentModel( $name ) {
return $this->getContentModelName() == $name;
public function hasContentModel( $id ) {
return $this->getContentModel() == $id;
}
/**

View file

@ -161,14 +161,14 @@ class WikiPage extends Page {
/**
* Returns the ContentHandler instance to be used to deal with the content of this WikiPage.
*
* Shorthand for ContentHandler::getForModelName( $this->getContentModelName() );
* Shorthand for ContentHandler::getForModelID( $this->getContentModel() );
*
* @return ContentHandler
*
* @since 1.WD
*/
public function getContentHandler() {
return ContentHandler::getForModelName( $this->getContentModelName() );
return ContentHandler::getForModelID( $this->getContentModel() );
}
/**
@ -380,27 +380,29 @@ class WikiPage extends Page {
}
/**
* Returns the page's content model name. Will use the revisions actual content model if the page exists,
* Returns the page's content model id (see the CONTENT_MODEL_XXX constants).
*
* Will use the revisions actual content model if the page exists,
* and the page's default if the page doesn't exist yet.
*
* @return int
*
* @since 1.WD
*/
public function getContentModelName() {
public function getContentModel() {
if ( $this->exists() ) {
# look at the revision's actual content model
$rev = $this->getRevision();
if ( $rev !== null ) {
return $rev->getContentModelName();
return $rev->getContentModel();
} else {
wfWarn( "Page exists but has no revision!" );
}
}
# use the default model for this page
return $this->mTitle->getContentModelName();
return $this->mTitle->getContentModel();
}
/**
@ -1099,7 +1101,7 @@ class WikiPage extends Page {
);
if ( $wgContentHandlerUseDB ) {
$row[ 'page_content_model' ] = $revision->getContentModelName();
$row[ 'page_content_model' ] = $revision->getContentModel();
}
$dbw->update( 'page',
@ -1518,7 +1520,7 @@ class WikiPage extends Page {
'user' => $user->getId(),
'user_text' => $user->getName(),
'timestamp' => $now,
'content_model' => $content->getModelName(),
'content_model' => $content->getModel(),
'content_format' => $serialisation_format,
) );
@ -1625,7 +1627,7 @@ class WikiPage extends Page {
'user' => $user->getId(),
'user_text' => $user->getName(),
'timestamp' => $now,
'content_model' => $content->getModelName(),
'content_model' => $content->getModel(),
'content_format' => $serialisation_format,
) );
$revisionId = $revision->insertOn( $dbw );
@ -2661,7 +2663,7 @@ class WikiPage extends Page {
wfDeprecated( __METHOD__, '1.WD' );
$handler = ContentHandler::getForModelName( CONTENT_MODEL_WIKITEXT );
$handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
$oldContent = is_null( $oldtext ) ? null : $handler->unserializeContent( $oldtext );
$newContent = is_null( $newtext ) ? null : $handler->unserializeContent( $newtext );
@ -3064,9 +3066,9 @@ class PoolWorkArticleView extends PoolCounterWork {
*/
function __construct( Page $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null, IContextSource $context = null ) {
if ( is_string($content) ) { #BC: old style call
$modelName = $page->getRevision()->getContentModelName();
$modelId = $page->getRevision()->getContentModel();
$format = $page->getRevision()->getContentFormat();
$content = ContentHandler::makeContent( $content, $page->getTitle(), $modelName, $format );
$content = ContentHandler::makeContent( $content, $page->getTitle(), $modelId, $format );
}
if ( is_null( $context ) ) {

View file

@ -139,7 +139,7 @@ class RawAction extends FormlessAction {
if ( !$content instanceof TextContent ) {
wfHttpError( 406, "Not Acceptable", "The requeste page uses the content model `"
. $content->getModelName() . "` which is not supported via this interface." );
. $content->getModel() . "` which is not supported via this interface." );
die();
}

View file

@ -35,7 +35,7 @@ class ApiComparePages extends ApiBase {
$rev1 = $this->revisionOrTitleOrId( $params['fromrev'], $params['fromtitle'], $params['fromid'] );
$rev2 = $this->revisionOrTitleOrId( $params['torev'], $params['totitle'], $params['toid'] );
$contentHandler = ContentHandler::getForModelName( $rev1->getContentModelName() );
$contentHandler = ContentHandler::getForModelID( $rev1->getContentModel() );
$de = $contentHandler->createDifferenceEngine( $this->getContext(),
$rev1,
$rev2,

View file

@ -111,7 +111,7 @@ class SpecialComparePages extends SpecialPage {
$rev2 = self::revOrTitle( $data['Revision2'], $data['Page2'] );
if( $rev1 && $rev2 ) {
$contentHandler = ContentHandler::getForModelName( $rev1->getContentModelName() );
$contentHandler = ContentHandler::getForModelID( $rev1->getContentModel() );
$de = $contentHandler->createDifferenceEngine( $form->getContext(),
$rev1,
$rev2,

View file

@ -4861,4 +4861,10 @@ Otherwise, you can use the easy form below. Your comment will be added to the pa
'duration-centuries' => '$1 {{PLURAL:$1|century|centuries}}',
'duration-millennia' => '$1 {{PLURAL:$1|millennium|millennia}}',
# Content model IDs for the ContentHandler facility; used by ContentHander::getContentModel()
'content-model-1' => 'wikitext',
'content-model-2' => 'JavaScript',
'content-model-3' => 'CSS',
'content-model-4' => 'plain text',
);

View file

@ -4676,4 +4676,10 @@ $4 is the gender of the target user.',
'api-error-uploaddisabled' => 'API error message that can be used for client side localisation of API errors.',
'api-error-verification-error' => 'The word "extension" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.',
# Content model IDs for the ContentHandler facility; used by ContentHander::getContentModel()
'content-model-1' => 'Name for the wikitext content model, used when decribing what type of content a page contains.',
'content-model-2' => 'Name for the JavaScript content model, used when decribing what type of content a page contains.',
'content-model-3' => 'Name for the CSS content model, used when decribing what type of content a page contains.',
'content-model-4' => 'Name for the plain text content model, used when decribing what type of content a page contains.',
);

View file

@ -1,2 +1,2 @@
ALTER TABLE /*$wgDBprefix*/archive
ADD ar_content_format varbinary(64) DEFAULT NULL;
ADD ar_content_format int unsigned DEFAULT NULL;

View file

@ -1,2 +1,2 @@
ALTER TABLE /*$wgDBprefix*/archive
ADD ar_content_model varbinary(32) DEFAULT NULL;
ADD ar_content_model int unsigned DEFAULT NULL;

View file

@ -1,2 +1,2 @@
ALTER TABLE /*$wgDBprefix*/page
ADD page_content_model varbinary(32) DEFAULT NULL;
ADD page_content_model int unsigned DEFAULT NULL;

View file

@ -1,2 +1,2 @@
ALTER TABLE /*$wgDBprefix*/revision
ADD rev_content_format varbinary(64) DEFAULT NULL;
ADD rev_content_format int unsigned DEFAULT NULL;

View file

@ -1,2 +1,2 @@
ALTER TABLE /*$wgDBprefix*/revision
ADD rev_content_model varbinary(32) DEFAULT NULL;
ADD rev_content_model int unsigned DEFAULT NULL;

View file

@ -262,8 +262,8 @@ CREATE TABLE /*_*/page (
-- Uncompressed length in bytes of the page's current source text.
page_len int unsigned NOT NULL,
-- content model
page_content_model varbinary(32) default NULL
-- content model, see CONTENT_MODEL_XXX constants
page_content_model int unsigned default NULL
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title);
@ -321,11 +321,11 @@ CREATE TABLE /*_*/revision (
-- SHA-1 text content hash in base-36
rev_sha1 varbinary(32) NOT NULL default '',
-- content model
rev_content_model varbinary(32) default NULL,
-- content model, see CONTENT_MODEL_XXX constants
rev_content_model int unsigned default NULL,
-- content format (mime type)
rev_content_format varbinary(64) default NULL
-- content format, see CONTENT_FORMAT_XXX constants
rev_content_format int unsigned default NULL
) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
-- In case tables are created as MyISAM, use row hints for MySQL <5.0 to avoid 4GB limit
@ -438,11 +438,11 @@ CREATE TABLE /*_*/archive (
-- SHA-1 text content hash in base-36
ar_sha1 varbinary(32) NOT NULL default '',
-- content model
ar_content_model varbinary(32) default NULL,
-- content model, see CONTENT_MODEL_XXX constants
ar_content_model int unsigned default NULL,
-- content format (mime type)
ar_content_format varbinary(64) default NULL
-- content format, see CONTENT_MODEL_XXX constants
ar_content_format int unsigned default NULL
) /*$wgDBTableOptions*/;

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class ContentHandlerTest extends MediaWikiTestCase {
public function setUp() {
@ -8,8 +11,8 @@ class ContentHandlerTest extends MediaWikiTestCase {
$wgExtraNamespaces[ 12312 ] = 'Dummy';
$wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
$wgNamespaceContentModels[ 12312 ] = 'DUMMY';
$wgContentHandlers[ 'DUMMY' ] = 'DummyContentHandlerForTesting';
$wgNamespaceContentModels[ 12312 ] = 999999;
$wgContentHandlers[ 999999 ] = 'DummyContentHandlerForTesting';
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
$wgContLang->resetNamespaces(); # reset namespace cache
@ -22,7 +25,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
unset( $wgExtraNamespaces[ 12313 ] );
unset( $wgNamespaceContentModels[ 12312 ] );
unset( $wgContentHandlers[ 'DUMMY' ] );
unset( $wgContentHandlers[ 999999 ] );
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
$wgContLang->resetNamespaces(); # reset namespace cache
@ -51,9 +54,9 @@ class ContentHandlerTest extends MediaWikiTestCase {
/**
* @dataProvider dataGetDefaultModelFor
*/
public function testGetDefaultModelFor( $title, $expectedModelName ) {
public function testGetDefaultModelFor( $title, $expectedModelId ) {
$title = Title::newFromText( $title );
$this->assertEquals( $expectedModelName, ContentHandler::getDefaultModelFor( $title ) );
$this->assertEquals( $expectedModelId, ContentHandler::getDefaultModelFor( $title ) );
}
/**
* @dataProvider dataGetDefaultModelFor
@ -61,7 +64,79 @@ class ContentHandlerTest extends MediaWikiTestCase {
public function testGetForTitle( $title, $expectedContentModel ) {
$title = Title::newFromText( $title );
$handler = ContentHandler::getForTitle( $title );
$this->assertEquals( $expectedContentModel, $handler->getModelName() );
$this->assertEquals( $expectedContentModel, $handler->getModelID() );
}
public function dataGetContentFormatMimeType( ) {
return array(
array( 0, null ),
array( null, null ),
array( 99887766, null ),
array( CONTENT_FORMAT_WIKITEXT, 'text/x-wiki' ),
array( CONTENT_FORMAT_JAVASCRIPT, 'text/javascript' ),
array( CONTENT_FORMAT_CSS, 'text/css' ),
array( CONTENT_FORMAT_JSON, 'application/json' ),
array( CONTENT_FORMAT_XML, 'application/xml' ),
array( CONTENT_FORMAT_SERIALIZED, 'application/vnd.php.serialized' ),
);
}
/**
* @dataProvider dataGetContentFormatMimeType
*/
public function testGetContentFormatMimeType( $id, $expectedMime ) {
$mime = ContentHandler::getContentFormatMimeType( $id );
$this->assertEquals( $expectedMime, $mime );
}
public function dataGetContentFormatID( ) {
return array(
array( '', null ),
array( 'foo', null ),
array( null, null ),
array( 'text/x-wiki', CONTENT_FORMAT_WIKITEXT ),
array( 'text/javascript', CONTENT_FORMAT_JAVASCRIPT ),
array( 'text/css', CONTENT_FORMAT_CSS ),
array( 'application/json', CONTENT_FORMAT_JSON ),
array( 'application/xml', CONTENT_FORMAT_XML ),
array( 'application/vnd.php.serialized', CONTENT_FORMAT_SERIALIZED ),
);
}
/**
* @dataProvider dataGetContentFormatID
*/
public function testGetContentFormatID( $mime, $expectedId ) {
$id = ContentHandler::getContentFormatID( $mime );
$this->assertEquals( $expectedId, $id );
}
public function dataGetContentModelName() {
return array(
array( 0, null ),
array( null, null ),
array( 99887766, null ),
array( CONTENT_MODEL_JAVASCRIPT, '/javascript/i' ), //XXX: depends on content language
);
}
/**
* @dataProvider dataGetContentModelName
*/
public function testGetContentModelName( $id, $expected ) {
$name = ContentHandler::getContentModelName( $id );
if ( $expected === null ) {
$this->assertNull( $name, "content model name for #$id was expected to be null" );
} else {
$this->assertNotNull( $name, "no name found for content model #$id" );
$this->assertTrue( preg_match( $expected, $name ) > 0 , "content model name for #$id did not match pattern $expected" );
}
}
public function testGetContentText_Null( ) {
@ -124,45 +199,45 @@ class ContentHandlerTest extends MediaWikiTestCase {
$this->assertNull( $text );
}
#public static function makeContent( $text, Title $title, $modelName = null, $format = null )
#public static function makeContent( $text, Title $title, $modelId = null, $format = null )
public function dataMakeContent() {
return array(
array( 'hallo', 'Test', null, null, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
array( 'hallo', 'MediaWiki:Test.js', null, null, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
array( serialize('hallo'), 'Dummy:Test', null, null, 'DUMMY', 'hallo', false ),
array( serialize('hallo'), 'Dummy:Test', null, null, 999999, 'hallo', false ),
array( 'hallo', 'Test', null, 'text/x-wiki', CONTENT_MODEL_WIKITEXT, 'hallo', false ),
array( 'hallo', 'MediaWiki:Test.js', null, 'text/javascript', CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
array( serialize('hallo'), 'Dummy:Test', null, 'dummy', 'DUMMY', 'hallo', false ),
array( 'hallo', 'Test', null, CONTENT_FORMAT_WIKITEXT, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
array( 'hallo', 'MediaWiki:Test.js', null, CONTENT_FORMAT_JAVASCRIPT, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
array( serialize('hallo'), 'Dummy:Test', null, 999999, 999999, 'hallo', false ),
array( 'hallo', 'Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
array( serialize('hallo'), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize('hallo'), false ),
array( 'hallo', 'Test', CONTENT_MODEL_WIKITEXT, 'dummy', null, null, true ),
array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, 'dummy', null, null, true ),
array( 'hallo', 'Dummy:Test', CONTENT_MODEL_JAVASCRIPT, 'dummy', null, null, true ),
array( 'hallo', 'Test', CONTENT_MODEL_WIKITEXT, 999999, null, null, true ),
array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, 999999, null, null, true ),
array( 'hallo', 'Dummy:Test', CONTENT_MODEL_JAVASCRIPT, 999999, null, null, true ),
);
}
/**
* @dataProvider dataMakeContent
*/
public function testMakeContent( $data, $title, $modelName, $format, $expectedModelName, $expectedNativeData, $shouldFail ) {
public function testMakeContent( $data, $title, $modelId, $format, $expectedModelId, $expectedNativeData, $shouldFail ) {
global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers;
$title = Title::newFromText( $title );
try {
$content = ContentHandler::makeContent( $data, $title, $modelName, $format );
$content = ContentHandler::makeContent( $data, $title, $modelId, $format );
if ( $shouldFail ) $this->fail( "ContentHandler::makeContent should have failed!" );
$this->assertEquals( $expectedModelName, $content->getModelName(), 'bad model name' );
$this->assertEquals( $expectedModelId, $content->getModel(), 'bad model id' );
$this->assertEquals( $expectedNativeData, $content->getNativeData(), 'bads native data' );
} catch ( MWException $ex ) {
if ( !$shouldFail ) $this->fail( "ContentHandler::makeContent failed unexpectedly!" );
if ( !$shouldFail ) $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() );
else $this->assertTrue( true ); // dummy, so we don't get the "test did not perform any assertions" message.
}
@ -174,7 +249,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
class DummyContentHandlerForTesting extends ContentHandler {
public function __construct( $dataModel ) {
parent::__construct( $dataModel, array('dummy') );
parent::__construct( $dataModel, array( 999999 ) );
}
/**
@ -215,7 +290,7 @@ class DummyContentHandlerForTesting extends ContentHandler {
class DummyContentForTesting extends Content {
public function __construct( $data ) {
parent::__construct( "DUMMY" );
parent::__construct( 999999 );
$this->data = $data;
}
@ -280,7 +355,7 @@ class DummyContentForTesting extends Content {
* if $copy = $original->copy()
*
* * get_class($original) === get_class($copy)
* * $original->getModelName() === $copy->getModelName()
* * $original->getModel() === $copy->getModel()
* * $original->equals( $copy )
*
* If and only if the Content object is imutable, the copy() method can and should

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class CssContentTest extends JavascriptContentTest {
public function newContent( $text ) {
@ -17,16 +20,16 @@ class CssContentTest extends JavascriptContentTest {
# =================================================================================================================
public function getModelName() {
public function testGetModel() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getModelName() );
$this->assertEquals( CONTENT_MODEL_CSS, $content->getModel() );
}
public function getContentHandler() {
public function testGetContentHandler() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelName() );
$this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() );
}
public function dataEquals( ) {

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class JavascriptContentTest extends WikitextContentTest {
public function newContent( $text ) {
@ -209,16 +212,16 @@ class JavascriptContentTest extends WikitextContentTest {
# =================================================================================================================
public function getModelName() {
public function testGetModel() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getModel() );
}
public function getContentHandler() {
public function testGetContentHandler() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelID() );
}
public function dataEquals( ) {

View file

@ -3,6 +3,7 @@
/**
* Test class for Revision storage.
*
* @group ContentHandler
* @group Database
* ^--- important, causes temporary tables to be used instead of the real database
*/
@ -76,7 +77,7 @@ class RevisionStorageTest extends PHPUnit_Framework_TestCase {
$this->assertEquals( $orig->getPage(), $rev->getPage() );
$this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() );
$this->assertEquals( $orig->getUser(), $rev->getUser() );
$this->assertEquals( $orig->getContentModelName(), $rev->getContentModelName() );
$this->assertEquals( $orig->getContentModel(), $rev->getContentModel() );
$this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() );
$this->assertEquals( $orig->getSha1(), $rev->getSha1() );
}
@ -251,14 +252,14 @@ class RevisionStorageTest extends PHPUnit_Framework_TestCase {
}
/**
* @covers Revision::getContentModelName
* @covers Revision::getContentModel
*/
public function testGetContentModelName()
public function testGetContentModel()
{
$orig = $this->makeRevision( array( 'text' => 'hello hello.', 'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
$rev = Revision::newFromId( $orig->getId() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
}
/**
@ -266,10 +267,10 @@ class RevisionStorageTest extends PHPUnit_Framework_TestCase {
*/
public function testGetContentFormat()
{
$orig = $this->makeRevision( array( 'text' => 'hello hello.', 'content_model' => CONTENT_MODEL_JAVASCRIPT, 'content_format' => 'text/javascript' ) );
$orig = $this->makeRevision( array( 'text' => 'hello hello.', 'content_model' => CONTENT_MODEL_JAVASCRIPT, 'content_format' => CONTENT_FORMAT_JAVASCRIPT ) );
$rev = Revision::newFromId( $orig->getId() );
$this->assertEquals( 'text/javascript', $rev->getContentFormat() );
$this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() );
}
/**

View file

@ -1,7 +1,7 @@
<?php
/**
*
* @group ContentHandler
* @group Database
* ^--- important, causes temporary tables to be used instead of the real database
*/
@ -57,16 +57,16 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
}
/**
* @covers Revision::getContentModelName
* @covers Revision::getContentModel
*/
public function testGetContentModelName()
public function testGetContentModel()
{
$orig = $this->makeRevision( array( 'text' => 'hello hello.', 'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
$rev = Revision::newFromId( $orig->getId() );
//NOTE: database fields for the content_model are disabled, so the model name is not retained.
// We expect to get the default here instead of what was suppleid when creating the revision.
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $rev->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $rev->getContentModel() );
}

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class RevisionTest extends MediaWikiTestCase {
var $saveGlobals = array();
@ -26,8 +29,8 @@ class RevisionTest extends MediaWikiTestCase {
$wgExtraNamespaces[ 12312 ] = 'Dummy';
$wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
$wgNamespaceContentModels[ 12312 ] = 'DUMMY';
$wgContentHandlers[ 'DUMMY' ] = 'DummyContentHandlerForTesting';
$wgNamespaceContentModels[ 12312 ] = 999999;
$wgContentHandlers[ 999999 ] = 'DummyContentHandlerForTesting';
MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
$wgContLang->resetNamespaces(); # reset namespace cache
@ -183,7 +186,7 @@ class RevisionTest extends MediaWikiTestCase {
return array(
array( 'hello world', 'Hello', null, null, CONTENT_MODEL_WIKITEXT ),
array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ),
array( serialize('hello world'), 'Dummy:Hello', null, null, 'DUMMY' ),
array( serialize('hello world'), 'Dummy:Hello', null, null, 999999 ),
);
}
@ -193,15 +196,15 @@ class RevisionTest extends MediaWikiTestCase {
function testGetContentModel( $text, $title, $model, $format, $expectedModel ) {
$rev = $this->newTestRevision( $text, $title, $model, $format );
$this->assertEquals( $expectedModel, $rev->getContentModelName() );
$this->assertEquals( $expectedModel, $rev->getContentModel() );
}
function dataGetContentFormat() {
return array(
array( 'hello world', 'Hello', null, null, 'text/x-wiki' ),
array( 'hello world', 'Hello', CONTENT_MODEL_CSS, null, 'text/css' ),
array( 'hello world', 'User:hello/there.css', null, null, 'text/css' ),
array( serialize('hello world'), 'Dummy:Hello', null, null, 'dummy' ),
array( 'hello world', 'Hello', null, null, CONTENT_FORMAT_WIKITEXT ),
array( 'hello world', 'Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ),
array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ),
array( serialize('hello world'), 'Dummy:Hello', null, null, 999999 ),
);
}
@ -234,7 +237,7 @@ class RevisionTest extends MediaWikiTestCase {
function dataGetContent() {
return array(
array( 'hello world', 'Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
array( serialize('hello world'), 'Hello', 'DUMMY', null, Revision::FOR_PUBLIC, serialize('hello world') ),
array( serialize('hello world'), 'Hello', 999999, null, Revision::FOR_PUBLIC, serialize('hello world') ),
array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize('hello world') ),
);
}
@ -252,7 +255,7 @@ class RevisionTest extends MediaWikiTestCase {
function dataGetText() {
return array(
array( 'hello world', 'Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
array( serialize('hello world'), 'Hello', 'DUMMY', null, Revision::FOR_PUBLIC, null ),
array( serialize('hello world'), 'Hello', 999999, null, Revision::FOR_PUBLIC, null ),
array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ),
);
}
@ -279,7 +282,7 @@ class RevisionTest extends MediaWikiTestCase {
public function dataGetSize( ) {
return array(
array( "hello world.", null, 12 ),
array( serialize( "hello world." ), "DUMMY", 12 ),
array( serialize( "hello world." ), 999999, 12 ),
);
}
@ -296,7 +299,7 @@ class RevisionTest extends MediaWikiTestCase {
public function dataGetSha1( ) {
return array(
array( "hello world.", null, Revision::base36Sha1( "hello world." ) ),
array( serialize( "hello world." ), "DUMMY", Revision::base36Sha1( serialize( "hello world." ) ) ),
array( serialize( "hello world." ), 999999, Revision::base36Sha1( serialize( "hello world." ) ) ),
);
}
@ -318,8 +321,8 @@ class RevisionTest extends MediaWikiTestCase {
$this->assertNotNull( $rev->getText(), 'no content text' );
$this->assertNotNull( $rev->getContent(), 'no content object available' );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
}
public function testConstructWithContent() {
@ -331,8 +334,8 @@ class RevisionTest extends MediaWikiTestCase {
$this->assertNotNull( $rev->getText(), 'no content text' );
$this->assertNotNull( $rev->getContent(), 'no content object available' );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
}
}

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class TitleMethodsTest extends MediaWikiTestCase {
public function setup() {
@ -100,7 +103,7 @@ class TitleMethodsTest extends MediaWikiTestCase {
}
public function dataGetContentModelName() {
public function dataGetContentModel() {
return array(
array( 'Foo', CONTENT_MODEL_WIKITEXT ),
array( 'Foo.js', CONTENT_MODEL_WIKITEXT ),
@ -126,19 +129,19 @@ class TitleMethodsTest extends MediaWikiTestCase {
}
/**
* @dataProvider dataGetContentModelName
* @dataProvider dataGetContentModel
*/
public function testGetContentModelName( $title, $expectedModelName ) {
public function testGetContentModel( $title, $expectedModelId ) {
$title = Title::newFromText( $title );
$this->assertEquals( $expectedModelName, $title->getContentModelName() );
$this->assertEquals( $expectedModelId, $title->getContentModel() );
}
/**
* @dataProvider dataGetContentModelName
* @dataProvider dataGetContentModel
*/
public function testHasContentModel( $title, $expectedModelName ) {
public function testHasContentModel( $title, $expectedModelId ) {
$title = Title::newFromText( $title );
$this->assertTrue( $title->hasContentModel( $expectedModelName ) );
$this->assertTrue( $title->hasContentModel( $expectedModelId ) );
}
public function dataIsCssOrJsPage() {

View file

@ -1,5 +1,6 @@
<?php
/**
* @group ContentHandler
* @group Database
* ^--- important, causes temporary tables to be used instead of the real database
**/
@ -235,11 +236,11 @@ class WikiPageTest extends MediaWikiTestCase {
$this->assertEquals( "some text", $text );
}
public function testGetContentModelName() {
$page = $this->createPage( "WikiPageTest_testGetContentModelName", "some text", CONTENT_MODEL_JAVASCRIPT );
public function testGetContentModel() {
$page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT );
$page = new WikiPage( $page->getTitle() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
}
public function testGetContentHandler() {
@ -536,7 +537,7 @@ more stuff
public function testReplaceSectionContent( $title, $text, $section, $with, $sectionTitle, $expected ) {
$page = $this->createPage( $title, $text );
$content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModelName() );
$content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
$c = $page->replaceSectionContent( $section, $content, $sectionTitle );
$this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
@ -773,7 +774,7 @@ more stuff
if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
else $user = $wgUser;
$content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModelName() );
$content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
$page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user );

View file

@ -1,7 +1,7 @@
<?php
/**
*
* @group ContentHandler
* @group Database
* ^--- important, causes temporary tables to be used instead of the real database
*/
@ -40,14 +40,14 @@ class WikiPageTest_ContentHandlerUseDB extends WikiPageTest {
parent::tearDown();
}
public function testGetContentModelName() {
$page = $this->createPage( "WikiPageTest_testGetContentModelName", "some text", CONTENT_MODEL_JAVASCRIPT );
public function testGetContentModel() {
$page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT );
$page = new WikiPage( $page->getTitle() );
// NOTE: since the content model is not recorded in the database,
// we expect to get the default, namely CONTENT_MODEL_WIKITEXT
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModelName() );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() );
}
public function testGetContentHandler() {

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class WikitextContentHandlerTest extends MediaWikiTestCase {
/**
@ -8,7 +11,7 @@ class WikitextContentHandlerTest extends MediaWikiTestCase {
var $handler;
public function setup() {
$this->handler = ContentHandler::getForModelName( CONTENT_MODEL_WIKITEXT );
$this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
}
public function teardown() {
@ -18,7 +21,7 @@ class WikitextContentHandlerTest extends MediaWikiTestCase {
$content = new WikitextContent( 'hello world' );
$this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) );
$this->assertEquals( 'hello world', $this->handler->serializeContent( $content, 'text/x-wiki' ) );
$this->assertEquals( 'hello world', $this->handler->serializeContent( $content, CONTENT_FORMAT_WIKITEXT ) );
try {
$this->handler->serializeContent( $content, 'dummy/foo' );
@ -32,7 +35,7 @@ class WikitextContentHandlerTest extends MediaWikiTestCase {
$content = $this->handler->unserializeContent( 'hello world' );
$this->assertEquals( 'hello world', $content->getNativeData() );
$content = $this->handler->unserializeContent( 'hello world', 'text/x-wiki' );
$content = $this->handler->unserializeContent( 'hello world', CONTENT_FORMAT_WIKITEXT );
$this->assertEquals( 'hello world', $content->getNativeData() );
try {
@ -53,8 +56,8 @@ class WikitextContentHandlerTest extends MediaWikiTestCase {
public function dataIsSupportedFormat( ) {
return array(
array( null, true ),
array( 'text/x-wiki', true ),
array( 'dummy/foo', false ),
array( CONTENT_FORMAT_WIKITEXT, true ),
array( 99887766, false ),
);
}

View file

@ -1,5 +1,8 @@
<?php
/**
* @group ContentHandler
*/
class WikitextContentTest extends MediaWikiTestCase {
public function setup() {
@ -369,16 +372,16 @@ just a test"
# =================================================================================================================
public function getModelName() {
public function testGetModel() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModelName() );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getModel() );
}
public function getContentHandler() {
public function testGetContentHandler() {
$content = $this->newContent( "hello world." );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelName() );
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
}
public function dataIsEmpty( ) {