* @var array
*/
protected static $globalSettings = [
- 'ResourceLoaderSources',
- 'ResourceLoaderLESSVars',
- 'DefaultUserOptions',
- 'HiddenPrefs',
- 'GroupPermissions',
- 'RevokePermissions',
- 'GrantPermissions',
- 'GrantPermissionGroups',
- 'ImplicitGroups',
- 'GroupsAddToSelf',
- 'GroupsRemoveFromSelf',
+ 'ActionFilteredLogs',
+ 'Actions',
'AddGroups',
- 'RemoveGroups',
- 'AvailableRights',
- 'ContentHandlers',
- 'ConfigRegistry',
- 'SessionProviders',
+ 'APIFormatModules',
+ 'APIListModules',
+ 'APIMetaModules',
+ 'APIModules',
+ 'APIPropModules',
'AuthManagerAutoConfig',
+ 'AvailableRights',
'CentralIdLookupProviders',
'ChangeCredentialsBlacklist',
- 'RemoveCredentialsBlacklist',
- 'RateLimits',
- 'RecentChangesFlags',
- 'MediaHandlers',
- 'ExtensionFunctions',
+ 'ConfigRegistry',
+ 'ContentHandlers',
+ 'DefaultUserOptions',
'ExtensionEntryPointListFiles',
- 'SpecialPages',
- 'JobClasses',
- 'LogTypes',
- 'LogRestrictions',
+ 'ExtensionFunctions',
+ 'FeedClasses',
+ 'FileExtensions',
'FilterLogTypes',
- 'ActionFilteredLogs',
- 'LogNames',
- 'LogHeaders',
+ 'GrantPermissionGroups',
+ 'GrantPermissions',
+ 'GroupPermissions',
+ 'GroupsAddToSelf',
+ 'GroupsRemoveFromSelf',
+ 'HiddenPrefs',
+ 'ImplicitGroups',
+ 'JobClasses',
'LogActions',
'LogActionsHandlers',
- 'Actions',
- 'APIModules',
- 'APIFormatModules',
- 'APIMetaModules',
- 'APIPropModules',
- 'APIListModules',
+ 'LogHeaders',
+ 'LogNames',
+ 'LogRestrictions',
+ 'LogTypes',
+ 'MediaHandlers',
+ 'PasswordPolicy',
+ 'RateLimits',
+ 'RecentChangesFlags',
+ 'RemoveCredentialsBlacklist',
+ 'RemoveGroups',
+ 'ResourceLoaderLESSVars',
+ 'ResourceLoaderSources',
+ 'RevokePermissions',
+ 'SessionProviders',
+ 'SpecialPages',
'ValidSkinNames',
- 'FeedClasses',
+ ];
+
+ /**
+ * Top-level attributes that come from MW core
+ *
+ * @var string[]
+ */
+ protected static $coreAttributes = [
+ 'SkinOOUIThemes',
+ 'TrackingCategories',
];
/**
* @var array
*/
protected static $mergeStrategies = [
- 'wgGroupPermissions' => 'array_plus_2d',
- 'wgRevokePermissions' => 'array_plus_2d',
- 'wgGrantPermissions' => 'array_plus_2d',
- 'wgHooks' => 'array_merge_recursive',
+ 'wgAuthManagerAutoConfig' => 'array_plus_2d',
+ 'wgCapitalLinkOverrides' => 'array_plus',
'wgExtensionCredits' => 'array_merge_recursive',
'wgExtraGenderNamespaces' => 'array_plus',
- 'wgNamespacesWithSubpages' => 'array_plus',
+ 'wgGrantPermissions' => 'array_plus_2d',
+ 'wgGroupPermissions' => 'array_plus_2d',
+ 'wgHooks' => 'array_merge_recursive',
'wgNamespaceContentModels' => 'array_plus',
'wgNamespaceProtection' => 'array_plus',
- 'wgCapitalLinkOverrides' => 'array_plus',
+ 'wgNamespacesWithSubpages' => 'array_plus',
+ 'wgPasswordPolicy' => 'array_merge_recursive',
'wgRateLimits' => 'array_plus_2d',
- 'wgAuthManagerAutoConfig' => 'array_plus_2d',
+ 'wgRevokePermissions' => 'array_plus_2d',
];
/**
/**
* Things to be called once registration of these extensions are done
+ * keyed by the name of the extension that it belongs to
*
* @var callable[]
*/
*/
protected $attributes = [];
+ /**
+ * Extension attributes, keyed by name =>
+ * settings.
+ *
+ * @var array
+ */
+ protected $extAttributes = [];
+
/**
* @param string $path
* @param array $info
$this->extractResourceLoaderModules( $dir, $info );
$this->extractServiceWiringFiles( $dir, $info );
$this->extractParserTestFiles( $dir, $info );
+ $name = $this->extractCredits( $path, $info );
if ( isset( $info['callback'] ) ) {
- $this->callbacks[] = $info['callback'];
+ $this->callbacks[$name] = $info['callback'];
+ }
+
+ if ( $version === 2 ) {
+ $this->extractAttributes( $path, $info );
}
- $this->extractCredits( $path, $info );
foreach ( $info as $key => $val ) {
+ // If it's a global setting,
if ( in_array( $key, self::$globalSettings ) ) {
$this->storeToArray( $path, "wg$key", $val, $this->globals );
+ continue;
+ }
// Ignore anything that starts with a @
- } elseif ( $key[0] !== '@' && !in_array( $key, self::$notAttributes )
- && !in_array( $key, self::$creditsAttributes )
- ) {
- $this->storeToArray( $path, $key, $val, $this->attributes );
+ if ( $key[0] === '@' ) {
+ continue;
+ }
+
+ if ( $version === 2 ) {
+ // Only whitelisted attributes are set
+ if ( in_array( $key, self::$coreAttributes ) ) {
+ $this->storeToArray( $path, $key, $val, $this->attributes );
+ }
+ } else {
+ // version === 1
+ if ( !in_array( $key, self::$notAttributes )
+ && !in_array( $key, self::$creditsAttributes )
+ ) {
+ // If it's not blacklisted, it's an attribute
+ $this->storeToArray( $path, $key, $val, $this->attributes );
+ }
+ }
+
+ }
+ }
+
+ /**
+ * @param string $path
+ * @param array $info
+ */
+ protected function extractAttributes( $path, array $info ) {
+ if ( isset( $info['attributes'] ) ) {
+ foreach ( $info['attributes'] as $extName => $value ) {
+ $this->storeToArray( $path, $extName, $value, $this->extAttributes );
}
}
}
}
}
+ // Merge $this->extAttributes into $this->attributes depending on what is loaded
+ foreach ( $this->extAttributes as $extName => $value ) {
+ // Only set the attribute if $extName is loaded (and hence present in credits)
+ if ( isset( $this->credits[$extName] ) ) {
+ foreach ( $value as $attrName => $attrValue ) {
+ $this->storeToArray(
+ '', // Don't provide a path since it's impossible to generate an error here
+ $extName . $attrName,
+ $attrValue,
+ $this->attributes
+ );
+ }
+ unset( $this->extAttributes[$extName] );
+ }
+ }
+
return [
'globals' => $this->globals,
'defines' => $this->defines,
}
public function getRequirements( array $info ) {
- $requirements = [];
- $key = ExtensionRegistry::MEDIAWIKI_CORE;
- if ( isset( $info['requires'][$key] ) ) {
- $requirements[$key] = $info['requires'][$key];
- }
-
- return $requirements;
+ return isset( $info['requires'] ) ? $info['requires'] : [];
}
protected function extractHooks( array $info ) {
protected function extractNamespaces( array $info ) {
if ( isset( $info['namespaces'] ) ) {
foreach ( $info['namespaces'] as $ns ) {
- $id = $ns['id'];
- $this->defines[$ns['constant']] = $id;
+ if ( defined( $ns['constant'] ) ) {
+ // If the namespace constant is already defined, use it.
+ // This allows namespace IDs to be overwritten locally.
+ $id = constant( $ns['constant'] );
+ } else {
+ $id = $ns['id'];
+ $this->defines[ $ns['constant'] ] = $id;
+ }
+
if ( !( isset( $ns['conditional'] ) && $ns['conditional'] ) ) {
// If it is not conditional, register it
$this->attributes['ExtensionNamespaces'][$id] = $ns['name'];
protected function extractExtensionMessagesFiles( $dir, array $info ) {
if ( isset( $info['ExtensionMessagesFiles'] ) ) {
- $this->globals["wgExtensionMessagesFiles"] += array_map( function( $file ) use ( $dir ) {
+ $this->globals["wgExtensionMessagesFiles"] += array_map( function ( $file ) use ( $dir ) {
return "$dir/$file";
}, $info['ExtensionMessagesFiles'] );
}
/**
* @param string $path
* @param array $info
+ * @return string Name of thing
* @throws Exception
*/
protected function extractCredits( $path, array $info ) {
$this->credits[$name] = $credits;
$this->globals['wgExtensionCredits'][$credits['type']][] = $credits;
+
+ return $name;
}
/**