SlideShare a Scribd company logo
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
I love my




http://www.flickr.com/photos/slushpup/3055613967/
Dennis Benkert
  Software Developer
      Coaching
      Coding
      Consulting
Things Your Mother Didn’t Tell
You About Bundle Configurations
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
app/config.yml
parameters:
    global.page_size:            10
    gloabl.page_num:             5
    global.tracking.key:         ASFDIPSADPFIHwer234123QSD

       # Various configuration
       webservices.timeout:      100
       content_check.enabled:    true
       birthdates.start:         1950 # TODO: Delete after release
       logging.registrations:    true

       # Tracking Bundle Configuration
       trackingbundle.user:               rebum
       trackingbundle.api.version:        1_0
       trackingbundle.use_ssl:            true    # Do not touch this!!!
       trackingbundle.track_super_users: false
       infobundle.god_mode:               true # Ticket 123456234
       infobundle.level:                  42
       # Connection data for some service
       some_webservice.url:
       some_webservice.user:
                                               This file was much
                                          http://example.com
                                          api
       some_webservice.key:               Sdfihwef $5sdf” SAFAWEF
       some_webservice.ssl:               true  loooooonger…
       # More configuration
       more.config:               100
       even.more.config:          true
       oh_my_option:              123
       foo.bar.baz:               true
       application.lock_user:     super
       misc.timeout:              300
       http.meta.title:           super page
       http.meta.keywords:
           - some
           - keywords
           - for
           - this
           - page
        http.description:         Some crazy description for the homepage that we all love so much

#...
app/config.yml
parameters:
    global.page_size: in
                  All      one context
                              10
    gloabl.page_num:          5
    global.tracking.key:      ASFDIPSADPFIHwer234123QSD

    # Various configuration                 Correct type?
    webservices.timeout:      '100'
    content_check.enabled:    true
    birthdates.start:         1950 # TODO: Delete after release
    logging.registrations:    true

    # Tracking Bundle Configuration
    trackingbundle.user:              rebum Only this bundle?!
    trackingbundle.api.version:       1_0
    trackingbundle.use_ssl:           true     # Do not touch this!!!
    trackingbundle.track_super_users: false
    infobundle.god_mode:              true # Ticket 123456234
    infobundle.levl:                  42
    # Connection data for some service
    some_webservice.url:              http://example.com
    some_webservice.user:             api Multiple connections?!
         Correct key?!
    some_webservice.key:               Sdfihwef $5sdf” SAFAWEF
    some_webservice.ssl:              true
app/config.yml
my_project_tracking:
    user:                   rebum
    api_version:            1_0
    use_ssl:                true    # Do not touch this!!!
    track_super_users:      false

my_project_info:
    god_mode:              More structure 123456234
                            true  # Ticket
    level:                  42

my_project_ webservice:
    connection:
        url:                http://example.com
        user:               api
        key:                Sdfihwef $5sdf” SAFAWEF
        ssl:                'true'
                                         Correct type?!!11one
parameters:
    global.page_size:       10
    gloabl.page_num:        5
    global.tracking.key:    ASFDIPSADPFIHwer234123QSD

    # ...
Bad configuration
   Worse than bad code
     (In terms of structure)
Bad validation
    Even worse
feature_x_bundle.redirct:   302


           Correct key?!
Config Component




    http://www.flickr.com/photos/capcase/2735500813/
Cache               Locate

           Config
Validate            Load
Cache               Locate

           Config
Validate            Load
Locate & Load




      http://www.flickr.com/photos/onthespiral/3406281939/
use SymfonyComponentConfigFileLocator;

$locator = new FileLocator(
    __DIR__.'/../Resources/config'
);
        Path(s) of resources
Available in path(s)?


$locator->locate('config.xml');
src/YourBundle/DependencyInjection/YourBundleExtension.php
             Special Loader for DIC
use SymfonyComponentDependencyInjectionLoader;

$loader = new LoaderXmlFileLoader(
    $container,
    new FileLocator('...')
);
                        Path(s) of resources
Load configuration in DIC


$loader->load('services.xml');


                Your services
$loader->load('services.xml');
$loader->load('other_services.xml');
Cache               Locate

           Config
Validate            Load
Validate




http://www.flickr.com/photos/jeremybrooks/3214838875/
Your bundle context
app/config.yml

your_bundle:
    enabled: true
src/YourBundle/DependencyInjection/YourBundleExtension.php

public function load($configs, /*...*/)
{
     $config = $this unprocessed
            Matched and
         ->processConfiguration(/**/);

       if (true === $config['enabled']) {
            $loader->load('services.xml');
       }            Processed and validated
}
your_bundle:
    enabled: true


               Validate
               Convert

