Skip to content

Database centric Symfony2 configuration management bundle. Global and per-entity settings supported.

License

Notifications You must be signed in to change notification settings

vlefr/SettingsBundle

 
 

Repository files navigation

SettingsBundle

Bundle is used for storing configuration with Symfony2 in database using Doctrine2 ORM.

Build Status SensioLabsInsight

Thanks to Tobias Nyholm and Artem Zhuravlov for contribution.

Features

  • Easy-to-use
  • Fast and extensible
  • Per-user settings
  • Settings scopes
  • Settings validation using full power of Symfony2 Form Component
  • 2 serialization mechanisms in DB: PHP's native serialize() and JSON + you can write your own
  • Settings caching

Docs

Installation (using Composer)

  • Add the following to your composer.json file:

    // composer.json
    {
        "require": {
            // ...
            "dmishh/settings-bundle": "2.0.*@dev"
        }
    }
  • Update dependencies, run from command line:

    php composer.phar update
  • Register the bundle in your AppKernel.php file:

    <?php
    
    // in AppKernel::registerBundles()
    $bundles = array(
        // ...
        new Dmishh\Bundle\SettingsBundle\DmishhSettingsBundle(),
    );
  • Update your database for creating settings table:

    php app/console doctrine:migrations:diff
    php app/console doctrine:migrations:migrate
    • Manually:
    php app/console doctrine:schema:update --force
  • Add following lines to your app/config/routing.yml (see how to override default routing and controller):

    settings:
        resource: "@DmishhSettingsBundle/Resources/config/routing.yml"
        prefix: /settings
  • Configure first setting, add to app/config/config.yml:

    dmishh_settings:
        settings:
            my_first_setting: ~
  • Open http://YOUR-PROJECT-URL/app_dev.php/settings/global and start managing your settings!

