Skip to content

Commit 864cf17

Browse files
committed
feat: Adding BaseService::updateServicesCache refreshes and looks for new services class post Autoload.
1 parent fd1061e commit 864cf17

File tree

6 files changed

+105
-0
lines changed

6 files changed

+105
-0
lines changed

system/Config/BaseService.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,4 +413,35 @@ protected static function buildServicesCache(): void
413413
static::$discovered = true;
414414
}
415415
}
416+
417+
/**
418+
* Update the services cache.
419+
*/
420+
public static function updateServicesCache(): void
421+
{
422+
if ((new Modules())->shouldDiscover('services')) {
423+
$locator = static::locator();
424+
$files = $locator->search('Config/Services');
425+
426+
$systemPath = static::autoloader()->getNamespace('CodeIgniter')[0];
427+
428+
// Get instances of all service classes and cache them locally.
429+
foreach ($files as $file) {
430+
// Does not search `CodeIgniter` namespace to prevent from loading twice.
431+
if (str_starts_with($file, $systemPath)) {
432+
continue;
433+
}
434+
435+
$classname = $locator->findQualifiedNameFromPath($file);
436+
437+
if ($classname === false) {
438+
continue;
439+
}
440+
441+
if ($classname !== Services::class && ! in_array($classname, self::$serviceNames, true)) {
442+
self::$serviceNames[] = $classname;
443+
}
444+
}
445+
}
446+
}
416447
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace AfterAutoloadModule\Config;
15+
16+
use AfterAutoloadModule\Test;
17+
use CodeIgniter\Config\BaseService;
18+
19+
class Services extends BaseService
20+
{
21+
public static function test(bool $getShared = true): Test
22+
{
23+
if ($getShared) {
24+
return static::getSharedInstance('test');
25+
}
26+
27+
return new Test();
28+
}
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace AfterAutoloadModule;
15+
16+
class Test
17+
{
18+
}

tests/system/Config/ServicesTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace CodeIgniter\Config;
1515

16+
use AfterAutoloadModule\Test;
1617
use CodeIgniter\Autoloader\Autoloader;
1718
use CodeIgniter\Autoloader\FileLocator;
1819
use CodeIgniter\Database\MigrationRunner;
@@ -350,6 +351,26 @@ public function testResetSingleCaseInsensitive(): void
350351
$this->assertNotInstanceOf(MockResponse::class, $someService);
351352
}
352353

354+
#[PreserveGlobalState(false)]
355+
#[RunInSeparateProcess]
356+
public function testUpdateServiceCache(): void
357+
{
358+
Services::injectMock('response', new MockResponse(new App()));
359+
$someService = service('response');
360+
$this->assertInstanceOf(MockResponse::class, $someService);
361+
service('response')->setStatusCode(200);
362+
363+
Services::autoloader()->addNamespace('AfterAutoloadModule', TESTPATH . '_support/Test/AfterAutoloadModule/');
364+
Services::updateServicesCache();
365+
366+
$someService = service('response');
367+
$this->assertInstanceOf(MockResponse::class, $someService);
368+
$this->assertSame(200, $someService->getStatusCode());
369+
370+
$someService = service('test');
371+
$this->assertInstanceOf(Test::class, $someService);
372+
}
373+
353374
public function testFilters(): void
354375
{
355376
$result = Services::filters();

user_guide_src/source/changelogs/v4.6.0.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ Helpers and Functions
7575

7676
Others
7777
======
78+
- **Services:** Added ``BaseService::updateServicesCache`` method to allow
79+
updating the services cache file post autoloading. This will only look for
80+
new services and add them to the class name cache.
7881

7982
***************
8083
Message Changes

user_guide_src/source/concepts/services.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,6 @@ would simply use the framework's ``Config\Services`` class to grab your service:
171171
.. literalinclude:: services/012.php
172172

173173
.. note:: If multiple Services files have the same method name, the first one found will be the instance returned.
174+
175+
There may be times when you need to have Service Discovery refresh it's cache after the inital autoload proccess. This can be done by running :php:meth:`Config\\Services::updateServicesCache()`.
176+
This will force the service discovery to re-scan the directories for any new services files.

0 commit comments

Comments
 (0)