diff --git a/book/forms.rst b/book/forms.rst index 4eeee6761f9..ac6c673d234 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -709,8 +709,8 @@ the correct values of a number of field options. (i.e. is the field ``nullable``). This is very useful, as your client-side validation will automatically match your validation rules. -* ``max_length``: If the field is some sort of text field, then the ``max_length`` - option can be guessed from the validation constraints (if ``Length`` or +* ``maxlength``: If the field is some sort of text field, then the ``maxlength`` + option attribute can be guessed from the validation constraints (if ``Length`` or ``Range`` is used) or from the Doctrine metadata (via the field's length). .. note:: @@ -721,7 +721,7 @@ the correct values of a number of field options. If you'd like to change one of the guessed values, you can override it by passing the option in the options field array:: - ->add('task', null, array('max_length' => 4)) + ->add('task', null, array('attr' => array('maxlength' => 4))) .. index:: single: Forms; Rendering in a template @@ -1899,7 +1899,7 @@ Learn more from the Cookbook .. _`Symfony2 Form component`: https://github.com/symfony/Form .. _`DateTime`: http://php.net/manual/en/class.datetime.php -.. _`Twig Bridge`: https://github.com/symfony/symfony/tree/2.3/src/Symfony/Bridge/Twig -.. _`form_div_layout.html.twig`: https://github.com/symfony/symfony/blob/2.3/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +.. _`Twig Bridge`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bridge/Twig +.. _`form_div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig .. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery -.. _`view on GitHub`: https://github.com/symfony/symfony/tree/2.3/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form +.. _`view on GitHub`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form diff --git a/book/installation.rst b/book/installation.rst index f73bc26a4b4..a929a0a9692 100644 --- a/book/installation.rst +++ b/book/installation.rst @@ -57,7 +57,7 @@ Distribution: .. code-block:: bash - $ php composer.phar create-project symfony/framework-standard-edition /path/to/webroot/Symfony 2.4.* + $ php composer.phar create-project symfony/framework-standard-edition /path/to/webroot/Symfony dev-master .. tip:: diff --git a/book/routing.rst b/book/routing.rst index 5f65f9b793e..6300fc69548 100644 --- a/book/routing.rst +++ b/book/routing.rst @@ -68,10 +68,6 @@ The route is simple: return $collection; -.. versionadded:: 2.2 - The ``path`` option was introduced in Symfony 2.2, ``pattern`` is used - in older versions. - The path defined by the ``blog_show`` route acts like ``/blog/*`` where the wildcard is given the name ``slug``. For the URL ``/blog/my-blog-post``, the ``slug`` variable gets a value of ``my-blog-post``, which is available @@ -706,10 +702,6 @@ be accomplished with the following route configuration: return $collection; -.. versionadded:: 2.2 - The ``methods`` option was introduced in Symfony 2.2. Use the ``_method`` - requirement in older versions. - Despite the fact that these two routes have identical paths (``/contact``), the first route will match only GET requests and the second route will match only POST requests. This means that you can display the form and submit the @@ -722,9 +714,6 @@ form via the same URL, while using distinct controllers for the two actions. Adding a Host Requirement ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - Host matching support was introduced in Symfony 2.2 - You can also match on the HTTP *host* of the incoming request. For more information, see :doc:`/components/routing/hostname_pattern` in the Routing component documentation. @@ -1166,9 +1155,6 @@ from the new routing resource. Adding a Host Requirement to Imported Routes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - Host matching support was introduced in Symfony 2.2 - You can set the host regex on imported routes. For more information, see :ref:`component-routing-host-imported`. diff --git a/book/security.rst b/book/security.rst index d61bdf11cb6..fb0f7884dfb 100644 --- a/book/security.rst +++ b/book/security.rst @@ -183,8 +183,9 @@ can access ``/foo`` without being prompted to authenticate. .. tip:: - You can also match a request against other details of the request (e.g. host). - For more information and examples read :doc:`/cookbook/security/firewall_restriction`. + You can also match a request against other details of the request (e.g. + host, method). For more information and examples read + :doc:`/cookbook/security/firewall_restriction`. .. image:: /images/book/security_anonymous_user_access.png :align: center @@ -1088,12 +1089,11 @@ fine-grained enough in certain cases. When necessary, you can easily force authorization from inside a controller:: // ... - use Symfony\Component\Security\Core\Exception\AccessDeniedException; public function helloAction($name) { if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) { - throw new AccessDeniedException(); + throw $this->createAccessDeniedException('Unable to access this page!'); } // ... @@ -1101,6 +1101,13 @@ authorization from inside a controller:: .. _book-security-securing-controller-annotations: +.. versionadded:: 2.5 + The ``createAccessDeniedException`` method was introduced in Symfony 2.5. + +The :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::createAccessDeniedException` +method creates a special :class:`Symfony\\Component\\Security\\Core\Exception\\AccessDeniedException` +object, which ultimately triggers a 403 HTTP response inside Symfony. + Thanks to the SensioFrameworkExtraBundle, you can also secure your controller using annotations:: // ... @@ -1444,9 +1451,10 @@ or via some online tool. Supported algorithms for this method depend on your PHP version. A full list is available by calling the PHP function :phpfunction:`hash_algos`. -.. versionadded:: 2.2 - As of Symfony 2.2 you can also use the :ref:`PBKDF2 ` - password encoder. +.. tip:: + + It's also possible to use different hashing algorithms on a user-by-user + basis. See :doc:`/cookbook/security/named_encoders` for more details. Determining the Hashed Password ............................... @@ -2065,10 +2073,6 @@ cookie will be ever created by Symfony2): Utilities --------- -.. versionadded:: 2.2 - The ``StringUtils`` and ``SecureRandom`` classes were introduced in Symfony - 2.2 - The Symfony Security component comes with a collection of nice utilities related to security. These utilities are used by Symfony, but you should also use them if you want to solve the problem they address. diff --git a/book/templating.rst b/book/templating.rst index 3cafc48c5e5..cfc6a1414e8 100644 --- a/book/templating.rst +++ b/book/templating.rst @@ -373,11 +373,6 @@ When working with template inheritance, here are some tips to keep in mind: Template Naming and Locations ----------------------------- -.. versionadded:: 2.2 - Namespaced path support was introduced in 2.2, allowing for template names - like ``@AcmeDemo/layout.html.twig``. See :doc:`/cookbook/templating/namespaced_paths` - for more details. - By default, templates can live in two different locations: * ``app/Resources/views/``: The applications ``views`` directory can contain @@ -570,10 +565,6 @@ 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 - The `include() function`_ is a new Twig feature that's available in Symfony - 2.2. Prior, the `{% include %} tag`_ tag was used. - .. index:: single: Templating; Embedding action @@ -780,9 +771,6 @@ in your application configuration: ), )); -.. versionadded:: 2.2 - Default templates per render function was introduced in Symfony 2.2 - You can define default templates per ``render`` function (which will override any global default template that is defined): @@ -1001,6 +989,44 @@ assets won't be cached when deployed. For example, ``/images/logo.png`` might look like ``/images/logo.png?v2``. For more information, see the :ref:`ref-framework-assets-version` configuration option. +.. _`book-templating-version-by-asset`: + +.. versionadded:: 2.5 + Setting versioned URLs on an asset-by-asset basis was introduced in Symfony 2.5. + +If you need to set a version for a specific asset, you can set the fourth +argument (or the ``version`` argument) to the desired version: + +.. configuration-block:: + + .. code-block:: html+jinja + + Symfony! + + .. code-block:: html+php + + Symfony! + +If you dont give a version or pass ``null``, the default package version +(from :ref:`ref-framework-assets-version`) will be used. If you pass ``false``, +versioned URL will be deactivated for this asset. + +.. versionadded:: 2.5 + Absolute URLs for assets were introduced in Symfony 2.5. + +If you need absolute URLs for assets, you can set the third argument (or the +``absolute`` argument) to ``true``: + +.. configuration-block:: + + .. code-block:: html+jinja + + Symfony! + + .. code-block:: html+php + + Symfony! + .. index:: single: Templating; Including stylesheets and JavaScripts single: Stylesheets; Including stylesheets diff --git a/book/translation.rst b/book/translation.rst index cd1cd7cdfb0..0f46aa03923 100644 --- a/book/translation.rst +++ b/book/translation.rst @@ -649,6 +649,173 @@ The translation of database content should be handled by Doctrine through the `Translatable Extension`_ or the `Translatable Behavior`_ (PHP 5.4+). For more information, see the documentation for thes libraries. +Debugging Translations +---------------------- + +.. versionadded:: 2.5 + The ``translation:debug`` command was introduced in Symfony 2.5. + +When maintaining a bundle, you may use or remove the usage of a translation +message without updating all message catalogues. The ``translation:debug`` +command helps you to find these missing or unused translation messages for a +given locale. It shows you a table with the result when translating the +message in the given locale and the result when the fallback would be used. +On top of that, it also shows you when the translation is the same as the +fallback translation (this could indicate that the message was not correctly +translated). + +Thanks to the messages extractors, the command will detect the translation +tag or filter usages in Twig templates: + +.. code-block:: jinja + + {% trans %}Symfony2 is great{% endtrans %} + + {{ 'Symfony2 is great'|trans }} + + {{ 'Symfony2 is great'|transchoice(1) }} + + {% transchoice 1 %}Symfony2 is great{% endtranschoice %} + +It will also detect the following translator usages in PHP templates: + +.. code-block:: php + + $view['translator']->trans("Symfony2 is great"); + + $view['translator']->trans('Symfony2 is great'); + +.. caution:: + + The extractors are not able to inspect the messages translated outside templates which means + that translator usages in form labels or inside your controllers won't be detected. + Dynamic translations involving variables or expressions are not detected in templates, + which means this example won't be analyzed: + + .. code-block:: jinja + + {% set message = 'Symfony2 is great' %} + {{ message|trans }} + +Suppose your application's default_locale is ``fr`` and you have configured ``en`` as the fallback locale +(see :ref:`book-translation-configuration` and :ref:`book-translation-fallback` for how to configure these). +And suppose you've already setup some translations for the ``fr`` locale inside an AcmeDemoBundle: + +.. configuration-block:: + + .. code-block:: xml + + + + + + + + Symfony2 is great + J'aime Symfony2 + + + + + + .. code-block:: php + + // src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.php + return array( + 'Symfony2 is great' => 'J\'aime Symfony2', + ); + + .. code-block:: yaml + + # src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.yml + Symfony2 is great: J'aime Symfony2 + +and for the ``en`` locale: + +.. configuration-block:: + + .. code-block:: xml + + + + + + + + Symfony2 is great + Symfony2 is great + + + + + + .. code-block:: php + + // src/Acme/AcmeDemoBundle/Resources/translations/messages.en.php + return array( + 'Symfony2 is great' => 'Symfony2 is great', + ); + + .. code-block:: yaml + + # src/Acme/AcmeDemoBundle/Resources/translations/messages.en.yml + Symfony2 is great: Symfony2 is great + +To inspect all messages in the ``fr`` locale for the AcmeDemoBundle, run: + +.. code-block:: bash + + $ php app/console translation:debug fr AcmeDemoBundle + +You will get this output: + +.. image:: /images/book/translation/debug_1.png + :align: center + +It indicates that the message ``Symfony2 is great`` is unused because it is translated, +but you haven't used it anywhere yet. + +Now, if you translate the message in one of your templates, you will get this output: + +.. image:: /images/book/translation/debug_2.png + :align: center + +The state is empty which means the message is translated in the ``fr`` locale and used in one or more templates. + +If you delete the message ``Symfony2 is great`` from your translation file for the ``fr`` locale +and run the command, you will get: + +.. image:: /images/book/translation/debug_3.png + :align: center + +The state indicates the message is missing because it is not translated in the ``fr`` locale +but it is still used in the template. +Moreover, the message in the ``fr`` locale equals to the message in the ``en`` locale. +This is a special case because the untranslated message id equals its translation in the ``en`` locale. + +If you copy the content of the translation file in the ``en`` locale, to the translation file +in the ``fr`` locale and run the command, you will get: + +.. image:: /images/book/translation/debug_4.png + :align: center + +You can see that the translations of the message are identical in the ``fr`` and ``en`` locales +which means this message was probably copied from French to English and maybe you forgot to translate it. + +By default all domains are inspected, but it is possible to specify a single domain: + +.. code-block:: bash + + $ php app/console translation:debug en AcmeDemoBundle --domain=messages + +When bundles have a lot of messages, it is useful to display only the unused +or only the missing messages, by using the ``--only-unused`` or ``--only-missing`` switches: + +.. code-block:: bash + + $ php app/console translation:debug en AcmeDemoBundle --only-unused + $ php app/console translation:debug en AcmeDemoBundle --only-missing + Summary ------- diff --git a/book/validation.rst b/book/validation.rst index f0a54ab9b59..127b666709c 100644 --- a/book/validation.rst +++ b/book/validation.rst @@ -583,8 +583,11 @@ Getters Constraints can also be applied to the return value of a method. Symfony2 allows you to add a constraint to any public method whose name starts with -"get" or "is". In this guide, both of these types of methods are referred -to as "getters". +"get", "is" or "has". In this guide, these types of methods are referred to +as "getters". + +.. versionadded:: 2.5 + Support for methods starting with ``has`` was introduced in Symfony 2.5. The benefit of this technique is that it allows you to validate your object dynamically. For example, suppose you want to make sure that a password field @@ -665,9 +668,9 @@ Now, create the ``isPasswordLegal()`` method, and include the logic you need:: .. note:: The keen-eyed among you will have noticed that the prefix of the getter - ("get" or "is") is omitted in the mapping. This allows you to move the - constraint to a property with the same name later (or vice versa) without - changing your validation logic. + ("get", "is" or "has") is omitted in the mapping. This allows you to move + the constraint to a property with the same name later (or vice versa) + without changing your validation logic. .. _validation-class-target: diff --git a/changelog.rst b/changelog.rst index ef4f2f3226c..46868fdda58 100644 --- a/changelog.rst +++ b/changelog.rst @@ -13,6 +13,80 @@ documentation. Do you also want to participate in the Symfony Documentation? Take a look at the ":doc:`/contributing/documentation/overview`" article. +May, 2014 +--------- + +New Documentation +~~~~~~~~~~~~~~~~~ + +- `4fd1b49 `_ #3753 [DependencyInjection] Add documentation about service decoration (romainneutron) +- `f913dd7 `_ #3603 [Serializer] Support for is.* getters in GetSetMethodNormalizer (tiraeth) +- `e8511cb `_ #3776 Updated event_listener.rst (bfgasparin) +- `af8c20f `_ #3818 [Form customization] added block_name example. (aitboudad) +- `c788325 `_ #3841 [Cookbook][Logging] register processor per handler and per channel (xabbuh) +- `979533a `_ #3839 document how to test actions (greg0ire) +- `d8aaac3 `_ #3835 Updated framework.ide configuration (WouterJ) +- `a9648e8 `_ #3742 [2.5][Templating] Add documentation about generating versioned URLs (romainneutron) +- `f665e14 `_ #3704 [Form] Added documentation for Form Events (csarrazi) +- `14b9f14 `_ #3777 added docs for the core team (fabpot) + +Fixed Documentation +~~~~~~~~~~~~~~~~~~~ + +- `0649c21 `_ #3869 Add a missing argument to the PdoSessionHandler (jakzal) +- `259a2b7 `_ #3866 [Book][Security]fixed Login when there is no session. (aitboudad) +- `9b7584f `_ #3863 Error in XML (tvlooy) +- `0cb9c3b `_ #3827 Update 'How to Create and store a Symfony2 Project in Git' (nicwortel) +- `4ed9a08 `_ #3830 Generate an APC prefix based on __FILE__ (trsteel88) +- `9a65412 `_ #3840 Update dialoghelper.rst (jdecoster) +- `1853fea `_ #3716 Fix issue #3712 (umpirsky) +- `baa9759 `_ #3791 Property access tweaks (weaverryan) +- `80d70a4 `_ #3779 [Book][Security] constants are defined in the SecurityContextInterface (xabbuh) + +Minor Documentation Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `302fa82 `_ #3872 Update hostname_pattern.rst (sofany) +- `50672f7 `_ #3867 fixed missing info about FosUserBundle. (aitboudad) +- `3e3004f `_ #3865 Fixed link. (aitboudad) +- `b32ec15 `_ #3856 Update voters_data_permission.rst (MarcomTeam) +- `bffe163 `_ #3859 Add filter cssrewrite (DOEO) +- `f617ff8 `_ #3764 Update testing.rst (NAYZO) +- `3792fee `_ #3858 Clarified Password Encoders example (WouterJ) +- `663d68c `_ #3857 Added little bit information about the route name (WouterJ) +- `797cbd5 `_ #3794 Adds link to new QuestionHelper (weaverryan) +- `4211bff `_ #3852 Fixed link and typo in type_guesser.rst (rpg600) +- `78ae7ec `_ #3845 added link to /cookbook/security/force_https. (aitboudad) +- `6c69362 `_ #3846 [Routing][Loader] added JMSI18nRoutingBundle (aitboudad) +- `136864b `_ #3844 [Components] Fixed some typos. (ahsio) +- `b0710bc `_ #3842 Update dialoghelper.rst (bijsterdee) +- `9f1a354 `_ #3804 [Components][DependencyInjection] add note about a use case that requires to compile the container (xabbuh) +- `d92c522 `_ #3769 Updated references to new Session() (scottwarren) +- `00f60a8 `_ #3837 More asset version details (weaverryan) +- `681ddc8 `_ #3843 [Changelog] fix literal positions (xabbuh) +- `1aa79d5 `_ #3834 fix the wording in versionadded directives (for the master branch) (xabbuh) +- `7288a33 `_ #3789 [Reference][Forms] Improvements to the form type (xabbuh) +- `72fae25 `_ #3790 [Reference][Forms] move versionadded directives for form options directly below the option's headline (xabbuh) +- `b4d4ac3 `_ #3838 fix filename typo in cookbook/form/unit_testing.rst (hice3000) +- `0b06287 `_ #3836 remove unnecessary rewrite from nginx conf (Burgov) +- `89d0dae `_ #3833 fix the wording in versionadded directives (for the 2.4 branch) (xabbuh) +- `e58e39f `_ #3832 fix the wording in versionadded directives (for the 2.3 branch) (xabbuh) +- `09d6ca1 `_ #3829 [Components] consistent headlines (xabbuh) +- `54e0882 `_ #3828 [Contributing] consistent headlines (xabbuh) +- `b1336d7 `_ #3823 Added empty line after if statements (zomberg) +- `79b9fdc `_ #3822 Update voters_data_permission.rst (mimol91) +- `69cb7b8 `_ #3821 Update custom_authentication_provider.rst (leberknecht) +- `9f602c4 `_ #3820 Update page_creation.rst (adreeun) +- `52518c0 `_ #3819 Update csrf_in_login_form.rst (micheal) +- `1adfd9b `_ #3802 Add a note about which types can be used in Symfony (fabpot) +- `fa27ded `_ #3801 [Cookbook][Form] Fixed Typo & missing word. (ahsio) +- `127beed `_ #3770 Update factories.rst (AlaaAttya) +- `822d985 `_ #3817 Update translation.rst (richardpi) +- `241d923 `_ #3813 [Reference][Forms]fix time field count. (yositani2002) +- `bc96f55 `_ #3812 [Cookbook][Configuration] Fixed broken link. (ahsio) +- `5867327 `_ #3809 Fixed typo (WouterJ) +- `678224e `_ #3808 Fixed broken link in "Handling Authentication Failure" (stacyhorton) + April, 2014 ----------- @@ -20,10 +94,15 @@ New Documentation ~~~~~~~~~~~~~~~~~ - `322972e `_ #3803 [Book][Validation] configuration examples for the GroupSequenceProvider (xabbuh) +- `9e129bc `_ #3752 [Console] Add documentation for QuestionHelper (romainneutron) +- `64a924d `_ #3756 [WCM][Console] Add Process Helper documentation (romainneutron) - `d4ca16a `_ #3743 Improve examples in parent services (WouterJ) +- `be4b9d3 `_ #3729 Added documentation for the new ``PropertyAccessor::isReadable()`` and ``isWritable()`` methods (webmozart) - `70a3893 `_ #3774 [Book][Internals] add description for the kernel.finish_request event (xabbuh) +- `1934720 `_ #3461 [Form] Deprecated max_length and pattern options (stefanosala) - `d611e77 `_ #3701 [Serializer] add documentation for serializer callbacks (cordoval) - `80c645c `_ #3719 Fixed event listeners priority (tony-co) +- `c062d81 `_ #3469 [Validator] - EmailConstraint reference (egulias) Fixed Documentation ~~~~~~~~~~~~~~~~~~~ @@ -55,6 +134,7 @@ Minor Documentation Changes - `703c2a6 `_ #3772 [Cookbook][Sessions] some language improvements (xabbuh) - `3d30b56 `_ #3773 modify Symfony CMF configuration values in the build process so that the... (xabbuh) - `cfd6d7c `_ #3758 [Book][Routing] Fixed typo on PHP version of a route definition (saro0h) +- `cedfdce `_ #3757 Fixed a typo in the request formats configuration page (gquemener) - `6bd134c `_ #3754 ignore more files and directories which are created when building the documentation (xabbuh) - `610462e `_ #3755 [Cookbook][Security] Firewall resitrction tweaks, fix markup, add to toc (xabbuh) - `0a21718 `_ #3695 Firewall backport (weaverryan) @@ -74,20 +154,33 @@ New Documentation - `3b640aa `_ #3644 made some small addition about our BC promise and semantic versioning (fabpot) - `2d1ecd9 `_ #3525 Update file_uploads.rst (juanmf) - `b1e8f56 `_ #3368 The host parameter has to be in defaults, not requirements (MarieMinasyan) +- `b34fb64 `_ #3619 [Validator] Uuid constraint reference (colinodell) +- `d7027c0 `_ #3418 [Validation] Add "hasser" support (bicpi) +- `4fd5fc1 `_ #3539 [Stopwatch] Describe retrieval of StopwatchEvent (jochenvdv) +- `1908a15 `_ #3696 [Console] Added standalone PSR-3 compliant logger (dunglas) - `c75b1a7 `_ #3621 [Console] Command as service (gnugat) - `00a462a `_ minor #3658 Fix PSR coding standards error (ifdattic) - `acf255d `_ #3328 [WIP] Travis integration (WouterJ) +- `450146e `_ #3681 Enhanced Firewall Restrictions docs (danez) - `3e7028d `_ #3659 [Internals] Complete notification description for kernel.terminate (bicpi) - `db3cde7 `_ #3124 Add note about the property attribute (Property Accessor) (raziel057) - `5965ec8 `_ #3420 [Cookbook][Configuration] add configuration cookbook handlig parameters in Configurator class (cordoval) +- `dcf8e6e `_ #3402 Added documentation about new requests formats configuration (gquemener) - `a1050eb `_ #3411 [Cookbook][Dynamic Form Modification] Add AJAX sample (bicpi) +- `842fd30 `_ #3683 [TwigBundle] Add documentation about generating absolute URL with the asset function (romainneutron) +- `fc1576a `_ #3664 [Process] Add doc for ``Process::disableOutput`` and ``Process::enableOutput`` (romainneutron) +- `3731e2e `_ #3686 Documentation of the new PSR-4 class loader. (derrabus) +- `5b915c2 `_ #3629 Added documentation for translation:debug (florianv) - `6951460 `_ #3601 Added documentation for missing ctype extension (slavafomin) +- `df63740 `_ #3627 added docs for the new Table console helper (fabpot) +- `96bd81b `_ #3626 added documentation for the new Symfony 2.5 progress bar (fabpot) - `b02c16a `_ #3565 added information on AuthenticationFailureHandlerInterface (samsamm777) - `2657ee7 `_ #3597 Document how to create a custom type guesser (WouterJ) - `5ad1599 `_ #3577 Development of custom error pages is impractical if you need to set kernel.debug=false (mpdude) - `3f4b319 `_ #3610 [HttpFoundation] Add doc for ``Request::getContent()`` method (bicpi) - `56bc266 `_ #3589 Finishing the Templating component docs (WouterJ) - `d881181 `_ #3588 Documented all form variables (WouterJ) +- `5cda1c7 `_ #3311 Use KernelTestCase instead of WebTestCase for testing code only requiring the Container (johnkary) - `e96e12d `_ #3234 [Cookbook] New cookbok: How to use the Cloud to send Emails (bicpi) - `d5d64ce `_ #3436 [Reference][Form Types] Add missing docs for "action" and "method" option (bicpi) - `3df34af `_ #3490 Tweaking Doctrine book chapter (WouterJ) @@ -96,6 +189,7 @@ New Documentation Fixed Documentation ~~~~~~~~~~~~~~~~~~~ +- `cad38ae `_ #3721 tweaks to the Console logger (xabbuh) - `06c56c1 `_ #3709 [Components][Security] Fix #3708 (bicpi) - `aadc61d `_ #3707 make method supportsClass() in custom voter compatible with the interface's documentation (xabbuh) - `65150f9 `_ #3637 Update render_without_controller.rst (94noni) @@ -120,13 +214,16 @@ Minor Documentation Changes - `aa9bb25 `_ #3636 Update security.rst (nomack84) - `78425c6 `_ #3722 add "Commands as Services" chapter to the cookbook's map (xabbuh) - `9f26da8 `_ #3720 [#3539] A backport of a sentence - the parts that apply to 2.3 (weaverryan) +- `4b611d6 `_ #3717 [master] Fixed versionadded blocks (WouterJ) - `5a3ba1b `_ #3715 change variable name to a better fitting one (xabbuh) - `499eb6c `_ #3714 [2.4] Versionadded consistency (WouterJ) - `e7580c0 `_ #3713 Updated versionadded directives to use "introduced" (WouterJ) - `e15afe0 `_ #3711 Simplified the Travis configuration (stof) +- `db1cda5 `_ #3700 [Cookbook][Security] Firewall restrictions tweaks (xabbuh) - `5035837 `_ #3706 Add support for nginx (guiditoito) - `00a462a `_ #3658 Fix PSR coding standards error (ifdattic) - `868de1e `_ #3698 Dynamic form modification cookbook: Fix inclusion of code (michaelperrin) +- `15a9d25 `_ #3697 [Console] Change Command namespaces (dunglas) - `41b2eb8 `_ #3693 Tweak to Absolute URL generation (weaverryan) - `bd473db `_ #3563 Add another tip to setup permissions (tony-co) - `67129b1 `_ #3611 [Reference][Forms] add an introductory table containing all options of the basic form type (xabbuh) @@ -140,15 +237,19 @@ Minor Documentation Changes - `12a6676 `_ #3640 [minor] fixed one typo and one formatting issue (javiereguiluz) - `9967b0c `_ #3638 [#3116] Fixing wrong table name - singular is used elsewhere (weaverryan) - `4fbf1cd `_ #3635 [QuickTour] close opened literals (xabbuh) +- `27b3410 `_ #3692 [Book][Translations] fixing a code block (xabbuh) - `2192c32 `_ #3650 Fixing some build errors (xabbuh) - `fa3f531 `_ #3677 [Reference][Forms] Remove variables section from tables (xabbuh) +- `cd6d1de `_ #3676 remove unnecessary code block directive (xabbuh) - `07822b8 `_ #3675 add missing code block directive (xabbuh) +- `739f43f `_ #3669 Fixed syntax highlighting (rvanlaarhoven) - `1f384bc `_ #3631 Added documentation for message option of the ``True`` constraint (naitsirch) - `f6a41b9 `_ #3630 Minor tweaks to form action/method (weaverryan) - `ae755e0 `_ #3628 Added anchor for permissions (WouterJ) - `6380113 `_ #3667 Update index.rst (NAYZO) - `97ef2f7 `_ #3566 Changes ACL permission setting hints (MicheleOnGit) - `9f7d742 `_ #3654 [Cookbook][Security] Fix VoterInterface signature (bicpi) +- `0a65b6f `_ #3608 [Reference][Forms] add versionadded directive for multiple option of file type (xabbuh) - `e34204e `_ #3605 Fixed a plural issue (benjaminpaap) - `e7d5a45 `_ #3599 [CHANGELOG] fix reference to contributing docs (xabbuh) - `3582bf1 `_ #3598 add changelog to hidden toctree (xabbuh) @@ -173,6 +274,8 @@ New Documentation - `9676f2c `_ #3523 [Components][EventDispatcher] describe that the event name and the event dispatcher are passed to even... (xabbuh) - `5c367b4 `_ #3517 Fixed OptionsResolver component docs (WouterJ) - `527c8b6 `_ #3496 Added a section about using named assets (vmattila) +- `8ccfe85 `_ #3491 Added doc for named encoders (tamirvs) +- `46377b2 `_ #3486 Documenting createAccessDeniedException() method (klaussilveira) Fixed Documentation ~~~~~~~~~~~~~~~~~~~ @@ -184,6 +287,7 @@ Fixed Documentation - `de71a51 `_ #3551 [Cookbook][Dynamic Form Modification] Fix sample code (rybakit) - `143db2f `_ #3550 Update introduction.rst (taavit) - `384538b `_ #3549 Fixed createPropertyAccessorBuilder usage (antonbabenko) +- `642e776 `_ #3544 Fix build errors (xabbuh) - `d275302 `_ #3541 Update generic_event.rst (Lumbendil) - `819949c `_ #3537 Add missing variable assignment (colinodell) - `d7e8262 `_ #3535 fix form type name. (yositani2002) @@ -217,6 +321,7 @@ Minor Documentation Changes - `6a2a55b `_ #3579 Fix build errors (xabbuh) - `dce2e23 `_ #3532 Added tip for Entity Listeners (slavafomin) - `73adf8b `_ #3528 Clarify service parameters usages (WouterJ) +- `7e75b64 `_ #3533 Moving the new named algorithms into their own cookbook entry (weaverryan) - `f634600 `_ #3531 Remove horizontal scrolling in code block (ifdattic) - `9ba4fa7 `_ #3527 Changes to components domcrawler (ifdattic) - `8973c81 `_ #3526 Changes for Console component (ifdattic) @@ -239,12 +344,16 @@ New Documentation ~~~~~~~~~~~~~~~~~ - `d52f3f8 `_ #3454 [Security] Add host option (ghostika) +- `11e079b `_ #3446 [WCM] Documented deprecation of the apache router. (jakzal) +- `0a0bf4c `_ #3437 Add info about callback in options resolver (marekkalnik) +- `6db5f23 `_ #3426 New Feature: Change the Default Command in the Console component (danielcsgomes) - `6b3c424 `_ #3428 Translation - Added info about JsonFileLoader added in 2.4 (singles) Fixed Documentation ~~~~~~~~~~~~~~~~~~~ - `fb22fa0 `_ #3456 remove duplicate label (xabbuh) +- `a87fe18 `_ #3470 Fixed typo (danielcsgomes) - `c205bc6 `_ #3468 enclose YAML string with double quotes to fix syntax highlighting (xabbuh) - `89963cc `_ #3463 Fix typos in cookbook/testing/database (ifdattic) - `e0a52ec `_ #3460 remove confusing outdated note on interactive rebasing (xabbuh) @@ -265,9 +374,10 @@ Fixed Documentation Minor Documentation Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- `b9bbe5d `_ #3499 Fix YAML syntax highlight + remove trailing whitespace (ifdattic) - `f285d93 `_ #3451 some language tweaks (AE, third-person perspective) (xabbuh) +- `b9bbe5d `_ #3499 Fix YAML syntax highlight + remove trailing whitespace (ifdattic) - `2b7e0f6 `_ #3497 Fix highlighting (WouterJ) +- `2746067 `_ #3472 Fixed `````versionadded````` inconsistencies in Symfony 2.5+ (danielcsgomes) - `a535ae0 `_ #3471 Fixed `````versionadded````` inconsistencies in Symfony 2.3 (danielcsgomes) - `f077a8e `_ #3465 change wording in versionadded example to be consistent with what we use... (xabbuh) - `f9f7548 `_ #3462 Replace ... with etc (ifdattic) diff --git a/components/class_loader/index.rst b/components/class_loader/index.rst index 4916933d6fa..de8da86c7c6 100644 --- a/components/class_loader/index.rst +++ b/components/class_loader/index.rst @@ -6,6 +6,7 @@ ClassLoader introduction class_loader + psr4_class_loader map_class_loader cache_class_loader debug_class_loader diff --git a/components/class_loader/psr4_class_loader.rst b/components/class_loader/psr4_class_loader.rst new file mode 100644 index 00000000000..489db8a351d --- /dev/null +++ b/components/class_loader/psr4_class_loader.rst @@ -0,0 +1,67 @@ +.. index:: + single: ClassLoader; PSR-4 Class Loader + +The PSR-4 Class Loader +====================== + +.. versionadded:: 2.5 + The :class:`Symfony\\Component\\ClassLoader\\Psr4ClassLoader` was + introduced in Symfony 2.5. + +Libraries that follow the `PSR-4`_ standard can be loaded with the ``Psr4ClassLoader``. + +.. note:: + + If you manage your dependencies via Composer, you get a PSR-4 compatible + autoloader out of the box. Use this loader in environments where Composer + is not available. + +.. tip:: + + All Symfony components follow PSR-4. + +Usage +----- + +The following example demonstrates how you can use the +:class:`Symfony\\Component\\ClassLoader\\Psr4ClassLoader` autoloader to use +Symfony's Yaml component. Imagine, you downloaded both the ClassLoader and +Yaml component as ZIP packages and unpacked them to a ``libs`` directory. +The directory structure will look like this: + +.. code-block:: text + + libs/ + ClassLoader/ + Psr4ClassLoader.php + ... + Yaml/ + Yaml.php + ... + config.yml + demo.php + +In ``demo.php`` you are going to parse the ``config.yml`` file. To do that, you +first need to configure the ``Psr4ClassLoader``: + +.. code-block:: php + + use Symfony\Component\ClassLoader\Psr4ClassLoader; + use Symfony\Component\Yaml\Yaml; + + require __DIR__.'/lib/ClassLoader/Psr4ClassLoader.php'; + + $loader = new Psr4ClassLoader(); + $loader->addPrefix('Symfony\\Component\\Yaml\\', __DIR__.'/lib/Yaml'); + $loader->register(); + + $data = Yaml::parse(__DIR__.'/config.yml'); + +First of all, the class loader is loaded manually using a ``require`` +statement, since there is no autoload mechanism yet. With the +:method:`Symfony\Component\ClassLoader\Psr4ClassLoader::addPrefix` call, you +tell the class loader where to look for classes with the +``Symfony\Component\Yaml\`` namespace prefix. After registering the autoloader, +the Yaml component is ready to be used. + +.. _PSR-4: http://www.php-fig.org/psr/psr-4/ diff --git a/components/config/definition.rst b/components/config/definition.rst index efae1a41928..772f51ceb9f 100644 --- a/components/config/definition.rst +++ b/components/config/definition.rst @@ -99,7 +99,7 @@ node definition. Node type are available for: * scalar * boolean -* integer (new in 2.2) +* integer * float * enum * array @@ -111,9 +111,6 @@ and are created with ``node($name, $type)`` or their associated shortcut Numeric Node Constraints ~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - The numeric (float and integer) nodes were introduced in Symfony 2.2. - Numeric nodes (float and integer) provide two extra constraints - :method:`Symfony\\Component\\Config\\Definition\\Builder::min` and :method:`Symfony\\Component\\Config\\Definition\\Builder::max` - @@ -287,10 +284,6 @@ has a certain value: Optional Sections ----------------- -.. versionadded:: 2.2 - The ``canBeEnabled`` and ``canBeDisabled`` methods were introduced in - Symfony 2.2. - 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 diff --git a/components/console/changing_default_command.rst b/components/console/changing_default_command.rst new file mode 100644 index 00000000000..1c191ba8571 --- /dev/null +++ b/components/console/changing_default_command.rst @@ -0,0 +1,67 @@ +.. index:: + single: Console; Changing the Default Command + +Changing the Default Command +============================ + +.. versionadded:: 2.5 + The :method:`Symfony\\Component\\Console\\Application::setDefaultCommand` + method was introduced in Symfony 2.5. + +will always run the ``ListCommand`` when no command name is passed. In order to change +the default command you just need to pass the command name you want to run by +default to the ``setDefaultCommand`` method:: + + namespace Acme\Console\Command; + + use Symfony\Component\Console\Command\Command; + use Symfony\Component\Console\Input\InputInterface; + use Symfony\Component\Console\Output\OutputInterface; + + class HelloWorldCommand extends Command + { + protected function configure() + { + $this->setName('hello:world') + ->setDescription('Outputs \'Hello World\''); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln('Hello World'); + } + } + +Executing the application and changing the default Command:: + + // application.php + + use Acme\Console\Command\HelloWorldCommand; + use Symfony\Component\Console\Application; + + $command = new HelloWorldCommand(); + $application = new Application(); + $application->add($command); + $application->setDefaultCommand($command->getName()); + $application->run(); + +Test the new default console command by running the following: + +.. code-block:: bash + + $ php application.php + +This will print the following to the command line: + +.. code-block:: text + + Hello Fabien + +.. tip:: + + This feature has a limitation: you cannot use it with any Command arguments. + +Learn More! +----------- + +* :doc:`/components/console/single_command_tool` diff --git a/components/console/helpers/dialoghelper.rst b/components/console/helpers/dialoghelper.rst index ff6ca161c5d..17fd4cdde08 100644 --- a/components/console/helpers/dialoghelper.rst +++ b/components/console/helpers/dialoghelper.rst @@ -4,6 +4,13 @@ Dialog Helper ============= +.. caution:: + + The Dialog Helper was deprecated in Symfony 2.5 and will be removed in + Symfony 3.0. You should now use the + :doc:`Question Helper ` instead, + which is simpler to use. + The :class:`Symfony\\Component\\Console\\Helper\\DialogHelper` provides functions to ask the user for more information. It is included in the default helper set, which you can get by calling @@ -59,9 +66,6 @@ If they leave it empty, the default value (``AcmeDemoBundle`` here) is returned. Autocompletion ~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - Autocompletion for questions was introduced in Symfony 2.2. - You can also specify an array of potential answers for a given question. These will be autocompleted as the user types:: @@ -77,9 +81,6 @@ will be autocompleted as the user types:: Hiding the User's Response ~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - The ``askHiddenResponse`` method was introduced in Symfony 2.2. - You can also ask a question and hide the response. This is particularly convenient for passwords:: @@ -149,9 +150,6 @@ be able to proceed if their input is valid. Validating a Hidden Response ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - The ``askHiddenResponseAndValidate`` method was introduced in Symfony 2.2. - You can also ask and validate a hidden response:: $dialog = $this->getHelperSet()->get('dialog'); @@ -160,7 +158,7 @@ You can also ask and validate a hidden response:: if ('' === trim($value)) { throw new \Exception('The password can not be empty'); } - + return $value; }; @@ -178,10 +176,6 @@ some reason, pass true as the fifth argument. Let the User Choose from a List of Answers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 2.2 - The :method:`Symfony\\Component\\Console\\Helper\\DialogHelper::select` method - was introduced in Symfony 2.2. - If you have a predefined set of answers the user can choose from, you could use the ``ask`` method described above or, to make sure the user provided a correct answer, the ``askAndValidate`` method. Both have diff --git a/components/console/helpers/index.rst b/components/console/helpers/index.rst index 1c95bc47057..d632eeeb66a 100644 --- a/components/console/helpers/index.rst +++ b/components/console/helpers/index.rst @@ -9,7 +9,10 @@ The Console Helpers dialoghelper formatterhelper + progressbar progresshelper + questionhelper + table tablehelper The Console component comes with some useful helpers. These helpers contain diff --git a/components/console/helpers/map.rst.inc b/components/console/helpers/map.rst.inc index 60b32c03975..b9a1114cfc2 100644 --- a/components/console/helpers/map.rst.inc +++ b/components/console/helpers/map.rst.inc @@ -1,4 +1,7 @@ * :doc:`/components/console/helpers/dialoghelper` * :doc:`/components/console/helpers/formatterhelper` +* :doc:`/components/console/helpers/progressbar` * :doc:`/components/console/helpers/progresshelper` +* :doc:`/components/console/helpers/questionhelper` +* :doc:`/components/console/helpers/table` * :doc:`/components/console/helpers/tablehelper` diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst new file mode 100644 index 00000000000..2ae9e64844a --- /dev/null +++ b/components/console/helpers/progressbar.rst @@ -0,0 +1,322 @@ +.. index:: + single: Console Helpers; Progress Bar + +Progress Bar +============ + +.. versionadded:: 2.5 + The Progress Bar feature was introduced in Symfony 2.5 as a replacement for + the :doc:`Progress Helper `. + +When executing longer-running commands, it may be helpful to show progress +information, which updates as your command runs: + +.. image:: /images/components/console/progressbar.gif + +To display progress details, use the +:class:`Symfony\\Component\\Console\\Helper\\ProgressBar`, pass it a total +number of units, and advance the progress as the command executes:: + + use Symfony\Component\Console\Helper\ProgressBar; + + // create a new progress bar (50 units) + $progress = new ProgressBar($output, 50); + + // start and displays the progress bar + $progress->start(); + + $i = 0; + while ($i++ < 50) { + // ... do some work + + // advance the progress bar 1 unit + $progress->advance(); + + // you can also advance the progress bar by more than 1 unit + // $progress->advance(3); + } + + // ensure that the progress bar is at 100% + $progress->finish(); + +Instead of advancing the bar by a number of steps (with the +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::advance` method), +you can also set the current progress by calling the +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::setCurrent` method. + +.. caution:: + + The progress bar only works if your platform supports ANSI codes; on other + platforms, no output is generated. + +If you don't know the number of steps in advance, just omit the steps argument +when creating the :class:`Symfony\\Component\\Console\\Helper\\ProgressBar` +instance:: + + $progress = new ProgressBar($output); + +The progress will then be displayed as a throbber: + +.. code-block:: text + + # no max steps (displays it like a throbber) + 0 [>---------------------------] + 5 [----->----------------------] + 5 [============================] + + # max steps defined + 0/3 [>---------------------------] 0% + 1/3 [=========>------------------] 33% + 3/3 [============================] 100% + +Whenever your task is finished, don't forget to call +:method:`Symfony\\Component\\Console\\Helper\\ProgressBar::finish` to ensure +that the progress bar display is refreshed with a 100% completion. + +.. note:: + + If you want to output something while the progress bar is running, + call :method:`Symfony\\Component\\Console\\Helper\\ProgressBar::clear` first. + After you're done, call + :method:`Symfony\\Component\\Console\\Helper\\ProgressBar::display` + to show the progress bar again. + +Customizing the Progress Bar +---------------------------- + +Built-in Formats +~~~~~~~~~~~~~~~~ + +By default, the information rendered on a progress bar depends on the current +level of verbosity of the ``OutputInterface`` instance: + +.. code-block:: text + + # OutputInterface::VERBOSITY_NORMAL (CLI with no verbosity flag) + 0/3 [>---------------------------] 0% + 1/3 [=========>------------------] 33% + 3/3 [============================] 100% + + # OutputInterface::VERBOSITY_VERBOSE (-v) + 0/3 [>---------------------------] 0% 1 sec + 1/3 [=========>------------------] 33% 1 sec + 3/3 [============================] 100% 1 sec + + # OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) + 0/3 [>---------------------------] 0% 1 sec + 1/3 [=========>------------------] 33% 1 sec + 3/3 [============================] 100% 1 sec + + # OutputInterface::VERBOSITY_DEBUG (-vvv) + 0/3 [>---------------------------] 0% 1 sec/1 sec 1.0 MB + 1/3 [=========>------------------] 33% 1 sec/1 sec 1.0 MB + 3/3 [============================] 100% 1 sec/1 sec 1.0 MB + +.. note:: + + If you call a command with the quiet flag (``-q``), the progress bar won't + be displayed. + +Instead of relying on the verbosity mode of the current command, you can also +force a format via ``setFormat()``:: + + $bar->setFormat('verbose'); + +The built-in formats are the following: + +* ``normal`` +* ``verbose`` +* ``very_verbose`` +* ``debug`` + +If you don't set the number of steps for your progress bar, use the ``_nomax`` +variants: + +* ``normal_nomax`` +* ``verbose_nomax`` +* ``very_verbose_nomax`` +* ``debug_nomax`` + +Custom Formats +~~~~~~~~~~~~~~ + +Instead of using the built-in formats, you can also set your own:: + + $bar->setFormat('%bar%'); + +This sets the format to only display the progress bar itself: + +.. code-block:: text + + >--------------------------- + =========>------------------ + ============================ + +A progress bar format is a string that contains specific placeholders (a name +enclosed with the ``%`` character); the placeholders are replaced based on the +current progress of the bar. Here is a list of the built-in placeholders: + +* ``current``: The current step; +* ``max``: The maximum number of steps (or 0 if no max is defined); +* ``bar``: The bar itself; +* ``percent``: The percentage of completion (not available if no max is defined); +* ``elapsed``: The time elapsed since the start of the progress bar; +* ``remaining``: The remaining time to complete the task (not available if no max is defined); +* ``estimated``: The estimated time to complete the task (not available if no max is defined); +* ``memory``: The current memory usage; +* ``message``: The current message attached to the progress bar. + +For instance, here is how you could set the format to be the same as the +``debug`` one:: + + $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%'); + +Notice the ``:6s`` part added to some placeholders? That's how you can tweak +the appearance of the bar (formatting and alignment). The part after the colon +(``:``) is used to set the ``sprintf`` format of the string. + +The ``message`` placeholder is a bit special as you must set the value +yourself:: + + $bar->setMessage('Task starts'); + $bar->start(); + + $bar->setMessage('Task in progress...'); + $bar->advance(); + + // ... + + $bar->setMessage('Task is finished'); + $bar->finish(); + +Instead of setting the format for a given instance of a progress bar, you can +also define global formats:: + + ProgressBar::setFormatDefinition('minimal', 'Progress: %percent%%'); + + $bar = new ProgressBar($output, 3); + $bar->setFormat('minimal'); + +This code defines a new ``minimal`` format that you can then use for your +progress bars: + +.. code-block:: text + + Progress: 0% + Progress: 33% + Progress: 100% + +.. tip:: + + It is almost always better to redefine built-in formats instead of creating + new ones as that allows the display to automatically vary based on the + verbosity flag of the command. + +When defining a new style that contains placeholders that are only available +when the maximum number of steps is known, you should create a ``_nomax`` +variant:: + + ProgressBar::setFormatDefinition('minimal', '%percent%% %remaining%'); + ProgressBar::setFormatDefinition('minimal_nomax', '%percent%%'); + + $bar = new ProgressBar($output); + $bar->setFormat('minimal'); + +When displaying the progress bar, the format will automatically be set to +``minimal_nomax`` if the bar does not have a maximum number of steps like in +the example above. + +.. tip:: + + A format can contain any valid ANSI codes and can also use the + Symfony-specific way to set colors:: + + ProgressBar::setFormatDefinition( + 'minimal', + '%percent%\033[32m%\033[0m %remaining%' + ); + +.. note:: + + A format can span more than one line; that's very useful when you want to + display more contextual information alongside the progress bar (see the + example at the beginning of this article). + +Bar Settings +~~~~~~~~~~~~ + +Amongst the placeholders, ``bar`` is a bit special as all the characters used +to display it can be customized:: + + // the finished part of the bar + $progress->setBarCharacter('='); + + // the unfinished part of the bar + $progress->setEmptyBarCharacter(' '); + + // the progress character + $progress->setProgressCharacter('|'); + + // the bar width + $progress->setBarWidth(50); + +.. caution:: + + For performance reasons, be careful if you set the total number of steps + to a high number. For example, if you're iterating over a large number of + items, consider setting the redraw frequency to a higher value by calling + :method:`Symfony\\Component\\Console\\Helper\\ProgressHelper::setRedrawFrequency`, + so it updates on only some iterations:: + + $progress->start($output, 50000); + + // update every 100 iterations + $progress->setRedrawFrequency(100); + + $i = 0; + while ($i++ < 50000) { + // ... do some work + + $progress->advance(); + } + +Custom Placeholders +~~~~~~~~~~~~~~~~~~~ + +If you want to display some information that depends on the progress bar +display that are not available in the list of built-in placeholders, you can +create your own. Let's see how you can create a ``remaining_steps`` placeholder +that displays the number of remaining steps:: + + ProgressBar::setPlaceholderFormatter( + '%remaining_steps%', + function (ProgressBar $bar, OutputInterface $output) { + return $bar->getMaxSteps() - $bar->getStep(); + } + ); + +Custom Messages +~~~~~~~~~~~~~~~ + +The ``%message%`` placeholder allows you to specify a custom message to be +displayed with the progress bar. But if you need more than one, just define +your own:: + + $bar->setMessage('Task starts'); + $bar->setMessage('', 'filename'); + $bar->start(); + + $bar->setMessage('Task is in progress...'); + while ($file = array_pop($files)) { + $bar->setMessage($filename, 'filename'); + $bar->advance(); + } + + $bar->setMessage('Task is finished'); + $bar->setMessage('', 'filename'); + $bar->finish(); + +For the ``filename`` to be part of the progress bar, just add the +``%filename%`` placeholder in your format:: + + $bar->setFormat(" %message%\n %step%/%max%\n Working on %filename%"); diff --git a/components/console/helpers/progresshelper.rst b/components/console/helpers/progresshelper.rst index 0ed67d73b76..3662fff8800 100644 --- a/components/console/helpers/progresshelper.rst +++ b/components/console/helpers/progresshelper.rst @@ -4,15 +4,19 @@ Progress Helper =============== -.. versionadded:: 2.2 - The ``progress`` helper was introduced in Symfony 2.2. - .. versionadded:: 2.3 The ``setCurrent`` method was introduced in Symfony 2.3. .. versionadded:: 2.4 The ``clear`` method was introduced in Symfony 2.4. +.. caution:: + + The Progress Helper was deprecated in Symfony 2.5 and will be removed in + Symfony 3.0. You should now use the + :doc:`Progress Bar ` instead which + is more powerful. + When executing longer-running commands, it may be helpful to show progress information, which updates as your command runs: @@ -28,7 +32,7 @@ pass it a total number of units, and advance the progress as your command execut while ($i++ < 50) { // ... do some work - // advance the progress bar 1 unit + // advances the progress bar 1 unit $progress->advance(); } @@ -82,7 +86,7 @@ To see other available options, check the API documentation for $progress->start($output, 50000); - // update every 100 iterations + // updates every 100 iterations $progress->setRedrawFrequency(100); $i = 0; diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst new file mode 100644 index 00000000000..0f1031392c1 --- /dev/null +++ b/components/console/helpers/questionhelper.rst @@ -0,0 +1,263 @@ +.. index:: + single: Console Helpers; Question Helper + +Question Helper +=============== + +.. versionadded:: 2.5 + The Question Helper was introduced in Symfony 2.5. + +The :class:`Symfony\\Component\\Console\\Helper\\QuestionHelper` provides +functions to ask the user for more information. It is included in the default +helper set, which you can get by calling +:method:`Symfony\\Component\\Console\\Command\\Command::getHelperSet`:: + + $helper = $this->getHelperSet()->get('question'); + +The Question Helper has a single method +:method:`Symfony\\Component\\Console\\Command\\Command::ask` that needs an +:class:`Symfony\\Component\\Console\\Output\\InputInterface` instance as the +first argument, an :class:`Symfony\\Component\\Console\\Output\\OutputInterface` +instance as the second argument and a +:class:`Symfony\\Component\\Console\\Question\\Question` as last argument. + +Asking the User for Confirmation +-------------------------------- + +Suppose you want to confirm an action before actually executing it. Add +the following to your command:: + + use Symfony\Component\Console\Question\ConfirmationQuestion; + // ... + + $helper = $this->getHelperSet()->get('question'); + $question = new ConfirmationQuestion('Continue with this action?', false); + + if (!$helper->ask($input, $output, $question)) { + return; + } + +In this case, the user will be asked "Continue with this action?". If the user +answers with ``y`` it returns ``true`` or ``false`` if they answer with ``n``. +The second argument to +:method:`Symfony\\Component\\Console\\Question\\ConfirmationQuestion::__construct` +is the default value to return if the user doesn't enter any input. Any other +input will ask the same question again. + +Asking the User for Information +------------------------------- + +You can also ask a question with more than a simple yes/no answer. For instance, +if you want to know a bundle name, you can add this to your command:: + + use Symfony\Component\Console\Question\Question; + // ... + + $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle'); + + $bundle = $helper->ask($input, $output, $question); + +The user will be asked "Please enter the name of the bundle". They can type +some name which will be returned by the +:method:`Symfony\\Component\\Console\\Helper\\QuestionHelper::ask` method. +If they leave it empty, the default value (``AcmeDemoBundle`` here) is returned. + +Let the User Choose from a List of Answers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you have a predefined set of answers the user can choose from, you +could use a :class:`Symfony\\Component\\Console\\Question\\ChoiceQuestion` +which makes sure that the user can only enter a valid string +from a predefined list:: + + use Symfony\Component\Console\Question\ChoiceQuestion; + // ... + + $helper = $app->getHelperSet()->get('question'); + $question = new ChoiceQuestion( + 'Please select your favorite color (defaults to red)', + array('red', 'blue', 'yellow'), + 'red' + ); + $question->setErrorMessage('Color %s is invalid.'); + + $color = $helper->ask($input, $output, $question); + $output->writeln('You have just selected: '.$color); + + // ... do something with the color + +The option which should be selected by default is provided with the third +argument of the constructor. The default is ``null``, which means that no +option is the default one. + +If the user enters an invalid string, an error message is shown and the user +is asked to provide the answer another time, until they enter a valid string +or reach the maximum number of attempts. The default value for the maximum number +of attempts is ``null``, which means infinite number attempts. You can define +your own error message using +:method:`Symfony\\Component\\Console\\Question\\ChoiceQuestion::setErrorMessage`. + +Multiple Choices +................ + +Sometimes, multiple answers can be given. The ``ChoiceQuestion`` provides this +feature using comma separated values. This is disabled by default, to enable +this use :method:`Symfony\\Component\\Console\\Question\\ChoiceQuestion::setMultiselect`:: + + use Symfony\Component\Console\Question\ChoiceQuestion; + // ... + + $helper = $app->getHelperSet()->get('question'); + $question = new ChoiceQuestion( + 'Please select your favorite color (defaults to red)', + array('red', 'blue', 'yellow'), + 'red' + ); + $question->setMultiselect(true); + + $colors = $helper->ask($input, $output, $question); + $output->writeln('You have just selected: ' . implode(', ', $colors)); + +Now, when the user enters ``1,2``, the result will be: +``You have just selected: blue, yellow``. + +Autocompletion +~~~~~~~~~~~~~~ + +You can also specify an array of potential answers for a given question. These +will be autocompleted as the user types:: + + use Symfony\Component\Console\Question\Question; + // ... + + $bundles = array('AcmeDemoBundle', 'AcmeBlogBundle', 'AcmeStoreBundle'); + $question = new Question('Please enter the name of a bundle', 'FooBundle'); + $question->setAutocompleterValues($bundles); + + $name = $helper->ask($input, $output, $question); + +Hiding the User's Response +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also ask a question and hide the response. This is particularly +convenient for passwords:: + + use Symfony\Component\Console\Question\Question; + // ... + + $question = new Question('What is the database password?'); + $question->setHidden(true); + $question->setHiddenFallback(false); + + $password = $helper->ask($input, $output, $question); + +.. caution:: + + When you ask for a hidden response, Symfony will use either a binary, change + stty mode or use another trick to hide the response. If none is available, + it will fallback and allow the response to be visible unless you set this + behavior to ``false`` using + :method:`Symfony\\Component\\Console\\Question\\Question::setHiddenFallback` + like in the example above. In this case, a ``RuntimeException`` + would be thrown. + +Validating the Answer +--------------------- + +You can even validate the answer. For instance, in a previous example you asked +for the bundle name. Following the Symfony naming conventions, it should +be suffixed with ``Bundle``. You can validate that by using the +:method:`Symfony\\Component\\Console\\Question\\Question::setValidator` +method:: + + use Symfony\Component\Console\Question\Question; + // ... + + $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle'); + $question->setValidator(function ($answer) { + if ('Bundle' !== substr($answer, -6)) { + throw new \RuntimeException( + 'The name of the bundle should be suffixed with \'Bundle\'' + ); + } + return $answer; + }); + $question->setMaxAttempts(2); + + $name = $helper->ask($input, $output, $question); + +The ``$validator`` is a callback which handles the validation. It should +throw an exception if there is something wrong. The exception message is displayed +in the console, so it is a good practice to put some useful information in it. The +callback function should also return the value of the user's input if the validation +was successful. + +You can set the max number of times to ask with the +:method:`Symfony\\Component\\Console\\Question\\Question::setMaxAttempts` method. +If you reach this max number it will use the default value. Using ``null`` means +the amount of attempts is infinite. The user will be asked as long as they provide an +invalid answer and will only be able to proceed if their input is valid. + +Validating a Hidden Response +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also use a validator with a hidden question:: + + use Symfony\Component\Console\Question\Question; + // ... + + $helper = $this->getHelperSet()->get('question'); + + $question = new Question('Please enter your password'); + $question->setValidator(function ($value) { + if (trim($value) == '') { + throw new \Exception('The password can not be empty'); + } + + return $value; + }); + $question->setHidden(true); + $question->setMaxAttempts(20); + + $password = $helper->ask($input, $output, $question); + + +Testing a Command that Expects Input +------------------------------------ + +If you want to write a unit test for a command which expects some kind of input +from the command line, you need to set the helper input stream:: + + use Symfony\Component\Console\Helper\QuestionHelper; + use Symfony\Component\Console\Helper\HelperSet; + use Symfony\Component\Console\Tester\CommandTester; + + // ... + public function testExecute() + { + // ... + $commandTester = new CommandTester($command); + + $helper = $command->getHelper('question'); + $helper->setInputStream($this->getInputStream('Test\\n')); + // Equals to a user inputting "Test" and hitting ENTER + // If you need to enter a confirmation, "yes\n" will work + + $commandTester->execute(array('command' => $command->getName())); + + // $this->assertRegExp('/.../', $commandTester->getDisplay()); + } + + protected function getInputStream($input) + { + $stream = fopen('php://memory', 'r+', false); + fputs($stream, $input); + rewind($stream); + + return $stream; + } + +By setting the input stream of the ``QuestionHelper``, you imitate what the +console would do internally with all user input through the cli. This way +you can test any user interaction (even complex ones) by passing an appropriate +input stream. diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst new file mode 100644 index 00000000000..7729ecce6eb --- /dev/null +++ b/components/console/helpers/table.rst @@ -0,0 +1,142 @@ +.. index:: + single: Console Helpers; Table + +Table +===== + +.. versionadded:: 2.5 + The ``Table`` class was introduced in Symfony 2.5 as a replacement for the + :doc:`Table Helper `. + +When building a console application it may be useful to display tabular data: + +.. code-block:: text + + +---------------+--------------------------+------------------+ + | ISBN | Title | Author | + +---------------+--------------------------+------------------+ + | 99921-58-10-7 | Divine Comedy | Dante Alighieri | + | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | + | 80-902734-1-6 | And Then There Were None | Agatha Christie | + +---------------+--------------------------+------------------+ + +To display a table, use :class:`Symfony\\Component\\Console\\Helper\\Table`, +set the headers, set the rows and then render the table:: + + use Symfony\Component\Helper\Table; + + $table = new Table($output); + $table + ->setHeaders(array('ISBN', 'Title', 'Author')) + ->setRows(array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + )) + ; + $table->render(); + +You can add a table separator anywhere in the output by passing an instance of +:class:`Symfony\\Component\\Console\\Helper\\TableSeparator` as a row:: + + use Symfony\Component\Helper\TableSeparator; + + $table->setRows(array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + new TableSeparator(), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + )); + +.. code-block:: text + + +---------------+--------------------------+------------------+ + | ISBN | Title | Author | + +---------------+--------------------------+------------------+ + | 99921-58-10-7 | Divine Comedy | Dante Alighieri | + | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + +---------------+--------------------------+------------------+ + | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | + | 80-902734-1-6 | And Then There Were None | Agatha Christie | + +---------------+--------------------------+------------------+ + +The table style can be changed to any built-in styles via +:method:`Symfony\\Component\\Console\\Helper\\Table::setStyle`:: + + // same as calling nothing + $table->setStyle('default'); + + // changes the default style to compact + $table->setStyle('compact'); + $table->render(); + +This code results in: + +.. code-block:: text + + ISBN Title Author + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + +You can also set the style to ``borderless``:: + + $table->setStyle('borderless'); + $table->render(); + +which outputs: + +.. code-block:: text + + =============== ========================== ================== + ISBN Title Author + =============== ========================== ================== + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + =============== ========================== ================== + +If the built-in styles do not fit your need, define your own:: + + use Symfony\Component\Helper\TableStyle; + + // by default, this is based on the default style + $style = new TableStyle(); + + // customize the style + $style + ->setHorizontalBorderChar('|') + ->setVerticalBorderChar('-') + ->setCrossingChar(' ') + ; + + // use the style for this table + $table->setStyle($style); + +Here is a full list of things you can customize: + +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setPaddingChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setHorizontalBorderChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setVerticalBorderChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setCrossingChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setCellHeaderFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setCellRowFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setBorderFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setPadType` + +.. tip:: + + You can also register a style globally:: + + // register the style under the colorful name + Table::setStyleDefinition('colorful', $style); + + // use it for a table + $table->setStyle('colorful'); + + This method can also be used to override a built-in style. diff --git a/components/console/helpers/tablehelper.rst b/components/console/helpers/tablehelper.rst index 6eec762e7d0..93643837181 100644 --- a/components/console/helpers/tablehelper.rst +++ b/components/console/helpers/tablehelper.rst @@ -7,6 +7,13 @@ Table Helper .. versionadded:: 2.3 The ``table`` helper was introduced in Symfony 2.3. +.. caution:: + + The Table Helper was deprecated in Symfony 2.5 and will be removed in + Symfony 3.0. You should now use the + :doc:`Table ` class instead which is + more powerful. + When building a console application it may be useful to display tabular data: .. image:: /images/components/console/table.png diff --git a/components/console/index.rst b/components/console/index.rst index c814942d018..b449eff094b 100644 --- a/components/console/index.rst +++ b/components/console/index.rst @@ -6,6 +6,8 @@ Console introduction usage + changing_default_command single_command_tool events + logger helpers/index diff --git a/components/console/introduction.rst b/components/console/introduction.rst index 0f68f44ea81..5d1c8b31b5e 100644 --- a/components/console/introduction.rst +++ b/components/console/introduction.rst @@ -402,10 +402,11 @@ Console Helpers The console component also contains a set of "helpers" - different small tools capable of helping you with different tasks: -* :doc:`/components/console/helpers/dialoghelper`: interactively ask the user for information +* :doc:`/components/console/helpers/questionhelper`: interactively ask the user for information * :doc:`/components/console/helpers/formatterhelper`: customize the output colorization * :doc:`/components/console/helpers/progresshelper`: shows a progress bar * :doc:`/components/console/helpers/tablehelper`: displays tabular data as a table +* :doc:`/components/console/helpers/dialoghelper`: (deprecated) interactively ask the user for information Testing Commands ---------------- @@ -526,6 +527,7 @@ Learn More! * :doc:`/components/console/usage` * :doc:`/components/console/single_command_tool` +* :doc:`/components/console/changing_default_command` * :doc:`/components/console/events` .. _Packagist: https://packagist.org/packages/symfony/console diff --git a/components/console/logger.rst b/components/console/logger.rst new file mode 100644 index 00000000000..43951c63130 --- /dev/null +++ b/components/console/logger.rst @@ -0,0 +1,108 @@ +.. index:: + single: Console; Logger + +Using the Logger +================ + +.. versionadded:: 2.5 + The :class:`Symfony\\Component\\Console\\Logger\\ConsoleLogger` was + introduced in Symfony 2.5. + +The Console component comes with a standalone logger complying with the +`PSR-3`_ standard. Depending on the verbosity setting, log messages will +be sent to the :class:`Symfony\\Component\\Console\\Output\\OutputInterface` +instance passed as a parameter to the constructor. + +The logger does not have any external dependency except ``php-fig/log``. +This is useful for console applications and commands needing a lightweight +PSR-3 compliant logger:: + + namespace Acme; + + use Psr\Log\LoggerInterface; + + class MyDependency + { + private $logger; + + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + + public function doStuff() + { + $this->logger->info('I love Tony Vairelles\' hairdresser.'); + } + } + +You can rely on the logger to use this dependency inside a command:: + + namespace Acme\Console\Command; + + use Acme\MyDependency; + use Symfony\Component\Console\Command\Command; + use Symfony\Component\Console\Input\InputInterface; + use Symfony\Component\Console\Output\OutputInterface; + use Symfony\Component\Console\Logger\ConsoleLogger; + + class MyCommand extends Command + { + protected function configure() + { + $this + ->setName('my:command') + ->setDescription( + 'Use an external dependency requiring a PSR-3 logger' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $logger = new ConsoleLogger($output); + + $myDependency = new MyDependency($logger); + $myDependency->doStuff(); + } + } + +The dependency will use the instance of +:class:`Symfony\\Component\\Console\\Logger\\ConsoleLogger` as logger. +Log messages emitted will be displayed on the console output. + +Verbosity +--------- + +Depending on the verbosity level that the command is run, messages may or +may not be sent to the :class:`Symfony\\Component\\Console\\Output\\OutputInterface` +instance. + +By default, the console logger behaves like the +:doc:`Monolog's Console Handler `. +The association between the log level and the verbosity can be configured +through the second parameter of the :class:`Symfony\\Component\\Console\\ConsoleLogger` +constructor:: + + // ... + $verbosityLevelMap = array( + LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, + LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL, + ); + $logger = new ConsoleLogger($output, $verbosityLevelMap); + +Color +----- + +The logger outputs the log messages formatted with a color reflecting their +level. This behavior is configurable through the third parameter of the +constructor:: + + // ... + $formatLevelMap = array( + LogLevel::CRITICAL => self::INFO, + LogLevel::DEBUG => self::ERROR, + ); + $logger = new ConsoleLogger($output, array(), $formatLevelMap); + +.. _PSR-3: http://www.php-fig.org/psr/psr-3/ diff --git a/components/console/single_command_tool.rst b/components/console/single_command_tool.rst index 5082575def6..609f7a0c2e3 100644 --- a/components/console/single_command_tool.rst +++ b/components/console/single_command_tool.rst @@ -1,5 +1,5 @@ .. index:: - single: Console; Single command application + single: Console; Single command application Building a single Command Application ===================================== diff --git a/components/dependency_injection/advanced.rst b/components/dependency_injection/advanced.rst index 77056c296ce..95d7e5b2697 100644 --- a/components/dependency_injection/advanced.rst +++ b/components/dependency_injection/advanced.rst @@ -185,3 +185,95 @@ the service itself gets loaded. To do so, you can use the ``file`` directive. Notice that Symfony will internally call the PHP statement ``require_once``, which means that your file will be included only once per request. + +Decorating Services +------------------- + +.. versionadded:: 2.5 + Decorated services were introduced in Symfony 2.5. + +When overriding an existing definition, the old service is lost: + +.. code-block:: php + + $container->register('foo', 'FooService'); + + // this is going to replace the old definition with the new one + // old definition is lost + $container->register('foo', 'CustomFooService'); + +Most of the time, that's exactly what you want to do. But sometimes, +you might want to decorate the old one instead. In this case, the +old service should be kept around to be able to reference it in the +new one. This configuration replaces ``foo`` with a new one, but keeps +a reference of the old one as ``bar.inner``: + +.. configuration-block:: + + .. code-block:: yaml + + bar: + public: false + class: stdClass + decorates: foo + arguments: ["@bar.inner"] + + .. code-block:: xml + + + + + + .. code-block:: php + + use Symfony\Component\DependencyInjection\Reference; + + $container->register('bar', 'stdClass') + ->addArgument(new Reference('bar.inner')) + ->setPublic(false) + ->setDecoratedService('foo'); + +Here is what's going on here: the ``setDecoratedService()` method tells +the container that the ``bar`` service should replace the ``foo`` service, +renaming ``foo`` to ``bar.inner``. +By convention, the old ``foo`` service is going to be renamed ``bar.inner``, +so you can inject it into your new service. + +.. note:: + The generated inner id is based on the id of the decorator service + (``bar`` here), not of the decorated service (``foo`` here). This is + mandatory to allow several decorators on the same service (they need to have + different generated inner ids). + + Most of the time, the decorator should be declared private, as you will not + need to retrieve it as ``bar`` from the container. The visibility of the + decorated ``foo`` service (which is an alias for ``bar``) will still be the + same as the original ``foo`` visibility. + +You can change the inner service name if you want to: + +.. configuration-block:: + + .. code-block:: yaml + + bar: + class: stdClass + public: false + decorates: foo + decoration_inner_name: bar.wooz + arguments: ["@bar.wooz"] + + .. code-block:: xml + + + + + + .. code-block:: php + + use Symfony\Component\DependencyInjection\Reference; + + $container->register('bar', 'stdClass') + ->addArgument(new Reference('bar.wooz')) + ->setPublic(false) + ->setDecoratedService('foo', 'bar.wooz'); diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index 9acbdde0aad..1868cacc848 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -278,10 +278,6 @@ but also load a secondary one only if a certain parameter is set:: Prepending Configuration Passed to the Extension ------------------------------------------------ -.. versionadded:: 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`:: diff --git a/components/finder.rst b/components/finder.rst index 621d98afe81..48a6c55a9b9 100644 --- a/components/finder.rst +++ b/components/finder.rst @@ -82,9 +82,6 @@ Search in several locations by chaining calls to $finder->files()->in(__DIR__)->in('/elsewhere'); -.. versionadded:: 2.2 - Wildcard support was introduced in version 2.2. - Use wildcard characters to search in the directories matching a pattern:: $finder->in('src/Symfony/*/*/Resources'); @@ -206,9 +203,6 @@ The ``notContains()`` method excludes files containing given pattern:: Path ~~~~ -.. versionadded:: 2.2 - The ``path()`` and ``notPath()`` methods were introduced in Symfony 2.2. - Restrict files and directories by path with the :method:`Symfony\\Component\\Finder\\Finder::path` method:: diff --git a/components/http_foundation/introduction.rst b/components/http_foundation/introduction.rst index 7308bec4555..4db19238609 100644 --- a/components/http_foundation/introduction.rst +++ b/components/http_foundation/introduction.rst @@ -256,10 +256,6 @@ by using the following methods: .. versionadded:: 2.4 The ``getEncodings()`` method was introduced in Symfony 2.4. -.. versionadded:: 2.2 - The :class:`Symfony\\Component\\HttpFoundation\\AcceptHeader` class was - introduced in Symfony 2.2. - If you need to get full access to parsed data from ``Accept``, ``Accept-Language``, ``Accept-Charset`` or ``Accept-Encoding``, you can use :class:`Symfony\\Component\\HttpFoundation\\AcceptHeader` utility class:: @@ -494,10 +490,6 @@ abstracts the hard work behind a simple API:: $response->headers->set('Content-Disposition', $d); -.. versionadded:: 2.2 - The :class:`Symfony\\Component\\HttpFoundation\\BinaryFileResponse` - class was introduced in Symfony 2.2. - Alternatively, if you are serving a static file, you can use a :class:`Symfony\\Component\\HttpFoundation\\BinaryFileResponse`:: diff --git a/components/map.rst.inc b/components/map.rst.inc index d3057cb53c6..49c1ee10249 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -4,6 +4,7 @@ * :doc:`/components/class_loader/introduction` * :doc:`/components/class_loader/class_loader` + * :doc:`/components/class_loader/psr4_class_loader` * :doc:`/components/class_loader/map_class_loader` * :doc:`/components/class_loader/cache_class_loader` * :doc:`/components/class_loader/debug_class_loader` @@ -20,7 +21,9 @@ * :doc:`/components/console/introduction` * :doc:`/components/console/usage` * :doc:`/components/console/single_command_tool` + * :doc:`/components/console/changing_default_command` * :doc:`/components/console/events` + * :doc:`/components/console/logger` * :doc:`/components/console/helpers/index` * **CssSelector** diff --git a/components/options_resolver.rst b/components/options_resolver.rst index 6e239e2f421..eaad4bc7eb1 100644 --- a/components/options_resolver.rst +++ b/components/options_resolver.rst @@ -327,6 +327,28 @@ There is also an method, which you can use if you want to add an allowed value to the previously configured allowed values. +.. versionadded:: 2.5 + The callback support for allowed values was introduced in Symfony 2.5. + +If you need to add some more logic to the value validation process, you can pass a callable +as an allowed value:: + + // ... + protected function setDefaultOptions(OptionsResolverInterface $resolver) + { + // ... + + $resolver->setAllowedValues(array( + 'transport' => function($value) { + return false !== strpos($value, 'mail'); + }, + )); + } + +.. caution:: + + Note that using this together with ``addAllowedValues`` will not work. + Configure Allowed Types ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/components/process.rst b/components/process.rst index 27a6221846e..a2d8dc67e4d 100644 --- a/components/process.rst +++ b/components/process.rst @@ -36,10 +36,6 @@ a command in a sub-process:: The component takes care of the subtle differences between the different platforms when executing the command. -.. versionadded:: 2.2 - The ``getIncrementalOutput()`` and ``getIncrementalErrorOutput()`` methods - were introduced in Symfony 2.2. - The ``getOutput()`` method always return the whole content of the standard output of the command and ``getErrorOutput()`` the content of the error output. Alternatively, the :method:`Symfony\\Component\\Process\\Process::getIncrementalOutput` @@ -286,6 +282,34 @@ You can access the `pid`_ of a running process with the you may have to prefix your commands with `exec`_. Please read `Symfony Issue#5759`_ to understand why this is happening. +Disabling Output +---------------- + +.. versionadded:: 2.5 + The :method:`Symfony\\Component\\Process\\Process::disableOutput` and + :method:`Symfony\\Component\\Process\\Process::enableOutput` methods were + introduced in Symfony 2.5. + +As standard output and error output are always fetched from the underlying process, +it might be convenient to disable output in some cases to save memory. +Use :method:`Symfony\\Component\\Process\\Process::disableOutput` and +:method:`Symfony\\Component\\Process\\Process::enableOutput` to toggle this feature:: + + use Symfony\Component\Process\Process; + + $process = new Process('/usr/bin/php worker.php'); + $process->disableOutput(); + $process->run(); + +.. caution:: + + You can not enable or disable the output while the process is running. + + If you disable the output, you cannot access ``getOutput``, + ``getIncrementalOutput``, ``getErrorOutput`` or ``getIncrementalErrorOutput``. + Moreover, you could not pass a callback to the ``start``, ``run`` or ``mustRun`` + methods or use ``setIdleTimeout``. + .. _`Symfony Issue#5759`: https://github.com/symfony/symfony/issues/5759 .. _`PHP Bug#39992`: https://bugs.php.net/bug.php?id=39992 .. _`exec`: http://en.wikipedia.org/wiki/Exec_(operating_system) diff --git a/components/property_access/introduction.rst b/components/property_access/introduction.rst index a9eb4083fd9..0a938117923 100644 --- a/components/property_access/introduction.rst +++ b/components/property_access/introduction.rst @@ -8,10 +8,6 @@ The PropertyAccess Component The PropertyAccess component provides function to read and write from/to an object or array using a simple string notation. -.. versionadded:: 2.2 - The PropertyAccess component was introduced in Symfony 2.2. Previously, - the ``PropertyPath`` class was located in the Form component. - Installation ------------ @@ -313,6 +309,39 @@ see `Enable other Features`_. echo $person->getWouter(); // array(...) +Checking Property Paths +----------------------- + +.. versionadded:: 2.5 + The + :method:`PropertyAccessor::isReadable ` + and + :method:`PropertyAccessor::isWritable ` + methods were introduced in Symfony 2.5. + +When you want to check whether +:method:`PropertyAccessor::getValue` +can safely be called without actually calling that method, you can use +:method:`PropertyAccessor::isReadable` +instead:: + + $person = new Person(); + + if ($accessor->isReadable($person, 'firstName') { + // ... + } + +The same is possible for :method:`PropertyAccessor::setValue`: +Call the +:method:`PropertyAccessor::isWritable` +method to find out whether a property path can be updated:: + + $person = new Person(); + + if ($accessor->isWritable($person, 'firstName') { + // ... + } + Mixing Objects and Arrays ------------------------- diff --git a/components/routing/hostname_pattern.rst b/components/routing/hostname_pattern.rst index b3052f66a74..b97fe30bb04 100644 --- a/components/routing/hostname_pattern.rst +++ b/components/routing/hostname_pattern.rst @@ -4,9 +4,6 @@ How to Match a Route Based on the Host ====================================== -.. versionadded:: 2.2 - Host matching support was introduced in Symfony 2.2 - You can also match on the HTTP *host* of the incoming request. .. configuration-block:: diff --git a/components/routing/introduction.rst b/components/routing/introduction.rst index e751b0a36d2..3ea410780db 100644 --- a/components/routing/introduction.rst +++ b/components/routing/introduction.rst @@ -93,9 +93,6 @@ A full route definition can contain up to seven parts: 7. An array of methods. These enforce a certain HTTP request method (``HEAD``, ``GET``, ``POST``, ...). -.. versionadded:: 2.2 - Host matching support was introduced in Symfony 2.2 - Take the following route, which combines several of these ideas:: $route = new Route( @@ -161,7 +158,6 @@ host to all routes of a subtree using methods provided by the $rootCollection->addCollection($subCollection); - Set the Request Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/components/serializer.rst b/components/serializer.rst index aeaabeb6067..872c5936e8b 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -62,6 +62,7 @@ exists in your project:: { private $age; private $name; + private $sportsman; // Getters public function getName() @@ -74,6 +75,12 @@ exists in your project:: return $this->age; } + // Issers + public function isSportsman() + { + return $this->sportsman; + } + // Setters public function setName($name) { @@ -84,6 +91,11 @@ exists in your project:: { $this->age = $age; } + + public function setSportsman($sportsman) + { + $this->sportsman = $sportsman; + } } Now, if you want to serialize this object into JSON, you only need to @@ -92,10 +104,11 @@ use the Serializer service created before:: $person = new Acme\Person(); $person->setName('foo'); $person->setAge(99); + $person->setSportsman(false); $jsonContent = $serializer->serialize($person, 'json'); - // $jsonContent contains {"name":"foo","age":99} + // $jsonContent contains {"name":"foo","age":99,"sportsman":false} echo $jsonContent; // or return it in a Response @@ -124,7 +137,7 @@ method on the normalizer definition:: $encoder = new JsonEncoder(); $serializer = new Serializer(array($normalizer), array($encoder)); - $serializer->serialize($person, 'json'); // Output: {"name":"foo"} + $serializer->serialize($person, 'json'); // Output: {"name":"foo","sportsman":false} Deserializing an Object ----------------------- @@ -136,6 +149,7 @@ of the ``Person`` class would be encoded in XML format:: foo 99 + false EOF; @@ -181,6 +195,18 @@ method on the normalizer definition:: As a final result, the deserializer uses the ``first_name`` attribute as if it were ``firstName`` and uses the ``getFirstName`` and ``setFirstName`` methods. +Serializing Boolean Attributes +------------------------------ + +.. versionadded:: 2.5 + Support for ``is*`` accessors in + :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer` + was introduced in Symfony 2.5. + +If you are using isser methods (methods prefixed by ``is``, like +``Acme\Person::isSportsman()``), the Serializer component will automatically +detect and use it to serialize related attributes. + Using Callbacks to Serialize Properties with Object Instances ------------------------------------------------------------- diff --git a/components/stopwatch.rst b/components/stopwatch.rst index e9506ce4c8f..58c76b85cff 100644 --- a/components/stopwatch.rst +++ b/components/stopwatch.rst @@ -7,10 +7,6 @@ The Stopwatch Component The Stopwatch component provides a way to profile code. -.. versionadded:: 2.2 - The Stopwatch component was introduced in Symfony 2.2. Previously, the - ``Stopwatch`` class was located in the HttpKernel component. - Installation ------------ @@ -35,10 +31,16 @@ microtime by yourself. Instead, use the simple // ... some code goes here $event = $stopwatch->stop('eventName'); +.. versionadded:: 2.5 + The ``getEvent()`` method was introduced in Symfony 2.5 + The :class:`Symfony\\Component\\Stopwatch\\StopwatchEvent` object can be retrieved -from the :method:`Symfony\\Component\\Stopwatch\\Stopwatch::start`, -:method:`Symfony\\Component\\Stopwatch\\Stopwatch::stop` and -:method:`Symfony\\Component\\Stopwatch\\Stopwatch::lap` methods. +from the :method:`Symfony\\Component\\Stopwatch\\Stopwatch::start`, +:method:`Symfony\\Component\\Stopwatch\\Stopwatch::stop`, +:method:`Symfony\\Component\\Stopwatch\\Stopwatch::lap` and +:method:`Symfony\\Component\\Stopwatch\\Stopwatch::getEvent` methods. +The latter should be used when you need to retrieve the duration of an event +while it is still running. You can also provide a category name to an event:: diff --git a/components/templating/helpers/assetshelper.rst b/components/templating/helpers/assetshelper.rst index 57ef49f0802..8e8dbf857bc 100644 --- a/components/templating/helpers/assetshelper.rst +++ b/components/templating/helpers/assetshelper.rst @@ -47,6 +47,23 @@ You can also specify a URL to use in the second parameter of the constructor:: Now URLs are rendered like ``http://cdn.example.com/images/logo.png``. +.. versionadded:: 2.5 + Absolute URLs for assets were introduced in Symfony 2.5. + +You can also use the third argument of the helper to force an absolute URL: + +.. code-block:: html+php + + + + +.. note:: + + If you already set a URL in the constructor, using the third argument of + ``getUrl`` will not affect the generated URL. + Versioning ---------- @@ -63,6 +80,19 @@ is used in :phpfunction:`sprintf`. The first argument is the path and the second is the version. For instance, ``%s?v=%s`` will be rendered as ``/images/logo.png?v=328rad75``. +.. versionadded:: 2.5 + On-demand versioned URLs for assets were introduced in Symfony 2.5. + +You can also generate a versioned URL on an asset-by-asset basis using the +fourth argument of the helper: + +.. code-block:: html+php + + + + Multiple Packages ----------------- diff --git a/cookbook/configuration/apache_router.rst b/cookbook/configuration/apache_router.rst index d765295147a..09c2925b4b5 100644 --- a/cookbook/configuration/apache_router.rst +++ b/cookbook/configuration/apache_router.rst @@ -7,6 +7,13 @@ How to use the Apache Router Symfony2, while fast out of the box, also provides various ways to increase that speed with a little bit of tweaking. One of these ways is by letting Apache handle routes directly, rather than using Symfony2 for this task. +.. caution:: + + Apache router was deprecated in Symfony 2.5 and will be removed in Symfony + 3.0. Since the PHP implementation of the Router was improved, performance + gains were no longer significant (while it's very hard to replicate the + same behavior). + Change Router Configuration Parameters -------------------------------------- diff --git a/cookbook/console/console_command.rst b/cookbook/console/console_command.rst index 01162d4b519..aded8aea91b 100644 --- a/cookbook/console/console_command.rst +++ b/cookbook/console/console_command.rst @@ -195,14 +195,14 @@ instead of To be able to use the fully set up service container for your console tests you can extend your test from -:class:`Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase`:: +:class:`Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase`:: use Symfony\Component\Console\Tester\CommandTester; use Symfony\Bundle\FrameworkBundle\Console\Application; - use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Acme\DemoBundle\Command\GreetCommand; - class ListCommandTest extends WebTestCase + class ListCommandTest extends KernelTestCase { public function testExecute() { @@ -226,3 +226,13 @@ you can extend your test from // ... } } + +.. versionadded:: 2.5 + :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase` was + extracted from :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase` + in Symfony 2.5. ``WebTestCase`` inherits from ``KernelTestCase``. The + ``WebTestCase`` creates an instance of + :class:`Symfony\\Bundle\\FrameworkBundle\\Client` via ``createClient()``, + while ``KernelTestCase`` creates an instance of + :class:`Symfony\\Component\\HttpKernel\\KernelInterface` via + ``createKernel()``. diff --git a/cookbook/console/sending_emails.rst b/cookbook/console/sending_emails.rst index b5f1ba41cb2..1fd86788d0d 100644 --- a/cookbook/console/sending_emails.rst +++ b/cookbook/console/sending_emails.rst @@ -17,16 +17,13 @@ what URL it should use when generating URLs. There are two ways of configuring the request context: at the application level and per Command. -Configuring the Request Context globally +Configuring the Request Context Globally ---------------------------------------- -.. versionadded: 2.2 - The ``base_url`` parameter was introduced in Symfony 2.2. - To configure the Request Context - which is used by the URL Generator - you can redefine the parameters it uses as default values to change the default host -(localhost) and scheme (http). Starting with Symfony 2.2 you can also configure -the base path if Symfony is not running in the root directory. +(localhost) and scheme (http). You can also configure the base path if Symfony +is not running in the root directory. Note that this does not impact URLs generated via normal web requests, since those will override the defaults. diff --git a/cookbook/controller/error_pages.rst b/cookbook/controller/error_pages.rst index 3cdf7deaec1..3766fa56b70 100644 --- a/cookbook/controller/error_pages.rst +++ b/cookbook/controller/error_pages.rst @@ -14,20 +14,12 @@ the status code that should be set for the given exception. Error pages can be customized in two different ways, depending on how much control you need: -1. Customize the error templates of the different error pages (explained below); +1. Customize the error templates of the different error pages; -2. Replace the default exception controller ``twig.controller.exception:showAction`` - with your own controller and handle it however you want (see - :ref:`exception_controller in the Twig reference `). - The default exception controller is registered as a service - the actual - class is ``Symfony\Bundle\TwigBundle\Controller\ExceptionController``. +2. Replace the default exception controller ``twig.controller.exception:showAction``. -.. tip:: - - The customization of exception handling is actually much more powerful - than what's written here. An internal event, ``kernel.exception``, is thrown - which allows complete control over exception handling. For more - information, see :ref:`kernel-kernel.exception`. +The default ExceptionController +------------------------------- The default ``ExceptionController`` will either display an *exception* or *error* page, depending on the setting of the ``kernel.debug`` @@ -43,9 +35,12 @@ shown to the end-user. The third-party `WebfactoryExceptionsBundle`_ provides a special test controller that allows you to display your custom error - pages for arbitrary HTTP status codes even with + pages for arbitrary HTTP status codes even with ``kernel.debug`` set to ``true``. +Override Error Templates +------------------------ + All of the error templates live inside the TwigBundle. To override the templates, simply rely on the standard method for overriding templates that live inside a bundle. For more information, see @@ -129,3 +124,32 @@ Symfony uses the following algorithm to determine which template to use: ``exception.json.twig`` for the JSON exception page. .. _`WebfactoryExceptionsBundle`: https://github.com/webfactory/exceptions-bundle + +Replace the default Exception Controller +---------------------------------------- + +If you need a little more flexibility beyond just overriding the template +(e.g. you need to pass some additional variables into your template), +then you can override the controller that renders the error page. + +The default exception controller is registered as a service - the actual +class is ``Symfony\Bundle\TwigBundle\Controller\ExceptionController``. + +To do this, create a new controller class and make it extend Symfony's default +``Symfony\Bundle\TwigBundle\Controller\ExceptionController`` class. + +There are several methods you can override to customize different parts of how +the error page is rendered. You could, for example, override the entire +``showAction`` or just the ``findTemplate`` method, which locates which +template should be rendered. + +To make Symfony use your exception controller instead of the default, set the +:ref:`twig.exception_controller ` option +in app/config/config.yml. + +.. tip:: + + The customization of exception handling is actually much more powerful + than what's written here. An internal event, ``kernel.exception``, is thrown + which allows complete control over exception handling. For more + information, see :ref:`kernel-kernel.exception`. diff --git a/cookbook/form/dynamic_form_modification.rst b/cookbook/form/dynamic_form_modification.rst index 262b34347d5..99c54860ea5 100644 --- a/cookbook/form/dynamic_form_modification.rst +++ b/cookbook/form/dynamic_form_modification.rst @@ -133,11 +133,6 @@ the event listener might look like the following:: }); } -.. versionadded:: 2.2 - The ability to pass a string into - :method:`FormInterface::add ` - was introduced in Symfony 2.2. - .. note:: The ``FormEvents::PRE_SET_DATA`` line actually resolves to the string @@ -521,10 +516,6 @@ On a form, we can usually listen to the following events: The events ``PRE_SUBMIT``, ``SUBMIT`` and ``POST_SUBMIT`` were introduced in Symfony 2.3. Before, they were named ``PRE_BIND``, ``BIND`` and ``POST_BIND``. -.. versionadded:: 2.2.6 - The behavior of the ``POST_SUBMIT`` event changed slightly in 2.2.6, which the - below example uses. - The key is to add a ``POST_SUBMIT`` listener to the field that your new field depends on. If you add a ``POST_SUBMIT`` listener to a form child (e.g. ``sport``), and add new children to the parent form, the Form component will detect the diff --git a/cookbook/logging/monolog_console.rst b/cookbook/logging/monolog_console.rst index 7945193022e..ec72197c4c9 100644 --- a/cookbook/logging/monolog_console.rst +++ b/cookbook/logging/monolog_console.rst @@ -12,6 +12,11 @@ It is possible to use the console to print messages for certain :class:`Symfony\\Component\\Console\\Output\\OutputInterface` instance that is passed when a command gets executed. +.. seealso:: + Alternatively, you can use the + :doc:`standalone PSR-3 logger ` provided with + the console component. + When a lot of logging has to happen, it's cumbersome to print information depending on the verbosity settings (``-v``, ``-vv``, ``-vvv``) because the calls need to be wrapped in conditions. The code quickly gets verbose or dirty. diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 0a548a04d35..ea2a53ca733 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -149,6 +149,7 @@ * :doc:`/cookbook/security/custom_authentication_provider` * :doc:`/cookbook/security/target_path` * :doc:`/cookbook/security/csrf_in_login_form` + * :doc:`/cookbook/security/named_encoders` * **Serializer** diff --git a/cookbook/request/mime_type.rst b/cookbook/request/mime_type.rst index fb57352c189..11851c02031 100644 --- a/cookbook/request/mime_type.rst +++ b/cookbook/request/mime_type.rst @@ -15,81 +15,107 @@ object. Internally, Symfony contains a map of the most common formats (e.g. easily be added. This document will show how you can add the ``jsonp`` format and corresponding MIME type. -Create a ``kernel.request`` Listener -------------------------------------- +.. versionadded:: 2.5 + The possibility to configure request formats was introduced in Symfony 2.5. -The key to defining a new MIME type is to create a class that will "listen" to -the ``kernel.request`` event dispatched by the Symfony kernel. The -``kernel.request`` event is dispatched early in Symfony's request handling -process and allows you to modify the request object. - -Create the following class, replacing the path with a path to a bundle in your -project:: - - // src/Acme/DemoBundle/RequestListener.php - namespace Acme\DemoBundle; - - use Symfony\Component\HttpKernel\HttpKernelInterface; - use Symfony\Component\HttpKernel\Event\GetResponseEvent; - - class RequestListener - { - public function onKernelRequest(GetResponseEvent $event) - { - $event->getRequest()->setFormat('jsonp', 'application/javascript'); - } - } - -Registering your Listener +Configure your New Format ------------------------- -As with any other listener, you need to add it in one of your configuration -files and register it as a listener by adding the ``kernel.event_listener`` tag: +The FrameworkBundle registers a subscriber that will add formats to incoming requests. + +All you have to do is to configure the ``jsonp`` format: .. configuration-block:: .. code-block:: yaml # app/config/config.yml - services: - acme.demobundle.listener.request: - class: Acme\DemoBundle\RequestListener - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } + framework: + request: + formats: + jsonp: 'application/javascript' .. code-block:: xml - + + - - - - - + xmlns:framework="http://symfony.com/schema/dic/symfony" + xsi:schemaLocation="http://symfony.com/schema/dic/services + http://symfony.com/schema/dic/services/services-1.0.xsd + http://symfony.com/schema/dic/symfony + http://symfony.com/schema/dic/symfony/symfony-1.0.xsd" + > + + + + application/javascript + + + .. code-block:: php - # app/config/config.php - $definition = new Definition('Acme\DemoBundle\RequestListener'); - $definition->addTag('kernel.event_listener', array( - 'event' => 'kernel.request', - 'method' => 'onKernelRequest', + // app/config/config.php + $container->loadFromExtension('framework', array( + 'request' => array( + 'formats' => array( + 'jsonp' => 'application/javascript', + ), + ), )); - $container->setDefinition('acme.demobundle.listener.request', $definition); - -At this point, the ``acme.demobundle.listener.request`` service has been -configured and will be notified when the Symfony kernel dispatches the -``kernel.request`` event. .. tip:: - You can also register the listener in a configuration extension class (see - :ref:`service-container-extension-configuration` for more information). + You can also associate multiple mime types to a format, but please note that + the preferred one must be the first as it will be used as the content type: + + .. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + framework: + request: + formats: + csv: ['text/csv', 'text/plain'] + + .. code-block:: xml + + + + + + + + + text/csv + text/plain + + + + + + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('framework', array( + 'request' => array( + 'formats' => array( + 'jsonp' => array( + 'text/csv', + 'text/plain', + ), + ), + ), + )); diff --git a/cookbook/security/acl_advanced.rst b/cookbook/security/acl_advanced.rst index 8a902004b3d..aad4153f0a3 100644 --- a/cookbook/security/acl_advanced.rst +++ b/cookbook/security/acl_advanced.rst @@ -45,6 +45,13 @@ Security Identities This is analog to the object identity, but represents a user, or a role in your application. Each role, or user has its own security identity. +.. versionadded:: 2.5 + For users, the security identity is based on the username. This means that, + if for any reason, a user's username was to change, you must ensure its + security identity is updated too. The + :method:`MutableAclProvider::updateUserSecurityIdentity() ` + method is there to handle the update, it was introduced in Symfony 2.5. + Database Table Structure ------------------------ diff --git a/cookbook/security/firewall_restriction.rst b/cookbook/security/firewall_restriction.rst index e5379cbc310..24d77c4df4c 100644 --- a/cookbook/security/firewall_restriction.rst +++ b/cookbook/security/firewall_restriction.rst @@ -131,3 +131,63 @@ the ``^`` and ``$`` regex characters) to the hostname ``admin.example.com``. If the hostname does not match this pattern, the firewall will not be activated and subsequent firewalls will have the opportunity to be matched for this request. + +Restricting by HTTP Methods +--------------------------- + +.. versionadded:: 2.5 + Support for restricting security firewalls to specific HTTP methods was introduced in + Symfony 2.5. + +The configuration option ``methods`` restricts the initialization of the firewall to +the provided HTTP methods. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + + # ... + security: + firewalls: + secured_area: + methods: [GET, POST] + # ... + + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // app/config/security.php + + // ... + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'secured_area' => array( + 'methods' => array('GET', 'POST'), + // ... + ), + ), + )); + +In this example, the firewall will only be activated if the HTTP method of the +request is either ``GET`` or ``POST``. If the method is not in the array of the +allowed methods, the firewall will not be activated and subsequent firewalls will again +have the opportunity to be matched for this request. diff --git a/cookbook/security/host_restriction.rst b/cookbook/security/host_restriction.rst index 2dea53f155e..0ee0d334e30 100644 --- a/cookbook/security/host_restriction.rst +++ b/cookbook/security/host_restriction.rst @@ -1,4 +1,6 @@ How to Restrict Firewalls to a Specific Host ============================================ -This entry has moved to ":doc:`/cookbook/security/firewall_restriction`". +As of Symfony 2.5, more possibilities to restrict firewalls have been added. +You can read everything about all the possibilities (including ``host``) +in ":doc:`/cookbook/security/firewall_restriction`". diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst index ebb0ae4db6a..90a9dd1fd86 100644 --- a/cookbook/security/index.rst +++ b/cookbook/security/index.rst @@ -14,6 +14,7 @@ Security force_https firewall_restriction host_restriction + firewall_restriction form_login securing_services custom_provider @@ -22,3 +23,4 @@ Security custom_authentication_provider target_path csrf_in_login_form + named_encoders diff --git a/cookbook/security/named_encoders.rst b/cookbook/security/named_encoders.rst new file mode 100644 index 00000000000..cf9ea3770c2 --- /dev/null +++ b/cookbook/security/named_encoders.rst @@ -0,0 +1,127 @@ +.. index:: + single: Security; Named Encoders + +How to Choose the Password Encoder Algorithm Dynamically +======================================================== + +.. versionadded:: 2.5 + Named encoders were introduced in Symfony 2.5. + +Usually, the same password encoder is used for all users by configuring it +to apply to all instances of a specific class: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + encoders: + Symfony\Component\Security\Core\User\User: sha512 + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + // ... + 'encoders' => array( + 'Symfony\Component\Security\Core\User\User' => array( + 'algorithm' => 'sha512', + ), + ), + )); + +Another option is to use a "named" encoder and then select which encoder +you want to use dynamically. + +In the previous example, you've set the ``sha512`` algorithm for ``Acme\UserBundle\Entity\User``. +This may be secure enough for a regular user, but what if you want your admins +to have a stronger algorithm, for example ``bcrypt``. This can be done with +named encoders: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + encoders: + harsh: + algorithm: bcrypt + cost: 15 + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + // ... + 'encoders' => array( + 'harsh' => array( + 'algorithm' => 'bcrypt', + 'cost' => '15' + ), + ), + )); + +This creates an encoder named ``harsh``. In order for a ``User`` instance +to use it, the class must implement +:class:`Symfony\\Component\\Security\\Core\\Encoder\\EncoderAwareInterface`. +The interface requires one method - ``getEncoderName`` - which should reutrn +the name of the encoder to use:: + + // src/Acme/UserBundle/Entity/User.php + namespace Acme\UserBundle\Entity; + + use Symfony\Component\Security\Core\User\UserInterface; + use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; + + class User implements UserInterface, EncoderAwareInterface + { + public function getEncoderName() + { + if ($this->isAdmin()) { + return 'harsh'; + } + + return null; // use the default encoder + } + } diff --git a/cookbook/security/voters_data_permission.rst b/cookbook/security/voters_data_permission.rst index f6f52904f7a..4d0c765abde 100644 --- a/cookbook/security/voters_data_permission.rst +++ b/cookbook/security/voters_data_permission.rst @@ -54,7 +54,9 @@ Creating the Custom Voter ------------------------- The goal is to create a voter that checks if a user has access to view or -edit a particular object. Here's an example implementation:: +edit a particular object. Here's an example implementation: + +.. code-block:: php // src/Acme/DemoBundle/Security/Authorization/Voter/PostVoter.php namespace Acme\DemoBundle\Security\Authorization\Voter; diff --git a/cookbook/templating/namespaced_paths.rst b/cookbook/templating/namespaced_paths.rst index f26ba8a3237..7340283c29f 100644 --- a/cookbook/templating/namespaced_paths.rst +++ b/cookbook/templating/namespaced_paths.rst @@ -4,9 +4,6 @@ How to Use and Register Namespaced Twig Paths ============================================= -.. versionadded:: 2.2 - Namespaced path support was introduced in 2.2. - Usually, when you refer to a template, you'll use the ``MyBundle:Subdir:filename.html.twig`` format (see :ref:`template-naming-locations`). diff --git a/cookbook/templating/render_without_controller.rst b/cookbook/templating/render_without_controller.rst index cfd96b61c7b..9f3274b0d37 100644 --- a/cookbook/templating/render_without_controller.rst +++ b/cookbook/templating/render_without_controller.rst @@ -77,10 +77,6 @@ this is probably only useful if you'd like to cache this page partial (see Caching the static Template --------------------------- -.. versionadded:: 2.2 - The ability to cache templates rendered via ``FrameworkBundle:Template:template`` - was introduced in Symfony 2.2. - Since templates that are rendered in this way are typically static, it might make sense to cache them. Fortunately, this is easy! By configuring a few other variables in your route, you can control exactly how your page is cached: diff --git a/cookbook/testing/doctrine.rst b/cookbook/testing/doctrine.rst index ef9467861a3..87779fcda41 100644 --- a/cookbook/testing/doctrine.rst +++ b/cookbook/testing/doctrine.rst @@ -17,15 +17,15 @@ Functional Testing ------------------ If you need to actually execute a query, you will need to boot the kernel -to get a valid connection. In this case, you'll extend the ``WebTestCase``, +to get a valid connection. In this case, you'll extend the ``KernelTestCase``, which makes all of this quite easy:: // src/Acme/StoreBundle/Tests/Entity/ProductRepositoryFunctionalTest.php namespace Acme\StoreBundle\Tests\Entity; - use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; - class ProductRepositoryFunctionalTest extends WebTestCase + class ProductRepositoryFunctionalTest extends KernelTestCase { /** * @var \Doctrine\ORM\EntityManager @@ -37,8 +37,7 @@ which makes all of this quite easy:: */ public function setUp() { - static::$kernel = static::createKernel(); - static::$kernel->boot(); + self::bootKernel(); $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager() diff --git a/images/book/translation/debug_1.png b/images/book/translation/debug_1.png new file mode 100644 index 00000000000..8f175f4d7ff Binary files /dev/null and b/images/book/translation/debug_1.png differ diff --git a/images/book/translation/debug_2.png b/images/book/translation/debug_2.png new file mode 100644 index 00000000000..04a57fa41d4 Binary files /dev/null and b/images/book/translation/debug_2.png differ diff --git a/images/book/translation/debug_3.png b/images/book/translation/debug_3.png new file mode 100644 index 00000000000..6ed595e097b Binary files /dev/null and b/images/book/translation/debug_3.png differ diff --git a/images/book/translation/debug_4.png b/images/book/translation/debug_4.png new file mode 100644 index 00000000000..db642b1773f Binary files /dev/null and b/images/book/translation/debug_4.png differ diff --git a/images/components/console/progressbar.gif b/images/components/console/progressbar.gif new file mode 100644 index 00000000000..6c80e6e897f Binary files /dev/null and b/images/components/console/progressbar.gif differ diff --git a/quick_tour/the_big_picture.rst b/quick_tour/the_big_picture.rst index 25ea4597693..2c2e3342796 100644 --- a/quick_tour/the_big_picture.rst +++ b/quick_tour/the_big_picture.rst @@ -18,7 +18,7 @@ directory: .. code-block:: bash - $ composer create-project symfony/framework-standard-edition myproject/ ~2.4 + $ composer create-project symfony/framework-standard-edition myproject/ ~2.5 .. note:: @@ -35,9 +35,25 @@ directory: Beware that the first time you install Symfony2, it may take a few minutes to download all its components. At the end of the installation process, the -installer will ask you to provide some configuration options for the Symfony2 -project. For this first project you can safely ignore this configuration by -pressing the ```` key repeatedly. +installer will ask you four questions: + +1. **Would you like to use Symfony 3 directory structure? [y/N]** The upcoming + Symfony 3 version will modify the default directory structure for Symfony + applications. If you want to test drive this new structure, type ``y``. + In order to follow this tutorial, press the ```` key to accept the + default ``N`` value and to keep using the default Symfony2 structure. +2. **Would you like to install Acme demo bundle? [y/N]** Symfony versions prior + to 2.5 included a demo application to test drive some features of the + framework. However, as this demo application is only useful for newcomers, + installing it is now optional. In order to follow this tutorial, type the + ``y`` key to install the demo application. +3. **Some parameters are missing. Please provide them.** Symfony2 asks you for + the value of all the configuration parameters. For this first project, + you can safely ignore this configuration by pressing the ```` key + repeatedly. +4. **Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?** + The development history of large projects such as Symfony can take a lot of + disk space. Press the ```` key to safely remove all this history data. Running Symfony2 ---------------- diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 3800db36304..21e330796fd 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -392,6 +392,10 @@ Now, the same asset will be rendered as ``/images/logo.png?v2`` If you use this feature, you **must** manually increment the ``assets_version`` value before each deployment so that the query parameters change. +It's also possible to set the version value on an asset-by-asset basis (instead +of using the global version - e.g. ``v2`` - set here). See +:ref:`Versioning by Asset ` for details. + You can also control how the query string works via the `assets_version_format`_ option. @@ -433,11 +437,6 @@ would be ``/images/logo.png?version=5``. profiler ~~~~~~~~ -.. versionadded:: 2.2 - The ``enabled`` option was introduced in Symfony 2.2. Previously, the profiler - could only be disabled by omitting the ``framework.profiler`` configuration - entirely. - .. _profiler.enabled: enabled diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index cbaaf60ce49..2eda8410c86 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -17,6 +17,10 @@ Each part will be explained in the next section. Support for restricting security firewalls to a specific host was introduced in Symfony 2.4. +.. versionadded:: 2.5 + Support for restricting security firewalls to specific http methods was introduced in + Symfony 2.5. + .. configuration-block:: .. code-block:: yaml @@ -104,6 +108,8 @@ Each part will be explained in the next section. pattern: .* # restrict the firewall to a specific host host: admin\.example\.com + # restrict the firewall to specific http methods + methods: [GET, POST] request_matcher: some.service.id access_denied_url: /foo/error403 access_denied_handler: some.service.id @@ -290,9 +296,6 @@ Redirecting after Login Using the PBKDF2 Encoder: Security and Speed -------------------------------------------- -.. versionadded:: 2.2 - The PBKDF2 password encoder was introduced in Symfony 2.2. - The `PBKDF2`_ encoder provides a high level of Cryptographic security, as recommended by the National Institute of Standards and Technology (NIST). @@ -315,9 +318,6 @@ Using the BCrypt Password Encoder To use this encoder, you either need to use PHP Version 5.5 or install the `ircmaxell/password-compat`_ library via Composer. -.. versionadded:: 2.2 - The BCrypt password encoder was introduced in Symfony 2.2. - .. configuration-block:: .. code-block:: yaml diff --git a/reference/constraints.rst b/reference/constraints.rst index 0b209bbf012..ac8ef5ae33c 100644 --- a/reference/constraints.rst +++ b/reference/constraints.rst @@ -18,6 +18,7 @@ Validation Constraints Reference constraints/Url constraints/Regex constraints/Ip + constraints/Uuid constraints/Range diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst index f8d706e665a..b589b4d334a 100644 --- a/reference/constraints/CardScheme.rst +++ b/reference/constraints/CardScheme.rst @@ -1,9 +1,6 @@ CardScheme ========== -.. versionadded:: 2.2 - The ``CardScheme`` constraint was introduced in Symfony 2.2. - This constraint ensures that a credit card number is valid for a given credit card company. It can be used to validate the number before trying to initiate a payment through a payment gateway. diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst index 5eacfbda04b..112620da68b 100644 --- a/reference/constraints/Email.rst +++ b/reference/constraints/Email.rst @@ -7,7 +7,8 @@ cast to a string before being validated. +----------------+---------------------------------------------------------------------+ | Applies to | :ref:`property or method ` | +----------------+---------------------------------------------------------------------+ -| Options | - `message`_ | +| Options | - `strict`_ | +| | - `message`_ | | | - `checkMX`_ | | | - `checkHost`_ | +----------------+---------------------------------------------------------------------+ @@ -89,6 +90,18 @@ Basic Usage Options ------- +.. versionadded:: 2.5 + The ``strict`` option was introduced in Symfony 2.5. + +strict +~~~~~~ + +**type**: ``boolean`` **default**: ``false`` + +When false, the email will be validated against a simple regular expression. +If true, then the `egulias/email-validator`_ library is required to perform +an RFC compliant validation. + message ~~~~~~~ @@ -112,3 +125,5 @@ checkHost If true, then the :phpfunction:`checkdnsrr` PHP function will be used to check the validity of the MX *or* the A *or* the AAAA record of the host of the given email. + +.. _egulias/email-validator: https://packagist.org/packages/egulias/email-validator diff --git a/reference/constraints/Luhn.rst b/reference/constraints/Luhn.rst index cdb55c7f156..70ca0912888 100644 --- a/reference/constraints/Luhn.rst +++ b/reference/constraints/Luhn.rst @@ -1,9 +1,6 @@ Luhn ==== -.. versionadded:: 2.2 - The ``Luhn`` constraint was introduced in Symfony 2.2. - This constraint is used to ensure that a credit card number passes the `Luhn algorithm`_. It is useful as a first step to validating a credit card: before communicating with a payment gateway. diff --git a/reference/constraints/UserPassword.rst b/reference/constraints/UserPassword.rst index d153c89401f..1383172aaed 100644 --- a/reference/constraints/UserPassword.rst +++ b/reference/constraints/UserPassword.rst @@ -1,14 +1,6 @@ UserPassword ============ -.. note:: - - Since Symfony 2.2, the ``UserPassword*`` classes in the - ``Symfony\\Component\\Security\\Core\\Validator\\Constraint`` namespace are - deprecated and will be removed in Symfony 2.3. Please use the - ``UserPassword*`` classes in the - ``Symfony\\Component\\Security\\Core\\Validator\\Constraints`` namespace instead. - This validates that an input value is equal to the current authenticated user's password. This is useful in a form where a user can change their password, but needs to enter their old password for security. diff --git a/reference/constraints/Uuid.rst b/reference/constraints/Uuid.rst new file mode 100644 index 00000000000..4db4fc8ceab --- /dev/null +++ b/reference/constraints/Uuid.rst @@ -0,0 +1,125 @@ +Uuid +==== + +.. versionadded:: 2.5 + The Uuid constraint was introduced in Symfony 2.5. + +Validates that a value is a valid `Universally unique identifier (UUID)`_ per `RFC 4122`_. +By default, this will validate the format according to the RFC's guidelines, but this can +be relaxed to accept non-standard UUIDs that other systems (like PostgreSQL) accept. +UUID versions can also be restricted using a whitelist. + ++----------------+---------------------------------------------------------------------+ +| Applies to | :ref:`property or method ` | ++----------------+---------------------------------------------------------------------+ +| Options | - `message`_ | +| | - `strict`_ | +| | - `versions`_ | ++----------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Validator\\Constraints\\Uuid` | ++----------------+---------------------------------------------------------------------+ +| Validator | :class:`Symfony\\Component\\Validator\\Constraints\\UuidValidator` | ++----------------+---------------------------------------------------------------------+ + +Basic Usage +----------- + +.. configuration-block:: + + .. code-block:: yaml + + # src/UploadsBundle/Resources/config/validation.yml + Acme\UploadsBundle\Entity\File: + properties: + identifier: + - Uuid: ~ + + .. code-block:: php-annotations + + // src/Acme/UploadsBundle/Entity/File.php + namespace Acme\UploadsBundle\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class File + { + /** + * @Assert\Uuid + */ + protected $identifier; + } + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // src/Acme/UploadsBundle/Entity/File.php + namespace Acme\UploadsBundle\Entity; + + use Symfony\Component\Validator\Mapping\ClassMetadata; + use Symfony\Component\Validator\Constraints as Assert; + + class File + { + public static function loadValidatorMetadata(ClassMetadata $metadata) + { + $metadata->addPropertyConstraint('identifier', new Assert\Uuid()); + } + } + + +Options +------- + +message +~~~~~~~ + +**type**: ``string`` **default**: ``This is not a valid UUID.`` + +This message is shown if the string is not a valid UUID. + +strict +~~~~~~ + +**type**: ``boolean`` **default**: ``true`` + +If this option is set to ``true`` the constraint will check if the UUID is formatted per the +RFC's input format rules: ``216fff40-98d9-11e3-a5e2-0800200c9a66``. Setting this to ``false`` +will allow alternate input formats like: + +* ``216f-ff40-98d9-11e3-a5e2-0800-200c-9a66`` +* ``{216fff40-98d9-11e3-a5e2-0800200c9a66}`` +* ``216fff4098d911e3a5e20800200c9a66`` + +versions +~~~~~~~~ + +**type**: ``int[]`` **default**: ``[1,2,3,4,5]`` + +This option can be used to only allow specific `UUID versions`_. Valid versions are 1 - 5. +The following PHP constants can also be used: + +* ``Uuid::V1_MAC`` +* ``Uuid::V2_DCE`` +* ``Uuid::V3_MD5`` +* ``Uuid::V4_RANDOM`` +* ``Uuid::V5_SHA1`` + +All five versions are allowed by default. + +.. _`Universally unique identifier (UUID)`: http://en.wikipedia.org/wiki/Universally_unique_identifier +.. _`RFC 4122`: http://tools.ietf.org/html/rfc4122 +.. _`UUID versions`: http://en.wikipedia.org/wiki/Universally_unique_identifier#Variants_and_versions diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc index 237329866d4..686ad22bca5 100644 --- a/reference/constraints/map.rst.inc +++ b/reference/constraints/map.rst.inc @@ -20,6 +20,7 @@ String Constraints * :doc:`Url ` * :doc:`Regex ` * :doc:`Ip ` +* :doc:`Uuid` Number Constraints ~~~~~~~~~~~~~~~~~~ diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index a3728a01ca2..7ed9632e57b 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -1245,5 +1245,6 @@ For an example, see the ``EntityInitializer`` class inside the Doctrine Bridge. .. _`Twig's documentation`: http://twig.sensiolabs.org/doc/advanced.html#creating-an-extension .. _`Twig official extension repository`: https://github.com/fabpot/Twig-extensions +.. _`KernelEvents`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/KernelEvents.php .. _`SwiftMailer's Plugin Documentation`: http://swiftmailer.org/docs/plugins.html .. _`Twig Loader`: http://twig.sensiolabs.org/doc/api.html#loaders diff --git a/reference/forms/twig_reference.rst b/reference/forms/twig_reference.rst index 1db2fb2f217..3f45d66c0b8 100644 --- a/reference/forms/twig_reference.rst +++ b/reference/forms/twig_reference.rst @@ -350,9 +350,11 @@ object: | ``required`` | If ``true``, a ``required`` attribute is added to the field to activate HTML5 | | | validation. Additionally, a ``required`` class is added to the label. | +------------------------+-------------------------------------------------------------------------------------+ -| ``max_length`` | Adds a ``maxlength`` HTML attribute to the element. | +| ``max_length`` | Adds a ``maxlength`` HTML attribute to the element. (deprecated as of 2.5, to be | +| | removed in 3.0, use ``attr["maxlength"]`` instead) | +------------------------+-------------------------------------------------------------------------------------+ -| ``pattern`` | Adds a ``pattern`` HTML attribute to the element. | +| ``pattern`` | Adds a ``pattern`` HTML attribute to the element. (deprecated as of 2.5, to be | +| | removed in 3.0, use ``attr["pattern"]`` instead) | +------------------------+-------------------------------------------------------------------------------------+ | ``label`` | The string label that will be rendered. | +------------------------+-------------------------------------------------------------------------------------+ diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index fc8aecd01ae..959678c59d3 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -19,6 +19,7 @@ forms, which is useful when creating forms that expose one-to-many relationships | | - `allow_delete`_ | | | - `prototype`_ | | | - `prototype_name`_ | +| | - `delete_empty`_ | +-------------+-----------------------------------------------------------------------------+ | Inherited | - `label`_ | | options | - `label_attr`_ | @@ -336,6 +337,19 @@ If you have several collections in your form, or worse, nested collections you may want to change the placeholder so that unrelated placeholders are not replaced with the same value. +delete_empty +~~~~~~~~~~~~ + +.. versionadded:: 2.5 + The ``delete_empty`` option was introduced in Symfony 2.5. + +**type**: ``Boolean`` **default**: ``false`` + +If you want to explicitly remove entirely empty collection entries from your +form you have to set this option to true. However, existing collection entries +will only be deleted if you have the allow_delete_ option enabled. Otherwise +the empty values will be kept. + Inherited Options ----------------- diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index 33908563a9a..e03177a47e1 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -10,7 +10,7 @@ The ``email`` field is a text field that is rendered using the HTML5 +-------------+---------------------------------------------------------------------+ | Rendered as | ``input`` ``email`` field (a text box) | +-------------+---------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index 32c718f3a8c..18f0683be0a 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -9,6 +9,8 @@ The ``file`` type represents a file input in your form. +-------------+---------------------------------------------------------------------+ | Rendered as | ``input`` ``file`` field | +-------------+---------------------------------------------------------------------+ +| Options | - `multiple`_ | ++-------------+---------------------------------------------------------------------+ | Inherited | - `empty_data`_ | | options | - `required`_ | | | - `label`_ | @@ -78,6 +80,19 @@ before using it directly. Read the :doc:`cookbook ` for an example of how to manage a file upload associated with a Doctrine entity. +Field Options +------------- + +multiple +~~~~~~~~ + +.. versionadded:: 2.5 + The ``multiple`` option was introduced in Symfony 2.5. + +**type**: ``Boolean`` **default**: ``false`` + +When set to true, the user will be able to upload multiple files at the same time. + Inherited Options ----------------- diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index a3b2ab83e65..a1370c36e0d 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -20,7 +20,7 @@ on all types for which ``form`` is the parent type. | | - `trim`_ | | | - `mapped`_ | | | - `property_path`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `by_reference`_ | | | - `error_bubbling`_ | | | - `inherit_data`_ | @@ -29,7 +29,7 @@ on all types for which ``form`` is the parent type. | | - `invalid_message_parameters`_ | | | - `extra_fields_message`_ | | | - `post_max_size_message`_ | -| | - `pattern`_ | +| | - `pattern`_ (deprecated as of 2.5) | | | - `action`_ | | | - `method`_ | +-----------+--------------------------------------------------------------------+ diff --git a/reference/forms/types/options/max_length.rst.inc b/reference/forms/types/options/max_length.rst.inc index d20d44e1199..85874698d15 100644 --- a/reference/forms/types/options/max_length.rst.inc +++ b/reference/forms/types/options/max_length.rst.inc @@ -1,10 +1,16 @@ +.. caution:: + + The ``max_length`` option has been deprecated and will be removed in 3.0. + Instead, use the ``attr`` option by setting it to an array with a ``maxlength`` key. + max_length ~~~~~~~~~~ **type**: ``integer`` **default**: ``null`` -If this option is not null, an attribute ``maxlength`` is added, which -is used by some browsers to limit the amount of text in a field. +If this option is not null, an attribute ``maxlength`` is added, which +is used by some browsers to limit the amount of text in a field. -This is just a browser validation, so data must still be validated +This is just a browser validation, so data must still be validated server-side. + diff --git a/reference/forms/types/options/pattern.rst.inc b/reference/forms/types/options/pattern.rst.inc index d1ff3aea732..65c3870961a 100644 --- a/reference/forms/types/options/pattern.rst.inc +++ b/reference/forms/types/options/pattern.rst.inc @@ -1,3 +1,8 @@ +.. caution:: + + The ``pattern`` option has been deprecated and will be removed in 3.0. + Instead, use the ``attr`` option by setting it to an array with a ``pattern`` key. + pattern ~~~~~~~ diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst index 12ed8b17d77..fa9df3f3b12 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -11,7 +11,7 @@ The ``password`` field renders an input password text box. +-------------+------------------------------------------------------------------------+ | Options | - `always_empty`_ | +-------------+------------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/forms/types/search.rst b/reference/forms/types/search.rst index 9ff7b9d8393..cc1ceeccb8d 100644 --- a/reference/forms/types/search.rst +++ b/reference/forms/types/search.rst @@ -12,7 +12,7 @@ Read about the input search field at `DiveIntoHTML5.info`_ +-------------+----------------------------------------------------------------------+ | Rendered as | ``input search`` field | +-------------+----------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/forms/types/text.rst b/reference/forms/types/text.rst index 675b1f800ae..c61de693ab9 100644 --- a/reference/forms/types/text.rst +++ b/reference/forms/types/text.rst @@ -9,7 +9,7 @@ The text field represents the most basic input text field. +-------------+--------------------------------------------------------------------+ | Rendered as | ``input`` ``text`` field | +-------------+--------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/forms/types/textarea.rst b/reference/forms/types/textarea.rst index da27d4e9efb..0963abadbad 100644 --- a/reference/forms/types/textarea.rst +++ b/reference/forms/types/textarea.rst @@ -9,7 +9,7 @@ Renders a ``textarea`` HTML element. +-------------+------------------------------------------------------------------------+ | Rendered as | ``textarea`` tag | +-------------+------------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst index 44a68d68218..ecd29752cb0 100644 --- a/reference/forms/types/url.rst +++ b/reference/forms/types/url.rst @@ -13,7 +13,7 @@ have a protocol. +-------------+-------------------------------------------------------------------+ | Options | - `default_protocol`_ | +-------------+-------------------------------------------------------------------+ -| Inherited | - `max_length`_ | +| Inherited | - `max_length`_ (deprecated as of 2.5) | | options | - `empty_data`_ | | | - `required`_ | | | - `label`_ | diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst index 3442a824c2b..00e709fd335 100644 --- a/reference/twig_reference.rst +++ b/reference/twig_reference.rst @@ -17,84 +17,80 @@ There may also be tags in bundles you use that aren't listed here. Functions --------- -.. versionadded:: 2.2 - The ``render`` and ``controller`` functions were introduced in Symfony - 2.2. Prior, the ``{% render %}`` tag was used and had a different signature. - .. versionadded:: 2.4 The ``expression`` function was introduced in Symfony 2.4. -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| Function Syntax | Usage | -+====================================================+============================================================================================+ -| ``render(uri, options = {})`` | This will render the fragment for the given controller or URL | -| ``render(controller('B:C:a', {params}))`` | For more information, see :ref:`templating-embedding-controller`. | -| ``render(path('route', {params}))`` | | -| ``render(url('route', {params}))`` | | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``render_esi(controller('B:C:a', {params}))`` | This will generate an ESI tag when possible or fallback to the ``render`` | -| ``render_esi(url('route', {params}))`` | behavior otherwise. For more information, see :ref:`templating-embedding-controller`. | -| ``render_esi(path('route', {params}))`` | | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``render_hinclude(controller(...))`` | This will generates an Hinclude tag for the given controller or URL. | -| ``render_hinclude(url('route', {params}))`` | For more information, see :ref:`templating-embedding-controller`. | -| ``render_hinclude(path('route', {params}))`` | | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``controller(attributes = {}, query = {})`` | Used along with the ``render`` tag to refer to the controller that you want to render. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``asset(path, packageName = null)`` | Get the public path of the asset, more information in | -| | ":ref:`book-templating-assets`". | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``asset_version(packageName = null)`` | Get the current version of the package, more information in | -| | ":ref:`book-templating-assets`". | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form(view, variables = {})`` | This will render the HTML of a complete form, more information in | -| | in :ref:`the Twig Form reference`. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_start(view, variables = {})`` | This will render the HTML start tag of a form, more information in | -| | in :ref:`the Twig Form reference`. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_end(view, variables = {})`` | This will render the HTML end tag of a form together with all fields that | -| | have not been rendered yet, more information | -| | in :ref:`the Twig Form reference`. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_enctype(view)`` | This will render the required ``enctype="multipart/form-data"`` attribute | -| | if the form contains at least one file upload field, more information in | -| | in :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_widget(view, variables = {})`` | This will render a complete form or a specific HTML widget of a field, | -| | more information in :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_errors(view)`` | This will render any errors for the given field or the "global" errors, | -| | more information in :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_label(view, label = null, variables = {})`` | This will render the label for the given field, more information in | -| | :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_row(view, variables = {})`` | This will render the row (the field's label, errors and widget) of the given | -| | field, more information in :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``form_rest(view, variables = {})`` | This will render all fields that have not yet been rendered, more | -| | information in :ref:`the Twig Form reference `. | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``csrf_token(intention)`` | This will render a CSRF token. Use this function if you want CSRF protection without | -| | creating a form | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``is_granted(role, object = null, field = null)`` | This will return ``true`` if the current user has the required role, more | -| | information in ":ref:`book-security-template`" | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``logout_path(key)`` | This will generate the relative logout URL for the given firewall | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``logout_url(key)`` | Equal to ``logout_path(...)`` but this will generate an absolute URL | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``path(name, parameters = {})`` | Get a relative URL for the given route, more information in | -| | ":ref:`book-templating-pages`". | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``url(name, parameters = {})`` | Equal to ``path(...)`` but it generates an absolute URL | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ -| ``expression(expression)`` | Creates an :class:`Symfony\\Component\\ExpressionLanguage\\Expression` in Twig. See | -| | ":ref:`Template Expressions `". | -+----------------------------------------------------+--------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| Function Syntax | Usage | ++=======================================================================+============================================================================================+ +| ``render(uri, options = {})`` | This will render the fragment for the given controller or URL | +| ``render(controller('B:C:a', {params}))`` | For more information, see :ref:`templating-embedding-controller`. | +| ``render(path('route', {params}))`` | | +| ``render(url('route', {params}))`` | | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``render_esi(controller('B:C:a', {params}))`` | This will generate an ESI tag when possible or fallback to the ``render`` | +| ``render_esi(url('route', {params}))`` | behavior otherwise. For more information, see :ref:`templating-embedding-controller`. | +| ``render_esi(path('route', {params}))`` | | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``render_hinclude(controller(...))`` | This will generates an Hinclude tag for the given controller or URL. | +| ``render_hinclude(url('route', {params}))`` | For more information, see :ref:`templating-embedding-controller`. | +| ``render_hinclude(path('route', {params}))`` | | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``controller(attributes = {}, query = {})`` | Used along with the ``render`` tag to refer to the controller that you want to render. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``asset(path, packageName = null, absolute = false, version = null)`` | Get the public path of the asset, more information in | +| | ":ref:`book-templating-assets`". | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``asset_version(packageName = null)`` | Get the current version of the package, more information in | +| | ":ref:`book-templating-assets`". | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form(view, variables = {})`` | This will render the HTML of a complete form, more information in | +| | in :ref:`the Twig Form reference`. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_start(view, variables = {})`` | This will render the HTML start tag of a form, more information in | +| | in :ref:`the Twig Form reference`. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_end(view, variables = {})`` | This will render the HTML end tag of a form together with all fields that | +| | have not been rendered yet, more information | +| | in :ref:`the Twig Form reference`. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_enctype(view)`` | This will render the required ``enctype="multipart/form-data"`` attribute | +| | if the form contains at least one file upload field, more information in | +| | in :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_widget(view, variables = {})`` | This will render a complete form or a specific HTML widget of a field, | +| | more information in :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_errors(view)`` | This will render any errors for the given field or the "global" errors, | +| | more information in :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_label(view, label = null, variables = {})`` | This will render the label for the given field, more information in | +| | :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_row(view, variables = {})`` | This will render the row (the field's label, errors and widget) of the given | +| | field, more information in :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``form_rest(view, variables = {})`` | This will render all fields that have not yet been rendered, more | +| | information in :ref:`the Twig Form reference `. | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``csrf_token(intention)`` | This will render a CSRF token. Use this function if you want CSRF protection without | +| | creating a form | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``is_granted(role, object = null, field = null)`` | This will return ``true`` if the current user has the required role, more | +| | information in ":ref:`book-security-template`" | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``logout_path(key)`` | This will generate the relative logout URL for the given firewall | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``logout_url(key)`` | Equal to ``logout_path(...)`` but this will generate an absolute URL | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``path(name, parameters = {})`` | Get a relative URL for the given route, more information in | +| | ":ref:`book-templating-pages`". | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``url(name, parameters = {})`` | Equal to ``path(...)`` but it generates an absolute URL | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ +| ``expression(expression)`` | Creates an :class:`Symfony\\Component\\ExpressionLanguage\\Expression` in Twig. See | +| | ":ref:`Template Expressions `". | ++-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------+ Filters -------