Skip to content

[Cookbook][Configuration] add configuration cookbook handlig parameters in Configurator class #3420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cookbook/bundles/extension.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ The second method has several specific advantages:
supported configuration settings for which backward compatibility will
be maintained.

.. seealso::

For other usages of the parameter ``%`` syntax see
:doc:`Using Configuration Parameters </cookbook/using_configuration_parameters>`.

.. index::
single: Bundle; Extension
single: DependencyInjection; Extension
Expand Down
2 changes: 1 addition & 1 deletion cookbook/configuration/apache_router.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Apache Router
single: Apache Router

How to use the Apache Router
============================
Expand Down
2 changes: 1 addition & 1 deletion cookbook/configuration/environments.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Environments
single: Environments

How to Master and Create new Environments
=========================================
Expand Down
2 changes: 1 addition & 1 deletion cookbook/configuration/external_parameters.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Environments; External parameters
single: Environments; External parameters

How to Set External Parameters in the Service Container
=======================================================
Expand Down
4 changes: 2 additions & 2 deletions cookbook/configuration/front_controllers_and_kernel.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. index::
single: How front controller, ``AppKernel`` and environments
work together
single: How front controller, ``AppKernel`` and environments
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How the front controller [...]

work together

Understanding how the Front Controller, Kernel and Environments work together
=============================================================================
Expand Down
1 change: 1 addition & 0 deletions cookbook/configuration/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Configuration

environments
override_dir_structure
using_configuration_parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're missing the addition in cookbook/map.rst.inc

front_controllers_and_kernel
external_parameters
pdo_session_storage
Expand Down
2 changes: 1 addition & 1 deletion cookbook/configuration/override_dir_structure.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Override Symfony
single: Override Symfony

How to override Symfony's Default Directory Structure
=====================================================
Expand Down
2 changes: 1 addition & 1 deletion cookbook/configuration/pdo_session_storage.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Session; Database Storage
single: Session; Database Storage

How to use PdoSessionHandler to store Sessions in the Database
==============================================================
Expand Down
217 changes: 217 additions & 0 deletions cookbook/configuration/using_configuration_parameters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
.. index::
single: Using Configuration Parameters

Using Configuration Parameters
==============================

Parameters, such as ``kernel.root_dir`` (pointing to a path) or ``kernel.debug``
(whether debug mode is enabled), are common in configuration. By wrapping the
parameter name within 2 ``%`` characters, you indicate that this value should
be replaced by the value of the parameter. When using Symfony, you can have
parameters defined in a bundle and used only in that bundle and also parameters
defined in a bundle and used in another. Usually they would have a name
like ``demo_bundle.service_doer.local_parameter`` making explicit where this
parameter comes from. If the parameter is global then it may not have a
namespace, e.g. ``%some_global_option_here%``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're giving a bit too much information here too early. I would stop this paragraph after replaced by the value of the parameter. If we want to tell people about the standards of naming parameters, we should just name them correctly in the examples below, and maybe add a note after a code block that mentions the standard. I fear that without code, the meaning is lost here.


Basic Usage
-----------

