Skip to content

Commit

Permalink
Merge pull request #1215 from bcit-ci/autodiscovery
Browse files Browse the repository at this point in the history
Autodiscovery for Modules
  • Loading branch information
lonnieezell authored Sep 13, 2018
2 parents a201aa8 + d6b5723 commit 9414217
Show file tree
Hide file tree
Showing 23 changed files with 263 additions and 179 deletions.
54 changes: 54 additions & 0 deletions application/Config/Modules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php namespace Config;

// Cannot extend BaseConfig or looping resources occurs.
class Modules
{
/*
|--------------------------------------------------------------------------
| Auto-Discovery Enabled?
|--------------------------------------------------------------------------
|
| If true, then auto-discovery will happen across all elements listed in
| $activeExplorers below. If false, no auto-discovery will happen at all,
| giving a slight performance boost.
*/
public $enabled = true;

/*
|--------------------------------------------------------------------------
| Auto-discover Rules
|--------------------------------------------------------------------------
|
| Lists the aliases of all discovery classes that will be active
| and used during the current application request. If it is not
| listed here, only the base application elements will be used.
*/
public $activeExplorers = [
'events',
'registrars',
'routes',
'services',
];

/**
* Should the application auto-discover the requested resources.
*
* Valid values are:
* - events
* - registrars
* - routes
* - services
*
* @param string $alias
*
* @return bool
*/
public function shouldDiscover(string $alias)
{
if (! $this->enabled) return false;

$alias = strtolower($alias);

return in_array($alias, $this->activeExplorers);
}
}
1 change: 0 additions & 1 deletion application/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(true);
$routes->discoverLocal(false);

/**
* --------------------------------------------------------------------
Expand Down
25 changes: 21 additions & 4 deletions system/Config/BaseConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ class BaseConfig
*
* @var array
*/
protected $registrars;
public static $registrars = [];

protected static $didDiscovery = false;

protected static $moduleConfig;

/**
* Will attempt to get environment variables with names
Expand All @@ -64,6 +68,8 @@ class BaseConfig
*/
public function __construct()
{
static::$moduleConfig = config('Modules');

$properties = array_keys(get_object_vars($this));
$prefix = get_class($this);
$slashAt = strrpos($prefix, '\\');
Expand Down Expand Up @@ -120,7 +126,10 @@ public function __construct()
}
}

$this->registerProperties();
if (ENVIRONMENT != 'testing')
{
$this->registerProperties();
}
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -165,13 +174,21 @@ protected function getEnvValue(string $property, string $prefix, string $shortPr
*/
protected function registerProperties()
{
if (empty($this->registrars))
if (! static::$moduleConfig->shouldDiscover('registrars'))
{
return;
}

if (! static::$didDiscovery)
{
$locator = \Config\Services::locator();
static::$registrars = $locator->search('Config/Registrar.php');
}

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

// Check the registrar class for a method named after this class' shortName
foreach ($this->registrars as $callable)
foreach (static::$registrars as $callable)
{
// ignore non-applicable registrars
if ( ! method_exists($callable, $shortName))
Expand Down
27 changes: 16 additions & 11 deletions system/Config/BaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,22 +202,27 @@ protected static function discoverServices(string $name, array $arguments)
{
if (! static::$discovered)
{
$locator = static::locator();
$files = $locator->search('Config/Services');
$config = config('Modules');

if (empty($files))
if ($config->shouldDiscover('services'))
{
return;
}
$locator = static::locator();
$files = $locator->search('Config/Services');

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

if (! in_array($classname, ['CodeIgniter\\Config\\Services']))
// Get instances of all service classes and cache them locally.
foreach ($files as $file)
{
static::$services[] = new $classname();
$classname = $locator->getClassname($file);

if (! in_array($classname, ['CodeIgniter\\Config\\Services']))
{
static::$services[] = new $classname();
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions system/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ public static function get(string $name, bool $getShared = true)

//--------------------------------------------------------------------

/**
* Helper method for injecting mock instances while testing.
*
* @param string $class
* @param $instance
*/
public static function injectMock(string $class, $instance)
{
self::$instances[$class] = $instance;
}

//--------------------------------------------------------------------

/**
* Find configuration class and create instance
*
Expand Down
2 changes: 1 addition & 1 deletion system/Config/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ public static function routes($getShared = true)
return self::getSharedInstance('routes');
}

return new \CodeIgniter\Router\RouteCollection(self::locator());
return new \CodeIgniter\Router\RouteCollection(self::locator(), config('Modules'));
}

//--------------------------------------------------------------------
Expand Down
75 changes: 48 additions & 27 deletions system/Events/Events.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php namespace CodeIgniter\Events;

use Config\Services;

/**
* CodeIgniter
*
Expand Down Expand Up @@ -53,19 +55,12 @@ class Events
protected static $listeners = [];

/**
* Flag to let us know if we've read from the Config file
* Flag to let us know if we've read from the Config file(s)
* and have all of the defined events.
*
* @var bool
*/
protected static $haveReadFromFile = false;

/**
* The path to the file containing the events to load in.
*
* @var string
*/
protected static $eventsFile = '';
protected static $initialized = false;

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

/**
* A list of found files.
* @var array
*/
protected static $files = [];

//--------------------------------------------------------------------

/**
* Ensures that we have a events file ready.
*
* @param string|null $file
*/
public static function initialize(string $file = null)
public static function initialize()
{
// Don't overwrite anything....
if ( ! empty(self::$eventsFile))
if (static::$initialized)
{
return;
}

// Default value
if (empty($file))
$config = config('Modules');

$files = [APPPATH.'Config/Events.php'];

if ($config->shouldDiscover('events'))
{
$locator = Services::locator();
$files = $locator->search('Config/Events.php');
}

static::$files = $files;

foreach (static::$files as $file)
{
$file = APPPATH . 'Config/Events.php';
if (! file_exists($file))
{
continue;
}

include $file;
}

self::$eventsFile = $file;
static::$initialized = true;
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -155,15 +170,9 @@ public static function on($event_name, callable $callback, $priority = EVENT_PRI
public static function trigger($eventName, ...$arguments): bool
{
// Read in our Config/events file so that we have them all!
if ( ! self::$haveReadFromFile)
if ( ! self::$initialized)
{
self::initialize();

if (is_file(self::$eventsFile))
{
include self::$eventsFile;
}
self::$haveReadFromFile = true;
}

$listeners = self::listeners($eventName);
Expand Down Expand Up @@ -288,11 +297,23 @@ public static function removeAllListeners($event_name = null)
/**
* Sets the path to the file that routes are read from.
*
* @param string $path
* @param array $files
*/
public static function setFiles(array $files)
{
static::$files = $files;
}

//--------------------------------------------------------------------

/**
* Returns the files that were found/loaded during this request.
*
* @return mixed
*/
public static function setFile(string $path)
public function getFiles()
{
self::$eventsFile = $path;
return static::$files;
}

//--------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 9414217

Please sign in to comment.