Merge "Only need one check for is_dir"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 12 Apr 2015 18:29:36 +0000 (18:29 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 12 Apr 2015 18:29:36 +0000 (18:29 +0000)
1  2 
includes/GlobalFunctions.php

@@@ -24,10 -24,6 +24,10 @@@ if ( !defined( 'MEDIAWIKI' ) ) 
        die( "This file is part of MediaWiki, it is not a valid entry point" );
  }
  
 +use Liuggio\StatsdClient\StatsdClient;
 +use Liuggio\StatsdClient\Sender\SocketSender;
 +use MediaWiki\Logger\LoggerFactory;
 +
  // Hide compatibility functions from Doxygen
  /// @cond
  
@@@ -167,8 -163,12 +167,8 @@@ if ( !function_exists( 'hash_equals' ) 
  /**
   * Load an extension
   *
 - * This is the closest equivalent to:
 - *   require_once "$IP/extensions/$name/$name.php";
 - * as it will process and load the extension immediately.
 - *
 - * However, batch loading with wfLoadExtensions will
 - * be more performant.
 + * This queues an extension to be loaded through
 + * the ExtensionRegistry system.
   *
   * @param string $name Name of the extension to load
   * @param string|null $path Absolute path of where to find the extension.json file
@@@ -178,7 -178,7 +178,7 @@@ function wfLoadExtension( $name, $path 
                global $IP;
                $path = "$IP/extensions/$name/extension.json";
        }
 -      ExtensionRegistry::getInstance()->load( $path );
 +      ExtensionRegistry::getInstance()->queue( $path );
  }
  
  /**
@@@ -199,6 -199,8 +199,6 @@@ function wfLoadExtensions( array $exts 
        foreach ( $exts as $ext ) {
                $registry->queue( "$IP/extensions/$ext/extension.json" );
        }
 -
 -      $registry->loadFromQueue();
  }
  
  /**
@@@ -213,7 -215,7 +213,7 @@@ function wfLoadSkin( $name, $path = nul
                global $IP;
                $path = "$IP/skins/$name/skin.json";
        }
 -      ExtensionRegistry::getInstance()->load( $path );
 +      ExtensionRegistry::getInstance()->queue( $path );
  }
  
  /**
@@@ -228,6 -230,8 +228,6 @@@ function wfLoadSkins( array $skins ) 
        foreach ( $skins as $skin ) {
                $registry->queue( "$IP/skins/$skin/skin.json" );
        }
 -
 -      $registry->loadFromQueue();
  }
  
  /**
@@@ -1023,7 -1027,12 +1023,7 @@@ function wfMatchesDomainList( $url, $do
   * @since 1.25 support for additional context data
   *
   * @param string $text
 - * @param string|bool $dest Destination of the message:
 - *     - 'all': both to the log and HTML (debug toolbar or HTML comments)
 - *     - 'log': only to the log and not in HTML
 - *   For backward compatibility, it can also take a boolean:
 - *     - true: same as 'all'
 - *     - false: same as 'log'
 + * @param string|bool $dest Unused
   * @param array $context Additional logging context data
   */
  function wfDebug( $text, $dest = 'all', array $context = array() ) {
                return;
        }
  
 -      // Turn $dest into a string if it's a boolean (for b/c)
 -      if ( $dest === true ) {
 -              $dest = 'all';
 -      } elseif ( $dest === false ) {
 -              $dest = 'log';
 -      }
 -
        $text = trim( $text );
  
        // Inline logic from deprecated wfDebugTimer()
                );
        }
  
 -      if ( $dest === 'all' ) {
 -              $prefix = '';
 -              if ( $wgDebugTimestamps ) {
 -                      // Prepend elapsed request time and real memory usage with two
 -                      // trailing spaces.
 -                      $prefix = "{$context['seconds_elapsed']} {$context['memory_used']}  ";
 -              }
 -              MWDebug::debugMsg( "{$prefix}{$text}" );
 -      }
 -
        if ( $wgDebugLogPrefix !== '' ) {
                $context['prefix'] = $wgDebugLogPrefix;
        }
  
 -      $logger = MWLoggerFactory::getInstance( 'wfDebug' );
 +      $logger = LoggerFactory::getInstance( 'wfDebug' );
        $logger->debug( $text, $context );
  }
  
