Hi everybody,
tl;dr: Package configuration in v2 now uses classes, not include files, to modify the project container. This BC-breaking change has little effect on libraries and kernels, but previously installed projects will need to change their config files. Kernel instantiation is also now via class, not a kernel script, so existing projects will need to update `web/index.php` and `cli/console.php` as well.
* * *
Aura v2 projects, like the Aura v1 framework, allow for auto-discovery of DI container configuration for all packages in a project (including library, kernel, and project packages). Until now, we did this by using an instance of an Aura Includer. It would receive a package list and then scan the package directories using glob() to find config files, and then include them in a separate scope with a `$di` container variable.
The benefit here was automation, but the drawback was decreased responsiveness and perhaps some obscurity. The 2-stage "define and modify" cycle meant reading up to 4 files per per package (1 or 2 for the baseline defaults, and then 1 or 2 for the actual config mode). It also meant using file system scans to find files, whether they existed or not. Finally, the look of the directory structure was a bit ugly.
To remedy these flaws, I have made a BC-breaking change in how an Aura v2 projects do their configuration. Instead of a pair of include files under a directory named for the config mode, we use a single class with `define()` and `modify()` methods named for the config mode. Instead of scanning the file system, we use a composer.json entry to map a config mode to a config class. You can see an example of the new layout here:
<
https://github.com/auraphp/Aura.Web_Project/tree/master/config>
This new way of working has the drawback of being somewhat less automated. You have to specify in the package what the config class mappings are. However, this does remove the file system scans entirely, and autoloads the config classes via PSR-4. This means the config classes can be class-mapped by Composer, and otherwise cached more easily. I think the class-based system is a net positive tradeoff as a result.
Unfortunately, it also has the drawback of being a BC break. If you have an existing Aura v2 project, and you `composer update` to the new kernels, your existing project-level config will not work any more.
Even though the project and kernel packages are still in development and have not had even a beta release yet, it still sucks to have BC breaks. Here is the conversion process if you want to get past the break:
1. Issue `composer update` to get the new kernel and library packages.
2. In your `config/` directory, create a `Common.php` class file that looks like the following. (Replace the "Web_Project" namespace portion with "Cli_Project" or "Framework_Project" as appropriate.)
<?php
namespace Aura\Web_Project\_Config;
use Aura\Di\Config;
use Aura\Di\Container;
class Common extends Config
{
public function define(Container $di)
{
}
public function modify(Container $di)
{
}
}
?>
3. Copy the contents of `config/default/define.php` and `config/default/define/*` to the `Common::define()` method.
4. Copy the contents`config/default/modify.php` and `config/default/modify/*`to the `Common::modify()` method.
5. Delete the `config/default/` directory.
6. Repeat steps 2-5 for each remaining `config/` directory. E.g. if the config directory is named `dev`, call the class `Dev`, then copy the `config/dev/` contents to the `define()` and `modify()` methods.
7. Modify your project-level composer.json file to add a new PSR-4 entry that maps the config class namespace to the `config/` directory.
"autoload": {
"psr-0": {
"": "src/"
},
"psr-4": {
"Aura\\Web_Project\\_Config\\": "config/"
}
},
8. Modify your project-level composer.json file to add a new "extra:aura:type" entry, and a new "extra:aura:config" entry. The "type" entry marks this as an Aura project, and the config entries map each config mode to a config class. The resulting composer.json entries will look something like this (again, replace the "Web_Project" namespace portion with "Cli_Project" or "Framework_Project" as appropriate).
"extra": {
"aura": {
"type": "project",
"config": {
"common": "Aura\\Web_Project\\_Config\\Common",
"dev": "Aura\\Web_Project\\_Config\\Dev",
"test": "Aura\\Web_Project\\_Config\\Test",
"prod": "Aura\\Web_Project\\_Config\\Prod"
}
}
}
9. Replace your `web/index.php` script with the following:
<?php
$path = dirname(__DIR__);
require "{$path}/vendor/autoload.php";
$kernel = (new \Aura\Project_Kernel\Factory)->newKernel(
$path,
'Aura\Web_Kernel\WebKernel'
);
$kernel();
?>
10. Replace your `cli/console.php` script with the following:
<?php
$path = dirname(__DIR__);
require "{$path}/vendor/autoload.php";
$kernel = (new \Aura\Project_Kernel\Factory)->newKernel(
$path,
'Aura\Cli_Kernel\CliKernel'
);
$status = $kernel();
exit($status);
?>
That should be all.
* * *
I know this is a big change, but I think it's a positive one, and (I hope) the last big change before a beta release of the kernel and project packages.
If you have questions, comments, or concerns, please raise them here and we can discuss.
Thank you for your patience, and thanks (as always) for using Aura!
--
Paul M. Jones
pmjo...@gmail.com
http://paul-m-jones.com
Modernizing Legacy Applications in PHP
http://mlaphp.com