Creating a Symfony 2 Settings Manager

Often you need a way to enable the user to edit some application settings like contact emails, site themes or social media links, so that you don't have to alter the code each time your admin user changes their email address. In one of our systems we needed a lot of such settings. That's when the idea of a Settings Manager came to life. The intent behind it was to create a way of exposing certain parameters to the user in a way that would be managable and extensible. At first we wanted to make <strong>app/config/parameters.yml</strong> editable, but that would expose too much sensitive information. As we all know, the user can not be trusted with sensitive or delicate data. Sooner than later, they would introduce a typo to some vital parameter, and the whole application would crash. With this option closed, we thought of making a database-based settings object that would hold this problematic data, but this option wasn't extensible enough. Adding another setting would require to add another column to the database table. So we ended up with creating a custom file-based YAML settings manager and a custom class to handle the input.<br/> This article will show you how to create such a manager and how to incorporate it into your own application.

First of all add a parameter to your app/config/parameters.yml file to indicate where the settings will be stored.

    #app/config/parameters.yml
    settings_file: %kernel.root_dir%/config/settings.yml

Create the file and add server write permissions to it any way you want (ie. chmod, chown, setfacl). It's also good practice to add the settings file to ignored files of the repository, and add a settings.yml.dist file to be distributed with the repo.
Let's add sample content to this file for testing.

    #settings.yml sample content    
    sampleNumberSetting: 5
    sampleEmailSetting: email@example.com

Now create the manager class. See this gist for the class code.
This class can be put anywhere in your project as long as it follows the symfony naming and namespace convention.
To use the namespace from the example code put it in Acme/DemoBundle/Helper/SettingsManager.php
It's recommended you create a service out of the manager. First of all, the settings manager will be available from the controller using $this->get('settings');. Moreover, you'll be able to inject the manager into forms and other services easily. Finally, as a service, the manager will be a singleton, which means that only one instance of the settings will be present at any given time. This guarantees that the changes made to the data won't be overwritten by another SettingsManager instance.
To add this class to the service container add the following to app/config/services.yml. Note the %settings_file% parameter from app/config/parameters.yml.

    #app/config/services.yml
    settings:
        class: Acme\DemoBundle\Helper\SettingsManager
        arguments: [%settings_file%]

To enable your users to edit the settings with ease, you'll need to create a form class. See this gist for code.

The final step is to create a controller action and a view with the form.
Controller code - put in Acme/DemoBundle/Controller/SettingsController.php
View code - put in Acme/DemoBundle/Resources/views/Settings/settings.html.twig
That's it! Try it out.

Next post