MediaWiki  1.31.0
GlobalFunctions.php
Go to the documentation of this file.
1 <?php
23 if ( !defined( 'MEDIAWIKI' ) ) {
24  die( "This file is part of MediaWiki, it is not a valid entry point" );
25 }
26 
32 use Wikimedia\ScopedCallback;
34 
45 function wfLoadExtension( $ext, $path = null ) {
46  if ( !$path ) {
48  $path = "$wgExtensionDirectory/$ext/extension.json";
49  }
51 }
52 
66 function wfLoadExtensions( array $exts ) {
68  $registry = ExtensionRegistry::getInstance();
69  foreach ( $exts as $ext ) {
70  $registry->queue( "$wgExtensionDirectory/$ext/extension.json" );
71  }
72 }
73 
82 function wfLoadSkin( $skin, $path = null ) {
83  if ( !$path ) {
85  $path = "$wgStyleDirectory/$skin/skin.json";
86  }
88 }
89 
97 function wfLoadSkins( array $skins ) {
99  $registry = ExtensionRegistry::getInstance();
100  foreach ( $skins as $skin ) {
101  $registry->queue( "$wgStyleDirectory/$skin/skin.json" );
102  }
103 }
104 
111 function wfArrayDiff2( $a, $b ) {
112  return array_udiff( $a, $b, 'wfArrayDiff2_cmp' );
113 }
114 
120 function wfArrayDiff2_cmp( $a, $b ) {
121  if ( is_string( $a ) && is_string( $b ) ) {
122  return strcmp( $a, $b );
123  } elseif ( count( $a ) !== count( $b ) ) {
124  return count( $a ) < count( $b ) ? -1 : 1;
125  } else {
126  reset( $a );
127  reset( $b );
128  while ( key( $a ) !== null && key( $b ) !== null ) {
129  $valueA = current( $a );
130  $valueB = current( $b );
131  $cmp = strcmp( $valueA, $valueB );
132  if ( $cmp !== 0 ) {
133  return $cmp;
134  }
135  next( $a );
136  next( $b );
137  }
138  return 0;
139  }
140 }
141 
150 function wfArrayFilter( array $arr, callable $callback ) {
151  if ( defined( 'ARRAY_FILTER_USE_BOTH' ) ) {
152  return array_filter( $arr, $callback, ARRAY_FILTER_USE_BOTH );
153  }
154  $filteredKeys = array_filter( array_keys( $arr ), function ( $key ) use ( $arr, $callback ) {
155  return call_user_func( $callback, $arr[$key], $key );
156  } );
157  return array_intersect_key( $arr, array_fill_keys( $filteredKeys, true ) );
158 }
159 
168 function wfArrayFilterByKey( array $arr, callable $callback ) {
169  return wfArrayFilter( $arr, function ( $val, $key ) use ( $callback ) {
170  return call_user_func( $callback, $key );
171  } );
172 }
173 
183 function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
184  if ( is_null( $changed ) ) {
185  throw new MWException( 'GlobalFunctions::wfAppendToArrayIfNotDefault got null' );
186  }
187  if ( $default[$key] !== $value ) {
188  $changed[$key] = $value;
189  }
190 }
191 
211 function wfMergeErrorArrays( /*...*/ ) {
212  $args = func_get_args();
213  $out = [];
214  foreach ( $args as $errors ) {
215  foreach ( $errors as $params ) {
216  $originalParams = $params;
217  if ( $params[0] instanceof MessageSpecifier ) {
218  $msg = $params[0];
219  $params = array_merge( [ $msg->getKey() ], $msg->getParams() );
220  }
221  # @todo FIXME: Sometimes get nested arrays for $params,
222  # which leads to E_NOTICEs
223  $spec = implode( "\t", $params );
224  $out[$spec] = $originalParams;
225  }
226  }
227  return array_values( $out );
228 }
229 
238 function wfArrayInsertAfter( array $array, array $insert, $after ) {
239  // Find the offset of the element to insert after.
240  $keys = array_keys( $array );
241  $offsetByKey = array_flip( $keys );
242 
243  $offset = $offsetByKey[$after];
244 
245  // Insert at the specified offset
246  $before = array_slice( $array, 0, $offset + 1, true );
247  $after = array_slice( $array, $offset + 1, count( $array ) - $offset, true );
248 
249  $output = $before + $insert + $after;
250 
251  return $output;
252 }
253 
261 function wfObjectToArray( $objOrArray, $recursive = true ) {
262  $array = [];
263  if ( is_object( $objOrArray ) ) {
264  $objOrArray = get_object_vars( $objOrArray );
265  }
266  foreach ( $objOrArray as $key => $value ) {
267  if ( $recursive && ( is_object( $value ) || is_array( $value ) ) ) {
269  }
270 
271  $array[$key] = $value;
272  }
273 
274  return $array;
275 }
276 
287 function wfRandom() {
288  // The maximum random value is "only" 2^31-1, so get two random
289  // values to reduce the chance of dupes
290  $max = mt_getrandmax() + 1;
291  $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12, '.', '' );
292  return $rand;
293 }
294 
305 function wfRandomString( $length = 32 ) {
306  $str = '';
307  for ( $n = 0; $n < $length; $n += 7 ) {
308  $str .= sprintf( '%07x', mt_rand() & 0xfffffff );
309  }
310  return substr( $str, 0, $length );
311 }
312 
340 function wfUrlencode( $s ) {
341  static $needle;
342 
343  if ( is_null( $s ) ) {
344  $needle = null;
345  return '';
346  }
347 
348  if ( is_null( $needle ) ) {
349  $needle = [ '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F', '%7E' ];
350  if ( !isset( $_SERVER['SERVER_SOFTWARE'] ) ||
351  ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7' ) === false )
352  ) {
353  $needle[] = '%3A';
354  }
355  }
356 
357  $s = urlencode( $s );
358  $s = str_ireplace(
359  $needle,
360  [ ';', '@', '$', '!', '*', '(', ')', ',', '/', '~', ':' ],
361  $s
362  );
363 
364  return $s;
365 }
366 
377 function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) {
378  if ( !is_null( $array2 ) ) {
379  $array1 = $array1 + $array2;
380  }
381 
382  $cgi = '';
383  foreach ( $array1 as $key => $value ) {
384  if ( !is_null( $value ) && $value !== false ) {
385  if ( $cgi != '' ) {
386  $cgi .= '&';
387  }
388  if ( $prefix !== '' ) {
389  $key = $prefix . "[$key]";
390  }
391  if ( is_array( $value ) ) {
392  $firstTime = true;
393  foreach ( $value as $k => $v ) {
394  $cgi .= $firstTime ? '' : '&';
395  if ( is_array( $v ) ) {
396  $cgi .= wfArrayToCgi( $v, null, $key . "[$k]" );
397  } else {
398  $cgi .= urlencode( $key . "[$k]" ) . '=' . urlencode( $v );
399  }
400  $firstTime = false;
401  }
402  } else {
403  if ( is_object( $value ) ) {
404  $value = $value->__toString();
405  }
406  $cgi .= urlencode( $key ) . '=' . urlencode( $value );
407  }
408  }
409  }
410  return $cgi;
411 }
412 
422 function wfCgiToArray( $query ) {
423  if ( isset( $query[0] ) && $query[0] == '?' ) {
424  $query = substr( $query, 1 );
425  }
426  $bits = explode( '&', $query );
427  $ret = [];
428  foreach ( $bits as $bit ) {
429  if ( $bit === '' ) {
430  continue;
431  }
432  if ( strpos( $bit, '=' ) === false ) {
433  // Pieces like &qwerty become 'qwerty' => '' (at least this is what php does)
434  $key = $bit;
435  $value = '';
436  } else {
437  list( $key, $value ) = explode( '=', $bit );
438  }
439  $key = urldecode( $key );
440  $value = urldecode( $value );
441  if ( strpos( $key, '[' ) !== false ) {
442  $keys = array_reverse( explode( '[', $key ) );
443  $key = array_pop( $keys );
444  $temp = $value;
445  foreach ( $keys as $k ) {
446  $k = substr( $k, 0, -1 );
447  $temp = [ $k => $temp ];
448  }
449  if ( isset( $ret[$key] ) ) {
450  $ret[$key] = array_merge( $ret[$key], $temp );
451  } else {
452  $ret[$key] = $temp;
453  }
454  } else {
455  $ret[$key] = $value;
456  }
457  }
458  return $ret;
459 }
460 
469 function wfAppendQuery( $url, $query ) {
470  if ( is_array( $query ) ) {
472  }
473  if ( $query != '' ) {
474  // Remove the fragment, if there is one
475  $fragment = false;
476  $hashPos = strpos( $url, '#' );
477  if ( $hashPos !== false ) {
478  $fragment = substr( $url, $hashPos );
479  $url = substr( $url, 0, $hashPos );
480  }
481 
482  // Add parameter
483  if ( false === strpos( $url, '?' ) ) {
484  $url .= '?';
485  } else {
486  $url .= '&';
487  }
488  $url .= $query;
489 
490  // Put the fragment back
491  if ( $fragment !== false ) {
492  $url .= $fragment;
493  }
494  }
495  return $url;
496 }
497 
521 function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
523  $wgHttpsPort;
524  if ( $defaultProto === PROTO_CANONICAL ) {
525  $serverUrl = $wgCanonicalServer;
526  } elseif ( $defaultProto === PROTO_INTERNAL && $wgInternalServer !== false ) {
527  // Make $wgInternalServer fall back to $wgServer if not set
528  $serverUrl = $wgInternalServer;
529  } else {
530  $serverUrl = $wgServer;
531  if ( $defaultProto === PROTO_CURRENT ) {
532  $defaultProto = $wgRequest->getProtocol() . '://';
533  }
534  }
535 
536  // Analyze $serverUrl to obtain its protocol
537  $bits = wfParseUrl( $serverUrl );
538  $serverHasProto = $bits && $bits['scheme'] != '';
539 
540  if ( $defaultProto === PROTO_CANONICAL || $defaultProto === PROTO_INTERNAL ) {
541  if ( $serverHasProto ) {
542  $defaultProto = $bits['scheme'] . '://';
543  } else {
544  // $wgCanonicalServer or $wgInternalServer doesn't have a protocol.
545  // This really isn't supposed to happen. Fall back to HTTP in this
546  // ridiculous case.
547  $defaultProto = PROTO_HTTP;
548  }
549  }
550 
551  $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
552 
553  if ( substr( $url, 0, 2 ) == '//' ) {
554  $url = $defaultProtoWithoutSlashes . $url;
555  } elseif ( substr( $url, 0, 1 ) == '/' ) {
556  // If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes,
557  // otherwise leave it alone.
558  $url = ( $serverHasProto ? '' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
559  }
560 
561  $bits = wfParseUrl( $url );
562 
563  // ensure proper port for HTTPS arrives in URL
564  // https://phabricator.wikimedia.org/T67184
565  if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
566  $bits['port'] = $wgHttpsPort;
567  }
568 
569  if ( $bits && isset( $bits['path'] ) ) {
570  $bits['path'] = wfRemoveDotSegments( $bits['path'] );
571  return wfAssembleUrl( $bits );
572  } elseif ( $bits ) {
573  # No path to expand
574  return $url;
575  } elseif ( substr( $url, 0, 1 ) != '/' ) {
576  # URL is a relative path
577  return wfRemoveDotSegments( $url );
578  }
579 
580  # Expanded URL is not valid.
581  return false;
582 }
583 
597 function wfAssembleUrl( $urlParts ) {
598  $result = '';
599 
600  if ( isset( $urlParts['delimiter'] ) ) {
601  if ( isset( $urlParts['scheme'] ) ) {
602  $result .= $urlParts['scheme'];
603  }
604 
605  $result .= $urlParts['delimiter'];
606  }
607 
608  if ( isset( $urlParts['host'] ) ) {
609  if ( isset( $urlParts['user'] ) ) {
610  $result .= $urlParts['user'];
611  if ( isset( $urlParts['pass'] ) ) {
612  $result .= ':' . $urlParts['pass'];
613  }
614  $result .= '@';
615  }
616 
617  $result .= $urlParts['host'];
618 
619  if ( isset( $urlParts['port'] ) ) {
620  $result .= ':' . $urlParts['port'];
621  }
622  }
623 
624  if ( isset( $urlParts['path'] ) ) {
625  $result .= $urlParts['path'];
626  }
627 
628  if ( isset( $urlParts['query'] ) ) {
629  $result .= '?' . $urlParts['query'];
630  }
631 
632  if ( isset( $urlParts['fragment'] ) ) {
633  $result .= '#' . $urlParts['fragment'];
634  }
635 
636  return $result;
637 }
638 
649 function wfRemoveDotSegments( $urlPath ) {
650  $output = '';
651  $inputOffset = 0;
652  $inputLength = strlen( $urlPath );
653 
654  while ( $inputOffset < $inputLength ) {
655  $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
656  $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
657  $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
658  $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
659  $trimOutput = false;
660 
661  if ( $prefixLengthTwo == './' ) {
662  # Step A, remove leading "./"
663  $inputOffset += 2;
664  } elseif ( $prefixLengthThree == '../' ) {
665  # Step A, remove leading "../"
666  $inputOffset += 3;
667  } elseif ( ( $prefixLengthTwo == '/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
668  # Step B, replace leading "/.$" with "/"
669  $inputOffset += 1;
670  $urlPath[$inputOffset] = '/';
671  } elseif ( $prefixLengthThree == '/./' ) {
672  # Step B, replace leading "/./" with "/"
673  $inputOffset += 2;
674  } elseif ( $prefixLengthThree == '/..' && ( $inputOffset + 3 == $inputLength ) ) {
675  # Step C, replace leading "/..$" with "/" and
676  # remove last path component in output
677  $inputOffset += 2;
678  $urlPath[$inputOffset] = '/';
679  $trimOutput = true;
680  } elseif ( $prefixLengthFour == '/../' ) {
681  # Step C, replace leading "/../" with "/" and
682  # remove last path component in output
683  $inputOffset += 3;
684  $trimOutput = true;
685  } elseif ( ( $prefixLengthOne == '.' ) && ( $inputOffset + 1 == $inputLength ) ) {
686  # Step D, remove "^.$"
687  $inputOffset += 1;
688  } elseif ( ( $prefixLengthTwo == '..' ) && ( $inputOffset + 2 == $inputLength ) ) {
689  # Step D, remove "^..$"
690  $inputOffset += 2;
691  } else {
692  # Step E, move leading path segment to output
693  if ( $prefixLengthOne == '/' ) {
694  $slashPos = strpos( $urlPath, '/', $inputOffset + 1 );
695  } else {
696  $slashPos = strpos( $urlPath, '/', $inputOffset );
697  }
698  if ( $slashPos === false ) {
699  $output .= substr( $urlPath, $inputOffset );
700  $inputOffset = $inputLength;
701  } else {
702  $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
703  $inputOffset += $slashPos - $inputOffset;
704  }
705  }
706 
707  if ( $trimOutput ) {
708  $slashPos = strrpos( $output, '/' );
709  if ( $slashPos === false ) {
710  $output = '';
711  } else {
712  $output = substr( $output, 0, $slashPos );
713  }
714  }
715  }
716 
717  return $output;
718 }
719 
727 function wfUrlProtocols( $includeProtocolRelative = true ) {
729 
730  // Cache return values separately based on $includeProtocolRelative
731  static $withProtRel = null, $withoutProtRel = null;
732  $cachedValue = $includeProtocolRelative ? $withProtRel : $withoutProtRel;
733  if ( !is_null( $cachedValue ) ) {
734  return $cachedValue;
735  }
736 
737  // Support old-style $wgUrlProtocols strings, for backwards compatibility
738  // with LocalSettings files from 1.5
739  if ( is_array( $wgUrlProtocols ) ) {
740  $protocols = [];
741  foreach ( $wgUrlProtocols as $protocol ) {
742  // Filter out '//' if !$includeProtocolRelative
743  if ( $includeProtocolRelative || $protocol !== '//' ) {
744  $protocols[] = preg_quote( $protocol, '/' );
745  }
746  }
747 
748  $retval = implode( '|', $protocols );
749  } else {
750  // Ignore $includeProtocolRelative in this case
751  // This case exists for pre-1.6 compatibility, and we can safely assume
752  // that '//' won't appear in a pre-1.6 config because protocol-relative
753  // URLs weren't supported until 1.18
755  }
756 
757  // Cache return value
758  if ( $includeProtocolRelative ) {
759  $withProtRel = $retval;
760  } else {
761  $withoutProtRel = $retval;
762  }
763  return $retval;
764 }
765 
773  return wfUrlProtocols( false );
774 }
775 
801 function wfParseUrl( $url ) {
802  global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
803 
804  // Protocol-relative URLs are handled really badly by parse_url(). It's so
805  // bad that the easiest way to handle them is to just prepend 'http:' and
806  // strip the protocol out later.
807  $wasRelative = substr( $url, 0, 2 ) == '//';
808  if ( $wasRelative ) {
809  $url = "http:$url";
810  }
811  Wikimedia\suppressWarnings();
812  $bits = parse_url( $url );
813  Wikimedia\restoreWarnings();
814  // parse_url() returns an array without scheme for some invalid URLs, e.g.
815  // parse_url("%0Ahttp://example.com") == [ 'host' => '%0Ahttp', 'path' => 'example.com' ]
816  if ( !$bits || !isset( $bits['scheme'] ) ) {
817  return false;
818  }
819 
820  // parse_url() incorrectly handles schemes case-sensitively. Convert it to lowercase.
821  $bits['scheme'] = strtolower( $bits['scheme'] );
822 
823  // most of the protocols are followed by ://, but mailto: and sometimes news: not, check for it
824  if ( in_array( $bits['scheme'] . '://', $wgUrlProtocols ) ) {
825  $bits['delimiter'] = '://';
826  } elseif ( in_array( $bits['scheme'] . ':', $wgUrlProtocols ) ) {
827  $bits['delimiter'] = ':';
828  // parse_url detects for news: and mailto: the host part of an url as path
829  // We have to correct this wrong detection
830  if ( isset( $bits['path'] ) ) {
831  $bits['host'] = $bits['path'];
832  $bits['path'] = '';
833  }
834  } else {
835  return false;
836  }
837 
838  /* Provide an empty host for eg. file:/// urls (see T30627) */
839  if ( !isset( $bits['host'] ) ) {
840  $bits['host'] = '';
841 
842  // See T47069
843  if ( isset( $bits['path'] ) ) {
844  /* parse_url loses the third / for file:///c:/ urls (but not on variants) */
845  if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
846  $bits['path'] = '/' . $bits['path'];
847  }
848  } else {
849  $bits['path'] = '';
850  }
851  }
852 
853  // If the URL was protocol-relative, fix scheme and delimiter
854  if ( $wasRelative ) {
855  $bits['scheme'] = '';
856  $bits['delimiter'] = '//';
857  }
858  return $bits;
859 }
860 
871 function wfExpandIRI( $url ) {
872  return preg_replace_callback(
873  '/((?:%[89A-F][0-9A-F])+)/i',
874  'wfExpandIRI_callback',
875  wfExpandUrl( $url )
876  );
877 }
878 
885  return urldecode( $matches[1] );
886 }
887 
894 function wfMakeUrlIndexes( $url ) {
895  $bits = wfParseUrl( $url );
896 
897  // Reverse the labels in the hostname, convert to lower case
898  // For emails reverse domainpart only
899  if ( $bits['scheme'] == 'mailto' ) {
900  $mailparts = explode( '@', $bits['host'], 2 );
901  if ( count( $mailparts ) === 2 ) {
902  $domainpart = strtolower( implode( '.', array_reverse( explode( '.', $mailparts[1] ) ) ) );
903  } else {
904  // No domain specified, don't mangle it
905  $domainpart = '';
906  }
907  $reversedHost = $domainpart . '@' . $mailparts[0];
908  } else {
909  $reversedHost = strtolower( implode( '.', array_reverse( explode( '.', $bits['host'] ) ) ) );
910  }
911  // Add an extra dot to the end
912  // Why? Is it in wrong place in mailto links?
913  if ( substr( $reversedHost, -1, 1 ) !== '.' ) {
914  $reversedHost .= '.';
915  }
916  // Reconstruct the pseudo-URL
917  $prot = $bits['scheme'];
918  $index = $prot . $bits['delimiter'] . $reversedHost;
919  // Leave out user and password. Add the port, path, query and fragment
920  if ( isset( $bits['port'] ) ) {
921  $index .= ':' . $bits['port'];
922  }
923  if ( isset( $bits['path'] ) ) {
924  $index .= $bits['path'];
925  } else {
926  $index .= '/';
927  }
928  if ( isset( $bits['query'] ) ) {
929  $index .= '?' . $bits['query'];
930  }
931  if ( isset( $bits['fragment'] ) ) {
932  $index .= '#' . $bits['fragment'];
933  }
934 
935  if ( $prot == '' ) {
936  return [ "http:$index", "https:$index" ];
937  } else {
938  return [ $index ];
939  }
940 }
941 
948 function wfMatchesDomainList( $url, $domains ) {
949  $bits = wfParseUrl( $url );
950  if ( is_array( $bits ) && isset( $bits['host'] ) ) {
951  $host = '.' . $bits['host'];
952  foreach ( (array)$domains as $domain ) {
953  $domain = '.' . $domain;
954  if ( substr( $host, -strlen( $domain ) ) === $domain ) {
955  return true;
956  }
957  }
958  }
959  return false;
960 }
961 
982 function wfDebug( $text, $dest = 'all', array $context = [] ) {
985 
986  if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
987  return;
988  }
989 
990  $text = trim( $text );
991 
992  if ( $wgDebugTimestamps ) {
993  $context['seconds_elapsed'] = sprintf(
994  '%6.4f',
995  microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT']
996  );
997  $context['memory_used'] = sprintf(
998  '%5.1fM',
999  ( memory_get_usage( true ) / ( 1024 * 1024 ) )
1000  );
1001  }
1002 
1003  if ( $wgDebugLogPrefix !== '' ) {
1004  $context['prefix'] = $wgDebugLogPrefix;
1005  }
1006  $context['private'] = ( $dest === false || $dest === 'private' );
1007 
1008  $logger = LoggerFactory::getInstance( 'wfDebug' );
1009  $logger->debug( $text, $context );
1010 }
1011 
1016 function wfIsDebugRawPage() {
1017  static $cache;
1018  if ( $cache !== null ) {
1019  return $cache;
1020  }
1021  # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
1022  if ( ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' )
1023  || (
1024  isset( $_SERVER['SCRIPT_NAME'] )
1025  && substr( $_SERVER['SCRIPT_NAME'], -8 ) == 'load.php'
1026  )
1027  ) {
1028  $cache = true;
1029  } else {
1030  $cache = false;
1031  }
1032  return $cache;
1033 }
1034 
1040 function wfDebugMem( $exact = false ) {
1041  $mem = memory_get_usage();
1042  if ( !$exact ) {
1043  $mem = floor( $mem / 1024 ) . ' KiB';
1044  } else {
1045  $mem .= ' B';
1046  }
1047  wfDebug( "Memory usage: $mem\n" );
1048 }
1049 
1075 function wfDebugLog(
1076  $logGroup, $text, $dest = 'all', array $context = []
1077 ) {
1078  $text = trim( $text );
1079 
1080  $logger = LoggerFactory::getInstance( $logGroup );
1081  $context['private'] = ( $dest === false || $dest === 'private' );
1082  $logger->info( $text, $context );
1083 }
1084 
1093 function wfLogDBError( $text, array $context = [] ) {
1094  $logger = LoggerFactory::getInstance( 'wfLogDBError' );
1095  $logger->error( trim( $text ), $context );
1096 }
1097 
1111 function wfDeprecated( $function, $version = false, $component = false, $callerOffset = 2 ) {
1112  MWDebug::deprecated( $function, $version, $component, $callerOffset + 1 );
1113 }
1114 
1125 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
1126  MWDebug::warning( $msg, $callerOffset + 1, $level, 'auto' );
1127 }
1128 
1138 function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
1139  MWDebug::warning( $msg, $callerOffset + 1, $level, 'production' );
1140 }
1141 
1155 function wfErrorLog( $text, $file, array $context = [] ) {
1156  wfDeprecated( __METHOD__, '1.25' );
1157  $logger = LoggerFactory::getInstance( 'wfErrorLog' );
1158  $context['destination'] = $file;
1159  $logger->info( trim( $text ), $context );
1160 }
1161 
1168 
1170  $request = $context->getRequest();
1171 
1172  $profiler = Profiler::instance();
1173  $profiler->setContext( $context );
1174  $profiler->logData();
1175 
1176  // Send out any buffered statsd metrics as needed
1178  MediaWikiServices::getInstance()->getStatsdDataFactory(),
1179  $context->getConfig()
1180  );
1181 
1182  // Profiling must actually be enabled...
1183  if ( $profiler instanceof ProfilerStub ) {
1184  return;
1185  }
1186 
1187  if ( isset( $wgDebugLogGroups['profileoutput'] )
1188  && $wgDebugLogGroups['profileoutput'] === false
1189  ) {
1190  // Explicitly disabled
1191  return;
1192  }
1193  if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
1194  return;
1195  }
1196 
1197  $ctx = [ 'elapsed' => $request->getElapsedTime() ];
1198  if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
1199  $ctx['forwarded_for'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
1200  }
1201  if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
1202  $ctx['client_ip'] = $_SERVER['HTTP_CLIENT_IP'];
1203  }
1204  if ( !empty( $_SERVER['HTTP_FROM'] ) ) {
1205  $ctx['from'] = $_SERVER['HTTP_FROM'];
1206  }
1207  if ( isset( $ctx['forwarded_for'] ) ||
1208  isset( $ctx['client_ip'] ) ||
1209  isset( $ctx['from'] ) ) {
1210  $ctx['proxy'] = $_SERVER['REMOTE_ADDR'];
1211  }
1212 
1213  // Don't load $wgUser at this late stage just for statistics purposes
1214  // @todo FIXME: We can detect some anons even if it is not loaded.
1215  // See User::getId()
1216  $user = $context->getUser();
1217  $ctx['anon'] = $user->isItemLoaded( 'id' ) && $user->isAnon();
1218 
1219  // Command line script uses a FauxRequest object which does not have
1220  // any knowledge about an URL and throw an exception instead.
1221  try {
1222  $ctx['url'] = urldecode( $request->getRequestURL() );
1223  } catch ( Exception $ignored ) {
1224  // no-op
1225  }
1226 
1227  $ctx['output'] = $profiler->getOutput();
1228 
1229  $log = LoggerFactory::getInstance( 'profileoutput' );
1230  $log->info( "Elapsed: {elapsed}; URL: <{url}>\n{output}", $ctx );
1231 }
1232 
1240 function wfIncrStats( $key, $count = 1 ) {
1241  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
1242  $stats->updateCount( $key, $count );
1243 }
1244 
1250 function wfReadOnly() {
1251  return MediaWikiServices::getInstance()->getReadOnlyMode()
1252  ->isReadOnly();
1253 }
1254 
1263 function wfReadOnlyReason() {
1264  return MediaWikiServices::getInstance()->getReadOnlyMode()
1265  ->getReason();
1266 }
1267 
1275  return MediaWikiServices::getInstance()->getConfiguredReadOnlyMode()
1276  ->getReason();
1277 }
1278 
1294 function wfGetLangObj( $langcode = false ) {
1295  # Identify which language to get or create a language object for.
1296  # Using is_object here due to Stub objects.
1297  if ( is_object( $langcode ) ) {
1298  # Great, we already have the object (hopefully)!
1299  return $langcode;
1300  }
1301 
1303  if ( $langcode === true || $langcode === $wgLanguageCode ) {
1304  # $langcode is the language code of the wikis content language object.
1305  # or it is a boolean and value is true
1306  return $wgContLang;
1307  }
1308 
1309  global $wgLang;
1310  if ( $langcode === false || $langcode === $wgLang->getCode() ) {
1311  # $langcode is the language code of user language object.
1312  # or it was a boolean and value is false
1313  return $wgLang;
1314  }
1315 
1316  $validCodes = array_keys( Language::fetchLanguageNames() );
1317  if ( in_array( $langcode, $validCodes ) ) {
1318  # $langcode corresponds to a valid language.
1319  return Language::factory( $langcode );
1320  }
1321 
1322  # $langcode is a string, but not a valid language code; use content language.
1323  wfDebug( "Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
1324  return $wgContLang;
1325 }
1326 
1343 function wfMessage( $key /*...*/ ) {
1344  $message = new Message( $key );
1345 
1346  // We call Message::params() to reduce code duplication
1347  $params = func_get_args();
1348  array_shift( $params );
1349  if ( $params ) {
1350  call_user_func_array( [ $message, 'params' ], $params );
1351  }
1352 
1353  return $message;
1354 }
1355 
1368 function wfMessageFallback( /*...*/ ) {
1369  $args = func_get_args();
1370  return call_user_func_array( 'Message::newFallbackSequence', $args );
1371 }
1372 
1381 function wfMsgReplaceArgs( $message, $args ) {
1382  # Fix windows line-endings
1383  # Some messages are split with explode("\n", $msg)
1384  $message = str_replace( "\r", '', $message );
1385 
1386  // Replace arguments
1387  if ( is_array( $args ) && $args ) {
1388  if ( is_array( $args[0] ) ) {
1389  $args = array_values( $args[0] );
1390  }
1391  $replacementKeys = [];
1392  foreach ( $args as $n => $param ) {
1393  $replacementKeys['$' . ( $n + 1 )] = $param;
1394  }
1395  $message = strtr( $message, $replacementKeys );
1396  }
1397 
1398  return $message;
1399 }
1400 
1408 function wfHostname() {
1409  static $host;
1410  if ( is_null( $host ) ) {
1411  # Hostname overriding
1413  if ( $wgOverrideHostname !== false ) {
1414  # Set static and skip any detection
1415  $host = $wgOverrideHostname;
1416  return $host;
1417  }
1418 
1419  if ( function_exists( 'posix_uname' ) ) {
1420  // This function not present on Windows
1421  $uname = posix_uname();
1422  } else {
1423  $uname = false;
1424  }
1425  if ( is_array( $uname ) && isset( $uname['nodename'] ) ) {
1426  $host = $uname['nodename'];
1427  } elseif ( getenv( 'COMPUTERNAME' ) ) {
1428  # Windows computer name
1429  $host = getenv( 'COMPUTERNAME' );
1430  } else {
1431  # This may be a virtual server.
1432  $host = $_SERVER['SERVER_NAME'];
1433  }
1434  }
1435  return $host;
1436 }
1437 
1447 function wfReportTime() {
1449 
1450  $elapsed = ( microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT'] );
1451  // seconds to milliseconds
1452  $responseTime = round( $elapsed * 1000 );
1453  $reportVars = [ 'wgBackendResponseTime' => $responseTime ];
1454  if ( $wgShowHostnames ) {
1455  $reportVars['wgHostname'] = wfHostname();
1456  }
1457  return Skin::makeVariablesScript( $reportVars );
1458 }
1459 
1470 function wfDebugBacktrace( $limit = 0 ) {
1471  static $disabled = null;
1472 
1473  if ( is_null( $disabled ) ) {
1474  $disabled = !function_exists( 'debug_backtrace' );
1475  if ( $disabled ) {
1476  wfDebug( "debug_backtrace() is disabled\n" );
1477  }
1478  }
1479  if ( $disabled ) {
1480  return [];
1481  }
1482 
1483  if ( $limit ) {
1484  return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit + 1 ), 1 );
1485  } else {
1486  return array_slice( debug_backtrace(), 1 );
1487  }
1488 }
1489 
1498 function wfBacktrace( $raw = null ) {
1500 
1501  if ( $raw === null ) {
1502  $raw = $wgCommandLineMode;
1503  }
1504 
1505  if ( $raw ) {
1506  $frameFormat = "%s line %s calls %s()\n";
1507  $traceFormat = "%s";
1508  } else {
1509  $frameFormat = "<li>%s line %s calls %s()</li>\n";
1510  $traceFormat = "<ul>\n%s</ul>\n";
1511  }
1512 
1513  $frames = array_map( function ( $frame ) use ( $frameFormat ) {
1514  $file = !empty( $frame['file'] ) ? basename( $frame['file'] ) : '-';
1515  $line = isset( $frame['line'] ) ? $frame['line'] : '-';
1516  $call = $frame['function'];
1517  if ( !empty( $frame['class'] ) ) {
1518  $call = $frame['class'] . $frame['type'] . $call;
1519  }
1520  return sprintf( $frameFormat, $file, $line, $call );
1521  }, wfDebugBacktrace() );
1522 
1523  return sprintf( $traceFormat, implode( '', $frames ) );
1524 }
1525 
1535 function wfGetCaller( $level = 2 ) {
1536  $backtrace = wfDebugBacktrace( $level + 1 );
1537  if ( isset( $backtrace[$level] ) ) {
1538  return wfFormatStackFrame( $backtrace[$level] );
1539  } else {
1540  return 'unknown';
1541  }
1542 }
1543 
1551 function wfGetAllCallers( $limit = 3 ) {
1552  $trace = array_reverse( wfDebugBacktrace() );
1553  if ( !$limit || $limit > count( $trace ) - 1 ) {
1554  $limit = count( $trace ) - 1;
1555  }
1556  $trace = array_slice( $trace, -$limit - 1, $limit );
1557  return implode( '/', array_map( 'wfFormatStackFrame', $trace ) );
1558 }
1559 
1566 function wfFormatStackFrame( $frame ) {
1567  if ( !isset( $frame['function'] ) ) {
1568  return 'NO_FUNCTION_GIVEN';
1569  }
1570  return isset( $frame['class'] ) && isset( $frame['type'] ) ?
1571  $frame['class'] . $frame['type'] . $frame['function'] :
1572  $frame['function'];
1573 }
1574 
1575 /* Some generic result counters, pulled out of SearchEngine */
1576 
1584 function wfShowingResults( $offset, $limit ) {
1585  return wfMessage( 'showingresults' )->numParams( $limit, $offset + 1 )->parse();
1586 }
1587 
1597 function wfClientAcceptsGzip( $force = false ) {
1598  static $result = null;
1599  if ( $result === null || $force ) {
1600  $result = false;
1601  if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
1602  # @todo FIXME: We may want to blacklist some broken browsers
1603  $m = [];
1604  if ( preg_match(
1605  '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
1606  $_SERVER['HTTP_ACCEPT_ENCODING'],
1607  $m
1608  )
1609  ) {
1610  if ( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) {
1611  $result = false;
1612  return $result;
1613  }
1614  wfDebug( "wfClientAcceptsGzip: client accepts gzip.\n" );
1615  $result = true;
1616  }
1617  }
1618  }
1619  return $result;
1620 }
1621 
1631 function wfEscapeWikiText( $text ) {
1633  static $repl = null, $repl2 = null;
1634  if ( $repl === null || defined( 'MW_PARSER_TEST' ) || defined( 'MW_PHPUNIT_TEST' ) ) {
1635  // Tests depend upon being able to change $wgEnableMagicLinks, so don't cache
1636  // in those situations
1637  $repl = [
1638  '"' => '&#34;', '&' => '&#38;', "'" => '&#39;', '<' => '&#60;',
1639  '=' => '&#61;', '>' => '&#62;', '[' => '&#91;', ']' => '&#93;',
1640  '{' => '&#123;', '|' => '&#124;', '}' => '&#125;', ';' => '&#59;',
1641  "\n#" => "\n&#35;", "\r#" => "\r&#35;",
1642  "\n*" => "\n&#42;", "\r*" => "\r&#42;",
1643  "\n:" => "\n&#58;", "\r:" => "\r&#58;",
1644  "\n " => "\n&#32;", "\r " => "\r&#32;",
1645  "\n\n" => "\n&#10;", "\r\n" => "&#13;\n",
1646  "\n\r" => "\n&#13;", "\r\r" => "\r&#13;",
1647  "\n\t" => "\n&#9;", "\r\t" => "\r&#9;", // "\n\t\n" is treated like "\n\n"
1648  "\n----" => "\n&#45;---", "\r----" => "\r&#45;---",
1649  '__' => '_&#95;', '://' => '&#58;//',
1650  ];
1651 
1652  $magicLinks = array_keys( array_filter( $wgEnableMagicLinks ) );
1653  // We have to catch everything "\s" matches in PCRE
1654  foreach ( $magicLinks as $magic ) {
1655  $repl["$magic "] = "$magic&#32;";
1656  $repl["$magic\t"] = "$magic&#9;";
1657  $repl["$magic\r"] = "$magic&#13;";
1658  $repl["$magic\n"] = "$magic&#10;";
1659  $repl["$magic\f"] = "$magic&#12;";
1660  }
1661 
1662  // And handle protocols that don't use "://"
1664  $repl2 = [];
1665  foreach ( $wgUrlProtocols as $prot ) {
1666  if ( substr( $prot, -1 ) === ':' ) {
1667  $repl2[] = preg_quote( substr( $prot, 0, -1 ), '/' );
1668  }
1669  }
1670  $repl2 = $repl2 ? '/\b(' . implode( '|', $repl2 ) . '):/i' : '/^(?!)/';
1671  }
1672  $text = substr( strtr( "\n$text", $repl ), 1 );
1673  $text = preg_replace( $repl2, '$1&#58;', $text );
1674  return $text;
1675 }
1676 
1687 function wfSetVar( &$dest, $source, $force = false ) {
1688  $temp = $dest;
1689  if ( !is_null( $source ) || $force ) {
1690  $dest = $source;
1691  }
1692  return $temp;
1693 }
1694 
1704 function wfSetBit( &$dest, $bit, $state = true ) {
1705  $temp = (bool)( $dest & $bit );
1706  if ( !is_null( $state ) ) {
1707  if ( $state ) {
1708  $dest |= $bit;
1709  } else {
1710  $dest &= ~$bit;
1711  }
1712  }
1713  return $temp;
1714 }
1715 
1722 function wfVarDump( $var ) {
1723  global $wgOut;
1724  $s = str_replace( "\n", "<br />\n", var_export( $var, true ) . "\n" );
1725  if ( headers_sent() || !isset( $wgOut ) || !is_object( $wgOut ) ) {
1726  print $s;
1727  } else {
1728  $wgOut->addHTML( $s );
1729  }
1730 }
1731 
1739 function wfHttpError( $code, $label, $desc ) {
1740  global $wgOut;
1742  if ( $wgOut ) {
1743  $wgOut->disable();
1744  $wgOut->sendCacheControl();
1745  }
1746 
1748  header( 'Content-type: text/html; charset=utf-8' );
1749  print '<!DOCTYPE html>' .
1750  '<html><head><title>' .
1751  htmlspecialchars( $label ) .
1752  '</title></head><body><h1>' .
1753  htmlspecialchars( $label ) .
1754  '</h1><p>' .
1755  nl2br( htmlspecialchars( $desc ) ) .
1756  "</p></body></html>\n";
1757 }
1758 
1776 function wfResetOutputBuffers( $resetGzipEncoding = true ) {
1777  if ( $resetGzipEncoding ) {
1778  // Suppress Content-Encoding and Content-Length
1779  // headers from OutputHandler::handle.
1782  }
1783  while ( $status = ob_get_status() ) {
1784  if ( isset( $status['flags'] ) ) {
1785  $flags = PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_REMOVABLE;
1786  $deleteable = ( $status['flags'] & $flags ) === $flags;
1787  } elseif ( isset( $status['del'] ) ) {
1788  $deleteable = $status['del'];
1789  } else {
1790  // Guess that any PHP-internal setting can't be removed.
1791  $deleteable = $status['type'] !== 0; /* PHP_OUTPUT_HANDLER_INTERNAL */
1792  }
1793  if ( !$deleteable ) {
1794  // Give up, and hope the result doesn't break
1795  // output behavior.
1796  break;
1797  }
1798  if ( $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
1799  // Unit testing barrier to prevent this function from breaking PHPUnit.
1800  break;
1801  }
1802  if ( !ob_end_clean() ) {
1803  // Could not remove output buffer handler; abort now
1804  // to avoid getting in some kind of infinite loop.
1805  break;
1806  }
1807  if ( $resetGzipEncoding ) {
1808  if ( $status['name'] == 'ob_gzhandler' ) {
1809  // Reset the 'Content-Encoding' field set by this handler
1810  // so we can start fresh.
1811  header_remove( 'Content-Encoding' );
1812  break;
1813  }
1814  }
1815  }
1816 }
1817 
1831  wfResetOutputBuffers( false );
1832 }
1833 
1842 function wfAcceptToPrefs( $accept, $def = '*/*' ) {
1843  # No arg means accept anything (per HTTP spec)
1844  if ( !$accept ) {
1845  return [ $def => 1.0 ];
1846  }
1847 
1848  $prefs = [];
1849 
1850  $parts = explode( ',', $accept );
1851 
1852  foreach ( $parts as $part ) {
1853  # @todo FIXME: Doesn't deal with params like 'text/html; level=1'
1854  $values = explode( ';', trim( $part ) );
1855  $match = [];
1856  if ( count( $values ) == 1 ) {
1857  $prefs[$values[0]] = 1.0;
1858  } elseif ( preg_match( '/q\s*=\s*(\d*\.\d+)/', $values[1], $match ) ) {
1859  $prefs[$values[0]] = floatval( $match[1] );
1860  }
1861  }
1862 
1863  return $prefs;
1864 }
1865 
1878 function mimeTypeMatch( $type, $avail ) {
1879  if ( array_key_exists( $type, $avail ) ) {
1880  return $type;
1881  } else {
1882  $mainType = explode( '/', $type )[0];
1883  if ( array_key_exists( "$mainType/*", $avail ) ) {
1884  return "$mainType/*";
1885  } elseif ( array_key_exists( '*/*', $avail ) ) {
1886  return '*/*';
1887  } else {
1888  return null;
1889  }
1890  }
1891 }
1892 
1906 function wfNegotiateType( $cprefs, $sprefs ) {
1907  $combine = [];
1908 
1909  foreach ( array_keys( $sprefs ) as $type ) {
1910  $subType = explode( '/', $type )[1];
1911  if ( $subType != '*' ) {
1912  $ckey = mimeTypeMatch( $type, $cprefs );
1913  if ( $ckey ) {
1914  $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
1915  }
1916  }
1917  }
1918 
1919  foreach ( array_keys( $cprefs ) as $type ) {
1920  $subType = explode( '/', $type )[1];
1921  if ( $subType != '*' && !array_key_exists( $type, $sprefs ) ) {
1922  $skey = mimeTypeMatch( $type, $sprefs );
1923  if ( $skey ) {
1924  $combine[$type] = $sprefs[$skey] * $cprefs[$type];
1925  }
1926  }
1927  }
1928 
1929  $bestq = 0;
1930  $besttype = null;
1931 
1932  foreach ( array_keys( $combine ) as $type ) {
1933  if ( $combine[$type] > $bestq ) {
1934  $besttype = $type;
1935  $bestq = $combine[$type];
1936  }
1937  }
1938 
1939  return $besttype;
1940 }
1941 
1948 function wfSuppressWarnings( $end = false ) {
1949  Wikimedia\suppressWarnings( $end );
1950 }
1951 
1956 function wfRestoreWarnings() {
1957  Wikimedia\restoreWarnings();
1958 }
1959 
1968 function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
1969  $ret = MWTimestamp::convert( $outputtype, $ts );
1970  if ( $ret === false ) {
1971  wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
1972  }
1973  return $ret;
1974 }
1975 
1984 function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
1985  if ( is_null( $ts ) ) {
1986  return null;
1987  } else {
1988  return wfTimestamp( $outputtype, $ts );
1989  }
1990 }
1991 
1997 function wfTimestampNow() {
1998  # return NOW
1999  return MWTimestamp::now( TS_MW );
2000 }
2001 
2007 function wfIsWindows() {
2008  static $isWindows = null;
2009  if ( $isWindows === null ) {
2010  $isWindows = strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN';
2011  }
2012  return $isWindows;
2013 }
2014 
2020 function wfIsHHVM() {
2021  return defined( 'HHVM_VERSION' );
2022 }
2023 
2030 function wfIsCLI() {
2031  return PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg';
2032 }
2033 
2045 function wfTempDir() {
2047 
2048  if ( $wgTmpDirectory !== false ) {
2049  return $wgTmpDirectory;
2050  }
2051 
2053 }
2054 
2064 function wfMkdirParents( $dir, $mode = null, $caller = null ) {
2066 
2067  if ( FileBackend::isStoragePath( $dir ) ) { // sanity
2068  throw new MWException( __FUNCTION__ . " given storage path '$dir'." );
2069  }
2070 
2071  if ( !is_null( $caller ) ) {
2072  wfDebug( "$caller: called wfMkdirParents($dir)\n" );
2073  }
2074 
2075  if ( strval( $dir ) === '' || is_dir( $dir ) ) {
2076  return true;
2077  }
2078 
2079  $dir = str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, $dir );
2080 
2081  if ( is_null( $mode ) ) {
2082  $mode = $wgDirectoryMode;
2083  }
2084 
2085  // Turn off the normal warning, we're doing our own below
2086  Wikimedia\suppressWarnings();
2087  $ok = mkdir( $dir, $mode, true ); // PHP5 <3
2088  Wikimedia\restoreWarnings();
2089 
2090  if ( !$ok ) {
2091  // directory may have been created on another request since we last checked
2092  if ( is_dir( $dir ) ) {
2093  return true;
2094  }
2095 
2096  // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis.
2097  wfLogWarning( sprintf( "failed to mkdir \"%s\" mode 0%o", $dir, $mode ) );
2098  }
2099  return $ok;
2100 }
2101 
2107 function wfRecursiveRemoveDir( $dir ) {
2108  wfDebug( __FUNCTION__ . "( $dir )\n" );
2109  // taken from https://secure.php.net/manual/en/function.rmdir.php#98622
2110  if ( is_dir( $dir ) ) {
2111  $objects = scandir( $dir );
2112  foreach ( $objects as $object ) {
2113  if ( $object != "." && $object != ".." ) {
2114  if ( filetype( $dir . '/' . $object ) == "dir" ) {
2115  wfRecursiveRemoveDir( $dir . '/' . $object );
2116  } else {
2117  unlink( $dir . '/' . $object );
2118  }
2119  }
2120  }
2121  reset( $objects );
2122  rmdir( $dir );
2123  }
2124 }
2125 
2132 function wfPercent( $nr, $acc = 2, $round = true ) {
2133  $ret = sprintf( "%.${acc}f", $nr );
2134  return $round ? round( $ret, $acc ) . '%' : "$ret%";
2135 }
2136 
2160 function wfIniGetBool( $setting ) {
2161  return wfStringToBool( ini_get( $setting ) );
2162 }
2163 
2176 function wfStringToBool( $val ) {
2177  $val = strtolower( $val );
2178  // 'on' and 'true' can't have whitespace around them, but '1' can.
2179  return $val == 'on'
2180  || $val == 'true'
2181  || $val == 'yes'
2182  || preg_match( "/^\s*[+-]?0*[1-9]/", $val ); // approx C atoi() function
2183 }
2184 
2197 function wfEscapeShellArg( /*...*/ ) {
2198  $args = func_get_args();
2199 
2200  return call_user_func_array( Shell::class . '::escape', $args );
2201 }
2202 
2211  wfDeprecated( __FUNCTION__, '1.30' );
2212  return Shell::isDisabled() ? 'disabled' : false;
2213 }
2214 
2238 function wfShellExec( $cmd, &$retval = null, $environ = [],
2239  $limits = [], $options = []
2240 ) {
2241  if ( Shell::isDisabled() ) {
2242  $retval = 1;
2243  // Backwards compatibility be upon us...
2244  return 'Unable to run external programs, proc_open() is disabled.';
2245  }
2246 
2247  if ( is_array( $cmd ) ) {
2248  $cmd = Shell::escape( $cmd );
2249  }
2250 
2251  $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
2252  $profileMethod = isset( $options['profileMethod'] ) ? $options['profileMethod'] : wfGetCaller();
2253 
2254  try {
2255  $result = Shell::command( [] )
2256  ->unsafeParams( (array)$cmd )
2257  ->environment( $environ )
2258  ->limits( $limits )
2259  ->includeStderr( $includeStderr )
2260  ->profileMethod( $profileMethod )
2261  // For b/c
2262  ->restrict( Shell::RESTRICT_NONE )
2263  ->execute();
2264  } catch ( ProcOpenError $ex ) {
2265  $retval = -1;
2266  return '';
2267  }
2268 
2269  $retval = $result->getExitCode();
2270 
2271  return $result->getStdout();
2272 }
2273 
2291 function wfShellExecWithStderr( $cmd, &$retval = null, $environ = [], $limits = [] ) {
2292  return wfShellExec( $cmd, $retval, $environ, $limits,
2293  [ 'duplicateStderr' => true, 'profileMethod' => wfGetCaller() ] );
2294 }
2295 
2304 function wfInitShellLocale() {
2305  wfDeprecated( __FUNCTION__, '1.30' );
2306 }
2307 
2322 function wfShellWikiCmd( $script, array $parameters = [], array $options = [] ) {
2323  global $wgPhpCli;
2324  // Give site config file a chance to run the script in a wrapper.
2325  // The caller may likely want to call wfBasename() on $script.
2326  Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
2327  $cmd = isset( $options['php'] ) ? [ $options['php'] ] : [ $wgPhpCli ];
2328  if ( isset( $options['wrapper'] ) ) {
2329  $cmd[] = $options['wrapper'];
2330  }
2331  $cmd[] = $script;
2332  // Escape each parameter for shell
2333  return Shell::escape( array_merge( $cmd, $parameters ) );
2334 }
2335 
2347 function wfMerge( $old, $mine, $yours, &$result, &$mergeAttemptResult = null ) {
2348  global $wgDiff3;
2349 
2350  # This check may also protect against code injection in
2351  # case of broken installations.
2352  Wikimedia\suppressWarnings();
2353  $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
2354  Wikimedia\restoreWarnings();
2355 
2356  if ( !$haveDiff3 ) {
2357  wfDebug( "diff3 not found\n" );
2358  return false;
2359  }
2360 
2361  # Make temporary files
2362  $td = wfTempDir();
2363  $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
2364  $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
2365  $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
2366 
2367  # NOTE: diff3 issues a warning to stderr if any of the files does not end with
2368  # a newline character. To avoid this, we normalize the trailing whitespace before
2369  # creating the diff.
2370 
2371  fwrite( $oldtextFile, rtrim( $old ) . "\n" );
2372  fclose( $oldtextFile );
2373  fwrite( $mytextFile, rtrim( $mine ) . "\n" );
2374  fclose( $mytextFile );
2375  fwrite( $yourtextFile, rtrim( $yours ) . "\n" );
2376  fclose( $yourtextFile );
2377 
2378  # Check for a conflict
2379  $cmd = Shell::escape( $wgDiff3, '-a', '--overlap-only', $mytextName,
2380  $oldtextName, $yourtextName );
2381  $handle = popen( $cmd, 'r' );
2382 
2383  $mergeAttemptResult = '';
2384  do {
2385  $data = fread( $handle, 8192 );
2386  if ( strlen( $data ) == 0 ) {
2387  break;
2388  }
2389  $mergeAttemptResult .= $data;
2390  } while ( true );
2391  pclose( $handle );
2392 
2393  $conflict = $mergeAttemptResult !== '';
2394 
2395  # Merge differences
2396  $cmd = Shell::escape( $wgDiff3, '-a', '-e', '--merge', $mytextName,
2397  $oldtextName, $yourtextName );
2398  $handle = popen( $cmd, 'r' );
2399  $result = '';
2400  do {
2401  $data = fread( $handle, 8192 );
2402  if ( strlen( $data ) == 0 ) {
2403  break;
2404  }
2405  $result .= $data;
2406  } while ( true );
2407  pclose( $handle );
2408  unlink( $mytextName );
2409  unlink( $oldtextName );
2410  unlink( $yourtextName );
2411 
2412  if ( $result === '' && $old !== '' && !$conflict ) {
2413  wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
2414  $conflict = true;
2415  }
2416  return !$conflict;
2417 }
2418 
2430 function wfDiff( $before, $after, $params = '-u' ) {
2431  if ( $before == $after ) {
2432  return '';
2433  }
2434 
2435  global $wgDiff;
2436  Wikimedia\suppressWarnings();
2437  $haveDiff = $wgDiff && file_exists( $wgDiff );
2438  Wikimedia\restoreWarnings();
2439 
2440  # This check may also protect against code injection in
2441  # case of broken installations.
2442  if ( !$haveDiff ) {
2443  wfDebug( "diff executable not found\n" );
2444  $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) );
2445  $format = new UnifiedDiffFormatter();
2446  return $format->format( $diffs );
2447  }
2448 
2449  # Make temporary files
2450  $td = wfTempDir();
2451  $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
2452  $newtextFile = fopen( $newtextName = tempnam( $td, 'merge-your-' ), 'w' );
2453 
2454  fwrite( $oldtextFile, $before );
2455  fclose( $oldtextFile );
2456  fwrite( $newtextFile, $after );
2457  fclose( $newtextFile );
2458 
2459  // Get the diff of the two files
2460  $cmd = "$wgDiff " . $params . ' ' . Shell::escape( $oldtextName, $newtextName );
2461 
2462  $h = popen( $cmd, 'r' );
2463  if ( !$h ) {
2464  unlink( $oldtextName );
2465  unlink( $newtextName );
2466  throw new Exception( __METHOD__ . '(): popen() failed' );
2467  }
2468 
2469  $diff = '';
2470 
2471  do {
2472  $data = fread( $h, 8192 );
2473  if ( strlen( $data ) == 0 ) {
2474  break;
2475  }
2476  $diff .= $data;
2477  } while ( true );
2478 
2479  // Clean up
2480  pclose( $h );
2481  unlink( $oldtextName );
2482  unlink( $newtextName );
2483 
2484  // Kill the --- and +++ lines. They're not useful.
2485  $diff_lines = explode( "\n", $diff );
2486  if ( isset( $diff_lines[0] ) && strpos( $diff_lines[0], '---' ) === 0 ) {
2487  unset( $diff_lines[0] );
2488  }
2489  if ( isset( $diff_lines[1] ) && strpos( $diff_lines[1], '+++' ) === 0 ) {
2490  unset( $diff_lines[1] );
2491  }
2492 
2493  $diff = implode( "\n", $diff_lines );
2494 
2495  return $diff;
2496 }
2497 
2516 function wfUsePHP( $req_ver ) {
2517  wfDeprecated( __FUNCTION__, '1.30' );
2518  $php_ver = PHP_VERSION;
2519 
2520  if ( version_compare( $php_ver, (string)$req_ver, '<' ) ) {
2521  throw new MWException( "PHP $req_ver required--this is only $php_ver" );
2522  }
2523 }
2524 
2547 function wfUseMW( $req_ver ) {
2549 
2550  if ( version_compare( $wgVersion, (string)$req_ver, '<' ) ) {
2551  throw new MWException( "MediaWiki $req_ver required--this is only $wgVersion" );
2552  }
2553 }
2554 
2567 function wfBaseName( $path, $suffix = '' ) {
2568  if ( $suffix == '' ) {
2569  $encSuffix = '';
2570  } else {
2571  $encSuffix = '(?:' . preg_quote( $suffix, '#' ) . ')?';
2572  }
2573 
2574  $matches = [];
2575  if ( preg_match( "#([^/\\\\]*?){$encSuffix}[/\\\\]*$#", $path, $matches ) ) {
2576  return $matches[1];
2577  } else {
2578  return '';
2579  }
2580 }
2581 
2591 function wfRelativePath( $path, $from ) {
2592  // Normalize mixed input on Windows...
2593  $path = str_replace( '/', DIRECTORY_SEPARATOR, $path );
2594  $from = str_replace( '/', DIRECTORY_SEPARATOR, $from );
2595 
2596  // Trim trailing slashes -- fix for drive root
2597  $path = rtrim( $path, DIRECTORY_SEPARATOR );
2598  $from = rtrim( $from, DIRECTORY_SEPARATOR );
2599 
2600  $pieces = explode( DIRECTORY_SEPARATOR, dirname( $path ) );
2601  $against = explode( DIRECTORY_SEPARATOR, $from );
2602 
2603  if ( $pieces[0] !== $against[0] ) {
2604  // Non-matching Windows drive letters?
2605  // Return a full path.
2606  return $path;
2607  }
2608 
2609  // Trim off common prefix
2610  while ( count( $pieces ) && count( $against )
2611  && $pieces[0] == $against[0] ) {
2612  array_shift( $pieces );
2613  array_shift( $against );
2614  }
2615 
2616  // relative dots to bump us to the parent
2617  while ( count( $against ) ) {
2618  array_unshift( $pieces, '..' );
2619  array_shift( $against );
2620  }
2621 
2622  array_push( $pieces, wfBaseName( $path ) );
2623 
2624  return implode( DIRECTORY_SEPARATOR, $pieces );
2625 }
2626 
2633 function wfResetSessionID() {
2634  wfDeprecated( __FUNCTION__, '1.27' );
2635  $session = SessionManager::getGlobalSession();
2636  $delay = $session->delaySave();
2637 
2638  $session->resetId();
2639 
2640  // Make sure a session is started, since that's what the old
2641  // wfResetSessionID() did.
2642  if ( session_id() !== $session->getId() ) {
2643  wfSetupSession( $session->getId() );
2644  }
2645 
2646  ScopedCallback::consume( $delay );
2647 }
2648 
2658 function wfSetupSession( $sessionId = false ) {
2659  wfDeprecated( __FUNCTION__, '1.27' );
2660 
2661  if ( $sessionId ) {
2662  session_id( $sessionId );
2663  }
2664 
2665  $session = SessionManager::getGlobalSession();
2666  $session->persist();
2667 
2668  if ( session_id() !== $session->getId() ) {
2669  session_id( $session->getId() );
2670  }
2671  Wikimedia\quietCall( 'session_start' );
2672 }
2673 
2681  global $IP;
2682 
2683  $file = "$IP/serialized/$name";
2684  if ( file_exists( $file ) ) {
2685  $blob = file_get_contents( $file );
2686  if ( $blob ) {
2687  return unserialize( $blob );
2688  }
2689  }
2690  return false;
2691 }
2692 
2700 function wfMemcKey( /*...*/ ) {
2701  return call_user_func_array(
2702  [ ObjectCache::getLocalClusterInstance(), 'makeKey' ],
2703  func_get_args()
2704  );
2705 }
2706 
2717 function wfForeignMemcKey( $db, $prefix /*...*/ ) {
2718  $args = array_slice( func_get_args(), 2 );
2719  $keyspace = $prefix ? "$db-$prefix" : $db;
2720  return call_user_func_array(
2721  [ ObjectCache::getLocalClusterInstance(), 'makeKeyInternal' ],
2722  [ $keyspace, $args ]
2723  );
2724 }
2725 
2738 function wfGlobalCacheKey( /*...*/ ) {
2739  return call_user_func_array(
2740  [ ObjectCache::getLocalClusterInstance(), 'makeGlobalKey' ],
2741  func_get_args()
2742  );
2743 }
2744 
2751 function wfWikiID() {
2753  if ( $wgDBprefix ) {
2754  return "$wgDBname-$wgDBprefix";
2755  } else {
2756  return $wgDBname;
2757  }
2758 }
2759 
2767 function wfSplitWikiID( $wiki ) {
2768  $bits = explode( '-', $wiki, 2 );
2769  if ( count( $bits ) < 2 ) {
2770  $bits[] = '';
2771  }
2772  return $bits;
2773 }
2774 
2800 function wfGetDB( $db, $groups = [], $wiki = false ) {
2801  return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
2802 }
2803 
2813 function wfGetLB( $wiki = false ) {
2814  if ( $wiki === false ) {
2815  return MediaWikiServices::getInstance()->getDBLoadBalancer();
2816  } else {
2817  $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2818  return $factory->getMainLB( $wiki );
2819  }
2820 }
2821 
2829 function wfGetLBFactory() {
2830  return MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2831 }
2832 
2841 function wfFindFile( $title, $options = [] ) {
2842  return RepoGroup::singleton()->findFile( $title, $options );
2843 }
2844 
2852 function wfLocalFile( $title ) {
2853  return RepoGroup::singleton()->getLocalRepo()->newFile( $title );
2854 }
2855 
2864  return $wgMiserMode
2865  || ( SiteStats::pages() > 100000
2866  && SiteStats::edits() > 1000000
2867  && SiteStats::users() > 10000 );
2868 }
2869 
2878 function wfScript( $script = 'index' ) {
2880  if ( $script === 'index' ) {
2881  return $wgScript;
2882  } elseif ( $script === 'load' ) {
2883  return $wgLoadScript;
2884  } else {
2885  return "{$wgScriptPath}/{$script}.php";
2886  }
2887 }
2888 
2894 function wfGetScriptUrl() {
2895  if ( isset( $_SERVER['SCRIPT_NAME'] ) ) {
2896  /* as it was called, minus the query string.
2897  *
2898  * Some sites use Apache rewrite rules to handle subdomains,
2899  * and have PHP set up in a weird way that causes PHP_SELF
2900  * to contain the rewritten URL instead of the one that the
2901  * outside world sees.
2902  *
2903  * If in this mode, use SCRIPT_URL instead, which mod_rewrite
2904  * provides containing the "before" URL.
2905  */
2906  return $_SERVER['SCRIPT_NAME'];
2907  } else {
2908  return $_SERVER['URL'];
2909  }
2910 }
2911 
2919 function wfBoolToStr( $value ) {
2920  return $value ? 'true' : 'false';
2921 }
2922 
2928 function wfGetNull() {
2929  return wfIsWindows() ? 'NUL' : '/dev/null';
2930 }
2931 
2955  $ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null
2956 ) {
2957  if ( $timeout === null ) {
2958  $timeout = wfIsCLI() ? 60 : 10;
2959  }
2960 
2961  if ( $cluster === '*' ) {
2962  $cluster = false;
2963  $wiki = false;
2964  } elseif ( $wiki === false ) {
2965  $wiki = wfWikiID();
2966  }
2967 
2968  try {
2969  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2970  $lbFactory->waitForReplication( [
2971  'wiki' => $wiki,
2972  'cluster' => $cluster,
2973  'timeout' => $timeout,
2974  // B/C: first argument used to be "max seconds of lag"; ignore such values
2975  'ifWritesSince' => ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null
2976  ] );
2977  } catch ( DBReplicationWaitError $e ) {
2978  return false;
2979  }
2980 
2981  return true;
2982 }
2983 
2993 function wfCountDown( $seconds ) {
2994  for ( $i = $seconds; $i >= 0; $i-- ) {
2995  if ( $i != $seconds ) {
2996  echo str_repeat( "\x08", strlen( $i + 1 ) );
2997  }
2998  echo $i;
2999  flush();
3000  if ( $i ) {
3001  sleep( 1 );
3002  }
3003  }
3004  echo "\n";
3005 }
3006 
3017  $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : '';
3018  $name = preg_replace(
3019  "/[^" . Title::legalChars() . "]" . $illegalFileChars . "/",
3020  '-',
3021  $name
3022  );
3023  // $wgIllegalFileChars may not include '/' and '\', so we still need to do this
3024  $name = wfBaseName( $name );
3025  return $name;
3026 }
3027 
3033 function wfMemoryLimit() {
3035  $memlimit = wfShorthandToInteger( ini_get( 'memory_limit' ) );
3036  if ( $memlimit != -1 ) {
3037  $conflimit = wfShorthandToInteger( $wgMemoryLimit );
3038  if ( $conflimit == -1 ) {
3039  wfDebug( "Removing PHP's memory limit\n" );
3040  Wikimedia\suppressWarnings();
3041  ini_set( 'memory_limit', $conflimit );
3042  Wikimedia\restoreWarnings();
3043  return $conflimit;
3044  } elseif ( $conflimit > $memlimit ) {
3045  wfDebug( "Raising PHP's memory limit to $conflimit bytes\n" );
3046  Wikimedia\suppressWarnings();
3047  ini_set( 'memory_limit', $conflimit );
3048  Wikimedia\restoreWarnings();
3049  return $conflimit;
3050  }
3051  }
3052  return $memlimit;
3053 }
3054 
3063 
3064  $timeLimit = ini_get( 'max_execution_time' );
3065  // Note that CLI scripts use 0
3066  if ( $timeLimit > 0 && $wgTransactionalTimeLimit > $timeLimit ) {
3067  set_time_limit( $wgTransactionalTimeLimit );
3068  }
3069 
3070  ignore_user_abort( true ); // ignore client disconnects
3071 
3072  return $timeLimit;
3073 }
3074 
3082 function wfShorthandToInteger( $string = '', $default = -1 ) {
3083  $string = trim( $string );
3084  if ( $string === '' ) {
3085  return $default;
3086  }
3087  $last = $string[strlen( $string ) - 1];
3088  $val = intval( $string );
3089  switch ( $last ) {
3090  case 'g':
3091  case 'G':
3092  $val *= 1024;
3093  // break intentionally missing
3094  case 'm':
3095  case 'M':
3096  $val *= 1024;
3097  // break intentionally missing
3098  case 'k':
3099  case 'K':
3100  $val *= 1024;
3101  }
3102 
3103  return $val;
3104 }
3105 
3116 function wfBCP47( $code ) {
3117  return LanguageCode::bcp47( $code );
3118 }
3119 
3126 function wfGetCache( $cacheType ) {
3127  return ObjectCache::getInstance( $cacheType );
3128 }
3129 
3135 function wfGetMainCache() {
3138 }
3139 
3148 }
3149 
3159 }
3160 
3171 function wfRunHooks( $event, array $args = [], $deprecatedVersion = null ) {
3172  wfDeprecated( __METHOD__, '1.25' );
3173  return Hooks::run( $event, $args, $deprecatedVersion );
3174 }
3175 
3190 function wfUnpack( $format, $data, $length = false ) {
3191  if ( $length !== false ) {
3192  $realLen = strlen( $data );
3193  if ( $realLen < $length ) {
3194  throw new MWException( "Tried to use wfUnpack on a "
3195  . "string of length $realLen, but needed one "
3196  . "of at least length $length."
3197  );
3198  }
3199  }
3200 
3201  Wikimedia\suppressWarnings();
3202  $result = unpack( $format, $data );
3203  Wikimedia\restoreWarnings();
3204 
3205  if ( $result === false ) {
3206  // If it cannot extract the packed data.
3207  throw new MWException( "unpack could not unpack binary data" );
3208  }
3209  return $result;
3210 }
3211 
3226 function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
3227  # Handle redirects; callers almost always hit wfFindFile() anyway,
3228  # so just use that method because it has a fast process cache.
3229  $file = wfFindFile( $name ); // get the final name
3230  $name = $file ? $file->getTitle()->getDBkey() : $name;
3231 
3232  # Run the extension hook
3233  $bad = false;
3234  if ( !Hooks::run( 'BadImage', [ $name, &$bad ] ) ) {
3235  return (bool)$bad;
3236  }
3237 
3239  $key = $cache->makeKey(
3240  'bad-image-list', ( $blacklist === null ) ? 'default' : md5( $blacklist )
3241  );
3242  $badImages = $cache->get( $key );
3243 
3244  if ( $badImages === false ) { // cache miss
3245  if ( $blacklist === null ) {
3246  $blacklist = wfMessage( 'bad_image_list' )->inContentLanguage()->plain(); // site list
3247  }
3248  # Build the list now
3249  $badImages = [];
3250  $lines = explode( "\n", $blacklist );
3251  foreach ( $lines as $line ) {
3252  # List items only
3253  if ( substr( $line, 0, 1 ) !== '*' ) {
3254  continue;
3255  }
3256 
3257  # Find all links
3258  $m = [];
3259  if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
3260  continue;
3261  }
3262 
3263  $exceptions = [];
3264  $imageDBkey = false;
3265  foreach ( $m[1] as $i => $titleText ) {
3266  $title = Title::newFromText( $titleText );
3267  if ( !is_null( $title ) ) {
3268  if ( $i == 0 ) {
3269  $imageDBkey = $title->getDBkey();
3270  } else {
3271  $exceptions[$title->getPrefixedDBkey()] = true;
3272  }
3273  }
3274  }
3275 
3276  if ( $imageDBkey !== false ) {
3277  $badImages[$imageDBkey] = $exceptions;
3278  }
3279  }
3280  $cache->set( $key, $badImages, 60 );
3281  }
3282 
3283  $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() : false;
3284  $bad = isset( $badImages[$name] ) && !isset( $badImages[$name][$contextKey] );
3285 
3286  return $bad;
3287 }
3288 
3296 function wfCanIPUseHTTPS( $ip ) {
3297  $canDo = true;
3298  Hooks::run( 'CanIPUseHTTPS', [ $ip, &$canDo ] );
3299  return !!$canDo;
3300 }
3301 
3309 function wfIsInfinity( $str ) {
3310  // These are hardcoded elsewhere in MediaWiki (e.g. mediawiki.special.block.js).
3311  $infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ];
3312  return in_array( $str, $infinityValues );
3313 }
3314 
3329 function wfThumbIsStandard( File $file, array $params ) {
3331 
3332  $multipliers = [ 1 ];
3333  if ( $wgResponsiveImages ) {
3334  // These available sizes are hardcoded currently elsewhere in MediaWiki.
3335  // @see Linker::processResponsiveImages
3336  $multipliers[] = 1.5;
3337  $multipliers[] = 2;
3338  }
3339 
3340  $handler = $file->getHandler();
3341  if ( !$handler || !isset( $params['width'] ) ) {
3342  return false;
3343  }
3344 
3345  $basicParams = [];
3346  if ( isset( $params['page'] ) ) {
3347  $basicParams['page'] = $params['page'];
3348  }
3349 
3350  $thumbLimits = [];
3351  $imageLimits = [];
3352  // Expand limits to account for multipliers
3353  foreach ( $multipliers as $multiplier ) {
3354  $thumbLimits = array_merge( $thumbLimits, array_map(
3355  function ( $width ) use ( $multiplier ) {
3356  return round( $width * $multiplier );
3357  }, $wgThumbLimits )
3358  );
3359  $imageLimits = array_merge( $imageLimits, array_map(
3360  function ( $pair ) use ( $multiplier ) {
3361  return [
3362  round( $pair[0] * $multiplier ),
3363  round( $pair[1] * $multiplier ),
3364  ];
3365  }, $wgImageLimits )
3366  );
3367  }
3368 
3369  // Check if the width matches one of $wgThumbLimits
3370  if ( in_array( $params['width'], $thumbLimits ) ) {
3371  $normalParams = $basicParams + [ 'width' => $params['width'] ];
3372  // Append any default values to the map (e.g. "lossy", "lossless", ...)
3373  $handler->normaliseParams( $file, $normalParams );
3374  } else {
3375  // If not, then check if the width matchs one of $wgImageLimits
3376  $match = false;
3377  foreach ( $imageLimits as $pair ) {
3378  $normalParams = $basicParams + [ 'width' => $pair[0], 'height' => $pair[1] ];
3379  // Decide whether the thumbnail should be scaled on width or height.
3380  // Also append any default values to the map (e.g. "lossy", "lossless", ...)
3381  $handler->normaliseParams( $file, $normalParams );
3382  // Check if this standard thumbnail size maps to the given width
3383  if ( $normalParams['width'] == $params['width'] ) {
3384  $match = true;
3385  break;
3386  }
3387  }
3388  if ( !$match ) {
3389  return false; // not standard for description pages
3390  }
3391  }
3392 
3393  // Check that the given values for non-page, non-width, params are just defaults
3394  foreach ( $params as $key => $value ) {
3395  if ( !isset( $normalParams[$key] ) || $normalParams[$key] != $value ) {
3396  return false;
3397  }
3398  }
3399 
3400  return true;
3401 }
3402 
3415 function wfArrayPlus2d( array $baseArray, array $newValues ) {
3416  // First merge items that are in both arrays
3417  foreach ( $baseArray as $name => &$groupVal ) {
3418  if ( isset( $newValues[$name] ) ) {
3419  $groupVal += $newValues[$name];
3420  }
3421  }
3422  // Now add items that didn't exist yet
3423  $baseArray += $newValues;
3424 
3425  return $baseArray;
3426 }
3427 
3436 function wfGetRusage() {
3437  if ( !function_exists( 'getrusage' ) ) {
3438  return false;
3439  } elseif ( defined( 'HHVM_VERSION' ) && PHP_OS === 'Linux' ) {
3440  return getrusage( 2 /* RUSAGE_THREAD */ );
3441  } else {
3442  return getrusage( 0 /* RUSAGE_SELF */ );
3443  }
3444 }
wfMessage
wfMessage( $key)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1343
$wgPhpCli
$wgPhpCli
Executable path of the PHP cli binary.
Definition: DefaultSettings.php:8245
wfUseMW
wfUseMW( $req_ver)
This function works like "use VERSION" in Perl except it checks the version of MediaWiki,...
Definition: GlobalFunctions.php:2547
wfArrayInsertAfter
wfArrayInsertAfter(array $array, array $insert, $after)
Insert array into another array after the specified KEY
Definition: GlobalFunctions.php:238
MediaWiki\Shell\Shell
Executes shell commands.
Definition: Shell.php:44
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:244
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:273
wfPercent
wfPercent( $nr, $acc=2, $round=true)
Definition: GlobalFunctions.php:2132
wfResetOutputBuffers
wfResetOutputBuffers( $resetGzipEncoding=true)
Clear away any user-level output buffers, discarding contents.
Definition: GlobalFunctions.php:1776
$wgThumbLimits
$wgThumbLimits
Adjust thumbnails on image pages according to a user setting.
Definition: DefaultSettings.php:1376
PROTO_CANONICAL
const PROTO_CANONICAL
Definition: Defines.php:224
wfBCP47
wfBCP47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: GlobalFunctions.php:3116
RepoGroup\singleton
static singleton()
Get a RepoGroup instance.
Definition: RepoGroup.php:59
wfCanIPUseHTTPS
wfCanIPUseHTTPS( $ip)
Determine whether the client at a given source IP is likely to be able to access the wiki via HTTPS.
Definition: GlobalFunctions.php:3296
wfMergeErrorArrays
wfMergeErrorArrays()
Merge arrays in the style of getUserPermissionsErrors, with duplicate removal e.g.
Definition: GlobalFunctions.php:211
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
ObjectCache\getLocalClusterInstance
static getLocalClusterInstance()
Get the main cluster-local cache object.
Definition: ObjectCache.php:367
SiteStats\users
static users()
Definition: SiteStats.php:121
MediaWiki\emitBufferedStatsdData
static emitBufferedStatsdData(IBufferingStatsdDataFactory $stats, Config $config)
Send out any buffered statsd data according to sampling rules.
Definition: MediaWiki.php:933
PROTO_INTERNAL
const PROTO_INTERNAL
Definition: Defines.php:225
MediaWiki\ProcOpenError
Definition: ProcOpenError.php:25
$context
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:2604
wfDiff
wfDiff( $before, $after, $params='-u')
Returns unified plain-text diff of two texts.
Definition: GlobalFunctions.php:2430
$wgResponsiveImages
$wgResponsiveImages
Generate and use thumbnails suitable for screens with 1.5 and 2.0 pixel densities.
Definition: DefaultSettings.php:1499
wfSetupSession
wfSetupSession( $sessionId=false)
Initialise php session.
Definition: GlobalFunctions.php:2658
$wgDebugRawPage
$wgDebugRawPage
If true, log debugging data from action=raw and load.php.
Definition: DefaultSettings.php:6080
wfThumbIsStandard
wfThumbIsStandard(File $file, array $params)
Returns true if these thumbnail parameters match one that MediaWiki requests from file description pa...
Definition: GlobalFunctions.php:3329
$wgTmpDirectory
$wgTmpDirectory
The local filesystem path to a temporary directory.
Definition: DefaultSettings.php:338
wfArrayPlus2d
wfArrayPlus2d(array $baseArray, array $newValues)
Merges two (possibly) 2 dimensional arrays into the target array ($baseArray).
Definition: GlobalFunctions.php:3415
Profiler\instance
static instance()
Singleton.
Definition: Profiler.php:62
wfMkdirParents
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
Definition: GlobalFunctions.php:2064
wfArrayFilter
wfArrayFilter(array $arr, callable $callback)
Like array_filter with ARRAY_FILTER_USE_BOTH, but works pre-5.6.
Definition: GlobalFunctions.php:150
$wgDiff3
$wgDiff3
Path to the GNU diff3 utility.
Definition: DefaultSettings.php:6554
wfMerge
wfMerge( $old, $mine, $yours, &$result, &$mergeAttemptResult=null)
wfMerge attempts to merge differences between three texts.
Definition: GlobalFunctions.php:2347
wfDebugBacktrace
wfDebugBacktrace( $limit=0)
Safety wrapper for debug_backtrace().
Definition: GlobalFunctions.php:1470
wfSetVar
wfSetVar(&$dest, $source, $force=false)
Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...
Definition: GlobalFunctions.php:1687
captcha-old.count
count
Definition: captcha-old.py:249
wfGetLB
wfGetLB( $wiki=false)
Get a load balancer object.
Definition: GlobalFunctions.php:2813
wfFormatStackFrame
wfFormatStackFrame( $frame)
Return a string representation of frame.
Definition: GlobalFunctions.php:1566
$last
$last
Definition: profileinfo.php:408
wfRemoveDotSegments
wfRemoveDotSegments( $urlPath)
Remove all dot-segments in the provided URL path.
Definition: GlobalFunctions.php:649
$wgScript
$wgScript
The URL path to index.php.
Definition: DefaultSettings.php:185
wfSetBit
wfSetBit(&$dest, $bit, $state=true)
As for wfSetVar except setting a bit.
Definition: GlobalFunctions.php:1704
wfNegotiateType
wfNegotiateType( $cprefs, $sprefs)
Returns the 'best' match between a client's requested internet media types and the server's list of a...
Definition: GlobalFunctions.php:1906
wfMakeUrlIndexes
wfMakeUrlIndexes( $url)
Make URL indexes, appropriate for the el_index field of externallinks.
Definition: GlobalFunctions.php:894
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page. Return false to stop further processing of the tag $reader:XMLReader object & $pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUnknownUser':When a user doesn 't exist locally, this hook is called to give extensions an opportunity to auto-create it. If the auto-creation is successful, return false. $name:User name 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports. & $fullInterwikiPrefix:Interwiki prefix, may contain colons. & $pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable. Can be used to lazy-load the import sources list. & $importSources:The value of $wgImportSources. Modify as necessary. See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. & $title:Title object for the current page & $request:WebRequest & $ignoreRedirect:boolean to skip redirect check & $target:Title/string of redirect target & $article:Article object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) & $article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() & $ip:IP being check & $result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED! Use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language & $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED! Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language & $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Array with elements of the form "language:title" in the order that they will be output. & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LanguageSelector':Hook to change the language selector available on a page. $out:The output page. $cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED! Use HtmlPageLinkRendererBegin instead. Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1985
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1968
$wgVersion
$wgVersion
MediaWiki version number.
Definition: DefaultSettings.php:74
Wikimedia\Rdbms\DBReplicationWaitError
Exception class for replica DB wait timeouts.
Definition: DBReplicationWaitError.php:28
SiteStats\pages
static pages()
Definition: SiteStats.php:112
wfUnpack
wfUnpack( $format, $data, $length=false)
Wrapper around php's unpack.
Definition: GlobalFunctions.php:3190
wfConfiguredReadOnlyReason
wfConfiguredReadOnlyReason()
Get the value of $wgReadOnly or the contents of $wgReadOnlyFile.
Definition: GlobalFunctions.php:1274
MessageSpecifier
Definition: MessageSpecifier.php:21
$wgShowHostnames
$wgShowHostnames
Expose backend server host names through the API and various HTML comments.
Definition: DefaultSettings.php:6274
wfObjectToArray
wfObjectToArray( $objOrArray, $recursive=true)
Recursively converts the parameter (an object) to an array with the same data.
Definition: GlobalFunctions.php:261
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
wfSuppressWarnings
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
Definition: GlobalFunctions.php:1948
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:340
wfArrayDiff2_cmp
wfArrayDiff2_cmp( $a, $b)
Definition: GlobalFunctions.php:120
wfGetScriptUrl
wfGetScriptUrl()
Get the script URL.
Definition: GlobalFunctions.php:2894
$wgMessageCacheType
$wgMessageCacheType
The cache type for storing the contents of the MediaWiki namespace.
Definition: DefaultSettings.php:2258
ProfilerStub
Stub profiler that does nothing.
Definition: ProfilerStub.php:29
$wgDiff
$wgDiff
Path to the GNU diff utility.
Definition: DefaultSettings.php:6559
wfBaseName
wfBaseName( $path, $suffix='')
Return the final portion of a pathname.
Definition: GlobalFunctions.php:2567
wfQueriesMustScale
wfQueriesMustScale()
Should low-performance queries be disabled?
Definition: GlobalFunctions.php:2862
unserialize
unserialize( $serialized)
Definition: ApiMessage.php:192
$params
$params
Definition: styleTest.css.php:40
wfHostname
wfHostname()
Fetch server name for use in error reporting etc.
Definition: GlobalFunctions.php:1408
wfReadOnly
wfReadOnly()
Check whether the wiki is in read-only mode.
Definition: GlobalFunctions.php:1250
wfMsgReplaceArgs
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
Definition: GlobalFunctions.php:1381
wfUsePHP
wfUsePHP( $req_ver)
This function works like "use VERSION" in Perl, the program will die with a backtrace if the current ...
Definition: GlobalFunctions.php:2516
wfSplitWikiID
wfSplitWikiID( $wiki)
Split a wiki ID into DB name and table prefix.
Definition: GlobalFunctions.php:2767
$s
$s
Definition: mergeMessageFileList.php:187
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1138
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
wfStringToBool
wfStringToBool( $val)
Convert string value to boolean, when the following are interpreted as true:
Definition: GlobalFunctions.php:2176
wfArrayFilterByKey
wfArrayFilterByKey(array $arr, callable $callback)
Like array_filter with ARRAY_FILTER_USE_KEY, but works pre-5.6.
Definition: GlobalFunctions.php:168
$wgTransactionalTimeLimit
$wgTransactionalTimeLimit
The minimum amount of time that MediaWiki needs for "slow" write request, particularly ones with mult...
Definition: DefaultSettings.php:2214
$wgDebugLogPrefix
$wgDebugLogPrefix
Prefix for debug log lines.
Definition: DefaultSettings.php:6066
wfExpandIRI
wfExpandIRI( $url)
Take a URL, make sure it's expanded to fully qualified, and replace any encoded non-ASCII Unicode cha...
Definition: GlobalFunctions.php:871
wfMessageFallback
wfMessageFallback()
This function accepts multiple message keys and returns a message instance for the first message whic...
Definition: GlobalFunctions.php:1368
wfWaitForSlaves
wfWaitForSlaves( $ifWritesSince=null, $wiki=false, $cluster=false, $timeout=null)
Waits for the replica DBs to catch up to the master position.
Definition: GlobalFunctions.php:2954
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:1075
$wgDBprefix
$wgDBprefix
Table name prefix.
Definition: DefaultSettings.php:1850
wfShellWikiCmd
wfShellWikiCmd( $script, array $parameters=[], array $options=[])
Generate a shell-escaped command line string to run a MediaWiki cli script.
Definition: GlobalFunctions.php:2322
php
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
wfBoolToStr
wfBoolToStr( $value)
Convenience function converts boolean values into "true" or "false" (string) values.
Definition: GlobalFunctions.php:2919
wfAppendQuery
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
Definition: GlobalFunctions.php:469
key
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling but I prefer the flexibility This should also do the output encoding The system allocates a global one in $wgOut Title Represents the title of an and does all the work of translating among various forms such as plain database key
Definition: design.txt:25
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:88
$query
null for the wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1591
wfParseUrl
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
Definition: GlobalFunctions.php:801
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:51
wfGetMainCache
wfGetMainCache()
Get the main cache object.
Definition: GlobalFunctions.php:3135
MWException
MediaWiki exception.
Definition: MWException.php:26
wfStripIllegalFilenameChars
wfStripIllegalFilenameChars( $name)
Replace all invalid characters with '-'.
Definition: GlobalFunctions.php:3015
wfMemcKey
wfMemcKey()
Make a cache key for the local wiki.
Definition: GlobalFunctions.php:2700
wfGetRusage
wfGetRusage()
Get system resource usage of current request context.
Definition: GlobalFunctions.php:3436
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
mimeTypeMatch
mimeTypeMatch( $type, $avail)
Checks if a given MIME type matches any of the keys in the given array.
Definition: GlobalFunctions.php:1878
wfGlobalCacheKey
wfGlobalCacheKey()
Make a cache key with database-agnostic prefix.
Definition: GlobalFunctions.php:2738
$wgDBname
controlled by $wgMainCacheType controlled by $wgParserCacheType controlled by $wgMessageCacheType If you set CACHE_NONE to one of the three control default value for MediaWiki still create a but requests to it are no ops and we always fall through to the database If the cache daemon can t be it should also disable itself fairly smoothly By $wgMemc is used but when it is $parserMemc or $messageMemc this is mentioned $wgDBname
Definition: memcached.txt:96
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1111
wfRestoreWarnings
wfRestoreWarnings()
Definition: GlobalFunctions.php:1956
Language\fetchLanguageNames
static fetchLanguageNames( $inLanguage=null, $include='mw')
Get an array of language names, indexed by code.
Definition: Language.php:803
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2878
wfArrayDiff2
wfArrayDiff2( $a, $b)
Like array_diff( $a, $b ) except that it works with two-dimensional arrays.
Definition: GlobalFunctions.php:111
wfIncrStats
wfIncrStats( $key, $count=1)
Increment a statistics counter.
Definition: GlobalFunctions.php:1240
FileBackend\isStoragePath
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
Definition: FileBackend.php:1435
$blob
$blob
Definition: testCompression.php:65
wfTransactionalTimeLimit
wfTransactionalTimeLimit()
Set PHP's time limit to the larger of php.ini or $wgTransactionalTimeLimit.
Definition: GlobalFunctions.php:3061
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2800
wfShellExecDisabled
wfShellExecDisabled()
Check if wfShellExec() is effectively disabled via php.ini config.
Definition: GlobalFunctions.php:2210
wfUrlProtocolsWithoutProtRel
wfUrlProtocolsWithoutProtRel()
Like wfUrlProtocols(), but excludes '//' from the protocol list.
Definition: GlobalFunctions.php:772
$wgCommandLineMode
global $wgCommandLineMode
Definition: DevelopmentSettings.php:27
$matches
$matches
Definition: NoLocalSettings.php:24
$wgDebugLogGroups
$wgDebugLogGroups
Map of string log group names to log destinations.
Definition: DefaultSettings.php:6185
$wgLoadScript
$wgLoadScript
The URL path to load.php.
Definition: DefaultSettings.php:193
wfTimestampOrNull
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
Definition: GlobalFunctions.php:1984
$IP
$IP
Definition: update.php:3
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:223
ObjectCache\getInstance
static getInstance( $id)
Get a cached instance of the specified type of cache object.
Definition: ObjectCache.php:92
wfGetLangObj
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
Definition: GlobalFunctions.php:1294
wfCgiToArray
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
Definition: GlobalFunctions.php:422
$lines
$lines
Definition: router.php:61
wfLoadSkins
wfLoadSkins(array $skins)
Load multiple skins at once.
Definition: GlobalFunctions.php:97
$wgLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
Definition: design.txt:56
$wgParserCacheType
$wgParserCacheType
The cache type for storing article HTML.
Definition: DefaultSettings.php:2266
MWDebug\deprecated
static deprecated( $function, $version=false, $component=false, $callerOffset=2)
Show a warning that $function is deprecated.
Definition: MWDebug.php:193
wfGetCache
wfGetCache( $cacheType)
Get a specific cache object.
Definition: GlobalFunctions.php:3126
$wgEnableMagicLinks
$wgEnableMagicLinks
Enable the magic links feature of automatically turning ISBN xxx, PMID xxx, RFC xxx into links.
Definition: DefaultSettings.php:4402
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
$output
$output
Definition: SyntaxHighlight.php:338
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1997
wfMemoryLimit
wfMemoryLimit()
Set PHP's memory limit to the larger of php.ini or $wgMemoryLimit.
Definition: GlobalFunctions.php:3033
wfForeignMemcKey
wfForeignMemcKey( $db, $prefix)
Make a cache key for a foreign DB.
Definition: GlobalFunctions.php:2717
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:982
wfAcceptToPrefs
wfAcceptToPrefs( $accept, $def=' */*')
Converts an Accept-* header into an array mapping string values to quality factors.
Definition: GlobalFunctions.php:1842
list
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
wfExpandIRI_callback
wfExpandIRI_callback( $matches)
Private callback for wfExpandIRI.
Definition: GlobalFunctions.php:884
PROTO_HTTPS
const PROTO_HTTPS
Definition: Defines.php:221
$wgCanonicalServer
$wgCanonicalServer
Canonical URL of the server, to use in IRC feeds and notification e-mails.
Definition: DefaultSettings.php:114
$wgMemoryLimit
$wgMemoryLimit
The minimum amount of memory that MediaWiki "needs"; MediaWiki will try to raise PHP's memory limit i...
Definition: DefaultSettings.php:2206
wfIsDebugRawPage
wfIsDebugRawPage()
Returns true if debug logging should be suppressed if $wgDebugRawPage = false.
Definition: GlobalFunctions.php:1016
UnifiedDiffFormatter
A formatter that outputs unified diffs.
Definition: UnifiedDiffFormatter.php:31
$request
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 $request
Definition: hooks.txt:2604
$wgDebugTimestamps
$wgDebugTimestamps
Prefix debug messages with relative timestamp.
Definition: DefaultSettings.php:6223
wfErrorLog
wfErrorLog( $text, $file, array $context=[])
Log to a file without getting "file size exceeded" signals.
Definition: GlobalFunctions.php:1155
wfUrlProtocols
wfUrlProtocols( $includeProtocolRelative=true)
Returns a regular expression of url protocols.
Definition: GlobalFunctions.php:727
$line
$line
Definition: cdb.php:59
wfIsBadImage
wfIsBadImage( $name, $contextTitle=false, $blacklist=null)
Determine if an image exists on the 'bad image list'.
Definition: GlobalFunctions.php:3226
wfLoadExtensions
wfLoadExtensions(array $exts)
Load multiple extensions at once.
Definition: GlobalFunctions.php:66
wfWikiID
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Definition: GlobalFunctions.php:2751
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2163
wfClearOutputBuffers
wfClearOutputBuffers()
More legible than passing a 'false' parameter to wfResetOutputBuffers():
Definition: GlobalFunctions.php:1830
$value
$value
Definition: styleTest.css.php:45
wfClientAcceptsGzip
wfClientAcceptsGzip( $force=false)
Whether the client accept gzip encoding.
Definition: GlobalFunctions.php:1597
$wgUrlProtocols
$wgUrlProtocols
URL schemes that should be recognized as valid by wfParseUrl().
Definition: DefaultSettings.php:4199
$wgExtensionDirectory
$wgExtensionDirectory
Filesystem extensions directory.
Definition: DefaultSettings.php:222
wfIsCLI
wfIsCLI()
Check if we are running from the commandline.
Definition: GlobalFunctions.php:2030
$retval
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account incomplete not yet checked for validity & $retval
Definition: hooks.txt:244
wfIsWindows
wfIsWindows()
Check if the operating system is Windows.
Definition: GlobalFunctions.php:2007
$wgServer
$wgServer
URL of the server.
Definition: DefaultSettings.php:105
wfEscapeShellArg
wfEscapeShellArg()
Version of escapeshellarg() that works better on Windows.
Definition: GlobalFunctions.php:2197
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:50
$wgLanguageCode
$wgLanguageCode
Site language code.
Definition: DefaultSettings.php:2866
wfIsInfinity
wfIsInfinity( $str)
Determine input string is represents as infinity.
Definition: GlobalFunctions.php:3309
wfDebugMem
wfDebugMem( $exact=false)
Send a line giving PHP memory usage.
Definition: GlobalFunctions.php:1040
wfInitShellLocale
wfInitShellLocale()
Formerly set the locale for locale-sensitive operations.
Definition: GlobalFunctions.php:2304
PROTO_HTTP
const PROTO_HTTP
Definition: Defines.php:220
$wgDirectoryMode
$wgDirectoryMode
Default value for chmoding of new directories.
Definition: DefaultSettings.php:1487
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1631
Skin\makeVariablesScript
static makeVariablesScript( $data)
Definition: Skin.php:382
$ret
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 & $ret
Definition: hooks.txt:1987
wfAppendToArrayIfNotDefault
wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed)
Appends to second array if $value differs from that in $default.
Definition: GlobalFunctions.php:183
$wgDisableOutputCompression
$wgDisableOutputCompression
Disable output compression (enabled by default if zlib is available)
Definition: DefaultSettings.php:3353
wfVarDump
wfVarDump( $var)
A wrapper around the PHP function var_export().
Definition: GlobalFunctions.php:1722
$wgIllegalFileChars
$wgIllegalFileChars
Additional characters that are not allowed in filenames.
Definition: DefaultSettings.php:411
wfGetParserCacheStorage
wfGetParserCacheStorage()
Get the cache object used by the parser cache.
Definition: GlobalFunctions.php:3156
wfGetNull
wfGetNull()
Get a platform-independent path to the null file, e.g.
Definition: GlobalFunctions.php:2928
TempFSFile\getUsableTempDirectory
static getUsableTempDirectory()
Definition: TempFSFile.php:85
$handler
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub 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 modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check set to true or false to override the $wgMaxImageArea check result gives extension the possibility to transform it themselves $handler
Definition: hooks.txt:783
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:434
wfGetLBFactory
wfGetLBFactory()
Get the load balancer factory object.
Definition: GlobalFunctions.php:2829
wfIniGetBool
wfIniGetBool( $setting)
Safety wrapper around ini_get() for boolean settings.
Definition: GlobalFunctions.php:2160
$wgOverrideHostname
$wgOverrideHostname
Override server hostname detection with a hardcoded value.
Definition: DefaultSettings.php:6281
wfFindFile
wfFindFile( $title, $options=[])
Find a file.
Definition: GlobalFunctions.php:2841
wfReportTime
wfReportTime()
Returns a script tag that stores the amount of time it took MediaWiki to handle the request in millis...
Definition: GlobalFunctions.php:1447
wfGetAllCallers
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
Definition: GlobalFunctions.php:1551
wfLoadExtension
wfLoadExtension( $ext, $path=null)
Load an extension.
Definition: GlobalFunctions.php:45
wfRunHooks
wfRunHooks( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:3171
wfGetMessageCacheStorage
wfGetMessageCacheStorage()
Get the cache object used by the message cache.
Definition: GlobalFunctions.php:3145
$args
if( $line===false) $args
Definition: cdb.php:64
wfLoadSkin
wfLoadSkin( $skin, $path=null)
Load a skin.
Definition: GlobalFunctions.php:82
wfShorthandToInteger
wfShorthandToInteger( $string='', $default=-1)
Converts shorthand byte notation to integer form.
Definition: GlobalFunctions.php:3082
$wgImageLimits
$wgImageLimits
Limit images on image description pages to a user-selectable limit.
Definition: DefaultSettings.php:1363
wfRandom
wfRandom()
Get a random decimal value between 0 and 1, in a way not likely to give duplicate values for any real...
Definition: GlobalFunctions.php:287
wfTempDir
wfTempDir()
Tries to get the system directory for temporary files.
Definition: GlobalFunctions.php:2045
$wgMiserMode
$wgMiserMode
Disable database-intensive features.
Definition: DefaultSettings.php:2170
wfHttpError
wfHttpError( $code, $label, $desc)
Provide a simple HTTP error.
Definition: GlobalFunctions.php:1739
wfReadOnlyReason
wfReadOnlyReason()
Check if the site is in read-only mode and return the message if so.
Definition: GlobalFunctions.php:1263
wfMatchesDomainList
wfMatchesDomainList( $url, $domains)
Check whether a given URL has a domain that occurs in a given set of domains.
Definition: GlobalFunctions.php:948
$cache
$cache
Definition: mcc.php:33
HttpStatus\header
static header( $code)
Output an HTTP status code header.
Definition: HttpStatus.php:96
$options
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 & $options
Definition: hooks.txt:1987
$code
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub 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 modifiable & $code
Definition: hooks.txt:783
wfGetPrecompiledData
wfGetPrecompiledData( $name)
Get an object from the precompiled serialized directory.
Definition: GlobalFunctions.php:2680
wfRecursiveRemoveDir
wfRecursiveRemoveDir( $dir)
Remove a directory and all its content.
Definition: GlobalFunctions.php:2107
$wgHttpsPort
$wgHttpsPort
Port where you have HTTPS running Supports HTTPS on non-standard ports.
Definition: DefaultSettings.php:8565
$path
$path
Definition: NoLocalSettings.php:25
$wgMainCacheType
CACHE_MEMCACHED $wgMainCacheType
Definition: memcached.txt:63
as
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
LanguageCode\bcp47
static bcp47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: LanguageCode.php:94
$skin
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 an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned $skin
Definition: hooks.txt:1987
$keys
$keys
Definition: testCompression.php:67
wfBacktrace
wfBacktrace( $raw=null)
Get a debug backtrace as a string.
Definition: GlobalFunctions.php:1498
LoggerFactory
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
$source
$source
Definition: mwdoc-filter.php:46
wfAssembleUrl
wfAssembleUrl( $urlParts)
This function will reassemble a URL parsed with wfParseURL.
Definition: GlobalFunctions.php:597
wfRelativePath
wfRelativePath( $path, $from)
Generate a relative path name to the given file.
Definition: GlobalFunctions.php:2591
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:183
$status
Status::newGood()` to allow deletion, and then `return false` from the hook function. Ensure you consume the 'ChangeTagAfterDelete' hook to carry out custom deletion actions. $tag:name of the tag $user:user initiating the action & $status:Status object. See above. 'ChangeTagsListActive':Allows you to nominate which of the tags your extension uses are in active use. & $tags:list of all active tags. Append to this array. 'ChangeTagsAfterUpdateTags':Called after tags have been updated with the ChangeTags::updateTags function. Params:$addedTags:tags effectively added in the update $removedTags:tags effectively removed in the update $prevTags:tags that were present prior to the update $rc_id:recentchanges table id $rev_id:revision table id $log_id:logging table id $params:tag params $rc:RecentChange being tagged when the tagging accompanies the action or null $user:User who performed the tagging when the tagging is subsequent to the action or null 'ChangeTagsAllowedAdd':Called when checking if a user can add tags to a change. & $allowedTags:List of all the tags the user is allowed to add. Any tags the user wants to add( $addTags) that are not in this array will cause it to fail. You may add or remove tags to this array as required. $addTags:List of tags user intends to add. $user:User who is adding the tags. 'ChangeUserGroups':Called before user groups are changed. $performer:The User who will perform the change $user:The User whose groups will be changed & $add:The groups that will be added & $remove:The groups that will be removed 'Collation::factory':Called if $wgCategoryCollation is an unknown collation. $collationName:Name of the collation in question & $collationObject:Null. Replace with a subclass of the Collation class that implements the collation given in $collationName. 'ConfirmEmailComplete':Called after a user 's email has been confirmed successfully. $user:user(object) whose email is being confirmed 'ContentAlterParserOutput':Modify parser output for a given content object. Called by Content::getParserOutput after parsing has finished. Can be used for changes that depend on the result of the parsing but have to be done before LinksUpdate is called(such as adding tracking categories based on the rendered HTML). $content:The Content to render $title:Title of the page, as context $parserOutput:ParserOutput to manipulate 'ContentGetParserOutput':Customize parser output for a given content object, called by AbstractContent::getParserOutput. May be used to override the normal model-specific rendering of page content. $content:The Content to render $title:Title of the page, as context $revId:The revision ID, as context $options:ParserOptions for rendering. To avoid confusing the parser cache, the output can only depend on parameters provided to this hook function, not on global state. $generateHtml:boolean, indicating whether full HTML should be generated. If false, generation of HTML may be skipped, but other information should still be present in the ParserOutput object. & $output:ParserOutput, to manipulate or replace 'ContentHandlerDefaultModelFor':Called when the default content model is determined for a given title. May be used to assign a different model for that title. $title:the Title in question & $model:the model name. Use with CONTENT_MODEL_XXX constants. 'ContentHandlerForModelID':Called when a ContentHandler is requested for a given content model name, but no entry for that model exists in $wgContentHandlers. Note:if your extension implements additional models via this hook, please use GetContentModels hook to make them known to core. $modeName:the requested content model name & $handler:set this to a ContentHandler object, if desired. 'ContentModelCanBeUsedOn':Called to determine whether that content model can be used on a given page. This is especially useful to prevent some content models to be used in some special location. $contentModel:ID of the content model in question $title:the Title in question. & $ok:Output parameter, whether it is OK to use $contentModel on $title. Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok. 'ContribsPager::getQueryInfo':Before the contributions query is about to run & $pager:Pager object for contributions & $queryInfo:The query for the contribs Pager 'ContribsPager::reallyDoQuery':Called before really executing the query for My Contributions & $data:an array of results of all contribs queries $pager:The ContribsPager object hooked into $offset:Index offset, inclusive $limit:Exact query limit $descending:Query direction, false for ascending, true for descending 'ContributionsLineEnding':Called before a contributions HTML line is finished $page:SpecialPage object for contributions & $ret:the HTML line $row:the DB row for this line & $classes:the classes to add to the surrounding< li > & $attribs:associative array of other HTML attributes for the< li > element. Currently only data attributes reserved to MediaWiki are allowed(see Sanitizer::isReservedDataAttribute). 'ContributionsToolLinks':Change tool links above Special:Contributions $id:User identifier $title:User page title & $tools:Array of tool links $specialPage:SpecialPage instance for context and services. Can be either SpecialContributions or DeletedContributionsPage. Extensions should type hint against a generic SpecialPage though. 'ConvertContent':Called by AbstractContent::convert when a conversion to another content model is requested. Handler functions that modify $result should generally return false to disable further attempts at conversion. $content:The Content object to be converted. $toModel:The ID of the content model to convert to. $lossy:boolean indicating whether lossy conversion is allowed. & $result:Output parameter, in case the handler function wants to provide a converted Content object. Note that $result->getContentModel() must return $toModel. 'CustomEditor':When invoking the page editor Return true to allow the normal editor to be used, or false if implementing a custom editor, e.g. for a special namespace, etc. $article:Article being edited $user:User performing the edit 'DatabaseOraclePostInit':Called after initialising an Oracle database $db:the DatabaseOracle object 'DeletedContribsPager::reallyDoQuery':Called before really executing the query for Special:DeletedContributions Similar to ContribsPager::reallyDoQuery & $data:an array of results of all contribs queries $pager:The DeletedContribsPager object hooked into $offset:Index offset, inclusive $limit:Exact query limit $descending:Query direction, false for ascending, true for descending 'DeletedContributionsLineEnding':Called before a DeletedContributions HTML line is finished. Similar to ContributionsLineEnding $page:SpecialPage object for DeletedContributions & $ret:the HTML line $row:the DB row for this line & $classes:the classes to add to the surrounding< li > & $attribs:associative array of other HTML attributes for the< li > element. Currently only data attributes reserved to MediaWiki are allowed(see Sanitizer::isReservedDataAttribute). 'DeleteUnknownPreferences':Called by the cleanupPreferences.php maintenance script to build a WHERE clause with which to delete preferences that are not known about. This hook is used by extensions that have dynamically-named preferences that should not be deleted in the usual cleanup process. For example, the Gadgets extension creates preferences prefixed with 'gadget-', and so anything with that prefix is excluded from the deletion. &where:An array that will be passed as the $cond parameter to IDatabase::select() to determine what will be deleted from the user_properties table. $db:The IDatabase object, useful for accessing $db->buildLike() etc. 'DifferenceEngineAfterLoadNewText':called in DifferenceEngine::loadNewText() after the new revision 's content has been loaded into the class member variable $differenceEngine->mNewContent but before returning true from this function. $differenceEngine:DifferenceEngine object 'DifferenceEngineLoadTextAfterNewContentIsLoaded':called in DifferenceEngine::loadText() after the new revision 's content has been loaded into the class member variable $differenceEngine->mNewContent but before checking if the variable 's value is null. This hook can be used to inject content into said class member variable. $differenceEngine:DifferenceEngine object 'DifferenceEngineMarkPatrolledLink':Allows extensions to change the "mark as patrolled" link which is shown both on the diff header as well as on the bottom of a page, usually wrapped in a span element which has class="patrollink". $differenceEngine:DifferenceEngine object & $markAsPatrolledLink:The "mark as patrolled" link HTML(string) $rcid:Recent change ID(rc_id) for this change(int) 'DifferenceEngineMarkPatrolledRCID':Allows extensions to possibly change the rcid parameter. For example the rcid might be set to zero due to the user being the same as the performer of the change but an extension might still want to show it under certain conditions. & $rcid:rc_id(int) of the change or 0 $differenceEngine:DifferenceEngine object $change:RecentChange object $user:User object representing the current user 'DifferenceEngineNewHeader':Allows extensions to change the $newHeader variable, which contains information about the new revision, such as the revision 's author, whether the revision was marked as a minor edit or not, etc. $differenceEngine:DifferenceEngine object & $newHeader:The string containing the various #mw-diff-otitle[1-5] divs, which include things like revision author info, revision comment, RevisionDelete link and more $formattedRevisionTools:Array containing revision tools, some of which may have been injected with the DiffRevisionTools hook $nextlink:String containing the link to the next revision(if any) $status
Definition: hooks.txt:1255
wfWarn
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
Definition: GlobalFunctions.php:1125
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
Title\legalChars
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:623
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:737
MediaWikiServices
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
MWDebug\warning
static warning( $msg, $callerOffset=1, $level=E_USER_NOTICE, $log='auto')
Adds a warning entry to the log.
Definition: MWDebug.php:151
File\getHandler
getHandler()
Get a MediaHandler instance for this file.
Definition: File.php:1383
$wgOut
$wgOut
Definition: Setup.php:904
wfIsHHVM
wfIsHHVM()
Check if we are running under HHVM.
Definition: GlobalFunctions.php:2020
$wgScriptPath
$wgScriptPath
The path we should point to.
Definition: DefaultSettings.php:137
wfLocalFile
wfLocalFile( $title)
Get an object referring to a locally registered file.
Definition: GlobalFunctions.php:2852
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
$ext
$ext
Definition: router.php:55
wfShowingResults
wfShowingResults( $offset, $limit)
Definition: GlobalFunctions.php:1584
wfResetSessionID
wfResetSessionID()
Reset the session id.
Definition: GlobalFunctions.php:2633
wfGetCaller
wfGetCaller( $level=2)
Get the name of the function which called this function wfGetCaller( 1 ) is the function with the wfG...
Definition: GlobalFunctions.php:1535
$wgStyleDirectory
$wgStyleDirectory
Filesystem stylesheets directory.
Definition: DefaultSettings.php:229
wfLogDBError
wfLogDBError( $text, array $context=[])
Log for database errors.
Definition: GlobalFunctions.php:1093
SiteStats\edits
static edits()
Definition: SiteStats.php:94
$wgInternalServer
$wgInternalServer
Internal server name as known to CDN, if different.
Definition: DefaultSettings.php:2692
wfCountDown
wfCountDown( $seconds)
Count down from $seconds to zero on the terminal, with a one-second pause between showing each number...
Definition: GlobalFunctions.php:2993
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:521
array
the array() calling protocol came about after MediaWiki 1.4rc1.
wfShellExecWithStderr
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
Definition: GlobalFunctions.php:2291
MediaWiki\HeaderCallback\warnIfHeadersSent
static warnIfHeadersSent()
Log a warning message if headers have already been sent.
Definition: HeaderCallback.php:57
wfLogProfilingData
wfLogProfilingData()
Definition: GlobalFunctions.php:1166
ObjectCache\getLocalServerInstance
static getLocalServerInstance( $fallback=CACHE_NONE)
Factory function for CACHE_ACCEL (referenced from DefaultSettings.php)
Definition: ObjectCache.php:288
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
Diff
Class representing a 'diff' between two sequences of strings.
Definition: DairikiDiff.php:200
wfShellExec
wfShellExec( $cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
Definition: GlobalFunctions.php:2238
wfArrayToCgi
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
Definition: GlobalFunctions.php:377
wfRandomString
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
Definition: GlobalFunctions.php:305
$out
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub 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:783
$type
$type
Definition: testCompression.php:48