@@@ -1152,7 -1178,11 +1152,7 @@@ function wfDebugLog
  
        $text = trim( $text );
  
 -      if ( $dest === 'all' ) {
 -              MWDebug::debugMsg( "[{$logGroup}] {$text}\n" );
 -      }
 -
 -      $logger = MWLoggerFactory::getInstance( $logGroup );
 +      $logger = LoggerFactory::getInstance( $logGroup );
        $context['private'] = ( $dest === 'private' );
        $logger->info( $text, $context );
  }
   * @param array $context Additional logging context data
   */
  function wfLogDBError( $text, array $context = array() ) {
 -      $logger = MWLoggerFactory::getInstance( 'wfLogDBError' );
 +      $logger = LoggerFactory::getInstance( 'wfLogDBError' );
        $logger->error( trim( $text ), $context );
  }
  
@@@ -1225,11 -1255,11 +1225,11 @@@ function wfLogWarning( $msg, $callerOff
   * @param string $file Filename
   * @param array $context Additional logging context data
   * @throws MWException
 - * @deprecated since 1.25 Use MWLoggerLegacyLogger::emit or UDPTransport
 + * @deprecated since 1.25 Use MediaWiki\Logger\LegacyLogger::emit or UDPTransport
   */
  function wfErrorLog( $text, $file, array $context = array() ) {
        wfDeprecated( __METHOD__, '1.25' );
 -      $logger = MWLoggerFactory::getInstance( 'wfErrorLog' );
 +      $logger = LoggerFactory::getInstance( 'wfErrorLog' );
        $context['destination'] = $file;
        $logger->info( trim( $text ), $context );
  }
   * @todo document
   */
  function wfLogProfilingData() {
 -      global $wgRequestTime, $wgDebugLogGroups, $wgDebugRawPage;
 -      global $wgProfileLimit, $wgUser, $wgRequest;
 +      global $wgDebugLogGroups, $wgDebugRawPage;
  
 -      StatCounter::singleton()->flush();
 +      $context = RequestContext::getMain();
 +      $request = $context->getRequest();
  
        $profiler = Profiler::instance();
 +      $profiler->setContext( $context );
 +      $profiler->logData();
  
 -      # Profiling must actually be enabled...
 -      if ( $profiler instanceof ProfilerStub ) {
 -              return;
 +      $config = $context->getConfig();
 +      if ( $config->has( 'StatsdServer' ) ) {
 +              $statsdServer = explode( ':', $config->get( 'StatsdServer' ) );
 +              $statsdHost = $statsdServer[0];
 +              $statsdPort = isset( $statsdServer[1] ) ? $statsdServer[1] : 8125;
 +              $statsdSender = new SocketSender( $statsdHost, $statsdPort );
 +              $statsdClient = new StatsdClient( $statsdSender );
 +              $statsdClient->send( $context->getStats()->getBuffer() );
        }
  
 -      // Get total page request time and only show pages that longer than
 -      // $wgProfileLimit time (default is 0)
 -      $elapsed = microtime( true ) - $wgRequestTime;
 -      if ( $elapsed <= $wgProfileLimit ) {
 +      # Profiling must actually be enabled...
 +      if ( $profiler instanceof ProfilerStub ) {
                return;
        }
  
 -      $profiler->logData();
 -
        if ( isset( $wgDebugLogGroups['profileoutput'] )
                && $wgDebugLogGroups['profileoutput'] === false
        ) {
                return;
        }
  
 -      $ctx = array( 'elapsed' => $elapsed );
 +      $ctx = array( 'elapsed' => $request->getElapsedTime() );
        if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
                $ctx['forwarded_for'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
        // Don't load $wgUser at this late stage just for statistics purposes
        // @todo FIXME: We can detect some anons even if it is not loaded.
        // See User::getId()
 -      if ( $wgUser->isItemLoaded( 'id' ) && $wgUser->isAnon() ) {
 -              $ctx['anon'] = true;
 -      } else {
 -              $ctx['anon'] = false;
 -      }
 +      $user = $context->getUser();
 +      $ctx['anon'] = $user->isItemLoaded( 'id' ) && $user->isAnon();
  
        // Command line script uses a FauxRequest object which does not have
        // any knowledge about an URL and throw an exception instead.
        try {
 -              $ctx['url'] = urldecode( $wgRequest->getRequestURL() );
 +              $ctx['url'] = urldecode( $request->getRequestURL() );
        } catch ( Exception $ignored ) {
                // no-op
        }
  
        $ctx['output'] = $profiler->getOutput();
  
 -      $log = MWLoggerFactory::getInstance( 'profileoutput' );
 +      $log = LoggerFactory::getInstance( 'profileoutput' );
        $log->info( "Elapsed: {elapsed}; URL: <{url}>\n{output}", $ctx );
  }
  
   * @return void
   */
  function wfIncrStats( $key, $count = 1 ) {
 -      StatCounter::singleton()->incr( $key, $count );
 +      $stats = RequestContext::getMain()->getStats();
 +      $stats->updateCount( $key, $count );
  }
  
  /**
@@@ -1344,12 -1373,6 +1344,12 @@@ function wfReadOnlyReason() 
                } else {
                        $wgReadOnly = false;
                }
 +              // Callers use this method to be aware that data presented to a user
 +              // may be very stale and thus allowing submissions can be problematic.
 +              if ( $wgReadOnly === false && wfGetLB()->getLaggedSlaveMode() ) {
 +                      $wgReadOnly = 'The database has been automatically locked ' .
 +                              'while the slave database servers catch up to the master';
 +              }
        }
  
        return $wgReadOnly;
@@@ -2473,6 -2496,20 +2473,6 @@@ function wfIsHHVM() 
        return defined( 'HHVM_VERSION' );
  }
  
 -/**
 - * Swap two variables
 - *
 - * @deprecated since 1.24
 - * @param mixed $x
 - * @param mixed $y
 - */
 -function swap( &$x, &$y ) {
 -      wfDeprecated( __FUNCTION__, '1.24' );
 -      $z = $x;
 -      $x = $y;
 -      $y = $z;
 -}
 -
  /**
   * Tries to get the system directory for temporary files. First
   * $wgTmpDirectory is checked, and then the TMPDIR, TMP, and TEMP
@@@ -2521,7 -2558,7 +2521,7 @@@ function wfMkdirParents( $dir, $mode = 
                wfDebug( "$caller: called wfMkdirParents($dir)\n" );
        }
  
-       if ( strval( $dir ) === '' || ( file_exists( $dir ) && is_dir( $dir ) ) ) {
+       if ( strval( $dir ) === '' || is_dir( $dir ) ) {
                return true;
        }
  
@@@ -2623,19 -2660,13 +2623,19 @@@ function wfIniGetBool( $setting ) 
   * Also fixes the locale problems on Linux in PHP 5.2.6+ (bug backported to
   * earlier distro releases of PHP)
   *
 - * @param string $args,...
 + * @param string ... strings to escape and glue together, or a single array of strings parameter
   * @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,
 +              // treat it as a list of arguments
 +              $args = reset( $args );
 +      }
 +
        $first = true;
        $retVal = '';
        foreach ( $args as $arg ) {
@@@ -2726,8 -2757,6 +2726,8 @@@ function wfShellExecDisabled() 
   * @param array $options Array of options:
   *   - duplicateStderr: Set this to true to duplicate stderr to stdout,
   *     including errors from limit.sh
 + *   - profileMethod: By default this function will profile based on the calling
 + *     method. Set this to a string for an alternative method to profile from
   *
   * @return string Collected stdout as a string
   */
@@@ -2746,7 -2775,6 +2746,7 @@@ function wfShellExec( $cmd, &$retval = 
        }
  
        $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
 +      $profileMethod = isset( $options['profileMethod'] ) ? $options['profileMethod'] : wfGetCaller();
  
        wfInitShellLocale();
  
                }
        }
        if ( is_array( $cmd ) ) {
 -              // Command line may be given as an array, escape each value and glue them together with a space
 -              $cmdVals = array();
 -              foreach ( $cmd as $val ) {
 -                      $cmdVals[] = wfEscapeShellArg( $val );
 -              }
 -              $cmd = implode( ' ', $cmdVals );
 +              $cmd = wfEscapeShellArg( $cmd );
        }
  
        $cmd = $envcmd . $cmd;
                $desc[3] = array( 'pipe', 'w' );
        }
        $pipes = null;
 +      $scoped = Profiler::instance()->scopedProfileIn( __FUNCTION__ . '-' . $profileMethod );
        $proc = proc_open( $cmd, $desc, $pipes );
        if ( !$proc ) {
                wfDebugLog( 'exec', "proc_open() failed: $cmd" );
   * @return string Collected stdout and stderr as a string
   */
  function wfShellExecWithStderr( $cmd, &$retval = null, $environ = array(), $limits = array() ) {
 -      return wfShellExec( $cmd, $retval, $environ, $limits, array( 'duplicateStderr' => true ) );
 +      return wfShellExec( $cmd, $retval, $environ, $limits,
 +              array( 'duplicateStderr' => true, 'profileMethod' => wfGetCaller() ) );
  }
  
  /**
@@@ -2988,6 -3019,15 +2988,6 @@@ function wfInitShellLocale() 
        }
  }
  
 -/**
 - * Alias to wfShellWikiCmd()
 - *
 - * @see wfShellWikiCmd()
 - */
 -function wfShellMaintenanceCmd( $script, array $parameters = array(), array $options = array() ) {
 -      return wfShellWikiCmd( $script, $parameters, $options );
 -}
 -
  /**
   * Generate a shell-escaped command line string to run a MediaWiki cli script.
   * Note that $parameters should be a flat array and an option with an argument
@@@ -3011,7 -3051,7 +3011,7 @@@ function wfShellWikiCmd( $script, arra
        }
        $cmd[] = $script;
        // Escape each parameter for shell
 -      return implode( " ", array_map( 'wfEscapeShellArg', array_merge( $cmd, $parameters ) ) );
 +      return wfEscapeShellArg( array_merge( $cmd, $parameters ) );
  }
  
  /**
@@@ -3056,8 -3096,10 +3056,8 @@@ function wfMerge( $old, $mine, $yours, 
        fclose( $yourtextFile );
  
        # Check for a conflict
 -      $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' .
 -              wfEscapeShellArg( $mytextName ) . ' ' .
 -              wfEscapeShellArg( $oldtextName ) . ' ' .
 -              wfEscapeShellArg( $yourtextName );
 +      $cmd = wfEscapeShellArg( $wgDiff3, '-a', '--overlap-only', $mytextName,
 +              $oldtextName, $yourtextName );
        $handle = popen( $cmd, 'r' );
  
        if ( fgets( $handle, 1024 ) ) {
        pclose( $handle );
  
        # Merge differences
 -      $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' .
 -              wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
 +      $cmd = wfEscapeShellArg( $wgDiff3, '-a', '-e', '--merge', $mytextName,
 +              $oldtextName, $yourtextName );
        $handle = popen( $cmd, 'r' );
        $result = '';
        do {
  
  /**
   * Returns unified plain-text diff of two texts.
 - * Useful for machine processing of diffs.
 + * "Useful" for machine processing of diffs.
 + *
 + * @deprecated since 1.25, use DiffEngine/UnifiedDiffFormatter directly
   *
   * @param string $before The text before the changes.
   * @param string $after The text after the changes.
@@@ -3135,11 -3175,6 +3135,11 @@@ function wfDiff( $before, $after, $para
        $cmd = "$wgDiff " . $params . ' ' . wfEscapeShellArg( $oldtextName, $newtextName );
  
        $h = popen( $cmd, 'r' );
 +      if ( !$h ) {
 +              unlink( $oldtextName );
 +              unlink( $newtextName );
 +              throw new Exception( __METHOD__ . '(): popen() failed' );
 +      }
  
        $diff = '';
  
@@@ -3624,7 -3659,19 +3624,7 @@@ function wfGetLBFactory() 
   * Shortcut for RepoGroup::singleton()->findFile()
   *
   * @param string $title String or Title object
 - * @param array $options Associative array of options:
 - *     time:           requested time for an archived image, or false for the
 - *                     current version. An image object will be returned which was
 - *                     created at the specified time.
 - *
 - *     ignoreRedirect: If true, do not follow file redirects
 - *
 - *     private:        If true, return restricted (deleted) files if the current
 - *                     user is allowed to view them. Otherwise, such files will not
 - *                     be found.
 - *
 - *     bypassCache:    If true, do not use the process-local cache of File objects
 - *
 + * @param array $options Associative array of options (see RepoGroup::findFile)
   * @return File|bool File, or false if the file does not exist
   */
  function wfFindFile( $title, $options = array() ) {
@@@ -3961,6 -4008,16 +3961,6 @@@ function wfGetParserCacheStorage() 
        return ObjectCache::getInstance( $wgParserCacheType );
  }
  
 -/**
 - * Get the cache object used by the language converter
 - *
 - * @return BagOStuff
 - */
 -function wfGetLangConverterCacheStorage() {
 -      global $wgLanguageConverterCacheType;
 -      return ObjectCache::getInstance( $wgLanguageConverterCacheType );
 -}
 -
  /**
   * Call hook functions defined in $wgHooks
   *
@@@ -4102,18 -4159,6 +4102,18 @@@ function wfCanIPUseHTTPS( $ip ) 
        return !!$canDo;
  }
  
 +/**
 + * Determine input string is represents as infinity
 + *
 + * @param string $str The string to determine
 + * @return bool
 + * @since 1.25
 + */
 +function wfIsInfinity( $str ) {
 +      $infinityValues = array( 'infinite', 'indefinite', 'infinity', 'never' );
 +      return in_array( $str, $infinityValues );
 +}
 +
  /**
   * Work out the IP address based on various globals
   * For trusted proxies, use the XFF client IP (first of the chain)