doc: Fix a few Example docs for PHP classes
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index 4e60e63..92cb8d8 100644 (file)
@@ -27,6 +27,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
 use Liuggio\StatsdClient\Sender\SocketSender;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\Session\SessionManager;
+use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\DBReplicationWaitError;
 
@@ -202,6 +203,38 @@ function wfArrayDiff2_cmp( $a, $b ) {
        }
 }
 
+/**
+ * Like array_filter with ARRAY_FILTER_USE_BOTH, but works pre-5.6.
+ *
+ * @param array $arr
+ * @param callable $callback Will be called with the array value and key (in that order) and
+ *   should return a bool which will determine whether the array element is kept.
+ * @return array
+ */
+function wfArrayFilter( array $arr, callable $callback ) {
+       if ( defined( 'ARRAY_FILTER_USE_BOTH' ) ) {
+               return array_filter( $arr, $callback, ARRAY_FILTER_USE_BOTH );
+       }
+       $filteredKeys = array_filter( array_keys( $arr ), function ( $key ) use ( $arr, $callback ) {
+               return call_user_func( $callback, $arr[$key], $key );
+       } );
+       return array_intersect_key( $arr, array_fill_keys( $filteredKeys, true ) );
+}
+
+/**
+ * Like array_filter with ARRAY_FILTER_USE_KEY, but works pre-5.6.
+ *
+ * @param array $arr
+ * @param callable $callback Will be called with the array key and should return a bool which
+ *   will determine whether the array element is kept.
+ * @return array
+ */
+function wfArrayFilterByKey( array $arr, callable $callback ) {
+       return wfArrayFilter( $arr, function ( $val, $key ) use ( $callback ) {
+               return call_user_func( $callback, $key );
+       } );
+}
+
 /**
  * Appends to second array if $value differs from that in $default
  *
@@ -810,10 +843,24 @@ function wfUrlProtocolsWithoutProtRel() {
  * 1) Does not raise warnings on bad URLs (just returns false).
  * 2) Handles protocols that don't use :// (e.g., mailto: and news:, as well as
  *    protocol-relative URLs) correctly.
- * 3) Adds a "delimiter" element to the array, either '://', ':' or '//' (see (2)).
+ * 3) Adds a "delimiter" element to the array (see (2)).
+ * 4) Verifies that the protocol is on the $wgUrlProtocols whitelist.
+ * 5) Rejects some invalid URLs that parse_url doesn't, e.g. the empty string or URLs starting with
+ *    a line feed character.
  *
  * @param string $url A URL to parse
- * @return string[]|bool Bits of the URL in an associative array, per PHP docs, false on failure
+ * @return string[]|bool Bits of the URL in an associative array, or false on failure.
+ *   Possible fields:
+ *   - scheme: URI scheme (protocol), e.g. 'http', 'mailto'. Lowercase, always present, but can
+ *       be an empty string for protocol-relative URLs.
+ *   - delimiter: either '://', ':' or '//'. Always present.
+ *   - host: domain name / IP. Always present, but could be an empty string, e.g. for file: URLs.
+ *   - user: user name, e.g. for HTTP Basic auth URLs such as http://user:pass@example.com/
+ *       Missing when there is no username.
+ *   - pass: password, same as above.
+ *   - path: path including the leading /. Will be missing when empty (e.g. 'http://example.com')
+ *   - query: query string (as a string; see wfCgiToArray() for parsing it), can be missing.
+ *   - fragment: the part after #, can be missing.
  */
 function wfParseUrl( $url ) {
        global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
@@ -1190,7 +1237,8 @@ function wfLogProfilingData() {
        $profiler->logData();
 
        $config = $context->getConfig();
-       if ( $config->get( 'StatsdServer' ) ) {
+       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+       if ( $config->get( 'StatsdServer' ) && $stats->hasData() ) {
                try {
                        $statsdServer = explode( ':', $config->get( 'StatsdServer' ) );
                        $statsdHost = $statsdServer[0];
@@ -1198,7 +1246,7 @@ function wfLogProfilingData() {
                        $statsdSender = new SocketSender( $statsdHost, $statsdPort );
                        $statsdClient = new SamplingStatsdClient( $statsdSender, true, false );
                        $statsdClient->setSamplingRates( $config->get( 'StatsdSamplingRates' ) );
-                       $statsdClient->send( $context->getStats()->getBuffer() );
+                       $statsdClient->send( $stats->getData() );
                } catch ( Exception $ex ) {
                        MWExceptionHandler::logException( $ex );
                }
@@ -1263,7 +1311,7 @@ function wfLogProfilingData() {
  * @return void
  */
 function wfIncrStats( $key, $count = 1 ) {
-       $stats = RequestContext::getMain()->getStats();
+       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
        $stats->updateCount( $key, $count );
 }
 
@@ -1273,7 +1321,8 @@ function wfIncrStats( $key, $count = 1 ) {
  * @return bool
  */
 function wfReadOnly() {
-       return wfReadOnlyReason() !== false;
+       return MediaWikiServices::getInstance()->getReadOnlyMode()
+               ->isReadOnly();
 }
 
 /**
@@ -1285,19 +1334,8 @@ function wfReadOnly() {
  * @return string|bool String when in read-only mode; false otherwise
  */
 function wfReadOnlyReason() {
-       $readOnly = wfConfiguredReadOnlyReason();
-       if ( $readOnly !== false ) {
-               return $readOnly;
-       }
-
-       static $lbReadOnly = null;
-       if ( $lbReadOnly === null ) {
-               // Callers use this method to be aware that data presented to a user
-               // may be very stale and thus allowing submissions can be problematic.
-               $lbReadOnly = wfGetLB()->getReadOnlyReason();
-       }
-
-       return $lbReadOnly;
+       return MediaWikiServices::getInstance()->getReadOnlyMode()
+               ->getReason();
 }
 
 /**
@@ -1307,18 +1345,8 @@ function wfReadOnlyReason() {
  * @since 1.27
  */
 function wfConfiguredReadOnlyReason() {
-       global $wgReadOnly, $wgReadOnlyFile;
-
-       if ( $wgReadOnly === null ) {
-               // Set $wgReadOnly for faster access next time
-               if ( is_file( $wgReadOnlyFile ) && filesize( $wgReadOnlyFile ) > 0 ) {
-                       $wgReadOnly = file_get_contents( $wgReadOnlyFile );
-               } else {
-                       $wgReadOnly = false;
-               }
-       }
-
-       return $wgReadOnly;
+       return MediaWikiServices::getInstance()->getConfiguredReadOnlyMode()
+               ->getReason();
 }
 
 /**
@@ -1453,7 +1481,6 @@ function wfMsgReplaceArgs( $message, $args ) {
 function wfHostname() {
        static $host;
        if ( is_null( $host ) ) {
-
                # Hostname overriding
                global $wgOverrideHostname;
                if ( $wgOverrideHostname !== false ) {
@@ -2211,8 +2238,6 @@ function wfIniGetBool( $setting ) {
  * @return string
  */
 function wfEscapeShellArg( /*...*/ ) {
-       wfInitShellLocale();
-
        $args = func_get_args();
        if ( count( $args ) === 1 && is_array( reset( $args ) ) ) {
                // If only one argument has been passed, and that argument is an array,
@@ -2327,8 +2352,6 @@ function wfShellExec( $cmd, &$retval = null, $environ = [],
        $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
        $profileMethod = isset( $options['profileMethod'] ) ? $options['profileMethod'] : wfGetCaller();
 
-       wfInitShellLocale();
-
        $envcmd = '';
        foreach ( $environ as $k => $v ) {
                if ( wfIsWindows() ) {
@@ -2552,18 +2575,14 @@ function wfShellExecWithStderr( $cmd, &$retval = null, $environ = [], $limits =
 }
 
 /**
- * Workaround for https://bugs.php.net/bug.php?id=45132
- * escapeshellarg() destroys non-ASCII characters if LANG is not a UTF-8 locale
+ * Formerly set the locale for locale-sensitive operations
+ *
+ * This is now done in Setup.php.
+ *
+ * @deprecated since 1.30, no longer needed
+ * @see $wgShellLocale
  */
 function wfInitShellLocale() {
-       static $done = false;
-       if ( $done ) {
-               return;
-       }
-       $done = true;
-       global $wgShellLocale;
-       putenv( "LC_CTYPE=$wgShellLocale" );
-       setlocale( LC_CTYPE, $wgShellLocale );
 }
 
 /**
@@ -2973,6 +2992,7 @@ function wfGetPrecompiledData( $name ) {
 /**
  * Make a cache key for the local wiki.
  *
+ * @deprecated since 1.30 Call makeKey on a BagOStuff instance
  * @param string $args,...
  * @return string
  */
@@ -3009,6 +3029,7 @@ function wfForeignMemcKey( $db, $prefix /*...*/ ) {
  * instead. Must have a prefix as otherwise keys that use a database name
  * in the first segment will clash with wfMemcKey/wfForeignMemcKey.
  *
+ * @deprecated since 1.30 Call makeGlobalKey on a BagOStuff instance
  * @since 1.26
  * @param string $args,...
  * @return string
@@ -3090,9 +3111,9 @@ function wfGetDB( $db, $groups = [], $wiki = false ) {
  */
 function wfGetLB( $wiki = false ) {
        if ( $wiki === false ) {
-               return \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancer();
+               return MediaWikiServices::getInstance()->getDBLoadBalancer();
        } else {
-               $factory = \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                return $factory->getMainLB( $wiki );
        }
 }
@@ -3105,7 +3126,7 @@ function wfGetLB( $wiki = false ) {
  * @return \Wikimedia\Rdbms\LBFactory
  */
 function wfGetLBFactory() {
-       return \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+       return MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
 }
 
 /**
@@ -3440,6 +3461,7 @@ function wfGetMessageCacheStorage() {
 /**
  * Get the cache object used by the parser cache
  *
+ * @deprecated since 1.30, use MediaWikiServices::getParserCache()->getCacheStorage()
  * @return BagOStuff
  */
 function wfGetParserCacheStorage() {
@@ -3524,7 +3546,9 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
        }
 
        $cache = ObjectCache::getLocalServerInstance( 'hash' );
-       $key = wfMemcKey( 'bad-image-list', ( $blacklist === null ) ? 'default' : md5( $blacklist ) );
+       $key = $cache->makeKey(
+               'bad-image-list', ( $blacklist === null ) ? 'default' : md5( $blacklist )
+       );
        $badImages = $cache->get( $key );
 
        if ( $badImages === false ) { // cache miss