Merge branch 'Wikidata' of ssh://gerrit.wikimedia.org:29418/mediawiki/core into Wikidata
authorNikola Smolenski <smolensk@eunet.rs>
Mon, 16 Apr 2012 15:47:29 +0000 (17:47 +0200)
committerNikola Smolenski <smolensk@eunet.rs>
Mon, 16 Apr 2012 15:47:29 +0000 (17:47 +0200)
20 files changed:
bin/svnstat [changed mode: 0755->0644]
bin/ulimit-tvf.sh [changed mode: 0755->0644]
bin/ulimit4.sh [changed mode: 0755->0644]
includes/Article.php
includes/Content.php
includes/ContentHandler.php
includes/EditPage.php
includes/WikiPage.php
includes/api/ApiParse.php
maintenance/cssjanus/cssjanus.py [changed mode: 0755->0644]
maintenance/cssjanus/csslex.py [changed mode: 0755->0644]
maintenance/dev/install.sh [changed mode: 0755->0644]
maintenance/dev/installmw.sh [changed mode: 0755->0644]
maintenance/dev/installphp.sh [changed mode: 0755->0644]
maintenance/dev/start.sh [changed mode: 0755->0644]
maintenance/hiphop/make [changed mode: 0755->0644]
maintenance/hiphop/run-server [changed mode: 0755->0644]
maintenance/storage/make-blobs [changed mode: 0755->0644]
tests/phpunit/install-phpunit.sh [changed mode: 0755->0644]
tests/phpunit/phpunit.php [changed mode: 0755->0644]

old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index d516ce9..31c0ac4 100644 (file)
@@ -206,7 +206,10 @@ class Article extends Page {
        }
 
        /**
-        * Note that getContent/loadContent do not follow redirects anymore.
+        * Returns a Content object representing the pages effective display content,
+     * not necessarily the revision's content!
+     *
+     * Note that getContent/loadContent do not follow redirects anymore.
         * If you need to fetch redirectable content easily, try
         * the shortcut in WikiPage::getRedirectTarget()
         *
@@ -215,7 +218,7 @@ class Article extends Page {
         *
         * @return Content
         */