You can use parameters inside the ``parameters.yml`` file:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure (I'd like to hear what others think) about showing how to use parameters here, because it's documented well in the components (and mentioned lightly throughout the book) - see http://symfony.com/doc/current/components/dependency_injection/parameters.html#parameters-in-configuration-files. Perhaps just a link to that section?


.. code-block:: yaml

# app/config/parameters.yml
parameters:
payment_test_mode: "%kernel.root_dir%"

Inside ``config.yml`` and other configuration files building larger
strings:

.. configuration-block::

.. code-block:: yaml

# app/config/config.yml
my_bundle:
local:
directory: "%kernel.root_dir%/../web/media/image"

.. code-block:: xml

<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
my-bundle="http://example.org/schema/dic/my_bundle">
<my-bundle:config>
<my-bundle:local directory="%kernel.root_dir%/../web/media/image" />
</my-bundle:config>
</container>

.. code-block:: php

$container->loadFromExtension('my_bundle', array(
'local' => array(
'directory' => '%kernel.root_dir%/../web/media/image',
),
));

For more information on how parameters are used in Symfony please see
:ref:`parameters <book-service-container-parameters>`.

Besides these usages above you can use this syntax in routing files and handle
parameters in special cases as discussed below.

Using Parameters in your Bundle Configuration
---------------------------------------------

If for instance, there is a use case in which you want to use the
``%kernel.debug%`` debug mode parameter to make your bundle adapt its
configuration depending on this. For this case you cannot use
the syntax directly and expect this to work. The configuration handling
will just treat this ``%kernel.debug%`` as a string. Consider
this example with the AcmeDemoBundle::

// Inside Configuration class
$rootNode
->children()
->booleanNode('logging')->defaultValue('%kernel.debug%')->end()
// ...
->end()
;

// Inside the Extension class
$config = $this->processConfiguration($configuration, $configs);
var_dump($config['logging']);

Now, examine the results to see this closely:

.. configuration-block::

.. code-block:: yaml

my_bundle:
logging: true
# true, as expected

my_bundle:
logging: %kernel.debug%
# true/false (depends on 2nd parameter of AppKernel),
# as expected, because %kernel.debug% inside configuration
# gets evaluated before being passed to the extension

my_bundle: ~
# passes the string "%kernel.debug%".
# Which is always considered as true.
# The Configurator does not know anything about
# "%kernel.debug%" being a parameter.

.. code-block:: xml

<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
my-bundle="http://example.org/schema/dic/my_bundle">

<my-bundle:config logging="true" />
<!-- true, as expected -->

<my-bundle:config logging="%kernel.debug%" />
<!-- true/false (depends on 2nd parameter of AppKernel),
as expected, because %kernel.debug% inside configuration
gets evaluated before being passed to the extension -->

<my-bundle:config />
<!-- passes the string "%kernel.debug%".
Which is always considered as true.
The Configurator does not know anything about
"%kernel.debug%" being a parameter. -->
</container>

.. code-block:: php

$container->loadFromExtension('my_bundle', array(
'logging' => true,
// true, as expected
)
);

$container->loadFromExtension('my_bundle', array(
'logging' => "%kernel.debug%",
// true/false (depends on 2nd parameter of AppKernel),
// as expected, because %kernel.debug% inside configuration
// gets evaluated before being passed to the extension
)
);

$container->loadFromExtension('my_bundle');
// passes the string "%kernel.debug%".
// Which is always considered as true.
// The Configurator does not know anything about
// "%kernel.debug%" being a parameter.

In order to support this use case, the ``Configuration`` class has to
be injected with this parameter via the extension as follows::

namespace Acme\DemoBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
private $debug;

public function __construct($debug)
{
$this->debug = (Boolean) $debug;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it works, PHP documentation uses lowercased boolean: http://www.php.net/manual/en/language.types.boolean.php

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but using Boolean is a crazy Symfony Coding standard...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about that ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wouterj there is a ticket about this in which all doubt is resolved, is buried in s/s repo but I can't recall now. This argument seems to be coming back every now and then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but using Boolean is a crazy Symfony Coding standard...

Really? Weird...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://en.wikipedia.org/wiki/George_Boole

It's always fun when it comes up on an issue somewhere :)

}

public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_demo');

$rootNode
->children()
// ...
->booleanNode('logging')->defaultValue($this->debug)->end()
// ...
->end()
;

return $treeBuilder;
}
}

And set it in the constructor of ``Configuration`` via the ``Extension`` class::

namespace Acme\DemoBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\FileLocator;

class AcmeDemoExtension extends Extension
{
// ...

public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($container->getParameter('kernel.debug'));
}
}

.. sidebar:: Setting the Default in the Extension

There are some instances of ``%kernel.debug%`` usage within a ``Configurator``
class in TwigBundle and AsseticBundle, however this is because the default
parameter value is set by the Extension class. For example in AsseticBundle,
you can find::

$container->setParameter('assetic.debug', $config['debug']);

The string ``%kernel.debug%`` passed here as an argument handles the
interpreting job to the container which in turn does the evaluation.
Both ways accomplish similar goals. AsseticBundle will not use
anymore ``%kernel.debug%`` but rather the new ``%assetic.debug%`` parameter.
2 changes: 1 addition & 1 deletion cookbook/configuration/web_server_configuration.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. index::
single: Web Server
single: Web Server

Configuring a web server
========================
Expand Down
5 changes: 5 additions & 0 deletions cookbook/routing/service_container_parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,8 @@ path):
However, as the ``%`` characters included in any URL are automatically encoded,
the resulting URL of this example would be ``/score-50%25`` (``%25`` is the
result of encoding the ``%`` character).

.. seealso::

For other usages of the parameter ``%`` syntax see
:doc:`Using Configuration Parameters </cookbook/using_configuration_parameters>`.