From a720db89571f408a67bfffc6baba1115654dc105 Mon Sep 17 00:00:00 2001 From: Daniel Kinzler Date: Tue, 27 Mar 2012 12:15:30 +0000 Subject: [PATCH] assert correct content model and format --- includes/Content.php | 26 ++++++++++++++ includes/ContentHandler.php | 68 ++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/includes/Content.php b/includes/Content.php index 52e3b1e880..1ec4b0c569 100644 --- a/includes/Content.php +++ b/includes/Content.php @@ -16,10 +16,36 @@ abstract class Content { return $this->mModelName; } + protected function checkModelName( $modelName ) { + if ( $modelName !== $this->mModelName ) { + throw new MWException( "Bad content model: expected " . $this->mModelName . " but got found " . $modelName ); + } + } + public function getContentHandler() { return ContentHandler::getForContent( $this ); } + public function getDefaultFormat() { + return $this->getContentHandler()->getDefaultFormat(); + } + + public function getSupportedFormats() { + return $this->getContentHandler()->getSupportedFormats(); + } + + public function isSupportedFormat( $format ) { + if ( !$format ) return true; # this means "use the default" + + return $this->getContentHandler()->isSupportedFormat( $format ); + } + + protected function checkFormat( $format ) { + if ( !$this->isSupportedFormat( $format ) ) { + throw new MWException( "Format $format is not supported for content model " . $this->getModelName() ); + } + } + public function serialize( $format = null ) { return $this->getContentHandler()->serialize( $this, $format ); } diff --git a/includes/ContentHandler.php b/includes/ContentHandler.php index 3a0d50a7b1..ce1c4fb2fc 100644 --- a/includes/ContentHandler.php +++ b/includes/ContentHandler.php @@ -118,8 +118,14 @@ abstract class ContentHandler { global $wgContentHandlers; if ( empty( $wgContentHandlers[$modelName] ) ) { - #FIXME: hook here! - throw new MWException( "No handler for model $modelName registered in \$wgContentHandlers" ); + $handler = null; + wfRunHooks( "ContentHandlerForModelName", array( $modelName, &$handler ) ); #FIXME: document new hook + + if ( $handler ) { # NOTE: may be a string or an object, either is fine! + $wgContentHandlers[$modelName] = $handler; + } else { + throw new MWException( "No handler for model $modelName registered in \$wgContentHandlers" ); + } } if ( is_string( $wgContentHandlers[$modelName] ) ) { @@ -142,6 +148,11 @@ abstract class ContentHandler { return $this->mModelName; } + protected function checkModelName( $modelName ) { + if ( $modelName !== $this->mModelName ) { + throw new MWException( "Bad content model: expected " . $this->mModelName . " but got found " . $modelName ); + } + } public function getSupportedFormats() { # for wikitext: "text/x-mediawiki-1", "text/x-mediawiki-2", etc @@ -153,6 +164,18 @@ abstract class ContentHandler { return $this->mSupportedFormats[0]; } + public function isSupportedFormat( $format ) { + if ( !$format ) return true; # this means "use the default" + + return in_array( $format, $this->mSupportedFormats ); + } + + protected function checkFormat( $format ) { + if ( !$this->isSupportedFormat( $format ) ) { + throw new MWException( "Format $format is not supported for content model " . $this->getModelName() ); + } + } + /** * @abstract * @param Content $content @@ -182,7 +205,8 @@ abstract class ContentHandler { * @todo Article is being refactored into an action class, keep track of that */ public function createArticle( Title $title ) { - #XXX: assert that $title->getContentModelName() == $this->getModelname()? + $this->checkModelName( $title->getContentModelName() ); + $article = new Article($title); return $article; } @@ -194,7 +218,8 @@ abstract class ContentHandler { * @return \EditPage */ public function createEditPage( Article $article ) { - #XXX: assert that $article->getContentObject()->getModelName() == $this->getModelname()? + $this->checkModelName( $article->getContentObject()->getModelName() ); + $editPage = new EditPage( $article ); return $editPage; } @@ -206,7 +231,8 @@ abstract class ContentHandler { * @return \ExternalEdit */ public function createExternalEdit( IContextSource $context ) { - #XXX: assert that $article->getContentObject()->getModelName() == $this->getModelname()? + $this->checkModelName( $context->getTitle()->getModelName() ); + $externalEdit = new ExternalEdit( $context ); return $externalEdit; } @@ -223,6 +249,8 @@ abstract class ContentHandler { public function getDifferenceEngine( IContextSource $context, $old = 0, $new = 0, $rcid = 0, #FIMXE: use everywhere! $refreshCache = false, $unhide = false ) { + $this->checkModelName( $context->getTitle()->getModelName() ); + $de = new DifferenceEngine( $context, $old, $new, $rcid, $refreshCache, $unhide ); return $de; @@ -428,6 +456,14 @@ abstract class ContentHandler { #TODO: Article::showCssOrJsPage ---> specialized classes! #XXX: ImagePage and CategoryPage... wrappers that use ContentHandler? or ContentHandler creates wrappers? + + #TODO: hook into dump generation to serialize and record model and format! + #TODO: cover action=raw + #TODO: make sure we cover lucene search / wikisearch. + #TODO: nice&sane integration of GeSHi syntax highlighting + # [11:59] Hooks are ugly; make CodeHighlighter interface and a config to set the class which handles syntax highlighting + # [12:00] And default it to a DummyHighlighter + #TODO: make sure we cover the external editor interface (does anyone actually use that?!) } @@ -438,7 +474,7 @@ abstract class TextContentHandler extends ContentHandler { } public function serialize( Content $content, $format = null ) { - #FIXME: assert format + $this->checkFormat( $format ); return $content->getNativeData(); } @@ -454,6 +490,9 @@ abstract class TextContentHandler extends ContentHandler { * @return Content|Bool */ public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) { + $this->checkModelName( $oldContent->getModelName() ); + #TODO: check that all Content objects have the same content model! #XXX: what to do if they don't? + $format = $this->getDefaultFormat(); $old = $this->serialize( $oldContent, $format ); @@ -478,17 +517,20 @@ class WikitextContentHandler extends TextContentHandler { } public function unserialize( $text, $format = null ) { - #FIXME: assert format - return new WikitextContent($text); + $this->checkFormat( $format ); + + return new WikitextContent( $text ); } public function emptyContent() { - return new WikitextContent(""); + return new WikitextContent( "" ); } } +#TODO: make ScriptContentHandler base class with plugin interface for syntax highlighting! + class JavaScriptContentHandler extends TextContentHandler { public function __construct( $modelName = CONTENT_MODEL_WIKITEXT ) { @@ -496,11 +538,11 @@ class JavaScriptContentHandler extends TextContentHandler { } public function unserialize( $text, $format = null ) { - return new JavaScriptContent($text); + return new JavaScriptContent( $text ); } public function emptyContent() { - return new JavaScriptContent(""); + return new JavaScriptContent( "" ); } } @@ -511,11 +553,11 @@ class CssContentHandler extends TextContentHandler { } public function unserialize( $text, $format = null ) { - return new CssContent($text); + return new CssContent( $text ); } public function emptyContent() { - return new CssContent(""); + return new CssContent( "" ); } } -- 2.20.1