ConfigBundle manages configuration settings stored in the database and makes them accessible via a service in your
Symfony project. These settings are similar to those defined in parameters.yml
but can be modified at runtime, e.g.
by an admin user.
Let Composer download and install the bundle by running
php composer.phar require effiana/config-bundle:~2.2
in a shell.
// in app/AppKernel.php
public function registerBundles() {
$bundles = [
// ...
new Effiana\ConfigBundle\EffianaConfigBundle(),
];
// ...
}
Preferably you do this by calling
# in a shell
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
or
# in a shell
php bin/console doctrine:schema:update
or however you like.
You can either import the default routing configuration
# in app/config/routing.yml
effiana_config_settings:
resource: "@EffianaConfigBundle/Resources/config/routing/settings.xml"
prefix: /settings
...or add your own to have full control over the URL pattern.
# in app/config/routing.yml
effiana_config_settings_modify:
path: /settings/modify
defaults:
_controller: Effiana\ConfigBundle\Controller\SettingsController::modifyAction
Some CSS is needed to render the form correctly. Install the assets in your project:
# in a shell
php bin/console assets:install --symlink web
This bundle does not provide functionality to create new settings because this would make no sense at runtime.
Those settings will be used in your application and thus code needs to be written for that.
This means that you have to create new settings in the database table effiana_config_setting
yourself, e.g. using a
migration.
If you added the route described above you can manage the values of all defined settings in a simple form.
By default, you can access that form by browsing to app_dev.php/settings/modify
.
But you probably want to limit access to this form in your security configuration.
The bundle provides a service called effiana_config
. Inside of a controller you can call
$this->get('effiana_config')->get('name-of-a-setting')
to retrieve the value of the setting name-of-a-setting
. Furthermore, you can call
$this->get('effiana_config')->all()
to get an associative array of all defined settings and their values.
$this->get('effiana_config')->getBySection('name-of-a-section')
will fetch only settings with the specified section (or those without a section if explicitly passing null
for the name).
With the same service you can set new values of settings:
$this->get('effiana_config')->set('name-of-a-setting', 'new value');
$this->get('effiana_config')->setMultiple(['setting-1' => 'foo', 'setting-2' => 'bar']);
Keep in mind that the setting has to be present, or an exception will be thrown.
The Twig extension in this bundle supports reading settings directly in your template.
{{ effiana_setting('name-of-a-setting') }}
To reduce the number of database queries, you can set up a cache for settings. First, you have to choose which cache implementation you'd like to use. Currently, there are adapters available for:
Refer to the documentation of each implementation for details and read on in the corresponding section below. When
done, ConfigBundle
will automatically cache settings (using the built-in effiana_config_cache_adapter
service).
Keep in mind to clear the cache (if needed) after modifying settings outside of your app (e.g. by Doctrine migrations):
# in a shell
php bin/console doctrine:cache:clear effiana_config_cache
Set the parameter effiana_config.cache_adapter.class
appropriately and configure a so-called cache provider with the
alias effiana_config_cache_provider
:
# in app/config/config.yml
parameters:
effiana_config.cache_adapter.class: Effiana\ConfigBundle\CacheAdapter\DoctrineCacheBundleAdapter
doctrine_cache:
providers:
effiana_config_cache:
apc: ~
namespace: effiana_config
aliases:
- effiana_config_cache_provider
Set the parameter effiana_config.cache_adapter.class
appropriately and configure a so-called cache pool with the
service id effiana_config_cache_provider
:
# in app/config/config.yml
parameters:
effiana_config.cache_adapter.class: Effiana\ConfigBundle\CacheAdapter\SymfonyCacheComponentAdapter
services:
effiana_config_cache_provider:
class: Symfony\Component\Cache\Adapter\FilesystemAdapter
public: false
arguments:
- 'effiana_config'
- 0
- '%kernel.cache_dir%'
If you've enabled the build-in form, you can define where to redirect on successfully saving the changes by setting the target route name:
# in app/config/parameters.yml
parameters:
effiana_config.redirectRouteAfterModify: effiana_config_settings_modify
If you want to render settings in a group (called section here), you'll have to assign those settings a common section name (in the database). Optionally, you can influence the order of these sections:
# in app/config/parameters.yml
parameters:
effiana_config.configTemplate.sectionOrder: [section1, section2, section3]
Settings without a section will be rendered at first. Sections without explicit ordering are rendered at last.
You can add translations for all settings (and sections) to be shown in the form by adding them to translation files
with the ConfigBundle
domain, e.g.
# in app/Resources/ConfigBundle/translations/ConfigBundle.en.yml
name-of-a-setting: name of the setting
# in app/Resources/ConfigBundle/translations/ConfigBundle.de.yml
name-of-a-setting: Name der Einstellung
The custom entity has to provide a mapping for the field value
. The class BaseSetting
defines this field, but no
mapping for it. This allows easy overriding, including the data type. In the following example, the value
field will
be mapped to a text
column, which will in turn render the built-in form fields as textarea
.
So create the entity and its appropriate mapping:
// src/MyCompany/MyBundle/Entity/MySetting.php
use Effiana\ConfigBundle\Entity\BaseSetting;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="Effiana\ConfigBundle\Repository\SettingRepository")
* @ORM\Table(name="my_setting")
*/
class MySetting extends BaseSetting {
/**
* @var string|null
* @ORM\Column(name="value", type="text", nullable=true)
*/
protected $value;
/**
* @var string|null
* @ORM\Column(name="comment", type="string", nullable=true)
*/
protected $comment;
public function setComment($comment) {
$this->comment = $comment;
}
public function getComment() {
return $this->comment;
}
}
And make the bundle aware of it:
# in app/config/config.yml
effiana_config:
entity_name: MyCompany\MyBundle\Entity\MySetting