MediaWiki master
ExtensionsProvider.php
Go to the documentation of this file.
1<?php
2
4
5use AutoLoader;
12
18class ExtensionsProvider extends Task {
19 public function getName() {
20 return 'extensions';
21 }
22
23 public function getProvidedNames() {
24 return [ 'HookContainer', 'VirtualDomains', 'ExtensionTaskSpecs' ];
25 }
26
27 public function execute(): Status {
28 if ( !$this->getOption( 'Extensions' ) ) {
29 $this->getContext()->provide( 'VirtualDomains', [] );
30 $this->getContext()->provide( 'ExtensionTaskSpecs', [] );
31 return Status::newGood();
32 }
33
34 // Marker for DatabaseUpdater::loadExtensions so we don't
35 // double load extensions
36 define( 'MW_EXTENSIONS_LOADED', true );
37
38 $legacySchemaHooks = $this->getAutoExtensionLegacySchemaHooks();
39 $data = $this->getAutoExtensionData();
40 if ( isset( $data['globals']['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
41 $legacySchemaHooks = array_merge( $legacySchemaHooks,
42 $data['globals']['wgHooks']['LoadExtensionSchemaUpdates'] );
43 }
44 $extDeprecatedHooks = $data['attributes']['DeprecatedHooks'] ?? [];
45
46 $legacyHooks = $legacySchemaHooks ? [ 'LoadExtensionSchemaUpdates' => $legacySchemaHooks ] : [];
47 $this->getContext()->provide( 'HookContainer',
48 new HookContainer(
50 $legacyHooks,
51 $data['attributes']['Hooks'] ?? [],
52 $extDeprecatedHooks
53 ),
54 MediaWikiServices::getInstance()->getObjectFactory()
55 )
56 );
57 $this->getContext()->provide( 'VirtualDomains',
58 $data['attributes']['DatabaseVirtualDomains'] ?? [] );
59 $this->getContext()->provide( 'ExtensionTaskSpecs',
60 $data['attributes']['InstallerTasks'] ?? [] );
61
62 return Status::newGood();
63 }
64
68 protected function getExtensionsDir() {
69 return MW_INSTALL_PATH . '/extensions';
70 }
71
75 protected function getSkinsDir() {
76 return MW_INSTALL_PATH . '/skins';
77 }
78
85 private function getAutoExtensionLegacySchemaHooks() {
86 $exts = $this->getOption( 'Extensions' );
87 $extensionsDir = $this->getExtensionsDir();
88 $files = [];
89 foreach ( $exts as $e ) {
90 if ( file_exists( "$extensionsDir/$e/$e.php" ) ) {
91 $files[] = "$extensionsDir/$e/$e.php";
92 }
93 }
94
95 if ( $files ) {
96 return $this->includeExtensionFiles( $files );
97 } else {
98 return [];
99 }
100 }
101
109 private function includeExtensionFiles( $files ) {
118 // Extract the defaults into the current scope
119 foreach ( MainConfigSchema::listDefaultValues( 'wg' ) as $var => $value ) {
120 $$var = $value;
121 }
122
123 // phpcs:ignore MediaWiki.VariableAnalysis.UnusedGlobalVariables
125 $wgExtensionDirectory = $this->getExtensionsDir();
126 $wgStyleDirectory = $this->getSkinsDir();
127
128 foreach ( $files as $file ) {
129 require_once $file;
130 }
131
132 // Ignore everyone else's hooks. Lord knows what someone might be doing
133 // in ParserFirstCallInit (see T29171)
134 // @phpcs:disable MediaWiki.VariableAnalysis.MisleadingGlobalNames.Misleading$wgHooks
135 // @phpcs:ignore Generic.Files.LineLength.TooLong
136 // @phan-suppress-next-line PhanUndeclaredVariable,PhanCoalescingAlwaysNull $wgHooks is defined by MainConfigSchema
137 $hooksWeWant = $wgHooks['LoadExtensionSchemaUpdates'] ?? [];
138 // @phpcs:enable MediaWiki.VariableAnalysis.MisleadingGlobalNames.Misleading$wgHooks
139 return $hooksWeWant;
140 }
141
148 private function getAutoExtensionData() {
149 $exts = $this->getOption( 'Extensions' );
150
151 $extensionProcessor = new ExtensionProcessor();
152 foreach ( $exts as $e ) {
153 $jsonPath = $this->getExtensionsDir() . "/$e/extension.json";
154 if ( file_exists( $jsonPath ) ) {
155 $extensionProcessor->extractInfoFromFile( $jsonPath );
156 }
157 }
158
159 $autoload = $extensionProcessor->getExtractedAutoloadInfo();
160 AutoLoader::loadFiles( $autoload['files'] );
161 AutoLoader::registerClasses( $autoload['classes'] );
162 AutoLoader::registerNamespaces( $autoload['namespaces'] );
163
164 return $extensionProcessor->getExtractedInfo();
165 }
166
167}
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Definition Setup.php:106
$wgAutoloadClasses
Definition Setup.php:155
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Locations of core classes Extension classes are specified with $wgAutoloadClasses.
static registerClasses(array $files)
Register a file to load the given class from.
static loadFiles(array $files)
Batch version of loadFile()
static registerNamespaces(array $dirs)
Register a directory to load the classes of a given namespace from, per PSR4.
This is a simple immutable HookRegistry which can be used to set up a local HookContainer in tests an...
A scheduled provider which loads extensions.
getName()
Get the symbolic name of the task.
getProvidedNames()
Get a list of names of objects that this task promises to provide via $this->getContext()->provide().
Base class for installer tasks.
Definition Task.php:24
getOption(string $name)
Get an installer option value.
Definition Task.php:192
getContext()
Get the execution context.
Definition Task.php:171
This class contains schema declarations for all configuration variables known to MediaWiki core.
static listDefaultValues(string $prefix='')
Returns a generator for iterating over all config settings and their default values.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Load extension manifests and then aggregate their contents.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
$wgStyleDirectory
Config variable stub for the StyleDirectory setting, for use by phpdoc and IDEs.
$wgHooks
Config variable stub for the Hooks setting, for use by phpdoc and IDEs.
$wgExtensionDirectory
Config variable stub for the ExtensionDirectory setting, for use by phpdoc and IDEs.