MediaWiki  REL1_21
Message.php
Go to the documentation of this file.
00001 <?php
00159 class Message {
00164         protected $interface = true;
00165 
00172         protected $language = null;
00173 
00177         protected $key;
00178 
00182         protected $parameters = array();
00183 
00193         protected $format = 'parse';
00194 
00198         protected $useDatabase = true;
00199 
00203         protected $title = null;
00204 
00208         protected $content = null;
00209 
00213         protected $message;
00214 
00222         public function __construct( $key, $params = array() ) {
00223                 global $wgLang;
00224                 $this->key = $key;
00225                 $this->parameters = array_values( $params );
00226                 $this->language = $wgLang;
00227         }
00228 
00236         public function getKey() {
00237                 return $this->key;
00238         }
00239 
00247         public function getParams() {
00248                 return $this->parameters;
00249         }
00250 
00258         public function getFormat() {
00259                 return $this->format;
00260         }
00261 
00271         public static function newFromKey( $key /*...*/ ) {
00272                 $params = func_get_args();
00273                 array_shift( $params );
00274                 return new self( $key, $params );
00275         }
00276 
00285         public static function newFallbackSequence( /*...*/ ) {
00286                 $keys = func_get_args();
00287                 if ( func_num_args() == 1 ) {
00288                         if ( is_array( $keys[0] ) ) {
00289                                 // Allow an array to be passed as the first argument instead
00290                                 $keys = array_values( $keys[0] );
00291                         } else {
00292                                 // Optimize a single string to not need special fallback handling
00293                                 $keys = $keys[0];
00294                         }
00295                 }
00296                 return new self( $keys );
00297         }
00298 
00305         public function params( /*...*/ ) {
00306                 $args = func_get_args();
00307                 if ( isset( $args[0] ) && is_array( $args[0] ) ) {
00308                         $args = $args[0];
00309                 }
00310                 $args_values = array_values( $args );
00311                 $this->parameters = array_merge( $this->parameters, $args_values );
00312                 return $this;
00313         }
00314 
00324         public function rawParams( /*...*/ ) {
00325                 $params = func_get_args();
00326                 if ( isset( $params[0] ) && is_array( $params[0] ) ) {
00327                         $params = $params[0];
00328                 }
00329                 foreach( $params as $param ) {
00330                         $this->parameters[] = self::rawParam( $param );
00331                 }
00332                 return $this;
00333         }
00334 
00342         public function numParams( /*...*/ ) {
00343                 $params = func_get_args();
00344                 if ( isset( $params[0] ) && is_array( $params[0] ) ) {
00345                         $params = $params[0];
00346                 }
00347                 foreach( $params as $param ) {
00348                         $this->parameters[] = self::numParam( $param );
00349                 }
00350                 return $this;
00351         }
00352 
00359         public function setContext( IContextSource $context ) {
00360                 $this->inLanguage( $context->getLanguage() );
00361                 $this->title( $context->getTitle() );
00362                 $this->interface = true;
00363 
00364                 return $this;
00365         }
00366 
00376         public function inLanguage( $lang ) {
00377                 if ( $lang instanceof Language || $lang instanceof StubUserLang ) {
00378                         $this->language = $lang;
00379                 } elseif ( is_string( $lang ) ) {
00380                         if( $this->language->getCode() != $lang ) {
00381                                 $this->language = Language::factory( $lang );
00382                         }
00383                 } else {
00384                         $type = gettype( $lang );
00385                         throw new MWException( __METHOD__ . " must be "
00386                                 . "passed a String or Language object; $type given"
00387                         );
00388                 }
00389                 $this->interface = false;
00390                 return $this;
00391         }
00392 
00400         public function inContentLanguage() {
00401                 global $wgForceUIMsgAsContentMsg;
00402                 if ( in_array( $this->key, (array)$wgForceUIMsgAsContentMsg ) ) {
00403                         return $this;
00404                 }
00405 
00406                 global $wgContLang;
00407                 $this->interface = false;
00408                 $this->language = $wgContLang;
00409                 return $this;
00410         }
00411 
00419         public function setInterfaceMessageFlag( $value ) {
00420                 $this->interface = (bool) $value;
00421                 return $this;
00422         }
00423 
00430         public function useDatabase( $value ) {
00431                 $this->useDatabase = (bool) $value;
00432                 return $this;
00433         }
00434 
00441         public function title( $title ) {
00442                 $this->title = $title;
00443                 return $this;
00444         }
00445 
00450         public function content() {
00451                 if ( !$this->content ) {
00452                         $this->content = new MessageContent( $this );
00453                 }
00454 
00455                 return $this->content;
00456         }
00457 
00463         public function toString() {
00464                 $string = $this->fetchMessage();
00465 
00466                 if ( $string === false ) {
00467                         $key = htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
00468                         if ( $this->format === 'plain' ) {
00469                                 return '<' . $key . '>';
00470                         }
00471                         return '&lt;' . $key . '&gt;';
00472                 }
00473 
00474                 # Replace $* with a list of parameters for &uselang=qqx.
00475                 if ( strpos( $string, '$*' ) !== false ) {
00476                         $paramlist = '';
00477                         if ( $this->parameters !== array() ) {
00478                                 $paramlist = ': $' . implode( ', $', range( 1, count( $this->parameters ) ) );
00479                         }
00480                         $string = str_replace( '$*', $paramlist, $string );
00481                 }
00482 
00483                 # Replace parameters before text parsing
00484                 $string = $this->replaceParameters( $string, 'before' );
00485 
00486                 # Maybe transform using the full parser
00487                 if( $this->format === 'parse' ) {
00488                         $string = $this->parseText( $string );
00489                         $m = array();
00490                         if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
00491                                 $string = $m[1];
00492                         }
00493                 } elseif( $this->format === 'block-parse' ) {
00494                         $string = $this->parseText( $string );
00495                 } elseif( $this->format === 'text' ) {
00496                         $string = $this->transformText( $string );
00497                 } elseif( $this->format === 'escaped' ) {
00498                         $string = $this->transformText( $string );
00499                         $string = htmlspecialchars( $string, ENT_QUOTES, 'UTF-8', false );
00500                 }
00501 
00502                 # Raw parameter replacement
00503                 $string = $this->replaceParameters( $string, 'after' );
00504 
00505                 return $string;
00506         }
00507 
00515         public function __toString() {
00516                 // PHP doesn't allow __toString to throw exceptions and will
00517                 // trigger a fatal error if it does. So, catch any exceptions.
00518 
00519                 try {
00520                         return $this->toString();
00521                 } catch ( Exception $ex ) {
00522                         try {
00523                                 trigger_error( "Exception caught in " . __METHOD__ . " (message " . $this->key . "): "
00524                                         . $ex, E_USER_WARNING );
00525                         } catch ( Exception $ex ) {
00526                                 // Doh! Cause a fatal error after all?
00527                         }
00528 
00529                         if ( $this->format === 'plain' ) {
00530                                 return '<' . $this->key . '>';
00531                         }
00532                         return '&lt;' . $this->key . '&gt;';
00533                 }
00534         }
00535 
00541         public function parse() {
00542                 $this->format = 'parse';
00543                 return $this->toString();
00544         }
00545 
00551         public function text() {
00552                 $this->format = 'text';
00553                 return $this->toString();
00554         }
00555 
00561         public function plain() {
00562                 $this->format = 'plain';
00563                 return $this->toString();
00564         }
00565 
00571         public function parseAsBlock() {
00572                 $this->format = 'block-parse';
00573                 return $this->toString();
00574         }
00575 
00582         public function escaped() {
00583                 $this->format = 'escaped';
00584                 return $this->toString();
00585         }
00586 
00592         public function exists() {
00593                 return $this->fetchMessage() !== false;
00594         }
00595 
00602         public function isBlank() {
00603                 $message = $this->fetchMessage();
00604                 return $message === false || $message === '';
00605         }
00606 
00612         public function isDisabled() {
00613                 $message = $this->fetchMessage();
00614                 return $message === false || $message === '' || $message === '-';
00615         }
00616 
00622         public static function rawParam( $value ) {
00623                 return array( 'raw' => $value );
00624         }
00625 
00631         public static function numParam( $value ) {
00632                 return array( 'num' => $value );
00633         }
00634 
00642         protected function replaceParameters( $message, $type = 'before' ) {
00643                 $replacementKeys = array();
00644                 foreach( $this->parameters as $n => $param ) {
00645                         list( $paramType, $value ) = $this->extractParam( $param );
00646                         if ( $type === $paramType ) {
00647                                 $replacementKeys['$' . ($n + 1)] = $value;
00648                         }
00649                 }
00650                 $message = strtr( $message, $replacementKeys );
00651                 return $message;
00652         }
00653 
00660         protected function extractParam( $param ) {
00661                 if ( is_array( $param ) && isset( $param['raw'] ) ) {
00662                         return array( 'after', $param['raw'] );
00663                 } elseif ( is_array( $param ) && isset( $param['num'] ) ) {
00664                         // Replace number params always in before step for now.
00665                         // No support for combined raw and num params
00666                         return array( 'before', $this->language->formatNum( $param['num'] ) );
00667                 } elseif ( !is_array( $param ) ) {
00668                         return array( 'before', $param );
00669                 } else {
00670                         trigger_error(
00671                                 "Invalid message parameter: " . htmlspecialchars( serialize( $param ) ),
00672                                 E_USER_WARNING
00673                         );
00674                         return array( 'before', '[INVALID]' );
00675                 }
00676         }
00677 
00684         protected function parseText( $string ) {
00685                 $out = MessageCache::singleton()->parse( $string, $this->title, /*linestart*/true, $this->interface, $this->language );
00686                 return is_object( $out ) ? $out->getText() : $out;
00687         }
00688 
00695         protected function transformText( $string ) {
00696                 return MessageCache::singleton()->transform( $string, $this->interface, $this->language, $this->title );
00697         }
00698 
00705         protected function fetchMessage() {
00706                 if ( !isset( $this->message ) ) {
00707                         $cache = MessageCache::singleton();
00708                         if ( is_array( $this->key ) ) {
00709                                 if ( !count( $this->key ) ) {
00710                                         throw new MWException( "Given empty message key array." );
00711                                 }
00712                                 foreach ( $this->key as $key ) {
00713                                         $message = $cache->get( $key, $this->useDatabase, $this->language );
00714                                         if ( $message !== false && $message !== '' ) {
00715                                                 break;
00716                                         }
00717                                 }
00718                                 $this->message = $message;
00719                         } else {
00720                                 $this->message = $cache->get( $this->key, $this->useDatabase, $this->language );
00721                         }
00722                 }
00723                 return $this->message;
00724         }
00725 
00726 }
00727 
00741 class RawMessage extends Message {
00750         public function __construct( $key, $params = array() ) {
00751                 parent::__construct( $key, $params );
00752                 // The key is the message.
00753                 $this->message = $key;
00754         }
00755 
00761         public function fetchMessage() {
00762                 // Just in case the message is unset somewhere.
00763                 if( !isset( $this->message ) ) {
00764                         $this->message = $this->key;
00765                 }
00766                 return $this->message;
00767         }
00768 }