From 936d298507087bd8c2bef7e6141034fb849a15c5 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 10:19:14 +0900 Subject: [PATCH 1/8] test: add test for get same config with different alias If the request class is the same, it is better to return the shared instance. --- tests/system/Config/FactoriesTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) 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); From 42f90a2d09bf1aaf55ffe98a3c3f141989723cba Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 10:20:42 +0900 Subject: [PATCH 2/8] fix: Factories do not return shared instance If it is called by different aliase like `'App'` and `App::class`. But if they are exactly the same FQCN, the shared instance should be returned. --- system/Config/Factories.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 0eb6d2443e44..935c80bad445 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -142,6 +142,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); } @@ -179,6 +180,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]; @@ -195,6 +197,21 @@ private static function getDefinedInstance(array $options, string $alias, array } } + // Try to locate the class + if (! $class = self::locateClass($options, $alias)) { + return null; + } + + // Need to verify if the shared instance matches the request + if (self::verifyInstanceOf($options, $class)) { + // Check for an existing instance for the class + if (isset(self::$instances[$options['component']][$class])) { + self::$aliases[$options['component']][$alias] = $class; + + return self::$instances[$options['component']][$class]; + } + } + return null; } From 39243390d772643f8b17ecc53ef2b9abe8dd2734 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 10:34:28 +0900 Subject: [PATCH 3/8] fix: Config cache may not be updated --- system/Config/Factories.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 935c80bad445..23a95e13b85f 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; } /** @@ -192,6 +193,7 @@ private static function getDefinedInstance(array $options, string $alias, array } self::$instances[$options['component']][$class] = new $class(...$arguments); + self::$updated[$options['component']] = true; return self::$instances[$options['component']][$class]; } @@ -207,6 +209,7 @@ private static function getDefinedInstance(array $options, string $alias, array // Check for an existing instance for the class if (isset(self::$instances[$options['component']][$class])) { self::$aliases[$options['component']][$alias] = $class; + self::$updated[$options['component']] = true; return self::$instances[$options['component']][$class]; } From 65a138521c6d8de8dad19bb5f097430e97431d76 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 10:49:29 +0900 Subject: [PATCH 4/8] refactor: extract method --- system/Config/Factories.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 23a95e13b85f..4e0218a6e835 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -162,9 +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; + self::createInstance($options['component'], $class, $arguments); + self::$aliases[$options['component']][$alias] = $class; // If a short classname is specified, also register FQCN to share the instance. if (! isset(self::$aliases[$options['component']][$class])) { @@ -192,8 +191,7 @@ private static function getDefinedInstance(array $options, string $alias, array return self::$instances[$options['component']][$class]; } - self::$instances[$options['component']][$class] = new $class(...$arguments); - self::$updated[$options['component']] = true; + self::createInstance($options['component'], $class, $arguments); return self::$instances[$options['component']][$class]; } @@ -218,6 +216,15 @@ private static function getDefinedInstance(array $options, string $alias, array 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; + } + /** * Is the component Config? * From 896b04717586503a619785816e8dc0f4e9f83faf Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 11:05:20 +0900 Subject: [PATCH 5/8] refactor: extract method --- system/Config/Factories.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 4e0218a6e835..a160793d3742 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -163,11 +163,11 @@ public static function __callStatic(string $component, array $arguments) } self::createInstance($options['component'], $class, $arguments); - self::$aliases[$options['component']][$alias] = $class; + self::setAlias($options['component'], $alias, $class); // 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::setAlias($options['component'], $class, $class); } return self::$instances[$options['component']][$class]; @@ -206,8 +206,7 @@ private static function getDefinedInstance(array $options, string $alias, array if (self::verifyInstanceOf($options, $class)) { // Check for an existing instance for the class if (isset(self::$instances[$options['component']][$class])) { - self::$aliases[$options['component']][$alias] = $class; - self::$updated[$options['component']] = true; + self::setAlias($options['component'], $alias, $class); return self::$instances[$options['component']][$class]; } @@ -225,6 +224,15 @@ private static function createInstance(string $component, string $class, array $ 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; + } + /** * Is the component Config? * From a895f634b32dfb5b7b63f370c8927787af103e24 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 11:07:34 +0900 Subject: [PATCH 6/8] refactor: move logic --- system/Config/Factories.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index a160793d3742..2e24b5cef65c 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -165,11 +165,6 @@ public static function __callStatic(string $component, array $arguments) self::createInstance($options['component'], $class, $arguments); self::setAlias($options['component'], $alias, $class); - // If a short classname is specified, also register FQCN to share the instance. - if (! isset(self::$aliases[$options['component']][$class])) { - self::setAlias($options['component'], $class, $class); - } - return self::$instances[$options['component']][$class]; } @@ -231,6 +226,11 @@ private static function setAlias(string $component, string $alias, string $class { 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::$aliases[$component][$class] = $class; + } } /** From add2cbdbea526b97805d56209cad92b970d6f746 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 11:11:46 +0900 Subject: [PATCH 7/8] refactor: change if condition This is more intuitive. --- system/Config/Factories.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 2e24b5cef65c..ba49e9360a91 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -228,7 +228,7 @@ private static function setAlias(string $component, string $alias, string $class self::$updated[$component] = true; // If a short classname is specified, also register FQCN to share the instance. - if (! isset(self::$aliases[$component][$class])) { + if (! isset(self::$aliases[$component][$class]) && ! self::isNamespaced($alias)) { self::$aliases[$component][$class] = $class; } } From 1b8847914ae5252186544381ea6476368528c18f Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 27 Aug 2023 11:19:30 +0900 Subject: [PATCH 8/8] refactor: remove unnecessary verifyInstanceOf() Because locateClass() already checks it. --- system/Config/Factories.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/system/Config/Factories.php b/system/Config/Factories.php index ba49e9360a91..6db25549dca9 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -197,14 +197,11 @@ private static function getDefinedInstance(array $options, string $alias, array return null; } - // Need to verify if the shared instance matches the request - if (self::verifyInstanceOf($options, $class)) { - // Check for an existing instance for the class - if (isset(self::$instances[$options['component']][$class])) { - self::setAlias($options['component'], $alias, $class); + // 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 self::$instances[$options['component']][$class]; } return null;