diff --git a/book/doctrine.rst b/book/doctrine.rst index 880bff8a54f..ad681d971a4 100644 --- a/book/doctrine.rst +++ b/book/doctrine.rst @@ -413,12 +413,12 @@ doesn't replace your existing methods). With the ``doctrine:generate:entities`` command you can: - * generate getters and setters; + * generate getters and setters; - * generate repository classes configured with the - ``@ORM\Entity(repositoryClass="...")`` annotation; + * generate repository classes configured with the + ``@ORM\Entity(repositoryClass="...")`` annotation; - * generate the appropriate constructor for 1:n and n:m relations. + * generate the appropriate constructor for 1:n and n:m relations. The ``doctrine:generate:entities`` command saves a backup of the original ``Product.php`` named ``Product.php~``. In some cases, the presence of @@ -631,7 +631,7 @@ Once you have your repository, you have access to all sorts of helpful methods:: You can also take advantage of the useful ``findBy`` and ``findOneBy`` methods to easily fetch objects based on multiple conditions:: - // query for one product matching be name and price + // query for one product matching by name and price $product = $repository->findOneBy( array('name' => 'foo', 'price' => 19.99) ); diff --git a/book/http_cache.rst b/book/http_cache.rst index ce99c7f6669..e584751df70 100644 --- a/book/http_cache.rst +++ b/book/http_cache.rst @@ -1034,7 +1034,7 @@ Cache Invalidation ------------------ "There are only two hard things in Computer Science: cache invalidation - and naming things." --Phil Karlton + and naming things." -- Phil Karlton You should never need to invalidate cached data because invalidation is already taken into account natively in the HTTP cache models. If you use validation, diff --git a/book/security.rst b/book/security.rst index fe7296c36e1..fb0f7884dfb 100644 --- a/book/security.rst +++ b/book/security.rst @@ -854,8 +854,8 @@ if ``ip``, ``host`` or ``method`` are not specified for an entry, that ``access_ will match any ``ip``, ``host`` or ``method``: +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+ -| **URI** | **IP** | **HOST** | **METHOD** | ``access_control`` | Why? | -+-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+ +| URI | IP | HOST | METHOD | ``access_control`` | Why? | ++=================+=============+=============+============+================================+=============================================================+ | ``/admin/user`` | 127.0.0.1 | example.com | GET | rule #1 (``ROLE_USER_IP``) | The URI matches ``path`` and the IP matches ``ip``. | +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+ | ``/admin/user`` | 127.0.0.1 | symfony.com | GET | rule #1 (``ROLE_USER_IP``) | The ``path`` and ``ip`` still match. This would also match | diff --git a/book/templating.rst b/book/templating.rst index 545e1c24531..cfc6a1414e8 100644 --- a/book/templating.rst +++ b/book/templating.rst @@ -75,7 +75,7 @@ to web designers and, in several ways, more powerful than PHP templates: -Twig defines two types of special syntax: +Twig defines three types of special syntax: * ``{{ ... }}``: "Says something": prints a variable or the result of an expression to the template; @@ -83,11 +83,9 @@ Twig defines two types of special syntax: * ``{% ... %}``: "Does something": a **tag** that controls the logic of the template; it is used to execute statements such as for-loops for example. -.. note:: - - There is a third syntax used for creating comments: ``{# this is a comment #}``. - This syntax can be used across multiple lines like the PHP-equivalent - ``/* comment */`` syntax. +* ``{# ... #}``: "Comment something": it's the equivalent of the PHP + ``/* comment */`` syntax. It's used to add single or multi-line comments. + The content of the comments isn't included in the rendered pages. Twig also contains **filters**, which modify content before being rendered. The following makes the ``title`` variable all uppercase before rendering @@ -394,14 +392,14 @@ lives in a specific location: template for a specific page. The three parts of the string, each separated by a colon (``:``), mean the following: - * ``AcmeBlogBundle``: (*bundle*) the template lives inside the - ``AcmeBlogBundle`` (e.g. ``src/Acme/BlogBundle``); + * ``AcmeBlogBundle``: (*bundle*) the template lives inside the + ``AcmeBlogBundle`` (e.g. ``src/Acme/BlogBundle``); - * ``Blog``: (*controller*) indicates that the template lives inside the - ``Blog`` subdirectory of ``Resources/views``; + * ``Blog``: (*controller*) indicates that the template lives inside the + ``Blog`` subdirectory of ``Resources/views``; - * ``index.html.twig``: (*template*) the actual name of the file is - ``index.html.twig``. + * ``index.html.twig``: (*template*) the actual name of the file is + ``index.html.twig``. Assuming that the ``AcmeBlogBundle`` lives at ``src/Acme/BlogBundle``, the final path to the layout would be ``src/Acme/BlogBundle/Resources/views/Blog/index.html.twig``. diff --git a/components/config/introduction.rst b/components/config/introduction.rst index 89eb4beaec9..11dae2e1d78 100644 --- a/components/config/introduction.rst +++ b/components/config/introduction.rst @@ -5,12 +5,9 @@ The Config Component ==================== -Introduction ------------- - -The Config component provides several classes to help you find, load, combine, -autofill and validate configuration values of any kind, whatever their source -may be (YAML, XML, INI files, or for instance a database). + The Config component provides several classes to help you find, load, + combine, autofill and validate configuration values of any kind, whatever + their source may be (YAML, XML, INI files, or for instance a database). .. caution:: diff --git a/components/css_selector.rst b/components/css_selector.rst index 412aed84e97..b62c58d94a3 100644 --- a/components/css_selector.rst +++ b/components/css_selector.rst @@ -55,7 +55,7 @@ This gives the following output: .. code-block:: text - descendant-or-self::div[contains(concat(' ',normalize-space(@class), ' '), ' item ')]/h4/a + descendant-or-self::div[@class and contains(concat(' ',normalize-space(@class), ' '), ' item ')]/h4/a You can use this expression with, for instance, :phpclass:`DOMXPath` or :phpclass:`SimpleXMLElement` to find elements in a document. @@ -76,8 +76,8 @@ web-browser. * link-state selectors: ``:link``, ``:visited``, ``:target`` * selectors based on user action: ``:hover``, ``:focus``, ``:active`` -* UI-state selectors: ``:enabled``, ``:disabled``, ``:indeterminate`` - (however, ``:checked`` and ``:unchecked`` are available) +* UI-state selectors: ``:invalid``, ``:indeterminate`` (however, ``:enabled``, + ``:disabled``, ``:checked`` and ``:unchecked`` are available) Pseudo-elements (``:before``, ``:after``, ``:first-line``, ``:first-letter``) are not supported because they select portions of text @@ -85,8 +85,6 @@ rather than elements. Several pseudo-classes are not yet supported: -* ``:lang(language)`` -* ``root`` * ``*:first-of-type``, ``*:last-of-type``, ``*:nth-of-type``, ``*:nth-last-of-type``, ``*:only-of-type``. (These work with an element name (e.g. ``li:first-of-type``) but not with ``*``. diff --git a/components/event_dispatcher/introduction.rst b/components/event_dispatcher/introduction.rst index 78cb703f5ac..98fb6c59d0c 100644 --- a/components/event_dispatcher/introduction.rst +++ b/components/event_dispatcher/introduction.rst @@ -5,6 +5,10 @@ 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. + Introduction ------------ diff --git a/components/form/form_events.rst b/components/form/form_events.rst index 1b81360f529..5a8ad2b6cf7 100644 --- a/components/form/form_events.rst +++ b/components/form/form_events.rst @@ -62,8 +62,8 @@ The ``FormEvents::PRE_SET_DATA`` event is dispatched at the beginning of the :ref:`Form Events Information Table` +-----------------+-----------+ -| **Data type** | **Value** | -+-----------------+-----------+ +| Data type | Value | ++=================+===========+ | Model data | ``null`` | +-----------------+-----------+ | Normalized data | ``null`` | @@ -99,8 +99,8 @@ the form. :ref:`Form Events Information Table` +-----------------+------------------------------------------------------+ -| **Data type** | **Value** | -+-----------------+------------------------------------------------------+ +| Data type | Value | ++=================+======================================================+ | Model data | Model data injected into ``setData()`` | +-----------------+------------------------------------------------------+ | Normalized data | Model data transformed using a model transformer | @@ -110,6 +110,9 @@ the form. .. sidebar:: ``FormEvents::POST_SET_DATA`` in the Form component + .. versionadded:: 2.4 + The data collector extension was introduced in Symfony 2.4. + The :class:`Symfony\\Component\\Form\\Extension\\DataCollector\\EventListener\\DataCollectorListener` class is subscribed to listen to the ``FormEvents::POST_SET_DATA`` event in order to collect information about the forms from the denormalized @@ -141,8 +144,8 @@ It can be used to: :ref:`Form Events Information Table` +-----------------+------------------------------------------+ -| **Data type** | **Value** | -+-----------------+------------------------------------------+ +| Data type | Value | ++=================+==========================================+ | Model data | Same as in ``FormEvents::POST_SET_DATA`` | +-----------------+------------------------------------------+ | Normalized data | Same as in ``FormEvents::POST_SET_DATA`` | @@ -171,8 +174,8 @@ It can be used to change data from the normalized representation of the data. :ref:`Form Events Information Table` +-----------------+-------------------------------------------------------------------------------------+ -| **Data type** | **Value** | -+-----------------+-------------------------------------------------------------------------------------+ +| Data type | Value | ++=================+=====================================================================================+ | Model data | Same as in ``FormEvents::POST_SET_DATA`` | +-----------------+-------------------------------------------------------------------------------------+ | Normalized data | Data from the request reverse-transformed from the request using a view transformer | @@ -203,8 +206,8 @@ It can be used to fetch data after denormalization. :ref:`Form Events Information Table` +-----------------+---------------------------------------------------------------+ -| **Data type** | **Value** | -+-----------------+---------------------------------------------------------------+ +| Data type | Value | ++=================+===============================================================+ | Model data | Normalized data reverse-transformed using a model transformer | +-----------------+---------------------------------------------------------------+ | Normalized data | Same as in ``FormEvents::POST_SUBMIT`` | @@ -218,6 +221,9 @@ It can be used to fetch data after denormalization. .. sidebar:: ``FormEvents::POST_SUBMIT`` in the Form component + .. versionadded:: 2.4 + The data collector extension was introduced in Symfony 2.4. + The :class:`Symfony\\Component\\Form\\Extension\\DataCollector\\EventListener\\DataCollectorListener` subscribes to the ``FormEvents::POST_SUBMIT`` event in order to collect information about the forms. @@ -242,19 +248,19 @@ processed. .. _component-form-event-table: -+--------------------+-------------------------------+------------------+ -| **Name** | ``FormEvents`` **Constant** | **Event's data** | -+--------------------+-------------------------------+------------------+ -| form.pre_set_data | ``FormEvents::PRE_SET_DATA`` | Model data | -+--------------------+-------------------------------+------------------+ -| form.post_set_data | ``FormEvents::POST_SET_DATA`` | Model data | -+--------------------+-------------------------------+------------------+ -| form.pre_bind | ``FormEvents::PRE_SUBMIT`` | Request data | -+--------------------+-------------------------------+------------------+ -| form.bind | ``FormEvents::SUBMIT`` | Normalized data | -+--------------------+-------------------------------+------------------+ -| form.post_bind | ``FormEvents::POST_SUBMIT`` | View data | -+--------------------+-------------------------------+------------------+ ++------------------------+-------------------------------+------------------+ +| Name | ``FormEvents`` Constant | Event's data | ++========================+===============================+==================+ +| ``form.pre_set_data`` | ``FormEvents::PRE_SET_DATA`` | Model data | ++------------------------+-------------------------------+------------------+ +| ``form.post_set_data`` | ``FormEvents::POST_SET_DATA`` | Model data | ++------------------------+-------------------------------+------------------+ +| ``form.pre_bind`` | ``FormEvents::PRE_SUBMIT`` | Request data | ++------------------------+-------------------------------+------------------+ +| ``form.bind`` | ``FormEvents::SUBMIT`` | Normalized data | ++------------------------+-------------------------------+------------------+ +| ``form.post_bind`` | ``FormEvents::POST_SUBMIT`` | View data | ++------------------------+-------------------------------+------------------+ .. versionadded:: 2.3 diff --git a/components/http_foundation/session_configuration.rst b/components/http_foundation/session_configuration.rst index bcd992128eb..f392c5272cf 100644 --- a/components/http_foundation/session_configuration.rst +++ b/components/http_foundation/session_configuration.rst @@ -37,7 +37,7 @@ activate these in the same way as it does for custom handlers. Symfony2 provides drivers for the following native save handler as an example: - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler` Example usage:: @@ -71,11 +71,11 @@ various points in the session workflow. Symfony2 HttpFoundation provides some by default and these can easily serve as examples if you wish to write your own. - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler` - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler` - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler` - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler` - * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler` +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler` Example usage:: diff --git a/components/http_kernel/introduction.rst b/components/http_kernel/introduction.rst index ddf53125063..4128ef85ee2 100644 --- a/components/http_kernel/introduction.rst +++ b/components/http_kernel/introduction.rst @@ -242,22 +242,22 @@ will be called after another event - ``kernel.controller`` - is dispatched. This string is then transformed into a PHP callable by doing the following: a) The ``AcmeDemoBundle:Default:index`` format of the ``_controller`` key - is changed to another string that contains the full class and method - name of the controller by following the convention used in Symfony2 - e.g. - ``Acme\DemoBundle\Controller\DefaultController::indexAction``. This transformation - is specific to the :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver` - sub-class used by the Symfony2 Framework. + is changed to another string that contains the full class and method + name of the controller by following the convention used in Symfony2 - e.g. + ``Acme\DemoBundle\Controller\DefaultController::indexAction``. This transformation + is specific to the :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver` + sub-class used by the Symfony2 Framework. b) A new instance of your controller class is instantiated with no - constructor arguments. + constructor arguments. c) If the controller implements :class:`Symfony\\Component\\DependencyInjection\\ContainerAwareInterface`, - ``setContainer`` is called on the controller object and the container - is passed to it. This step is also specific to the :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver` - sub-class used by the Symfony2 Framework. + ``setContainer`` is called on the controller object and the container + is passed to it. This step is also specific to the :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver` + sub-class used by the Symfony2 Framework. - There are also a few other variations on the above process (e.g. if - you're registering your controllers as services). + There are also a few other variations on the above process (e.g. if + you're registering your controllers as services). .. _component-http-kernel-kernel-controller: @@ -325,14 +325,14 @@ of arguments that should be passed when executing that callable. to determine which value should be passed for each argument: a) If the ``Request`` attributes bag contains a key that matches the name - of the argument, that value is used. For example, if the first argument - to a controller is ``$slug``, and there is a ``slug`` key in the ``Request`` - ``attributes`` bag, that value is used (and typically this value came - from the ``RouterListener``). + of the argument, that value is used. For example, if the first argument + to a controller is ``$slug``, and there is a ``slug`` key in the ``Request`` + ``attributes`` bag, that value is used (and typically this value came + from the ``RouterListener``). b) If the argument in the controller is type-hinted with Symfony's - :class:`Symfony\\Component\\HttpFoundation\\Request` object, then the - ``Request`` is passed in as the value. + :class:`Symfony\\Component\\HttpFoundation\\Request` object, then the + ``Request`` is passed in as the value. .. _component-http-kernel-calling-controller: @@ -528,20 +528,20 @@ below for more details). The listener has several goals: 1) The thrown exception is converted into a - :class:`Symfony\\Component\\HttpKernel\\Exception\\FlattenException` - object, which contains all the information about the request, but which - can be printed and serialized. + :class:`Symfony\\Component\\HttpKernel\\Exception\\FlattenException` + object, which contains all the information about the request, but which + can be printed and serialized. 2) If the original exception implements - :class:`Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface`, - then ``getStatusCode`` and ``getHeaders`` are called on the exception - and used to populate the headers and status code of the ``FlattenException`` - object. The idea is that these are used in the next step when creating - the final response. + :class:`Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface`, + then ``getStatusCode`` and ``getHeaders`` are called on the exception + and used to populate the headers and status code of the ``FlattenException`` + object. The idea is that these are used in the next step when creating + the final response. 3) A controller is executed and passed the flattened exception. The exact - controller to render is passed as a constructor argument to this listener. - This controller will return the final ``Response`` for this error page. + controller to render is passed as a constructor argument to this listener. + This controller will return the final ``Response`` for this error page. **ExceptionListener in Security** @@ -570,7 +570,7 @@ each event has their own event object: .. _component-http-kernel-event-table: +-----------------------+----------------------------------+-------------------------------------------------------------------------------------+ -| **Name** | ``KernelEvents`` **Constant** | **Argument passed to the listener** | +| Name | ``KernelEvents`` Constant | Argument passed to the listener | +-----------------------+----------------------------------+-------------------------------------------------------------------------------------+ | kernel.request | ``KernelEvents::REQUEST`` | :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent` | +-----------------------+----------------------------------+-------------------------------------------------------------------------------------+ @@ -660,7 +660,7 @@ argument as follows:: // create some other request manually as needed $request = new Request(); // for example, possibly set its _controller manually - $request->attributes->add('_controller', '...'); + $request->attributes->set('_controller', '...'); $response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST); // do something with this response diff --git a/components/routing/hostname_pattern.rst b/components/routing/hostname_pattern.rst index fb72abae257..b97fe30bb04 100644 --- a/components/routing/hostname_pattern.rst +++ b/components/routing/hostname_pattern.rst @@ -173,17 +173,11 @@ instance, if you want to match both ``m.example.com`` and return $collection; -.. sidebar:: Using Service Parameters +.. tip:: You can also use service parameters if you do not want to hardcode the hostname: - .. tip:: - - Make sure you also include a default option for the ``domain`` placeholder, - otherwise you need to include a domain value each time you generate - a URL using the route. - .. configuration-block:: .. code-block:: yaml @@ -209,9 +203,9 @@ instance, if you want to match both ``m.example.com`` and xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + AcmeDemoBundle:Main:mobileHomepage - %domain% + %domain% %domain% @@ -239,6 +233,12 @@ instance, if you want to match both ``m.example.com`` and return $collection; +.. tip:: + + Make sure you also include a default option for the ``domain`` placeholder, + otherwise you need to include a domain value each time you generate + a URL using the route. + .. _component-routing-host-imported: Using Host Matching of Imported Routes @@ -286,12 +286,12 @@ Testing your Controllers You need to set the Host HTTP header on your request objects if you want to get past url matching in your functional tests. - .. code-block:: php +.. code-block:: php - $crawler = $client->request( - 'GET', - '/homepage', - array(), - array(), - array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')) - ); + $crawler = $client->request( + 'GET', + '/homepage', + array(), + array(), + array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')) + ); diff --git a/components/security/introduction.rst b/components/security/introduction.rst index 09c19f5f99f..7d0cec88d74 100644 --- a/components/security/introduction.rst +++ b/components/security/introduction.rst @@ -4,15 +4,12 @@ The Security Component ====================== -Introduction ------------- - -The Security component provides a complete security system for your web -application. It ships with facilities for authenticating using HTTP basic -or digest authentication, interactive form login or X.509 certificate login, -but also allows you to implement your own authentication strategies. -Furthermore, the component provides ways to authorize authenticated users -based on their roles, and it contains an advanced ACL system. + The Security component provides a complete security system for your web + application. It ships with facilities for authenticating using HTTP basic + or digest authentication, interactive form login or X.509 certificate + login, but also allows you to implement your own authentication strategies. + Furthermore, the component provides ways to authorize authenticated users + based on their roles, and it contains an advanced ACL system. Installation ------------ diff --git a/components/stopwatch.rst b/components/stopwatch.rst index 762d26ff902..58c76b85cff 100644 --- a/components/stopwatch.rst +++ b/components/stopwatch.rst @@ -5,7 +5,7 @@ The Stopwatch Component ======================= - Stopwatch component provides a way to profile code. + The Stopwatch component provides a way to profile code. Installation ------------ diff --git a/contributing/code/patches.rst b/contributing/code/patches.rst index aa9037d2c56..1967c8dc0f0 100644 --- a/contributing/code/patches.rst +++ b/contributing/code/patches.rst @@ -310,23 +310,23 @@ translation files, use the shorter version of the check-list: Some answers to the questions trigger some more requirements: - * If you answer yes to "Bug fix?", check if the bug is already listed in the - Symfony issues and reference it/them in "Fixed tickets"; +* If you answer yes to "Bug fix?", check if the bug is already listed in the + Symfony issues and reference it/them in "Fixed tickets"; - * If you answer yes to "New feature?", you must submit a pull request to the - documentation and reference it under the "Doc PR" section; +* If you answer yes to "New feature?", you must submit a pull request to the + documentation and reference it under the "Doc PR" section; - * If you answer yes to "BC breaks?", the patch must contain updates to the - relevant ``CHANGELOG`` and ``UPGRADE`` files; +* If you answer yes to "BC breaks?", the patch must contain updates to the + relevant ``CHANGELOG`` and ``UPGRADE`` files; - * If you answer yes to "Deprecations?", the patch must contain updates to the - relevant ``CHANGELOG`` and ``UPGRADE`` files; +* If you answer yes to "Deprecations?", the patch must contain updates to the + relevant ``CHANGELOG`` and ``UPGRADE`` files; - * If you answer no to "Tests pass", you must add an item to a todo-list with - the actions that must be done to fix the tests; +* If you answer no to "Tests pass", you must add an item to a todo-list with + the actions that must be done to fix the tests; - * If the "license" is not MIT, just don't submit the pull request as it won't - be accepted anyway. +* If the "license" is not MIT, just don't submit the pull request as it won't + be accepted anyway. If some of the previous requirements are not met, create a todo-list and add relevant items: diff --git a/contributing/documentation/standards.rst b/contributing/documentation/standards.rst index 76003a2acfe..6e702c09bcf 100644 --- a/contributing/documentation/standards.rst +++ b/contributing/documentation/standards.rst @@ -81,6 +81,23 @@ Configuration examples should show all supported formats using * **Validation**: YAML, Annotations, XML, PHP * **Doctrine Mapping**: Annotations, YAML, XML, PHP +Files and Directories +~~~~~~~~~~~~~~~~~~~~~ + +* When referencing directories, always add a trailing slash to avoid confusions + with regular files (e.g. *"execute the ``console`` script located at the ``app/`` + directory"*). +* When referencing file extensions explicitly, you should include a leading dot + for every extension (e.g. "*XML files use the ``.xml`` extension*"). +* When you list a Symfony file/directory hierarchy, use ``your-project/`` as the + top level directory. E.g. + + your-project/ + ├─ app/ + ├─ src/ + ├─ vendor/ + └─ ... + Example ~~~~~~~ @@ -128,11 +145,11 @@ Language Standards * When referencing a hypothetical person, such as "a user with a session cookie", gender-neutral pronouns (they/their/them) should be used. For example, instead of: - * he or she, use they - * him or her, use them - * his or her, use their - * his or hers, use theirs - * himself or herself, use themselves + * he or she, use they + * him or her, use them + * his or her, use their + * his or hers, use theirs + * himself or herself, use themselves .. _`the Sphinx documentation`: http://sphinx-doc.org/rest.html#source-code .. _`Twig Coding Standards`: http://twig.sensiolabs.org/doc/coding_standards.html diff --git a/cookbook/configuration/environments.rst b/cookbook/configuration/environments.rst index 7b68bb7b744..6360350e2cc 100644 --- a/cookbook/configuration/environments.rst +++ b/cookbook/configuration/environments.rst @@ -287,12 +287,12 @@ The new environment is now accessible via:: .. note:: - Some environments, like the ``dev`` environment, are never meant to be - accessed on any deployed server by the general public. This is because - certain environments, for debugging purposes, may give too much information - about the application or underlying infrastructure. To be sure these environments - aren't accessible, the front controller is usually protected from external - IP addresses via the following code at the top of the controller: + Some environments, like the ``dev`` environment, are never meant to be + accessed on any deployed server by the general public. This is because + certain environments, for debugging purposes, may give too much information + about the application or underlying infrastructure. To be sure these environments + aren't accessible, the front controller is usually protected from external + IP addresses via the following code at the top of the controller: .. code-block:: php @@ -315,8 +315,12 @@ However, each environment caches its own set of files: .. code-block:: text - app/cache/dev - cache directory for the *dev* environment - app/cache/prod - cache directory for the *prod* environment + / + ├─ app/ + │ ├─ cache/ + │ │ ├─ dev/ # cache directory for the *dev* environment + │ │ └─ prod/ # cache directory for the *prod* environment + │ ├─ ... Sometimes, when debugging, it may be helpful to inspect a cached file to understand how something is working. When doing so, remember to look in diff --git a/cookbook/configuration/web_server_configuration.rst b/cookbook/configuration/web_server_configuration.rst index 717f030ef66..5fbe75f6923 100644 --- a/cookbook/configuration/web_server_configuration.rst +++ b/cookbook/configuration/web_server_configuration.rst @@ -55,13 +55,13 @@ following configuration snippet: In Apache 2.4, ``Order allow,deny`` has been replaced by ``Require all granted``, and hence you need to modify your ``Directory`` permission settings as follows: - .. code-block:: apache + .. code-block:: apache - - # enable the .htaccess rewrites - AllowOverride All - Require all granted - + + # enable the .htaccess rewrites + AllowOverride All + Require all granted + Nginx ----- diff --git a/cookbook/console/console_command.rst b/cookbook/console/console_command.rst index a1bc3ef8530..aded8aea91b 100644 --- a/cookbook/console/console_command.rst +++ b/cookbook/console/console_command.rst @@ -77,8 +77,27 @@ Getting Services from the Service Container By using :class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand` as the base class for the command (instead of the more basic :class:`Symfony\\Component\\Console\\Command\\Command`), you have access to the -service container. In other words, you have access to any configured service. -For example, you could easily extend the task to be translatable:: +service container. In other words, you have access to any configured service:: + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('name'); + $logger = $this->getContainer()->get('logger'); + + $logger->info('Executing command for '.$name); + // ... + } + +However, due to the `container scopes `_ this +code doesn't work for some services. For instance, if you try to get the ``request`` +service or any other service related to it, you'll get the following error: + +.. code-block:: text + + You cannot create a service ("request") of an inactive scope ("request"). + +Consider the following example that uses the ``translator`` service to +translate some contents using a console command:: protected function execute(InputInterface $input, OutputInterface $output) { @@ -91,6 +110,43 @@ For example, you could easily extend the task to be translatable:: } } +If you dig into the Translator component classes, you'll see that the ``request`` +service is required to get the locale into which the contents are translated:: + + // vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php + public function getLocale() + { + if (null === $this->locale && $this->container->isScopeActive('request') + && $this->container->has('request')) { + $this->locale = $this->container->get('request')->getLocale(); + } + + return $this->locale; + } + +Therefore, when using the ``translator`` service inside a command, you'll get the +previous *"You cannot create a service of an inactive scope"* error message. +The solution in this case is as easy as setting the locale value explicitly +before translating contents:: + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('name'); + $locale = $input->getArgument('locale'); + + $translator = $this->getContainer()->get('translator'); + $translator->setLocale($locale); + + if ($name) { + $output->writeln($translator->trans('Hello %name%!', array('%name%' => $name))); + } else { + $output->writeln($translator->trans('Hello!')); + } + } + +However for other services the solution might be more complex. For more details, +see :doc:`/cookbook/service_container/scopes`. + Testing Commands ---------------- diff --git a/cookbook/form/data_transformers.rst b/cookbook/form/data_transformers.rst index f8b3942737f..f847127c894 100644 --- a/cookbook/form/data_transformers.rst +++ b/cookbook/form/data_transformers.rst @@ -109,49 +109,49 @@ Using the Transformer Now that you have the transformer built, you just need to add it to your issue field in some form. - You can also use transformers without creating a new custom form type - by calling ``addModelTransformer`` (or ``addViewTransformer`` - see - `Model and View Transformers`_) on any field builder:: +You can also use transformers without creating a new custom form type +by calling ``addModelTransformer`` (or ``addViewTransformer`` - see +`Model and View Transformers`_) on any field builder:: - use Symfony\Component\Form\FormBuilderInterface; - use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformer; + use Symfony\Component\Form\FormBuilderInterface; + use Acme\TaskBundle\Form\DataTransformer\IssueToNumberTransformer; - class TaskType extends AbstractType + class TaskType extends AbstractType + { + public function buildForm(FormBuilderInterface $builder, array $options) { - public function buildForm(FormBuilderInterface $builder, array $options) - { - // ... - - // this assumes that the entity manager was passed in as an option - $entityManager = $options['em']; - $transformer = new IssueToNumberTransformer($entityManager); - - // add a normal text field, but add your transformer to it - $builder->add( - $builder->create('issue', 'text') - ->addModelTransformer($transformer) - ); - } + // ... - public function setDefaultOptions(OptionsResolverInterface $resolver) - { - $resolver - ->setDefaults(array( - 'data_class' => 'Acme\TaskBundle\Entity\Task', - )) - ->setRequired(array( - 'em', - )) - ->setAllowedTypes(array( - 'em' => 'Doctrine\Common\Persistence\ObjectManager', - )); - - // ... - } + // this assumes that the entity manager was passed in as an option + $entityManager = $options['em']; + $transformer = new IssueToNumberTransformer($entityManager); + + // add a normal text field, but add your transformer to it + $builder->add( + $builder->create('issue', 'text') + ->addModelTransformer($transformer) + ); + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver + ->setDefaults(array( + 'data_class' => 'Acme\TaskBundle\Entity\Task', + )) + ->setRequired(array( + 'em', + )) + ->setAllowedTypes(array( + 'em' => 'Doctrine\Common\Persistence\ObjectManager', + )); // ... } + // ... + } + This example requires that you pass in the entity manager as an option when creating your form. Later, you'll learn how you could create a custom ``issue`` field type to avoid needing to do this in your controller:: @@ -189,21 +189,21 @@ types of underlying data. .. image:: /images/cookbook/form/DataTransformersTypes.png :align: center -In any form, the 3 different types of data are: +In any form, the three different types of data are: 1) **Model data** - This is the data in the format used in your application -(e.g. an ``Issue`` object). If you call ``Form::getData`` or ``Form::setData``, -you're dealing with the "model" data. + (e.g. an ``Issue`` object). If you call ``Form::getData`` or ``Form::setData``, + you're dealing with the "model" data. 2) **Norm Data** - This is a normalized version of your data, and is commonly -the same as your "model" data (though not in our example). It's not commonly -used directly. + the same as your "model" data (though not in our example). It's not commonly + used directly. 3) **View Data** - This is the format that's used to fill in the form fields -themselves. It's also the format in which the user will submit the data. When -you call ``Form::submit($data)``, the ``$data`` is in the "view" data format. + themselves. It's also the format in which the user will submit the data. When + you call ``Form::submit($data)``, the ``$data`` is in the "view" data format. -The 2 different types of transformers help convert to and from each of these +The two different types of transformers help convert to and from each of these types of data: **Model transformers**: diff --git a/cookbook/form/dynamic_form_modification.rst b/cookbook/form/dynamic_form_modification.rst index 5b51ab6cd2c..99c54860ea5 100644 --- a/cookbook/form/dynamic_form_modification.rst +++ b/cookbook/form/dynamic_form_modification.rst @@ -9,20 +9,20 @@ how to customize your form based on three common use-cases: 1) :ref:`cookbook-form-events-underlying-data` -Example: you have a "Product" form and need to modify/add/remove a field -based on the data on the underlying Product being edited. + Example: you have a "Product" form and need to modify/add/remove a field + based on the data on the underlying Product being edited. 2) :ref:`cookbook-form-events-user-data` -Example: you create a "Friend Message" form and need to build a drop-down -that contains only users that are friends with the *current* authenticated -user. + Example: you create a "Friend Message" form and need to build a drop-down + that contains only users that are friends with the *current* authenticated + user. 3) :ref:`cookbook-form-events-submitted-data` -Example: on a registration form, you have a "country" field and a "state" -field which should populate dynamically based on the value in the "country" -field. + Example: on a registration form, you have a "country" field and a "state" + field which should populate dynamically based on the value in the "country" + field. If you wish to learn more about the basics behind form events, you can take a look at the :doc:`Form Events ` diff --git a/cookbook/security/custom_authentication_provider.rst b/cookbook/security/custom_authentication_provider.rst index 66312dad9b5..42f098464ab 100644 --- a/cookbook/security/custom_authentication_provider.rst +++ b/cookbook/security/custom_authentication_provider.rst @@ -299,8 +299,8 @@ The Factory ----------- You have created a custom token, custom listener, and custom provider. Now -you need to tie them all together. How do you make your provider available -to your security configuration? The answer is by using a *factory*. A factory +you need to tie them all together. How do you make a unique provider available +for every firewall? The answer is by using a *factory*. A factory is where you hook into the Security component, telling it the name of your provider and any configuration options available for it. First, you must create a class which implements diff --git a/cookbook/security/entity_provider.rst b/cookbook/security/entity_provider.rst index 3ae31907877..efe3a0f4592 100644 --- a/cookbook/security/entity_provider.rst +++ b/cookbook/security/entity_provider.rst @@ -190,11 +190,11 @@ security layer, the entity class must implement the :class:`Symfony\\Component\\Security\\Core\\User\\UserInterface`. This interface forces the class to implement the five following methods: -* ``getRoles()``, -* ``getPassword()``, -* ``getSalt()``, -* ``getUsername()``, -* ``eraseCredentials()`` +* :method:`Symfony\\Component\\Security\\Core\\User\\UserInterface::getRoles` +* :method:`Symfony\\Component\\Security\\Core\\User\\UserInterface::getPassword` +* :method:`Symfony\\Component\\Security\\Core\\User\\UserInterface::getSalt` +* :method:`Symfony\\Component\\Security\\Core\\User\\UserInterface::getUsername` +* :method:`Symfony\\Component\\Security\\Core\\User\\UserInterface::eraseCredential` For more details on each of these, see :class:`Symfony\\Component\\Security\\Core\\User\\UserInterface`. @@ -377,11 +377,14 @@ entity class to benefit from simple and advanced authentication behaviors. The :class:`Symfony\\Component\\Security\\Core\\User\\AdvancedUserInterface` interface adds four extra methods to validate the account status: -* ``isAccountNonExpired()`` checks whether the user's account has expired, -* ``isAccountNonLocked()`` checks whether the user is locked, -* ``isCredentialsNonExpired()`` checks whether the user's credentials (password) - has expired, -* ``isEnabled()`` checks whether the user is enabled. +* :method:`Symfony\\Component\\Security\\Core\\User\\AdvancedUserInterface::isAccountNonExpired` + checks whether the user's account has expired, +* :method:`Symfony\\Component\\Security\\Core\\User\\AdvancedUserInterface::isAccountNonLocked` + checks whether the user is locked, +* :method:`Symfony\\Component\\Security\\Core\\User\\AdvancedUserInterface::isCredentialsNonExpired` + checks whether the user's credentials (password) has expired, +* :method:`Symfony\\Component\\Security\\Core\\User\\AdvancedUserInterface::isEnabled` + checks whether the user is enabled. For this example, the first three methods will return ``true`` whereas the ``isEnabled()`` method will return the boolean value in the ``isActive`` field. diff --git a/cookbook/templating/namespaced_paths.rst b/cookbook/templating/namespaced_paths.rst index 398ca058b24..7340283c29f 100644 --- a/cookbook/templating/namespaced_paths.rst +++ b/cookbook/templating/namespaced_paths.rst @@ -1,7 +1,7 @@ .. index:: single: Templating; Namespaced Twig Paths -How to use and Register namespaced Twig Paths +How to Use and Register Namespaced Twig Paths ============================================= Usually, when you refer to a template, you'll use the ``MyBundle:Subdir:filename.html.twig`` @@ -30,7 +30,7 @@ Both paths are valid and functional by default in Symfony2. As an added bonus, the namespaced syntax is faster. -Registering your own namespaces +Registering your own Namespaces ------------------------------- You can also register your own custom namespaces. Suppose that you're using @@ -78,3 +78,55 @@ called ``sidebar.twig`` in that directory, you can use it easily: .. code-block:: jinja {% include '@foo_bar/sidebar.twig' %} + +Multiple Paths per Namespace +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also assign several paths to the same template namespace. The order in +which paths are configured is very important, because Twig will always load +the first template that exists, starting from the first configured path. This +feature can be used as a fallback mechanism to load generic templates when the +specific template doesn't exist. + + .. code-block:: yaml + + # app/config/config.yml + twig: + # ... + paths: + "%kernel.root_dir%/../vendor/acme/themes/theme1": theme + "%kernel.root_dir%/../vendor/acme/themes/theme2": theme + "%kernel.root_dir%/../vendor/acme/themes/common": theme + + .. code-block:: xml + + + + + + + %kernel.root_dir%/../vendor/acme/themes/theme1 + %kernel.root_dir%/../vendor/acme/themes/theme2 + %kernel.root_dir%/../vendor/acme/themes/common + + + + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('twig', array( + 'paths' => array( + '%kernel.root_dir%/../vendor/acme/themes/theme1' => 'theme', + '%kernel.root_dir%/../vendor/acme/themes/theme2' => 'theme', + '%kernel.root_dir%/../vendor/acme/themes/common' => 'theme', + ); + )); + +Now, you can use the same ``@theme`` namespace to refer to any template located +in the previous three directories: + +.. code-block:: jinja + + {% include '@theme/header.twig' %} diff --git a/quick_tour/the_big_picture.rst b/quick_tour/the_big_picture.rst index aafbc41cb29..2c2e3342796 100644 --- a/quick_tour/the_big_picture.rst +++ b/quick_tour/the_big_picture.rst @@ -100,7 +100,7 @@ main concepts. Go to the following URL to be greeted by Symfony2 (replace .. code-block:: text - http://localhost:8000/demo/hello/Fabien + http://localhost:8000/app_dev.php/demo/hello/Fabien .. image:: /images/quick_tour/hello_fabien.png :align: center diff --git a/reference/constraints/Collection.rst b/reference/constraints/Collection.rst index 1badcf050f8..0e21d2c8a0d 100644 --- a/reference/constraints/Collection.rst +++ b/reference/constraints/Collection.rst @@ -195,11 +195,11 @@ field is optional but must be a valid email if supplied, you can do the followin - Collection: fields: personal_email: - - Collection\Required + - Required - NotBlank: ~ - Email: ~ alternate_email: - - Collection\Optional: + - Optional: - Email: ~ .. code-block:: php-annotations @@ -237,13 +237,13 @@ field is optional but must be a valid email if supplied, you can do the followin