diff --git a/book/forms.rst b/book/forms.rst index 11e2219f4df..b6f4ddbfd4d 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -711,8 +711,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:: @@ -723,7 +723,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 @@ -1903,7 +1903,7 @@ Learn more from the Cookbook .. _`Symfony 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/from_flat_php_to_symfony2.rst b/book/from_flat_php_to_symfony2.rst index c28d5175695..107ff0c22ed 100644 --- a/book/from_flat_php_to_symfony2.rst +++ b/book/from_flat_php_to_symfony2.rst @@ -435,7 +435,7 @@ content: { "require": { - "symfony/symfony": "2.4.*" + "symfony/symfony": "2.5.*" }, "autoload": { "files": ["model.php","controllers.php"] diff --git a/book/installation.rst b/book/installation.rst index 6dacc986a41..bd8ab676211 100644 --- a/book/installation.rst +++ b/book/installation.rst @@ -59,7 +59,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 '2.5.*' .. tip:: @@ -106,10 +106,10 @@ one of the following commands (replacing ``###`` with your actual filename): .. code-block:: bash # for .tgz file - $ tar zxvf Symfony_Standard_Vendors_2.4.###.tgz + $ tar zxvf Symfony_Standard_Vendors_2.5.###.tgz # for a .zip file - $ unzip Symfony_Standard_Vendors_2.4.###.zip + $ unzip Symfony_Standard_Vendors_2.5.###.zip If you've downloaded "without vendors", you'll definitely need to read the next section. diff --git a/book/routing.rst b/book/routing.rst index d8846f49633..ac5398fa2c6 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 @@ -733,10 +729,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 @@ -749,9 +741,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. @@ -1196,9 +1185,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 bd2d4f000a1..03aac0677f9 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 @@ -938,7 +939,7 @@ will match any ``ip``, ``host`` or ``method``: ..................... Once Symfony has decided which ``access_control`` entry matches (if any), -it then *enforces* access restrictions based on the ``roles`` and ``requires_channel`` +it then *enforces* access restrictions based on the ``roles``, ``allow_if`` and ``requires_channel`` options: * ``role`` If the user does not have the given role(s), then access is denied @@ -1170,12 +1171,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!'); } // ... @@ -1183,6 +1183,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:: // ... @@ -1552,9 +1559,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 ............................... @@ -2217,10 +2225,6 @@ cookie will be ever created by Symfony): 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 4f5d80ebebf..f7c9f098bde 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 @@ -781,9 +772,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): @@ -1014,6 +1002,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 0e0dc68852f..8abe3c8da2c 100644 --- a/book/translation.rst +++ b/book/translation.rst @@ -658,6 +658,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 these 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 3e0bfa7855f..4ccb264fe8a 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. Symfony 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 1ff28341e50..1fa891aeb67 100644 --- a/changelog.rst +++ b/changelog.rst @@ -70,6 +70,7 @@ Minor Documentation Changes - `6e90520 `_ #4135 [#3940] Adding php example for an array of emails (weaverryan) - `b37ee61 `_ #4132 Use proper way to reference a doc page for legacy sessions (Baptouuuu) - `189a123 `_ #4129 [Components] consistent & complete config examples (xabbuh) +- `5ab5246 `_ #4127 Second part of #3848 (WouterJ) - `46f3108 `_ #4126 Rebased #3848 (WouterJ) - `84e6e7f `_ #4114 [Book] consistent and complete config examples (xabbuh) - `03fcab1 `_ #4112 [Contributing][Documentation] add order of translation formats (xabbuh) @@ -84,6 +85,7 @@ Minor Documentation Changes - `7806aa7 `_ #4117 Added a note about the automatic handling of the memory spool in the CLI (stof) - `5959b6c `_ #4101 [Contributing] extended Symfony 2.4 maintenance (xabbuh) - `e2056ad `_ #4072 [Contributing][Code] add note on Symfony SE forks for bug reports (xabbuh) +- `b8687dd `_ #4091 Put version into quotes, otherwise it fails in ZSH (dannykopping) - `665c091 `_ #4087 Typo (tvlooy) - `f95bbf3 `_ #4023 [Cookbook][Security] usage of a non-default entity manager in an entity user provider (xabbuh) - `27b1003 `_ #4074 Fixed (again) a typo: Toolbet --> Toolbelt (javiereguiluz) @@ -100,8 +102,10 @@ New Documentation - `1b4c1c8 `_ #4045 Added a new "Deploying to Heroku Cloud" cookbook article (javiereguiluz) - `f943eee `_ #4009 Remove "Controllers extends ContainerAware" best practice (tgalopin) - `eae9ad0 `_ #3875 Added a note about customizing a form with more than one template (javiereguiluz) +- `1938c2f `_ #3724 Updated ISBN validator docs (sprain) - `d6787b7 `_ #3989 adde stof as a merger (fabpot) - `4a9e49e `_ #3946 DQL custom functions on doctrine reference page (healdropper) +- `2b2d9d3 `_ #3972 Added PSR-4 to Class Loaders list (dosten) Fixed Documentation ~~~~~~~~~~~~~~~~~~~ @@ -109,7 +113,9 @@ Fixed Documentation - `1b695b5 `_ #4063 fix parent form types (xabbuh) - `7901005 `_ #4048 $this->request replaced by $request (danielsan) - `f6123f1 `_ #4031 Update form_events.rst (redstar504) +- `99932cf `_ #4010 [Console] Fixed documentation for ProgressBar (VasekPurchart) - `06f8c31 `_ #4012 Fix xml route configuration for routing condition (xavierbriand) +- `a1435e5 `_ #3998 [Console] Fixed QuestionHelper examples (florianv) - `b32f9f2 `_ #3771 Fix function example in expression language component (raulfraile) - `eb813a5 `_ #3979 removed invalid processors option (ricoli) @@ -130,6 +136,9 @@ Minor Documentation Changes - `f5c2602 `_ #4036 Update page_creation.rst (redstar504) - `c2eda93 `_ #4034 Update internals.rst (redstar504) - `a5ad0df `_ #4035 Update version in Rework your Patch section (yguedidi) +- `eed8d64 `_ #4026 Updating Symfony version from 2.4 to 2.5 (danielsan) +- `12752c1 `_ #4013 Removed wrong reference to cookbook (gquemener) +- `ec832dc `_ #3994 [Console] Fix Console component $app to $this and use of getHelper() method (eko) - `d8b037a `_ #4019 Update twig_reference.rst (redstar504) - `7ea87e6 `_ #4016 Fixed the format of one letter-based list (javiereguiluz) - `579a873 `_ #4015 Fixed bad indenting (the list was treated as a blockquote) (javiereguiluz) @@ -158,11 +167,13 @@ New Documentation - `23b51c8 `_ #3901 Bootstraped the standards for "Files and Directories" (javiereguiluz) - `8931c36 `_ #3889 Fixed the section about getting services from a command (javiereguiluz) - `9fddab6 `_ #3877 Added a note about configuring several paths under the same namespace (javiereguiluz) +- `eadf281 `_ #3874 Updated the installation instructions for Symfony 2.5+ (javiereguiluz) Fixed Documentation ~~~~~~~~~~~~~~~~~~~ - `aeffd12 `_ #3961 Fixing php coding (mvhirsch) +- `84332ff `_ #3945 Fixed missing component name in namespaces (WouterJ) - `d8329dc `_ #3943 Fixing simple quotes in double quotes (ptitlazy) - `04f4318 `_ #3934 Move __construct after the repository assignment (cmodijk) - `0626f2b `_ #3897 Collection constraint (hhamon) @@ -178,13 +189,17 @@ Minor Documentation Changes - `fba083e `_ #3957 [Cookbook][Bundles] fix typos in the prepend extension chapter (xabbuh) - `c444b5d `_ #3948 update the Sphinx extensions to raise warnings when backslashes are not ... (xabbuh) - `8fef7b7 `_ #3938 [Contributing][Documentation] don't render the list inside a blockquote (xabbuh) +- `b7a03f8 `_ #3937 properly escape backslashes in class and method directives (xabbuh) +- `882471f `_ #3935 Typo (greg0ire) - `222a014 `_ #3933 render directory inside a code block (xabbuh) +- `0c2a9b3 `_ #3931 [Component][EventDispatcher] 2.5 specific documentation for the TraceableEventDispatcher (xabbuh) - `b31ea51 `_ #3929 Update custom_authentication_provider.rst (verschoof) - `7937864 `_ #3927 [Cookbook][Security] Explicit 'your_user_provider' configuration parameter (zefrog) - `26d00d0 `_ #3925 Fixed the indentation of two code blocks (javiereguiluz) - `351b2cf `_ #3922 update fabpot Sphinx extensions version (xabbuh) - `3ddbe1b `_ #3923 Fixed the headers of one table (javiereguiluz) - `35cbffc `_ #3920 [Components][Form] remove blank line to render the versionadded directive properly (xabbuh) +- `df9f31a `_ #3882 change version numbers in installation notes to be in line with the docu... (xabbuh) - `ed496ae `_ #3887 [Components][Form] add versionadded for the data collector form extension (xabbuh) - `36337e7 `_ #3906 Blockquote introductions (xabbuh) - `5e0e119 `_ #3899 [RFR] Misc. fixes mostly related to formatting issues (javiereguiluz) @@ -199,11 +214,14 @@ 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) @@ -217,6 +235,7 @@ Fixed Documentation - `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 @@ -224,11 +243,13 @@ 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) @@ -236,6 +257,9 @@ Minor Documentation Changes - `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) @@ -265,10 +289,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 ~~~~~~~~~~~~~~~~~~~ @@ -300,6 +329,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) @@ -319,20 +349,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) @@ -341,6 +384,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) @@ -365,13 +409,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) @@ -385,15 +432,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) @@ -418,6 +469,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 ~~~~~~~~~~~~~~~~~~~ @@ -429,6 +482,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) @@ -462,6 +516,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) @@ -484,12 +539,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) @@ -510,9 +569,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 864bf77d734..9808f59c6d8 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/introduction.rst b/components/class_loader/introduction.rst index ab8f1566a6e..9db1e7f41fa 100644 --- a/components/class_loader/introduction.rst +++ b/components/class_loader/introduction.rst @@ -12,11 +12,14 @@ Usage Whenever you reference a class that has not been required or included yet, PHP uses the `autoloading mechanism`_ to delegate the loading of a file defining -the class. Symfony provides two autoloaders, which are able to load your classes: +the class. Symfony provides three autoloaders, which are able to load your classes: * :doc:`/components/class_loader/class_loader`: loads classes that follow the `PSR-0` class naming standard; +* :doc:`/components/class_loader/psr4_class_loader`: loads classes that follow + the `PSR-4` class naming standard; + * :doc:`/components/class_loader/map_class_loader`: loads classes using a static map from class name to file path. diff --git a/components/class_loader/psr4_class_loader.rst b/components/class_loader/psr4_class_loader.rst new file mode 100644 index 00000000000..e388590310d --- /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 9c7b1f15f8d..3b703559f1d 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` - @@ -296,10 +293,6 @@ The info will be printed as a comment when dumping the configuration tree. 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 09b3e215033..8b0730ee3e5 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->getHelper('dialog'); @@ -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..fec1b8c127f --- /dev/null +++ b/components/console/helpers/progressbar.rst @@ -0,0 +1,323 @@ +.. 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\\ProgressBar::setRedrawFrequency`, + so it updates on only some iterations:: + + $progress = new ProgressBar($output, 50000); + $progress->start(); + + // 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::setPlaceholderFormatterDefinition( + '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 c7bc437860e..78e09e0eb25 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..6a745c09609 --- /dev/null +++ b/components/console/helpers/questionhelper.rst @@ -0,0 +1,266 @@ +.. 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->getHelper('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->getHelper('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 = $this->getHelper('question'); + $question = new ChoiceQuestion( + 'Please select your favorite color (defaults to red)', + array('red', 'blue', 'yellow'), + 0 + ); + $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 = $this->getHelper('question'); + $question = new ChoiceQuestion( + 'Please select your favorite colors (defaults to red and blue)', + array('red', 'blue', 'yellow'), + '0,1' + ); + $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``. + +If the user does not enter anything, the result will be: +``You have just selected: red, blue``. + +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->getHelper('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..0f3511fe040 --- /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\Console\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\Console\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\Console\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 e852796a187..d1c094938cf 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 6182690864d..e28e9f9bc67 100644 --- a/components/console/introduction.rst +++ b/components/console/introduction.rst @@ -405,10 +405,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 ---------------- @@ -529,6 +530,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 2d07d0eab13..babd7cfd0fc 100644 --- a/components/dependency_injection/advanced.rst +++ b/components/dependency_injection/advanced.rst @@ -221,3 +221,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 f3c074106cf..da9adee4f83 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -277,10 +277,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/event_dispatcher/traceable_dispatcher.rst b/components/event_dispatcher/traceable_dispatcher.rst index 6b1cb19db86..22404865fbf 100644 --- a/components/event_dispatcher/traceable_dispatcher.rst +++ b/components/event_dispatcher/traceable_dispatcher.rst @@ -5,13 +5,17 @@ The Traceable Event Dispatcher ============================== -The :class:`Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher` +.. versionadded:: 2.5 + The ``TraceableEventDispatcher`` class was moved to the EventDispatcher + component in Symfony 2.5. Before, it was located in the HttpKernel component. + +The :class:`Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher` is an event dispatcher that wraps any other event dispatcher and can then be used to determine which event listeners have been called by the dispatcher. Pass the event dispatcher to be wrapped and an instance of the :class:`Symfony\\Component\\Stopwatch\\Stopwatch` to its constructor:: - use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher; + use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\Stopwatch\Stopwatch; // the event dispatcher to debug 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 2c42b9931ea..cf2f81a2fdd 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 73eb44a964a..f9eab711e07 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` @@ -21,7 +22,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..ef77f6078da 100644 --- a/components/process.rst +++ b/components/process.rst @@ -31,15 +31,11 @@ a command in a sub-process:: throw new \RuntimeException($process->getErrorOutput()); } - print $process->getOutput(); + echo $process->getOutput(); 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` @@ -54,6 +50,27 @@ the contents of the output and :method:`Symfony\\Component\\Process\\Process::clearErrorOutput` clears the contents of the error output. +.. versionadded:: 2.5 + The ``mustRun()`` method was introduced in Symfony 2.5. + +The ``mustRun()`` method is identical to ``run()``, except that it will throw +a :class:`Symfony\\Component\\Process\\Exception\\ProcessFailedException` +if the process couldn't be executed successfully (i.e. the process exited +with a non-zero code):: + + use Symfony\Component\Process\Exception\ProcessFailedException; + use Symfony\Component\Process\Process; + + $process = new Process('ls -lsa'); + + try { + $process->mustRun(); + + echo $process->getOutput(); + } catch (ProcessFailedException $e) { + echo $e->getMessage(); + } + Getting real-time Process Output -------------------------------- @@ -222,17 +239,17 @@ Process Idle Timeout .. versionadded:: 2.4 The :method:`Symfony\\Component\\Process\\Process::setIdleTimeout` method was introduced in Symfony 2.4. - + In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process:: use Symfony\Component\Process\Process; - + $process = new Process('something-with-variable-runtime'); $process->setTimeout(3600); $process->setIdleTimeout(60); $process->run(); - + In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds. @@ -286,6 +303,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 fd2e8671504..804ece250ba 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 ed4e681c19a..73f8042aaab 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 90f652992f4..4129e507eeb 100644 --- a/cookbook/configuration/apache_router.rst +++ b/cookbook/configuration/apache_router.rst @@ -7,6 +7,13 @@ How to Use the Apache Router Symfony, 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 Symfony 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 23f2ad2b494..4ed71637446 100644 --- a/cookbook/console/console_command.rst +++ b/cookbook/console/console_command.rst @@ -194,14 +194,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() { @@ -225,3 +225,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 2ecd95e4104..dd2e021cf93 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/form/dynamic_form_modification.rst b/cookbook/form/dynamic_form_modification.rst index 36b4b9e9800..6d3b4cdb970 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 05c9f80d70c..24a0cd78371 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -156,6 +156,7 @@ * :doc:`/cookbook/security/pre_authenticated` * :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 648c29e6d43..adee071daed 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 7d6efe5dc8f..36864b6b8cd 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 cdf7f049e5f..91f4d654188 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 @@ -23,3 +24,4 @@ Security pre_authenticated 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..3b22a2d9343 --- /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 return +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 071f3733176..35442dd5afb 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 e4ce2331f71..52e21eb3c8e 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 004a8816a55..d655d487e84 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 b4f1cda682a..e3e3e4b1b3a 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/cookbook/workflow/new_project_git.rst b/cookbook/workflow/new_project_git.rst index c40cba6d53f..7551e87622d 100644 --- a/cookbook/workflow/new_project_git.rst +++ b/cookbook/workflow/new_project_git.rst @@ -26,7 +26,7 @@ git repository: .. code-block:: bash - $ php composer.phar create-project symfony/framework-standard-edition path/ '~2.3' + $ php composer.phar create-project symfony/framework-standard-edition path/ "~2.3" Composer will now download the Standard Distribution along with all of the required vendor libraries. For more information about downloading Symfony using 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 3cfc648f2d5..7d6728775fa 100644 --- a/quick_tour/the_big_picture.rst +++ b/quick_tour/the_big_picture.rst @@ -20,7 +20,7 @@ directory: .. code-block:: bash - $ composer create-project symfony/framework-standard-edition myproject/ '~2.3' + $ composer create-project symfony/framework-standard-edition myproject/ "~2.3" .. note:: @@ -37,9 +37,20 @@ directory: Beware that the first time you install Symfony, 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 Symfony -project. For this first project you can safely ignore this configuration by -pressing the ```` key repeatedly. +installer will ask you three questions: + +1. **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. +2. **Some parameters are missing. Please provide them.** Symfony 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. +3. **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 00120a616f8..9cfb5b6947b 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -423,6 +423,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. @@ -464,11 +468,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 029649b0ae6..0ee73aabd90 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 7f11b66c930..94077dd3052 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 85e15ec85d6..9df3332a749 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/Isbn.rst b/reference/constraints/Isbn.rst index 84cb78b16e5..6883f0e1aa4 100644 --- a/reference/constraints/Isbn.rst +++ b/reference/constraints/Isbn.rst @@ -4,14 +4,21 @@ Isbn .. versionadded:: 2.3 The Isbn constraint was introduced in Symfony 2.3. +.. caution:: + + The ``isbn10`` and ``isbn13`` options are deprecated since Symfony 2.5 + and will be removed in Symfony 3.0. Use the ``type`` option instead. + Furthermore, when using the ``type`` option, lowercase characters are no + longer supported starting in Symfony 2.5, as they are not allowed in ISBNs. + This constraint validates that an `International Standard Book Number (ISBN)`_ -is either a valid ISBN-10, a valid ISBN-13 or both. +is either a valid ISBN-10 or a valid ISBN-13. +----------------+----------------------------------------------------------------------+ | Applies to | :ref:`property or method` | +----------------+----------------------------------------------------------------------+ -| Options | - `isbn10`_ | -| | - `isbn13`_ | +| Options | - `type`_ | +| | - `message`_ | | | - `isbn10Message`_ | | | - `isbn13Message`_ | | | - `bothIsbnMessage`_ | @@ -25,7 +32,7 @@ Basic Usage ----------- To use the ``Isbn`` validator, simply apply it to a property or method -on an object that will contain a ISBN number. +on an object that will contain an ISBN. .. configuration-block:: @@ -36,9 +43,8 @@ on an object that will contain a ISBN number. properties: isbn: - Isbn: - isbn10: true - isbn13: true - bothIsbnMessage: This value is neither a valid ISBN-10 nor a valid ISBN-13. + type: isbn10 + message: This value is not valid. .. code-block:: php-annotations @@ -51,9 +57,8 @@ on an object that will contain a ISBN number. { /** * @Assert\Isbn( - * isbn10 = true, - * isbn13 = true, - * bothIsbnMessage = "This value is neither a valid ISBN-10 nor a valid ISBN-13." + * type = isbn10, + * message: This value is not valid. * ) */ protected $isbn; @@ -70,9 +75,8 @@ on an object that will contain a ISBN number. - - - + + @@ -93,9 +97,8 @@ on an object that will contain a ISBN number. public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('isbn', new Assert\Isbn(array( - 'isbn10' => true, - 'isbn13' => true, - 'bothIsbnMessage' => 'This value is neither a valid ISBN-10 nor a valid ISBN-13.' + 'type' => isbn10, + 'message' => 'This value is not valid.' ))); } } @@ -103,28 +106,28 @@ on an object that will contain a ISBN number. Available Options ----------------- -isbn10 -~~~~~~ +type +~~~~ -**type**: ``boolean`` +**type**: ``string`` **default**: ``null`` -If this required option is set to ``true`` the constraint will check if the -code is a valid ISBN-10 code. +The type of ISBN to validate against. +Valid values are ``isbn10``, ``isbn13`` and ``null`` to accept any kind of ISBN. -isbn13 -~~~~~~ +message +~~~~~~~ -**type**: ``boolean`` +**type**: ``string`` **default**: ``null`` -If this required option is set to ``true`` the constraint will check if the -code is a valid ISBN-13 code. +The message that will be shown if the value is not valid. +If not ``null``, this message has priority over all the other messages. isbn10Message ~~~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is not a valid ISBN-10.`` -The message that will be shown if the `isbn10`_ option is true and the given +The message that will be shown if the `type`_ option is ``isbn10`` and the given value does not pass the ISBN-10 check. isbn13Message @@ -132,7 +135,7 @@ isbn13Message **type**: ``string`` **default**: ``This value is not a valid ISBN-13.`` -The message that will be shown if the `isbn13`_ option is true and the given +The message that will be shown if the `type`_ option is ``isbn13`` and the given value does not pass the ISBN-13 check. bothIsbnMessage @@ -140,7 +143,7 @@ bothIsbnMessage **type**: ``string`` **default**: ``This value is neither a valid ISBN-10 nor a valid ISBN-13.`` -The message that will be shown if both the `isbn10`_ and `isbn13`_ options -are true and the given value does not pass the ISBN-13 nor the ISBN-13 check. +The message that will be shown if the `type`_ option is ``null`` and the given +value does not pass any of the ISBN checks. .. _`International Standard Book Number (ISBN)`: http://en.wikipedia.org/wiki/Isbn diff --git a/reference/constraints/Luhn.rst b/reference/constraints/Luhn.rst index 97d1d27d743..0dca2831300 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 ee879a0d7c2..dee677b1d78 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 a5441a57e8e..0cd97bff55e 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -551,9 +551,6 @@ points. For a full example of this listener, read the :doc:`/cookbook/service_container/event_listener` cookbook entry. -For another practical example of a kernel listener, see the cookbook -article: :doc:`/cookbook/request/mime_type`. - Core Event Listener Reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1402,5 +1399,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 0c86877850d..d6ed4ba760c 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -15,6 +15,7 @@ forms, which is useful when creating forms that expose one-to-many relationships +-------------+-----------------------------------------------------------------------------+ | Options | - `allow_add`_ | | | - `allow_delete`_ | +| | - `delete_empty`_ | | | - `options`_ | | | - `prototype`_ | | | - `prototype_name`_ | @@ -255,6 +256,19 @@ For more information, see :ref:`cookbook-form-collections-remove`. None of this is handled automatically. For more information, see :ref:`cookbook-form-collections-remove`. +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. + options ~~~~~~~ diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index 9a60ae4f32c..d6277f5bee9 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -18,7 +18,7 @@ The ``email`` field is a text field that is rendered using the HTML5 | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index 3751bdff8b1..67e7d34c5b3 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 | - `disabled`_ | | options | - `empty_data`_ | | | - `error_bubbling`_ | @@ -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 976f3c3e5d1..16a502a808f 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -24,9 +24,9 @@ on all types for which ``form`` is the parent type. | | - `invalid_message_parameters`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `method`_ | -| | - `pattern`_ | +| | - `pattern`_ (deprecated as of 2.5) | | | - `post_max_size_message`_ | | | - `property_path`_ | | | - `read_only`_ | 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 2bb115b4483..a7bd1d1aaaf 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 eefe8eb7c31..a7d605883ad 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -18,7 +18,7 @@ The ``password`` field renders an input password text box. | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/forms/types/search.rst b/reference/forms/types/search.rst index 955c52cadaf..c9c9890d490 100644 --- a/reference/forms/types/search.rst +++ b/reference/forms/types/search.rst @@ -19,7 +19,7 @@ Read about the input search field at `DiveIntoHTML5.info`_ | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/forms/types/text.rst b/reference/forms/types/text.rst index f9fbb152c22..5fb4f07ae34 100644 --- a/reference/forms/types/text.rst +++ b/reference/forms/types/text.rst @@ -17,7 +17,7 @@ The text field represents the most basic input text field. | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/forms/types/textarea.rst b/reference/forms/types/textarea.rst index 1352d9e2e6f..a75ffbb0f27 100644 --- a/reference/forms/types/textarea.rst +++ b/reference/forms/types/textarea.rst @@ -18,7 +18,7 @@ Renders a ``textarea`` HTML element. | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst index 1df99a06d30..ace61dd0588 100644 --- a/reference/forms/types/url.rst +++ b/reference/forms/types/url.rst @@ -21,7 +21,7 @@ have a protocol. | | - `label`_ | | | - `label_attr`_ | | | - `mapped`_ | -| | - `max_length`_ | +| | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | | | - `required`_ | | | - `trim`_ | diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst index f70d7f5c6fc..6cc04119379 100644 --- a/reference/twig_reference.rst +++ b/reference/twig_reference.rst @@ -19,84 +19,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 -------