diff --git a/system/Config/BaseConfig.php b/system/Config/BaseConfig.php index 095bd74d9e6d..b74dd7a74c7b 100644 --- a/system/Config/BaseConfig.php +++ b/system/Config/BaseConfig.php @@ -177,8 +177,9 @@ protected function registerProperties() if (! static::$didDiscovery) { - $locator = \Config\Services::locator(); - static::$registrars = $locator->search('Config/Registrar.php'); + $locator = \Config\Services::locator(); + static::$registrars = $locator->search('Config/Registrar.php'); + static::$didDiscovery = true; } $shortName = (new \ReflectionClass($this))->getShortName(); diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 62929cef8a1c..da65f471554c 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -251,6 +251,7 @@ protected static function discoverServices(string $name, array $arguments) if (empty($files)) { + // no files at all found - this would be really, really bad return null; } @@ -271,6 +272,7 @@ protected static function discoverServices(string $name, array $arguments) if (! static::$services) { + // we found stuff, but no services - this would be really bad return null; } diff --git a/tests/_support/Config/BadRegistrar.php b/tests/_support/Config/BadRegistrar.php index 877d7be5a9c2..a651d11d3004 100644 --- a/tests/_support/Config/BadRegistrar.php +++ b/tests/_support/Config/BadRegistrar.php @@ -10,7 +10,7 @@ class BadRegistrar { - public static function RegistrarConfig2() + public static function RegistrarConfig() { return 'I am not worthy'; } diff --git a/tests/_support/Config/MockServices.php b/tests/_support/Config/MockServices.php new file mode 100644 index 000000000000..0bd6400eb306 --- /dev/null +++ b/tests/_support/Config/MockServices.php @@ -0,0 +1,28 @@ + TESTPATH . '_support/', + ]; + public $classmap = []; + + //-------------------------------------------------------------------- + + public function __construct() + { + // Don't call the parent since we don't want the default mappings. + // parent::__construct(); + } + + //-------------------------------------------------------------------- + public static function locator(bool $getShared = true) + { + return new \CodeIgniter\Autoloader\FileLocator(static::autoloader()); + } + +} diff --git a/tests/system/Config/BaseConfigTest.php b/tests/system/Config/BaseConfigTest.php index c130ef4bae01..ee0616dfbc78 100644 --- a/tests/system/Config/BaseConfigTest.php +++ b/tests/system/Config/BaseConfigTest.php @@ -185,10 +185,40 @@ public function testBadRegistrar() $config = new \RegistrarConfig(); $config::$registrars = ['\Tests\Support\Config\BadRegistrar']; $this->setPrivateProperty($config, 'didDiscovery', true); + + $this->expectException(\RuntimeException::class); $method = $this->getPrivateMethodInvoker($config, 'registerProperties'); $method(); $this->assertEquals('bar', $config->foo); } + public function testNotEnabled() + { + $modulesConfig = config('Modules'); + $modulesConfig->enabled = false; + + $config = new \RegistrarConfig(); + $expected = $config::$registrars; + + $method = $this->getPrivateMethodInvoker($config, 'registerProperties'); + $method(); + + $this->assertEquals($expected, $config::$registrars); + } + + public function testDidDiscovery() + { + $modulesConfig = config('Modules'); + $modulesConfig->enabled = true; + + $config = new \RegistrarConfig(); + $this->setPrivateProperty($config, 'didDiscovery', false); + + $method = $this->getPrivateMethodInvoker($config, 'registerProperties'); + $method(); + + $this->assertEquals(true, $this->getPrivateProperty($config, 'didDiscovery')); + } + } diff --git a/tests/system/Config/ConfigTest.php b/tests/system/Config/ConfigTest.php index 2a44773e17da..9269554801a1 100644 --- a/tests/system/Config/ConfigTest.php +++ b/tests/system/Config/ConfigTest.php @@ -1,4 +1,5 @@ -assertTrue($Config === $Config2); @@ -35,4 +36,16 @@ public function testCreateNonConfig() $this->assertNull($Config); } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testInjection() + { + Config::reset(); + Config::injectMock('Banana', '\stdClass'); + $this->assertNotNull(Config::get('Banana')); + } + } diff --git a/user_guide_src/source/concepts/services.rst b/user_guide_src/source/concepts/services.rst index f0d589078e21..228eacb063cd 100644 --- a/user_guide_src/source/concepts/services.rst +++ b/user_guide_src/source/concepts/services.rst @@ -133,17 +133,17 @@ within the class, and, if not, creates a new one. All of the factory methods pro Service Discovery ----------------- -CodeIgniter can automatically discover any Config\Services.php files you may have created within any defined namespaces. +CodeIgniter can automatically discover any Config\\Services.php files you may have created within any defined namespaces. This allows simple use of any module Services files. In order for custom Services files to be discovered, they must meet these requirements: -- It's namespace must be defined ``Config\Autoload.php`` +- Its namespace must be defined in ``Config\Autoload.php`` - Inside the namespace, the file must be found at ``Config\Services.php`` - It must extend ``CodeIgniter\Config\BaseService`` A small example should clarify this. -Imagine that you've created a new directory, ``Blog`` in your root directory. This will hold a blog module with controllers, +Imagine that you've created a new directory, ``Blog`` in your root directory. This will hold a **blog module** with controllers, models, etc, and you'd like to make some of the classes available as a service. The first step is to create a new file: ``Blog\Config\Services.php``. The skeleton of the file should be:: @@ -164,4 +164,4 @@ would simply use the framework's ``Config\Services`` class to grab your service: $postManager = Config\Services::postManager(); -.. note:: If multiple Services file have the same method name, the first one found will be the instance returned. +.. note:: If multiple Services files have the same method name, the first one found will be the instance returned.