Skip to content

Commit e035c1f

Browse files
authored
Merge pull request #6397 from kenjis/feat-autoload-helpers
feat: autoload helpers
2 parents 7d7d967 + 4e3e20c commit e035c1f

File tree

7 files changed

+113
-29
lines changed

7 files changed

+113
-29
lines changed

app/Config/Autoload.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,10 @@ class Autoload extends AutoloadConfig
3131
* else you will need to modify all of those classes for this to work.
3232
*
3333
* Prototype:
34-
*```
3534
* $psr4 = [
3635
* 'CodeIgniter' => SYSTEMPATH,
37-
* 'App' => APPPATH
36+
* 'App' => APPPATH
3837
* ];
39-
*```
4038
*
4139
* @var array<string, string>
4240
*/
@@ -56,11 +54,9 @@ class Autoload extends AutoloadConfig
5654
* were being autoloaded through a namespace.
5755
*
5856
* Prototype:
59-
*```
6057
* $classmap = [
6158
* 'MyClass' => '/path/to/class/file.php'
6259
* ];
63-
*```
6460
*
6561
* @var array<string, string>
6662
*/
@@ -75,13 +71,26 @@ class Autoload extends AutoloadConfig
7571
* or for loading functions.
7672
*
7773
* Prototype:
78-
* ```
79-
* $files = [
80-
* '/path/to/my/file.php',
81-
* ];
82-
* ```
74+
* $files = [
75+
* '/path/to/my/file.php',
76+
* ];
8377
*
84-
* @var array<int, string>
78+
* @var string[]
79+
* @phpstan-var list<string>
8580
*/
8681
public $files = [];
82+
83+
/**
84+
* -------------------------------------------------------------------
85+
* Helpers
86+
* -------------------------------------------------------------------
87+
* Prototype:
88+
* $helpers = [
89+
* 'form',
90+
* ];
91+
*
92+
* @var string[]
93+
* @phpstan-var list<string>
94+
*/
95+
public $helpers = [];
8796
}

system/Autoloader/Autoloader.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,20 @@ class Autoloader
7171
/**
7272
* Stores files as a list.
7373
*
74-
* @var array<int, string>
74+
* @var string[]
75+
* @phpstan-var list<string>
7576
*/
7677
protected $files = [];
7778

79+
/**
80+
* Stores helper list.
81+
* Always load the URL helper, it should be used in most apps.
82+
*
83+
* @var string[]
84+
* @phpstan-var list<string>
85+
*/
86+
protected $helpers = ['url'];
87+
7888
/**
7989
* Reads in the configuration array (described above) and stores
8090
* the valid parts that we'll need.
@@ -105,6 +115,10 @@ public function initialize(Autoload $config, Modules $modules)
105115
$this->files = $config->files;
106116
}
107117

118+
if (isset($config->helpers)) { // @phpstan-ignore-line
119+
$this->helpers = [...$this->helpers, ...$config->helpers];
120+
}
121+
108122
if (is_file(COMPOSER_PATH)) {
109123
$this->loadComposerInfo($modules);
110124
}
@@ -146,6 +160,17 @@ public function register()
146160
}
147161
}
148162

163+
/**
164+
* Unregister autoloader.
165+
*
166+
* This method is for testing.
167+
*/
168+
public function unregister(): void
169+
{
170+
spl_autoload_unregister([$this, 'loadClass']);
171+
spl_autoload_unregister([$this, 'loadClassmap']);
172+
}
173+
149174
/**
150175
* Registers namespaces with the autoloader.
151176
*
@@ -396,4 +421,12 @@ protected function discoverComposerNamespaces()
396421
$this->prefixes = array_merge($this->prefixes, $newPaths);
397422
$this->classmap = array_merge($this->classmap, $classes);
398423
}
424+
425+
/**
426+
* Loads helpers
427+
*/
428+
public function loadHelpers(): void
429+
{
430+
helper($this->helpers);
431+
}
399432
}

system/bootstrap.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103

104104
// Initialize and register the loader with the SPL autoloader stack.
105105
Services::autoloader()->initialize(new Autoload(), new Modules())->register();
106+
Services::autoloader()->loadHelpers();
106107

107108
// Now load Composer's if it's available
108109
if (is_file(COMPOSER_PATH)) {
@@ -117,6 +118,3 @@
117118

118119
require_once COMPOSER_PATH;
119120
}
120-
121-
// Always load the URL helper, it should be used in most of apps.
122-
helper('url');

tests/system/Autoloader/AutoloaderTest.php

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ protected function setUp(): void
4949
$this->loader->initialize($config, $modules)->register();
5050
}
5151

52+
protected function tearDown(): void
53+
{
54+
$this->loader->unregister();
55+
56+
parent::tearDown();
57+
}
58+
5259
public function testLoadStoredClass()
5360
{
5461
$this->assertInstanceOf('UnnamespacedClass', new UnnamespacedClass());
@@ -98,10 +105,13 @@ public function testServiceAutoLoader()
98105
$autoloader = Services::autoloader(false);
99106
$autoloader->initialize(new Autoload(), new Modules());
100107
$autoloader->register();
108+
101109
// look for Home controller, as that should be in base repo
102110
$actual = $autoloader->loadClass(Home::class);
103111
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
104112
$this->assertSame($expected, realpath($actual) ?: $actual);
113+
114+
$autoloader->unregister();
105115
}
106116

