From 1103e00ced05ce83a59c101993c4a3329289678a Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 16 Jul 2015 14:25:05 +0900 Subject: [PATCH 01/15] Fix mock $matcher --- create_framework/unit-testing.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/create_framework/unit-testing.rst b/create_framework/unit-testing.rst index de26e202570..014e04468b6 100644 --- a/create_framework/unit-testing.rst +++ b/create_framework/unit-testing.rst @@ -157,6 +157,11 @@ Response:: } ))) ; + $matcher + ->expects($this->once()) + ->method('getContext') + ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext'))) + ; $resolver = new ControllerResolver(); $framework = new Framework($matcher, $resolver); From 01cdbf5a6e282433c25c8e7bbe5c996f447c4fcc Mon Sep 17 00:00:00 2001 From: WouterJ Date: Tue, 21 Jul 2015 18:09:49 +0200 Subject: [PATCH 02/15] Reviewed some component chapters --- components/class_loader/class_loader.rst | 34 ++-- .../class_loader/class_map_generator.rst | 27 +-- .../class_loader/debug_class_loader.rst | 8 +- components/class_loader/introduction.rst | 8 +- components/class_loader/map_class_loader.rst | 20 +- components/config/caching.rst | 39 ++-- components/config/definition.rst | 111 ++++++----- components/config/introduction.rst | 3 +- components/config/resources.rst | 50 ++--- .../_imports-parameters-note.rst.inc | 6 +- components/dependency_injection/advanced.rst | 16 +- .../dependency_injection/compilation.rst | 181 ++++++++++-------- .../dependency_injection/configurators.rst | 49 ++--- .../dependency_injection/definitions.rst | 16 +- components/dependency_injection/factories.rst | 30 +-- components/dependency_injection/index.rst | 2 +- .../dependency_injection/introduction.rst | 19 +- .../dependency_injection/lazy_services.rst | 25 +-- .../dependency_injection/parameters.rst | 46 ++--- .../dependency_injection/parentservices.rst | 64 ++++--- .../synthetic_services.rst | 12 +- components/dependency_injection/tags.rst | 43 ++--- components/dependency_injection/types.rst | 37 ++-- components/dependency_injection/workflow.rst | 61 +++--- 24 files changed, 479 insertions(+), 428 deletions(-) diff --git a/components/class_loader/class_loader.rst b/components/class_loader/class_loader.rst index c852e91fcb6..26be9882909 100644 --- a/components/class_loader/class_loader.rst +++ b/components/class_loader/class_loader.rst @@ -7,14 +7,14 @@ The PSR-0 Class Loader .. versionadded:: 2.1 The ``ClassLoader`` class was introduced in Symfony 2.1. -If your classes and third-party libraries follow the `PSR-0`_ standard, you -can use the :class:`Symfony\\Component\\ClassLoader\\ClassLoader` class to -load all of your project's classes. +If your classes and third-party libraries follow the `PSR-0`_ standard, +you can use the :class:`Symfony\\Component\\ClassLoader\\ClassLoader` class +to load all of your project's classes. .. tip:: - You can use both the ``ApcClassLoader`` and the ``XcacheClassLoader`` to - :doc:`cache ` a ``ClassLoader`` + You can use both the ``ApcClassLoader`` and the ``XcacheClassLoader`` + to :doc:`cache ` a ``ClassLoader`` instance or the ``DebugClassLoader`` to :doc:`debug ` it. @@ -39,12 +39,12 @@ is straightforward:: .. note:: - The autoloader is automatically registered in a Symfony application (see - ``app/autoload.php``). + The autoloader is automatically registered in a Symfony application + (see ``app/autoload.php``). -Use the :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefix` or -:method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefixes` methods to -register your classes:: +Use the :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefix` +or :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefixes` methods +to register your classes:: // register a single namespaces $loader->addPrefix('Symfony', __DIR__.'/vendor/symfony/symfony/src'); @@ -63,9 +63,9 @@ register your classes:: 'Twig_' => __DIR__.'/vendor/twig/twig/lib', )); -Classes from a sub-namespace or a sub-hierarchy of `PEAR`_ classes can be looked -for in a location list to ease the vendoring of a sub-set of classes for large -projects:: +Classes from a sub-namespace or a sub-hierarchy of `PEAR`_ classes can be +looked for in a location list to ease the vendoring of a sub-set of classes +for large projects:: $loader->addPrefixes(array( 'Doctrine\\Common' => __DIR__.'/vendor/doctrine/common/lib', @@ -75,10 +75,10 @@ projects:: )); In this example, if you try to use a class in the ``Doctrine\Common`` namespace -or one of its children, the autoloader will first look for the class under the -``doctrine-common`` directory. If not found, it will then fallback to the default -``Doctrine`` directory (the last one configured) before giving up. The order -of the prefix registrations is significant in this case. +or one of its children, the autoloader will first look for the class under +the ``doctrine-common`` directory. If not found, it will then fallback to +the default ``Doctrine`` directory (the last one configured) before giving +up. The order of the prefix registrations is significant in this case. .. _PEAR: http://pear.php.net/manual/en/standards.naming.php .. _PSR-0: http://www.php-fig.org/psr/psr-0/ diff --git a/components/class_loader/class_map_generator.rst b/components/class_loader/class_map_generator.rst index 772bd9ab693..da1a9c73ab4 100644 --- a/components/class_loader/class_map_generator.rst +++ b/components/class_loader/class_map_generator.rst @@ -5,10 +5,11 @@ The Class Map Generator ======================= -Loading a class usually is an easy task given the `PSR-0`_ and `PSR-4`_ standards. -Thanks to the Symfony ClassLoader component or the autoloading mechanism provided -by Composer, you don't have to map your class names to actual PHP files manually. -Nowadays, PHP libraries usually come with autoloading support through Composer. +Loading a class usually is an easy task given the `PSR-0`_ and `PSR-4`_ +standards. Thanks to the Symfony ClassLoader component or the autoloading +mechanism provided by Composer, you don't have to map your class names to +actual PHP files manually. Nowadays, PHP libraries usually come with autoloading +support through Composer. But from time to time you may have to use a third-party library that comes without any autoloading support and therefore forces you to load each class @@ -44,16 +45,17 @@ it possible to create a map of class names to files. Generating a Class Map ---------------------- -To generate the class map, simply pass the root directory of your class files -to the :method:`Symfony\\Component\\ClassLoader\\ClassMapGenerator::createMap` +To generate the class map, simply pass the root directory of your class +files to the +:method:`Symfony\\Component\\ClassLoader\\ClassMapGenerator::createMap` method:: use Symfony\Component\ClassLoader\ClassMapGenerator; var_dump(ClassMapGenerator::createMap(__DIR__.'/library')); -Given the files and class from the table above, you should see an output like -this: +Given the files and class from the table above, you should see an output +like this: .. code-block:: text @@ -87,8 +89,9 @@ file in the same directory with the following contents:: 'Acme\\Bar' => '/var/www/library/bar/Foo.php', ); -Instead of loading each file manually, you'll only have to register the generated -class map with, for example, the :class:`Symfony\\Component\\ClassLoader\\MapClassLoader`:: +Instead of loading each file manually, you'll only have to register the +generated class map with, for example, the +:class:`Symfony\\Component\\ClassLoader\\MapClassLoader`:: use Symfony\Component\ClassLoader\MapClassLoader; @@ -110,8 +113,8 @@ class map with, for example, the :class:`Symfony\\Component\\ClassLoader\\MapCla component. Besides dumping the class map for one directory, you can also pass an array -of directories for which to generate the class map (the result actually is -the same as in the example above):: +of directories for which to generate the class map (the result actually +is the same as in the example above):: use Symfony\Component\ClassLoader\ClassMapGenerator; diff --git a/components/class_loader/debug_class_loader.rst b/components/class_loader/debug_class_loader.rst index cc99762b5cc..1f08128749f 100644 --- a/components/class_loader/debug_class_loader.rst +++ b/components/class_loader/debug_class_loader.rst @@ -7,10 +7,10 @@ Debugging a Class Loader .. versionadded:: 2.1 The ``DebugClassLoader`` class was introduced in Symfony 2.1. -The :class:`Symfony\\Component\\ClassLoader\\DebugClassLoader` attempts to -throw more helpful exceptions when a class isn't found by the registered -autoloaders. All autoloaders that implement a ``findFile()`` method are replaced -with a ``DebugClassLoader`` wrapper. +The :class:`Symfony\\Component\\ClassLoader\\DebugClassLoader` attempts +to throw more helpful exceptions when a class isn't found by the registered +autoloaders. All autoloaders that implement a ``findFile()`` method are +replaced with a ``DebugClassLoader`` wrapper. Using the ``DebugClassLoader`` is as easy as calling its static :method:`Symfony\\Component\\ClassLoader\\DebugClassLoader::enable` method:: diff --git a/components/class_loader/introduction.rst b/components/class_loader/introduction.rst index 9ba98db987d..6bc7a6c70c6 100644 --- a/components/class_loader/introduction.rst +++ b/components/class_loader/introduction.rst @@ -11,11 +11,12 @@ Usage ----- Whenever you reference a class that has not been required or included yet, -PHP uses the `autoloading mechanism`_ to delegate the loading of a file defining -the class. Symfony provides two autoloaders, which are able to load your classes: +PHP uses the `autoloading mechanism`_ to delegate the loading of a file +defining the class. Symfony provides two autoloaders, which are able to +load your classes: * :doc:`/components/class_loader/class_loader`: loads classes that follow - the `PSR-0` class naming standard; + the `PSR-0`_ class naming standard; * :doc:`/components/class_loader/map_class_loader`: loads classes using a static map from class name to file path. @@ -38,5 +39,6 @@ You can install the component in 2 different ways: .. include:: /components/require_autoload.rst.inc +.. _PSR-0: http://www.php-fig.org/psr/psr-0/ .. _`autoloading mechanism`: http://php.net/manual/en/language.oop5.autoload.php .. _Packagist: https://packagist.org/packages/symfony/class-loader diff --git a/components/class_loader/map_class_loader.rst b/components/class_loader/map_class_loader.rst index 2705fa24282..f9bd70abfa4 100644 --- a/components/class_loader/map_class_loader.rst +++ b/components/class_loader/map_class_loader.rst @@ -4,20 +4,22 @@ MapClassLoader ============== -The :class:`Symfony\\Component\\ClassLoader\\MapClassLoader` allows you to -autoload files via a static map from classes to files. This is useful if you -use third-party libraries which don't follow the `PSR-0`_ standards and so -can't use the :doc:`PSR-0 class loader `. +The :class:`Symfony\\Component\\ClassLoader\\MapClassLoader` allows you +to autoload files via a static map from classes to files. This is useful +if you use third-party libraries which don't follow the `PSR-0`_ standards +and so can't use the +:doc:`PSR-0 class loader `. -The ``MapClassLoader`` can be used along with the :doc:`PSR-0 class loader ` -by configuring and calling the ``register()`` method on both. +The ``MapClassLoader`` can be used along with the +:doc:`PSR-0 class loader ` by +configuring and calling the ``register()`` method on both. .. note:: The default behavior is to append the ``MapClassLoader`` on the autoload - stack. If you want to use it as the first autoloader, pass ``true`` when - calling the ``register()`` method. Your class loader will then be prepended - on the autoload stack. + stack. If you want to use it as the first autoloader, pass ``true`` + when calling the ``register()`` method. Your class loader will then + be prepended on the autoload stack. Usage ----- diff --git a/components/config/caching.rst b/components/config/caching.rst index 4bb43558c64..4984a59d755 100644 --- a/components/config/caching.rst +++ b/components/config/caching.rst @@ -1,26 +1,27 @@ .. index:: single: Config; Caching based on resources -Caching Based on Resources +Caching based on Resources ========================== -When all configuration resources are loaded, you may want to process the configuration -values and combine them all in one file. This file acts like a cache. Its -contents don’t have to be regenerated every time the application runs – only -when the configuration resources are modified. +When all configuration resources are loaded, you may want to process the +configuration values and combine them all in one file. This file acts +like a cache. Its contents don’t have to be regenerated every time the +application runs – only when the configuration resources are modified. For example, the Symfony Routing component allows you to load all routes, and then dump a URL matcher or a URL generator based on these routes. In -this case, when one of the resources is modified (and you are working in a -development environment), the generated file should be invalidated and regenerated. -This can be accomplished by making use of the :class:`Symfony\\Component\\Config\\ConfigCache` -class. - -The example below shows you how to collect resources, then generate some code -based on the resources that were loaded, and write this code to the cache. The -cache also receives the collection of resources that were used for generating -the code. By looking at the "last modified" timestamp of these resources, -the cache can tell if it is still fresh or that its contents should be regenerated:: +this case, when one of the resources is modified (and you are working +in a development environment), the generated file should be invalidated +and regenerated. This can be accomplished by making use of the +:class:`Symfony\\Component\\Config\\ConfigCache` class. + +The example below shows you how to collect resources, then generate some +code based on the resources that were loaded and write this code to the +cache. The cache also receives the collection of resources that were used +for generating the code. By looking at the "last modified" timestamp of +these resources, the cache can tell if it is still fresh or that its contents +should be regenerated:: use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Resource\FileResource; @@ -52,8 +53,8 @@ the cache can tell if it is still fresh or that its contents should be regenerat // you may want to require the cached code: require $cachePath; -In debug mode, a ``.meta`` file will be created in the same directory as the -cache file itself. This ``.meta`` file contains the serialized resources, -whose timestamps are used to determine if the cache is still fresh. When not -in debug mode, the cache is considered to be "fresh" as soon as it exists, +In debug mode, a ``.meta`` file will be created in the same directory as +the cache file itself. This ``.meta`` file contains the serialized resources, +whose timestamps are used to determine if the cache is still fresh. When +not in debug mode, the cache is considered to be "fresh" as soon as it exists, and therefore no ``.meta`` file will be generated. diff --git a/components/config/definition.rst b/components/config/definition.rst index b79ad3853a2..b13be69b8b1 100644 --- a/components/config/definition.rst +++ b/components/config/definition.rst @@ -8,12 +8,13 @@ Validating Configuration Values ------------------------------- After loading configuration values from all kinds of resources, the values -and their structure can be validated using the "Definition" part of the Config -Component. Configuration values are usually expected to show some kind of -hierarchy. Also, values should be of a certain type, be restricted in number -or be one of a given set of values. For example, the following configuration -(in YAML) shows a clear hierarchy and some validation rules that should be -applied to it (like: "the value for ``auto_connect`` must be a boolean value"): +and their structure can be validated using the "Definition" part of the +Config Component. Configuration values are usually expected to show some +kind of hierarchy. Also, values should be of a certain type, be restricted +in number or be one of a given set of values. For example, the following +configuration (in YAML) shows a clear hierarchy and some validation rules +that should be applied to it (like: "the value for ``auto_connect`` must +be a boolean value"): .. code-block:: yaml @@ -44,9 +45,9 @@ Defining a Hierarchy of Configuration Values Using the TreeBuilder All the rules concerning configuration values can be defined using the :class:`Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder`. -A :class:`Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder` instance -should be returned from a custom ``Configuration`` class which implements the -:class:`Symfony\\Component\\Config\\Definition\\ConfigurationInterface`:: +A :class:`Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder` +instance should be returned from a custom ``Configuration`` class which +implements the :class:`Symfony\\Component\\Config\\Definition\\ConfigurationInterface`:: namespace Acme\DatabaseConfiguration; @@ -89,7 +90,8 @@ reflect the real structure of the configuration values:: The root node itself is an array node, and has children, like the boolean node ``auto_connect`` and the scalar node ``default_connection``. In general: -after defining a node, a call to ``end()`` takes you one step up in the hierarchy. +after defining a node, a call to ``end()`` takes you one step up in the +hierarchy. Node Type ~~~~~~~~~ @@ -97,13 +99,15 @@ Node Type It is possible to validate the type of a provided value by using the appropriate node definition. Node types are available for: -* scalar (generic type that includes booleans, strings, integers, floats and ``null``) +* scalar (generic type that includes booleans, strings, integers, floats + and ``null``) * boolean * scalar * boolean * integer (new in 2.2) * float (new in 2.2) -* enum (new in 2.1) (similar to scalar, but it only allows a finite set of values) +* enum (new in 2.1) (similar to scalar, but it only allows a finite set + of values) * array * variable (no validation) @@ -201,12 +205,14 @@ Array Node Options Before defining the children of an array node, you can provide options like: ``useAttributeAsKey()`` - Provide the name of a child node, whose value should be used as the key in the resulting array. + Provide the name of a child node, whose value should be used as the + key in the resulting array. ``requiresAtLeastOneElement()`` - There should be at least one element in the array (works only when ``isRequired()`` is also - called). + There should be at least one element in the array (works only when + ``isRequired()`` is also called). ``addDefaultsIfNotSet()`` - If any child nodes have default values, use them if explicit values haven't been provided. + If any child nodes have default values, use them if explicit values + haven't been provided. An example of this:: @@ -233,12 +239,12 @@ In YAML, the configuration might look like this: parameters: param1: { value: param1val } -In XML, each ``parameters`` node would have a ``name`` attribute (along with -``value``), which would be removed and used as the key for that element in -the final array. The ``useAttributeAsKey`` is useful for normalizing how -arrays are specified between different formats like XML and YAML. +In XML, each ``parameters`` node would have a ``name`` attribute (along +with ``value``), which would be removed and used as the key for that element +in the final array. The ``useAttributeAsKey`` is useful for normalizing +how arrays are specified between different formats like XML and YAML. -Default and required Values +Default and Required Values --------------------------- For all node types, it is possible to define default values and replacement @@ -254,7 +260,8 @@ has a certain value: ``default*()`` (``null``, ``true``, ``false``), shortcut for ``defaultValue()`` ``treat*Like()`` - (``null``, ``true``, ``false``), provide a replacement value in case the value is ``*.`` + (``null``, ``true``, ``false``), provide a replacement value in case + the value is ``*.`` .. code-block:: php @@ -296,8 +303,8 @@ All options can be documented using the :method:`Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::info` method. -The info will be printed as a comment when dumping the configuration tree with -the ``config:dump`` command. +The info will be printed as a comment when dumping the configuration tree +with the ``config:dump`` command. Optional Sections ----------------- @@ -308,8 +315,10 @@ Optional Sections If you have entire sections which are optional and can be enabled/disabled, you can take advantage of the shortcut -:method:`Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition::canBeEnabled` and -:method:`Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition::canBeDisabled` methods:: +:method:`Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition::canBeEnabled` +and +:method:`Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition::canBeDisabled` +methods:: $arrayNode ->canBeEnabled() @@ -335,21 +344,22 @@ Merging Options Extra options concerning the merge process may be provided. For arrays: ``performNoDeepMerging()`` - When the value is also defined in a second configuration array, don’t + When the value is also defined in a second configuration array, don't try to merge an array, but overwrite it entirely For all nodes: ``cannotBeOverwritten()`` - don’t let other configuration arrays overwrite an existing value for this node + don't let other configuration arrays overwrite an existing value for + this node Appending Sections ------------------ If you have a complex configuration to validate then the tree can grow to -be large and you may want to split it up into sections. You can do this by -making a section a separate node and then appending it into the main tree -with ``append()``:: +be large and you may want to split it up into sections. You can do this +by making a section a separate node and then appending it into the main +tree with ``append()``:: public function getConfigTreeBuilder() { @@ -413,9 +423,9 @@ and finally the tree is used to validate the resulting array. The normalization process is used to remove some of the differences that result from different configuration formats, mainly the differences between YAML and XML. -The separator used in keys is typically ``_`` in YAML and ``-`` in XML. For -example, ``auto_connect`` in YAML and ``auto-connect`` in XML. -The normalization would make both of these ``auto_connect``. +The separator used in keys is typically ``_`` in YAML and ``-`` in XML. +For example, ``auto_connect`` in YAML and ``auto-connect`` in XML. The +normalization would make both of these ``auto_connect``. .. caution:: @@ -440,8 +450,8 @@ and in XML: This difference can be removed in normalization by pluralizing the key used -in XML. You can specify that you want a key to be pluralized in this way with -``fixXmlConfig()``:: +in XML. You can specify that you want a key to be pluralized in this way +with ``fixXmlConfig()``:: $rootNode ->fixXmlConfig('extension') @@ -483,9 +493,9 @@ in the second making it difficult to validate. You can ensure it is always an array with ``fixXmlConfig``. You can further control the normalization process if you need to. For example, -you may want to allow a string to be set and used as a particular key or several -keys to be set explicitly. So that, if everything apart from ``name`` is optional -in this config: +you may want to allow a string to be set and used as a particular key or +several keys to be set explicitly. So that, if everything apart from ``name`` +is optional in this config: .. code-block:: yaml @@ -543,8 +553,8 @@ The builder is used for adding advanced validation rules to node definitions, li ->end() ; -A validation rule always has an "if" part. You can specify this part in the -following ways: +A validation rule always has an "if" part. You can specify this part in +the following ways: - ``ifTrue()`` - ``ifString()`` @@ -568,19 +578,24 @@ of the node's original value. Processing Configuration Values ------------------------------- -The :class:`Symfony\\Component\\Config\\Definition\\Processor` uses the tree -as it was built using the :class:`Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder` -to process multiple arrays of configuration values that should be merged. -If any value is not of the expected type, is mandatory and yet undefined, -or could not be validated in some other way, an exception will be thrown. +The :class:`Symfony\\Component\\Config\\Definition\\Processor` uses the +tree as it was built using the +:class:`Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder` to +process multiple arrays of configuration values that should be merged. If +any value is not of the expected type, is mandatory and yet undefined, or +could not be validated in some other way, an exception will be thrown. Otherwise the result is a clean array of configuration values:: use Symfony\Component\Yaml\Yaml; use Symfony\Component\Config\Definition\Processor; use Acme\DatabaseConfiguration; - $config1 = Yaml::parse(file_get_contents(__DIR__.'/src/Matthias/config/config.yml')); - $config2 = Yaml::parse(file_get_contents(__DIR__.'/src/Matthias/config/config_extra.yml')); + $config1 = Yaml::parse( + file_get_contents(__DIR__.'/src/Matthias/config/config.yml') + ); + $config2 = Yaml::parse( + file_get_contents(__DIR__.'/src/Matthias/config/config_extra.yml') + ); $configs = array($config1, $config2); diff --git a/components/config/introduction.rst b/components/config/introduction.rst index 70f74c2072f..154cca424b8 100644 --- a/components/config/introduction.rst +++ b/components/config/introduction.rst @@ -14,7 +14,8 @@ Installation You can install the component in 2 different ways: -* :doc:`Install it via Composer ` (``symfony/config`` on `Packagist`_); +* :doc:`Install it via Composer ` (``symfony/config`` + on `Packagist`_); * Use the official Git repository (https://github.com/symfony/Config). .. include:: /components/require_autoload.rst.inc diff --git a/components/config/resources.rst b/components/config/resources.rst index 1a5fba23c2b..a7905e0747d 100644 --- a/components/config/resources.rst +++ b/components/config/resources.rst @@ -14,8 +14,9 @@ Loading Resources Locating Resources ------------------ -Loading the configuration normally starts with a search for resources – in -most cases: files. This can be done with the :class:`Symfony\\Component\\Config\\FileLocator`:: +Loading the configuration normally starts with a search for resources – +in most cases: files. This can be done with the +:class:`Symfony\\Component\\Config\\FileLocator`:: use Symfony\Component\Config\FileLocator; @@ -24,20 +25,21 @@ most cases: files. This can be done with the :class:`Symfony\\Component\\Config\ $locator = new FileLocator($configDirectories); $yamlUserFiles = $locator->locate('users.yml', null, false); -The locator receives a collection of locations where it should look for files. -The first argument of ``locate()`` is the name of the file to look for. The -second argument may be the current path and when supplied, the locator will -look in this directory first. The third argument indicates whether or not the -locator should return the first file it has found, or an array containing -all matches. +The locator receives a collection of locations where it should look for +files. The first argument of ``locate()`` is the name of the file to look +for. The second argument may be the current path and when supplied, the +locator will look in this directory first. The third argument indicates +whether or not the locator should return the first file it has found or +an array containing all matches. Resource Loaders ---------------- -For each type of resource (YAML, XML, annotation, etc.) a loader must be defined. -Each loader should implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` -or extend the abstract :class:`Symfony\\Component\\Config\\Loader\\FileLoader` -class, which allows for recursively importing other resources:: +For each type of resource (YAML, XML, annotation, etc.) a loader must be +defined. Each loader should implement +:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` or extend the +abstract :class:`Symfony\\Component\\Config\\Loader\\FileLoader` class, +which allows for recursively importing other resources:: use Symfony\Component\Config\Loader\FileLoader; use Symfony\Component\Yaml\Yaml; @@ -64,19 +66,21 @@ class, which allows for recursively importing other resources:: } } -Finding the right Loader +Finding the Right Loader ------------------------ -The :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` receives as -its first constructor argument a collection of loaders. When a resource (for -instance an XML file) should be loaded, it loops through this collection -of loaders and returns the loader which supports this particular resource type. - -The :class:`Symfony\\Component\\Config\\Loader\\DelegatingLoader` makes use -of the :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver`. When -it is asked to load a resource, it delegates this question to the -:class:`Symfony\\Component\\Config\\Loader\\LoaderResolver`. In case the resolver -has found a suitable loader, this loader will be asked to load the resource:: +The :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` receives +as its first constructor argument a collection of loaders. When a resource +(for instance an XML file) should be loaded, it loops through this collection +of loaders and returns the loader which supports this particular resource +type. + +The :class:`Symfony\\Component\\Config\\Loader\\DelegatingLoader` makes +use of the :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver`. +When it is asked to load a resource, it delegates this question to the +:class:`Symfony\\Component\\Config\\Loader\\LoaderResolver`. In case the +resolver has found a suitable loader, this loader will be asked to load +the resource:: use Symfony\Component\Config\Loader\LoaderResolver; use Symfony\Component\Config\Loader\DelegatingLoader; diff --git a/components/dependency_injection/_imports-parameters-note.rst.inc b/components/dependency_injection/_imports-parameters-note.rst.inc index 2f35ec5bdef..4fd8b4005e0 100644 --- a/components/dependency_injection/_imports-parameters-note.rst.inc +++ b/components/dependency_injection/_imports-parameters-note.rst.inc @@ -1,8 +1,8 @@ .. note:: - Due to the way in which parameters are resolved, you cannot use them to - build paths in imports dynamically. This means that something like the - following doesn't work: + Due to the way in which parameters are resolved, you cannot use them + to build paths in imports dynamically. This means that something like + the following doesn't work: .. configuration-block:: diff --git a/components/dependency_injection/advanced.rst b/components/dependency_injection/advanced.rst index 5e9b09d5ae0..93372c8723e 100644 --- a/components/dependency_injection/advanced.rst +++ b/components/dependency_injection/advanced.rst @@ -1,19 +1,19 @@ .. index:: - single: DependencyInjection; Advanced configuration + single: DependencyInjection; Advanced configuration Advanced Container Configuration ================================ .. _container-private-services: -Marking Services as public / private +Marking Services as Public / Private ------------------------------------ When defining services, you'll usually want to be able to access these definitions -within your application code. These services are called ``public``. For example, -the ``doctrine`` service registered with the container when using the DoctrineBundle -is a public service. This means that you can fetch it from the container -using the ``get()`` method:: +within your application code. These services are called ``public``. For +example, the ``doctrine`` service registered with the container when using +the DoctrineBundle is a public service. This means that you can fetch it +from the container using the ``get()`` method:: $doctrine = $container->get('doctrine'); @@ -68,8 +68,8 @@ This *may or may not work*, depending on if the service could be inlined. Simply said: A service can be marked as private if you do not want to access it directly from your code. -However, if a service has been marked as private, you can still alias it (see -below) to access this service (via the alias). +However, if a service has been marked as private, you can still alias it +(see below) to access this service (via the alias). .. note:: diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index e9b9939bff8..34552dafe97 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -1,5 +1,5 @@ .. index:: - single: DependencyInjection; Compilation + single: DependencyInjection; Compilation Compiling the Container ======================= @@ -8,8 +8,8 @@ The service container can be compiled for various reasons. These reasons include checking for any potential issues such as circular references and making the container more efficient by resolving parameters and removing unused services. Also, certain features - like using -:doc:`parent services ` - -require the container to be compiled. +:doc:`parent services ` +- require the container to be compiled. It is compiled by running:: @@ -17,12 +17,13 @@ It is compiled by running:: The compile method uses *Compiler Passes* for the compilation. The DependencyInjection component comes with several passes which are automatically registered for -compilation. For example the :class:`Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass` -checks for various potential issues with the definitions that have been set -in the container. After this and several other passes that check the container's -validity, further compiler passes are used to optimize the configuration -before it is cached. For example, private services and abstract services -are removed, and aliases are resolved. +compilation. For example the +:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass` +checks for various potential issues with the definitions that have been +set in the container. After this and several other passes that check the +container's validity, further compiler passes are used to optimize the +configuration before it is cached. For example, private services and abstract +services are removed and aliases are resolved. .. _components-dependency-injection-extension: @@ -30,27 +31,29 @@ Managing Configuration with Extensions -------------------------------------- As well as loading configuration directly into the container as shown in -:doc:`/components/dependency_injection/introduction`, you can manage it by -registering extensions with the container. The first step in the compilation +:doc:`/components/dependency_injection/introduction`, you can manage it +by registering extensions with the container. The first step in the compilation process is to load configuration from any extension classes registered with the container. Unlike the configuration loaded directly, they are only processed when the container is compiled. If your application is modular then extensions allow each module to register and manage their own service configuration. -The extensions must implement :class:`Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface` +The extensions must implement +:class:`Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface` and can be registered with the container with:: $container->registerExtension($extension); -The main work of the extension is done in the ``load`` method. In the ``load`` method -you can load configuration from one or more configuration files as well as -manipulate the container definitions using the methods shown in :doc:`/components/dependency_injection/definitions`. +The main work of the extension is done in the ``load`` method. In the ``load`` +method you can load configuration from one or more configuration files as +well as manipulate the container definitions using the methods shown in +:doc:`/components/dependency_injection/definitions`. The ``load`` method is passed a fresh container to set up, which is then -merged afterwards into the container it is registered with. This allows you -to have several extensions managing container definitions independently. -The extensions do not add to the containers configuration when they are added -but are processed when the container's ``compile`` method is called. +merged afterwards into the container it is registered with. This allows +you to have several extensions managing container definitions independently. +The extensions do not add to the containers configuration when they are +added but are processed when the container's ``compile`` method is called. A very simple extension may just load configuration files into the container:: @@ -73,14 +76,14 @@ A very simple extension may just load configuration files into the container:: // ... } -This does not gain very much compared to loading the file directly into the -overall container being built. It just allows the files to be split up amongst -the modules/bundles. Being able to affect the configuration of a module from -configuration files outside of the module/bundle is needed to make a complex -application configurable. This can be done by specifying sections of config files -loaded directly into the container as being for a particular extension. These -sections on the config will not be processed directly by the container but by the -relevant Extension. +This does not gain very much compared to loading the file directly into +the overall container being built. It just allows the files to be split +up amongst the modules/bundles. Being able to affect the configuration +of a module from configuration files outside of the module/bundle is needed +to make a complex application configurable. This can be done by specifying +sections of config files loaded directly into the container as being for +a particular extension. These sections on the config will not be processed +directly by the container but by the relevant Extension. The Extension must specify a ``getAlias`` method to implement the interface:: @@ -96,8 +99,8 @@ The Extension must specify a ``getAlias`` method to implement the interface:: } } -For YAML configuration files specifying the alias for the Extension as a key -will mean that those values are passed to the Extension's ``load`` method: +For YAML configuration files specifying the alias for the Extension as a +key will mean that those values are passed to the Extension's ``load`` method: .. code-block:: yaml @@ -106,8 +109,9 @@ will mean that those values are passed to the Extension's ``load`` method: foo: fooValue bar: barValue -If this file is loaded into the configuration then the values in it are only -processed when the container is compiled at which point the Extensions are loaded:: +If this file is loaded into the configuration then the values in it are +only processed when the container is compiled at which point the Extensions +are loaded:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; @@ -138,9 +142,9 @@ argument of the ``load`` method of the extension:: } The ``$configs`` argument is an array containing each different config file -that was loaded into the container. You are only loading a single config file -in the above example but it will still be within an array. The array will look -like this:: +that was loaded into the container. You are only loading a single config +file in the above example but it will still be within an array. The array +will look like this:: array( array( @@ -150,9 +154,9 @@ like this:: ) Whilst you can manually manage merging the different files, it is much better -to use :doc:`the Config component ` to merge -and validate the config values. Using the configuration processing you could -access the config value this way:: +to use :doc:`the Config component ` to +merge and validate the config values. Using the configuration processing +you could access the config value this way:: use Symfony\Component\Config\Definition\Processor; // ... @@ -207,13 +211,13 @@ The XML version of the config would then look like this: .. note:: - In the Symfony full-stack Framework there is a base Extension class which - implements these methods as well as a shortcut method for processing the - configuration. See :doc:`/cookbook/bundles/extension` for more details. + In the Symfony full-stack Framework there is a base Extension class + which implements these methods as well as a shortcut method for processing + the configuration. See :doc:`/cookbook/bundles/extension` for more details. -The processed config value can now be added as container parameters as if it were -listed in a ``parameters`` section of the config file but with the additional -benefit of merging multiple files and validation of the configuration:: +The processed config value can now be added as container parameters as if +it were listed in a ``parameters`` section of the config file but with the +additional benefit of merging multiple files and validation of the configuration:: public function load(array $configs, ContainerBuilder $container) { @@ -227,8 +231,8 @@ benefit of merging multiple files and validation of the configuration:: } More complex configuration requirements can be catered for in the Extension -classes. For example, you may choose to load a main service configuration file -but also load a secondary one only if a certain parameter is set:: +classes. For example, you may choose to load a main service configuration +file but also load a secondary one only if a certain parameter is set:: public function load(array $configs, ContainerBuilder $container) { @@ -278,11 +282,12 @@ Prepending Configuration Passed to the Extension ------------------------------------------------ .. versionadded:: 2.2 - The ability to prepend the configuration of a bundle was introduced in - Symfony 2.2. + The ability to prepend the configuration of a bundle was introduced + in Symfony 2.2. An Extension can prepend the configuration of any Bundle before the ``load()`` -method is called by implementing :class:`Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface`:: +method is called by implementing +:class:`Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface`:: use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; // ... @@ -301,8 +306,9 @@ method is called by implementing :class:`Symfony\\Component\\DependencyInjection } } -For more details, see :doc:`/cookbook/bundles/prepend_extension`, which is -specific to the Symfony Framework, but contains more details about this feature. +For more details, see :doc:`/cookbook/bundles/prepend_extension`, which +is specific to the Symfony Framework, but contains more details about this +feature. Creating a Compiler Pass ------------------------ @@ -310,9 +316,9 @@ Creating a Compiler Pass You can also create and register your own compiler passes with the container. To create a compiler pass it needs to implement the :class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` -interface. The compiler pass gives you an opportunity to manipulate the service -definitions that have been compiled. This can be very powerful, but is not -something needed in everyday use. +interface. The compiler pass gives you an opportunity to manipulate the +service definitions that have been compiled. This can be very powerful, +but is not something needed in everyday use. The compiler pass must have the ``process`` method which is passed the container being compiled:: @@ -330,9 +336,9 @@ being compiled:: The container's parameters and definitions can be manipulated using the methods described in the :doc:`/components/dependency_injection/definitions`. -One common thing to do in a compiler pass is to search for all services that -have a certain tag in order to process them in some way or dynamically plug -each into some other service. +One common thing to do in a compiler pass is to search for all services +that have a certain tag in order to process them in some way or dynamically +plug each into some other service. Registering a Compiler Pass --------------------------- @@ -356,9 +362,10 @@ Controlling the Pass Ordering The default compiler passes are grouped into optimization passes and removal passes. The optimization passes run first and include tasks such as resolving -references within the definitions. The removal passes perform tasks such as removing -private aliases and unused services. You can choose where in the order any custom -passes you add are run. By default they will be run before the optimization passes. +references within the definitions. The removal passes perform tasks such +as removing private aliases and unused services. You can choose where in +the order any custom passes you add are run. By default they will be run +before the optimization passes. You can use the following constants as the second argument when registering a pass with the container to control where it goes in the order: @@ -369,7 +376,8 @@ a pass with the container to control where it goes in the order: * ``PassConfig::TYPE_REMOVE`` * ``PassConfig::TYPE_AFTER_REMOVING`` -For example, to run your custom pass after the default removal passes have been run:: +For example, to run your custom pass after the default removal passes have +been run:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; @@ -386,12 +394,13 @@ Dumping the Configuration for Performance ----------------------------------------- Using configuration files to manage the service container can be much easier -to understand than using PHP once there are a lot of services. This ease comes -at a price though when it comes to performance as the config files need to be -parsed and the PHP configuration built from them. The compilation process makes -the container more efficient but it takes time to run. You can have the best of both -worlds though by using configuration files and then dumping and caching the resulting -configuration. The ``PhpDumper`` makes dumping the compiled container easy:: +to understand than using PHP once there are a lot of services. This ease +comes at a price though when it comes to performance as the config files +need to be parsed and the PHP configuration built from them. The compilation +process makes the container more efficient but it takes time to run. You +can have the best of both worlds though by using configuration files and +then dumping and caching the resulting configuration. The ``PhpDumper`` +makes dumping the compiled container easy:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; @@ -411,8 +420,8 @@ configuration. The ``PhpDumper`` makes dumping the compiled container easy:: } ``ProjectServiceContainer`` is the default name given to the dumped container -class, you can change this though this with the ``class`` option when you dump -it:: +class, you can change this though this with the ``class`` option when you +dump it:: // ... $file = __DIR__ .'/cache/container.php'; @@ -432,14 +441,15 @@ it:: ); } -You will now get the speed of the PHP configured container with the ease of using -configuration files. Additionally dumping the container in this way further optimizes -how the services are created by the container. +You will now get the speed of the PHP configured container with the ease +of using configuration files. Additionally dumping the container in this +way further optimizes how the services are created by the container. In the above example you will need to delete the cached container file whenever -you make any changes. Adding a check for a variable that determines if you are -in debug mode allows you to keep the speed of the cached container in production -but getting an up to date configuration whilst developing your application:: +you make any changes. Adding a check for a variable that determines if you +are in debug mode allows you to keep the speed of the cached container in +production but getting an up to date configuration whilst developing your +application:: // ... @@ -472,11 +482,11 @@ the container in the way described in ":doc:`/components/config/caching`" in the config component documentation. You do not need to work out which files to cache as the container builder -keeps track of all the resources used to configure it, not just the configuration -files but the extension classes and compiler passes as well. This means that -any changes to any of these files will invalidate the cache and trigger the -container being rebuilt. You just need to ask the container for these resources -and use them as metadata for the cache:: +keeps track of all the resources used to configure it, not just the +configuration files but the extension classes and compiler passes as well. +This means that any changes to any of these files will invalidate the cache +and trigger the container being rebuilt. You just need to ask the container +for these resources and use them as metadata for the cache:: // ... @@ -501,12 +511,13 @@ and use them as metadata for the cache:: require_once $file; $container = new MyCachedContainer(); -Now the cached dumped container is used regardless of whether debug mode is on or not. -The difference is that the ``ConfigCache`` is set to debug mode with its second -constructor argument. When the cache is not in debug mode the cached container -will always be used if it exists. In debug mode, an additional metadata file -is written with the timestamps of all the resource files. These are then checked -to see if the files have changed, if they have the cache will be considered stale. +Now the cached dumped container is used regardless of whether debug mode +is on or not. The difference is that the ``ConfigCache`` is set to debug +mode with its second constructor argument. When the cache is not in debug +mode the cached container will always be used if it exists. In debug mode, +an additional metadata file is written with the timestamps of all the resource +files. These are then checked to see if the files have changed, if they +have the cache will be considered stale. .. note:: diff --git a/components/dependency_injection/configurators.rst b/components/dependency_injection/configurators.rst index c8036fc8685..02ccf800af4 100644 --- a/components/dependency_injection/configurators.rst +++ b/components/dependency_injection/configurators.rst @@ -4,27 +4,28 @@ Configuring Services with a Service Configurator ================================================ -The Service Configurator is a feature of the Dependency Injection Container that -allows you to use a callable to configure a service after its instantiation. +The Service Configurator is a feature of the Dependency Injection Container +that allows you to use a callable to configure a service after its instantiation. -You can specify a method in another service, a PHP function or a static method -in a class. The service instance is passed to the callable, allowing the -configurator to do whatever it needs to configure the service after its -creation. +You can specify a method in another service, a PHP function or a static +method in a class. The service instance is passed to the callable, allowing +the configurator to do whatever it needs to configure the service after +its creation. -A Service Configurator can be used, for example, when you have a service that -requires complex setup based on configuration settings coming from different -sources/services. Using an external configurator, you can maintain the service -implementation cleanly and keep it decoupled from the other objects that provide -the configuration needed. +A Service Configurator can be used, for example, when you have a service +that requires complex setup based on configuration settings coming from +different sources/services. Using an external configurator, you can maintain +the service implementation cleanly and keep it decoupled from the other +objects that provide the configuration needed. -Another interesting use case is when you have multiple objects that share a -common configuration or that should be configured in a similar way at runtime. +Another interesting use case is when you have multiple objects that +share a common configuration or that should be configured in a similar way +at runtime. -For example, suppose you have an application where you send different types of -emails to users. Emails are passed through different formatters that could be -enabled or not depending on some dynamic application settings. You start -defining a ``NewsletterManager`` class like this:: +For example, suppose you have an application where you send different types +of emails to users. Emails are passed through different formatters that +could be enabled or not depending on some dynamic application settings. +You start defining a ``NewsletterManager`` class like this:: class NewsletterManager implements EmailFormatterAwareInterface { @@ -64,8 +65,8 @@ and also a ``GreetingCardManager`` class:: // ... } -As mentioned before, the goal is to set the formatters at runtime depending on -application settings. To do this, you also have an ``EmailFormatterManager`` +As mentioned before, the goal is to set the formatters at runtime depending +on application settings. To do this, you also have an ``EmailFormatterManager`` class which is responsible for loading and validating formatters enabled in the application:: @@ -91,8 +92,8 @@ in the application:: } If your goal is to avoid having to couple ``NewsletterManager`` and -``GreetingCardManager`` with ``EmailFormatterManager``, then you might want to -create a configurator class to configure these instances:: +``GreetingCardManager`` with ``EmailFormatterManager``, then you might want +to create a configurator class to configure these instances:: class EmailConfigurator { @@ -115,9 +116,9 @@ create a configurator class to configure these instances:: The ``EmailConfigurator``'s job is to inject the enabled filters into ``NewsletterManager`` and ``GreetingCardManager`` because they are not aware of where the enabled -filters come from. In the other hand, the ``EmailFormatterManager`` holds the -knowledge about the enabled formatters and how to load them, keeping the single -responsibility principle. +filters come from. In the other hand, the ``EmailFormatterManager`` holds +the knowledge about the enabled formatters and how to load them, keeping +the single responsibility principle. Configurator Service Config --------------------------- diff --git a/components/dependency_injection/definitions.rst b/components/dependency_injection/definitions.rst index 9c9574c7b9b..9205de8fb6a 100644 --- a/components/dependency_injection/definitions.rst +++ b/components/dependency_injection/definitions.rst @@ -1,5 +1,5 @@ .. index:: - single: DependencyInjection; Service definitions + single: DependencyInjection; Service definitions Working with Container Service Definitions ========================================== @@ -13,7 +13,8 @@ To find out if there is a definition for a service id:: $container->hasDefinition($serviceId); -This is useful if you only want to do something if a particular definition exists. +This is useful if you only want to do something if a particular definition +exists. You can retrieve a definition with:: @@ -36,7 +37,7 @@ it to the container using:: Working with a Definition ------------------------- -Creating a new Definition +Creating a New Definition ~~~~~~~~~~~~~~~~~~~~~~~~~ If you need to create a new definition rather than manipulate one retrieved @@ -104,11 +105,12 @@ Add a method call with:: $definition->addMethodCall($method, $arguments); -Where ``$method`` is the method name and ``$arguments`` is an array of the arguments -to call the method with. The arguments can be strings, arrays, parameters or -service ids as with the constructor arguments. +Where ``$method`` is the method name and ``$arguments`` is an array of the +arguments to call the method with. The arguments can be strings, arrays, +parameters or service ids as with the constructor arguments. -You can also replace any existing method calls with an array of new ones with:: +You can also replace any existing method calls with an array of new ones +with:: $definition->setMethodCalls($methodCalls); diff --git a/components/dependency_injection/factories.rst b/components/dependency_injection/factories.rst index 7a22ba17da2..8807975d5f8 100644 --- a/components/dependency_injection/factories.rst +++ b/components/dependency_injection/factories.rst @@ -8,9 +8,9 @@ Symfony's Service Container provides a powerful way of controlling the creation of objects, allowing you to specify arguments passed to the constructor as well as calling methods and setting parameters. Sometimes, however, this will not provide you with everything you need to construct your objects. -For this situation, you can use a factory to create the object and tell the -service container to call a method on the factory rather than directly instantiating -the class. +For this situation, you can use a factory to create the object and tell +the service container to call a method on the factory rather than directly +instantiating the class. Suppose you have a factory that configures and returns a new ``NewsletterManager`` object:: @@ -28,8 +28,8 @@ object:: } To make the ``NewsletterManager`` object available as a service, you can -configure the service container to use the ``NewsletterManagerFactory`` factory -class: +configure the service container to use the ``NewsletterManagerFactory`` +factory class: .. configuration-block:: @@ -71,16 +71,16 @@ class: .. note:: When using a factory to create services, the value chosen for the ``class`` - option has no effect on the resulting service. The actual class name only - depends on the object that is returned by the factory. However, the configured - class name may be used by compiler passes and therefore should be set to a - sensible value. + option has no effect on the resulting service. The actual class name + only depends on the object that is returned by the factory. However, + the configured class name may be used by compiler passes and therefore + should be set to a sensible value. When you specify the class to use for the factory (via ``factory_class``) the method will be called statically. If the factory itself should be instantiated -and the resulting object's method called, configure the factory itself as a service. -In this case, the method (e.g. ``createNewsletterManager``) should be changed -to be non-static: +and the resulting object's method called, configure the factory itself +as a service. In this case, the method (e.g. ``createNewsletterManager``) +should be changed to be non-static: .. configuration-block:: @@ -129,9 +129,9 @@ to be non-static: .. note:: - The factory service is specified by its id name and not a reference to - the service itself. So, you do not need to use the @ syntax for this in - YAML configurations. + The factory service is specified by its id name and not a reference + to the service itself. So, you do not need to use the ``@`` syntax for + this in YAML configurations. Passing Arguments to the Factory Method --------------------------------------- diff --git a/components/dependency_injection/index.rst b/components/dependency_injection/index.rst index dfa2e1ef54b..313f29af3f4 100644 --- a/components/dependency_injection/index.rst +++ b/components/dependency_injection/index.rst @@ -1,4 +1,4 @@ -DependencyInjection +DependencyInjection =================== .. toctree:: diff --git a/components/dependency_injection/introduction.rst b/components/dependency_injection/introduction.rst index 58fe212780d..880b56efe95 100644 --- a/components/dependency_injection/introduction.rst +++ b/components/dependency_injection/introduction.rst @@ -16,7 +16,8 @@ Installation You can install the component in 2 different ways: -* :doc:`Install it via Composer ` (``symfony/dependency-injection`` on `Packagist`_); +* :doc:`Install it via Composer ` (``symfony/dependency-injection`` + on `Packagist`_); * Use the official Git repository (https://github.com/symfony/DependencyInjection). .. include:: /components/require_autoload.rst.inc @@ -74,10 +75,10 @@ Then you can set the choice of transport in the container:: This class is now much more flexible as you have separated the choice of transport out of the implementation and into the container. -Which mail transport you have chosen may be something other services need to -know about. You can avoid having to change it in multiple places by making -it a parameter in the container and then referring to this parameter for the -``Mailer`` service's constructor argument:: +Which mail transport you have chosen may be something other services need +to know about. You can avoid having to change it in multiple places by making +it a parameter in the container and then referring to this parameter for +the ``Mailer`` service's constructor argument:: use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -182,10 +183,10 @@ Setting up the Container with Configuration Files As well as setting up the services using PHP as above you can also use configuration files. This allows you to use XML or YAML to write the definitions -for the services rather than using PHP to define the services as in the above -examples. In anything but the smallest applications it makes sense to organize -the service definitions by moving them into one or more configuration files. -To do this you also need to install +for the services rather than using PHP to define the services as in the +above examples. In anything but the smallest applications it makes sense +to organize the service definitions by moving them into one or more configuration +files. To do this you also need to install :doc:`the Config component `. Loading an XML config file:: diff --git a/components/dependency_injection/lazy_services.rst b/components/dependency_injection/lazy_services.rst index d527d02db98..3ed6fb33678 100644 --- a/components/dependency_injection/lazy_services.rst +++ b/components/dependency_injection/lazy_services.rst @@ -7,7 +7,7 @@ Lazy Services .. versionadded:: 2.3 Lazy services were introduced in Symfony 2.3. -Why lazy Services? +Why Lazy Services? ------------------ In some cases, you may want to inject a service that is a bit heavy to instantiate, @@ -17,10 +17,10 @@ a few methods on your ``NewsletterManager`` actually use the ``mailer``, but even when you don't need it, a ``mailer`` service is always instantiated in order to construct your ``NewsletterManager``. -Configuring lazy services is one answer to this. With a lazy service, a "proxy" -of the ``mailer`` service is actually injected. It looks and acts just like -the ``mailer``, except that the ``mailer`` isn't actually instantiated until -you interact with the proxy in some way. +Configuring lazy services is one answer to this. With a lazy service, a +"proxy" of the ``mailer`` service is actually injected. It looks and acts +just like the ``mailer``, except that the ``mailer`` isn't actually instantiated +until you interact with the proxy in some way. Installation ------------ @@ -34,8 +34,9 @@ the `ProxyManager bridge`_: .. note:: - If you're using the full-stack framework, the proxy manager bridge is already - included but the actual proxy manager needs to be included. So, run: + If you're using the full-stack framework, the proxy manager bridge is + already included but the actual proxy manager needs to be included. + So, run: .. code-block:: bash @@ -94,14 +95,14 @@ received object. var_dump(class_implements($service)); -If the class implements the ``ProxyManager\Proxy\LazyLoadingInterface`` your -lazy loaded services are working. +If the class implements the ``ProxyManager\Proxy\LazyLoadingInterface`` +your lazy loaded services are working. .. note:: - If you don't install the `ProxyManager bridge`_, the container will just - skip over the ``lazy`` flag and simply instantiate the service as it would - normally do. + If you don't install the `ProxyManager bridge`_, the container will + just skip over the ``lazy`` flag and simply instantiate the service + as it would normally do. The proxy gets initialized and the actual service is instantiated as soon as you interact in any way with this object. diff --git a/components/dependency_injection/parameters.rst b/components/dependency_injection/parameters.rst index 1ceb887a138..604cf00f704 100644 --- a/components/dependency_injection/parameters.rst +++ b/components/dependency_injection/parameters.rst @@ -29,8 +29,8 @@ and set a parameter in the container with:: The used ``.`` notation is just a :ref:`Symfony convention ` to make parameters - easier to read. Parameters are just flat key-value elements, they can't be - organized into a nested array + easier to read. Parameters are just flat key-value elements, they can't + be organized into a nested array .. note:: @@ -67,14 +67,15 @@ You can also use the ``parameters`` section of a config file to set parameters: $container->setParameter('mailer.transport', 'sendmail'); As well as retrieving the parameter values directly from the container you -can use them in the config files. You can refer to parameters elsewhere by -surrounding them with percent (``%``) signs, e.g. ``%mailer.transport%``. +can use them in the config files. You can refer to parameters elsewhere +by surrounding them with percent (``%``) signs, e.g. ``%mailer.transport%``. One use for this is to inject the values into your services. This allows -you to configure different versions of services between applications or multiple -services based on the same class but configured differently within a single -application. You could inject the choice of mail transport into the ``Mailer`` -class directly. But declaring it as a parameter makes it easier to change -rather than being tied up and hidden with the service definition: +you to configure different versions of services between applications or +multiple services based on the same class but configured differently +within a single application. You could inject the choice of mail transport +into the ``Mailer`` class directly. But declaring it as a parameter makes +it easier to change rather than being tied up and hidden with the service +definition: .. configuration-block:: @@ -118,8 +119,8 @@ rather than being tied up and hidden with the service definition: .. caution:: - The values between ``parameter`` tags in XML configuration files are not - trimmed. + The values between ``parameter`` tags in XML configuration files are + not trimmed. This means that the following configuration sample will have the value ``\n sendmail\n``: @@ -130,8 +131,9 @@ rather than being tied up and hidden with the service definition: sendmail - In some cases (for constants or class names), this could throw errors. In - order to prevent this, you must always inline your parameters as follow: + In some cases (for constants or class names), this could throw errors. + In order to prevent this, you must always inline your parameters as + follow: .. code-block:: xml @@ -142,8 +144,8 @@ the parameter value in one place if needed. .. note:: - The percent sign inside a parameter or argument, as part of the string, must - be escaped with another percent sign: + The percent sign inside a parameter or argument, as part of the string, + must be escaped with another percent sign: .. configuration-block:: @@ -165,8 +167,8 @@ Array Parameters ---------------- Parameters do not need to be flat strings, they can also contain array values. -For the XML format, you need to use the ``type="collection"`` attribute for -all parameters that are arrays. +For the XML format, you need to use the ``type="collection"`` attribute +for all parameters that are arrays. .. configuration-block:: @@ -224,9 +226,9 @@ all parameters that are arrays. Constants as Parameters ----------------------- -The container also has support for setting PHP constants as parameters. To -take advantage of this feature, map the name of your constant to a parameter -key, and define the type as ``constant``. +The container also has support for setting PHP constants as parameters. +To take advantage of this feature, map the name of your constant to a parameter +key and define the type as ``constant``. .. configuration-block:: @@ -261,8 +263,8 @@ key, and define the type as ``constant``. PHP Keywords in XML ------------------- -By default, ``true``, ``false`` and ``null`` in XML are converted to the PHP -keywords (respectively ``true``, ``false`` and ``null``): +By default, ``true``, ``false`` and ``null`` in XML are converted to the +PHP keywords (respectively ``true``, ``false`` and ``null``): .. code-block:: xml diff --git a/components/dependency_injection/parentservices.rst b/components/dependency_injection/parentservices.rst index b7729ab1f50..9237e57ac21 100644 --- a/components/dependency_injection/parentservices.rst +++ b/components/dependency_injection/parentservices.rst @@ -1,12 +1,13 @@ .. index:: - single: DependencyInjection; Parent services + single: DependencyInjection; Parent services -Managing common Dependencies with parent Services +Managing Common Dependencies with Parent Services ================================================= -As you add more functionality to your application, you may well start to have -related classes that share some of the same dependencies. For example you -may have a Newsletter Manager which uses setter injection to set its dependencies:: +As you add more functionality to your application, you may well start to +have related classes that share some of the same dependencies. For example, +you may have a Newsletter Manager which uses setter injection to set its +dependencies:: class NewsletterManager { @@ -136,12 +137,13 @@ The service config for these classes would look something like this: )) ; -There is a lot of repetition in both the classes and the configuration. This -means that if you changed, for example, the ``Mailer`` of ``EmailFormatter`` -classes to be injected via the constructor, you would need to update the config -in two places. Likewise if you needed to make changes to the setter methods -you would need to do this in both classes. The typical way to deal with the -common methods of these related classes would be to extract them to a super class:: +There is a lot of repetition in both the classes and the configuration. +This means that if you changed, for example, the ``Mailer`` of +``EmailFormatter`` classes to be injected via the constructor, you would +need to update the config in two places. Likewise if you needed to make +changes to the setter methods you would need to do this in both classes. +The typical way to deal with the common methods of these related classes +would be to extract them to a super class:: abstract class MailManager { @@ -260,10 +262,10 @@ a parent for a service. $greetingCardManager->setClass('GreetingCardManager'); $container->setDefinition('greeting_card_manager', $greetingCardManager); -In this context, having a ``parent`` service implies that the arguments and -method calls of the parent service should be used for the child services. -Specifically, the setter methods defined for the parent service will be called -when the child services are instantiated. +In this context, having a ``parent`` service implies that the arguments +and method calls of the parent service should be used for the child services. +Specifically, the setter methods defined for the parent service will be +called when the child services are instantiated. .. note:: @@ -275,19 +277,19 @@ when the child services are instantiated. .. caution:: - The ``scope``, ``abstract`` and ``tags`` attributes are always taken from - the child service. + The ``scope``, ``abstract`` and ``tags`` attributes are always taken + from the child service. -The parent service is abstract as it should not be directly retrieved from the -container or passed into another service. It exists merely as a "template" that -other services can use. This is why it can have no ``class`` configured which -would cause an exception to be raised for a non-abstract service. +The parent service is abstract as it should not be directly retrieved from +the container or passed into another service. It exists merely as a "template" +that other services can use. This is why it can have no ``class`` configured +which would cause an exception to be raised for a non-abstract service. .. note:: - In order for parent dependencies to resolve, the ``ContainerBuilder`` must - first be compiled. See :doc:`/components/dependency_injection/compilation` - for more details. + In order for parent dependencies to resolve, the ``ContainerBuilder`` + must first be compiled. See + :doc:`/components/dependency_injection/compilation` for more details. .. tip:: @@ -296,7 +298,7 @@ would cause an exception to be raised for a non-abstract service. You can just extract common parts of similar service definitions into a parent service without also extending a parent class in PHP. -Overriding parent Dependencies +Overriding Parent Dependencies ------------------------------ There may be times where you want to override what class is passed in for @@ -411,10 +413,10 @@ instead of the ``my_mailer`` service. .. caution:: - You can't override method calls. When you defined new method calls in the child - service, it'll be added to the current set of configured method calls. This means - it works perfectly when the setter overrides the current property, but it doesn't - work as expected when the setter appends it to the existing data (e.g. an - ``addFilters()`` method). - In those cases, the only solution is to *not* extend the parent service and configuring + You can't override method calls. When you defined new method calls in + the child service, it'll be added to the current set of configured method + calls. This means it works perfectly when the setter overrides the current + property, but it doesn't work as expected when the setter appends it + to the existing data (e.g. an ``addFilters()`` method). In those cases, + the only solution is to *not* extend the parent service and configuring the service just like you did before knowing this feature. diff --git a/components/dependency_injection/synthetic_services.rst b/components/dependency_injection/synthetic_services.rst index cbe32a8c60a..d53e4636bdc 100644 --- a/components/dependency_injection/synthetic_services.rst +++ b/components/dependency_injection/synthetic_services.rst @@ -4,8 +4,8 @@ How to Inject Instances into the Container ------------------------------------------ -When using the container in your application, you sometimes need to inject an -instance instead of configuring the container to create a new instance. +When using the container in your application, you sometimes need to inject +an instance instead of configuring the container to create a new instance. For instance, if you're using the :doc:`HttpKernel ` component with the DependencyInjection component, then the ``kernel`` @@ -24,10 +24,10 @@ service is injected into the container from within the ``Kernel`` class:: } } -The ``kernel`` service is called a synthetic service. This service has to be -configured in the container, so the container knows the service does exist -during compilation (otherwise, services depending on this ``kernel`` service -will get a "service does not exists" error). +The ``kernel`` service is called a synthetic service. This service has to +be configured in the container, so the container knows the service does +exist during compilation (otherwise, services depending on this ``kernel`` +service will get a "service does not exists" error). In order to do so, you have to use :method:`Definition::setSynthetic() `:: diff --git a/components/dependency_injection/tags.rst b/components/dependency_injection/tags.rst index 9bb0d000707..17b8b584e53 100644 --- a/components/dependency_injection/tags.rst +++ b/components/dependency_injection/tags.rst @@ -4,12 +4,12 @@ Working with Tagged Services ============================ -Tags are a generic string (along with some options) that can be applied to -any service. By themselves, tags don't actually alter the functionality of your -services in any way. But if you choose to, you can ask a container builder -for a list of all services that were tagged with some specific tag. This -is useful in compiler passes where you can find these services and use or -modify them in some specific way. +Tags are a generic string (along with some options) that can be applied +to any service. By themselves, tags don't actually alter the functionality +of your services in any way. But if you choose to, you can ask a container +builder for a list of all services that were tagged with some specific tag. +This is useful in compiler passes where you can find these services and +use or modify them in some specific way. For example, if you are using Swift Mailer you might imagine that you want to implement a "transport chain", which is a collection of classes implementing @@ -57,11 +57,9 @@ Then, define the chain as a service: .. code-block:: php - use Symfony\Component\DependencyInjection\Definition; - - $container->setDefinition('acme_mailer.transport_chain', new Definition('TransportChain')); + $container->register('acme_mailer.transport_chain', 'TransportChain'); -Define Services with a custom Tag +Define Services with a Custom Tag --------------------------------- Now you might want several of the ``\Swift_Transport`` classes to be instantiated @@ -154,11 +152,11 @@ custom tag:: } The ``process()`` method checks for the existence of the ``acme_mailer.transport_chain`` -service, then looks for all services tagged ``acme_mailer.transport``. It adds -to the definition of the ``acme_mailer.transport_chain`` service a call to -``addTransport()`` for each "acme_mailer.transport" service it has found. -The first argument of each of these calls will be the mailer transport service -itself. +service, then looks for all services tagged ``acme_mailer.transport``. It +adds to the definition of the ``acme_mailer.transport_chain`` service a +call to ``addTransport()`` for each "acme_mailer.transport" service it has +found. The first argument of each of these calls will be the mailer transport +service itself. Register the Pass with the Container ------------------------------------ @@ -177,11 +175,12 @@ run when the container is compiled:: framework. See :doc:`/cookbook/service_container/compiler_passes` for more details. -Adding additional Attributes on Tags +Adding Additional Attributes on Tags ------------------------------------ -Sometimes you need additional information about each service that's tagged with your tag. -For example, you might want to add an alias to each member of the transport chain. +Sometimes you need additional information about each service that's tagged +with your tag. For example, you might want to add an alias to each member +of the transport chain. To begin with, change the ``TransportChain`` class:: @@ -293,7 +292,7 @@ use this, update the compiler:: } } -The double loop may be confusing. This is because a service can have more than one -tag. You tag a service twice or more with the ``acme_mailer.transport`` tag. The -second foreach loop iterates over the ``acme_mailer.transport`` tags set for the -current service and gives you the attributes. +The double loop may be confusing. This is because a service can have more +than one tag. You tag a service twice or more with the ``acme_mailer.transport`` +tag. The second foreach loop iterates over the ``acme_mailer.transport`` +tags set for the current service and gives you the attributes. diff --git a/components/dependency_injection/types.rst b/components/dependency_injection/types.rst index 0a1f65304b8..c7181396218 100644 --- a/components/dependency_injection/types.rst +++ b/components/dependency_injection/types.rst @@ -9,8 +9,8 @@ into it is a good way of making a class more reusable, testable and decoupled from others. There are several ways that the dependencies can be injected. Each injection -point has advantages and disadvantages to consider, as well as different ways -of working with them when using the service container. +point has advantages and disadvantages to consider, as well as different +ways of working with them when using the service container. Constructor Injection --------------------- @@ -89,19 +89,20 @@ There are several advantages to using constructor injection: then injecting it via the constructor ensures it is present when the class is used as the class cannot be constructed without it. -* The constructor is only ever called once when the object is created, so you - can be sure that the dependency will not change during the object's lifetime. +* The constructor is only ever called once when the object is created, so + you can be sure that the dependency will not change during the object's + lifetime. -These advantages do mean that constructor injection is not suitable for working -with optional dependencies. It is also more difficult to use in combination -with class hierarchies: if a class uses constructor injection then extending it -and overriding the constructor becomes problematic. +These advantages do mean that constructor injection is not suitable for +working with optional dependencies. It is also more difficult to use in +combination with class hierarchies: if a class uses constructor injection +then extending it and overriding the constructor becomes problematic. Setter Injection ---------------- -Another possible injection point into a class is by adding a setter method that -accepts the dependency:: +Another possible injection point into a class is by adding a setter method +that accepts the dependency:: class NewsletterManager { @@ -159,19 +160,19 @@ accepts the dependency:: This time the advantages are: -* Setter injection works well with optional dependencies. If you do not need - the dependency, then just do not call the setter. +* Setter injection works well with optional dependencies. If you do not + need the dependency, then just do not call the setter. -* You can call the setter multiple times. This is particularly useful if the - method adds the dependency to a collection. You can then have a variable number - of dependencies. +* You can call the setter multiple times. This is particularly useful if + the method adds the dependency to a collection. You can then have a variable + number of dependencies. The disadvantages of setter injection are: * The setter can be called more than just at the time of construction so - you cannot be sure the dependency is not replaced during the lifetime of the - object (except by explicitly writing the setter method to check if it has already - been called). + you cannot be sure the dependency is not replaced during the lifetime + of the object (except by explicitly writing the setter method to check + if it has already been called). * You cannot be sure the setter will be called and so you need to add checks that any required dependencies are injected. diff --git a/components/dependency_injection/workflow.rst b/components/dependency_injection/workflow.rst index d528c10fa6b..77c5a10813b 100644 --- a/components/dependency_injection/workflow.rst +++ b/components/dependency_injection/workflow.rst @@ -13,21 +13,21 @@ whether you are using the full-stack framework or looking to use the service container in another application. The full-stack framework uses the HttpKernel component to manage the loading -of the service container configuration from the application and bundles and -also handles the compilation and caching. Even if you are not using HttpKernel, -it should give you an idea of one way of organizing configuration in a modular -application. +of the service container configuration from the application and bundles +and also handles the compilation and caching. Even if you are not using +HttpKernel, it should give you an idea of one way of organizing configuration +in a modular application. Working with a Cached Container ------------------------------- -Before building it, the kernel checks to see if a cached version of the container -exists. The HttpKernel has a debug setting and if this is false, the -cached version is used if it exists. If debug is true then the kernel +Before building it, the kernel checks to see if a cached version of the +container exists. The HttpKernel has a debug setting and if this is false, +the cached version is used if it exists. If debug is true then the kernel :doc:`checks to see if configuration is fresh ` -and if it is, the cached version of the container is used. If not then the container -is built from the application-level configuration and the bundles's extension -configuration. +and if it is, the cached version of the container is used. If not then the +container is built from the application-level configuration and the bundles's +extension configuration. Read :ref:`Dumping the Configuration for Performance ` for more details. @@ -36,11 +36,13 @@ Application-level Configuration ------------------------------- Application level config is loaded from the ``app/config`` directory. Multiple -files are loaded which are then merged when the extensions are processed. This -allows for different configuration for different environments e.g. dev, prod. +files are loaded which are then merged when the extensions are processed. +This allows for different configuration for different environments e.g. +dev, prod. These files contain parameters and services that are loaded directly into -the container as per :ref:`Setting Up the Container with Configuration Files `. +the container as per +:ref:`Setting Up the Container with Configuration Files `. They also contain configuration that is processed by extensions as per :ref:`Managing Configuration with Extensions `. These are considered to be bundle configuration since each bundle contains @@ -51,28 +53,29 @@ Bundle-level Configuration with Extensions By convention, each bundle contains an Extension class which is in the bundle's ``DependencyInjection`` directory. These are registered with the ``ContainerBuilder`` -when the kernel is booted. When the ``ContainerBuilder`` is :doc:`compiled `, -the application-level configuration relevant to the bundle's extension is -passed to the Extension which also usually loads its own config file(s), typically from the bundle's -``Resources/config`` directory. The application-level config is usually processed -with a :doc:`Configuration object ` also stored -in the bundle's ``DependencyInjection`` directory. +when the kernel is booted. When the ``ContainerBuilder`` is +:doc:`compiled `, the application-level +configuration relevant to the bundle's extension is passed to the Extension +which also usually loads its own config file(s), typically from the bundle's +``Resources/config`` directory. The application-level config is usually +processed with a :doc:`Configuration object ` +also stored in the bundle's ``DependencyInjection`` directory. Compiler Passes to Allow Interaction between Bundles ---------------------------------------------------- -:ref:`Compiler passes ` are -used to allow interaction between different bundles as they cannot affect -each other's configuration in the extension classes. One of the main uses is -to process tagged services, allowing bundles to register services to be picked -up by other bundles, such as Monolog loggers, Twig extensions and Data Collectors -for the Web Profiler. Compiler passes are usually placed in the bundle's -``DependencyInjection/Compiler`` directory. +:ref:`Compiler passes ` +are used to allow interaction between different bundles as they cannot affect +each other's configuration in the extension classes. One of the main uses +is to process tagged services, allowing bundles to register services to +be picked up by other bundles, such as Monolog loggers, Twig extensions +and Data Collectors for the Web Profiler. Compiler passes are usually placed +in the bundle's ``DependencyInjection/Compiler`` directory. Compilation and Caching ----------------------- After the compilation process has loaded the services from the configuration, -extensions and the compiler passes, it is dumped so that the cache can be used -next time. The dumped version is then used during subsequent requests as it -is more efficient. +extensions and the compiler passes, it is dumped so that the cache can be +used next time. The dumped version is then used during subsequent requests +as it is more efficient. From a045995ea52094b664a494a9a52ed543e3de28fd Mon Sep 17 00:00:00 2001 From: WouterJ Date: Tue, 21 Jul 2015 18:34:52 +0200 Subject: [PATCH 03/15] Fix BOM characters --- components/dependency_injection/compilation.rst | 3 ++- components/dependency_injection/definitions.rst | 3 ++- components/dependency_injection/introduction.rst | 3 ++- components/dependency_injection/tags.rst | 3 ++- components/dependency_injection/types.rst | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index 34552dafe97..68ef2693883 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -1,4 +1,4 @@ -.. index:: +.. index:: single: DependencyInjection; Compilation Compiling the Container @@ -523,3 +523,4 @@ have the cache will be considered stale. In the full-stack framework the compilation and caching of the container is taken care of for you. + diff --git a/components/dependency_injection/definitions.rst b/components/dependency_injection/definitions.rst index 9205de8fb6a..bd13b766b43 100644 --- a/components/dependency_injection/definitions.rst +++ b/components/dependency_injection/definitions.rst @@ -1,4 +1,4 @@ -.. index:: +.. index:: single: DependencyInjection; Service definitions Working with Container Service Definitions @@ -139,3 +139,4 @@ the service itself gets loaded. To do so, you can use the Notice that Symfony will internally call the PHP statement ``require_once``, which means that your file will be included only once per request. + diff --git a/components/dependency_injection/introduction.rst b/components/dependency_injection/introduction.rst index 880b56efe95..f972a5b3578 100644 --- a/components/dependency_injection/introduction.rst +++ b/components/dependency_injection/introduction.rst @@ -1,4 +1,4 @@ -.. index:: +.. index:: single: DependencyInjection single: Components; DependencyInjection @@ -285,3 +285,4 @@ config files: ->addMethodCall('setMailer', array(new Reference('mailer'))); .. _Packagist: https://packagist.org/packages/symfony/dependency-injection + diff --git a/components/dependency_injection/tags.rst b/components/dependency_injection/tags.rst index 17b8b584e53..83deec45395 100644 --- a/components/dependency_injection/tags.rst +++ b/components/dependency_injection/tags.rst @@ -1,4 +1,4 @@ -.. index:: +.. index:: single: DependencyInjection; Tags Working with Tagged Services @@ -296,3 +296,4 @@ The double loop may be confusing. This is because a service can have more than one tag. You tag a service twice or more with the ``acme_mailer.transport`` tag. The second foreach loop iterates over the ``acme_mailer.transport`` tags set for the current service and gives you the attributes. + diff --git a/components/dependency_injection/types.rst b/components/dependency_injection/types.rst index c7181396218..f04781d8aad 100644 --- a/components/dependency_injection/types.rst +++ b/components/dependency_injection/types.rst @@ -1,4 +1,4 @@ -.. index:: +.. index:: single: DependencyInjection; Injection types Types of Injection @@ -242,3 +242,4 @@ to setter injection but with these additional important problems: But, it is useful to know that this can be done with the service container, especially if you are working with code that is out of your control, such as in a third party library, which uses public properties for its dependencies. + From f0d4ea4674ca96371252d3eaa0810f09a213355d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 22 Jul 2015 08:19:36 +0200 Subject: [PATCH 04/15] use the include() Twig function instead of the tag --- book/templating.rst | 4 ++-- cookbook/profiler/data_collector.rst | 10 +++++----- cookbook/templating/namespaced_paths.rst | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/book/templating.rst b/book/templating.rst index 62500e250bb..05c607eb4a8 100644 --- a/book/templating.rst +++ b/book/templating.rst @@ -584,9 +584,9 @@ you set `with_context`_ to false). maps (i.e. an array with named keys). If you needed to pass in multiple elements, it would look like this: ``{'foo': foo, 'bar': bar}``. -.. versionadded:: 2.2 +.. versionadded:: 2.3 The `include() function`_ is a new Twig feature that's available in Symfony - 2.2. Prior, the `{% include %} tag`_ tag was used. + 2.3. Prior, the `{% include %} tag`_ tag was used. .. index:: single: Templating; Embedding action diff --git a/cookbook/profiler/data_collector.rst b/cookbook/profiler/data_collector.rst index 985738aa5cb..74e7d07006a 100644 --- a/cookbook/profiler/data_collector.rst +++ b/cookbook/profiler/data_collector.rst @@ -131,15 +131,15 @@ following example can help you get started: {% endset %} - {# Set the "link" value to false if you do not have a big "panel" + {# Set the "link" value to false if you do not have a big "panel" section that you want to direct the user to. #} - {% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': true } %} + {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }} {% endblock %} {% block head %} - {# Optional, if you need your own JS or CSS files. #} - {{ parent() }} {# Use parent() to keep the default styles #} + {# Optional, if you need your own JS or CSS files. #} + {{ parent() }} {# Use parent() to keep the default styles #} {% endblock %} {% block menu %} @@ -151,7 +151,7 @@ following example can help you get started: {% endblock %} {% block panel %} - {# Optional, for showing the most details. #} + {# Optional, for showing the most details. #}

Example

Major information goes here diff --git a/cookbook/templating/namespaced_paths.rst b/cookbook/templating/namespaced_paths.rst index 3cccde0bf10..94c37f67fb4 100644 --- a/cookbook/templating/namespaced_paths.rst +++ b/cookbook/templating/namespaced_paths.rst @@ -18,14 +18,14 @@ Take the following paths as an example: .. code-block:: jinja {% extends "AppBundle::layout.html.twig" %} - {% include "AppBundle:Foo:bar.html.twig" %} + {{ include('AppBundle:Foo:bar.html.twig') }} With namespaced paths, the following works as well: .. code-block:: jinja {% extends "@App/layout.html.twig" %} - {% include "@App/Foo/bar.html.twig" %} + {{ include('@App/Foo/bar.html.twig') }} Both paths are valid and functional by default in Symfony. @@ -80,7 +80,7 @@ called ``sidebar.twig`` in that directory, you can use it easily: .. code-block:: jinja - {% include '@foo_bar/sidebar.twig' %} + {{ include('@foo_bar/sidebar.twig') }} Multiple Paths per Namespace ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -134,4 +134,4 @@ in the previous three directories: .. code-block:: jinja - {% include '@theme/header.twig' %} + {{ include('@theme/header.twig') }} From b85837f52358b292e13458dedc05fb367a2662d9 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Wed, 22 Jul 2015 10:34:23 +0200 Subject: [PATCH 05/15] Reviewed EventDispatcher docs --- .../container_aware_dispatcher.rst | 15 +- components/event_dispatcher/generic_event.rst | 27 ++- .../event_dispatcher/immutable_dispatcher.rst | 10 +- components/event_dispatcher/introduction.rst | 224 +++++++++--------- .../event_dispatcher/traceable_dispatcher.rst | 4 +- 5 files changed, 143 insertions(+), 137 deletions(-) diff --git a/components/event_dispatcher/container_aware_dispatcher.rst b/components/event_dispatcher/container_aware_dispatcher.rst index 82a502f582b..c73d249c994 100644 --- a/components/event_dispatcher/container_aware_dispatcher.rst +++ b/components/event_dispatcher/container_aware_dispatcher.rst @@ -7,14 +7,15 @@ The Container Aware Event Dispatcher Introduction ------------ -The :class:`Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher` is -a special ``EventDispatcher`` implementation which is coupled to the service container -that is part of :doc:`the DependencyInjection component `. +The :class:`Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher` +is a special ``EventDispatcher`` implementation which is coupled to the +service container that is part of +:doc:`the DependencyInjection component `. It allows services to be specified as event listeners making the ``EventDispatcher`` extremely powerful. -Services are lazy loaded meaning the services attached as listeners will only be -created if an event is dispatched that requires those listeners. +Services are lazy loaded meaning the services attached as listeners will +only be created if an event is dispatched that requires those listeners. Setup ----- @@ -34,8 +35,8 @@ Adding Listeners The ``ContainerAwareEventDispatcher`` can either load specified services directly or services that implement :class:`Symfony\\Component\\EventDispatcher\\EventSubscriberInterface`. -The following examples assume the service container has been loaded with any -services that are mentioned. +The following examples assume the service container has been loaded with +any services that are mentioned. .. note:: diff --git a/components/event_dispatcher/generic_event.rst b/components/event_dispatcher/generic_event.rst index 27d3723e994..c26ee546432 100644 --- a/components/event_dispatcher/generic_event.rst +++ b/components/event_dispatcher/generic_event.rst @@ -4,20 +4,21 @@ The Generic Event Object ======================== -The base :class:`Symfony\\Component\\EventDispatcher\\Event` class provided by the -EventDispatcher component is deliberately sparse to allow the creation of -API specific event objects by inheritance using OOP. This allows for elegant and -readable code in complex applications. +The base :class:`Symfony\\Component\\EventDispatcher\\Event` class provided +by the EventDispatcher component is deliberately sparse to allow the creation +of API specific event objects by inheritance using OOP. This allows for +elegant and readable code in complex applications. The :class:`Symfony\\Component\\EventDispatcher\\GenericEvent` is available -for convenience for those who wish to use just one event object throughout their -application. It is suitable for most purposes straight out of the box, because -it follows the standard observer pattern where the event object +for convenience for those who wish to use just one event object throughout +their application. It is suitable for most purposes straight out of the +box, because it follows the standard observer pattern where the event object encapsulates an event 'subject', but has the addition of optional extra arguments. -:class:`Symfony\\Component\\EventDispatcher\\GenericEvent` has a simple API in -addition to the base class :class:`Symfony\\Component\\EventDispatcher\\Event` +:class:`Symfony\\Component\\EventDispatcher\\GenericEvent` has a simple +API in addition to the base class +:class:`Symfony\\Component\\EventDispatcher\\Event` * :method:`Symfony\\Component\\EventDispatcher\\GenericEvent::__construct`: Constructor takes the event subject and any arguments; @@ -41,8 +42,8 @@ addition to the base class :class:`Symfony\\Component\\EventDispatcher\\Event` Returns true if the argument key exists; The ``GenericEvent`` also implements :phpclass:`ArrayAccess` on the event -arguments which makes it very convenient to pass extra arguments regarding the -event subject. +arguments which makes it very convenient to pass extra arguments regarding +the event subject. The following examples show use-cases to give a general idea of the flexibility. The examples assume event listeners have been added to the dispatcher. @@ -64,8 +65,8 @@ Simply passing a subject:: } } -Passing and processing arguments using the :phpclass:`ArrayAccess` API to access -the event arguments:: +Passing and processing arguments using the :phpclass:`ArrayAccess` API to +access the event arguments:: use Symfony\Component\EventDispatcher\GenericEvent; diff --git a/components/event_dispatcher/immutable_dispatcher.rst b/components/event_dispatcher/immutable_dispatcher.rst index bbcc167dc4a..7df2aecf282 100644 --- a/components/event_dispatcher/immutable_dispatcher.rst +++ b/components/event_dispatcher/immutable_dispatcher.rst @@ -7,13 +7,13 @@ The Immutable Event Dispatcher .. versionadded:: 2.1 This feature was introduced in Symfony 2.1. -The :class:`Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher` is -a locked or frozen event dispatcher. The dispatcher cannot register new +The :class:`Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher` +is a locked or frozen event dispatcher. The dispatcher cannot register new listeners or subscribers. -The ``ImmutableEventDispatcher`` takes another event dispatcher with all the -listeners and subscribers. The immutable dispatcher is just a proxy of this -original dispatcher. +The ``ImmutableEventDispatcher`` takes another event dispatcher with all +the listeners and subscribers. The immutable dispatcher is just a proxy +of this original dispatcher. To use it, first create a normal dispatcher (``EventDispatcher`` or ``ContainerAwareEventDispatcher``) and register some listeners or diff --git a/components/event_dispatcher/introduction.rst b/components/event_dispatcher/introduction.rst index e2c863bcafa..79071406086 100644 --- a/components/event_dispatcher/introduction.rst +++ b/components/event_dispatcher/introduction.rst @@ -6,44 +6,45 @@ The EventDispatcher Component ============================= The EventDispatcher component provides tools that allow your application - components to communicate with each other by dispatching events and listening - to them. + components to communicate with each other by dispatching events and + listening to them. Introduction ------------ -Object-oriented code has gone a long way to ensuring code extensibility. By -creating classes that have well defined responsibilities, your code becomes -more flexible and a developer can extend them with subclasses to modify their -behaviors. But if they want to share the changes with other developers who have -also made their own subclasses, code inheritance is no longer the answer. - -Consider the real-world example where you want to provide a plugin system for -your project. A plugin should be able to add methods, or do something before -or after a method is executed, without interfering with other plugins. This is -not an easy problem to solve with single inheritance, and multiple inheritance +Object-oriented code has gone a long way to ensuring code extensibility. +By creating classes that have well defined responsibilities, your code becomes +more flexible and a developer can extend them with subclasses to modify +their behaviors. But if they want to share the changes with other developers +who have also made their own subclasses, code inheritance is no longer the +answer. + +Consider the real-world example where you want to provide a plugin system +for your project. A plugin should be able to add methods, or do something +before or after a method is executed, without interfering with other plugins. +This is not an easy problem to solve with single and multiple inheritance (were it possible with PHP) has its own drawbacks. -The Symfony EventDispatcher component implements the `Mediator`_ pattern in -a simple and effective way to make all these things possible and to make your -projects truly extensible. +The Symfony EventDispatcher component implements the `Mediator`_ pattern +in a simple and effective way to make all these things possible and to make +your projects truly extensible. -Take a simple example from :doc:`/components/http_kernel/introduction`. Once a -``Response`` object has been created, it may be useful to allow other elements -in the system to modify it (e.g. add some cache headers) before it's actually -used. To make this possible, the Symfony kernel throws an event - -``kernel.response``. Here's how it works: +Take a simple example from :doc:`/components/http_kernel/introduction`. +Once a ``Response`` object has been created, it may be useful to allow other +elements in the system to modify it (e.g. add some cache headers) before +it's actually used. To make this possible, the Symfony kernel throws an +event - ``kernel.response``. Here's how it works: -* A *listener* (PHP object) tells a central *dispatcher* object that it wants - to listen to the ``kernel.response`` event; +* A *listener* (PHP object) tells a central *dispatcher* object that it + wants to listen to the ``kernel.response`` event; * At some point, the Symfony kernel tells the *dispatcher* object to dispatch - the ``kernel.response`` event, passing with it an ``Event`` object that has - access to the ``Response`` object; + the ``kernel.response`` event, passing with it an ``Event`` object that + has access to the ``Response`` object; * The dispatcher notifies (i.e. calls a method on) all listeners of the - ``kernel.response`` event, allowing each of them to make modifications to - the ``Response`` object. + ``kernel.response`` event, allowing each of them to make modifications + to the ``Response`` object. .. index:: single: EventDispatcher; Events @@ -53,7 +54,8 @@ Installation You can install the component in 2 different ways: -* :doc:`Install it via Composer ` (``symfony/event-dispatcher`` on `Packagist`_); +* :doc:`Install it via Composer ` + (``symfony/event-dispatcher`` on `Packagist`_); * Use the official Git repository (https://github.com/symfony/EventDispatcher). .. include:: /components/require_autoload.rst.inc @@ -65,10 +67,10 @@ Events ~~~~~~ When an event is dispatched, it's identified by a unique name (e.g. -``kernel.response``), which any number of listeners might be listening to. An -:class:`Symfony\\Component\\EventDispatcher\\Event` instance is also created -and passed to all of the listeners. As you'll see later, the ``Event`` object -itself often contains data about the event being dispatched. +``kernel.response``), which any number of listeners might be listening to. +An :class:`Symfony\\Component\\EventDispatcher\\Event` instance is also +created and passed to all of the listeners. As you'll see later, the ``Event`` +object itself often contains data about the event being dispatched. .. index:: pair: EventDispatcher; Naming conventions @@ -79,7 +81,7 @@ Naming Conventions The unique event name can be any string, but optionally follows a few simple naming conventions: -* use only lowercase letters, numbers, dots (``.``), and underscores (``_``); +* use only lowercase letters, numbers, dots (``.``) and underscores (``_``); * prefix names with a namespace followed by a dot (e.g. ``kernel.``); @@ -98,23 +100,24 @@ Event Names and Event Objects ............................. When the dispatcher notifies listeners, it passes an actual ``Event`` object -to those listeners. The base ``Event`` class is very simple: it contains a -method for stopping :ref:`event -propagation `, but not much else. +to those listeners. The base ``Event`` class is very simple: it +contains a method for stopping +:ref:`event propagation `, but not much +else. Often times, data about a specific event needs to be passed along with the -``Event`` object so that the listeners have needed information. In the case of -the ``kernel.response`` event, the ``Event`` object that's created and passed to -each listener is actually of type +``Event`` object so that the listeners have needed information. In the case +of the ``kernel.response`` event, the ``Event`` object that's created and +passed to each listener is actually of type :class:`Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent`, a -subclass of the base ``Event`` object. This class contains methods such as -``getResponse`` and ``setResponse``, allowing listeners to get or even replace -the ``Response`` object. +subclass of the base ``Event`` object. This class contains methods such +as ``getResponse`` and ``setResponse``, allowing listeners to get or even +replace the ``Response`` object. The moral of the story is this: When creating a listener to an event, the -``Event`` object that's passed to the listener may be a special subclass that -has additional methods for retrieving information from and responding to the -event. +``Event`` object that's passed to the listener may be a special subclass +that has additional methods for retrieving information from and responding +to the event. The Dispatcher ~~~~~~~~~~~~~~ @@ -134,10 +137,10 @@ listeners registered with that event:: Connecting Listeners ~~~~~~~~~~~~~~~~~~~~ -To take advantage of an existing event, you need to connect a listener to the -dispatcher so that it can be notified when the event is dispatched. A call to -the dispatcher's ``addListener()`` method associates any valid PHP callable to -an event:: +To take advantage of an existing event, you need to connect a listener to +the dispatcher so that it can be notified when the event is dispatched. +A call to the dispatcher's ``addListener()`` method associates any valid +PHP callable to an event:: $listener = new AcmeListener(); $dispatcher->addListener('foo.action', array($listener, 'onFooAction')); @@ -149,11 +152,11 @@ The ``addListener()`` method takes up to three arguments: * A PHP callable that will be notified when an event is thrown that it listens to; -* An optional priority integer (higher equals more important, and therefore +* An optional priority integer (higher equals more important and therefore that the listener will be triggered earlier) that determines when a listener is triggered versus other listeners (defaults to ``0``). If two listeners - have the same priority, they are executed in the order that they were added - to the dispatcher. + have the same priority, they are executed in the order that they were + added to the dispatcher. .. note:: @@ -164,8 +167,8 @@ The ``addListener()`` method takes up to three arguments: a string representing a function, or an array representing an object method or a class method. - So far, you've seen how PHP objects can be registered as listeners. You - can also register PHP `Closures`_ as event listeners:: + So far, you've seen how PHP objects can be registered as listeners. + You can also register PHP `Closures`_ as event listeners:: use Symfony\Component\EventDispatcher\Event; @@ -173,10 +176,10 @@ The ``addListener()`` method takes up to three arguments: // will be executed when the foo.action event is dispatched }); -Once a listener is registered with the dispatcher, it waits until the event is -notified. In the above example, when the ``foo.action`` event is dispatched, -the dispatcher calls the ``AcmeListener::onFooAction`` method and passes the -``Event`` object as the single argument:: +Once a listener is registered with the dispatcher, it waits until the event +is notified. In the above example, when the ``foo.action`` event is dispatched, +the dispatcher calls the ``AcmeListener::onFooAction`` method and passes +the ``Event`` object as the single argument:: use Symfony\Component\EventDispatcher\Event; @@ -190,12 +193,13 @@ the dispatcher calls the ``AcmeListener::onFooAction`` method and passes the } } -In many cases, a special ``Event`` subclass that's specific to the given event -is passed to the listener. This gives the listener access to special -information about the event. Check the documentation or implementation of each -event to determine the exact ``Symfony\Component\EventDispatcher\Event`` -instance that's being passed. For example, the ``kernel.response`` event passes an -instance of ``Symfony\Component\HttpKernel\Event\FilterResponseEvent``:: +In many cases, a special ``Event`` subclass that's specific to the given +event is passed to the listener. This gives the listener access to special +information about the event. Check the documentation or implementation of +each event to determine the exact ``Symfony\Component\EventDispatcher\Event`` +instance that's being passed. For example, the ``kernel.response`` event +passes an instance of +``Symfony\Component\HttpKernel\Event\FilterResponseEvent``:: use Symfony\Component\HttpKernel\Event\FilterResponseEvent; @@ -247,9 +251,9 @@ instance of ``Symfony\Component\HttpKernel\Event\FilterResponseEvent``:: By default, the listeners pass assumes that the event dispatcher's service id is ``event_dispatcher``, that event listeners are tagged with the - ``kernel.event_listener`` tag and that event subscribers are tagged with - the ``kernel.event_subscriber`` tag. You can change these default values - by passing custom values to the constructor of ``RegisterListenersPass``. + ``kernel.event_listener`` tag and that event subscribers are tagged + with the ``kernel.event_subscriber`` tag. You can change these default + values by passing custom values to the constructor of ``RegisterListenersPass``. .. _event_dispatcher-closures-as-listeners: @@ -259,10 +263,10 @@ instance of ``Symfony\Component\HttpKernel\Event\FilterResponseEvent``:: Creating and Dispatching an Event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In addition to registering listeners with existing events, you can create and -dispatch your own events. This is useful when creating third-party libraries -and also when you want to keep different components of your own system -flexible and decoupled. +In addition to registering listeners with existing events, you can create +and dispatch your own events. This is useful when creating third-party +libraries and also when you want to keep different components of your own +system flexible and decoupled. The Static ``Events`` Class ........................... @@ -335,9 +339,9 @@ Dispatch the Event .................. The :method:`Symfony\\Component\\EventDispatcher\\EventDispatcher::dispatch` -method notifies all listeners of the given event. It takes two arguments: the -name of the event to dispatch and the ``Event`` instance to pass to each -listener of that event:: +method notifies all listeners of the given event. It takes two arguments: +the name of the event to dispatch and the ``Event`` instance to pass to +each listener of that event:: use Acme\StoreBundle\StoreEvents; use Acme\StoreBundle\Order; @@ -351,10 +355,10 @@ listener of that event:: $event = new FilterOrderEvent($order); $dispatcher->dispatch(StoreEvents::STORE_ORDER, $event); -Notice that the special ``FilterOrderEvent`` object is created and passed to -the ``dispatch`` method. Now, any listener to the ``store.order`` event will -receive the ``FilterOrderEvent`` and have access to the ``Order`` object via -the ``getOrder`` method:: +Notice that the special ``FilterOrderEvent`` object is created and passed +to the ``dispatch`` method. Now, any listener to the ``store.order`` event +will receive the ``FilterOrderEvent`` and have access to the ``Order`` object +via the ``getOrder`` method:: // some listener class that's been registered for "store.order" event use Acme\StoreBundle\Event\FilterOrderEvent; @@ -374,8 +378,8 @@ Using Event Subscribers ~~~~~~~~~~~~~~~~~~~~~~~ The most common way to listen to an event is to register an *event listener* -with the dispatcher. This listener can listen to one or more events and is -notified each time those events are dispatched. +with the dispatcher. This listener can listen to one or more events and +is notified each time those events are dispatched. Another way to listen to events is via an *event subscriber*. An event subscriber is a PHP class that's able to tell the dispatcher exactly which @@ -438,13 +442,13 @@ method:: The dispatcher will automatically register the subscriber for each event returned by the ``getSubscribedEvents`` method. This method returns an array -indexed by event names and whose values are either the method name to call or -an array composed of the method name to call and a priority. The example -above shows how to register several listener methods for the same event in -subscriber and also shows how to pass the priority of each listener method. +indexed by event names and whose values are either the method name to call +or an array composed of the method name to call and a priority. The example +above shows how to register several listener methods for the same event +in subscriber and also shows how to pass the priority of each listener method. The higher the priority, the earlier the method is called. In the above example, when the ``kernel.response`` event is triggered, the methods -``onKernelResponsePre``, ``onKernelResponseMid``, and ``onKernelResponsePost`` +``onKernelResponsePre``, ``onKernelResponseMid`` and ``onKernelResponsePost`` are called in that order. .. index:: @@ -456,10 +460,10 @@ Stopping Event Flow/Propagation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In some cases, it may make sense for a listener to prevent any other listeners -from being called. In other words, the listener needs to be able to tell the -dispatcher to stop all propagation of the event to future listeners (i.e. to -not notify any more listeners). This can be accomplished from inside a -listener via the +from being called. In other words, the listener needs to be able to tell +the dispatcher to stop all propagation of the event to future listeners +(i.e. to not notify any more listeners). This can be accomplished from +inside a listener via the :method:`Symfony\\Component\\EventDispatcher\\Event::stopPropagation` method:: use Acme\StoreBundle\Event\FilterOrderEvent; @@ -471,12 +475,12 @@ listener via the $event->stopPropagation(); } -Now, any listeners to ``store.order`` that have not yet been called will *not* -be called. +Now, any listeners to ``store.order`` that have not yet been called will +*not* be called. It is possible to detect if an event was stopped by using the -:method:`Symfony\\Component\\EventDispatcher\\Event::isPropagationStopped` method -which returns a boolean value:: +:method:`Symfony\\Component\\EventDispatcher\\Event::isPropagationStopped` +method which returns a boolean value:: $dispatcher->dispatch('foo.event', $event); if ($event->isPropagationStopped()) { @@ -488,18 +492,18 @@ which returns a boolean value:: .. _event_dispatcher-dispatcher-aware-events: -EventDispatcher aware Events and Listeners +EventDispatcher Aware Events and Listeners ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``EventDispatcher`` always injects a reference to itself in the passed event -object. This means that all listeners have direct access to the +The ``EventDispatcher`` always injects a reference to itself in the passed +event object. This means that all listeners have direct access to the ``EventDispatcher`` object that notified the listener via the passed ``Event`` object's :method:`Symfony\\Component\\EventDispatcher\\Event::getDispatcher` method. This can lead to some advanced applications of the ``EventDispatcher`` including -letting listeners dispatch other events, event chaining or even lazy loading of -more listeners into the dispatcher object. Examples follow: +letting listeners dispatch other events, event chaining or even lazy loading +of more listeners into the dispatcher object. Examples follow: Lazy loading listeners:: @@ -570,8 +574,8 @@ Or setter injection:: } } -Choosing between the two is really a matter of taste. Many tend to prefer the -constructor injection as the objects are fully initialized at construction +Choosing between the two is really a matter of taste. Many tend to prefer +the constructor injection as the objects are fully initialized at construction time. But when you have a long list of dependencies, using setter injection can be the way to go, especially for optional dependencies. @@ -585,17 +589,17 @@ Dispatcher Shortcuts The :method:`EventDispatcher::dispatch ` method always returns an :class:`Symfony\\Component\\EventDispatcher\\Event` -object. This allows for various shortcuts. For example, if one does not need -a custom event object, one can simply rely on a plain -:class:`Symfony\\Component\\EventDispatcher\\Event` object. You do not even need -to pass this to the dispatcher as it will create one by default unless you -specifically pass one:: +object. This allows for various shortcuts. For example, if one does not +need a custom event object, one can simply rely on a plain +:class:`Symfony\\Component\\EventDispatcher\\Event` object. You do not even +need to pass this to the dispatcher as it will create one by default unless +you specifically pass one:: $dispatcher->dispatch('foo.event'); Moreover, the event dispatcher always returns whichever event object that -was dispatched, i.e. either the event that was passed or the event that was -created internally by the dispatcher. This allows for nice shortcuts:: +was dispatched, i.e. either the event that was passed or the event that +was created internally by the dispatcher. This allows for nice shortcuts:: if (!$dispatcher->dispatch('foo.event')->isPropagationStopped()) { // ... @@ -626,8 +630,8 @@ it, the event name is also injected into the to event listeners via the :method:`Symfony\\Component\\EventDispatcher\\Event::getName` method. -The event name, (as with any other data in a custom event object) can be used as -part of the listener's processing logic:: +The event name, (as with any other data in a custom event object) can be +used as part of the listener's processing logic:: use Symfony\Component\EventDispatcher\Event; @@ -642,8 +646,8 @@ part of the listener's processing logic:: Other Dispatchers ----------------- -Besides the commonly used ``EventDispatcher``, the component comes with 2 -other dispatchers: +Besides the commonly used ``EventDispatcher``, the component comes +with 2 other dispatchers: * :doc:`/components/event_dispatcher/container_aware_dispatcher` * :doc:`/components/event_dispatcher/immutable_dispatcher` diff --git a/components/event_dispatcher/traceable_dispatcher.rst b/components/event_dispatcher/traceable_dispatcher.rst index b9c3e79d4d4..70fad87bb03 100644 --- a/components/event_dispatcher/traceable_dispatcher.rst +++ b/components/event_dispatcher/traceable_dispatcher.rst @@ -42,8 +42,8 @@ to register event listeners and dispatch events:: After your application has been processed, you can use the :method:`Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface::getCalledListeners` -method to retrieve an array of event listeners that have been called in your -application. Similarly, the +method to retrieve an array of event listeners that have been called in +your application. Similarly, the :method:`Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface::getNotCalledListeners` method returns an array of event listeners that have not been called:: From 10e022d0a2b4558d62e8cdb3f7e3608581ed6e54 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 2 Jul 2015 21:51:47 +0200 Subject: [PATCH 06/15] some additional tweaks for the voter cookbook --- cookbook/security/voters.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cookbook/security/voters.rst b/cookbook/security/voters.rst index 59f40dbc48c..d0378d72507 100644 --- a/cookbook/security/voters.rst +++ b/cookbook/security/voters.rst @@ -105,8 +105,8 @@ edit a particular object. Here's an example implementation: break; case self::EDIT: - // we assume that our data object has a method getOwner() to - // get the current owner user entity for this data object + // this assumes that the data object has a getOwner() method + // to get the entity of the user who owns this data object if ($user->getId() === $post->getOwner()->getId()) { return true; } @@ -214,9 +214,7 @@ from the authorization checker is called. $authChecker = $this->get('security.authorization_checker'); - if (false === $authChecker->isGranted('view', $post)) { - throw $this->createAccessDeniedException('Unauthorized access!'); - } + $this->denyAccessUnlessGranted('view', $post, 'Unauthorized access!'); return new Response('

'.$post->getName().'

'); } From 966be4a6caa61cd9f9890336de8cb338dc3b1c5e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 19 Jun 2015 10:25:37 +0200 Subject: [PATCH 07/15] Fix doc about deprecations policy --- contributing/code/conventions.rst | 11 +++- cookbook/map.rst.inc | 1 - cookbook/upgrade/deprecation_warnings.rst | 74 ----------------------- cookbook/upgrade/index.rst | 1 - cookbook/upgrade/major_version.rst | 24 ++++++-- 5 files changed, 28 insertions(+), 83 deletions(-) delete mode 100644 cookbook/upgrade/deprecation_warnings.rst diff --git a/contributing/code/conventions.rst b/contributing/code/conventions.rst index e48eebd414e..4e698f5a182 100644 --- a/contributing/code/conventions.rst +++ b/contributing/code/conventions.rst @@ -92,7 +92,7 @@ A feature is marked as deprecated by adding a ``@deprecated`` phpdoc to relevant classes, methods, properties, ...:: /** - * @deprecated Deprecated since version 2.X, to be removed in 2.Y. Use XXX instead. + * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use XXX instead. */ The deprecation message should indicate the version when the class/method was @@ -103,4 +103,11 @@ A PHP ``E_USER_DEPRECATED`` error must also be triggered to help people with the migration starting one or two minor versions before the version where the feature will be removed (depending on the criticality of the removal):: - trigger_error('XXX() is deprecated since version 2.X and will be removed in 2.Y. Use XXX instead.', E_USER_DEPRECATED); + @trigger_error('XXX() is deprecated since version 2.8 and will be removed in 3.0. Use XXX instead.', E_USER_DEPRECATED); + +Without the `@-silencing operator`_, users would need to opt-out from deprecation +notices. Silencing swaps this behavior and allows users to opt-in when they are +ready to cope with them (by adding a custom error handler like the one used by +the Web Debug Toolbar or by the PHPUnit bridge). + +.. _`@-silencing operator`: https://php.net/manual/en/language.operators.errorcontrol.php diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 691c9a71d73..4316f0de726 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -224,7 +224,6 @@ * :doc:`/cookbook/upgrade/patch_version` * :doc:`/cookbook/upgrade/minor_version` * :doc:`/cookbook/upgrade/major_version` - * :doc:`/cookbook/upgrade/deprecation_warnings` * :doc:`/cookbook/validation/index` diff --git a/cookbook/upgrade/deprecation_warnings.rst b/cookbook/upgrade/deprecation_warnings.rst deleted file mode 100644 index 12e6c21c7e9..00000000000 --- a/cookbook/upgrade/deprecation_warnings.rst +++ /dev/null @@ -1,74 +0,0 @@ -What do these "XXX is deprecated " E_USER_DEPRECATED Warnings mean? -=================================================================== - -Starting in Symfony 2.7, if you use a deprecated class, function or option, -Symfony triggers an ``E_USER_DEPRECATED`` error. Internally, that looks something -like this:: - - trigger_error( - 'The fooABC method is deprecated since version 2.4 and will be removed in 3.0.', - E_USER_DEPRECATED - ); - -This is great, because you can check your logs to know what needs to change -before you upgrade. In the Symfony Framework, the number of deprecated calls -shows up in the web debug toolbar. And if you install the `phpunit-bridge`_, -you can get a report of deprecated calls after running your tests. - -How can I Silence the Warnings? -------------------------------- - -As useful as these are, you don't want them to show up while developing and -you may also want to silence them on production to avoid filling up your -error logs. - -In the Symfony Framework -~~~~~~~~~~~~~~~~~~~~~~~~ - -In the Symfony Framework, ``~E_USER_DEPRECATED`` is added to ``app/bootstrap.php.cache`` -automatically, but you need at least version 2.3.14 or 3.0.21 of the -`SensioDistributionBundle`_. So, you may need to upgrade: - -.. code-block:: bash - - $ composer update sensio/distribution-bundle - -Once you've updated, the ``bootstrap.php.cache`` file is rebuilt automatically. -At the top, you should see a line adding ``~E_USER_DEPRECATED``. - -Outside of the Symfony Framework -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To do that, add ``~E_USER_DEPRECATED`` to your ``error_reporting`` -setting in ``php.ini``: - -.. code-block:: ini - - ; before - error_reporting = E_ALL - ; after - error_reporting = E_ALL & ~E_USER_DEPRECATED - -Alternatively, you can set this directly in bootstrap of your project:: - - error_reporting(error_reporting() & ~E_USER_DEPRECATED); - -How can I Fix the Warnings? ---------------------------- - -Of course ultimately, you want to stop using the deprecated functionality. -Sometimes, this is easy: the warning might tell you exactly what to change. - -But other times, the warning might be unclear: a setting somewhere might -cause a class deeper to trigger the warning. In this case, Symfony does its -best to give a clear message, but you may need to research that warning further. - -And sometimes, the warning may come from a third-party library or bundle -that you're using. If that's true, there's a good chance that those deprecations -have already been updated. In that case, upgrade the library to fix them. - -Once all the deprecation warnings are gone, you can upgrade with a lot -more confidence. - -.. _`phpunit-bridge`: https://github.com/symfony/phpunit-bridge -.. _`SensioDistributionBundle`: https://github.com/sensiolabs/SensioDistributionBundle diff --git a/cookbook/upgrade/index.rst b/cookbook/upgrade/index.rst index 3a37aa78a61..b943f2ae32a 100644 --- a/cookbook/upgrade/index.rst +++ b/cookbook/upgrade/index.rst @@ -16,4 +16,3 @@ There are three types of upgrades, all needing a little different preparation: /cookbook/upgrade/patch_version /cookbook/upgrade/minor_version /cookbook/upgrade/major_version - /cookbook/upgrade/deprecation_warnings diff --git a/cookbook/upgrade/major_version.rst b/cookbook/upgrade/major_version.rst index 0c5107b6fed..8ff9ff51f6b 100644 --- a/cookbook/upgrade/major_version.rst +++ b/cookbook/upgrade/major_version.rst @@ -26,7 +26,7 @@ There are a couple of steps to upgrading a major version: During the lifecycle of a major release, new features are added and method signatures and public API usages are changed. However, :doc:`minor versions ` should not contain any -backwards compatibility changes. To accomplish this, the "old" (e.g. functions, +backwards incompatible changes. To accomplish this, the "old" (e.g. functions, classes, etc) code still works, but is marked as *deprecated*, indicating that it will be removed/changed in the future and that you should stop using it. @@ -35,13 +35,27 @@ functionality are removed. So, as long as you've updated your code to stop using these deprecated features in the last version before the major (e.g. 2.8.*), you should be able to upgrade without a problem. -To help you with this, the last minor releases will trigger deprecated notices. -For example, 2.7 and 2.8 trigger deprecated notices. When visiting your -application in the :doc:`dev environment ` +To help you with this, deprecation notices are triggered whenever you end up +using a deprecated feature. When visiting your application in the +:doc:`dev environment ` in your browser, these notices are shown in the web dev toolbar: .. image:: /images/cookbook/deprecations-in-profiler.png +Of course ultimately, you want to stop using the deprecated functionality. +Sometimes, this is easy: the warning might tell you exactly what to change. + +But other times, the warning might be unclear: a setting somewhere might +cause a class deeper to trigger the warning. In this case, Symfony does its +best to give a clear message, but you may need to research that warning further. + +And sometimes, the warning may come from a third-party library or bundle +that you're using. If that's true, there's a good chance that those deprecations +have already been updated. In that case, upgrade the library to fix them. + +Once all the deprecation warnings are gone, you can upgrade with a lot +more confidence. + Deprecations in PHPUnit ~~~~~~~~~~~~~~~~~~~~~~~ @@ -52,7 +66,7 @@ To make sure this doesn't happen, you can install the PHPUnit bridge: .. code-block:: bash - $ composer require symfony/phpunit-bridge + $ composer require --dev symfony/phpunit-bridge Now, your tests execute normally and a nice summary of the deprecation notices is displayed at the end of the test report: From a6e9a10873eca5e97a77abab95622aa58e304787 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Thu, 23 Jul 2015 16:27:20 -0300 Subject: [PATCH 08/15] [2.3] [Contributing] Added note about empty returns | Q | A | ------------- | --- | Doc fix? | no | New docs? | no | Applies to | | Fixed tickets | --- contributing/code/standards.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst index 2168129d7fa..97491888bc8 100644 --- a/contributing/code/standards.rst +++ b/contributing/code/standards.rst @@ -112,6 +112,9 @@ Structure * Add a blank line before ``return`` statements, unless the return is alone inside a statement-group (like an ``if`` statement); +* Use just ``return;`` instead of ``return null;`` when a function must return void + early; + * Use braces to indicate control structure body regardless of the number of statements it contains; From 39b054278c9f02a57164331378202ade79c3b255 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 25 Jul 2015 11:00:33 +0200 Subject: [PATCH 09/15] fix max line length --- contributing/code/standards.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst index 97491888bc8..7d6d9f09987 100644 --- a/contributing/code/standards.rst +++ b/contributing/code/standards.rst @@ -112,8 +112,8 @@ Structure * Add a blank line before ``return`` statements, unless the return is alone inside a statement-group (like an ``if`` statement); -* Use just ``return;`` instead of ``return null;`` when a function must return void - early; +* Use just ``return;`` instead of ``return null;`` when a function must return + void early; * Use braces to indicate control structure body regardless of the number of statements it contains; From bc880d09d7e31b15f8f9386ef9a6e8413caf5546 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 19 Jul 2015 14:45:32 +0200 Subject: [PATCH 10/15] add missing versionadded directive --- cookbook/email/email.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cookbook/email/email.rst b/cookbook/email/email.rst index 361ada048ce..6b205fb5770 100644 --- a/cookbook/email/email.rst +++ b/cookbook/email/email.rst @@ -138,6 +138,11 @@ template might look something like this: {# Makes an absolute URL to the /images/logo.png file #} Date: Tue, 28 Jul 2015 12:55:20 +0100 Subject: [PATCH 11/15] Change Sql Field name because it's reserved --- book/from_flat_php_to_symfony2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/from_flat_php_to_symfony2.rst b/book/from_flat_php_to_symfony2.rst index 5938ec8323a..67c39c5a0e1 100644 --- a/book/from_flat_php_to_symfony2.rst +++ b/book/from_flat_php_to_symfony2.rst @@ -266,7 +266,7 @@ an individual blog result based on a given id:: $link = open_database_connection(); $id = intval($id); - $query = 'SELECT date, title, body FROM post WHERE id = '.$id; + $query = 'SELECT created_date, title, body FROM post WHERE id = '.$id; $result = mysql_query($query); $row = mysql_fetch_assoc($result); @@ -297,7 +297,7 @@ the individual blog post:

-
+
From a9d75c69453b817170c2f9465028105bd0e9c848 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 15 Jul 2015 20:20:06 +0900 Subject: [PATCH 12/15] Fix code --- create_framework/templating.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/create_framework/templating.rst b/create_framework/templating.rst index 43e77f92623..987a9ea26d1 100644 --- a/create_framework/templating.rst +++ b/create_framework/templating.rst @@ -41,7 +41,7 @@ rendered:: function render_template($request) { - extract($request->attributes->all(), EXTR_SKIP); + extract($request->attributes->all()); ob_start(); include sprintf(__DIR__.'/../src/pages/%s.php', $_route); @@ -110,7 +110,7 @@ Here is the updated and improved version of our framework:: function render_template($request) { - extract($request->attributes->all(), EXTR_SKIP); + extract($request->attributes->all()); ob_start(); include sprintf(__DIR__.'/../src/pages/%s.php', $_route); From 0134123dd5c54452a5365321fc60c1533454b0ea Mon Sep 17 00:00:00 2001 From: WouterJ Date: Tue, 28 Jul 2015 16:19:16 +0200 Subject: [PATCH 13/15] [#5567] Renamed `created_date` to `created_at` This seems to be more common. --- book/from_flat_php_to_symfony2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/from_flat_php_to_symfony2.rst b/book/from_flat_php_to_symfony2.rst index 67c39c5a0e1..382a656dab9 100644 --- a/book/from_flat_php_to_symfony2.rst +++ b/book/from_flat_php_to_symfony2.rst @@ -266,7 +266,7 @@ an individual blog result based on a given id:: $link = open_database_connection(); $id = intval($id); - $query = 'SELECT created_date, title, body FROM post WHERE id = '.$id; + $query = 'SELECT created_at, title, body FROM post WHERE id = '.$id; $result = mysql_query($query); $row = mysql_fetch_assoc($result); @@ -297,7 +297,7 @@ the individual blog post:

-
+
From 43e06c30050f94e059b5b15fba8dc865672ede77 Mon Sep 17 00:00:00 2001 From: Nicolas Dewez Date: Thu, 23 Jul 2015 13:53:47 +0200 Subject: [PATCH 14/15] Fix typo Esi in part create framework --- create_framework/http-kernel-httpkernelinterface.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/create_framework/http-kernel-httpkernelinterface.rst b/create_framework/http-kernel-httpkernelinterface.rst index e0a07731e36..6f8d6a8e994 100644 --- a/create_framework/http-kernel-httpkernelinterface.rst +++ b/create_framework/http-kernel-httpkernelinterface.rst @@ -153,7 +153,7 @@ sub-requests to convert them to their proper content:: $framework = new HttpKernel\HttpCache\HttpCache( $framework, new HttpKernel\HttpCache\Store(__DIR__.'/../cache'), - new HttpKernel\HttpCache\ESI() + new HttpKernel\HttpCache\Esi() ); .. note:: @@ -166,7 +166,7 @@ When using complex HTTP caching strategies and/or many ESI include tags, it can be hard to understand why and when a resource should be cached or not. To ease debugging, you can enable the debug mode:: - $framework = new HttpCache($framework, new Store(__DIR__.'/../cache'), new ESI(), array('debug' => true)); + $framework = new HttpCache($framework, new Store(__DIR__.'/../cache'), new Esi(), array('debug' => true)); The debug mode adds a ``X-Symfony-Cache`` header to each response that describes what the cache layer did: From 0d283069a5a5b3f3c496d9fee133fae36510144a Mon Sep 17 00:00:00 2001 From: WouterJ Date: Tue, 28 Jul 2015 17:07:04 +0200 Subject: [PATCH 15/15] Fixed issues discovered by the human reviewers --- components/class_loader/class_loader.rst | 6 +++--- components/config/resources.rst | 5 ++--- components/dependency_injection/compilation.rst | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/components/class_loader/class_loader.rst b/components/class_loader/class_loader.rst index 26be9882909..9e477795c10 100644 --- a/components/class_loader/class_loader.rst +++ b/components/class_loader/class_loader.rst @@ -42,9 +42,9 @@ is straightforward:: The autoloader is automatically registered in a Symfony application (see ``app/autoload.php``). -Use the :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefix` -or :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefixes` methods -to register your classes:: +Use :method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefix` or +:method:`Symfony\\Component\\ClassLoader\\ClassLoader::addPrefixes` to register +your classes:: // register a single namespaces $loader->addPrefix('Symfony', __DIR__.'/vendor/symfony/symfony/src'); diff --git a/components/config/resources.rst b/components/config/resources.rst index a7905e0747d..97924703158 100644 --- a/components/config/resources.rst +++ b/components/config/resources.rst @@ -14,9 +14,8 @@ Loading Resources Locating Resources ------------------ -Loading the configuration normally starts with a search for resources – -in most cases: files. This can be done with the -:class:`Symfony\\Component\\Config\\FileLocator`:: +Loading the configuration normally starts with a search for resources, mostly +files. This can be done with the :class:`Symfony\\Component\\Config\\FileLocator`:: use Symfony\Component\Config\FileLocator; diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index 68ef2693883..388815f3b6c 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -99,7 +99,7 @@ The Extension must specify a ``getAlias`` method to implement the interface:: } } -For YAML configuration files specifying the alias for the Extension as a +For YAML configuration files specifying the alias for the extension as a key will mean that those values are passed to the Extension's ``load`` method: .. code-block:: yaml