General usage

  • In controllers:

    <?php
    
    // GLOBAL SETTINGS
    
    // Set setting value by its name
    $this->get('settings_manager')->set('my_first_setting', 'value');
    
    // Get setting value by its name
    $this->get('settings_manager')->get('my_first_setting'); // => 'value'
    
    // Get all settings
    $this->get('settings_manager')->all(); // => array('my_first_setting' => 'value')
    
    // Set settings' values from associative name-value array
    $this->get('settings_manager')->setMany(array('my_first_setting' => 'new_value'));
    $this->get('settings_manager')->get('my_first_setting'); // => 'new_value'
    <?php
    
    // PER USER SETTINGS
    
    // Each of methods above has last optional $user parameter
    // that allows to get/set per-user settings
    // Your User Entity must implement SettingsOwnerInterface if you wish to use per-user settings
    
    // class User implements SettingsOwnerInterface {
    //     public function getSettingIdentifier() {
    //         return $this->id;
    //     }
    // }
    
    // These are same examples as above with only difference that they are for current user
    $this->get('settings_manager')->set('my_first_setting', 'user_value', $this->getUser());
    $this->get('settings_manager')->get('my_first_setting', $this->getUser()); // => 'user_value'
    $this->get('settings_manager')->all($this->getUser()); //  array('my_first_setting' => 'user_value')
    $this->get('settings_manager')->setMany(array('my_first_setting' => 'new_user_value'), $this->getUser());
    $this->get('settings_manager')->get('my_first_setting', $this->getUser()); // => 'new_user_value'
    
    
    // PER ENTITY SETTINGS
    
    // This is the most interesting part. You can have settings for any entity.
    // Just make sure you have unique values for getSettingIdentifier()
    
    // class Company implements SettingsOwnerInterface {
    //     public function getSettingIdentifier() {
    //         return 'company_' . $this->id;
    //     }
    // }
    
    $myCompany = new Company();
    $this->get('settings_manager')->set('delivery_frequency_setting', 'daily', $myCompany);
    $this->get('settings_manager')->get('delivery_frequency_setting', $this->getUser()); // => 'daily'
  • In services: you must inject @settings_manager or the whole @service_container into your service and use it in the same way as in controllers (like in the example above)

  • In Twig templates:

    {# Global setting #}
    {{ get_setting('some_setting') }} {# => 'value' #}
    
    {# User setting #}
    {{ get_setting('some_user_setting', app.user) }} {# => 'value' #}
    
    {# Getting all global settings #}
    {% for setting in get_all_settings() %}
        {{ setting }} {# => 'value', ... #}
    {% endfor %}

Advanced configuration

Full list of options:

dmishh_settings:
    layout: DmishhSettingsBundle::layout.html.twig
    template: DmishhSettingsBundle:Settings:manage.html.twig
    cache_service: null
    cache_lifetime: 3600
    security:
         manage_global_settings_role: ROLE_USER
         users_can_manage_own_settings: true
    serialization: php # database serialization mechanism (php|json)
    settings:
        my_first_setting:
            validation:
                type: number # any Symfony2 form type
                options: # options passed to form
                    required: false
                    constraints:
                        Symfony\Component\Validator\Constraints\Range:
                            min: 1
                            max: 65535

Settings validation

Settings validation uses Symfony Forms Component. You just specify, for example, type text and use it's options like max_length, etc. Also you can use built-in or custom constraints.

dmishh_settings:
    settings:
        my_first_setting:
            validation:
                type: text
                options:
                    max_length: 15
                    constraints:
                        Symfony\Component\Validator\Constraints\Regex:
                            pattern: "/^\d+$/"

Note: validation is provided only at the form level.

Understanding scopes

Bundle provides settings separation into 3 scopes: ALL, GLOBAL and USER.

GLOBAL and USER scopes are totally independent. ALL scope provides you to inherit global settings when user setting with the same name is not setted. Examples must give more clearance:

<?php

// Example with ALL scope
$this->get('settings_manager')->set('all_scope_setting', 'value');
$this->get('settings_manager')->get('all_scope_setting'); // => 'value'
$this->get('settings_manager')->get('all_scope_setting', $this->getUser()); // => 'value'
$this->get('settings_manager')->set('all_scope_setting', 'user_value', $this->getUser());
$this->get('settings_manager')->get('all_scope_setting', $this->getUser()); // => 'user_value'

// Example #1 with GLOBAL and USER scopes
$this->get('settings_manager')->set('global_scope_setting', 'value');
$this->get('settings_manager')->get('global_scope_setting'); // => 'value'
$this->get('settings_manager')->get('global_scope_setting', $this->getUser()); // => WrongScopeException
$this->get('settings_manager')->set('global_scope_setting', 'value', $this->getUser()); // => WrongScopeException

// Example #2 with GLOBAL and USER scopes
$this->get('settings_manager')->set('user_scope_setting', 'value', $this->getUser());
$this->get('settings_manager')->get('user_scope_setting', $this->getUser()); // => 'value'
$this->get('settings_manager')->get('user_scope_setting'); // => WrongScopeException
$this->get('settings_manager')->set('user_scope_setting', 'value'); // => WrongScopeException

Configuring scope

You may configure a scope to each of your settings. You can use ALL (default), GLOBAL or USER scope.

dmishh_settings:
    settings:
        my_first_user_setting:
            scope: user # all, global

Security

To protect settings modification bundle uses Symfony Security Component. You can limit global settings modification with manage_global_settings_role and grant access to authenticated users to modify their settings.

dmishh_settings:
    security:
         manage_global_settings_role: ROLE_USER
         users_can_manage_own_settings: true

Caching

If you want to cache your settings you may provide a cache service that implements Doctrine\Common\Cache\CacheProvider. Every time you fetch a setting from the database we will cache it for cache_lifetime seconds. If you edit the setting we will automatically invalidate the cache.

dmishh_settings:
    cache_service: apc_cache
    cache_lifetime: 3600

doctrine_cache:
    aliases:
        apc_cache: my_apc_cache
    providers:
        my_apc_cache:
            type: apc
            namespace: random_namespace

Read more about how you configure the Doctrine cache bundle on their GitHub page.

I18n

Define custom settings names

  1. Create yml or xliff file for domain settings (example: settings.en.yml) in any of your bundles or directly in app/Resources (note: your bundle must be activated after DmishhSettingsBundle in AppKernel.php)
  2. Add your settings translations like in the following example for yml format:
labels:
    my_custom_setting: My Custom Label
    profile_update_interval: Profile update interval

Clear your cache with app/console cache:clear

Provide translations for choice type

  1. Create, if not yet, yml or xliff file for domain settings (example: settings.en.yml) in any of your bundles or directly in app/Resources (note: your bundle must be activated after DmishhSettingsBundle in AppKernel.php)
  2. Add your choices translations like in the following example for yml format (add _choice postfix to your setting's name):
labels:
    gender: Gender
    gender_choices:
        m: Male
        f: Female

Clear your cache with app/console cache:clear

Customization

Overriding layout

Via config

Set your layout in config

dmishh_settings:
    layout: DmishhSettingsBundle::layout.html.twig # change to your own

Place settings_form block near your main content block

{% block settings_form %}{% endblock %}
Via bundle inheritance

TODO

Overriding template

dmishh_settings:
    template: DmishhSettingsBundle:Settings:manage.html.twig # change to your own

Overriding controller

TODO

FAQ

→ How to add optional setting?

Add required: false to setting validation options

dmishh_settings:
    settings:
        my_first_setting:
            validation:
                required: false

→ How to add an array setting?

TODO

→ How to inject settings_manager into form?

TODO

Upgrade from 1.0.*

Make sure to read the UPGRADE.md to successfully migrate your application.

Roadmap and contribution

Please, do not hesitate to report bugs or send pull requests. It will help to motivate me to support library better than anything else :)

Version 2.0.0-dev

  • Added optional caching
  • New interface for your entity. We are no longer using UserInterface. Use SettingsOwnerInterface instead.
  • Changed behavior of SettingsManager::all. It will not return global config if the user/local values are missing
  • Added possibility to add default value as third parameter on SettingsManager::get

Version 1.0.2-1.0.7

  • Minor code improvements and bug fixes
  • System messages translations to en, it, es, fr, de, ru, uk, sv languages

Version 1.0.1

  • Ability to choose serialization mechanism (php or json)
  • Ability to add constraints to validation

Version 1.0.0

  • First stable version

License

The MIT License. For the full text of license, please, see LICENSE

© 2013-2015 Dmitriy Scherbina

About

Database centric Symfony2 configuration management bundle. Global and per-entity settings supported.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 98.5%
  • HTML 1.5%