From 7489cdfc05c87c4ab6c0916c4a5293c6b8b7f3a1 Mon Sep 17 00:00:00 2001 From: victorbarbu Date: Sun, 27 Dec 2015 11:03:41 +0200 Subject: [PATCH] registration: Allow loading composer's autoloader if it exists Extensions that have composer dependencies can set "load_composer_autoloader": true to load "$dir/vendor/autoload.php" if it exists. While it is recommended to use composer-merge-plugin to manage composer dependencies for extensions, using a local autoloader can be easier for development and is used by ExtensionDistributor. Bug: T119766 Change-Id: Ib031bef17c8a7d708a5c7878e74967d19217bbc8 --- docs/extension.schema.json | 4 ++++ includes/registration/ExtensionProcessor.php | 12 ++++++++++++ includes/registration/ExtensionRegistry.php | 12 ++++++++++-- includes/registration/Processor.php | 10 ++++++++++ .../includes/registration/ExtensionRegistryTest.php | 1 + 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/extension.schema.json b/docs/extension.schema.json index b6354679e9..8c760cc31d 100644 --- a/docs/extension.schema.json +++ b/docs/extension.schema.json @@ -729,6 +729,10 @@ "ParserTestFiles": { "type": "array", "description": "Parser test suite files to be run by parserTests.php when no specific filename is passed to it" + }, + "load_composer_autoloader": { + "type": "boolean", + "description": "Load the composer autoloader for this extension, if one is present" } } } diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index 84e873dd6c..cab889f5e5 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -102,6 +102,7 @@ class ExtensionProcessor implements Processor { 'ParserTestFiles', 'AutoloadClasses', 'manifest_version', + 'load_composer_autoloader', ); /** @@ -353,4 +354,15 @@ class ExtensionProcessor implements Processor { $array[$name] = $value; } } + + public function getExtraAutoloaderPaths( $dir, array $info ) { + $paths = array(); + if ( isset( $info['load_composer_autoloader'] ) && $info['load_composer_autoloader'] === true ) { + $path = "$dir/vendor/autoload.php"; + if ( file_exists( $path ) ) { + $paths[] = $path; + } + } + return $paths; + } } diff --git a/includes/registration/ExtensionRegistry.php b/includes/registration/ExtensionRegistry.php index 732b4a03e5..e37e7f5945 100644 --- a/includes/registration/ExtensionRegistry.php +++ b/includes/registration/ExtensionRegistry.php @@ -29,7 +29,7 @@ class ExtensionRegistry { /** * Bump whenever the registration cache needs resetting */ - const CACHE_VERSION = 1; + const CACHE_VERSION = 2; /** * Special key that defines the merge strategy @@ -173,6 +173,7 @@ class ExtensionRegistry { public function readFromQueue( array $queue ) { global $wgVersion; $autoloadClasses = array(); + $autoloaderPaths = array(); $processor = new ExtensionProcessor(); $incompatible = array(); $coreVersionParser = new CoreVersionChecker( $wgVersion ); @@ -208,6 +209,9 @@ class ExtensionRegistry { . '.'; continue; } + // Get extra paths for later inclusion + $autoloaderPaths = array_merge( $autoloaderPaths, + $processor->getExtraAutoloaderPaths( dirname( $path ), $info ) ); // Compatible, read and extract info $processor->extractInfo( $path, $info, $version ); } @@ -226,6 +230,7 @@ class ExtensionRegistry { } $data['globals']['wgExtensionCredits'][self::MERGE_STRATEGY] = 'array_merge_recursive'; $data['autoload'] = $autoloadClasses; + $data['autoloaderPaths'] = $autoloaderPaths; return $data; } @@ -279,8 +284,11 @@ class ExtensionRegistry { call_user_func( $cb ); } - $this->loaded += $info['credits']; + foreach ( $info['autoloaderPaths'] as $path ) { + require_once $path; + } + $this->loaded += $info['credits']; if ( $info['attributes'] ) { if ( !$this->attributes ) { $this->attributes = $info['attributes']; diff --git a/includes/registration/Processor.php b/includes/registration/Processor.php index e5669d2779..a4100bbc07 100644 --- a/includes/registration/Processor.php +++ b/includes/registration/Processor.php @@ -40,4 +40,14 @@ interface Processor { * like 'MediaWiki'. Values are a constraint string like "1.26.1". */ public function getRequirements( array $info ); + + /** + * Get the path for additional autoloaders, e.g. the one of Composer. + * + * @param string $dir + * @param array $info + * @return array Containing the paths for autoloader file(s). + * @since 1.27 + */ + public function getExtraAutoloaderPaths( $dir, array $info ); } diff --git a/tests/phpunit/includes/registration/ExtensionRegistryTest.php b/tests/phpunit/includes/registration/ExtensionRegistryTest.php index 201cbfcdf1..543eb5c78d 100644 --- a/tests/phpunit/includes/registration/ExtensionRegistryTest.php +++ b/tests/phpunit/includes/registration/ExtensionRegistryTest.php @@ -25,6 +25,7 @@ class ExtensionRegistryTest extends MediaWikiTestCase { 'defines' => array(), 'credits' => array(), 'attributes' => array(), + 'autoloaderPaths' => array() ); $registry = new ExtensionRegistry(); $class = new ReflectionClass( 'ExtensionRegistry' ); -- 2.20.1