Coding style
[lhc/web/wiklou.git] / includes / Message.php
index 3db82cd..44c72ad 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * OBS!!! *EXPERIMENTAL* This class is still under discussion.
- *
  * This class provides methods for fetching interface messages and
  * processing them into variety of formats that are needed in MediaWiki.
  *
  *
  * Examples:
  * Fetching a message text for interface message
- *    $button = Xml::button( Message::key( 'submit' )->text() );
+ *    $button = Xml::button( wfMessage( 'submit' )->text() );
  * </pre>
  * Messages can have parameters:
- *    Message::key( 'welcome-to' )->params( $wgSitename )->text(); 
+ *    wfMessage( 'welcome-to' )->params( $wgSitename )->text(); 
  *        {{GRAMMAR}} and friends work correctly
- *    Message::key( 'are-friends' )->params( $user, $friend );
- *    Message::key( 'bad-message' )->rawParams( '<script>...</script>' )->escaped()
+ *    wfMessage( 'are-friends', $user, $friend );
+ *    wfMessage( 'bad-message' )->rawParams( '<script>...</script>' )->escaped();
  * </pre>
  * Sometimes the message text ends up in the database, so content language is needed.
- *    Message::key( 'file-log' )->params( $user, $filename )->inContentLanguage()->text()
+ *    wfMessage( 'file-log', $user, $filename )->inContentLanguage()->text()
  * </pre>
  * Checking if message exists:
- *    Message::key( 'mysterious-message' )->exists()
+ *    wfMessage( 'mysterious-message' )->exists()
  * </pre>
  * If you want to use a different language:
- *    Message::key( 'email-header' )->language( $user->getOption( 'language' ) )->plain()
+ *    wfMessage( 'email-header' )->inLanguage( $user->getOption( 'language' ) )->plain()
  *        Note that you cannot parse the text except in the content or interface
  *        languages
  * </pre>
  *
  * Use full parsing.
  *     wfMsgExt( 'key', array( 'parseinline' ), 'apple' );
