[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/ -> Message.php (source)

   1  <?php
   2  /**
   3   * Fetching and processing of interface messages.
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @author Niklas Laxström
  22   */
  23  
  24  /**
  25   * The Message class provides methods which fulfil two basic services:
  26   *  - fetching interface messages
  27   *  - processing messages into a variety of formats
  28   *
  29   * First implemented with MediaWiki 1.17, the Message class is intended to
  30   * replace the old wfMsg* functions that over time grew unusable.
  31   * @see https://www.mediawiki.org/wiki/Manual:Messages_API for equivalences
  32   * between old and new functions.
  33   *
  34   * You should use the wfMessage() global function which acts as a wrapper for
  35   * the Message class. The wrapper let you pass parameters as arguments.
  36   *
  37   * The most basic usage cases would be:
  38   *
  39   * @code
  40   *     // Initialize a Message object using the 'some_key' message key
  41   *     $message = wfMessage( 'some_key' );
  42   *
  43   *     // Using two parameters those values are strings 'value1' and 'value2':
  44   *     $message = wfMessage( 'some_key',
  45   *          'value1', 'value2'
  46   *     );
  47   * @endcode
  48   *
  49   * @section message_global_fn Global function wrapper:
  50   *
  51   * Since wfMessage() returns a Message instance, you can chain its call with
  52   * a method. Some of them return a Message instance too so you can chain them.
  53   * You will find below several examples of wfMessage() usage.
  54   *
  55   * Fetching a message text for interface message:
  56   *
  57   * @code
  58   *    $button = Xml::button(
  59   *         wfMessage( 'submit' )->text()
  60   *    );
  61   * @endcode
  62   *
  63   * A Message instance can be passed parameters after it has been constructed,
  64   * use the params() method to do so:
  65   *
  66   * @code
  67   *     wfMessage( 'welcome-to' )
  68   *         ->params( $wgSitename )
  69   *         ->text();
  70   * @endcode
  71   *
  72   * {{GRAMMAR}} and friends work correctly:
  73   *
  74   * @code
  75   *    wfMessage( 'are-friends',
  76   *        $user, $friend
  77   *    );
  78   *    wfMessage( 'bad-message' )
  79   *         ->rawParams( '<script>...</script>' )
  80   *         ->escaped();
  81   * @endcode
  82   *
  83   * @section message_language Changing language:
  84   *
  85   * Messages can be requested in a different language or in whatever current
  86   * content language is being used. The methods are:
  87   *     - Message->inContentLanguage()
  88   *     - Message->inLanguage()
  89   *
  90   * Sometimes the message text ends up in the database, so content language is
  91   * needed:
  92   *
  93   * @code
  94   *    wfMessage( 'file-log',
  95   *        $user, $filename
  96   *    )->inContentLanguage()->text();
  97   * @endcode
  98   *
  99   * Checking whether a message exists:
 100   *
 101   * @code
 102   *    wfMessage( 'mysterious-message' )->exists()
 103   *    // returns a boolean whether the 'mysterious-message' key exist.
 104   * @endcode
 105   *
 106   * If you want to use a different language:
 107   *
 108   * @code
 109   *    $userLanguage = $user->getOption( 'language' );
 110   *    wfMessage( 'email-header' )
 111   *         ->inLanguage( $userLanguage )
 112   *         ->plain();
 113   * @endcode
 114   *
 115   * @note You can parse the text only in the content or interface languages
 116   *
 117   * @section message_compare_old Comparison with old wfMsg* functions:
 118   *
 119   * Use full parsing:
 120   *
 121   * @code
 122   *     // old style:
 123   *     wfMsgExt( 'key', array( 'parseinline' ), 'apple' );
 124   *     // new style:
 125   *     wfMessage( 'key', 'apple' )->parse();
 126   * @endcode
 127   *
 128   * Parseinline is used because it is more useful when pre-building HTML.
 129   * In normal use it is better to use OutputPage::(add|wrap)WikiMsg.
 130   *
 131   * Places where HTML cannot be used. {{-transformation is done.
 132   * @code
 133   *     // old style:
 134   *     wfMsgExt( 'key', array( 'parsemag' ), 'apple', 'pear' );
 135   *     // new style:
 136   *     wfMessage( 'key', 'apple', 'pear' )->text();
 137   * @endcode
 138   *
 139   * Shortcut for escaping the message too, similar to wfMsgHTML(), but
 140   * parameters are not replaced after escaping by default.
 141   * @code
 142   *     $escaped = wfMessage( 'key' )
 143   *          ->rawParams( 'apple' )
 144   *          ->escaped();
 145   * @endcode
 146   *
 147   * @section message_appendix Appendix:
 148   *
 149   * @todo
 150   * - test, can we have tests?
 151   * - this documentation needs to be extended
 152   *
 153   * @see https://www.mediawiki.org/wiki/WfMessage()
 154   * @see https://www.mediawiki.org/wiki/New_messages_API
 155   * @see https://www.mediawiki.org/wiki/Localisation
 156   *
 157   * @since 1.17
 158   */
 159  class Message {
 160  
 161      /**
 162       * In which language to get this message. True, which is the default,
 163       * means the current interface language, false content language.
 164       *
 165       * @var bool
 166       */
 167      protected $interface = true;
 168  
 169      /**
 170       * In which language to get this message. Overrides the $interface
 171       * variable.
 172       *
 173       * @var Language
 174       */
 175      protected $language = null;
 176  
 177      /**
 178       * @var string The message key. If $keysToTry has more than one element,
 179       * this may change to one of the keys to try when fetching the message text.
 180       */
 181      protected $key;
 182  
 183      /**
 184       * @var string[] List of keys to try when fetching the message.
 185       */
 186      protected $keysToTry;
 187  
 188      /**
 189       * @var array List of parameters which will be substituted into the message.
 190       */
 191      protected $parameters = array();
 192  
 193      /**
 194       * Format for the message.
 195       * Supported formats are:
 196       * * text (transform)
 197       * * escaped (transform+htmlspecialchars)
 198       * * block-parse
 199       * * parse (default)
 200       * * plain
 201       *
 202       * @var string
 203       */
 204      protected $format = 'parse';
 205  
 206      /**
 207       * @var bool Whether database can be used.
 208       */
 209      protected $useDatabase = true;
 210  
 211      /**
 212       * @var Title Title object to use as context.
 213       */
 214      protected $title = null;
 215  
 216      /**
 217       * @var Content Content object representing the message.
 218       */
 219      protected $content = null;
 220  
 221      /**
 222       * @var string
 223       */
 224      protected $message;
 225  
 226      /**
 227       * @since 1.17
 228       *
 229       * @param string|string[] $key Message key or array of message keys to try and use the first
 230       * non-empty message for.
 231       * @param array $params Message parameters.
 232       * @param Language $language Optional language of the message, defaults to $wgLang.
 233       *
 234       * @throws InvalidArgumentException
 235       */
 236  	public function __construct( $key, $params = array(), Language $language = null ) {
 237          global $wgLang;
 238  
 239          if ( !is_string( $key ) && !is_array( $key ) ) {
 240              throw new InvalidArgumentException( '$key must be a string or an array' );
 241          }
 242  
 243          $this->keysToTry = (array)$key;
 244  
 245          if ( empty( $this->keysToTry ) ) {
 246              throw new InvalidArgumentException( '$key must not be an empty list' );
 247          }
 248  
 249          $this->key = reset( $this->keysToTry );
 250  
 251          $this->parameters = array_values( $params );
 252          $this->language = $language ? $language : $wgLang;
 253      }
 254  
 255      /**
 256       * @since 1.24
 257       *
 258       * @return bool True if this is a multi-key message, that is, if the key provided to the
 259       * constructor was a fallback list of keys to try.
 260       */
 261  	public function isMultiKey() {
 262          return count( $this->keysToTry ) > 1;
 263      }
 264  
 265      /**
 266       * @since 1.24
 267       *
 268       * @return string[] The list of keys to try when fetching the message text,
 269       * in order of preference.
 270       */
 271  	public function getKeysToTry() {
 272          return $this->keysToTry;
 273      }
 274  
 275      /**
 276       * Returns the message key.
 277       *
 278       * If a list of multiple possible keys was supplied to the constructor, this method may
 279       * return any of these keys. After the message ahs been fetched, this method will return
 280       * the key that was actually used to fetch the message.
 281       *
 282       * @since 1.21
 283       *
 284       * @return string
 285       */
 286  	public function getKey() {
 287          return $this->key;
 288      }
 289  
 290      /**
 291       * Returns the message parameters.
 292       *
 293       * @since 1.21
 294       *
 295       * @return array
 296       */
 297  	public function getParams() {
 298          return $this->parameters;
 299      }
 300  
 301      /**
 302       * Returns the message format.
 303       *
 304       * @since 1.21
 305       *
 306       * @return string
 307       */
 308  	public function getFormat() {
 309          return $this->format;
 310      }
 311  
 312      /**
 313       * Returns the Language of the Message.
 314       *
 315       * @since 1.23
 316       *
 317       * @return Language
 318       */
 319  	public function getLanguage() {
 320          return $this->language;
 321      }
 322  
 323      /**
 324       * Factory function that is just wrapper for the real constructor. It is
 325       * intended to be used instead of the real constructor, because it allows
 326       * chaining method calls, while new objects don't.
 327       *
 328       * @since 1.17
 329       *
 330       * @param string|string[] $key Message key or array of keys.
 331       * @param mixed $param,... Parameters as strings.
 332       *
 333       * @return Message
 334       */
 335  	public static function newFromKey( $key /*...*/ ) {
 336          $params = func_get_args();
 337          array_shift( $params );
 338          return new self( $key, $params );
 339      }
 340  
 341      /**
 342       * Factory function accepting multiple message keys and returning a message instance
 343       * for the first message which is non-empty. If all messages are empty then an
 344       * instance of the first message key is returned.
 345       *
 346       * @since 1.18
 347       *
 348       * @param string|string[] $keys,... Message keys, or first argument as an array of all the
 349       * message keys.
 350       *
 351       * @return Message
 352       */
 353  	public static function newFallbackSequence( /*...*/ ) {
 354          $keys = func_get_args();
 355          if ( func_num_args() == 1 ) {
 356              if ( is_array( $keys[0] ) ) {
 357                  // Allow an array to be passed as the first argument instead
 358                  $keys = array_values( $keys[0] );
 359              } else {
 360                  // Optimize a single string to not need special fallback handling
 361                  $keys = $keys[0];
 362              }
 363          }
 364          return new self( $keys );
 365      }
 366  
 367      /**
 368       * Adds parameters to the parameter list of this message.
 369       *
 370       * @since 1.17
 371       *
 372       * @param mixed $params,... Parameters as strings, or a single argument that is
 373       * an array of strings.
 374       *
 375       * @return Message $this
 376       */
 377  	public function params( /*...*/ ) {
 378          $args = func_get_args();
 379          if ( isset( $args[0] ) && is_array( $args[0] ) ) {
 380              $args = $args[0];
 381          }
 382          $args_values = array_values( $args );
 383          $this->parameters = array_merge( $this->parameters, $args_values );
 384          return $this;
 385      }
 386  
 387      /**
 388       * Add parameters that are substituted after parsing or escaping.
 389       * In other words the parsing process cannot access the contents
 390       * of this type of parameter, and you need to make sure it is
 391       * sanitized beforehand.  The parser will see "$n", instead.
 392       *
 393       * @since 1.17
 394       *
 395       * @param mixed $params,... Raw parameters as strings, or a single argument that is
 396       * an array of raw parameters.
 397       *
 398       * @return Message $this
 399       */
 400  	public function rawParams( /*...*/ ) {
 401          $params = func_get_args();
 402          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 403              $params = $params[0];
 404          }
 405          foreach ( $params as $param ) {
 406              $this->parameters[] = self::rawParam( $param );
 407          }
 408          return $this;
 409      }
 410  
 411      /**
 412       * Add parameters that are numeric and will be passed through
 413       * Language::formatNum before substitution
 414       *
 415       * @since 1.18
 416       *
 417       * @param mixed $param,... Numeric parameters, or a single argument that is
 418       * an array of numeric parameters.
 419       *
 420       * @return Message $this
 421       */
 422  	public function numParams( /*...*/ ) {
 423          $params = func_get_args();
 424          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 425              $params = $params[0];
 426          }
 427          foreach ( $params as $param ) {
 428              $this->parameters[] = self::numParam( $param );
 429          }
 430          return $this;
 431      }
 432  
 433      /**
 434       * Add parameters that are durations of time and will be passed through
 435       * Language::formatDuration before substitution
 436       *
 437       * @since 1.22
 438       *
 439       * @param int|int[] $param,... Duration parameters, or a single argument that is
 440       * an array of duration parameters.
 441       *
 442       * @return Message $this
 443       */
 444  	public function durationParams( /*...*/ ) {
 445          $params = func_get_args();
 446          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 447              $params = $params[0];
 448          }
 449          foreach ( $params as $param ) {
 450              $this->parameters[] = self::durationParam( $param );
 451          }
 452          return $this;
 453      }
 454  
 455      /**
 456       * Add parameters that are expiration times and will be passed through
 457       * Language::formatExpiry before substitution
 458       *
 459       * @since 1.22
 460       *
 461       * @param string|string[] $param,... Expiry parameters, or a single argument that is
 462       * an array of expiry parameters.
 463       *
 464       * @return Message $this
 465       */
 466  	public function expiryParams( /*...*/ ) {
 467          $params = func_get_args();
 468          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 469              $params = $params[0];
 470          }
 471          foreach ( $params as $param ) {
 472              $this->parameters[] = self::expiryParam( $param );
 473          }
 474          return $this;
 475      }
 476  
 477      /**
 478       * Add parameters that are time periods and will be passed through
 479       * Language::formatTimePeriod before substitution
 480       *
 481       * @since 1.22
 482       *
 483       * @param int|int[] $param,... Time period parameters, or a single argument that is
 484       * an array of time period parameters.
 485       *
 486       * @return Message $this
 487       */
 488  	public function timeperiodParams( /*...*/ ) {
 489          $params = func_get_args();
 490          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 491              $params = $params[0];
 492          }
 493          foreach ( $params as $param ) {
 494              $this->parameters[] = self::timeperiodParam( $param );
 495          }
 496          return $this;
 497      }
 498  
 499      /**
 500       * Add parameters that are file sizes and will be passed through
 501       * Language::formatSize before substitution
 502       *
 503       * @since 1.22
 504       *
 505       * @param int|int[] $param,... Size parameters, or a single argument that is
 506       * an array of size parameters.
 507       *
 508       * @return Message $this
 509       */
 510  	public function sizeParams( /*...*/ ) {
 511          $params = func_get_args();
 512          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 513              $params = $params[0];
 514          }
 515          foreach ( $params as $param ) {
 516              $this->parameters[] = self::sizeParam( $param );
 517          }
 518          return $this;
 519      }
 520  
 521      /**
 522       * Add parameters that are bitrates and will be passed through
 523       * Language::formatBitrate before substitution
 524       *
 525       * @since 1.22
 526       *
 527       * @param int|int[] $param,... Bit rate parameters, or a single argument that is
 528       * an array of bit rate parameters.
 529       *
 530       * @return Message $this
 531       */
 532  	public function bitrateParams( /*...*/ ) {
 533          $params = func_get_args();
 534          if ( isset( $params[0] ) && is_array( $params[0] ) ) {
 535              $params = $params[0];
 536          }
 537          foreach ( $params as $param ) {
 538              $this->parameters[] = self::bitrateParam( $param );
 539          }
 540          return $this;
 541      }
 542  
 543      /**
 544       * Set the language and the title from a context object
 545       *
 546       * @since 1.19
 547       *
 548       * @param IContextSource $context
 549       *
 550       * @return Message $this
 551       */
 552  	public function setContext( IContextSource $context ) {
 553          $this->inLanguage( $context->getLanguage() );
 554          $this->title( $context->getTitle() );
 555          $this->interface = true;
 556  
 557          return $this;
 558      }
 559  
 560      /**
 561       * Request the message in any language that is supported.
 562       * As a side effect interface message status is unconditionally
 563       * turned off.
 564       *
 565       * @since 1.17
 566       *
 567       * @param Language|string $lang Language code or Language object.
 568       *
 569       * @return Message $this
 570       * @throws MWException
 571       */
 572  	public function inLanguage( $lang ) {
 573          if ( $lang instanceof Language || $lang instanceof StubUserLang ) {
 574              $this->language = $lang;
 575          } elseif ( is_string( $lang ) ) {
 576              if ( $this->language->getCode() != $lang ) {
 577                  $this->language = Language::factory( $lang );
 578              }
 579          } else {
 580              $type = gettype( $lang );
 581              throw new MWException( __METHOD__ . " must be "
 582                  . "passed a String or Language object; $type given"
 583              );
 584          }
 585          $this->message = null;
 586          $this->interface = false;
 587          return $this;
 588      }
 589  
 590      /**
 591       * Request the message in the wiki's content language,
 592       * unless it is disabled for this message.
 593       *
 594       * @since 1.17
 595       * @see $wgForceUIMsgAsContentMsg
 596       *
 597       * @return Message $this
 598       */
 599  	public function inContentLanguage() {
 600          global $wgForceUIMsgAsContentMsg;
 601          if ( in_array( $this->key, (array)$wgForceUIMsgAsContentMsg ) ) {
 602              return $this;
 603          }
 604  
 605          global $wgContLang;
 606          $this->inLanguage( $wgContLang );
 607          return $this;
 608      }
 609  
 610      /**
 611       * Allows manipulating the interface message flag directly.
 612       * Can be used to restore the flag after setting a language.
 613       *
 614       * @since 1.20
 615       *
 616       * @param bool $interface
 617       *
 618       * @return Message $this
 619       */
 620  	public function setInterfaceMessageFlag( $interface ) {
 621          $this->interface = (bool)$interface;
 622          return $this;
 623      }
 624  
 625      /**
 626       * Enable or disable database use.
 627       *
 628       * @since 1.17
 629       *
 630       * @param bool $useDatabase
 631       *
 632       * @return Message $this
 633       */
 634  	public function useDatabase( $useDatabase ) {
 635          $this->useDatabase = (bool)$useDatabase;
 636          return $this;
 637      }
 638  
 639      /**
 640       * Set the Title object to use as context when transforming the message
 641       *
 642       * @since 1.18
 643       *
 644       * @param Title $title
 645       *
 646       * @return Message $this
 647       */
 648  	public function title( $title ) {
 649          $this->title = $title;
 650          return $this;
 651      }
 652  
 653      /**
 654       * Returns the message as a Content object.
 655       *
 656       * @return Content
 657       */
 658  	public function content() {
 659          if ( !$this->content ) {
 660              $this->content = new MessageContent( $this );
 661          }
 662  
 663          return $this->content;
 664      }
 665  
 666      /**
 667       * Returns the message parsed from wikitext to HTML.
 668       *
 669       * @since 1.17
 670       *
 671       * @return string HTML
 672       */
 673  	public function toString() {
 674          $string = $this->fetchMessage();
 675  
 676          if ( $string === false ) {
 677              $key = htmlspecialchars( $this->key );
 678              if ( $this->format === 'plain' ) {
 679                  return '<' . $key . '>';
 680              }
 681              return '&lt;' . $key . '&gt;';
 682          }
 683  
 684          # Replace $* with a list of parameters for &uselang=qqx.
 685          if ( strpos( $string, '$*' ) !== false ) {
 686              $paramlist = '';
 687              if ( $this->parameters !== array() ) {
 688                  $paramlist = ': $' . implode( ', $', range( 1, count( $this->parameters ) ) );
 689              }
 690              $string = str_replace( '$*', $paramlist, $string );
 691          }
 692  
 693          # Replace parameters before text parsing
 694          $string = $this->replaceParameters( $string, 'before' );
 695  
 696          # Maybe transform using the full parser
 697          if ( $this->format === 'parse' ) {
 698              $string = $this->parseText( $string );
 699              $string = Parser::stripOuterParagraph( $string );
 700          } elseif ( $this->format === 'block-parse' ) {
 701              $string = $this->parseText( $string );
 702          } elseif ( $this->format === 'text' ) {
 703              $string = $this->transformText( $string );
 704          } elseif ( $this->format === 'escaped' ) {
 705              $string = $this->transformText( $string );
 706              $string = htmlspecialchars( $string, ENT_QUOTES, 'UTF-8', false );
 707          }
 708  
 709          # Raw parameter replacement
 710          $string = $this->replaceParameters( $string, 'after' );
 711  
 712          return $string;
 713      }
 714  
 715      /**
 716       * Magic method implementation of the above (for PHP >= 5.2.0), so we can do, eg:
 717       *     $foo = Message::get( $key );
 718       *     $string = "<abbr>$foo</abbr>";
 719       *
 720       * @since 1.18
 721       *
 722       * @return string
 723       */
 724  	public function __toString() {
 725          // PHP doesn't allow __toString to throw exceptions and will
 726          // trigger a fatal error if it does. So, catch any exceptions.
 727  
 728          try {
 729              return $this->toString();
 730          } catch ( Exception $ex ) {
 731              try {
 732                  trigger_error( "Exception caught in " . __METHOD__ . " (message " . $this->key . "): "
 733                      . $ex, E_USER_WARNING );
 734              } catch ( Exception $ex ) {
 735                  // Doh! Cause a fatal error after all?
 736              }
 737  
 738              if ( $this->format === 'plain' ) {
 739                  return '<' . $this->key . '>';
 740              }
 741              return '&lt;' . $this->key . '&gt;';
 742          }
 743      }
 744  
 745      /**
 746       * Fully parse the text from wikitext to HTML.
 747       *
 748       * @since 1.17
 749       *
 750       * @return string Parsed HTML.
 751       */
 752  	public function parse() {
 753          $this->format = 'parse';
 754          return $this->toString();
 755      }
 756  
 757      /**
 758       * Returns the message text. {{-transformation is done.
 759       *
 760       * @since 1.17
 761       *
 762       * @return string Unescaped message text.
 763       */
 764  	public function text() {
 765          $this->format = 'text';
 766          return $this->toString();
 767      }
 768  
 769      /**
 770       * Returns the message text as-is, only parameters are substituted.
 771       *
 772       * @since 1.17
 773       *
 774       * @return string Unescaped untransformed message text.
 775       */
 776  	public function plain() {
 777          $this->format = 'plain';
 778          return $this->toString();
 779      }
 780  
 781      /**
 782       * Returns the parsed message text which is always surrounded by a block element.
 783       *
 784       * @since 1.17
 785       *
 786       * @return string HTML
 787       */
 788  	public function parseAsBlock() {
 789          $this->format = 'block-parse';
 790          return $this->toString();
 791      }
 792  
 793      /**
 794       * Returns the message text. {{-transformation is done and the result
 795       * is escaped excluding any raw parameters.
 796       *
 797       * @since 1.17
 798       *
 799       * @return string Escaped message text.
 800       */
 801  	public function escaped() {
 802          $this->format = 'escaped';
 803          return $this->toString();
 804      }
 805  
 806      /**
 807       * Check whether a message key has been defined currently.
 808       *
 809       * @since 1.17
 810       *
 811       * @return bool
 812       */
 813  	public function exists() {
 814          return $this->fetchMessage() !== false;
 815      }
 816  
 817      /**
 818       * Check whether a message does not exist, or is an empty string
 819       *
 820       * @since 1.18
 821       * @todo FIXME: Merge with isDisabled()?
 822       *
 823       * @return bool
 824       */
 825  	public function isBlank() {
 826          $message = $this->fetchMessage();
 827          return $message === false || $message === '';
 828      }
 829  
 830      /**
 831       * Check whether a message does not exist, is an empty string, or is "-".
 832       *
 833       * @since 1.18
 834       *
 835       * @return bool
 836       */
 837  	public function isDisabled() {
 838          $message = $this->fetchMessage();
 839          return $message === false || $message === '' || $message === '-';
 840      }
 841  
 842      /**
 843       * @since 1.17
 844       *
 845       * @param mixed $raw
 846       *
 847       * @return array Array with a single "raw" key.
 848       */
 849  	public static function rawParam( $raw ) {
 850          return array( 'raw' => $raw );
 851      }
 852  
 853      /**
 854       * @since 1.18
 855       *
 856       * @param mixed $num
 857       *
 858       * @return array Array with a single "num" key.
 859       */
 860  	public static function numParam( $num ) {
 861          return array( 'num' => $num );
 862      }
 863  
 864      /**
 865       * @since 1.22
 866       *
 867       * @param int $duration
 868       *
 869       * @return int[] Array with a single "duration" key.
 870       */
 871  	public static function durationParam( $duration ) {
 872          return array( 'duration' => $duration );
 873      }
 874  
 875      /**
 876       * @since 1.22
 877       *
 878       * @param string $expiry
 879       *
 880       * @return string[] Array with a single "expiry" key.
 881       */
 882  	public static function expiryParam( $expiry ) {
 883          return array( 'expiry' => $expiry );
 884      }
 885  
 886      /**
 887       * @since 1.22
 888       *
 889       * @param number $period
 890       *
 891       * @return number[] Array with a single "period" key.
 892       */
 893  	public static function timeperiodParam( $period ) {
 894          return array( 'period' => $period );
 895      }
 896  
 897      /**
 898       * @since 1.22
 899       *
 900       * @param int $size
 901       *
 902       * @return int[] Array with a single "size" key.
 903       */
 904  	public static function sizeParam( $size ) {
 905          return array( 'size' => $size );
 906      }
 907  
 908      /**
 909       * @since 1.22
 910       *
 911       * @param int $bitrate
 912       *
 913       * @return int[] Array with a single "bitrate" key.
 914       */
 915  	public static function bitrateParam( $bitrate ) {
 916          return array( 'bitrate' => $bitrate );
 917      }
 918  
 919      /**
 920       * Substitutes any parameters into the message text.
 921       *
 922       * @since 1.17
 923       *
 924       * @param string $message The message text.
 925       * @param string $type Either "before" or "after".
 926       *
 927       * @return string
 928       */
 929  	protected function replaceParameters( $message, $type = 'before' ) {
 930          $replacementKeys = array();
 931          foreach ( $this->parameters as $n => $param ) {
 932              list( $paramType, $value ) = $this->extractParam( $param );
 933              if ( $type === $paramType ) {
 934                  $replacementKeys['$' . ( $n + 1 )] = $value;
 935              }
 936          }
 937          $message = strtr( $message, $replacementKeys );
 938          return $message;
 939      }
 940  
 941      /**
 942       * Extracts the parameter type and preprocessed the value if needed.
 943       *
 944       * @since 1.18
 945       *
 946       * @param mixed $param Parameter as defined in this class.
 947       *
 948       * @return array Array with the parameter type (either "before" or "after") and the value.
 949       */
 950  	protected function extractParam( $param ) {
 951          if ( is_array( $param ) ) {
 952              if ( isset( $param['raw'] ) ) {
 953                  return array( 'after', $param['raw'] );
 954              } elseif ( isset( $param['num'] ) ) {
 955                  // Replace number params always in before step for now.
 956                  // No support for combined raw and num params
 957                  return array( 'before', $this->language->formatNum( $param['num'] ) );
 958              } elseif ( isset( $param['duration'] ) ) {
 959                  return array( 'before', $this->language->formatDuration( $param['duration'] ) );
 960              } elseif ( isset( $param['expiry'] ) ) {
 961                  return array( 'before', $this->language->formatExpiry( $param['expiry'] ) );
 962              } elseif ( isset( $param['period'] ) ) {
 963                  return array( 'before', $this->language->formatTimePeriod( $param['period'] ) );
 964              } elseif ( isset( $param['size'] ) ) {
 965                  return array( 'before', $this->language->formatSize( $param['size'] ) );
 966              } elseif ( isset( $param['bitrate'] ) ) {
 967                  return array( 'before', $this->language->formatBitrate( $param['bitrate'] ) );
 968              } else {
 969                  $warning = 'Invalid parameter for message "' . $this->getKey() . '": ' .
 970                      htmlspecialchars( serialize( $param ) );
 971                  trigger_error( $warning, E_USER_WARNING );
 972                  $e = new Exception;
 973                  wfDebugLog( 'Bug58676', $warning . "\n" . $e->getTraceAsString() );
 974  
 975                  return array( 'before', '[INVALID]' );
 976              }
 977          } elseif ( $param instanceof Message ) {
 978              // Message objects should not be before parameters because
 979              // then they'll get double escaped. If the message needs to be
 980              // escaped, it'll happen right here when we call toString().
 981              return array( 'after', $param->toString() );
 982          } else {
 983              return array( 'before', $param );
 984          }
 985      }
 986  
 987      /**
 988       * Wrapper for what ever method we use to parse wikitext.
 989       *
 990       * @since 1.17
 991       *
 992       * @param string $string Wikitext message contents.
 993       *
 994       * @return string Wikitext parsed into HTML.
 995       */
 996  	protected function parseText( $string ) {
 997          $out = MessageCache::singleton()->parse(
 998              $string,
 999              $this->title,
1000              /*linestart*/true,
1001              $this->interface,
1002              $this->language
1003          );
1004  
1005          return $out instanceof ParserOutput ? $out->getText() : $out;
1006      }
1007  
1008      /**
1009       * Wrapper for what ever method we use to {{-transform wikitext.
1010       *
1011       * @since 1.17
1012       *
1013       * @param string $string Wikitext message contents.
1014       *
1015       * @return string Wikitext with {{-constructs replaced with their values.
1016       */
1017  	protected function transformText( $string ) {
1018          return MessageCache::singleton()->transform(
1019              $string,
1020              $this->interface,
1021              $this->language,
1022              $this->title
1023          );
1024      }
1025  
1026      /**
1027       * Wrapper for what ever method we use to get message contents.
1028       *
1029       * @since 1.17
1030       *
1031       * @return string
1032       * @throws MWException If message key array is empty.
1033       */
1034  	protected function fetchMessage() {
1035          if ( $this->message === null ) {
1036              $cache = MessageCache::singleton();
1037  
1038              foreach ( $this->keysToTry as $key ) {
1039                  $message = $cache->get( $key, $this->useDatabase, $this->language );
1040                  if ( $message !== false && $message !== '' ) {
1041                      break;
1042                  }
1043              }
1044  
1045              // NOTE: The constructor makes sure keysToTry isn't empty,
1046              //       so we know that $key and $message are initialized.
1047              $this->key = $key;
1048              $this->message = $message;
1049          }
1050          return $this->message;
1051      }
1052  
1053  }
1054  
1055  /**
1056   * Variant of the Message class.
1057   *
1058   * Rather than treating the message key as a lookup
1059   * value (which is passed to the MessageCache and
1060   * translated as necessary), a RawMessage key is
1061   * treated as the actual message.
1062   *
1063   * All other functionality (parsing, escaping, etc.)
1064   * is preserved.
1065   *
1066   * @since 1.21
1067   */
1068  class RawMessage extends Message {
1069  
1070      /**
1071       * Call the parent constructor, then store the key as
1072       * the message.
1073       *
1074       * @see Message::__construct
1075       *
1076       * @param string $text Message to use.
1077       * @param array $params Parameters for the message.
1078       *
1079       * @throws InvalidArgumentException
1080       */
1081  	public function __construct( $text, $params = array() ) {
1082          if ( !is_string( $text ) ) {
1083              throw new InvalidArgumentException( '$text must be a string' );
1084          }
1085  
1086          parent::__construct( $text, $params );
1087  
1088          // The key is the message.
1089          $this->message = $text;
1090      }
1091  
1092      /**
1093       * Fetch the message (in this case, the key).
1094       *
1095       * @return string
1096       */
1097  	public function fetchMessage() {
1098          // Just in case the message is unset somewhere.
1099          if ( $this->message === null ) {
1100              $this->message = $this->key;
1101          }
1102  
1103          return $this->message;
1104      }
1105  
1106  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1