Skip to content

Commit 9414217

Browse files
authored
Merge pull request #1215 from bcit-ci/autodiscovery
Autodiscovery for Modules
2 parents a201aa8 + d6b5723 commit 9414217

23 files changed

Lines changed: 263 additions & 179 deletions

application/Config/Modules.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php namespace Config;
2+
3+
// Cannot extend BaseConfig or looping resources occurs.
4+
class Modules
5+
{
6+
/*
7+
|--------------------------------------------------------------------------
8+
| Auto-Discovery Enabled?
9+
|--------------------------------------------------------------------------
10+
|
11+
| If true, then auto-discovery will happen across all elements listed in
12+
| $activeExplorers below. If false, no auto-discovery will happen at all,
13+
| giving a slight performance boost.
14+
*/
15+
public $enabled = true;
16+
17+
/*
18+
|--------------------------------------------------------------------------
19+
| Auto-discover Rules
20+
|--------------------------------------------------------------------------
21+
|
22+
| Lists the aliases of all discovery classes that will be active
23+
| and used during the current application request. If it is not
24+
| listed here, only the base application elements will be used.
25+
*/
26+
public $activeExplorers = [
27+
'events',
28+
'registrars',
29+
'routes',
30+
'services',
31+
];
32+
33+
/**
34+
* Should the application auto-discover the requested resources.
35+
*
36+
* Valid values are:
37+
* - events
38+
* - registrars
39+
* - routes
40+
* - services
41+
*
42+
* @param string $alias
43+
*
44+
* @return bool
45+
*/
46+
public function shouldDiscover(string $alias)
47+
{
48+
if (! $this->enabled) return false;
49+
50+
$alias = strtolower($alias);
51+
52+
return in_array($alias, $this->activeExplorers);
53+
}
54+
}

application/Config/Routes.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
$routes->setTranslateURIDashes(false);
6565
$routes->set404Override();
6666
$routes->setAutoRoute(true);
67-
$routes->discoverLocal(false);
6867

6968
/**
7069
* --------------------------------------------------------------------

system/Config/BaseConfig.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ class BaseConfig
5454
*
5555
* @var array
5656
*/
57-
protected $registrars;
57+
public static $registrars = [];
58+
59+
protected static $didDiscovery = false;
60+
61+
protected static $moduleConfig;
5862

5963
/**
6064
* Will attempt to get environment variables with names
@@ -64,6 +68,8 @@ class BaseConfig
6468
*/
6569
public function __construct()
6670
{
71+
static::$moduleConfig = config('Modules');
72+
6773
$properties = array_keys(get_object_vars($this));
6874
$prefix = get_class($this);
6975
$slashAt = strrpos($prefix, '\\');
@@ -120,7 +126,10 @@ public function __construct()
120126
}
121127
}
122128

123-
$this->registerProperties();
129+
if (ENVIRONMENT != 'testing')
130+
{
131+
$this->registerProperties();
132+
}
124133
}
125134

