Merge "Make sure that SQLite uses no prefix"
[lhc/web/wiklou.git] / includes / content / ContentHandler.php
index 4bb4e40..b61dc34 100644 (file)
@@ -24,7 +24,27 @@ class MWContentSerializationException extends MWException {
  * type), but wikitext content may be represented by a DOM or AST structure in
  * the future.
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
  * @since 1.21
+ *
+ * @file
+ * @ingroup Content
+ *
+ * @author Daniel Kinzler
  */
 abstract class ContentHandler {
 
@@ -60,7 +80,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
         * @param $content Content|null
         * @return null|string the textual form of $content, if available
         * @throws MWException if $content is not an instance of TextContent and
@@ -77,6 +96,8 @@ abstract class ContentHandler {
                        return $content->getNativeData();
                }
 
+               wfDebugLog( 'ContentHandler', 'Accessing ' . $content->getModel() . ' content as text!' );
+
                if ( $wgContentHandlerTextFallback == 'fail' ) {
                        throw new MWException(
                                "Attempt to get text from Content with model " .
@@ -101,8 +122,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
-        *
         * @param $text string the textual representation, will be
         *    unserialized to create the Content object
         * @param $title null|Title the title of the page this text belongs to.
@@ -162,7 +181,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
         * @param $title Title
         * @return null|string default model name for the page given by $title
         */
@@ -234,7 +252,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
         * @param $title Title
         * @return ContentHandler
         */
@@ -249,7 +266,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
         * @param $content Content
         * @return ContentHandler
         */
@@ -282,7 +298,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @static
         * @param $modelId String 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
@@ -317,6 +332,9 @@ abstract class ContentHandler {
                        }
                }
 
+               wfDebugLog( 'ContentHandler', 'Created handler for ' . $modelId
+                                       . ': ' . get_class( $handler ) );
+
                ContentHandler::$handlers[$modelId] = $handler;
                return ContentHandler::$handlers[$modelId];
        }
@@ -327,7 +345,6 @@ abstract class ContentHandler {
         * Model names are localized using system messages. Message keys
         * have the form content-model-$name, where $name is getContentModelName( $id ).
         *
-        * @static
         * @param $name String The content model ID, as given by a CONTENT_MODEL_XXX
         *    constant or returned by Revision::getContentModel().
         *
@@ -390,7 +407,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @abstract
         * @param $content Content The Content object to serialize
         * @param $format null|String The desired serialization format
         * @return string Serialized form of the content
@@ -402,7 +418,6 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @abstract
         * @param $blob string serialized form of the content
         * @param $format null|String the format used for serialization
         * @return Content the Content object created by deserializing $blob
@@ -567,8 +582,6 @@ abstract class ContentHandler {
                $rcid = 0, # FIXME: use everywhere!
                $refreshCache = false, $unhide = false
        ) {
-               $this->checkModelID( $context->getTitle()->getContentModel() );
-
                $diffEngineClass = $this->getDiffEngineClass();
 
                return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
@@ -592,15 +605,17 @@ abstract class ContentHandler {
         * @return Language the page's language
         */
        public function getPageLanguage( Title $title, Content $content = null ) {
-               global $wgContLang;
+               global $wgContLang, $wgLang;
+               $pageLang = $wgContLang;
 
                if ( $title->getNamespace() == NS_MEDIAWIKI ) {
                        // Parse mediawiki messages with correct target language
                        list( /* $unused */, $lang ) = MessageCache::singleton()->figureMessage( $title->getText() );
-                       return wfGetLangObj( $lang );
+                       $pageLang = wfGetLangObj( $lang );
                }
 
-               return $wgContLang;
+               wfRunHooks( 'PageContentLanguage', array( $title, &$pageLang, $wgLang ) );
+               return wfGetLangObj( $pageLang );
        }
 
        /**
@@ -787,20 +802,21 @@ abstract class ContentHandler {
                $content = $rev->getContent();
                $blank = false;
 
-               $this->checkModelID( $content->getModel() );
-
                // If the page is blank, use the text from the previous revision,
                // which can only be blank if there's a move/import/protect dummy
                // revision involved
-               if ( $content->getSize() == 0 ) {
+               if ( !$content || $content->isEmpty() ) {
                        $prev = $rev->getPrevious();
 
-                       if ( $prev )    {
-                               $content = $prev->getContent();
+                       if ( $prev ) {
+                               $rev = $prev;
+                               $content = $rev->getContent();
                                $blank = true;
                        }
                }
 
+               $this->checkModelID( $rev->getContentModel() );
+
                // Find out if there was only one contributor
                // Only scan the last 20 revisions
                $res = $dbw->select( 'revision', 'rev_user_text',
@@ -856,7 +872,7 @@ abstract class ContentHandler {
                }
 
                // Max content length = max comment length - length of the comment (excl. $1)
-               $text = $content->getTextForSummary( 255 - ( strlen( $reason ) - 2 ) );
+               $text = $content ? $content->getTextForSummary( 255 - ( strlen( $reason ) - 2 ) ) : '';
 
                // Now replace the '$1' placeholder
                $reason = str_replace( '$1', $text, $reason );
@@ -1081,239 +1097,3 @@ abstract class ContentHandler {
        }
 }
 
-/**
- * @since 1.21
- */
-class TextContentHandler extends ContentHandler {
-
-       public function __construct( $modelId = CONTENT_MODEL_TEXT, $formats = array( CONTENT_FORMAT_TEXT ) ) {
-               parent::__construct( $modelId, $formats );
-       }
-
-       /**
-        * Returns the content's text as-is.
-        *
-        * @param $content Content
-        * @param $format string|null
-        * @return mixed
-        */
-       public function serializeContent( Content $content, $format = null ) {
-               $this->checkFormat( $format );
-               return $content->getNativeData();
-       }
-
-       /**
-        * Attempts to merge differences between three versions. Returns a new
-        * Content object for a clean merge and false for failure or a conflict.
-        *
-        * All three Content objects passed as parameters must have the same
-        * content model.
-        *
-        * This text-based implementation uses wfMerge().
-        *
-        * @param $oldContent \Content|string  String
-        * @param $myContent \Content|string   String
-        * @param $yourContent \Content|string String
-        *
-        * @return Content|Bool
-        */
-       public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
-               $this->checkModelID( $oldContent->getModel() );
-               $this->checkModelID( $myContent->getModel() );
-               $this->checkModelID( $yourContent->getModel() );
-
-               $format = $this->getDefaultFormat();
-
-               $old = $this->serializeContent( $oldContent, $format );
-               $mine = $this->serializeContent( $myContent, $format );
-               $yours = $this->serializeContent( $yourContent, $format );
-
-               $ok = wfMerge( $old, $mine, $yours, $result );
-
-               if ( !$ok ) {
-                       return false;
-               }
-
-               if ( !$result ) {
-                       return $this->makeEmptyContent();
-               }
-
-               $mergedContent = $this->unserializeContent( $result, $format );
-               return $mergedContent;
-       }
-
-       /**
-        * Unserializes a Content object of the type supported by this ContentHandler.
-        *
-        * @since 1.21
-        *
-        * @param $text   string serialized form of the content
-        * @param $format null|String the format used for serialization
-        *
-        * @return Content the TextContent object wrapping $text
-        */
-       public function unserializeContent( $text, $format = null ) {
-               $this->checkFormat( $format );
-
-               return new TextContent( $text );
-       }
-
-       /**
-        * Creates an empty TextContent object.
-        *
-        * @since 1.21
-        *
-        * @return Content
-        */
-       public function makeEmptyContent() {
-               return new TextContent( '' );
-       }
-}
-
-/**
- * @since 1.21
- */
-class WikitextContentHandler extends TextContentHandler {
-
-       public function __construct( $modelId = CONTENT_MODEL_WIKITEXT ) {
-               parent::__construct( $modelId, array( CONTENT_FORMAT_WIKITEXT ) );
-       }
-
-       public function unserializeContent( $text, $format = null ) {
-               $this->checkFormat( $format );
-
-               return new WikitextContent( $text );
-       }
-
-       /**
-        * @see ContentHandler::makeEmptyContent
-        *
-        * @return Content
-        */
-       public function makeEmptyContent() {
-               return new WikitextContent( '' );
-       }
-
-
-       /**
-        * Returns a WikitextContent object representing a redirect to the given destination page.
-        *
-        * @see ContentHandler::makeRedirectContent
-        *
-        * @param Title $destination the page to redirect to.
-        *
-        * @return Content
-        */
-       public function makeRedirectContent( Title $destination ) {
-               $mwRedir = MagicWord::get( 'redirect' );
-               $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $destination->getPrefixedText() . "]]\n";
-
-               return new WikitextContent( $redirectText );
-       }
-
-       /**
-        * Returns true because wikitext supports sections.
-        *
-        * @return boolean whether sections are supported.
-        */
-       public function supportsSections() {
-               return true;
-       }
-
-       /**
-        * Returns true, because wikitext supports caching using the
-        * ParserCache mechanism.
-        *
-        * @since 1.21
-        * @return bool
-        */
-       public function isParserCacheSupported() {
-               return true;
-       }
-}
-
-# XXX: make ScriptContentHandler base class, do highlighting stuff there?
-
-/**
- * @since 1.21
- */
-class JavaScriptContentHandler extends TextContentHandler {
-
-       public function __construct( $modelId = CONTENT_MODEL_JAVASCRIPT ) {
-               parent::__construct( $modelId, array( CONTENT_FORMAT_JAVASCRIPT ) );
-       }
-
-       public function unserializeContent( $text, $format = null ) {
-               $this->checkFormat( $format );
-
-               return new JavaScriptContent( $text );
-       }
-
-       public function makeEmptyContent() {
-               return new JavaScriptContent( '' );
-       }
-
-       /**
-        * Returns the english language, because JS is english, and should be handled as such.
-        *
-        * @return Language wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
-       /**
-        * Returns the english language, because CSS is english, and should be handled as such.
-        *
-        * @return Language wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageViewLanguage()
-        */
-       public function getPageViewLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-}
-
-/**
- * @since 1.21
- */
-class CssContentHandler extends TextContentHandler {
-
-       public function __construct( $modelId = CONTENT_MODEL_CSS ) {
-               parent::__construct( $modelId, array( CONTENT_FORMAT_CSS ) );
-       }
-
-       public function unserializeContent( $text, $format = null ) {
-               $this->checkFormat( $format );
-
-               return new CssContent( $text );
-       }
-
-       public function makeEmptyContent() {
-               return new CssContent( '' );
-       }
-
-       /**
-        * Returns the english language, because CSS is english, and should be handled as such.
-        *
-        * @return Language wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
-       /**
-        * Returns the english language, because CSS is english, and should be handled as such.
-        *
-        * @return Language wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageViewLanguage()
-        */
-       public function getPageViewLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-}