- *     === Message::key( 'key' )->params( 'apple' )->parse();
+ *     === wfMessage( 'key', 'apple' )->parse();
  * </pre>
  * Parseinline is used because it is more useful when pre-building html.
  * In normal use it is better to use OutputPage::(add|wrap)WikiMsg.
  *
  * Places where html cannot be used. {{-transformation is done.
  *     wfMsgExt( 'key', array( 'parsemag' ), 'apple', 'pear' );
- *     === Message::key( 'key' )->params( 'apple', 'pear' )->text();
+ *     === wfMessage( 'key', 'apple', 'pear' )->text();
  * </pre>
  *
  * Shortcut for escaping the message too, similar to wfMsgHTML, but
  * parameters are not replaced after escaping by default.
- * $escaped = Message::key( 'key' )->rawParams( 'apple' )->escaped();
+ * $escaped = wfMessage( 'key' )->rawParams( 'apple' )->escaped();
  * </pre>
  *
  * TODO:
  * - test, can we have tests?
  * - sort out the details marked with fixme
- * - should we have _m() or similar global wrapper?
  *
  * @since 1.17
+ * @author Niklas Laxström
  */
 class Message {
        /**
@@ -79,60 +77,57 @@ class Message {
         * List of parameters which will be substituted into the message.
         */
        protected $parameters = array();
-       
+
+       /**
+        * Format for the message.
+        * Supported formats are:
+        * * text (transform)
+        * * escaped (transform+htmlspecialchars)
+        * * block-parse
+        * * parse (default)
+        * * plain
+        */
+       protected $format = 'parse';
+
        /**
-        * Some situations need exotic combinations of options to the
-        * underlying Language modules; which can be specified here.
-        * Dependencies:
-        *     'parse' implies 'transform', 'escape'
+        * Whether database can be used.
         */
-       protected $options = array(
-               # Don't wrap the output in a block-level element
-               'inline' => true,
-               # Expand {{ constructs
-               'transform' => true,
-               # Output will be safe HTML
-               'escape' => true,
-               # Parse the text with the full parser
-               'parse' => true,
-               # Access the database when getting the message text
-               'usedb' => true,
-       );
+       protected $useDatabase = true;
 
        /**
         * Constructor.
         * @param $key String: message key
         * @param $params Array message parameters
-        * @param $options Array message options
         * @return Message: $this
         */
-       public function __construct( $key, $params=array(), $options=array() ) {
+       public function __construct( $key, $params = array() ) {
+               global $wgLang;
                $this->key = $key;
-               foreach( $params as $param ){
-                       $this->params( $param );
-               }
-               $this->options( $options );
+               $this->parameters = array_values( $params );
+               $this->language = $wgLang;
        }
 
        /**
         * Factory function that is just wrapper for the real constructor. It is
         * intented to be used instead of the real constructor, because it allows
         * chaining method calls, while new objects don't.
-        * //FIXME: key or get or something else?
         * @param $key String: message key
+        * @param Varargs: parameters as Strings
         * @return Message: $this
         */
-       public static function key( $key ) {
-               return new Message( $key );
+       public static function newFromKey( $key /*...*/ ) {
+               $params = func_get_args();
+               array_shift( $params );
+               return new self( $key, $params );
        }
 
        /**
         * Adds parameters to the parameter list of this message.
-        * @param Vargars: parameters as Strings
+        * @param Varargs: parameters as Strings
         * @return Message: $this
         */
        public function params( /*...*/ ) {
-               $this->parameters += array_values( func_get_args() );
+               $this->parameters = array_merge( $this->parameters, array_values( func_get_args() ) );
                return $this;
        }
 
@@ -146,35 +141,20 @@ class Message {
         */
        public function rawParams( /*...*/ ) {
                $params = func_get_args();
-               foreach( $params as $param ){
-                       $this->parameters[] =  array( 'raw' => $param );
+               foreach( $params as $param ) {
+                       $this->parameters[] = self::rawParam( $param );
                }
                return $this;
        }
        
-       /**
-        * Set some of the individual options, if you need to use some 
-        * funky combination of them.
-        * @param $options Array $option => $value
-        * @return Message $this
-        */
-       public function options( array $options ){
-               foreach( $options as $key => $value ){
-                       if( in_array( $key, $this->options ) ){
-                               $this->options[$key] = (bool)$value;
-                       }
-               }
-               return $this;
-       }
-
        /**
         * Request the message in any language that is supported.
         * As a side effect interface message status is unconditionally
         * turned off.
-        * @param $lang Mixed: langauge code or language object.
+        * @param $lang Mixed: language code or Language object.
         * @return Message: $this
         */
-       public function language( $lang ) {
+       public function inLanguage( $lang ) {
                if( $lang instanceof Language ){
                        $this->language = $lang;
                } elseif ( is_string( $lang ) ) {
@@ -194,8 +174,19 @@ class Message {
         * @return Message: $this
         */
        public function inContentLanguage() {
+               global $wgContLang;
                $this->interface = false;
-               $this->language = null;
+               $this->language = $wgContLang;
+               return $this;
+       }
+
+       /**
+        * Enable or disable database use.
+        * @param $value Boolean
+        * @return Message: $this
+        */
+       public function useDatabase( $value ) {
+               $this->useDatabase = (bool) $value;
                return $this;
        }
 
@@ -216,28 +207,20 @@ class Message {
                $string = $this->replaceParameters( $string, 'before' );
                
                # Maybe transform using the full parser
-               if( $this->options['parse'] ){
+               if( $this->format === 'parse' ) {
                        $string = $this->parseText( $string );
-               } else {
-                       
-                       # Transform {{ constructs
-                       if( $this->options['transform'] ){
-                               $string = $this->transformText( $string );
-                       }
-                       
-                       # Sanitise
-                       if( $this->options['escape'] ){
-                               # FIXME: Sanitizer method here?
-                               $string = htmlspecialchars( $string );
-                       }
-               }
-               
-               # Strip the block element
-               if( !$this->options['inline'] ){
                        $m = array();
                        if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
                                $string = $m[1];
                        }
+               } elseif( $this->format === 'block-parse' ){
+                       $string = $this->parseText( $string );
+               } elseif( $this->format === 'text' ){
+                       $string = $this->transformText( $string );
+               } elseif( $this->format === 'escaped' ){
+                       # FIXME: Sanitizer method here?
+                       $string = $this->transformText( $string );
+                       $string = htmlspecialchars( $string );
                }
                
                # Raw parameter replacement
@@ -250,11 +233,9 @@ class Message {
         * Fully parse the text from wikitext to HTML
         * @return String parsed HTML
         */
-       public function parse(){
-               $this->options( array(
-                       'parse' => true,
-               ));             
-               return $this->tostring();
+       public function parse() {
+               $this->format = 'parse';
+               return $this->toString();
        }
 
        /**
@@ -262,12 +243,8 @@ class Message {
         * @return String: Unescaped message text.
         */
        public function text() {
-               $this->options( array(
-                       'parse' => false,
-                       'transform' => true,
-                       'escape' => false,
-               ));             
-               return $this->tostring();
+               $this->format = 'text';
+               return $this->toString();
        }
 
        /**
@@ -275,13 +252,8 @@ class Message {
         * @return String: Unescaped untransformed message text.
         */
        public function plain() {
-               $this->options( array(
-                       'parse' => false,
-                       'transform' => false,
-                       'escape' => false,
-                       'inline' => false,
-               ));             
-               return $this->tostring();
+               $this->format = 'plain';
+               return $this->toString();
        }
 
        /**
@@ -289,26 +261,18 @@ class Message {
         * @return String: HTML
         */
        public function parseAsBlock() {
-               $this->options( array(
-                       'parse' => true,
-                       'inline' => false,
-               ));             
-               return $this->tostring();
+               $this->format = 'block-parse';
+               return $this->toString();
        }
 
        /**
         * Returns the message text. {{-transformation is done and the result
-        * is excaped excluding any raw parameters.
+        * is escaped excluding any raw parameters.
         * @return String: Escaped message text.
         */
        public function escaped() {
-               $this->options( array(
-                       'parse' => false,
-                       'transform' => true,
-                       'escape' => true,
-                       'inline' => false,
-               ));             
-               return $this->tostring();
+               $this->format = 'escaped';
+               return $this->toString();
        }
 
        /**
@@ -316,12 +280,11 @@ class Message {
         * @return Bool: true if it is and false if not.
         */
        public function exists() {
-               global $wgMessageCache;
-               return $wgMessageCache->get( 
-                       $this->key, 
-                       $this->options['usedb'], 
-                       $this->language 
-               ) !== false;
+               return $this->fetchMessage() !== false;
+       }
+
+       public static function rawParam( $value ) {
+               return array( 'raw' => $value );
        }
 
        /**
@@ -349,8 +312,8 @@ class Message {
         * @return Wikitext parsed into HTML
         */
        protected function parseText( $string ) {
-               global $wgOut;
-               if ( $this->language !== null ) {
+               global $wgOut, $wgLang, $wgContLang;
+               if ( $this->language !== $wgLang && $this->language !== $wgContLang ) {
                        # FIXME: remove this limitation
                        throw new MWException( 'Can only parse in interface or content language' );
                }
@@ -368,15 +331,27 @@ class Message {
        }
 
        /**
-        * Wrapper for what ever method we use to get message contents
-        * @return Unmodified message contents
+        * Returns the textual value for the message.
+        * @return Message contents or placeholder
         */
        protected function getMessageText() {
-               global $wgMessageCache;
-               $message = $wgMessageCache->get( $this->key, $this->options['usedb'], $this->language );
-               return $message === false
-                       ? '&lt;' . htmlspecialchars( $this->key ) . '&gt;'
-                       : $message;
+               $message = $this->fetchMessage();
+               if ( $message === false ) {
+                       return '&lt;' . htmlspecialchars( $this->key ) . '&gt;';
+               } else {
+                       return $message;
+               }
+       }
+
+       /**
+        * Wrapper for what ever method we use to get message contents
+        */
+       protected function fetchMessage() {
+               if ( !isset( $this->message ) ) {
+                       global $wgMessageCache;
+                       $this->message = $wgMessageCache->get( $this->key, $this->useDatabase, $this->language );
+               }
+               return $this->message;
        }
 
 }
\ No newline at end of file