diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 0eb6d2443e44..6db25549dca9 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -118,6 +118,7 @@ public static function define(string $component, string $alias, string $classnam self::getOptions($component); self::$aliases[$component][$alias] = $classname; + self::$updated[$component] = true; } /** @@ -142,6 +143,7 @@ public static function __callStatic(string $component, array $arguments) return new $class(...$arguments); } + // Try to locate the class if ($class = self::locateClass($options, $alias)) { return new $class(...$arguments); } @@ -160,14 +162,8 @@ public static function __callStatic(string $component, array $arguments) return null; } - self::$instances[$options['component']][$class] = new $class(...$arguments); - self::$aliases[$options['component']][$alias] = $class; - self::$updated[$options['component']] = true; - - // If a short classname is specified, also register FQCN to share the instance. - if (! isset(self::$aliases[$options['component']][$class])) { - self::$aliases[$options['component']][$class] = $class; - } + self::createInstance($options['component'], $class, $arguments); + self::setAlias($options['component'], $alias, $class); return self::$instances[$options['component']][$class]; } @@ -179,6 +175,7 @@ public static function __callStatic(string $component, array $arguments) */ private static function getDefinedInstance(array $options, string $alias, array $arguments) { + // The alias is already defined. if (isset(self::$aliases[$options['component']][$alias])) { $class = self::$aliases[$options['component']][$alias]; @@ -189,15 +186,50 @@ private static function getDefinedInstance(array $options, string $alias, array return self::$instances[$options['component']][$class]; } - self::$instances[$options['component']][$class] = new $class(...$arguments); + self::createInstance($options['component'], $class, $arguments); return self::$instances[$options['component']][$class]; } } + // Try to locate the class + if (! $class = self::locateClass($options, $alias)) { + return null; + } + + // Check for an existing instance for the class + if (isset(self::$instances[$options['component']][$class])) { + self::setAlias($options['component'], $alias, $class); + + return self::$instances[$options['component']][$class]; + } + return null; } + /** + * Creates the shared instance. + */ + private static function createInstance(string $component, string $class, array $arguments): void + { + self::$instances[$component][$class] = new $class(...$arguments); + self::$updated[$component] = true; + } + + /** + * Sets alias + */ + private static function setAlias(string $component, string $alias, string $class): void + { + self::$aliases[$component][$alias] = $class; + self::$updated[$component] = true; + + // If a short classname is specified, also register FQCN to share the instance. + if (! isset(self::$aliases[$component][$class]) && ! self::isNamespaced($alias)) { + self::$aliases[$component][$class] = $class; + } + } + /** * Is the component Config? * diff --git a/tests/system/Config/FactoriesTest.php b/tests/system/Config/FactoriesTest.php index c5936a7c341f..b53c1e9133e5 100644 --- a/tests/system/Config/FactoriesTest.php +++ b/tests/system/Config/FactoriesTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Config; use CodeIgniter\Test\CIUnitTestCase; +use Config\App; use Config\Database; use InvalidArgumentException; use ReflectionClass; @@ -322,6 +323,14 @@ public function testCanLoadTwoCellsWithSameShortName() $this->assertNotSame($cell1, $cell2); } + public function testCanLoadSharedConfigWithDifferentAlias() + { + $config1 = Factories::config(App::class); + $config2 = Factories::config('App'); + + $this->assertSame($config1, $config2); + } + public function testDefineSameAliasTwiceWithDifferentClasses() { $this->expectException(InvalidArgumentException::class);