MediaWiki  master
Message.php
Go to the documentation of this file.
1 <?php
26 
164  const FORMAT_PLAIN = 'plain';
166  const FORMAT_BLOCK_PARSE = 'block-parse';
168  const FORMAT_PARSE = 'parse';
170  const FORMAT_TEXT = 'text';
172  const FORMAT_ESCAPED = 'escaped';
173 
178  protected static $listTypeMap = [
179  'comma' => 'commaList',
180  'semicolon' => 'semicolonList',
181  'pipe' => 'pipeList',
182  'text' => 'listToText',
183  ];
184 
191  protected $interface = true;
192 
198  protected $language = false;
199 
204  protected $key;
205 
209  protected $keysToTry;
210 
214  protected $parameters = [];
215 
220  protected $format = 'parse';
221 
225  protected $useDatabase = true;
226 
230  protected $title = null;
231 
235  protected $content = null;
236 
240  protected $message;
241 
251  public function __construct( $key, $params = [], Language $language = null ) {
252  if ( $key instanceof MessageSpecifier ) {
253  if ( $params ) {
254  throw new InvalidArgumentException(
255  '$params must be empty if $key is a MessageSpecifier'
256  );
257  }
258  $params = $key->getParams();
259  $key = $key->getKey();
260  }
261 
262  if ( !is_string( $key ) && !is_array( $key ) ) {
263  throw new InvalidArgumentException( '$key must be a string or an array' );
264  }
265 
266  $this->keysToTry = (array)$key;
267 
268  if ( empty( $this->keysToTry ) ) {
269  throw new InvalidArgumentException( '$key must not be an empty list' );
270  }
271 
272  $this->key = reset( $this->keysToTry );
273 
274  $this->parameters = array_values( $params );
275  // User language is only resolved in getLanguage(). This helps preserve the
276  // semantic intent of "user language" across serialize() and unserialize().
277  $this->language = $language ?: false;
278  }
279 
285  public function serialize() {
286  return serialize( [
287  'interface' => $this->interface,
288  'language' => $this->language ? $this->language->getCode() : false,
289  'key' => $this->key,
290  'keysToTry' => $this->keysToTry,
291  'parameters' => $this->parameters,
292  'format' => $this->format,
293  'useDatabase' => $this->useDatabase,
294  'titlestr' => $this->title ? $this->title->getFullText() : null,
295  ] );
296  }
297 
303  public function unserialize( $serialized ) {
304  $data = unserialize( $serialized );
305  if ( !is_array( $data ) ) {
306  throw new InvalidArgumentException( __METHOD__ . ': Invalid serialized data' );
307  }
308 
309  $this->interface = $data['interface'];
310  $this->key = $data['key'];
311  $this->keysToTry = $data['keysToTry'];
312  $this->parameters = $data['parameters'];
313  $this->format = $data['format'];
314  $this->useDatabase = $data['useDatabase'];
315  $this->language = $data['language'] ? Language::factory( $data['language'] ) : false;
316 
317  if ( isset( $data['titlestr'] ) ) {
318  $this->title = Title::newFromText( $data['titlestr'] );
319  } elseif ( isset( $data['title'] ) && $data['title'] instanceof Title ) {
320  // Old serializations from before December 2018
321  $this->title = $data['title'];
322  } else {
323  $this->title = null; // Explicit for sanity
324  }
325  }
326 
333  public function isMultiKey() {
334  return count( $this->keysToTry ) > 1;
335  }
336 
343  public function getKeysToTry() {
344  return $this->keysToTry;
345  }
346 
358  public function getKey() {
359  return $this->key;
360  }
361 
369  public function getParams() {
370  return $this->parameters;
371  }
372 
381  public function getFormat() {
382  wfDeprecated( __METHOD__, '1.29' );
383  return $this->format;
384  }
385 
393  public function getLanguage() {
394  // Defaults to false which means current user language
395  return $this->language ?: RequestContext::getMain()->getLanguage();
396  }
397 
410  public static function newFromKey( $key /*...*/ ) {
411  $params = func_get_args();
412  array_shift( $params );
413  return new self( $key, $params );
414  }
415 
429  public static function newFromSpecifier( $value ) {
430  $params = [];
431  if ( is_array( $value ) ) {
432  $params = $value;
433  $value = array_shift( $params );
434  }
435 
436  if ( $value instanceof Message ) { // Message, RawMessage, ApiMessage, etc
437  $message = clone $value;
438  } elseif ( $value instanceof MessageSpecifier ) {
439  $message = new Message( $value );
440  } elseif ( is_string( $value ) ) {
441  $message = new Message( $value, $params );
442  } else {
443  throw new InvalidArgumentException( __METHOD__ . ': invalid argument type '
444  . gettype( $value ) );
445  }
446 
447  return $message;
448  }
449 
462  public static function newFallbackSequence( /*...*/ ) {
463  $keys = func_get_args();
464  if ( func_num_args() == 1 ) {
465  if ( is_array( $keys[0] ) ) {
466  // Allow an array to be passed as the first argument instead
467  $keys = array_values( $keys[0] );
468  } else {
469  // Optimize a single string to not need special fallback handling
470  $keys = $keys[0];
471  }
472  }
473  return new self( $keys );
474  }
475 
486  public function getTitle() {
488 
489  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
490  $lang = $this->getLanguage();
491  $title = $this->key;
492  if (
493  !$lang->equals( $contLang )
494  && in_array( $this->key, (array)$wgForceUIMsgAsContentMsg )
495  ) {
496  $title .= '/' . $lang->getCode();
497  }
498 
499  return Title::makeTitle(
500  NS_MEDIAWIKI, $contLang->ucfirst( strtr( $title, ' ', '_' ) ) );
501  }
502 
513  public function params( /*...*/ ) {
514  $args = func_get_args();
515 
516  // If $args has only one entry and it's an array, then it's either a
517  // non-varargs call or it happens to be a call with just a single
518  // "special" parameter. Since the "special" parameters don't have any
519  // numeric keys, we'll test that to differentiate the cases.
520  if ( count( $args ) === 1 && isset( $args[0] ) && is_array( $args[0] ) ) {
521  if ( $args[0] === [] ) {
522  $args = [];
523  } else {
524  foreach ( $args[0] as $key => $value ) {
525  if ( is_int( $key ) ) {
526  $args = $args[0];
527  break;
528  }
529  }
530  }
531  }
532 
533  $this->parameters = array_merge( $this->parameters, array_values( $args ) );
534  return $this;
535  }
536 
550  public function rawParams( /*...*/ ) {
551  $params = func_get_args();
552  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
553  $params = $params[0];
554  }
555  foreach ( $params as $param ) {
556  $this->parameters[] = self::rawParam( $param );
557  }
558  return $this;
559  }
560 
572  public function numParams( /*...*/ ) {
573  $params = func_get_args();
574  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
575  $params = $params[0];
576  }
577  foreach ( $params as $param ) {
578  $this->parameters[] = self::numParam( $param );
579  }
580  return $this;
581  }
582 
594  public function durationParams( /*...*/ ) {
595  $params = func_get_args();
596  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
597  $params = $params[0];
598  }
599  foreach ( $params as $param ) {
600  $this->parameters[] = self::durationParam( $param );
601  }
602  return $this;
603  }
604 
616  public function expiryParams( /*...*/ ) {
617  $params = func_get_args();
618  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
619  $params = $params[0];
620  }
621  foreach ( $params as $param ) {
622  $this->parameters[] = self::expiryParam( $param );
623  }
624  return $this;
625  }
626 
638  public function timeperiodParams( /*...*/ ) {
639  $params = func_get_args();
640  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
641  $params = $params[0];
642  }
643  foreach ( $params as $param ) {
644  $this->parameters[] = self::timeperiodParam( $param );
645  }
646  return $this;
647  }
648 
660  public function sizeParams( /*...*/ ) {
661  $params = func_get_args();
662  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
663  $params = $params[0];
664  }
665  foreach ( $params as $param ) {
666  $this->parameters[] = self::sizeParam( $param );
667  }
668  return $this;
669  }
670 
682  public function bitrateParams( /*...*/ ) {
683  $params = func_get_args();
684  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
685  $params = $params[0];
686  }
687  foreach ( $params as $param ) {
688  $this->parameters[] = self::bitrateParam( $param );
689  }
690  return $this;
691  }
692 
706  public function plaintextParams( /*...*/ ) {
707  $params = func_get_args();
708  if ( isset( $params[0] ) && is_array( $params[0] ) ) {
709  $params = $params[0];
710  }
711  foreach ( $params as $param ) {
712  $this->parameters[] = self::plaintextParam( $param );
713  }
714  return $this;
715  }
716 
726  public function setContext( IContextSource $context ) {
727  $this->inLanguage( $context->getLanguage() );
728  $this->title( $context->getTitle() );
729  $this->interface = true;
730 
731  return $this;
732  }
733 
745  public function inLanguage( $lang ) {
746  $previousLanguage = $this->language;
747 
748  if ( $lang instanceof Language ) {
749  $this->language = $lang;
750  } elseif ( is_string( $lang ) ) {
751  if ( !$this->language instanceof Language || $this->language->getCode() != $lang ) {
752  $this->language = Language::factory( $lang );
753  }
754  } elseif ( $lang instanceof StubUserLang ) {
755  $this->language = false;
756  } else {
757  $type = gettype( $lang );
758  throw new MWException( __METHOD__ . " must be "
759  . "passed a String or Language object; $type given"
760  );
761  }
762 
763  if ( $this->language !== $previousLanguage ) {
764  // The language has changed. Clear the message cache.
765  $this->message = null;
766  }
767  $this->interface = false;
768  return $this;
769  }
770 
780  public function inContentLanguage() {
782  if ( in_array( $this->key, (array)$wgForceUIMsgAsContentMsg ) ) {
783  return $this;
784  }
785 
786  $this->inLanguage( MediaWikiServices::getInstance()->getContentLanguage() );
787  return $this;
788  }
789 
800  public function setInterfaceMessageFlag( $interface ) {
801  $this->interface = (bool)$interface;
802  return $this;
803  }
804 
814  public function useDatabase( $useDatabase ) {
815  $this->useDatabase = (bool)$useDatabase;
816  $this->message = null;
817  return $this;
818  }
819 
829  public function title( $title ) {
830  $this->title = $title;
831  return $this;
832  }
833 
839  public function content() {
840  if ( !$this->content ) {
841  $this->content = new MessageContent( $this );
842  }
843 
844  return $this->content;
845  }
846 
858  public function toString( $format = null ) {
859  if ( $format === null ) {
860  $ex = new LogicException( __METHOD__ . ' using implicit format: ' . $this->format );
861  LoggerFactory::getInstance( 'message-format' )->warning(
862  $ex->getMessage(), [ 'exception' => $ex, 'format' => $this->format, 'key' => $this->key ] );
864  }
865  $string = $this->fetchMessage();
866 
867  if ( $string === false ) {
868  // Err on the side of safety, ensure that the output
869  // is always html safe in the event the message key is
870  // missing, since in that case its highly likely the
871  // message key is user-controlled.
872  // '⧼' is used instead of '<' to side-step any
873  // double-escaping issues.
874  // (Keep synchronised with mw.Message#toString in JS.)
875  return '⧼' . htmlspecialchars( $this->key ) . '⧽';
876  }
877 
878  # Replace $* with a list of parameters for &uselang=qqx.
879  if ( strpos( $string, '$*' ) !== false ) {
880  $paramlist = '';
881  if ( $this->parameters !== [] ) {
882  $paramlist = ': $' . implode( ', $', range( 1, count( $this->parameters ) ) );
883  }
884  $string = str_replace( '$*', $paramlist, $string );
885  }
886 
887  # Replace parameters before text parsing
888  $string = $this->replaceParameters( $string, 'before', $format );
889 
890  # Maybe transform using the full parser
891  if ( $format === self::FORMAT_PARSE ) {
892  $string = $this->parseText( $string );
893  $string = Parser::stripOuterParagraph( $string );
894  } elseif ( $format === self::FORMAT_BLOCK_PARSE ) {
895  $string = $this->parseText( $string );
896  } elseif ( $format === self::FORMAT_TEXT ) {
897  $string = $this->transformText( $string );
898  } elseif ( $format === self::FORMAT_ESCAPED ) {
899  $string = $this->transformText( $string );
900  $string = htmlspecialchars( $string, ENT_QUOTES, 'UTF-8', false );
901  }
902 
903  # Raw parameter replacement
904  $string = $this->replaceParameters( $string, 'after', $format );
905 
906  return $string;
907  }
908 
918  public function __toString() {
919  // PHP doesn't allow __toString to throw exceptions and will
920  // trigger a fatal error if it does. So, catch any exceptions.
921 
922  try {
923  return $this->toString( self::FORMAT_PARSE );
924  } catch ( Exception $ex ) {
925  try {
926  trigger_error( "Exception caught in " . __METHOD__ . " (message " . $this->key . "): "
927  . $ex, E_USER_WARNING );
928  } catch ( Exception $ex ) {
929  // Doh! Cause a fatal error after all?
930  }
931 
932  return '⧼' . htmlspecialchars( $this->key ) . '⧽';
933  }
934  }
935 
943  public function parse() {
944  $this->format = self::FORMAT_PARSE;
945  return $this->toString( self::FORMAT_PARSE );
946  }
947 
955  public function text() {
956  $this->format = self::FORMAT_TEXT;
957  return $this->toString( self::FORMAT_TEXT );
958  }
959 
967  public function plain() {
968  $this->format = self::FORMAT_PLAIN;
969  return $this->toString( self::FORMAT_PLAIN );
970  }
971 
979  public function parseAsBlock() {
980  $this->format = self::FORMAT_BLOCK_PARSE;
981  return $this->toString( self::FORMAT_BLOCK_PARSE );
982  }
983 
992  public function escaped() {
993  $this->format = self::FORMAT_ESCAPED;
994  return $this->toString( self::FORMAT_ESCAPED );
995  }
996 
1004  public function exists() {
1005  return $this->fetchMessage() !== false;
1006  }
1007 
1016  public function isBlank() {
1017  $message = $this->fetchMessage();
1018  return $message === false || $message === '';
1019  }
1020 
1028  public function isDisabled() {
1029  $message = $this->fetchMessage();
1030  return $message === false || $message === '' || $message === '-';
1031  }
1032 
1040  public static function rawParam( $raw ) {
1041  return [ 'raw' => $raw ];
1042  }
1043 
1051  public static function numParam( $num ) {
1052  return [ 'num' => $num ];
1053  }
1054 
1062  public static function durationParam( $duration ) {
1063  return [ 'duration' => $duration ];
1064  }
1065 
1073  public static function expiryParam( $expiry ) {
1074  return [ 'expiry' => $expiry ];
1075  }
1076 
1084  public static function timeperiodParam( $period ) {
1085  return [ 'period' => $period ];
1086  }
1087 
1095  public static function sizeParam( $size ) {
1096  return [ 'size' => $size ];
1097  }
1098 
1106  public static function bitrateParam( $bitrate ) {
1107  return [ 'bitrate' => $bitrate ];
1108  }
1109 
1117  public static function plaintextParam( $plaintext ) {
1118  return [ 'plaintext' => $plaintext ];
1119  }
1120 
1128  public static function listParam( array $list, $type = 'text' ) {
1129  if ( !isset( self::$listTypeMap[$type] ) ) {
1130  throw new InvalidArgumentException(
1131  "Invalid type '$type'. Known types are: " . implode( ', ', array_keys( self::$listTypeMap ) )
1132  );
1133  }
1134  return [ 'list' => $list, 'type' => $type ];
1135  }
1136 
1148  protected function replaceParameters( $message, $type, $format ) {
1149  // A temporary marker for $1 parameters that is only valid
1150  // in non-attribute contexts. However if the entire message is escaped
1151  // then we don't want to use it because it will be mangled in all contexts
1152  // and its unnessary as ->escaped() messages aren't html.
1153  $marker = $format === self::FORMAT_ESCAPED ? '$' : '$\'"';
1154  $replacementKeys = [];
1155  foreach ( $this->parameters as $n => $param ) {
1156  list( $paramType, $value ) = $this->extractParam( $param, $format );
1157  if ( $type === 'before' ) {
1158  if ( $paramType === 'before' ) {
1159  $replacementKeys['$' . ( $n + 1 )] = $value;
1160  } else /* $paramType === 'after' */ {
1161  // To protect against XSS from replacing parameters
1162  // inside html attributes, we convert $1 to $'"1.
1163  // In the event that one of the parameters ends up
1164  // in an attribute, either the ' or the " will be
1165  // escaped, breaking the replacement and avoiding XSS.
1166  $replacementKeys['$' . ( $n + 1 )] = $marker . ( $n + 1 );
1167  }
1168  } elseif ( $paramType === 'after' ) {
1169  $replacementKeys[$marker . ( $n + 1 )] = $value;
1170  }
1171  }
1172  return strtr( $message, $replacementKeys );
1173  }
1174 
1185  protected function extractParam( $param, $format ) {
1186  if ( is_array( $param ) ) {
1187  if ( isset( $param['raw'] ) ) {
1188  return [ 'after', $param['raw'] ];
1189  } elseif ( isset( $param['num'] ) ) {
1190  // Replace number params always in before step for now.
1191  // No support for combined raw and num params
1192  return [ 'before', $this->getLanguage()->formatNum( $param['num'] ) ];
1193  } elseif ( isset( $param['duration'] ) ) {
1194  return [ 'before', $this->getLanguage()->formatDuration( $param['duration'] ) ];
1195  } elseif ( isset( $param['expiry'] ) ) {
1196  return [ 'before', $this->getLanguage()->formatExpiry( $param['expiry'] ) ];
1197  } elseif ( isset( $param['period'] ) ) {
1198  return [ 'before', $this->getLanguage()->formatTimePeriod( $param['period'] ) ];
1199  } elseif ( isset( $param['size'] ) ) {
1200  return [ 'before', $this->getLanguage()->formatSize( $param['size'] ) ];
1201  } elseif ( isset( $param['bitrate'] ) ) {
1202  return [ 'before', $this->getLanguage()->formatBitrate( $param['bitrate'] ) ];
1203  } elseif ( isset( $param['plaintext'] ) ) {
1204  return [ 'after', $this->formatPlaintext( $param['plaintext'], $format ) ];
1205  } elseif ( isset( $param['list'] ) ) {
1206  return $this->formatListParam( $param['list'], $param['type'], $format );
1207  } else {
1208  if ( !is_scalar( $param ) ) {
1209  $param = serialize( $param );
1210  }
1211  LoggerFactory::getInstance( 'Bug58676' )->warning(
1212  'Invalid parameter for message "{msgkey}": {param}',
1213  [
1214  'exception' => new Exception,
1215  'msgkey' => $this->getKey(),
1216  'param' => htmlspecialchars( $param ),
1217  ]
1218  );
1219 
1220  return [ 'before', '[INVALID]' ];
1221  }
1222  } elseif ( $param instanceof Message ) {
1223  // Match language, flags, etc. to the current message.
1224  $msg = clone $param;
1225  if ( $msg->language !== $this->language || $msg->useDatabase !== $this->useDatabase ) {
1226  // Cache depends on these parameters
1227  $msg->message = null;
1228  }
1229  $msg->interface = $this->interface;
1230  $msg->language = $this->language;
1231  $msg->useDatabase = $this->useDatabase;
1232  $msg->title = $this->title;
1233 
1234  // DWIM
1235  if ( $format === 'block-parse' ) {
1236  $format = 'parse';
1237  }
1238  $msg->format = $format;
1239 
1240  // Message objects should not be before parameters because
1241  // then they'll get double escaped. If the message needs to be
1242  // escaped, it'll happen right here when we call toString().
1243  return [ 'after', $msg->toString( $format ) ];
1244  } else {
1245  return [ 'before', $param ];
1246  }
1247  }
1248 
1258  protected function parseText( $string ) {
1259  $out = MessageCache::singleton()->parse(
1260  $string,
1261  $this->title,
1262  /*linestart*/true,
1263  $this->interface,
1264  $this->getLanguage()
1265  );
1266 
1267  return $out instanceof ParserOutput
1268  ? $out->getText( [
1269  'enableSectionEditLinks' => false,
1270  // Wrapping messages in an extra <div> is probably not expected. If
1271  // they're outside the content area they probably shouldn't be
1272  // targeted by CSS that's targeting the parser output, and if
1273  // they're inside they already are from the outer div.
1274  'unwrap' => true,
1275  ] )
1276  : $out;
1277  }
1278 
1288  protected function transformText( $string ) {
1289  return MessageCache::singleton()->transform(
1290  $string,
1291  $this->interface,
1292  $this->getLanguage(),
1293  $this->title
1294  );
1295  }
1296 
1305  protected function fetchMessage() {
1306  if ( $this->message === null ) {
1308 
1309  foreach ( $this->keysToTry as $key ) {
1310  $message = $cache->get( $key, $this->useDatabase, $this->getLanguage() );
1311  if ( $message !== false && $message !== '' ) {
1312  break;
1313  }
1314  }
1315 
1316  // NOTE: The constructor makes sure keysToTry isn't empty,
1317  // so we know that $key and $message are initialized.
1318  $this->key = $key;
1319  $this->message = $message;
1320  }
1321  return $this->message;
1322  }
1323 
1336  protected function formatPlaintext( $plaintext, $format ) {
1337  switch ( $format ) {
1338  case self::FORMAT_TEXT:
1339  case self::FORMAT_PLAIN:
1340  return $plaintext;
1341 
1342  case self::FORMAT_PARSE:
1343  case self::FORMAT_BLOCK_PARSE:
1344  case self::FORMAT_ESCAPED:
1345  default:
1346  return htmlspecialchars( $plaintext, ENT_QUOTES );
1347  }
1348  }
1349 
1358  protected function formatListParam( array $params, $listType, $format ) {
1359  if ( !isset( self::$listTypeMap[$listType] ) ) {
1360  $warning = 'Invalid list type for message "' . $this->getKey() . '": '
1361  . htmlspecialchars( $listType )
1362  . ' (params are ' . htmlspecialchars( serialize( $params ) ) . ')';
1363  trigger_error( $warning, E_USER_WARNING );
1364  $e = new Exception;
1365  wfDebugLog( 'Bug58676', $warning . "\n" . $e->getTraceAsString() );
1366  return [ 'before', '[INVALID]' ];
1367  }
1368  $func = self::$listTypeMap[$listType];
1369 
1370  // Handle an empty list sensibly
1371  if ( !$params ) {
1372  return [ 'before', $this->getLanguage()->$func( [] ) ];
1373  }
1374 
1375  // First, determine what kinds of list items we have
1376  $types = [];
1377  $vars = [];
1378  $list = [];
1379  foreach ( $params as $n => $p ) {
1380  list( $type, $value ) = $this->extractParam( $p, $format );
1381  $types[$type] = true;
1382  $list[] = $value;
1383  $vars[] = '$' . ( $n + 1 );
1384  }
1385 
1386  // Easy case: all are 'before' or 'after', so just join the
1387  // values and use the same type.
1388  if ( count( $types ) === 1 ) {
1389  return [ key( $types ), $this->getLanguage()->$func( $list ) ];
1390  }
1391 
1392  // Hard case: We need to process each value per its type, then
1393  // return the concatenated values as 'after'. We handle this by turning
1394  // the list into a RawMessage and processing that as a parameter.
1395  $vars = $this->getLanguage()->$func( $vars );
1396  return $this->extractParam( new RawMessage( $vars, $params ), $format );
1397  }
1398 }
getKeysToTry()
Definition: Message.php:343
getKey()
Returns the message key.
Definition: Message.php:358
static rawParam( $raw)
Definition: Message.php:1040
string [] $keysToTry
List of keys to try when fetching the message.
Definition: Message.php:209
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
static array bool $interface
In which language to get this message.
Definition: Message.php:191
isBlank()
Check whether a message does not exist, or is an empty string.
Definition: Message.php:1016
durationParams()
Add parameters that are durations of time and will be passed through Language::formatDuration before ...
Definition: Message.php:594
bool $useDatabase
Whether database can be used.
Definition: Message.php:225
Content $content
Content object representing the message.
Definition: Message.php:235
Title $title
Title object to use as context.
Definition: Message.php:230
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
rawParams()
Add parameters that are substituted after parsing or escaping.
Definition: Message.php:550
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
unserialize( $serialized)
Definition: Message.php:303
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2147
string $format
Definition: Message.php:220
Wrapper allowing us to handle a system message as a Content object.
formatListParam(array $params, $listType, $format)
Formats a list of parameters as a concatenated string.
Definition: Message.php:1358
const FORMAT_PLAIN
Use message text as-is.
Definition: Message.php:164
if(!isset( $args[0])) $lang
const FORMAT_BLOCK_PARSE
Use normal wikitext -> HTML parsing (the result will be wrapped in a block-level HTML tag) ...
Definition: Message.php:166
Language bool $language
In which language to get this message.
Definition: Message.php:198
$value
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation use $formDescriptor instead default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message key
Definition: hooks.txt:2139
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
text()
Returns the message text.
Definition: Message.php:955
const FORMAT_PARSE
Use normal wikitext -> HTML parsing but strip the block-level wrapper.
Definition: Message.php:168
parseAsBlock()
Returns the parsed message text which is always surrounded by a block element.
Definition: Message.php:979
getFormat()
Returns the message format.
Definition: Message.php:381
static numParam( $num)
Definition: Message.php:1051
content()
Returns the message as a Content object.
Definition: Message.php:839
static bitrateParam( $bitrate)
Definition: Message.php:1106
if( $line===false) $args
Definition: cdb.php:64
static stripOuterParagraph( $html)
Strip outer.
Definition: Parser.php:6455
useDatabase( $useDatabase)
Enable or disable database use.
Definition: Message.php:814
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:767
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1972
static array $listTypeMap
Mapping from Message::listParam() types to Language methods.
Definition: Message.php:178
getParams()
Returns the message parameters.
Definition: Message.php:369
transformText( $string)
Wrapper for what ever method we use to {{-transform wikitext.
Definition: Message.php:1288
static getMain()
Get the RequestContext object associated with the main request.
setInterfaceMessageFlag( $interface)
Allows manipulating the interface message flag directly.
Definition: Message.php:800
isMultiKey()
Definition: Message.php:333
const FORMAT_TEXT
Transform {{..}} constructs but don&#39;t transform to HTML.
Definition: Message.php:170
timeperiodParams()
Add parameters that are time periods and will be passed through Language::formatTimePeriod before sub...
Definition: Message.php:638
expiryParams()
Add parameters that are expiration times and will be passed through Language::formatExpiry before sub...
Definition: Message.php:616
static newFallbackSequence()
Factory function accepting multiple message keys and returning a message instance for the first messa...
Definition: Message.php:462
serialize()
Definition: Message.php:285
$cache
Definition: mcc.php:33
$params
string $key
The message key.
Definition: Message.php:204
array $parameters
List of parameters which will be substituted into the message.
Definition: Message.php:214
static newFromKey( $key)
Factory function that is just wrapper for the real constructor.
Definition: Message.php:410
params()
Adds parameters to the parameter list of this message.
Definition: Message.php:513
static durationParam( $duration)
Definition: Message.php:1062
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:767
setContext(IContextSource $context)
Set the language and the title from a context object.
Definition: Message.php:726
toString( $format=null)
Returns the message parsed from wikitext to HTML.
Definition: Message.php:858
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:216
getLanguage()
Returns the Language of the Message.
Definition: Message.php:393
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
inLanguage( $lang)
Request the message in any language that is supported.
Definition: Message.php:745
parse()
Fully parse the text from wikitext to HTML.
Definition: Message.php:943
const NS_MEDIAWIKI
Definition: Defines.php:68
$wgForceUIMsgAsContentMsg
When translating messages with wfMessage(), it is not always clear what should be considered UI messa...
title( $title)
Set the Title object to use as context when transforming the message.
Definition: Message.php:829
formatPlaintext( $plaintext, $format)
Formats a message parameter wrapped with &#39;plaintext&#39;.
Definition: Message.php:1336
exists()
Check whether a message key has been defined currently.
Definition: Message.php:1004
numParams()
Add parameters that are numeric and will be passed through Language::formatNum before substitution...
Definition: Message.php:572
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:592
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
static newFromSpecifier( $value)
Transform a MessageSpecifier or a primitive value used interchangeably with specifiers (a message key...
Definition: Message.php:429
sizeParams()
Add parameters that are file sizes and will be passed through Language::formatSize before substitutio...
Definition: Message.php:660
Variant of the Message class.
Definition: RawMessage.php:34
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not...
__toString()
Magic method implementation of the above (for PHP >= 5.2.0), so we can do, eg: $foo = new Message( $k...
Definition: Message.php:918
Stub object for the user language.
getTitle()
Get a title object for a mediawiki message, where it can be found in the mediawiki namespace...
Definition: Message.php:486
replaceParameters( $message, $type, $format)
Substitutes any parameters into the message text.
Definition: Message.php:1148
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation use $formDescriptor instead default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a message
Definition: hooks.txt:2139
extractParam( $param, $format)
Extracts the parameter type and preprocessed the value if needed.
Definition: Message.php:1185
plaintextParams()
Add parameters that are plaintext and will be passed through without the content being evaluated...
Definition: Message.php:706
bitrateParams()
Add parameters that are bitrates and will be passed through Language::formatBitrate before substituti...
Definition: Message.php:682
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on and they can depend only on the ResourceLoaderContext $context
Definition: hooks.txt:2621
parseText( $string)
Wrapper for what ever method we use to parse wikitext.
Definition: Message.php:1258
plain()
Returns the message text as-is, only parameters are substituted.
Definition: Message.php:967
inContentLanguage()
Request the message in the wiki&#39;s content language, unless it is disabled for this message...
Definition: Message.php:780
MediaWiki Logger LoggerFactory implements a PSR [0] compatible message logging system Named Psr Log LoggerInterface instances can be obtained from the MediaWiki Logger LoggerFactory::getInstance() static method. MediaWiki\Logger\LoggerFactory expects a class implementing the MediaWiki\Logger\Spi interface to act as a factory for new Psr\Log\LoggerInterface instances. The "Spi" in MediaWiki\Logger\Spi stands for "service provider interface". An SPI is an API intended to be implemented or extended by a third party. This software design pattern is intended to enable framework extension and replaceable components. It is specifically used in the MediaWiki\Logger\LoggerFactory service to allow alternate PSR-3 logging implementations to be easily integrated with MediaWiki. The service provider interface allows the backend logging library to be implemented in multiple ways. The $wgMWLoggerDefaultSpi global provides the classname of the default MediaWiki\Logger\Spi implementation to be loaded at runtime. This can either be the name of a class implementing the MediaWiki\Logger\Spi with a zero argument const ructor or a callable that will return an MediaWiki\Logger\Spi instance. Alternately the MediaWiki\Logger\LoggerFactory MediaWiki Logger LoggerFactory
Definition: logger.txt:5
fetchMessage()
Wrapper for what ever method we use to get message contents.
Definition: Message.php:1305
escaped()
Returns the message text.
Definition: Message.php:992
string $message
Definition: Message.php:240
static timeperiodParam( $period)
Definition: Message.php:1084
const FORMAT_ESCAPED
Transform {{..}} constructs, HTML-escape the result.
Definition: Message.php:172
foreach( $res as $row) $serialized
static sizeParam( $size)
Definition: Message.php:1095
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:2205
isDisabled()
Check whether a message does not exist, is an empty string, or is "-".
Definition: Message.php:1028
static plaintextParam( $plaintext)
Definition: Message.php:1117
static singleton()
Get the signleton instance of this class.
static listParam(array $list, $type='text')
Definition: Message.php:1128
if the prop value should be in the metadata multi language array format
Definition: hooks.txt:1623
__construct( $key, $params=[], Language $language=null)
Definition: Message.php:251
static expiryParam( $expiry)
Definition: Message.php:1073
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:322