Git Product home page Git Product logo

settingsbundle's Introduction

SettingsBundle

Bundle for storing configuration with Symfony in database using Doctrine ORM.

๐Ÿ‘€ This bundle was previously known as dmissh/settings-bundle, and the Packagist installation instruction will stay as is.

Features

  • Easy-to-use (Twig extension, container service)
  • Settings scopes per user, global or all
  • Settings validation by using the Symfony Form Component
  • 2 serialization mechanisms: PHP serialize() and JSON (+ you can write your own)
  • Settings caching (PSR-6)
  • Fast and extensible

Quick usage examples

Symfony controller:

// Global settings
$settingsManager->set('name', 'foo');
$settingsManager->get('name'); // returns 'foo'

// User settings
$settingsManager->get('name', $user); // returns global 'foo'
$settingsManager->set('name', 'bar', $user);
$settingsManager->get('name', $user); // returns 'bar'

Twig template:

{# Global setting #}
{{ get_setting('some_setting') }} {# => 'value' #}

{# User setting #}
{{ get_setting('some_user_setting', app.user) }} {# => 'value' #}

See the general usage documentation for more examples.

Documentation

Changelog, 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 :)

See CHANGELOG.md for all major changes.

Upgrade from 1.0.*

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

License

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

settingsbundle's People

Contributors

alexandre-t avatar aminin avatar atyz avatar dmishh avatar fautor avatar foaly-nr1 avatar hason avatar jongotlin avatar jphilaine avatar koc avatar nikophil avatar nyholm avatar rvanlaak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

settingsbundle's Issues

2.8 / 3.0 Compatibily ?

List of TODOs for ~2.8|~3.0 compatibility:

  • Twig SettingExtension deprecations
  • Decide on bumping framework-bundle from 2.3 LTS to 2.6 or 2.7 LTS
  • Service definition factory method #62
  • FormType::getName, FormType::setDefaultOptions, buildForm via FormType FQCN

Customizing form labels

Hello,
Thank you for the bundle! It seems very useful for my purposes. The only problem is that I'm having trouble figuring out how to customize form labels. I tried adding a "label" option under "options" in the configuration file, but that had no effect. Any help would be appreciated.

Code standards

I would suggest to follow Symfony best practices with coding standards. That means PSR-1 and PSR-2 + some extra Symfony stuff.

Any thoughts?

Entity

Hi. Its possible to save Entities in setting field ?

dmishh_settings:
    settings:
        project_filter:
            type: entity
            options: {class: AppBundle:Project, multiple: true, choice_label: name}

In this config it save, but then on form load (/settings/global) symfony throw error

Entities passed to the choice field must be managed. Maybe persist them in the entity manager?

Problem with cache

I use a filesystem cache service like described in the docs. The problem is, when I change the value of a setting with the CachedSettingsManager set method, the cache with the single setting key (for example dmishh_settings__setting) is cleared, but not the cache that will be filled with the all method (dmishh_settings__).
So when I fetch the settings with $this->get('settings_manager')->all(), I get wrong values from the expired cache.
So maybe this cache should also be deleted in the set methods.

Error on Settings form

Hello and thx for your work these days !

I updated my project, and now I get an error when I want to display the built-in settings form :

The type name specified for the service "form.type.settings_management" does not match the actual name. Expected "settings_management", given "Dmishh\SettingsBundle\Form\Type\SettingsType"

You can quickly get rid of this error by replacing this line in SettingsController.php :

$form = $this->createForm('settings_management', $this->get('settings_manager')->all($owner));

by that :

$form = $this->createForm(SettingsType::class, $this->get('settings_manager')->all($owner));

(and add the corresponding use statement)
And then, delete the corresponding service.

Thx again for your work ๐Ÿ‘

Symfony 4 support

Hi,

thanks for this nice bundle.

could you provide a symfony 4 support please ?

thanks

Make it easier to configure settings

There is a very deep tree. A typical setting config looks like this:

dmishh_settings:
    settings:
        my_first_setting:
            scope: user
            validation:
                type: number # any Symfony2 form type
                options: # options passed to form
                    required: false
                    attr: { class: 'my-class' }
                    constraints: # To make sure the data looks like you expect
                        Symfony\Component\Validator\Constraints\Range:
                            min: 1
                            max: 65535

I suggest to make it a bit more flat. Maybe something like:

dmishh_settings:
    settings:
        my_first_setting:
            scope: user
            type: number # any Symfony2 form type
            options: # options passed to form
                required: false
                attr: { class: 'my-class' }
            constraints: # To make sure the data looks like you expect
                Symfony\Component\Validator\Constraints\Range:
                    min: 1
                    max: 65535

I've moved the type and constraints up one level and removed the validation. How do you feel about this change? Should I make a PR?

Rewrite the message in WrongScopeException

We should rewrite the WrongScopeException to something more descriptive. Ie there are two reasons for the WrongScopeException to be thrown.

  1. You have misconfigured the scope
  2. You have called the SettingsManager::get with the wrong amount of parameters. Either you forgot the $owner on Local scope or you used $owner on a Global scope.

Symfony 5.x compatablity

Today I installed this bundle in my SF 5.1 project and encountered the following issues:

Routing not working properly

Changed:

# Dmishh\SettingsBundle\Resources\config\routing.yml
dmishh_settings_manage_global:
    path:         /global
    defaults:     { _controller: DmishhSettingsBundle:Settings:manageGlobal }

dmishh_settings_manage_own:
    path:         /personal
    defaults:     { _controller: DmishhSettingsBundle:Settings:manageOwn }

into:

# Dmishh\SettingsBundle\Resources\config\routing.yml
dmishh_settings_manage_global:
    path:         /global
    defaults:
        _controller: Dmishh\SettingsBundle\Controller\SettingsController::manageGlobalAction

dmishh_settings_manage_own:
    path:         /personal
    defaults:
        _controller: Dmishh\SettingsBundle\Controller\SettingsController::manageOwnAction

Autowiring not working properly

Changed:

# Dmishh\SettingsBundle\Resources\config\services.yml
    Dmishh\SettingsBundle\Controller\SettingsController:
        arguments:
            - '@translator'
            - '@Dmishh\SettingsBundle\Manager\SettingsManagerInterface'
            - ~ # template
            - ~ # manage own settings
            - ~ # security role

Into:

# Dmishh\SettingsBundle\Resources\config\services.yml
    Dmishh\SettingsBundle\Controller\SettingsController:
        public: true
        autowire: true
        tags: ['container.service_subscriber']
        arguments:
            - '@translator'
            - '@Dmishh\SettingsBundle\Manager\SettingsManagerInterface'
            - ~ # template
            - ~ # manage own settings
            - ~ # security role

Using deprecated templating paths

Changed:

// Dmishh\SettingsBundle\DependencyInjection/Configuration.php

//...
        $rootNode
            ->children()
                ->scalarNode('template')
                    ->defaultValue('DmishhSettingsBundle:Settings:manage.html.twig')
//...

Into:

// Dmishh\SettingsBundle\DependencyInjection/Configuration.php

// ...
        $rootNode
            ->children()
                ->scalarNode('template')
                    ->defaultValue('@DmishhSettings/Settings/manage.html.twig')
//...

If I have the time, I will open a PR.

Wrong/outdated code snippets in the docs

I've just begun using this bundle and I've come across a few code snippets in the documentation that are wrong or outdated when compared to the current master. Proposed fixes in the pull request #83:

Resources/doc/installation.md

master:

<?php

// in AppKernel::registerBundles()
$bundles = array(
    // ...
    new Dmishh\SettingsBundle\DmishhSettingsBundle(),
);

is missing the Bundle part of the namespace just before SettingsBundle.

Fixed:

<?php

// in AppKernel::registerBundles()
$bundles = array(
    // ...
    new Dmishh\Bundle\SettingsBundle\DmishhSettingsBundle(),
);

Resources/doc/advanced-configuration.md

master:

dmishh_settings:
    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:
            type: number # any Symfony form type
            options: # options passed to form
                required: false
            constraints:
                Symfony\Component\Validator\Constraints\Range:
                    min: 1
                    max: 65535

The options and constraints sections of my_first_setting appear directly below it but they should go below a validation section. Also the constraints section must go under the options section.

Fixed:

dmishh_settings:
    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 Symfony form type
                options: # options passed to form
                    required: false
                    constraints:
                        Symfony\Component\Validator\Constraints\Range:
                            min: 1
                            max: 65535

master:

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

Fixed:

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

Resources/doc/faq.md

master:

dmishh_settings:
    settings:
        my_first_setting:
            options:
                required: false

same error as Resources/doc/advanced-configuration.md

fixed:

dmishh_settings:
    settings:
        my_first_setting:
            validation:
                options:
                    required: false

Understanding scopes

I want to discuss planned features of this bundle. The PR (#54) from @juanolon got me thinking of this.

Currently we have 3 scopes. GLOBAL and USER where the latter requires you to provide an entity. We do also have ALL which is some kind of default for the USER scope. (One can discuss if the names are proper #23).

PR #54 introduce a granularity of the USER scope. I understand the need and I agree with it. He wants to make sure class A does not access settings of class B. (Both are naturally in the USER scope). This is a fix for #3.


I can see some possible solution for this. I don't know which one is better. .

Option 1) Making scopes dynamic. Lets use GLOBAL, ALL and DYNAMIC and then extend the SettingsOwnerInterface with a getScope function.

Option 2) Something more like #54 where we define a namespace and make sure the entity in the USER scope is an instance of that namespace.

Option 3) In the configuration specify what entities that are allowed to what sections of the configuration.

Option 4) ??? There must be something else

Load settings choices from database

I have a use case where putting the choices for a setting in the configuration files is not naturel.
I have content stored in a database and users can select some items from this content and put it
in their preferences.

The form type class Dmishh\Bundle\SettingsBundle\Form\Type/SettingsType builds choices from the configuration and I think it does not allow to provide choices from another source.

By design the Symfont Form Component does not allow to change form options after it has been built.

Letting dev provide the choices from another source would add more flexibilite and allow building more complex settings.

What about doing it using Symfony Event dispatcher ?

Serialization

It would be great if this bundle will be configurable to choose serialization type - (un)?serialize, json_(en|de)code. To provide availability to read data from different systems.

Use Symfony Serializer

I think the Symfony Serializer might be better than php's serialize().

Or in addition to, I guess.

Duplicated settings

I have found a weird problem when using alpha2, the database is storing duplicated settings.


With this configuration...

dmishh_settings:
    settings:
        test1: ~

...and this code in a Symfony command:

protected function execute(InputInterface $input, OutputInterface $output)
{
    $manager = $this->getContainer()->get('settings_manager');

    $manager->set('test1', 1);
    $manager->set('test1', 2);
    $manager->set('test1', 3);
}

Everything works fine, the "dmishh_settings" table stores a single row:

id name value ownerId
1 test1 i:3; NULL

With this configuration...

dmishh_settings:
    settings:
        test1: ~
        test2: ~

...and this code in a Symfony command:

protected function execute(InputInterface $input, OutputInterface $output)
{
    $manager = $this->getContainer()->get('settings_manager');

    $manager->set('test1', 1);
    $manager->set('test1', 2);
    $manager->set('test1', 3);
    $manager->set('test2', true);
}

It inserts 5 rows in "dmishh_settings":

id name value ownerId
1 test1 i:3; NULL
2 test2 N; NULL
3 test2 N; NULL
4 test2 b:1; NULL
5 test1 i:3; NULL

Update BuildForm to use FQCN

This is required to support sf 3.0.

Does this mean we need to specify the FQCN in the config?

dmishh_settings:
    settings:
        my_first_setting:
            type: 'Symfony\Component\Form\Extension\Core\Type\IntegerType'

We maybe should have a converter somehow for some standard types.

database schema for clean install

Hi guys,

I am trying to install this bundle in my project but when i create a new database and run doctrine:schema:create i get the following error:
There is no column with name 'ownerId' on table 'dmishh_settings'.
Any idea what could be causing this?

What should SettingManager::all return?

As the topic suggest, what should be returned on all? (A) All settings that the users have stored or (B) All settings that the user can store?

Scenario A:

$sm=$this->get('settings_manager');
$sm->all(); // array('all_scope_setting'=>null)
$sm->all($this->getUser()); // array()  /* difference */

$sm->set('all_scope_setting', 'value');
$sm->all(); // array('all_scope_setting'=>'value')
$sm->all($this->getUser()); // array() /* difference */

$sm->set('all_scope_setting', 'foobar', $this->getUser());
$sm->all(); // array('all_scope_setting'=>'value')
$sm->all($this->getUser()); // array('all_scope_setting'=>'foobar')

Scenario B:

$sm=$this->get('settings_manager');
$sm->all(); // array('all_scope_setting'=>null)
$sm->all($this->getUser()); // array('all_scope_setting'=>null)  /* difference */

$sm->set('all_scope_setting', 'value');
$sm->all(); // array('all_scope_setting'=>'value')
$sm->all($this->getUser()); // array('all_scope_setting'=>'value')  /* difference */

$sm->set('all_scope_setting', 'foobar', $this->getUser());
$sm->all(); // array('all_scope_setting'=>'value')
$sm->all($this->getUser()); // array('all_scope_setting'=>'foobar')

At the moment is A implemented. I suggest we should implement B instead because it make more sense. Especially with #15.

Error SettingsController not public on Symfony 4.4

Hi,

I am getting the following error on Symfony 4.4:

The controller for URI "/settings/global" is not callable: Controller "Dmishh\SettingsBundle\Controller\SettingsController" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?

This is solved by adding public: true to the service definition of SettingsController

[RFC] Use TranslationBundle while editing Settings

The backend to edit Settings is great, especially because it just uses the Symfony form component in a proper way.

Some of my Settings require translation, that's why I'd like to know you opinion on integrating the TranslationFormBundle into your bundle. It will allow the SettingsBundle to introduce an optional config parameter:

dmishh_settings:
    settings:
        my_first_setting: 
            translatable: true

Can you maybe comment on the translation strategy to use? I'm using the KnpDoctrineExtension strategy in my application, which works great.

Clear method does not clear owned settings

I am using this bundle in a project to define a global shipping_cost setting. Since an admin can set a "discounted" shipping cost to specific customers, the setting has ALL scope. This way I can do something like $settings->get('shipping_cost', $user) to retrieve either the specific (customer) shipping cost, or the global one.

The problem appears when an admin wants to remove the specific shipping cost from the customer. It does not get deleted from the database. Instead of that, it is set to the same value as the global one. This creates a problem when the global value changes.

settings per entity

Hey,
nice bundle btw. i do have a question:
i would like to have different settings per user. On my project, we use different entities per user group. And each of them has different settings. The user entity already implements the SettingsOwnerInterface interface and getSettingIdentifier() returns different id's per user type. But all settings with scope "user" are being show to all users.

So my question is, did i miss something? or is this the current behaviour of the scope "user"? if so, does adding a new config namespace to the scope "user", and then filter the settings per entity class would be a good approach? something like this:

dmishh_settings:
    settings:
        guide:
            scope: user
            namespace: 'My\Bundle\Entity\Student'
            validation:
                type: choice
                options:
                    choices:
                        - opt1
                        - opt2
                    required: false
                    expanded: true
                    attr:
                        class:  'form-group checkbox'
                    placeholder: false

Symfony 6 compatibility

Hi,
Has anyone already started working on the changes to be made to be compatible with Symfony 6?
Thank you

Exception on new Cache interface

When we build the new cached container, we get the following exception:

Catchable Fatal Error: Argument 2 passed to Dmishh\SettingsBundle\Manager\CachedSettingsManager::__construct() must be an instance of Psr\Cache\CacheItemPoolInterface, instance of Doctrine\Common\Cache\ApcCache given

The cache service we inject right now is defined via doctrine_cache:

dmishh_settings:
    cache_service: my_apc_cache
    cache_lifetime: 3600
doctrine_cache:
    providers:
        my_apc_cache:
            type: apc
            namespace: my_apc

See https://github.com/dmishh/SettingsBundle/blob/master/Resources/doc/advanced-configuration.md

@Nyholm The caching layer has changed, so can you also add some docs to UPGRADE.md about that?

Do you think we should make the Doctrine\Common\Cache that was supported before compatible with the new Psr\Cache\CacheItemPoolInterface that is used now? Or will Doctrine eventually also move to PSR? That would mean everybody has to require https://github.com/php-cache/adapter-bundle right?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.