From dc9b44f531f39d01991655924c4b016a84c60407 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 8 Aug 2024 12:58:33 +0800 Subject: [PATCH] MDL-82747 core: Register composer autoload files Unfortunately PHP does not provide any means to autoload the files that a functions is located in, even if they are in an namespace. To work around this, Composer makes use of an `autoload.files` section in the `composer.json` file. Shortly after the Composer autoloader is registered with the `spl_autoload_register` call it also includes any files listed in this section. Moodle does not do this and really we should be doing so. This change adds a section to the autoloader registration method which loads all of the files defined in any third-party library included in our `lib` directory which contains any `composer.json` file with such a stanza. --- lib/classes/component.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/classes/component.php b/lib/classes/component.php index 0da8f0cd523..d954186e738 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -129,6 +129,25 @@ class core_component { 'Invoker' => 'lib/php-di/invoker/src', ]; + /** + * An array containing files which are normally in a package's composer/autoload.files section. + * + * PHP does not provide a mechanism for automatically including the files that methods are in. + * + * The Composer autoloader includes all files in this section of the composer.json file during the instantiation of the loader. + * + * @var array + */ + protected static $composerautoloadfiles = [ + 'lib/aws-sdk/src/functions.php', + 'lib/guzzlehttp/guzzle/src/functions_include.php', + 'lib/guzzlehttp/promises/src/functions_include.php', + 'lib/jmespath/src/JmesPath.php', + 'lib/php-di/php-di/src/functions.php', + 'lib/ralouphi/getallheaders/src/getallheaders.php', + 'lib/symfony/deprecation-contracts/function.php', + ]; + /** * Register the Moodle class autoloader. */ @@ -138,6 +157,15 @@ class core_component { } else { spl_autoload_register([self::class, 'classloader']); } + + // Load any composer-driven autoload files. + // This is intended to mimic the behaviour of the standard Composer Autoloader. + foreach (static::$composerautoloadfiles as $file) { + $path = dirname(__DIR__, 2) . '/' . $file; + if (file_exists($path)) { + require_once($path); + } + } } /**