Configuring components
The application and its components are configured using a collection of files called configuration fragments. These fragments are used to synthesize the configuration of one or more components. When the same fragments are used to synthesize different configurations, these configurations are qualified as derived. Fragments are synthesized using callback functions called synthesizers. What's great about synthesized configurations is that they are tailored to exactly for the need of their components, and that they can be cached cancelling the cost of the synthesis.
Configuration fragments
A configuration fragment is a PHP file returning an array. Multiple fragments are used to synthesize
a configuration, or derived configuration. They are usually located in config
directories and
are usually named after the config they are used to synthesize.
The following code is an example of a app
config fragment, which is used to configure the core of
the application:
<?php
namespace ICanBoogie;
return [
AppConfig::CACHE_CATALOGS => false,
AppConfig::CACHE_CONFIGS => false,
AppConfig::CACHE_MODULES => false,
AppConfig::STORAGE_FOR_CONFIGS => Hooks::class . '::create_storage_for_configs',
AppConfig::STORAGE_FOR_VARS => Hooks::class . '::create_storage_for_vars',
AppConfig::ERROR_HANDLER => Debug::class. '::error_handler',
AppConfig::EXCEPTION_HANDLER => Debug::class. '::exception_handler',
AppConfig::SESSION => [
SessionOptions::OPTION_NAME => 'ICanBoogie'
]
];
Synthesizing a configuration
The synthesize()
method of the Config instance is used to synthesize a configuration.
The following example demonstrates how a closure can be used to synthesize multiple fragments:
<?php
use function ICanBoogie\array_merge_recursive;
/* @var $config \ICanBoogie\Config */
$app_config = $config->synthesize('app', function(array $fragments) {
return array_merge_recursive(...$fragments);
});
Magic constructors
The synthesize()
methods supports the magic constructors merge
and recursive merge
which
respectively use the array_merge()
and ICanBoogie\array_merge_recursive()
functions. Thus,
the following code examples are equivalent:
<?php
use function ICanBoogie\array_merge_recursive;
/* @var $config \ICanBoogie\Config */
$app_config = $config->synthesize('app', function(array $fragments) {
return array_merge_recursive(...$fragments);
});
<?php
/* @var $config \ICanBoogie\Config */
$app_config = $config->synthesize('app', 'merge recursive');
Configuration synthesizers
Synthesizers can be defined for each configuration, they are used when the config collection is used as an array:
<?php
use ICanBoogie\Config;
/* @var array $paths */
$synthesizers = [ 'app' => 'merge recursive' ];
$config = new Config($paths, $synthesizers);
$app_config = $config['app'];
Derived configurations
It is possible to synthesize a configuration from the same fragments as another configuration, such a configuration is qualified as derived.
For instance, connections, models, and facets, for the icanboogie/bind-activerecord package are
defined in activerecord
fragments, the synthesizer for the activerecord_connections
configuration filters the fragments data to extract what is relevant.
The following example demonstrates how to obtain the activerecord_connections
configuration using
the synthesize()
method:
<?php
use ICanBoogie\Binding\ActiveRecord\Hooks;
/* @var $config \ICanBoogie\Config */
$events_config = $config->synthesize(
'activerecord_connections',
Hooks::class . '::synthesize_connections_config',
'activerecord'
);
The following example demonstrates how to define the synthesizer of the activerecord_connections
configuration:
<?php
use ICanBoogie\Binding\ActiveRecord\Hooks;
use ICanBoogie\Config;
/* @var $paths array */
$config = new Config($paths, [
'activerecord_connections' => [
Hooks::class . '::synthesize_connections_config', 'activerecord'
]
]);
Declaring synthesizers
Configuration synthesizers are declared using the extra
section of the composer.json
file.
The following example demonstrates how the synthesizers can be declared for an
activerecord_connections
and an activerecord_models
configuration. Notice how the #
sign is
used to separate the callable and the configuration fragment name:
{
"extra": {
"icanboogie": {
"config-constructor": {
"activerecord_connections": "ICanBoogie\\Binding\\ActiveRecord\\Hooks::synthesize_connections_config#activerecord",
"activerecord_models": "ICanBoogie\\Binding\\ActiveRecord\\Hooks::synthesize_models_config#activerecord"
}
}
}
}
Caching synthesized configurations
Caching synthesized configurations removes the cost of synthesizing configurations by reusing the result of a previous synthesis. To enable caching, you just need to provide an instance implementing Storage.
<?php
use ICanBoogie\Config;
use ICanBoogie\Storage\Storage;
/* @var $paths array */
/* @var $synthesizers array */
/* @var Storage $cache */
$config = new Config($paths, $synthesizers, $cache);
Events
Cache must be cleared
The clear_cache
event of class ClearCacheEvent is fired when the various caches of the
application must be cleared. Event hooks may use this event to clear their own cache. For instance,
ICanBoogie clears its configurations cache when this event is fired.