-   public function getContentObject() {
+   protected function getContentObject() {
                global $wgUser;
 
                wfProfileIn( __METHOD__ );
@@ -635,7 +638,7 @@ class Article extends Page {
                                                        # Viewing a redirect page (e.g. with parameter redirect=no)
                                                        $wgOut->addHTML( $this->viewRedirect( $rt ) );
                                                        # Parse just to get categories, displaytitle, etc.
-                                                       $this->mParserOutput = $content->getParserOutput( $this->getTitle(), $oldid, $parserOptions );
+                                                       $this->mParserOutput = $content->getParserOutput( $this->getTitle(), $oldid, $parserOptions, false );
                                                        $wgOut->addParserOutputNoText( $this->mParserOutput );
                                                        $outputDone = true;
                                                }
index 4e80716..d8fbf7c 100644 (file)
@@ -57,28 +57,74 @@ abstract class Content {
                $this->mModelName = $modelName;
        }
 
+    /**
+     * Returns the name of the content model used by this content objects.
+     * Corresponds to the CONTENT_MODEL_XXX constants.
+     *
+     * @return String the model name
+     */
        public function getModelName() {
                return $this->mModelName;
        }
 
+    /**
+     * Throws an MWException if $modelName is not the name of the content model
+     * supported by this Content object.
+     */
        protected function checkModelName( $modelName ) {
                if ( $modelName !== $this->mModelName ) {
                        throw new MWException( "Bad content model: expected " . $this->mModelName . " but got found " . $modelName );
                }
        }
 
+    /**
+     * Conveniance method that returns the ContentHandler singleton for handling the content
+     * model this Content object uses.
+     *
+     * Shorthand for ContentHandler::getForContent( $this )
+     *
+     * @return ContentHandler
+     */
        public function getContentHandler() {
                return ContentHandler::getForContent( $this );
        }
 
+    /**
+     * Conveniance method that returns the default serialization format for the content model
+     * model this Content object uses.
+     *
+     * Shorthand for $this->getContentHandler()->getDefaultFormat()
+     *
+     * @return ContentHandler
+     */
        public function getDefaultFormat() {
                return $this->getContentHandler()->getDefaultFormat();
        }
 
+    /**
+     * Conveniance method that returns the list of serialization formats supported
+     * for the content model model this Content object uses.
+     *
+     * Shorthand for $this->getContentHandler()->getSupportedFormats()
+     *
+     * @return array of supported serialization formats
+     */
        public function getSupportedFormats() {
                return $this->getContentHandler()->getSupportedFormats();
        }
 
+    /**
+     * Returns true if $format is a supported serialization format for this Content object,
+     * false if it isn't.
+     *
+     * Note that this will always return true if $format is null, because null stands for the
+     * default serialization.
+     *
+     * Shorthand for $this->getContentHandler()->isSupportedFormat( $format )
+     *
+     * @param String $format the format to check
+     * @return bool whether the format is supported
+     */
        public function isSupportedFormat( $format ) {
                if ( !$format ) {
                        return true; // this means "use the default"
@@ -87,25 +133,59 @@ abstract class Content {
                return $this->getContentHandler()->isSupportedFormat( $format );
        }
 
+    /**
+     * Throws an MWException if $this->isSupportedFormat( $format ) doesn't return true.
+     *
+     * @param $format
+     * @throws MWException
+     */
        protected function checkFormat( $format ) {
                if ( !$this->isSupportedFormat( $format ) ) {
                        throw new MWException( "Format $format is not supported for content model " . $this->getModelName() );
                }
        }
 
+    /**
+     * Conveniance method for serializing this Content object.
+     *
+     * Shorthand for $this->getContentHandler()->serialize( $this, $format )
+     *
+     * @param null|String $format the desired serialization format (or null for the default format).
+     * @return String serialized form of this Content object
+     */
        public function serialize( $format = null ) {
                return $this->getContentHandler()->serialize( $this, $format );
        }
 
+    /**
+     * Returns true if this Content object represents empty content.
+     *
+     * @return bool whether this Content object is empty
+     */
     public function isEmpty() {
         return $this->getSize() == 0;
     }
 
-    public function equals( Content $that ) {
+    /**
+     * Returns true if this Content objects is conceptually equivalent to the given Content object.
+     *
+     * Will returns false if $that is null.
+     * Will return true if $that === $this.
+     *
+     * Returns false if this Content object uses a different content model than the
+     *
+     * @param Content $that the Content object to compare to
+     * @return bool true if this Content object is euzqla to $that, false otherwise.
+     */
+    public function equals( Content $that = null ) {
         if ( empty( $that ) ){ // FIXME: empty on an object?
                        return false;
                }
 
+               return false;
+               // FIXME: something is doing wrong here, causing the compared objects to always be the same.
+               // Hence returning false for now, so changes can actually be saved...
+
         if ( $that === $this ) {
                        return true;
                }
@@ -130,9 +210,13 @@ abstract class Content {
      * @param null|Title $title
      * @param null $revId
      * @param null|ParserOptions $options
+     * @param Boolean $generateHtml whether to generate Html (default: true). If false,
+     *        the result of calling getText() on the ParserOutput object returned by
+     *        this method is undefined.
+     *
      * @return ParserOutput
      */
-    public abstract function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = NULL );
+    public abstract function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = NULL, $generateHtml = true );
 
     /**
      * Construct the redirect destination from this content and return an
@@ -336,10 +420,12 @@ abstract class TextContent extends Content {
      *
      * @return ParserOutput representing the HTML form of the text
      */
-    public function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = null ) {
+    public function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = null, $generateHtml = true ) {
         # generic implementation, relying on $this->getHtml()
 
-        $html = $this->getHtml( $options );
+        if ( $generateHtml ) $html = $this->getHtml( $options );
+        else $html = '';
+
         $po = new ParserOutput( $html );
 
         return $po;
@@ -376,7 +462,7 @@ class WikitextContent extends TextContent {
      *
      * @return ParserOutput representing the HTML form of the text
      */
-    public function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = null ) {
+    public function getParserOutput( Title $title = null, $revId = null, ParserOptions $options = null, $generateHtml = true ) {
         global $wgParser;
 
         if ( !$options ) {
index 1a55788..b1e5827 100644 (file)
@@ -8,40 +8,40 @@ class MWContentSerializationException extends MWException {
 /**
  * A content handler knows how do deal with a specific type of content on a wiki page.
  * Content is stored in the database in a serialized form (using a serialization format aka mime type)
- * and is be unserialized into it's native PHP represenation (the content model).
- * 
+ * and is be unserialized into it's native PHP represenation (the content model), which is wrappe in
+ * an instance of the appropriate subclass of Content.
+ *
+ * ContentHandler instances are stateless singletons that serve, among other things, as a factory for
+ * Content objects. Generally, there is one subclass of ContentHandler and one subclass of Content
+ * for every type of content model.
+ *
  * Some content types have a flat model, that is, their native represenation is the
  * same as their serialized form. Examples would be JavaScript and CSS code. As of now,
  * this also applies to wikitext (mediawiki's default content type), but wikitext
  * content may be represented by a DOM or AST structure in the future.
- *
- * TODO: add documentation
  */
 abstract class ContentHandler {
 
-       /**
-        * @abstract
-        * @param Content $content
-        * @param null $format
-        * @return String
-        */
-       public abstract function serialize( Content $content, $format = null );
-
-       /**
-        * TODO: calling unserialize on a ContentHandler returns a Content?!! Something looks wrong here...
-        *
-        * @abstract
-        * @param $blob String
-        * @param null $format
-        * @return Content
-        */
-       public abstract function unserialize( $blob, $format = null );
-
-       /**
-        * FIXME: bad method name: suggests it empties the content of an instance rather then creating a new empty one
-        */
-       public abstract function emptyContent();
-
+    /**
+     * Conveniance function for getting flat text from a Content object. This shleould only
+     * be used in the context of backwards compatibility with code that is not yet able
+     * to handle Content objects!
+     *
+     * If $content is equal to null or false, this method returns the empty string.
+     *
+     * If $content is an instance of TextContent, this method returns the flat text as returned by $content->getnativeData().
+     *
+     * If $content is not a TextContent object, the bahaviour of this method depends on the global $wgContentHandlerTextFallback:
+     * If $wgContentHandlerTextFallback is 'fail' and $content is not a TextContent object, an MWException is thrown.
+     * If $wgContentHandlerTextFallback is 'serialize' and $content is not a TextContent object, $content->serialize()
+     * is called to get a string form of the content.
+     * Otherwise, this method returns null.
+     *
+     * @static
+     * @param Content|null $content
+     * @return null|string the textual form of $content, if available
+     * @throws MWException if $content is not an instance of TextContent and $wgContentHandlerTextFallback was set to 'fail'.
+     */
     public static function getContentText( Content $content = null ) {
         global $wgContentHandlerTextFallback;
 
@@ -64,6 +64,20 @@ abstract class ContentHandler {
         return null;
     }
 
+    /**
+     * 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.
+     *
+     * @static
+     * @param $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 $format the format to use for deserialization. If not given, the model's default format is used.
+     *
+     * @return Content a Content object representing $text
+     */
     public static function makeContent( $text, Title $title, $modelName = null, $format = null ) {
 
         if ( is_null( $modelName ) ) {
@@ -74,6 +88,28 @@ abstract class ContentHandler {
         return $handler->unserialize( $text, $format );
     }
 
+    /**
+     * 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().
+     *
+     * 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.
+     * * The hook DefaultModelFor may be used to override the page's default model.
+     * * Pages in NS_MEDIAWIKI and NS_USER default to the CSS or JavaScript model if they end in .js or .css, respectively.
+     * * Pages in NS_MEDIAWIKI default to the wikitext model otherwise.
+     * * The hook TitleIsCssOrJsPage may be used to force a page to use the CSS or JavaScript model if they end in .js or .css, respectively.
+     * * The hook TitleIsWikitextPage may be used to force a page to use the wikitext model.
+     *
+     * If none of the above applies, the wikitext model is used.
+     *
+     * Note: this is used by, and may thus not use, Title::getContentModelName()
+     *
+     * @static
+     * @param Title $title
+     * @return null|string default model name for the page given by $title
+     */
     public static function getDefaultModelFor( Title $title ) {
         global $wgNamespaceContentModels;
 
@@ -135,21 +171,48 @@ abstract class ContentHandler {
         return CONTENT_MODEL_WIKITEXT;
     }
 
+    /**
+     * returns the appropriate ContentHandler singleton for the given title
+     *
+     * @static
+     * @param Title $title
+     * @return ContentHandler
+     */
     public static function getForTitle( Title $title ) {
         $modelName = $title->getContentModelName();
         return ContentHandler::getForModelName( $modelName );
     }
 
+    /**
+     * returns the appropriate ContentHandler singleton for the given Content object
+     *
+     * @static
+     * @param Content $content
+     * @return ContentHandler
+     */
     public static function getForContent( Content $content ) {
         $modelName = $content->getModelName();
         return ContentHandler::getForModelName( $modelName );
     }
 
     /**
+     * returns the ContentHandler singleton for the given model name. 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
+     * model names, the values are either ContentHandler singleton objects, or strings specifying the appropriate
+     * subclass of 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.
+     *
      * @static
      * @param $modelName String the name of the content model for which to get a handler. Use CONTENT_MODEL_XXX constants.
-     * @return ContentHandler
-     * @throws MWException
+     * @return ContentHandler the ContentHandler singleton for handling the model given by $modelName
+     * @throws MWException if no handler is known for $modelName.
      */
     public static function getForModelName( $modelName ) {
         global $wgContentHandlers;
@@ -176,33 +239,104 @@ abstract class ContentHandler {
     }
 
     // ----------------------------------------------------------------------------------------------------------
+
+    /**
+     * Constructor, initializing the ContentHandler instance with it's model name 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 array $formats list for supported serialization formats (typically as MIME types)
+     */
     public function __construct( $modelName, $formats ) {
         $this->mModelName = $modelName;
         $this->mSupportedFormats = $formats;
     }
 
+
+    /**
+     * Serializes Content object of the type supported by this ContentHandler.
+     *
+     * @FIXME: bad method name: suggests it serializes a ContentHandler, while in fact it serializes a Content object
+     *
+     * @abstract
+     * @param Content $content the Content object to serialize
+     * @param null $format the desired serialization format
+     * @return String serialized form of the content
+     */
+    public abstract function serialize( Content $content, $format = null );
+
+    /**
+     * Unserializes a Content object of the type supported by this ContentHandler.
+     *
+     * @FIXME: bad method name: suggests it unserializes a ContentHandler, while in fact it unserializes a Content object
+     *
+     * @abstract
+     * @param $blob String serialized form of the content
+     * @param null $format the format used for serialization
+     * @return Content the Content object created by deserializing $blob
+     */
+    public abstract function unserialize( $blob, $format = null );
+
+    /**
+     * Creates an empty Content object of the type supported by this ContentHandler.
+     *
+     * @FIXME: bad method name: suggests it empties the content of an instance rather then creating a new empty one
+     */
+    public abstract function emptyContent();
+
+    /**
+     * Returns the model name that identifies the content model this ContentHandler can handle.
+     * Use with the CONTENT_MODEL_XXX constants.
+     *
+     * @return String the model name
+     */
     public function getModelName() {
-        // for wikitext: wikitext; in the future: wikiast, wikidom?
-        // for wikidata: wikidata
         return $this->mModelName;
     }
 
+    /**
+     * Throws an MWException if $modelName is not the content model handeled by this ContentHandler.
+     *
+     * @param $modelName the model name to check
+     */
     protected function checkModelName( $modelName ) {
         if ( $modelName !== $this->mModelName ) {
             throw new MWException( "Bad content model: expected " . $this->mModelName . " but got found " . $modelName );
         }
     }
 
+    /**
+     * Returns a list of serialization formats supported by the serialize() and unserialize() methods of
+     * this ContentHandler.
+     *
+     * @return array of serialization formats as MIME type like strings
+     */
     public function getSupportedFormats() {
-        // for wikitext: "text/x-mediawiki-1", "text/x-mediawiki-2", etc
-        // for wikidata: "application/json", "application/x-php", etc
         return $this->mSupportedFormats;
     }
 
+    /**
+     * The format used for serialization/deserialization per default by this ContentHandler.
+     *
+     * This default implementation will return the first element of the array of formats
+     * that was passed to the constructor.
+     *
+     * @return String the name of the default serialiozation format as a MIME type
+     */
     public function getDefaultFormat() {
         return $this->mSupportedFormats[0];
     }
 
+    /**
+     * Returns true if $format is a serialization format supported by this ContentHandler,
+     * and false otherwise.
+     *
+     * Note that if $format is null, this method always returns true, because null
+     * means "use the default format".
+     *
+     * @param $format the serialization format to check
+     * @return bool
+     */
     public function isSupportedFormat( $format ) {
 
         if ( !$format ) {
@@ -212,12 +346,30 @@ abstract class ContentHandler {
         return in_array( $format, $this->mSupportedFormats );
     }
 
+    /**
+     * Throws an MWException if isSupportedFormat( $format ) is not true. Convenient
+     * for checking whether a format provided as a parameter is actually supported.
+     *
+     * @param $format the serialization format to check
+     */
     protected function checkFormat( $format ) {
         if ( !$this->isSupportedFormat( $format ) ) {
             throw new MWException( "Format $format is not supported for content model " . $this->getModelName() );
         }
     }
 
+    /**
+     * Returns overrides for action handlers.
+     * Classes listed here will be used instead of the default one when
+     * (and only when) $wgActions[$action] === true. This allows subclasses
+     * to override the default actiuon handlers.
+     *
+     * @return Array
+     */
+    public function getActionOverrides() {
+        return array();
+    }
+
     /**
      * Return an Article object suitable for viewing the given object
      *
@@ -227,6 +379,7 @@ abstract class ContentHandler {
      * @param Title $title
      * @return Article
      * @todo Article is being refactored into an action class, keep track of that
+     * @todo Article really defines the view of the content... rename this method to createViewPage ?
      */
     public function createArticle( Title $title ) {
         $this->checkModelName( $title->getContentModelName() );
@@ -253,6 +406,7 @@ abstract class ContentHandler {
      *
      * @param IContextSource $context
      * @return ExternalEdit
+     * @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()->getModelName() );
@@ -271,6 +425,7 @@ abstract class ContentHandler {
      * @param $unhide boolean If set, allow viewing deleted revs
         *
         * @return DifferenceEngine
+     * @todo rename to createDifferenceEngine for consistency.
      */
     public function getDifferenceEngine( IContextSource $context, $old = 0, $new = 0, $rcid = 0, #FIMXE: use everywhere!
                                          $refreshCache = false, $unhide = false ) {
@@ -372,6 +527,8 @@ abstract class ContentHandler {
      * @param &$hasHistory Boolean: whether the page has a history
      * @return mixed String containing deletion reason or empty string, or boolean false
      *    if no revision occurred
+     *
+     * @todo &$hasHistory is extremely ugly, it's here because WikiPage::getAutoDeleteReason() and Article::getReason() have it / want it.
      */
     public function getAutoDeleteReason( Title $title, &$hasHistory ) {
         $dbw = wfGetDB( DB_MASTER );
index c61ef9a..51fbaaf 100644 (file)
@@ -901,9 +901,8 @@ class EditPage {
         * section replaced in its context (using WikiPage::replaceSection())
         * to the original text of the edit.
         *
-        * This difers from Article::getContent() that when a missing revision is
-        * encountered the result will be an empty string and not the
-        * 'missing-article' message.
+        * When a missing revision is
+        * encountered, the result will be an empty Content object.
         *
         * @since 1.19
         * @return string
@@ -920,7 +919,7 @@ class EditPage {
                        return $handler->emptyContent();
                }
 
-               $content = $this->mArticle->getContentObject();
+               $content = $revision->getContent();
                return $content;
        }
 
index b44db8d..4638546 100644 (file)
@@ -139,9 +139,21 @@ class WikiPage extends Page {
         * @return Array
         */
        public function getActionOverrides() {
-               return array();
+        $content_handler = $this->getContentHandler();
+               return $content_handler->getActionOverrides();
        }
 
+    /**
+     * Returns the ContentHandler instance to be used to deal with the content of this WikiPage.
+     *
+     * Shorthand for ContentHandler::getForModelName( $this->getContentModelName() );
+     *
+     * @return ContentHandler
+     */
+    public function getContentHandler() {
+        return ContentHandler::getForModelName( $this->getContentModelName() );
+    }
+
        /**
         * Get the title object of the article
         * @return Title object of this page
index afff5fd..bb079dd 100644 (file)
@@ -189,7 +189,7 @@ class ApiParse extends ApiBase {
                                return;
                        }
                        // Not cached (save or load)
-                       $p_result = $wgParser->parse( $params['pst'] ? $this->pstText : $this->text, $titleObj, $popts );
+                       $p_result = $wgParser->parse( $params['pst'] ? $this->pstText : $this->text, $titleObj, $popts ); #FIXME: use Content object¡
                }
 
                $result_array = array();
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)