array('enabled' => true);
Build a Config Tree




          http://www.flickr.com/photos/jlscha/6226656013/
src/YourBundle/DependencyInjection/Configuration.php

public function getConfigTreeBuilder()
{           The config tree
    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder
        ->root('your_bundle');

       // tree definition ...
             Your root node

       return $treeBuilder;
}
your_bundle:
    enabled: true
$rootNode Node type           Node name
     ->children()
          ->booleanNode('enabled')
                ->defaultFalse()
          ->end()
     ->end()     More options
;
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
src/YourBundle/DependencyInjection/YourBundleExtension.php
                      Correct type
public function load($configs, /*...*/)
{
     if (true === $config['enabled']) {
         // ...
     }
}
Scalar

Boolean            Array


          Node
Scalar

Boolean            Array


          Node
->booleanNode('enabled')->end()
your_bundle:
    enabled: troo
Type validation
Scalar

Boolean            Array


          Node
your_bundle:
    timeout: 60
All scalar types


->scalarNode('timeout')
     ->defaultValue(3600)
     ->isRequired()
     ->cannotBeEmpty()
->end()
              Validation options
your_bundle:
    timeout: sixty seconds
->scalarNode('timeout')
        Custom validation
     // ...                      Validation logic
     ->validate()
          ->ifTrue(function ($v) {
                return !is_int($v);
          })
          ->thenInvalid('No integer')
     ->end()
->end()                   Custom error
Custom error
Scalar

Boolean            Array


          Node
connection:
    url: http://example.com
    user: api
    key: $ome35ecre7Ke$
Group of nodes

->arrayNode('connection')
    ->children()
        ->scalarNode('url')
            ->isRequired()
                              Specific validation
        ->end()
        ->scalarNode('user')->end()
        ->scalarNode('key')->end()
    ->end()
->end()
array('connection' =>
    array(
        'url' => 'http://example.com',
        'user' => 'api',
        'key' => '$ome35ecre7Ke$'
    )
);
connections:
     default:
          url:    http://example.com
          user:   api
          key:    $ome35ecre7Ke$
     fallback:
          url:    http://back.example.com
          user:   fallback_api
          key:    $ome35ecre7Ke$
->arrayNode('connections')
Prototype variations
    ->useAttributeAsKey('name')
    ->prototype('array')
        ->children()
              ->scalarNode('url')
                  ->isRequired()
              ->end()
              ->scalarNode('user')->end()
              ->scalarNode('key')->end()
        ->end() validation
        Prototype
    ->end()
    ->requiresAtLeastOneElement()
->end()
array (
    'connections' => array (
        'default' => array (
            'url' => '...',
            'user' => 'api',
            'key' => '$ome35ecre7Ke$'
        ),
        'fallback' => array (
            'url' => '...',
            'user' => 'fallback_api',
            'key' => '$ome35ecre7Ke$'
        )
));
Using Configuration




     http://www.flickr.com/photos/victornuno/222145881/
src/YourBundle/DependencyInjection/YourBundleExtension.php

public function load(/*...*/)
{               Load services
     if (true === $config['enabled']) {
          $loader->load('services.xml');
     }
}
src/YourBundle/DependencyInjection/YourBundleExtension.php

public function load(/*...*/)
{
    if (true === $config['enabled']) {
        $loader->load('services.xml');
    }            Split services

     if (true === $config['add_extras']) {
         $loader->load('extras.xml');
     }
}
Manipulate DIC
src/YourBundle/DependencyInjection/YourBundleExtension.php

$container->setParameter(
    'your_bundle.timeout',
    $config['timeout']
);
src/YourBundle/Controller/YourController.php

public function someAction(/*...*/)
{
    $timeout = $container->getParameter(
        'global.timeout');
}
sfConfig::get('global.timeout');



           Good old symfony times…
Configure Services

     Not global options
src/YourBundle/DependencyInjection/YourBundleExtension.php

$container->setParameter(
    'your_bundle.timeout',
    $config['timeout']
);
src/YourBundle/Resources/config/services.xml
<?xml version="1.0" ?>       You config option
<container>
    <parameters>
        <parameter key="your_service_x.timeout"></parameter>
    </parameters>

    <services>
        <service id="your_service_x">
             <argument>%your_service_x.timeout%</argument>
        </service>
    </services>
</container>
src/YourBundle/DependencyInjection/YourBundleExtension.php

$container->setParameter(
    'your_service_x.timeout',
    $config['timeout']
);
Let‘s recap




http://www.flickr.com/photos/tine72/5464869042/
Configuration
needs structure
Configuration
needs validation
Configuration
needs conversion
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012
http://joind.in/7060

More Related Content

Things Your Mother Didn't Tell You About Bundle Configurations - Symfony Live London 2012