107117
public function testExistingFile()
@@ -252,10 +262,10 @@ public function testFindsComposerRoutes()
252262
$modules = new Modules();
253263
$modules->discoverInComposer = true;
254264

255-
$this->loader = new Autoloader();
256-
$this->loader->initialize($config, $modules);
265+
$loader = new Autoloader();
266+
$loader->initialize($config, $modules);
257267

258-
$namespaces = $this->loader->getNamespace();
268+
$namespaces = $loader->getNamespace();
259269
$this->assertArrayHasKey('Laminas\\Escaper', $namespaces);
260270
}
261271

@@ -268,10 +278,10 @@ public function testComposerNamespaceDoesNotOverwriteConfigAutoloadPsr4()
268278
$modules = new Modules();
269279
$modules->discoverInComposer = true;
270280

271-
$this->loader = new Autoloader();
272-
$this->loader->initialize($config, $modules);
281+
$loader = new Autoloader();
282+
$loader->initialize($config, $modules);
273283

274-
$namespaces = $this->loader->getNamespace();
284+
$namespaces = $loader->getNamespace();
275285
$this->assertSame('/Config/Autoload/Psr/Log/', $namespaces['Psr\Log'][0]);
276286
$this->assertStringContainsString(VENDORPATH, $namespaces['Psr\Log'][1]);
277287
}
@@ -284,29 +294,49 @@ public function testFindsComposerRoutesWithComposerPathNotFound()
284294
$modules = new Modules();
285295
$modules->discoverInComposer = true;
286296

287-
$this->loader = new Autoloader();
297+
$loader = new Autoloader();
288298

289299
rename(COMPOSER_PATH, COMPOSER_PATH . '.backup');
290-
$this->loader->initialize($config, $modules);
300+
$loader->initialize($config, $modules);
291301
rename(COMPOSER_PATH . '.backup', $composerPath);
292302

293-
$namespaces = $this->loader->getNamespace();
303+
$namespaces = $loader->getNamespace();
294304
$this->assertArrayNotHasKey('Laminas\\Escaper', $namespaces);
295305
}
296306

297307
public function testAutoloaderLoadsNonClassFiles(): void
298308
{
299-
$config = new Autoload();
300-
309+
$config = new Autoload();
301310
$config->files[] = SUPPORTPATH . 'Autoloader/functions.php';
302311

303-
$this->loader = new Autoloader();
304-
$this->loader->initialize($config, new Modules());
305-
$this->loader->register();
312+
$loader = new Autoloader();
313+
$loader->initialize($config, new Modules());
314+
$loader->register();
306315

307316
$this->assertTrue(function_exists('autoload_foo'));
308317
$this->assertSame('I am autoloaded by Autoloader through $files!', autoload_foo());
309318
$this->assertTrue(defined('AUTOLOAD_CONSTANT'));
310319
$this->assertSame('foo', AUTOLOAD_CONSTANT);
320+
321+
$loader->unregister();
322+
}
323+
324+
/**
325+
* @runInSeparateProcess
326+
* @preserveGlobalState disabled
327+
*/
328+
public function testLoadHelpers(): void
329+
{
330+
$config = new Autoload();
331+
$config->helpers[] = 'form';
332+
333+
$loader = new Autoloader();
334+
$loader->initialize($config, new Modules());
335+
336+
$loader->loadHelpers();
337+
338+
$this->assertTrue(function_exists('form_open'));
339+
340+
$loader->unregister();
311341
}
312342
}

user_guide_src/source/changelogs/v4.3.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Others
6868
- Added new :ref:`entities-property-casting` class ``IntBoolCast`` for Entity.
6969
- Help information for a spark command can now be accessed using the ``--help`` option (e.g. ``php spark serve --help``)
7070
- Added new Form helper function :php:func:`validation_errors()`, :php:func:`validation_list_errors()` and :php:func:`validation_show_error()` to display Validation Errors.
71+
- Now you can autoload helpers by **app/Config/Autoload.php**.
7172

7273
Changes
7374
*******

user_guide_src/source/general/helpers.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ use the following command to load the helper for us:
8383
.. note:: The functions within files loaded this way are not truly namespaced.
8484
The namespace is simply used as a convenient way to locate the files.
8585

86+
.. _auto-loading-helpers:
87+
88+
Auto-loading Helpers
89+
--------------------
90+
91+
.. versionadded:: 4.3.0
92+
93+
If you find that you need a particular helper globally throughout your application,
94+
you can tell CodeIgniter to auto-load it during system initialization.
95+
This is done by opening the **app/Config/Autoload.php** file
96+
and adding the helper to the ``$helpers`` property.
97+
8698
Using a Helper
8799
==============
88100

user_guide_src/source/installation/upgrade_4xx.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Helpers
109109
=======
110110

111111
- Helpers are pretty much the same as before, though some have been simplified.
112+
- Since v4.3.0, you can autoload helpers by **app/Config/Autoload.php** as well as CI3.
112113
- In CI4, ``redirect()`` returns a ``RedirectResponse`` instance instead of redirecting and terminating script execution. You must return it.
113114
- `redirect() Documentation CodeIgniter 3.X <https://codeigniter.com/userguide3/helpers/url_helper.html#redirect>`_
114115
- `redirect() Documentation CodeIgniter 4.X <../general/common_functions.html#redirect>`_

0 commit comments

Comments
 (0)