diff options
Diffstat (limited to 'includes/registration')
-rw-r--r-- | includes/registration/ExtensionProcessor.php | 41 | ||||
-rw-r--r-- | includes/registration/ExtensionRegistry.php | 84 |
2 files changed, 105 insertions, 20 deletions
diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index bb8fb329..0b594b42 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -47,6 +47,24 @@ class ExtensionProcessor implements Processor { ); /** + * Mapping of global settings to their specific merge strategies. + * + * @see ExtensionRegistry::exportExtractedData + * @see getExtractedInfo + * @var array + */ + protected static $mergeStrategies = array( + 'wgGroupPermissions' => 'array_plus_2d', + 'wgRevokePermissions' => 'array_plus_2d', + 'wgHooks' => 'array_merge_recursive', + // credits are handled in the ExtensionRegistry + //'wgExtensionCredits' => 'array_merge_recursive', + 'wgExtraGenderNamespaces' => 'array_plus', + 'wgNamespacesWithSubpages' => 'array_plus', + 'wgNamespaceContentModels' => 'array_plus', + ); + + /** * Keys that are part of the extension credits * * @var array @@ -155,6 +173,13 @@ class ExtensionProcessor implements Processor { } public function getExtractedInfo() { + // Make sure the merge strategies are set + foreach ( $this->globals as $key => $val ) { + if ( isset( self::$mergeStrategies[$key] ) ) { + $this->globals[$key][ExtensionRegistry::MERGE_STRATEGY] = self::$mergeStrategies[$key]; + } + } + return array( 'globals' => $this->globals, 'defines' => $this->defines, @@ -166,8 +191,10 @@ class ExtensionProcessor implements Processor { protected function extractHooks( array $info ) { if ( isset( $info['Hooks'] ) ) { - foreach ( $info['Hooks'] as $name => $callable ) { - $this->globals['wgHooks'][$name][] = $callable; + foreach ( $info['Hooks'] as $name => $value ) { + foreach ( (array)$value as $callback ) { + $this->globals['wgHooks'][$name][] = $callback; + } } } } @@ -182,7 +209,7 @@ class ExtensionProcessor implements Processor { foreach ( $info['namespaces'] as $ns ) { $id = $ns['id']; $this->defines[$ns['constant']] = $id; - $this->globals['wgExtraNamespaces'][$id] = $ns['name']; + $this->attributes['ExtensionNamespaces'][$id] = $ns['name']; if ( isset( $ns['gender'] ) ) { $this->globals['wgExtraGenderNamespaces'][$id] = $ns['gender']; } @@ -269,9 +296,15 @@ class ExtensionProcessor implements Processor { */ protected function extractConfig( array $info ) { if ( isset( $info['config'] ) ) { + if ( isset( $info['config']['_prefix'] ) ) { + $prefix = $info['config']['_prefix']; + unset( $info['config']['_prefix'] ); + } else { + $prefix = 'wg'; + } foreach ( $info['config'] as $key => $val ) { if ( $key[0] !== '@' ) { - $this->globals["wg$key"] = $val; + $this->globals["$prefix$key"] = $val; } } } diff --git a/includes/registration/ExtensionRegistry.php b/includes/registration/ExtensionRegistry.php index 4e690aa8..16d83356 100644 --- a/includes/registration/ExtensionRegistry.php +++ b/includes/registration/ExtensionRegistry.php @@ -12,6 +12,28 @@ class ExtensionRegistry { /** + * Version of the highest supported manifest version + */ + const MANIFEST_VERSION = 1; + + /** + * Version of the oldest supported manifest version + */ + const OLDEST_MANIFEST_VERSION = 1; + + /** + * Bump whenever the registration cache needs resetting + */ + const CACHE_VERSION = 1; + + /** + * Special key that defines the merge strategy + * + * @since 1.26 + */ + const MERGE_STRATEGY = '_merge_strategy'; + + /** * @var BagOStuff */ protected $cache; @@ -92,7 +114,7 @@ class ExtensionRegistry { } // See if this queue is in APC - $key = wfMemcKey( 'registration', md5( json_encode( $this->queued ) ) ); + $key = wfMemcKey( 'registration', md5( json_encode( $this->queued ) ), self::CACHE_VERSION ); $data = $this->cache->get( $key ); if ( $data ) { $this->exportExtractedData( $data ); @@ -155,31 +177,61 @@ class ExtensionRegistry { foreach ( $data['credits'] as $credit ) { $data['globals']['wgExtensionCredits'][$credit['type']][] = $credit; } + $data['globals']['wgExtensionCredits'][self::MERGE_STRATEGY] = 'array_merge_recursive'; $data['autoload'] = $autoloadClasses; return $data; } protected function exportExtractedData( array $info ) { foreach ( $info['globals'] as $key => $val ) { + // If a merge strategy is set, read it and remove it from the value + // so it doesn't accidentally end up getting set. + // Need to check $val is an array for PHP 5.3 which will return + // true on isset( 'string'['foo'] ). + if ( isset( $val[self::MERGE_STRATEGY] ) && is_array( $val ) ) { + $mergeStrategy = $val[self::MERGE_STRATEGY]; + unset( $val[self::MERGE_STRATEGY] ); + } else { + $mergeStrategy = 'array_merge'; + } + + // Optimistic: If the global is not set, or is an empty array, replace it entirely. + // Will be O(1) performance. if ( !isset( $GLOBALS[$key] ) || ( is_array( $GLOBALS[$key] ) && !$GLOBALS[$key] ) ) { $GLOBALS[$key] = $val; - } elseif ( $key === 'wgHooks' || $key === 'wgExtensionCredits' ) { - // Special case $wgHooks and $wgExtensionCredits, which require a recursive merge. - // Ideally it would have been taken care of in the first if block though. - $GLOBALS[$key] = array_merge_recursive( $GLOBALS[$key], $val ); - } elseif ( $key === 'wgGroupPermissions' ) { - // First merge individual groups - foreach ( $GLOBALS[$key] as $name => &$groupVal ) { - if ( isset( $val[$name] ) ) { - $groupVal += $val[$name]; + continue; + } + + if ( !is_array( $GLOBALS[$key] ) || !is_array( $val ) ) { + // config setting that has already been overridden, don't set it + continue; + } + + switch ( $mergeStrategy ) { + case 'array_merge_recursive': + $GLOBALS[$key] = array_merge_recursive( $GLOBALS[$key], $val ); + break; + case 'array_plus_2d': + // First merge items that are in both arrays + foreach ( $GLOBALS[$key] as $name => &$groupVal ) { + if ( isset( $val[$name] ) ) { + $groupVal += $val[$name]; + } } - } - // Now merge groups that didn't exist yet - $GLOBALS[$key] += $val; - } elseif ( is_array( $GLOBALS[$key] ) && is_array( $val ) ) { - $GLOBALS[$key] = array_merge( $val, $GLOBALS[$key] ); - } // else case is a config setting where it has already been overriden, so don't set it + // Now add items that didn't exist yet + $GLOBALS[$key] += $val; + break; + case 'array_plus': + $GLOBALS[$key] += $val; + break; + case 'array_merge': + $GLOBALS[$key] = array_merge( $val, $GLOBALS[$key] ); + break; + default: + throw new UnexpectedValueException( "Unknown merge strategy '$mergeStrategy'" ); + } } + foreach ( $info['defines'] as $name => $val ) { define( $name, $val ); } |