MediaWiki  1.33.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;
33 use Wikimedia\WrappedString;
34 
45 function wfLoadExtension( $ext, $path = null ) {
46  if ( !$path ) {
47  global $wgExtensionDirectory;
48  $path = "$wgExtensionDirectory/$ext/extension.json";
49  }
51 }
52 
66 function wfLoadExtensions( array $exts ) {
67  global $wgExtensionDirectory;
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 ) {
84  global $wgStyleDirectory;
85  $path = "$wgStyleDirectory/$skin/skin.json";
86  }
88 }
89 
97 function wfLoadSkins( array $skins ) {
98  global $wgStyleDirectory;
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 );
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  wfDeprecated( __FUNCTION__, '1.32' );
152  return array_filter( $arr, $callback, ARRAY_FILTER_USE_BOTH );
153 }
154 
163 function wfArrayFilterByKey( array $arr, callable $callback ) {
164  wfDeprecated( __FUNCTION__, '1.32' );
165  return array_filter( $arr, $callback, ARRAY_FILTER_USE_KEY );
166 }
167 
177 function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
178  if ( is_null( $changed ) ) {
179  throw new MWException( 'GlobalFunctions::wfAppendToArrayIfNotDefault got null' );
180  }
181  if ( $default[$key] !== $value ) {
182  $changed[$key] = $value;
183  }
184 }
185 
205 function wfMergeErrorArrays( ...$args ) {
206  $out = [];
207  foreach ( $args as $errors ) {
208  foreach ( $errors as $params ) {
209  $originalParams = $params;
210  if ( $params[0] instanceof MessageSpecifier ) {
211  $msg = $params[0];
212  $params = array_merge( [ $msg->getKey() ], $msg->getParams() );
213  }
214  # @todo FIXME: Sometimes get nested arrays for $params,
215  # which leads to E_NOTICEs
216  $spec = implode( "\t", $params );
217  $out[$spec] = $originalParams;
218  }
219  }
220  return array_values( $out );
221 }
222 
231 function wfArrayInsertAfter( array $array, array $insert, $after ) {
232  // Find the offset of the element to insert after.
233  $keys = array_keys( $array );
234  $offsetByKey = array_flip( $keys );
235 
236  $offset = $offsetByKey[$after];
237 
238  // Insert at the specified offset
239  $before = array_slice( $array, 0, $offset + 1, true );
240  $after = array_slice( $array, $offset + 1, count( $array ) - $offset, true );
241 
242  $output = $before + $insert + $after;
243 
244  return $output;
245 }
246 
254 function wfObjectToArray( $objOrArray, $recursive = true ) {
255  $array = [];
256  if ( is_object( $objOrArray ) ) {
257  $objOrArray = get_object_vars( $objOrArray );
258  }
259  foreach ( $objOrArray as $key => $value ) {
260  if ( $recursive && ( is_object( $value ) || is_array( $value ) ) ) {
262  }
263 
264  $array[$key] = $value;
265  }
266 
267  return $array;
268 }
269 
280 function wfRandom() {
281  // The maximum random value is "only" 2^31-1, so get two random
282  // values to reduce the chance of dupes
283  $max = mt_getrandmax() + 1;
284  $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12, '.', '' );
285  return $rand;
286 }
287 
298 function wfRandomString( $length = 32 ) {
299  $str = '';
300  for ( $n = 0; $n < $length; $n += 7 ) {
301  $str .= sprintf( '%07x', mt_rand() & 0xfffffff );
302  }
303  return substr( $str, 0, $length );
304 }
305 
333 function wfUrlencode( $s ) {
334  static $needle;
335 
336  if ( is_null( $s ) ) {
337  // Reset $needle for testing.
338  $needle = null;
339  return '';
340  }
341 
342  if ( is_null( $needle ) ) {
343  $needle = [ '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F', '%7E' ];
344  if ( !isset( $_SERVER['SERVER_SOFTWARE'] ) ||
345  ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7' ) === false )
346  ) {
347  $needle[] = '%3A';
348  }
349  }
350 
351  $s = urlencode( $s );
352  $s = str_ireplace(
353  $needle,
354  [ ';', '@', '$', '!', '*', '(', ')', ',', '/', '~', ':' ],
355  $s
356  );
357 
358  return $s;
359 }
360 
371 function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) {
372  if ( !is_null( $array2 ) ) {
373  $array1 = $array1 + $array2;
374  }
375 
376  $cgi = '';
377  foreach ( $array1 as $key => $value ) {
378  if ( !is_null( $value ) && $value !== false ) {
379  if ( $cgi != '' ) {
380  $cgi .= '&';
381  }
382  if ( $prefix !== '' ) {
383  $key = $prefix . "[$key]";
384  }
385  if ( is_array( $value ) ) {
386  $firstTime = true;
387  foreach ( $value as $k => $v ) {
388  $cgi .= $firstTime ? '' : '&';
389  if ( is_array( $v ) ) {
390  $cgi .= wfArrayToCgi( $v, null, $key . "[$k]" );
391  } else {
392  $cgi .= urlencode( $key . "[$k]" ) . '=' . urlencode( $v );
393  }
394  $firstTime = false;
395  }
396  } else {
397  if ( is_object( $value ) ) {
398  $value = $value->__toString();
399  }
400  $cgi .= urlencode( $key ) . '=' . urlencode( $value );
401  }
402  }
403  }
404  return $cgi;
405 }
406 
416 function wfCgiToArray( $query ) {
417  if ( isset( $query[0] ) && $query[0] == '?' ) {
418  $query = substr( $query, 1 );
419  }
420  $bits = explode( '&', $query );
421  $ret = [];
422  foreach ( $bits as $bit ) {
423  if ( $bit === '' ) {
424  continue;
425  }
426  if ( strpos( $bit, '=' ) === false ) {
427  // Pieces like &qwerty become 'qwerty' => '' (at least this is what php does)
428  $key = $bit;
429  $value = '';
430  } else {
431  list( $key, $value ) = explode( '=', $bit );
432  }
433  $key = urldecode( $key );
434  $value = urldecode( $value );
435  if ( strpos( $key, '[' ) !== false ) {
436  $keys = array_reverse( explode( '[', $key ) );
437  $key = array_pop( $keys );
438  $temp = $value;
439  foreach ( $keys as $k ) {
440  $k = substr( $k, 0, -1 );
441  $temp = [ $k => $temp ];
442  }
443  if ( isset( $ret[$key] ) ) {
444  $ret[$key] = array_merge( $ret[$key], $temp );
445  } else {
446  $ret[$key] = $temp;
447  }
448  } else {
449  $ret[$key] = $value;
450  }
451  }
452  return $ret;
453 }
454 
463 function wfAppendQuery( $url, $query ) {
464  if ( is_array( $query ) ) {
466  }
467  if ( $query != '' ) {
468  // Remove the fragment, if there is one
469  $fragment = false;
470  $hashPos = strpos( $url, '#' );
471  if ( $hashPos !== false ) {
472  $fragment = substr( $url, $hashPos );
473  $url = substr( $url, 0, $hashPos );
474  }
475 
476  // Add parameter
477  if ( strpos( $url, '?' ) === false ) {
478  $url .= '?';
479  } else {
480  $url .= '&';
481  }
482  $url .= $query;
483 
484  // Put the fragment back
485  if ( $fragment !== false ) {
486  $url .= $fragment;
487  }
488  }
489  return $url;
490 }
491 
515 function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
517  $wgHttpsPort;
518  if ( $defaultProto === PROTO_CANONICAL ) {
519  $serverUrl = $wgCanonicalServer;
520  } elseif ( $defaultProto === PROTO_INTERNAL && $wgInternalServer !== false ) {
521  // Make $wgInternalServer fall back to $wgServer if not set
522  $serverUrl = $wgInternalServer;
523  } else {
524  $serverUrl = $wgServer;
525  if ( $defaultProto === PROTO_CURRENT ) {
526  $defaultProto = $wgRequest->getProtocol() . '://';
527  }
528  }
529 
530  // Analyze $serverUrl to obtain its protocol
531  $bits = wfParseUrl( $serverUrl );
532  $serverHasProto = $bits && $bits['scheme'] != '';
533 
534  if ( $defaultProto === PROTO_CANONICAL || $defaultProto === PROTO_INTERNAL ) {
535  if ( $serverHasProto ) {
536  $defaultProto = $bits['scheme'] . '://';
537  } else {
538  // $wgCanonicalServer or $wgInternalServer doesn't have a protocol.
539  // This really isn't supposed to happen. Fall back to HTTP in this
540  // ridiculous case.
541  $defaultProto = PROTO_HTTP;
542  }
543  }
544 
545  $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
546 
547  if ( substr( $url, 0, 2 ) == '//' ) {
548  $url = $defaultProtoWithoutSlashes . $url;
549  } elseif ( substr( $url, 0, 1 ) == '/' ) {
550  // If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes,
551  // otherwise leave it alone.
552  if ( $serverHasProto ) {
553  $url = $serverUrl . $url;
554  } else {
555  // If an HTTPS URL is synthesized from a protocol-relative $wgServer, allow the
556  // user to override the port number (T67184)
557  if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
558  if ( isset( $bits['port'] ) ) {
559  throw new Exception( 'A protocol-relative $wgServer may not contain a port number' );
560  }
561  $url = $defaultProtoWithoutSlashes . $serverUrl . ':' . $wgHttpsPort . $url;
562  } else {
563  $url = $defaultProtoWithoutSlashes . $serverUrl . $url;
564  }
565  }
566  }
567 
568  $bits = wfParseUrl( $url );
569 
570  if ( $bits && isset( $bits['path'] ) ) {
571  $bits['path'] = wfRemoveDotSegments( $bits['path'] );
572  return wfAssembleUrl( $bits );
573  } elseif ( $bits ) {
574  # No path to expand
575  return $url;
576  } elseif ( substr( $url, 0, 1 ) != '/' ) {
577  # URL is a relative path
578  return wfRemoveDotSegments( $url );
579  }
580 
581  # Expanded URL is not valid.
582  return false;
583 }
584 
593 function wfGetServerUrl( $proto ) {
594  $url = wfExpandUrl( '/', $proto );
595  return substr( $url, 0, -1 );
596 }
597 
611 function wfAssembleUrl( $urlParts ) {
612  $result = '';
613 
614  if ( isset( $urlParts['delimiter'] ) ) {
615  if ( isset( $urlParts['scheme'] ) ) {
616  $result .= $urlParts['scheme'];
617  }
618 
619  $result .= $urlParts['delimiter'];
620  }
621 
622  if ( isset( $urlParts['host'] ) ) {
623  if ( isset( $urlParts['user'] ) ) {
624  $result .= $urlParts['user'];
625  if ( isset( $urlParts['pass'] ) ) {
626  $result .= ':' . $urlParts['pass'];
627  }
628  $result .= '@';
629  }
630 
631  $result .= $urlParts['host'];
632 
633  if ( isset( $urlParts['port'] ) ) {
634  $result .= ':' . $urlParts['port'];
635  }
636  }
637 
638  if ( isset( $urlParts['path'] ) ) {
639  $result .= $urlParts['path'];
640  }
641 
642  if ( isset( $urlParts['query'] ) ) {
643  $result .= '?' . $urlParts['query'];
644  }
645 
646  if ( isset( $urlParts['fragment'] ) ) {
647  $result .= '#' . $urlParts['fragment'];
648  }
649 
650  return $result;
651 }
652 
665 function wfRemoveDotSegments( $urlPath ) {
666  $output = '';
667  $inputOffset = 0;
668  $inputLength = strlen( $urlPath );
669 
670  while ( $inputOffset < $inputLength ) {
671  $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
672  $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
673  $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
674  $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
675  $trimOutput = false;
676 
677  if ( $prefixLengthTwo == './' ) {
678  # Step A, remove leading "./"
679  $inputOffset += 2;
680  } elseif ( $prefixLengthThree == '../' ) {
681  # Step A, remove leading "../"
682  $inputOffset += 3;
683  } elseif ( ( $prefixLengthTwo == '/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
684  # Step B, replace leading "/.$" with "/"
685  $inputOffset += 1;
686  $urlPath[$inputOffset] = '/';
687  } elseif ( $prefixLengthThree == '/./' ) {
688  # Step B, replace leading "/./" with "/"
689  $inputOffset += 2;
690  } elseif ( $prefixLengthThree == '/..' && ( $inputOffset + 3 == $inputLength ) ) {
691  # Step C, replace leading "/..$" with "/" and
692  # remove last path component in output
693  $inputOffset += 2;
694  $urlPath[$inputOffset] = '/';
695  $trimOutput = true;
696  } elseif ( $prefixLengthFour == '/../' ) {
697  # Step C, replace leading "/../" with "/" and
698  # remove last path component in output
699  $inputOffset += 3;
700  $trimOutput = true;
701  } elseif ( ( $prefixLengthOne == '.' ) && ( $inputOffset + 1 == $inputLength ) ) {
702  # Step D, remove "^.$"
703  $inputOffset += 1;
704  } elseif ( ( $prefixLengthTwo == '..' ) && ( $inputOffset + 2 == $inputLength ) ) {
705  # Step D, remove "^..$"
706  $inputOffset += 2;
707  } else {
708  # Step E, move leading path segment to output
709  if ( $prefixLengthOne == '/' ) {
710  $slashPos = strpos( $urlPath, '/', $inputOffset + 1 );
711  } else {
712  $slashPos = strpos( $urlPath, '/', $inputOffset );
713  }
714  if ( $slashPos === false ) {
715  $output .= substr( $urlPath, $inputOffset );
716  $inputOffset = $inputLength;
717  } else {
718  $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
719  $inputOffset += $slashPos - $inputOffset;
720  }
721  }
722 
723  if ( $trimOutput ) {
724  $slashPos = strrpos( $output, '/' );
725  if ( $slashPos === false ) {
726  $output = '';
727  } else {
728  $output = substr( $output, 0, $slashPos );
729  }
730  }
731  }
732 
733  return $output;
734 }
735 
743 function wfUrlProtocols( $includeProtocolRelative = true ) {
744  global $wgUrlProtocols;
745 
746  // Cache return values separately based on $includeProtocolRelative
747  static $withProtRel = null, $withoutProtRel = null;
748  $cachedValue = $includeProtocolRelative ? $withProtRel : $withoutProtRel;
749  if ( !is_null( $cachedValue ) ) {
750  return $cachedValue;
751  }
752 
753  // Support old-style $wgUrlProtocols strings, for backwards compatibility
754  // with LocalSettings files from 1.5
755  if ( is_array( $wgUrlProtocols ) ) {
756  $protocols = [];
757  foreach ( $wgUrlProtocols as $protocol ) {
758  // Filter out '//' if !$includeProtocolRelative
759  if ( $includeProtocolRelative || $protocol !== '//' ) {
760  $protocols[] = preg_quote( $protocol, '/' );
761  }
762  }
763 
764  $retval = implode( '|', $protocols );
765  } else {
766  // Ignore $includeProtocolRelative in this case
767  // This case exists for pre-1.6 compatibility, and we can safely assume
768  // that '//' won't appear in a pre-1.6 config because protocol-relative
769  // URLs weren't supported until 1.18
770  $retval = $wgUrlProtocols;
771  }
772 
773  // Cache return value
774  if ( $includeProtocolRelative ) {
775  $withProtRel = $retval;
776  } else {
777  $withoutProtRel = $retval;
778  }
779  return $retval;
780 }
781 
789  return wfUrlProtocols( false );
790 }
791 
817 function wfParseUrl( $url ) {
818  global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
819 
820  // Protocol-relative URLs are handled really badly by parse_url(). It's so
821  // bad that the easiest way to handle them is to just prepend 'http:' and
822  // strip the protocol out later.
823  $wasRelative = substr( $url, 0, 2 ) == '//';
824  if ( $wasRelative ) {
825  $url = "http:$url";
826  }
827  Wikimedia\suppressWarnings();
828  $bits = parse_url( $url );
829  Wikimedia\restoreWarnings();
830  // parse_url() returns an array without scheme for some invalid URLs, e.g.
831  // parse_url("%0Ahttp://example.com") == [ 'host' => '%0Ahttp', 'path' => 'example.com' ]
832  if ( !$bits || !isset( $bits['scheme'] ) ) {
833  return false;
834  }
835 
836  // parse_url() incorrectly handles schemes case-sensitively. Convert it to lowercase.
837  $bits['scheme'] = strtolower( $bits['scheme'] );
838 
839  // most of the protocols are followed by ://, but mailto: and sometimes news: not, check for it
840  if ( in_array( $bits['scheme'] . '://', $wgUrlProtocols ) ) {
841  $bits['delimiter'] = '://';
842  } elseif ( in_array( $bits['scheme'] . ':', $wgUrlProtocols ) ) {
843  $bits['delimiter'] = ':';
844  // parse_url detects for news: and mailto: the host part of an url as path
845  // We have to correct this wrong detection
846  if ( isset( $bits['path'] ) ) {
847  $bits['host'] = $bits['path'];
848  $bits['path'] = '';
849  }
850  } else {
851  return false;
852  }
853 
854  /* Provide an empty host for eg. file:/// urls (see T30627) */
855  if ( !isset( $bits['host'] ) ) {
856  $bits['host'] = '';
857 
858  // See T47069
859  if ( isset( $bits['path'] ) ) {
860  /* parse_url loses the third / for file:///c:/ urls (but not on variants) */
861  if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
862  $bits['path'] = '/' . $bits['path'];
863  }
864  } else {
865  $bits['path'] = '';
866  }
867  }
868 
869  // If the URL was protocol-relative, fix scheme and delimiter
870  if ( $wasRelative ) {
871  $bits['scheme'] = '';
872  $bits['delimiter'] = '//';
873  }
874  return $bits;
875 }
876 
887 function wfExpandIRI( $url ) {
888  return preg_replace_callback(
889  '/((?:%[89A-F][0-9A-F])+)/i',
890  function ( array $matches ) {
891  return urldecode( $matches[1] );
892  },
893  wfExpandUrl( $url )
894  );
895 }
896 
904 function wfMakeUrlIndexes( $url ) {
905  wfDeprecated( __FUNCTION__, '1.33' );
906  return LinkFilter::makeIndexes( $url );
907 }
908 
915 function wfMatchesDomainList( $url, $domains ) {
916  $bits = wfParseUrl( $url );
917  if ( is_array( $bits ) && isset( $bits['host'] ) ) {
918  $host = '.' . $bits['host'];
919  foreach ( (array)$domains as $domain ) {
920  $domain = '.' . $domain;
921  if ( substr( $host, -strlen( $domain ) ) === $domain ) {
922  return true;
923  }
924  }
925  }
926  return false;
927 }
928 
949 function wfDebug( $text, $dest = 'all', array $context = [] ) {
951  global $wgDebugTimestamps;
952 
953  if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
954  return;
955  }
956 
957  $text = trim( $text );
958 
959  if ( $wgDebugTimestamps ) {
960  $context['seconds_elapsed'] = sprintf(
961  '%6.4f',
962  microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT']
963  );
964  $context['memory_used'] = sprintf(
965  '%5.1fM',
966  ( memory_get_usage( true ) / ( 1024 * 1024 ) )
967  );
968  }
969 
970  if ( $wgDebugLogPrefix !== '' ) {
971  $context['prefix'] = $wgDebugLogPrefix;
972  }
973  $context['private'] = ( $dest === false || $dest === 'private' );
974 
975  $logger = LoggerFactory::getInstance( 'wfDebug' );
976  $logger->debug( $text, $context );
977 }
978 
983 function wfIsDebugRawPage() {
984  static $cache;
985  if ( $cache !== null ) {
986  return $cache;
987  }
988  // Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
989  // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
990  if ( ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' )
991  || (
992  isset( $_SERVER['SCRIPT_NAME'] )
993  && substr( $_SERVER['SCRIPT_NAME'], -8 ) == 'load.php'
994  )
995  ) {
996  $cache = true;
997  } else {
998  $cache = false;
999  }
1000  return $cache;
1001 }
1002 
1008 function wfDebugMem( $exact = false ) {
1009  $mem = memory_get_usage();
1010  if ( !$exact ) {
1011  $mem = floor( $mem / 1024 ) . ' KiB';
1012  } else {
1013  $mem .= ' B';
1014  }
1015  wfDebug( "Memory usage: $mem\n" );
1016 }
1017 
1043 function wfDebugLog(
1044  $logGroup, $text, $dest = 'all', array $context = []
1045 ) {
1046  $text = trim( $text );
1047 
1048  $logger = LoggerFactory::getInstance( $logGroup );
1049  $context['private'] = ( $dest === false || $dest === 'private' );
1050  $logger->info( $text, $context );
1051 }
1052 
1061 function wfLogDBError( $text, array $context = [] ) {
1062  $logger = LoggerFactory::getInstance( 'wfLogDBError' );
1063  $logger->error( trim( $text ), $context );
1064 }
1065 
1078 function wfDeprecated( $function, $version = false, $component = false, $callerOffset = 2 ) {
1079  MWDebug::deprecated( $function, $version, $component, $callerOffset + 1 );
1080 }
1081 
1092 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
1093  MWDebug::warning( $msg, $callerOffset + 1, $level, 'auto' );
1094 }
1095 
1105 function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
1106  MWDebug::warning( $msg, $callerOffset + 1, $level, 'production' );
1107 }
1108 
1115 
1117  $request = $context->getRequest();
1118 
1119  $profiler = Profiler::instance();
1120  $profiler->setContext( $context );
1121  $profiler->logData();
1122 
1123  // Send out any buffered statsd metrics as needed
1125  MediaWikiServices::getInstance()->getStatsdDataFactory(),
1126  $context->getConfig()
1127  );
1128 
1129  // Profiling must actually be enabled...
1130  if ( $profiler instanceof ProfilerStub ) {
1131  return;
1132  }
1133 
1134  if ( isset( $wgDebugLogGroups['profileoutput'] )
1135  && $wgDebugLogGroups['profileoutput'] === false
1136  ) {
1137  // Explicitly disabled
1138  return;
1139  }
1140  if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
1141  return;
1142  }
1143 
1144  $ctx = [ 'elapsed' => $request->getElapsedTime() ];
1145  if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
1146  $ctx['forwarded_for'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
1147  }
1148  if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
1149  $ctx['client_ip'] = $_SERVER['HTTP_CLIENT_IP'];
1150  }
1151  if ( !empty( $_SERVER['HTTP_FROM'] ) ) {
1152  $ctx['from'] = $_SERVER['HTTP_FROM'];
1153  }
1154  if ( isset( $ctx['forwarded_for'] ) ||
1155  isset( $ctx['client_ip'] ) ||
1156  isset( $ctx['from'] ) ) {
1157  $ctx['proxy'] = $_SERVER['REMOTE_ADDR'];
1158  }
1159 
1160  // Don't load $wgUser at this late stage just for statistics purposes
1161  // @todo FIXME: We can detect some anons even if it is not loaded.
1162  // See User::getId()
1163  $user = $context->getUser();
1164  $ctx['anon'] = $user->isItemLoaded( 'id' ) && $user->isAnon();
1165 
1166  // Command line script uses a FauxRequest object which does not have
1167  // any knowledge about an URL and throw an exception instead.
1168  try {
1169  $ctx['url'] = urldecode( $request->getRequestURL() );
1170  } catch ( Exception $ignored ) {
1171  // no-op
1172  }
1173 
1174  $ctx['output'] = $profiler->getOutput();
1175 
1176  $log = LoggerFactory::getInstance( 'profileoutput' );
1177  $log->info( "Elapsed: {elapsed}; URL: <{url}>\n{output}", $ctx );
1178 }
1179 
1187 function wfIncrStats( $key, $count = 1 ) {
1188  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
1189  $stats->updateCount( $key, $count );
1190 }
1191 
1197 function wfReadOnly() {
1198  return MediaWikiServices::getInstance()->getReadOnlyMode()
1199  ->isReadOnly();
1200 }
1201 
1210 function wfReadOnlyReason() {
1211  return MediaWikiServices::getInstance()->getReadOnlyMode()
1212  ->getReason();
1213 }
1214 
1222  return MediaWikiServices::getInstance()->getConfiguredReadOnlyMode()
1223  ->getReason();
1224 }
1225 
1241 function wfGetLangObj( $langcode = false ) {
1242  # Identify which language to get or create a language object for.
1243  # Using is_object here due to Stub objects.
1244  if ( is_object( $langcode ) ) {
1245  # Great, we already have the object (hopefully)!
1246  return $langcode;
1247  }
1248 
1249  global $wgLanguageCode;
1250  if ( $langcode === true || $langcode === $wgLanguageCode ) {
1251  # $langcode is the language code of the wikis content language object.
1252  # or it is a boolean and value is true
1253  return MediaWikiServices::getInstance()->getContentLanguage();
1254  }
1255 
1256  global $wgLang;
1257  if ( $langcode === false || $langcode === $wgLang->getCode() ) {
1258  # $langcode is the language code of user language object.
1259  # or it was a boolean and value is false
1260  return $wgLang;
1261  }
1262 
1263  $validCodes = array_keys( Language::fetchLanguageNames() );
1264  if ( in_array( $langcode, $validCodes ) ) {
1265  # $langcode corresponds to a valid language.
1266  return Language::factory( $langcode );
1267  }
1268 
1269  # $langcode is a string, but not a valid language code; use content language.
1270  wfDebug( "Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
1271  return MediaWikiServices::getInstance()->getContentLanguage();
1272 }
1273 
1290 function wfMessage( $key, ...$params ) {
1291  $message = new Message( $key );
1292 
1293  // We call Message::params() to reduce code duplication
1294  if ( $params ) {
1295  $message->params( ...$params );
1296  }
1297 
1298  return $message;
1299 }
1300 
1313 function wfMessageFallback( ...$keys ) {
1314  return Message::newFallbackSequence( ...$keys );
1315 }
1316 
1325 function wfMsgReplaceArgs( $message, $args ) {
1326  # Fix windows line-endings
1327  # Some messages are split with explode("\n", $msg)
1328  $message = str_replace( "\r", '', $message );
1329 
1330  // Replace arguments
1331  if ( is_array( $args ) && $args ) {
1332  if ( is_array( $args[0] ) ) {
1333  $args = array_values( $args[0] );
1334  }
1335  $replacementKeys = [];
1336  foreach ( $args as $n => $param ) {
1337  $replacementKeys['$' . ( $n + 1 )] = $param;
1338  }
1339  $message = strtr( $message, $replacementKeys );
1340  }
1341 
1342  return $message;
1343 }
1344 
1352 function wfHostname() {
1353  static $host;
1354  if ( is_null( $host ) ) {
1355  # Hostname overriding
1356  global $wgOverrideHostname;
1357  if ( $wgOverrideHostname !== false ) {
1358  # Set static and skip any detection
1359  $host = $wgOverrideHostname;
1360  return $host;
1361  }
1362 
1363  if ( function_exists( 'posix_uname' ) ) {
1364  // This function not present on Windows
1365  $uname = posix_uname();
1366  } else {
1367  $uname = false;
1368  }
1369  if ( is_array( $uname ) && isset( $uname['nodename'] ) ) {
1370  $host = $uname['nodename'];
1371  } elseif ( getenv( 'COMPUTERNAME' ) ) {
1372  # Windows computer name
1373  $host = getenv( 'COMPUTERNAME' );
1374  } else {
1375  # This may be a virtual server.
1376  $host = $_SERVER['SERVER_NAME'];
1377  }
1378  }
1379  return $host;
1380 }
1381 
1392 function wfReportTime( $nonce = null ) {
1393  global $wgShowHostnames;
1394 
1395  $elapsed = ( microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT'] );
1396  // seconds to milliseconds
1397  $responseTime = round( $elapsed * 1000 );
1398  $reportVars = [ 'wgBackendResponseTime' => $responseTime ];
1399  if ( $wgShowHostnames ) {
1400  $reportVars['wgHostname'] = wfHostname();
1401  }
1402  return Skin::makeVariablesScript( $reportVars, $nonce );
1403 }
1404 
1415 function wfDebugBacktrace( $limit = 0 ) {
1416  static $disabled = null;
1417 
1418  if ( is_null( $disabled ) ) {
1419  $disabled = !function_exists( 'debug_backtrace' );
1420  if ( $disabled ) {
1421  wfDebug( "debug_backtrace() is disabled\n" );
1422  }
1423  }
1424  if ( $disabled ) {
1425  return [];
1426  }
1427 
1428  if ( $limit ) {
1429  return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit + 1 ), 1 );
1430  } else {
1431  return array_slice( debug_backtrace(), 1 );
1432  }
1433 }
1434 
1443 function wfBacktrace( $raw = null ) {
1444  global $wgCommandLineMode;
1445 
1446  if ( $raw === null ) {
1447  $raw = $wgCommandLineMode;
1448  }
1449 
1450  if ( $raw ) {
1451  $frameFormat = "%s line %s calls %s()\n";
1452  $traceFormat = "%s";
1453  } else {
1454  $frameFormat = "<li>%s line %s calls %s()</li>\n";
1455  $traceFormat = "<ul>\n%s</ul>\n";
1456  }
1457 
1458  $frames = array_map( function ( $frame ) use ( $frameFormat ) {
1459  $file = !empty( $frame['file'] ) ? basename( $frame['file'] ) : '-';
1460  $line = $frame['line'] ?? '-';
1461  $call = $frame['function'];
1462  if ( !empty( $frame['class'] ) ) {
1463  $call = $frame['class'] . $frame['type'] . $call;
1464  }
1465  return sprintf( $frameFormat, $file, $line, $call );
1466  }, wfDebugBacktrace() );
1467 
1468  return sprintf( $traceFormat, implode( '', $frames ) );
1469 }
1470 
1480 function wfGetCaller( $level = 2 ) {
1481  $backtrace = wfDebugBacktrace( $level + 1 );
1482  if ( isset( $backtrace[$level] ) ) {
1483  return wfFormatStackFrame( $backtrace[$level] );
1484  } else {
1485  return 'unknown';
1486  }
1487 }
1488 
1496 function wfGetAllCallers( $limit = 3 ) {
1497  $trace = array_reverse( wfDebugBacktrace() );
1498  if ( !$limit || $limit > count( $trace ) - 1 ) {
1499  $limit = count( $trace ) - 1;
1500  }
1501  $trace = array_slice( $trace, -$limit - 1, $limit );
1502  return implode( '/', array_map( 'wfFormatStackFrame', $trace ) );
1503 }
1504 
1511 function wfFormatStackFrame( $frame ) {
1512  if ( !isset( $frame['function'] ) ) {
1513  return 'NO_FUNCTION_GIVEN';
1514  }
1515  return isset( $frame['class'] ) && isset( $frame['type'] ) ?
1516  $frame['class'] . $frame['type'] . $frame['function'] :
1517  $frame['function'];
1518 }
1519 
1520 /* Some generic result counters, pulled out of SearchEngine */
1521 
1529 function wfShowingResults( $offset, $limit ) {
1530  return wfMessage( 'showingresults' )->numParams( $limit, $offset + 1 )->parse();
1531 }
1532 
1542 function wfClientAcceptsGzip( $force = false ) {
1543  static $result = null;
1544  if ( $result === null || $force ) {
1545  $result = false;
1546  if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
1547  # @todo FIXME: We may want to blacklist some broken browsers
1548  $m = [];
1549  if ( preg_match(
1550  '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
1551  $_SERVER['HTTP_ACCEPT_ENCODING'],
1552  $m
1553  )
1554  ) {
1555  if ( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) {
1556  $result = false;
1557  return $result;
1558  }
1559  wfDebug( "wfClientAcceptsGzip: client accepts gzip.\n" );
1560  $result = true;
1561  }
1562  }
1563  }
1564  return $result;
1565 }
1566 
1577 function wfEscapeWikiText( $text ) {
1578  global $wgEnableMagicLinks;
1579  static $repl = null, $repl2 = null;
1580  if ( $repl === null || defined( 'MW_PARSER_TEST' ) || defined( 'MW_PHPUNIT_TEST' ) ) {
1581  // Tests depend upon being able to change $wgEnableMagicLinks, so don't cache
1582  // in those situations
1583  $repl = [
1584  '"' => '&#34;', '&' => '&#38;', "'" => '&#39;', '<' => '&#60;',
1585  '=' => '&#61;', '>' => '&#62;', '[' => '&#91;', ']' => '&#93;',
1586  '{' => '&#123;', '|' => '&#124;', '}' => '&#125;', ';' => '&#59;',
1587  "\n#" => "\n&#35;", "\r#" => "\r&#35;",
1588  "\n*" => "\n&#42;", "\r*" => "\r&#42;",
1589  "\n:" => "\n&#58;", "\r:" => "\r&#58;",
1590  "\n " => "\n&#32;", "\r " => "\r&#32;",
1591  "\n\n" => "\n&#10;", "\r\n" => "&#13;\n",
1592  "\n\r" => "\n&#13;", "\r\r" => "\r&#13;",
1593  "\n\t" => "\n&#9;", "\r\t" => "\r&#9;", // "\n\t\n" is treated like "\n\n"
1594  "\n----" => "\n&#45;---", "\r----" => "\r&#45;---",
1595  '__' => '_&#95;', '://' => '&#58;//',
1596  ];
1597 
1598  $magicLinks = array_keys( array_filter( $wgEnableMagicLinks ) );
1599  // We have to catch everything "\s" matches in PCRE
1600  foreach ( $magicLinks as $magic ) {
1601  $repl["$magic "] = "$magic&#32;";
1602  $repl["$magic\t"] = "$magic&#9;";
1603  $repl["$magic\r"] = "$magic&#13;";
1604  $repl["$magic\n"] = "$magic&#10;";
1605  $repl["$magic\f"] = "$magic&#12;";
1606  }
1607 
1608  // And handle protocols that don't use "://"
1609  global $wgUrlProtocols;
1610  $repl2 = [];
1611  foreach ( $wgUrlProtocols as $prot ) {
1612  if ( substr( $prot, -1 ) === ':' ) {
1613  $repl2[] = preg_quote( substr( $prot, 0, -1 ), '/' );
1614  }
1615  }
1616  $repl2 = $repl2 ? '/\b(' . implode( '|', $repl2 ) . '):/i' : '/^(?!)/';
1617  }
1618  $text = substr( strtr( "\n$text", $repl ), 1 );
1619  $text = preg_replace( $repl2, '$1&#58;', $text );
1620  return $text;
1621 }
1622 
1633 function wfSetVar( &$dest, $source, $force = false ) {
1634  $temp = $dest;
1635  if ( !is_null( $source ) || $force ) {
1636  $dest = $source;
1637  }
1638  return $temp;
1639 }
1640 
1650 function wfSetBit( &$dest, $bit, $state = true ) {
1651  $temp = (bool)( $dest & $bit );
1652  if ( !is_null( $state ) ) {
1653  if ( $state ) {
1654  $dest |= $bit;
1655  } else {
1656  $dest &= ~$bit;
1657  }
1658  }
1659  return $temp;
1660 }
1661 
1668 function wfVarDump( $var ) {
1669  global $wgOut;
1670  $s = str_replace( "\n", "<br />\n", var_export( $var, true ) . "\n" );
1671  if ( headers_sent() || !isset( $wgOut ) || !is_object( $wgOut ) ) {
1672  print $s;
1673  } else {
1674  $wgOut->addHTML( $s );
1675  }
1676 }
1677 
1685 function wfHttpError( $code, $label, $desc ) {
1686  global $wgOut;
1688  if ( $wgOut ) {
1689  $wgOut->disable();
1690  $wgOut->sendCacheControl();
1691  }
1692 
1694  header( 'Content-type: text/html; charset=utf-8' );
1695  print '<!DOCTYPE html>' .
1696  '<html><head><title>' .
1697  htmlspecialchars( $label ) .
1698  '</title></head><body><h1>' .
1699  htmlspecialchars( $label ) .
1700  '</h1><p>' .
1701  nl2br( htmlspecialchars( $desc ) ) .
1702  "</p></body></html>\n";
1703 }
1704 
1722 function wfResetOutputBuffers( $resetGzipEncoding = true ) {
1723  if ( $resetGzipEncoding ) {
1724  // Suppress Content-Encoding and Content-Length
1725  // headers from OutputHandler::handle.
1728  }
1729  while ( $status = ob_get_status() ) {
1730  if ( isset( $status['flags'] ) ) {
1731  $flags = PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_REMOVABLE;
1732  $deleteable = ( $status['flags'] & $flags ) === $flags;
1733  } elseif ( isset( $status['del'] ) ) {
1734  $deleteable = $status['del'];
1735  } else {
1736  // Guess that any PHP-internal setting can't be removed.
1737  $deleteable = $status['type'] !== 0; /* PHP_OUTPUT_HANDLER_INTERNAL */
1738  }
1739  if ( !$deleteable ) {
1740  // Give up, and hope the result doesn't break
1741  // output behavior.
1742  break;
1743  }
1744  if ( $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
1745  // Unit testing barrier to prevent this function from breaking PHPUnit.
1746  break;
1747  }
1748  if ( !ob_end_clean() ) {
1749  // Could not remove output buffer handler; abort now
1750  // to avoid getting in some kind of infinite loop.
1751  break;
1752  }
1753  if ( $resetGzipEncoding && $status['name'] == 'ob_gzhandler' ) {
1754  // Reset the 'Content-Encoding' field set by this handler
1755  // so we can start fresh.
1756  header_remove( 'Content-Encoding' );
1757  break;
1758  }
1759  }
1760 }
1761 
1775  wfResetOutputBuffers( false );
1776 }
1777 
1786 function wfAcceptToPrefs( $accept, $def = '*/*' ) {
1787  # No arg means accept anything (per HTTP spec)
1788  if ( !$accept ) {
1789  return [ $def => 1.0 ];
1790  }
1791 
1792  $prefs = [];
1793 
1794  $parts = explode( ',', $accept );
1795 
1796  foreach ( $parts as $part ) {
1797  # @todo FIXME: Doesn't deal with params like 'text/html; level=1'
1798  $values = explode( ';', trim( $part ) );
1799  $match = [];
1800  if ( count( $values ) == 1 ) {
1801  $prefs[$values[0]] = 1.0;
1802  } elseif ( preg_match( '/q\s*=\s*(\d*\.\d+)/', $values[1], $match ) ) {
1803  $prefs[$values[0]] = floatval( $match[1] );
1804  }
1805  }
1806 
1807  return $prefs;
1808 }
1809 
1822 function mimeTypeMatch( $type, $avail ) {
1823  if ( array_key_exists( $type, $avail ) ) {
1824  return $type;
1825  } else {
1826  $mainType = explode( '/', $type )[0];
1827  if ( array_key_exists( "$mainType/*", $avail ) ) {
1828  return "$mainType/*";
1829  } elseif ( array_key_exists( '*/*', $avail ) ) {
1830  return '*/*';
1831  } else {
1832  return null;
1833  }
1834  }
1835 }
1836 
1850 function wfNegotiateType( $cprefs, $sprefs ) {
1851  $combine = [];
1852 
1853  foreach ( array_keys( $sprefs ) as $type ) {
1854  $subType = explode( '/', $type )[1];
1855  if ( $subType != '*' ) {
1856  $ckey = mimeTypeMatch( $type, $cprefs );
1857  if ( $ckey ) {
1858  $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
1859  }
1860  }
1861  }
1862 
1863  foreach ( array_keys( $cprefs ) as $type ) {
1864  $subType = explode( '/', $type )[1];
1865  if ( $subType != '*' && !array_key_exists( $type, $sprefs ) ) {
1866  $skey = mimeTypeMatch( $type, $sprefs );
1867  if ( $skey ) {
1868  $combine[$type] = $sprefs[$skey] * $cprefs[$type];
1869  }
1870  }
1871  }
1872 
1873  $bestq = 0;
1874  $besttype = null;
1875 
1876  foreach ( array_keys( $combine ) as $type ) {
1877  if ( $combine[$type] > $bestq ) {
1878  $besttype = $type;
1879  $bestq = $combine[$type];
1880  }
1881  }
1882 
1883  return $besttype;
1884 }
1885 
1892 function wfSuppressWarnings( $end = false ) {
1893  Wikimedia\suppressWarnings( $end );
1894 }
1895 
1900 function wfRestoreWarnings() {
1901  Wikimedia\restoreWarnings();
1902 }
1903 
1912 function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
1913  $ret = MWTimestamp::convert( $outputtype, $ts );
1914  if ( $ret === false ) {
1915  wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
1916  }
1917  return $ret;
1918 }
1919 
1928 function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
1929  if ( is_null( $ts ) ) {
1930  return null;
1931  } else {
1932  return wfTimestamp( $outputtype, $ts );
1933  }
1934 }
1935 
1941 function wfTimestampNow() {
1942  # return NOW
1943  return MWTimestamp::now( TS_MW );
1944 }
1945 
1951 function wfIsWindows() {
1952  static $isWindows = null;
1953  if ( $isWindows === null ) {
1954  $isWindows = strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN';
1955  }
1956  return $isWindows;
1957 }
1958 
1964 function wfIsHHVM() {
1965  return defined( 'HHVM_VERSION' );
1966 }
1967 
1974 function wfIsCLI() {
1975  return PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg';
1976 }
1977 
1989 function wfTempDir() {
1990  global $wgTmpDirectory;
1991 
1992  if ( $wgTmpDirectory !== false ) {
1993  return $wgTmpDirectory;
1994  }
1995 
1997 }
1998 
2008 function wfMkdirParents( $dir, $mode = null, $caller = null ) {
2009  global $wgDirectoryMode;
2010 
2011  if ( FileBackend::isStoragePath( $dir ) ) { // sanity
2012  throw new MWException( __FUNCTION__ . " given storage path '$dir'." );
2013  }
2014 
2015  if ( !is_null( $caller ) ) {
2016  wfDebug( "$caller: called wfMkdirParents($dir)\n" );
2017  }
2018 
2019  if ( strval( $dir ) === '' || is_dir( $dir ) ) {
2020  return true;
2021  }
2022 
2023  $dir = str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, $dir );
2024 
2025  if ( is_null( $mode ) ) {
2026  $mode = $wgDirectoryMode;
2027  }
2028 
2029  // Turn off the normal warning, we're doing our own below
2030  Wikimedia\suppressWarnings();
2031  $ok = mkdir( $dir, $mode, true ); // PHP5 <3
2032  Wikimedia\restoreWarnings();
2033 
2034  if ( !$ok ) {
2035  // directory may have been created on another request since we last checked
2036  if ( is_dir( $dir ) ) {
2037  return true;
2038  }
2039 
2040  // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis.
2041  wfLogWarning( sprintf( "failed to mkdir \"%s\" mode 0%o", $dir, $mode ) );
2042  }
2043  return $ok;
2044 }
2045 
2051 function wfRecursiveRemoveDir( $dir ) {
2052  wfDebug( __FUNCTION__ . "( $dir )\n" );
2053  // taken from https://secure.php.net/manual/en/function.rmdir.php#98622
2054  if ( is_dir( $dir ) ) {
2055  $objects = scandir( $dir );
2056  foreach ( $objects as $object ) {
2057  if ( $object != "." && $object != ".." ) {
2058  if ( filetype( $dir . '/' . $object ) == "dir" ) {
2059  wfRecursiveRemoveDir( $dir . '/' . $object );
2060  } else {
2061  unlink( $dir . '/' . $object );
2062  }
2063  }
2064  }
2065  reset( $objects );
2066  rmdir( $dir );
2067  }
2068 }
2069 
2076 function wfPercent( $nr, $acc = 2, $round = true ) {
2077  $ret = sprintf( "%.${acc}f", $nr );
2078  return $round ? round( $ret, $acc ) . '%' : "$ret%";
2079 }
2080 
2104 function wfIniGetBool( $setting ) {
2105  return wfStringToBool( ini_get( $setting ) );
2106 }
2107 
2120 function wfStringToBool( $val ) {
2121  $val = strtolower( $val );
2122  // 'on' and 'true' can't have whitespace around them, but '1' can.
2123  return $val == 'on'
2124  || $val == 'true'
2125  || $val == 'yes'
2126  || preg_match( "/^\s*[+-]?0*[1-9]/", $val ); // approx C atoi() function
2127 }
2128 
2141 function wfEscapeShellArg( ...$args ) {
2142  return Shell::escape( ...$args );
2143 }
2144 
2168 function wfShellExec( $cmd, &$retval = null, $environ = [],
2169  $limits = [], $options = []
2170 ) {
2171  if ( Shell::isDisabled() ) {
2172  $retval = 1;
2173  // Backwards compatibility be upon us...
2174  return 'Unable to run external programs, proc_open() is disabled.';
2175  }
2176 
2177  if ( is_array( $cmd ) ) {
2178  $cmd = Shell::escape( $cmd );
2179  }
2180 
2181  $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
2182  $profileMethod = $options['profileMethod'] ?? wfGetCaller();
2183 
2184  try {
2185  $result = Shell::command( [] )
2186  ->unsafeParams( (array)$cmd )
2187  ->environment( $environ )
2188  ->limits( $limits )
2189  ->includeStderr( $includeStderr )
2190  ->profileMethod( $profileMethod )
2191  // For b/c
2192  ->restrict( Shell::RESTRICT_NONE )
2193  ->execute();
2194  } catch ( ProcOpenError $ex ) {
2195  $retval = -1;
2196  return '';
2197  }
2198 
2199  $retval = $result->getExitCode();
2200 
2201  return $result->getStdout();
2202 }
2203 
2221 function wfShellExecWithStderr( $cmd, &$retval = null, $environ = [], $limits = [] ) {
2222  return wfShellExec( $cmd, $retval, $environ, $limits,
2223  [ 'duplicateStderr' => true, 'profileMethod' => wfGetCaller() ] );
2224 }
2225 
2240 function wfShellWikiCmd( $script, array $parameters = [], array $options = [] ) {
2241  global $wgPhpCli;
2242  // Give site config file a chance to run the script in a wrapper.
2243  // The caller may likely want to call wfBasename() on $script.
2244  Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
2245  $cmd = [ $options['php'] ?? $wgPhpCli ];
2246  if ( isset( $options['wrapper'] ) ) {
2247  $cmd[] = $options['wrapper'];
2248  }
2249  $cmd[] = $script;
2250  // Escape each parameter for shell
2251  return Shell::escape( array_merge( $cmd, $parameters ) );
2252 }
2253 
2265 function wfMerge( $old, $mine, $yours, &$result, &$mergeAttemptResult = null ) {
2266  global $wgDiff3;
2267 
2268  # This check may also protect against code injection in
2269  # case of broken installations.
2270  Wikimedia\suppressWarnings();
2271  $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
2272  Wikimedia\restoreWarnings();
2273 
2274  if ( !$haveDiff3 ) {
2275  wfDebug( "diff3 not found\n" );
2276  return false;
2277  }
2278 
2279  # Make temporary files
2280  $td = wfTempDir();
2281  $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
2282  $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
2283  $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
2284 
2285  # NOTE: diff3 issues a warning to stderr if any of the files does not end with
2286  # a newline character. To avoid this, we normalize the trailing whitespace before
2287  # creating the diff.
2288 
2289  fwrite( $oldtextFile, rtrim( $old ) . "\n" );
2290  fclose( $oldtextFile );
2291  fwrite( $mytextFile, rtrim( $mine ) . "\n" );
2292  fclose( $mytextFile );
2293  fwrite( $yourtextFile, rtrim( $yours ) . "\n" );
2294  fclose( $yourtextFile );
2295 
2296  # Check for a conflict
2297  $cmd = Shell::escape( $wgDiff3, '-a', '--overlap-only', $mytextName,
2298  $oldtextName, $yourtextName );
2299  $handle = popen( $cmd, 'r' );
2300 
2301  $mergeAttemptResult = '';
2302  do {
2303  $data = fread( $handle, 8192 );
2304  if ( strlen( $data ) == 0 ) {
2305  break;
2306  }
2307  $mergeAttemptResult .= $data;
2308  } while ( true );
2309  pclose( $handle );
2310 
2311  $conflict = $mergeAttemptResult !== '';
2312 
2313  # Merge differences
2314  $cmd = Shell::escape( $wgDiff3, '-a', '-e', '--merge', $mytextName,
2315  $oldtextName, $yourtextName );
2316  $handle = popen( $cmd, 'r' );
2317  $result = '';
2318  do {
2319  $data = fread( $handle, 8192 );
2320  if ( strlen( $data ) == 0 ) {
2321  break;
2322  }
2323  $result .= $data;
2324  } while ( true );
2325  pclose( $handle );
2326  unlink( $mytextName );
2327  unlink( $oldtextName );
2328  unlink( $yourtextName );
2329 
2330  if ( $result === '' && $old !== '' && !$conflict ) {
2331  wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
2332  $conflict = true;
2333  }
2334  return !$conflict;
2335 }
2336 
2348 function wfDiff( $before, $after, $params = '-u' ) {
2349  if ( $before == $after ) {
2350  return '';
2351  }
2352 
2353  global $wgDiff;
2354  Wikimedia\suppressWarnings();
2355  $haveDiff = $wgDiff && file_exists( $wgDiff );
2356  Wikimedia\restoreWarnings();
2357 
2358  # This check may also protect against code injection in
2359  # case of broken installations.
2360  if ( !$haveDiff ) {
2361  wfDebug( "diff executable not found\n" );
2362  $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) );
2363  $format = new UnifiedDiffFormatter();
2364  return $format->format( $diffs );
2365  }
2366 
2367  # Make temporary files
2368  $td = wfTempDir();
2369  $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
2370  $newtextFile = fopen( $newtextName = tempnam( $td, 'merge-your-' ), 'w' );
2371 
2372  fwrite( $oldtextFile, $before );
2373  fclose( $oldtextFile );
2374  fwrite( $newtextFile, $after );
2375  fclose( $newtextFile );
2376 
2377  // Get the diff of the two files
2378  $cmd = "$wgDiff " . $params . ' ' . Shell::escape( $oldtextName, $newtextName );
2379 
2380  $h = popen( $cmd, 'r' );
2381  if ( !$h ) {
2382  unlink( $oldtextName );
2383  unlink( $newtextName );
2384  throw new Exception( __METHOD__ . '(): popen() failed' );
2385  }
2386 
2387  $diff = '';
2388 
2389  do {
2390  $data = fread( $h, 8192 );
2391  if ( strlen( $data ) == 0 ) {
2392  break;
2393  }
2394  $diff .= $data;
2395  } while ( true );
2396 
2397  // Clean up
2398  pclose( $h );
2399  unlink( $oldtextName );
2400  unlink( $newtextName );
2401 
2402  // Kill the --- and +++ lines. They're not useful.
2403  $diff_lines = explode( "\n", $diff );
2404  if ( isset( $diff_lines[0] ) && strpos( $diff_lines[0], '---' ) === 0 ) {
2405  unset( $diff_lines[0] );
2406  }
2407  if ( isset( $diff_lines[1] ) && strpos( $diff_lines[1], '+++' ) === 0 ) {
2408  unset( $diff_lines[1] );
2409  }
2410 
2411  $diff = implode( "\n", $diff_lines );
2412 
2413  return $diff;
2414 }
2415 
2428 function wfBaseName( $path, $suffix = '' ) {
2429  if ( $suffix == '' ) {
2430  $encSuffix = '';
2431  } else {
2432  $encSuffix = '(?:' . preg_quote( $suffix, '#' ) . ')?';
2433  }
2434 
2435  $matches = [];
2436  if ( preg_match( "#([^/\\\\]*?){$encSuffix}[/\\\\]*$#", $path, $matches ) ) {
2437  return $matches[1];
2438  } else {
2439  return '';
2440  }
2441 }
2442 
2452 function wfRelativePath( $path, $from ) {
2453  // Normalize mixed input on Windows...
2454  $path = str_replace( '/', DIRECTORY_SEPARATOR, $path );
2455  $from = str_replace( '/', DIRECTORY_SEPARATOR, $from );
2456 
2457  // Trim trailing slashes -- fix for drive root
2458  $path = rtrim( $path, DIRECTORY_SEPARATOR );
2459  $from = rtrim( $from, DIRECTORY_SEPARATOR );
2460 
2461  $pieces = explode( DIRECTORY_SEPARATOR, dirname( $path ) );
2462  $against = explode( DIRECTORY_SEPARATOR, $from );
2463 
2464  if ( $pieces[0] !== $against[0] ) {
2465  // Non-matching Windows drive letters?
2466  // Return a full path.
2467  return $path;
2468  }
2469 
2470  // Trim off common prefix
2471  while ( count( $pieces ) && count( $against )
2472  && $pieces[0] == $against[0] ) {
2473  array_shift( $pieces );
2474  array_shift( $against );
2475  }
2476 
2477  // relative dots to bump us to the parent
2478  while ( count( $against ) ) {
2479  array_unshift( $pieces, '..' );
2480  array_shift( $against );
2481  }
2482 
2483  array_push( $pieces, wfBaseName( $path ) );
2484 
2485  return implode( DIRECTORY_SEPARATOR, $pieces );
2486 }
2487 
2494 function wfResetSessionID() {
2495  wfDeprecated( __FUNCTION__, '1.27' );
2496  $session = SessionManager::getGlobalSession();
2497  $delay = $session->delaySave();
2498 
2499  $session->resetId();
2500 
2501  // Make sure a session is started, since that's what the old
2502  // wfResetSessionID() did.
2503  if ( session_id() !== $session->getId() ) {
2504  wfSetupSession( $session->getId() );
2505  }
2506 
2507  ScopedCallback::consume( $delay );
2508 }
2509 
2519 function wfSetupSession( $sessionId = false ) {
2520  wfDeprecated( __FUNCTION__, '1.27' );
2521 
2522  if ( $sessionId ) {
2523  session_id( $sessionId );
2524  }
2525 
2526  $session = SessionManager::getGlobalSession();
2527  $session->persist();
2528 
2529  if ( session_id() !== $session->getId() ) {
2530  session_id( $session->getId() );
2531  }
2532  Wikimedia\quietCall( 'session_start' );
2533 }
2534 
2542  global $IP;
2543 
2544  $file = "$IP/serialized/$name";
2545  if ( file_exists( $file ) ) {
2546  $blob = file_get_contents( $file );
2547  if ( $blob ) {
2548  return unserialize( $blob );
2549  }
2550  }
2551  return false;
2552 }
2553 
2561 function wfMemcKey( ...$args ) {
2562  return ObjectCache::getLocalClusterInstance()->makeKey( ...$args );
2563 }
2564 
2575 function wfForeignMemcKey( $db, $prefix, ...$args ) {
2576  $keyspace = $prefix ? "$db-$prefix" : $db;
2577  return ObjectCache::getLocalClusterInstance()->makeKeyInternal( $keyspace, $args );
2578 }
2579 
2592 function wfGlobalCacheKey( ...$args ) {
2593  return ObjectCache::getLocalClusterInstance()->makeGlobalKey( ...$args );
2594 }
2595 
2602 function wfWikiID() {
2603  global $wgDBprefix, $wgDBname;
2604  if ( $wgDBprefix ) {
2605  return "$wgDBname-$wgDBprefix";
2606  } else {
2607  return $wgDBname;
2608  }
2609 }
2610 
2636 function wfGetDB( $db, $groups = [], $wiki = false ) {
2637  return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
2638 }
2639 
2649 function wfGetLB( $wiki = false ) {
2650  if ( $wiki === false ) {
2651  return MediaWikiServices::getInstance()->getDBLoadBalancer();
2652  } else {
2653  $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2654  return $factory->getMainLB( $wiki );
2655  }
2656 }
2657 
2665 function wfGetLBFactory() {
2666  return MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2667 }
2668 
2677 function wfFindFile( $title, $options = [] ) {
2678  return RepoGroup::singleton()->findFile( $title, $options );
2679 }
2680 
2688 function wfLocalFile( $title ) {
2689  return RepoGroup::singleton()->getLocalRepo()->newFile( $title );
2690 }
2691 
2699  global $wgMiserMode;
2700  return $wgMiserMode
2701  || ( SiteStats::pages() > 100000
2702  && SiteStats::edits() > 1000000
2703  && SiteStats::users() > 10000 );
2704 }
2705 
2714 function wfScript( $script = 'index' ) {
2716  if ( $script === 'index' ) {
2717  return $wgScript;
2718  } elseif ( $script === 'load' ) {
2719  return $wgLoadScript;
2720  } else {
2721  return "{$wgScriptPath}/{$script}.php";
2722  }
2723 }
2724 
2730 function wfGetScriptUrl() {
2731  if ( isset( $_SERVER['SCRIPT_NAME'] ) ) {
2732  /* as it was called, minus the query string.
2733  *
2734  * Some sites use Apache rewrite rules to handle subdomains,
2735  * and have PHP set up in a weird way that causes PHP_SELF
2736  * to contain the rewritten URL instead of the one that the
2737  * outside world sees.
2738  *
2739  * If in this mode, use SCRIPT_URL instead, which mod_rewrite
2740  * provides containing the "before" URL.
2741  */
2742  return $_SERVER['SCRIPT_NAME'];
2743  } else {
2744  return $_SERVER['URL'];
2745  }
2746 }
2747 
2755 function wfBoolToStr( $value ) {
2756  return $value ? 'true' : 'false';
2757 }
2758 
2764 function wfGetNull() {
2765  return wfIsWindows() ? 'NUL' : '/dev/null';
2766 }
2767 
2791  $ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null
2792 ) {
2793  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
2794 
2795  if ( $cluster === '*' ) {
2796  $cluster = false;
2797  $domain = false;
2798  } elseif ( $wiki === false ) {
2799  $domain = $lbFactory->getLocalDomainID();
2800  } else {
2801  $domain = $wiki;
2802  }
2803 
2804  $opts = [
2805  'domain' => $domain,
2806  'cluster' => $cluster,
2807  // B/C: first argument used to be "max seconds of lag"; ignore such values
2808  'ifWritesSince' => ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null
2809  ];
2810  if ( $timeout !== null ) {
2811  $opts['timeout'] = $timeout;
2812  }
2813 
2814  return $lbFactory->waitForReplication( $opts );
2815 }
2816 
2826 function wfCountDown( $seconds ) {
2827  wfDeprecated( __FUNCTION__, '1.31' );
2828  for ( $i = $seconds; $i >= 0; $i-- ) {
2829  if ( $i != $seconds ) {
2830  echo str_repeat( "\x08", strlen( $i + 1 ) );
2831  }
2832  echo $i;
2833  flush();
2834  if ( $i ) {
2835  sleep( 1 );
2836  }
2837  }
2838  echo "\n";
2839 }
2840 
2850  global $wgIllegalFileChars;
2851  $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : '';
2852  $name = preg_replace(
2853  "/[^" . Title::legalChars() . "]" . $illegalFileChars . "/",
2854  '-',
2855  $name
2856  );
2857  // $wgIllegalFileChars may not include '/' and '\', so we still need to do this
2858  $name = wfBaseName( $name );
2859  return $name;
2860 }
2861 
2867 function wfMemoryLimit() {
2868  global $wgMemoryLimit;
2869  $memlimit = wfShorthandToInteger( ini_get( 'memory_limit' ) );
2870  if ( $memlimit != -1 ) {
2871  $conflimit = wfShorthandToInteger( $wgMemoryLimit );
2872  if ( $conflimit == -1 ) {
2873  wfDebug( "Removing PHP's memory limit\n" );
2874  Wikimedia\suppressWarnings();
2875  ini_set( 'memory_limit', $conflimit );
2876  Wikimedia\restoreWarnings();
2877  return $conflimit;
2878  } elseif ( $conflimit > $memlimit ) {
2879  wfDebug( "Raising PHP's memory limit to $conflimit bytes\n" );
2880  Wikimedia\suppressWarnings();
2881  ini_set( 'memory_limit', $conflimit );
2882  Wikimedia\restoreWarnings();
2883  return $conflimit;
2884  }
2885  }
2886  return $memlimit;
2887 }
2888 
2897 
2898  $timeLimit = ini_get( 'max_execution_time' );
2899  // Note that CLI scripts use 0
2900  if ( $timeLimit > 0 && $wgTransactionalTimeLimit > $timeLimit ) {
2901  set_time_limit( $wgTransactionalTimeLimit );
2902  }
2903 
2904  ignore_user_abort( true ); // ignore client disconnects
2905 
2906  return $timeLimit;
2907 }
2908 
2916 function wfShorthandToInteger( $string = '', $default = -1 ) {
2917  $string = trim( $string );
2918  if ( $string === '' ) {
2919  return $default;
2920  }
2921  $last = $string[strlen( $string ) - 1];
2922  $val = intval( $string );
2923  switch ( $last ) {
2924  case 'g':
2925  case 'G':
2926  $val *= 1024;
2927  // break intentionally missing
2928  case 'm':
2929  case 'M':
2930  $val *= 1024;
2931  // break intentionally missing
2932  case 'k':
2933  case 'K':
2934  $val *= 1024;
2935  }
2936 
2937  return $val;
2938 }
2939 
2950 function wfBCP47( $code ) {
2951  wfDeprecated( __METHOD__, '1.31' );
2952  return LanguageCode::bcp47( $code );
2953 }
2954 
2962 function wfGetCache( $cacheType ) {
2963  return ObjectCache::getInstance( $cacheType );
2964 }
2965 
2972 function wfGetMainCache() {
2974 }
2975 
2982  global $wgMessageCacheType;
2984 }
2985 
3000 function wfUnpack( $format, $data, $length = false ) {
3001  if ( $length !== false ) {
3002  $realLen = strlen( $data );
3003  if ( $realLen < $length ) {
3004  throw new MWException( "Tried to use wfUnpack on a "
3005  . "string of length $realLen, but needed one "
3006  . "of at least length $length."
3007  );
3008  }
3009  }
3010 
3011  Wikimedia\suppressWarnings();
3012  $result = unpack( $format, $data );
3013  Wikimedia\restoreWarnings();
3014 
3015  if ( $result === false ) {
3016  // If it cannot extract the packed data.
3017  throw new MWException( "unpack could not unpack binary data" );
3018  }
3019  return $result;
3020 }
3021 
3036 function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
3037  # Handle redirects; callers almost always hit wfFindFile() anyway,
3038  # so just use that method because it has a fast process cache.
3039  $file = wfFindFile( $name ); // get the final name
3040  $name = $file ? $file->getTitle()->getDBkey() : $name;
3041 
3042  # Run the extension hook
3043  $bad = false;
3044  if ( !Hooks::run( 'BadImage', [ $name, &$bad ] ) ) {
3045  return (bool)$bad;
3046  }
3047 
3049  $key = $cache->makeKey(
3050  'bad-image-list', ( $blacklist === null ) ? 'default' : md5( $blacklist )
3051  );
3052  $badImages = $cache->get( $key );
3053 
3054  if ( $badImages === false ) { // cache miss
3055  if ( $blacklist === null ) {
3056  $blacklist = wfMessage( 'bad_image_list' )->inContentLanguage()->plain(); // site list
3057  }
3058  # Build the list now
3059  $badImages = [];
3060  $lines = explode( "\n", $blacklist );
3061  foreach ( $lines as $line ) {
3062  # List items only
3063  if ( substr( $line, 0, 1 ) !== '*' ) {
3064  continue;
3065  }
3066 
3067  # Find all links
3068  $m = [];
3069  if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
3070  continue;
3071  }
3072 
3073  $exceptions = [];
3074  $imageDBkey = false;
3075  foreach ( $m[1] as $i => $titleText ) {
3076  $title = Title::newFromText( $titleText );
3077  if ( !is_null( $title ) ) {
3078  if ( $i == 0 ) {
3079  $imageDBkey = $title->getDBkey();
3080  } else {
3081  $exceptions[$title->getPrefixedDBkey()] = true;
3082  }
3083  }
3084  }
3085 
3086  if ( $imageDBkey !== false ) {
3087  $badImages[$imageDBkey] = $exceptions;
3088  }
3089  }
3090  $cache->set( $key, $badImages, 60 );
3091  }
3092 
3093  $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() : false;
3094  $bad = isset( $badImages[$name] ) && !isset( $badImages[$name][$contextKey] );
3095 
3096  return $bad;
3097 }
3098 
3106 function wfCanIPUseHTTPS( $ip ) {
3107  $canDo = true;
3108  Hooks::run( 'CanIPUseHTTPS', [ $ip, &$canDo ] );
3109  return (bool)$canDo;
3110 }
3111 
3119 function wfIsInfinity( $str ) {
3120  // These are hardcoded elsewhere in MediaWiki (e.g. mediawiki.special.block.js).
3121  $infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ];
3122  return in_array( $str, $infinityValues );
3123 }
3124 
3141 
3142  $multipliers = [ 1 ];
3143  if ( $wgResponsiveImages ) {
3144  // These available sizes are hardcoded currently elsewhere in MediaWiki.
3145  // @see Linker::processResponsiveImages
3146  $multipliers[] = 1.5;
3147  $multipliers[] = 2;
3148  }
3149 
3150  $handler = $file->getHandler();
3151  if ( !$handler || !isset( $params['width'] ) ) {
3152  return false;
3153  }
3154 
3155  $basicParams = [];
3156  if ( isset( $params['page'] ) ) {
3157  $basicParams['page'] = $params['page'];
3158  }
3159 
3160  $thumbLimits = [];
3161  $imageLimits = [];
3162  // Expand limits to account for multipliers
3163  foreach ( $multipliers as $multiplier ) {
3164  $thumbLimits = array_merge( $thumbLimits, array_map(
3165  function ( $width ) use ( $multiplier ) {
3166  return round( $width * $multiplier );
3167  }, $wgThumbLimits )
3168  );
3169  $imageLimits = array_merge( $imageLimits, array_map(
3170  function ( $pair ) use ( $multiplier ) {
3171  return [
3172  round( $pair[0] * $multiplier ),
3173  round( $pair[1] * $multiplier ),
3174  ];
3175  }, $wgImageLimits )
3176  );
3177  }
3178 
3179  // Check if the width matches one of $wgThumbLimits
3180  if ( in_array( $params['width'], $thumbLimits ) ) {
3181  $normalParams = $basicParams + [ 'width' => $params['width'] ];
3182  // Append any default values to the map (e.g. "lossy", "lossless", ...)
3183  $handler->normaliseParams( $file, $normalParams );
3184  } else {
3185  // If not, then check if the width matchs one of $wgImageLimits
3186  $match = false;
3187  foreach ( $imageLimits as $pair ) {
3188  $normalParams = $basicParams + [ 'width' => $pair[0], 'height' => $pair[1] ];
3189  // Decide whether the thumbnail should be scaled on width or height.
3190  // Also append any default values to the map (e.g. "lossy", "lossless", ...)
3191  $handler->normaliseParams( $file, $normalParams );
3192  // Check if this standard thumbnail size maps to the given width
3193  if ( $normalParams['width'] == $params['width'] ) {
3194  $match = true;
3195  break;
3196  }
3197  }
3198  if ( !$match ) {
3199  return false; // not standard for description pages
3200  }
3201  }
3202 
3203  // Check that the given values for non-page, non-width, params are just defaults
3204  foreach ( $params as $key => $value ) {
3205  if ( !isset( $normalParams[$key] ) || $normalParams[$key] != $value ) {
3206  return false;
3207  }
3208  }
3209 
3210  return true;
3211 }
3212 
3225 function wfArrayPlus2d( array $baseArray, array $newValues ) {
3226  // First merge items that are in both arrays
3227  foreach ( $baseArray as $name => &$groupVal ) {
3228  if ( isset( $newValues[$name] ) ) {
3229  $groupVal += $newValues[$name];
3230  }
3231  }
3232  // Now add items that didn't exist yet
3233  $baseArray += $newValues;
3234 
3235  return $baseArray;
3236 }
3237 
3246 function wfGetRusage() {
3247  if ( !function_exists( 'getrusage' ) ) {
3248  return false;
3249  } elseif ( defined( 'HHVM_VERSION' ) && PHP_OS === 'Linux' ) {
3250  return getrusage( 2 /* RUSAGE_THREAD */ );
3251  } else {
3252  return getrusage( 0 /* RUSAGE_SELF */ );
3253  }
3254 }
$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. 'ContentSecurityPolicyDefaultSource':Modify the allowed CSP load sources. This affects all directives except for the script directive. If you want to add a script source, see ContentSecurityPolicyScriptSource hook. & $defaultSrc:Array of Content-Security-Policy allowed sources $policyConfig:Current configuration for the Content-Security-Policy header $mode:ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE depending on type of header 'ContentSecurityPolicyDirectives':Modify the content security policy directives. Use this only if ContentSecurityPolicyDefaultSource and ContentSecurityPolicyScriptSource do not meet your needs. & $directives:Array of CSP directives $policyConfig:Current configuration for the CSP header $mode:ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE depending on type of header 'ContentSecurityPolicyScriptSource':Modify the allowed CSP script sources. Note that you also have to use ContentSecurityPolicyDefaultSource if you want non-script sources to be loaded from whatever you add. & $scriptSrc:Array of CSP directives $policyConfig:Current configuration for the CSP header $mode:ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE depending on type of header '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:1266
$wgPhpCli
$wgPhpCli
Executable path of the PHP cli binary.
Definition: DefaultSettings.php:8311
wfArrayInsertAfter
wfArrayInsertAfter(array $array, array $insert, $after)
Insert array into another array after the specified KEY
Definition: GlobalFunctions.php:231
MediaWiki\Shell\Shell
Executes shell commands.
Definition: Shell.php:44
$user
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1476
wfMergeErrorArrays
wfMergeErrorArrays(... $args)
Merge arrays in the style of getUserPermissionsErrors, with duplicate removal e.g.
Definition: GlobalFunctions.php:205
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:306
wfPercent
wfPercent( $nr, $acc=2, $round=true)
Definition: GlobalFunctions.php:2076
wfResetOutputBuffers
wfResetOutputBuffers( $resetGzipEncoding=true)
Clear away any user-level output buffers, discarding contents.
Definition: GlobalFunctions.php:1722
wfMessageFallback
wfMessageFallback(... $keys)
This function accepts multiple message keys and returns a message instance for the first message whic...
Definition: GlobalFunctions.php:1313
$wgThumbLimits
$wgThumbLimits
Adjust thumbnails on image pages according to a user setting.
Definition: DefaultSettings.php:1459
PROTO_CANONICAL
const PROTO_CANONICAL
Definition: Defines.php:223
wfBCP47
wfBCP47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: GlobalFunctions.php:2950
RepoGroup\singleton
static singleton()
Get a RepoGroup instance.
Definition: RepoGroup.php:61
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Definition: router.php:42
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:3106
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
$wgDBname
controlled by the following MediaWiki still creates a BagOStuff but calls it to it are no ops If the cache daemon can t be it should also disable itself fairly $wgDBname
Definition: memcached.txt:93
ObjectCache\getLocalClusterInstance
static getLocalClusterInstance()
Get the main cluster-local cache object.
Definition: ObjectCache.php:356
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:224
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:2636
wfDiff
wfDiff( $before, $after, $params='-u')
Returns unified plain-text diff of two texts.
Definition: GlobalFunctions.php:2348
$wgResponsiveImages
$wgResponsiveImages
Generate and use thumbnails suitable for screens with 1.5 and 2.0 pixel densities.
Definition: DefaultSettings.php:1578
wfSetupSession
wfSetupSession( $sessionId=false)
Initialise php session.
Definition: GlobalFunctions.php:2519
$wgDebugRawPage
$wgDebugRawPage
If true, log debugging data from action=raw and load.php.
Definition: DefaultSettings.php:6112
wfThumbIsStandard
wfThumbIsStandard(File $file, array $params)
Returns true if these thumbnail parameters match one that MediaWiki requests from file description pa...
Definition: GlobalFunctions.php:3139
$wgTmpDirectory
$wgTmpDirectory
The local filesystem path to a temporary directory.
Definition: DefaultSettings.php:339
wfArrayPlus2d
wfArrayPlus2d(array $baseArray, array $newValues)
Merges two (possibly) 2 dimensional arrays into the target array ($baseArray).
Definition: GlobalFunctions.php:3225
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:2008
wfArrayFilter
wfArrayFilter(array $arr, callable $callback)
Definition: GlobalFunctions.php:150
$wgDiff3
$wgDiff3
Path to the GNU diff3 utility.
Definition: DefaultSettings.php:6661
wfMerge
wfMerge( $old, $mine, $yours, &$result, &$mergeAttemptResult=null)
wfMerge attempts to merge differences between three texts.
Definition: GlobalFunctions.php:2265
wfDebugBacktrace
wfDebugBacktrace( $limit=0)
Safety wrapper for debug_backtrace().
Definition: GlobalFunctions.php:1415
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:1633
captcha-old.count
count
Definition: captcha-old.py:249
wfGetLB
wfGetLB( $wiki=false)
Get a load balancer object.
Definition: GlobalFunctions.php:2649
wfFormatStackFrame
wfFormatStackFrame( $frame)
Return a string representation of frame.
Definition: GlobalFunctions.php:1511
wfRemoveDotSegments
wfRemoveDotSegments( $urlPath)
Remove all dot-segments in the provided URL path.
Definition: GlobalFunctions.php:665
$wgScript
$wgScript
The URL path to index.php.
Definition: DefaultSettings.php:186
wfSetBit
wfSetBit(&$dest, $bit, $state=true)
As for wfSetVar except setting a bit.
Definition: GlobalFunctions.php:1650
Skin\makeVariablesScript
static makeVariablesScript( $data, $nonce=null)
Definition: Skin.php:399
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:1850
wfMakeUrlIndexes
wfMakeUrlIndexes( $url)
Make URL indexes, appropriate for the el_index field of externallinks.
Definition: GlobalFunctions.php:904
$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. '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 '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 since 1.28! 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:1983
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1912
SiteStats\pages
static pages()
Definition: SiteStats.php:112
$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 When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:780
wfUnpack
wfUnpack( $format, $data, $length=false)
Wrapper around php's unpack.
Definition: GlobalFunctions.php:3000
wfConfiguredReadOnlyReason
wfConfiguredReadOnlyReason()
Get the value of $wgReadOnly or the contents of $wgReadOnlyFile.
Definition: GlobalFunctions.php:1221
MessageSpecifier
Definition: MessageSpecifier.php:21
$wgShowHostnames
$wgShowHostnames
Expose backend server host names through the API and various HTML comments.
Definition: DefaultSettings.php:6316
wfObjectToArray
wfObjectToArray( $objOrArray, $recursive=true)
Recursively converts the parameter (an object) to an array with the same data.
Definition: GlobalFunctions.php:254
wfSuppressWarnings
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
Definition: GlobalFunctions.php:1892
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:333
wfArrayDiff2_cmp
wfArrayDiff2_cmp( $a, $b)
Definition: GlobalFunctions.php:120
wfGetScriptUrl
wfGetScriptUrl()
Get the script URL.
Definition: GlobalFunctions.php:2730
$wgMessageCacheType
$wgMessageCacheType
The cache type for storing the contents of the MediaWiki namespace.
Definition: DefaultSettings.php:2344
ProfilerStub
Stub profiler that does nothing.
Definition: ProfilerStub.php:29
$wgDiff
$wgDiff
Path to the GNU diff utility.
Definition: DefaultSettings.php:6666
wfBaseName
wfBaseName( $path, $suffix='')
Return the final portion of a pathname.
Definition: GlobalFunctions.php:2428
wfQueriesMustScale
wfQueriesMustScale()
Should low-performance queries be disabled?
Definition: GlobalFunctions.php:2698
$params
$params
Definition: styleTest.css.php:44
wfHostname
wfHostname()
Fetch server name for use in error reporting etc.
Definition: GlobalFunctions.php:1352
wfReadOnly
wfReadOnly()
Check whether the wiki is in read-only mode.
Definition: GlobalFunctions.php:1197
wfMsgReplaceArgs
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
Definition: GlobalFunctions.php:1325
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1290
$s
$s
Definition: mergeMessageFileList.php:186
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1105
$last
$last
Definition: profileinfo.php:416
wfStringToBool
wfStringToBool( $val)
Convert string value to boolean, when the following are interpreted as true:
Definition: GlobalFunctions.php:2120
wfArrayFilterByKey
wfArrayFilterByKey(array $arr, callable $callback)
Definition: GlobalFunctions.php:163
$wgTransactionalTimeLimit
$wgTransactionalTimeLimit
The minimum amount of time that MediaWiki needs for "slow" write request, particularly ones with mult...
Definition: DefaultSettings.php:2300
$wgDebugLogPrefix
$wgDebugLogPrefix
Prefix for debug log lines.
Definition: DefaultSettings.php:6098
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:887
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:2790
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:1043
$wgDBprefix
$wgDBprefix
Table name prefix.
Definition: DefaultSettings.php:1941
wfShellWikiCmd
wfShellWikiCmd( $script, array $parameters=[], array $options=[])
Generate a shell-escaped command line string to run a MediaWiki cli script.
Definition: GlobalFunctions.php:2240
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
LinkFilter\makeIndexes
static makeIndexes( $url)
Converts a URL into a format for el_index.
Definition: LinkFilter.php:171
wfBoolToStr
wfBoolToStr( $value)
Convenience function converts boolean values into "true" or "false" (string) values.
Definition: GlobalFunctions.php:2755
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:463
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:98
$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:1588
$data
$data
Utility to generate mapping file used in mw.Title (phpCharToUpper.json)
Definition: generatePhpCharToUpperMappings.php:13
wfParseUrl
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
Definition: GlobalFunctions.php:817
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:52
wfReportTime
wfReportTime( $nonce=null)
Returns a script tag that stores the amount of time it took MediaWiki to handle the request in millis...
Definition: GlobalFunctions.php:1392
wfGetMainCache
wfGetMainCache()
Get the main cache object.
Definition: GlobalFunctions.php:2972
MWException
MediaWiki exception.
Definition: MWException.php:26
wfStripIllegalFilenameChars
wfStripIllegalFilenameChars( $name)
Replace all invalid characters with '-'.
Definition: GlobalFunctions.php:2849
wfGetRusage
wfGetRusage()
Get system resource usage of current request context.
Definition: GlobalFunctions.php:3246
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:925
mimeTypeMatch
mimeTypeMatch( $type, $avail)
Checks if a given MIME type matches any of the keys in the given array.
Definition: GlobalFunctions.php:1822
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1078
wfRestoreWarnings
wfRestoreWarnings()
Definition: GlobalFunctions.php:1900
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2714
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:1187
FileBackend\isStoragePath
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
Definition: FileBackend.php:1419
$blob
$blob
Definition: testCompression.php:65
$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 When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output 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:780
wfTransactionalTimeLimit
wfTransactionalTimeLimit()
Set PHP's time limit to the larger of php.ini or $wgTransactionalTimeLimit.
Definition: GlobalFunctions.php:2895
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2636
wfUrlProtocolsWithoutProtRel
wfUrlProtocolsWithoutProtRel()
Like wfUrlProtocols(), but excludes '//' from the protocol list.
Definition: GlobalFunctions.php:788
$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:6222
$wgLang
$wgLang
Definition: Setup.php:875
$wgLoadScript
$wgLoadScript
The URL path to load.php.
Definition: DefaultSettings.php:194
wfTimestampOrNull
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
Definition: GlobalFunctions.php:1928
$IP
$IP
Definition: update.php:3
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:222
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:1241
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
$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 When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
Definition: hooks.txt:780
wfCgiToArray
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
Definition: GlobalFunctions.php:416
$lines
$lines
Definition: router.php:61
wfLoadSkins
wfLoadSkins(array $skins)
Load multiple skins at once.
Definition: GlobalFunctions.php:97
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:2962
$wgEnableMagicLinks
$wgEnableMagicLinks
Enable the magic links feature of automatically turning ISBN xxx, PMID xxx, RFC xxx into links.
Definition: DefaultSettings.php:4333
$output
$output
Definition: SyntaxHighlight.php:334
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1941
wfMemoryLimit
wfMemoryLimit()
Set PHP's memory limit to the larger of php.ini or $wgMemoryLimit.
Definition: GlobalFunctions.php:2867
array
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
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:949
wfAcceptToPrefs
wfAcceptToPrefs( $accept, $def=' */*')
Converts an Accept-* header into an array mapping string values to quality factors.
Definition: GlobalFunctions.php:1786
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
PROTO_HTTPS
const PROTO_HTTPS
Definition: Defines.php:220
$wgCanonicalServer
$wgCanonicalServer
Canonical URL of the server, to use in IRC feeds and notification e-mails.
Definition: DefaultSettings.php:115
$wgMemoryLimit
$wgMemoryLimit
The minimum amount of memory that MediaWiki "needs"; MediaWiki will try to raise PHP's memory limit i...
Definition: DefaultSettings.php:2292
wfIsDebugRawPage
wfIsDebugRawPage()
Returns true if debug logging should be suppressed if $wgDebugRawPage = false.
Definition: GlobalFunctions.php:983
wfForeignMemcKey
wfForeignMemcKey( $db, $prefix,... $args)
Make a cache key for a foreign DB.
Definition: GlobalFunctions.php:2575
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:2636
$wgDebugTimestamps
$wgDebugTimestamps
Prefix debug messages with relative timestamp.
Definition: DefaultSettings.php:6260
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:271
key
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation use $formDescriptor instead default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message key
Definition: hooks.txt:2154
wfUrlProtocols
wfUrlProtocols( $includeProtocolRelative=true)
Returns a regular expression of url protocols.
Definition: GlobalFunctions.php:743
$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:3036
wfLoadExtensions
wfLoadExtensions(array $exts)
Load multiple extensions at once.
Definition: GlobalFunctions.php:66
wfGlobalCacheKey
wfGlobalCacheKey(... $args)
Make a cache key with database-agnostic prefix.
Definition: GlobalFunctions.php:2592
wfWikiID
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Definition: GlobalFunctions.php:2602
wfClearOutputBuffers
wfClearOutputBuffers()
More legible than passing a 'false' parameter to wfResetOutputBuffers():
Definition: GlobalFunctions.php:1774
$value
$value
Definition: styleTest.css.php:49
wfClientAcceptsGzip
wfClientAcceptsGzip( $force=false)
Whether the client accept gzip encoding.
Definition: GlobalFunctions.php:1542
$wgUrlProtocols
$wgUrlProtocols
URL schemes that should be recognized as valid by wfParseUrl().
Definition: DefaultSettings.php:4170
$wgExtensionDirectory
$wgExtensionDirectory
Filesystem extensions directory.
Definition: DefaultSettings.php:223
wfIsCLI
wfIsCLI()
Check if we are running from the commandline.
Definition: GlobalFunctions.php:1974
wfIsWindows
wfIsWindows()
Check if the operating system is Windows.
Definition: GlobalFunctions.php:1951
$wgServer
$wgServer
URL of the server.
Definition: DefaultSettings.php:106
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:2912
wfIsInfinity
wfIsInfinity( $str)
Determine input string is represents as infinity.
Definition: GlobalFunctions.php:3119
wfDebugMem
wfDebugMem( $exact=false)
Send a line giving PHP memory usage.
Definition: GlobalFunctions.php:1008
PROTO_HTTP
const PROTO_HTTP
Definition: Defines.php:219
$wgDirectoryMode
$wgDirectoryMode
Default value for chmoding of new directories.
Definition: DefaultSettings.php:1570
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1577
$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:1985
wfAppendToArrayIfNotDefault
wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed)
Appends to second array if $value differs from that in $default.
Definition: GlobalFunctions.php:177
$wgDisableOutputCompression
$wgDisableOutputCompression
Disable output compression (enabled by default if zlib is available)
Definition: DefaultSettings.php:3396
wfVarDump
wfVarDump( $var)
A wrapper around the PHP function var_export().
Definition: GlobalFunctions.php:1668
$wgIllegalFileChars
$wgIllegalFileChars
Additional characters that are not allowed in filenames.
Definition: DefaultSettings.php:418
wfGetNull
wfGetNull()
Get a platform-independent path to the null file, e.g.
Definition: GlobalFunctions.php:2764
TempFSFile\getUsableTempDirectory
static getUsableTempDirectory()
Definition: TempFSFile.php:85
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:430
wfGetLBFactory
wfGetLBFactory()
Get the load balancer factory object.
Definition: GlobalFunctions.php:2665
wfIniGetBool
wfIniGetBool( $setting)
Safety wrapper around ini_get() for boolean settings.
Definition: GlobalFunctions.php:2104
$wgOverrideHostname
$wgOverrideHostname
Override server hostname detection with a hardcoded value.
Definition: DefaultSettings.php:6323
wfFindFile
wfFindFile( $title, $options=[])
Find a file.
Definition: GlobalFunctions.php:2677
wfGetAllCallers
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
Definition: GlobalFunctions.php:1496
wfLoadExtension
wfLoadExtension( $ext, $path=null)
Load an extension.
Definition: GlobalFunctions.php:45
wfGetMessageCacheStorage
wfGetMessageCacheStorage()
Get the cache object used by the message cache.
Definition: GlobalFunctions.php:2981
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:142
$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:2916
$wgImageLimits
$wgImageLimits
Limit images on image description pages to a user-selectable limit.
Definition: DefaultSettings.php:1446
wfRandom
wfRandom()
Get a random decimal value in the domain of [0, 1), in a way not likely to give duplicate values for ...
Definition: GlobalFunctions.php:280
wfTempDir
wfTempDir()
Tries to get the system directory for temporary files.
Definition: GlobalFunctions.php:1989
$wgMiserMode
$wgMiserMode
Disable database-intensive features.
Definition: DefaultSettings.php:2256
wfHttpError
wfHttpError( $code, $label, $desc)
Provide a simple HTTP error.
Definition: GlobalFunctions.php:1685
wfReadOnlyReason
wfReadOnlyReason()
Check if the site is in read-only mode and return the message if so.
Definition: GlobalFunctions.php:1210
wfMatchesDomainList
wfMatchesDomainList( $url, $domains)
Check whether a given URL has a domain that occurs in a given set of domains.
Definition: GlobalFunctions.php:915
$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:1985
wfGetPrecompiledData
wfGetPrecompiledData( $name)
Get an object from the precompiled serialized directory.
Definition: GlobalFunctions.php:2541
wfRecursiveRemoveDir
wfRecursiveRemoveDir( $dir)
Remove a directory and all its content.
Definition: GlobalFunctions.php:2051
$wgHttpsPort
$wgHttpsPort
For installations where the canonical server is HTTP but HTTPS is optionally supported,...
Definition: DefaultSettings.php:8639
$path
$path
Definition: NoLocalSettings.php:25
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:179
$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:1985
$keys
$keys
Definition: testCompression.php:67
wfBacktrace
wfBacktrace( $raw=null)
Get a debug backtrace as a string.
Definition: GlobalFunctions.php:1443
wfEscapeShellArg
wfEscapeShellArg(... $args)
Version of escapeshellarg() that works better on Windows.
Definition: GlobalFunctions.php:2141
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:611
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
wfRelativePath
wfRelativePath( $path, $from)
Generate a relative path name to the given file.
Definition: GlobalFunctions.php:2452
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:215
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:1092
Title\legalChars
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:669
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:728
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
wfMemcKey
wfMemcKey(... $args)
Make a cache key for the local wiki.
Definition: GlobalFunctions.php:2561
Language\fetchLanguageNames
static fetchLanguageNames( $inLanguage=self::AS_AUTONYMS, $include='mw')
Get an array of language names, indexed by code.
Definition: Language.php:836
$wgOut
$wgOut
Definition: Setup.php:880
wfGetServerUrl
wfGetServerUrl( $proto)
Get the wiki's "server", i.e.
Definition: GlobalFunctions.php:593
wfIsHHVM
wfIsHHVM()
Check if we are running under HHVM.
Definition: GlobalFunctions.php:1964
$wgScriptPath
$wgScriptPath
The path we should point to.
Definition: DefaultSettings.php:138
wfLocalFile
wfLocalFile( $title)
Get an object referring to a locally registered file.
Definition: GlobalFunctions.php:2688
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
wfShowingResults
wfShowingResults( $offset, $limit)
Definition: GlobalFunctions.php:1529
wfResetSessionID
wfResetSessionID()
Reset the session id.
Definition: GlobalFunctions.php:2494
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:1480
$wgStyleDirectory
$wgStyleDirectory
Filesystem stylesheets directory.
Definition: DefaultSettings.php:230
wfLogDBError
wfLogDBError( $text, array $context=[])
Log for database errors.
Definition: GlobalFunctions.php:1061
SiteStats\edits
static edits()
Definition: SiteStats.php:94
$wgInternalServer
$wgInternalServer
Internal server name as known to CDN, if different.
Definition: DefaultSettings.php:2742
wfCountDown
wfCountDown( $seconds)
Count down from $seconds to zero on the terminal, with a one-second pause between showing each number...
Definition: GlobalFunctions.php:2826
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:515
wfShellExecWithStderr
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
Definition: GlobalFunctions.php:2221
MediaWiki\HeaderCallback\warnIfHeadersSent
static warnIfHeadersSent()
Log a warning message if headers have already been sent.
Definition: HeaderCallback.php:61
wfLogProfilingData
wfLogProfilingData()
Definition: GlobalFunctions.php:1113
ObjectCache\getLocalServerInstance
static getLocalServerInstance( $fallback=CACHE_NONE)
Factory function for CACHE_ACCEL (referenced from DefaultSettings.php)
Definition: ObjectCache.php:279
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:2168
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:371
wfRandomString
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
Definition: GlobalFunctions.php:298
$type
$type
Definition: testCompression.php:48