/**
* Bump whenever the registration cache needs resetting
*/
- const CACHE_VERSION = 3;
+ const CACHE_VERSION = 4;
/**
* Special key that defines the merge strategy
*/
protected $queued = [];
+ /**
+ * Whether we are done loading things
+ *
+ * @var bool
+ */
+ private $finished = false;
+
/**
* Items in the JSON file that aren't being
* set as globals
}
public function __construct() {
- // We use a try/catch instead of the $fallback parameter because
- // we don't want to fail here if $wgObjectCaches is not configured
- // properly for APC setup
+ // We use a try/catch because we don't want to fail here
+ // if $wgObjectCaches is not configured properly for APC setup
try {
$this->cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
} catch ( MWException $e ) {
$this->queued[$path] = $mtime;
}
+ /**
+ * @throws MWException If the queue is already marked as finished (no further things should
+ * be loaded then).
+ */
public function loadFromQueue() {
global $wgVersion;
if ( !$this->queued ) {
return;
}
+ if ( $this->finished ) {
+ throw new MWException(
+ "The following paths tried to load late: "
+ . implode( ', ', array_keys( $this->queued ) )
+ );
+ }
+
// A few more things to vary the cache on
$versions = [
'registration' => self::CACHE_VERSION,
$this->queued = [];
}
+ /**
+ * After this is called, no more extensions can be loaded
+ *
+ * @since 1.29
+ */
+ public function finish() {
+ $this->finished = true;
+ }
+
/**
* Process a queue of extensions and return their extracted data
*
if ( !is_array( $info ) ) {
throw new Exception( "$path is not a valid JSON file." );
}
+
+ // Check any constraints against MediaWiki core
+ $requires = $processor->getRequirements( $info );
+ if ( isset( $requires[self::MEDIAWIKI_CORE] )
+ && !$coreVersionParser->check( $requires[self::MEDIAWIKI_CORE] )
+ ) {
+ // Doesn't match, mark it as incompatible.
+ $incompatible[] = "{$info['name']} is not compatible with the current "
+ . "MediaWiki core (version {$wgVersion}), it requires: " . $requires[self::MEDIAWIKI_CORE]
+ . '.';
+ continue;
+ }
+
if ( !isset( $info['manifest_version'] ) ) {
// For backwards-compatability, assume a version of 1
$info['manifest_version'] = 1;
if ( $version < self::OLDEST_MANIFEST_VERSION || $version > self::MANIFEST_VERSION ) {
throw new Exception( "$path: unsupported manifest_version: {$version}" );
}
+
$autoload = $this->processAutoLoader( dirname( $path ), $info );
// Set up the autoloader now so custom processors will work
$GLOBALS['wgAutoloadClasses'] += $autoload;
$autoloadClasses += $autoload;
- // Check any constraints against MediaWiki core
- $requires = $processor->getRequirements( $info );
- if ( isset( $requires[self::MEDIAWIKI_CORE] )
- && !$coreVersionParser->check( $requires[self::MEDIAWIKI_CORE] )
- ) {
- // Doesn't match, mark it as incompatible.
- $incompatible[] = "{$info['name']} is not compatible with the current "
- . "MediaWiki core (version {$wgVersion}), it requires: " . $requires[self::MEDIAWIKI_CORE]
- . '.';
- continue;
- }
+
// Get extra paths for later inclusion
$autoloaderPaths = array_merge( $autoloaderPaths,
$processor->getExtraAutoloaderPaths( dirname( $path ), $info ) );
case 'array_merge_recursive':
$GLOBALS[$key] = array_merge_recursive( $GLOBALS[$key], $val );
break;
+ case 'array_replace_recursive':
+ $GLOBALS[$key] = array_replace_recursive( $GLOBALS[$key], $val );
+ break;
case 'array_plus_2d':
$GLOBALS[$key] = wfArrayPlus2d( $GLOBALS[$key], $val );
break;
foreach ( $info['autoloaderPaths'] as $path ) {
require_once $path;
}
- foreach ( $info['callbacks'] as $cb ) {
- call_user_func( $cb );
- }
$this->loaded += $info['credits'];
if ( $info['attributes'] ) {
$this->attributes = array_merge_recursive( $this->attributes, $info['attributes'] );
}
}
+
+ foreach ( $info['callbacks'] as $name => $cb ) {
+ call_user_func( $cb, $info['credits'][$name] );
+ }
}
/**