126135
//--------------------------------------------------------------------
@@ -165,13 +174,21 @@ protected function getEnvValue(string $property, string $prefix, string $shortPr
165174
*/
166175
protected function registerProperties()
167176
{
168-
if (empty($this->registrars))
177+
if (! static::$moduleConfig->shouldDiscover('registrars'))
178+
{
169179
return;
180+
}
181+
182+
if (! static::$didDiscovery)
183+
{
184+
$locator = \Config\Services::locator();
185+
static::$registrars = $locator->search('Config/Registrar.php');
186+
}
170187

171188
$shortName = (new \ReflectionClass($this))->getShortName();
172189

173190
// Check the registrar class for a method named after this class' shortName
174-
foreach ($this->registrars as $callable)
191+
foreach (static::$registrars as $callable)
175192
{
176193
// ignore non-applicable registrars
177194
if ( ! method_exists($callable, $shortName))

system/Config/BaseService.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,27 @@ protected static function discoverServices(string $name, array $arguments)
202202
{
203203
if (! static::$discovered)
204204
{
205-
$locator = static::locator();
206-
$files = $locator->search('Config/Services');
205+
$config = config('Modules');
207206

208-
if (empty($files))
207+
if ($config->shouldDiscover('services'))
209208
{
210-
return;
211-
}
209+
$locator = static::locator();
210+
$files = $locator->search('Config/Services');
212211

213-
// Get instances of all service classes and cache them locally.
214-
foreach ($files as $file)
215-
{
216-
$classname = $locator->getClassname($file);
212+
if (empty($files))
213+
{
214+
return;
215+
}
217216

218-
if (! in_array($classname, ['CodeIgniter\\Config\\Services']))
217+
// Get instances of all service classes and cache them locally.
218+
foreach ($files as $file)
219219
{
220-
static::$services[] = new $classname();
220+
$classname = $locator->getClassname($file);
221+
222+
if (! in_array($classname, ['CodeIgniter\\Config\\Services']))
223+
{
224+
static::$services[] = new $classname();
225+
}
221226
}
222227
}
223228

system/Config/Config.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ public static function get(string $name, bool $getShared = true)
8484

8585
//--------------------------------------------------------------------
8686

87+
/**
88+
* Helper method for injecting mock instances while testing.
89+
*
90+
* @param string $class
91+
* @param $instance
92+
*/
93+
public static function injectMock(string $class, $instance)
94+
{
95+
self::$instances[$class] = $instance;
96+
}
97+
98+
//--------------------------------------------------------------------
99+
87100
/**
88101
* Find configuration class and create instance
89102
*

system/Config/Services.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ public static function routes($getShared = true)
598598
return self::getSharedInstance('routes');
599599
}
600600

601-
return new \CodeIgniter\Router\RouteCollection(self::locator());
601+
return new \CodeIgniter\Router\RouteCollection(self::locator(), config('Modules'));
602602
}
603603

604604
//--------------------------------------------------------------------

system/Events/Events.php

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php namespace CodeIgniter\Events;
22

3+
use Config\Services;
4+
35
/**
46
* CodeIgniter
57
*
@@ -53,19 +55,12 @@ class Events
5355
protected static $listeners = [];
5456

5557
/**
56-
* Flag to let us know if we've read from the Config file
58+
* Flag to let us know if we've read from the Config file(s)
5759
* and have all of the defined events.
5860
*
5961
* @var bool
6062
*/
61-
protected static $haveReadFromFile = false;
62-
63-
/**
64-
* The path to the file containing the events to load in.
65-
*
66-
* @var string
67-
*/
68-
protected static $eventsFile = '';
63+
protected static $initialized = false;
6964

7065
/**
7166
* If true, events will not actually be fired.
@@ -82,28 +77,48 @@ class Events
8277
*/
8378
protected static $performanceLog = [];
8479

80+
/**
81+
* A list of found files.
82+
* @var array
83+
*/
84+
protected static $files = [];
85+
8586
//--------------------------------------------------------------------
8687

8788
/**
8889
* Ensures that we have a events file ready.
89-
*
90-
* @param string|null $file
9190
*/
92-
public static function initialize(string $file = null)
91+
public static function initialize()
9392
{
9493
// Don't overwrite anything....
95-
if ( ! empty(self::$eventsFile))
94+
if (static::$initialized)
9695
{
9796
return;
9897
}
9998

100-
// Default value
101-
if (empty($file))
99+
$config = config('Modules');
100+
101+
$files = [APPPATH.'Config/Events.php'];
102+
103+
if ($config->shouldDiscover('events'))
104+
{
105+
$locator = Services::locator();
106+
$files = $locator->search('Config/Events.php');
107+
}
108+
109+
static::$files = $files;
110+
111+
foreach (static::$files as $file)
102112
{
103-
$file = APPPATH . 'Config/Events.php';
113+
if (! file_exists($file))
114+
{
115+
continue;
116+
}
117+
118+
include $file;
104119
}
105120

106-
self::$eventsFile = $file;
121+
static::$initialized = true;
107122
}
108123

109124
//--------------------------------------------------------------------
@@ -155,15 +170,9 @@ public static function on($event_name, callable $callback, $priority = EVENT_PRI
155170
public static function trigger($eventName, ...$arguments): bool
156171
{
157172
// Read in our Config/events file so that we have them all!
158-
if ( ! self::$haveReadFromFile)
173+
if ( ! self::$initialized)
159174
{
160175
self::initialize();
161-
162-
if (is_file(self::$eventsFile))
163-
{
164-
include self::$eventsFile;
165-
}
166-
self::$haveReadFromFile = true;
167176
}
168177

169178
$listeners = self::listeners($eventName);
@@ -288,11 +297,23 @@ public static function removeAllListeners($event_name = null)
288297
/**
289298
* Sets the path to the file that routes are read from.
290299
*
291-
* @param string $path
300+
* @param array $files
301+
*/
302+
public static function setFiles(array $files)
303+
{
304+
static::$files = $files;
305+
}
306+
307+
//--------------------------------------------------------------------
308+
309+
/**
310+
* Returns the files that were found/loaded during this request.
311+
*
312+
* @return mixed
292313
*/
293-
public static function setFile(string $path)
314+
public function getFiles()
294315
{
295-
self::$eventsFile = $path;
316+
return static::$files;
296317
}
297318

298319
//--------------------------------------------------------------------

0 commit comments

Comments
 (0)