From b268226bb94b178bd25a92e9d33ab9076287a6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Fri, 9 Oct 2015 23:19:11 +0100 Subject: [PATCH 01/25] Add HautelookAliceBundle mention --- best_practices/tests.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/best_practices/tests.rst b/best_practices/tests.rst index 758c7b567ce..2ab5f1eee34 100644 --- a/best_practices/tests.rst +++ b/best_practices/tests.rst @@ -113,7 +113,7 @@ pure JavaScript-based testing tools. Learn More about Functional Tests --------------------------------- -Consider using `Faker`_ and `Alice`_ libraries to generate real-looking data +Consider using `Faker`_, `Alice`_ or `HautelookAliceBundle`_ libraries to generate real-looking data for your test fixtures. .. _`Faker`: https://github.com/fzaninotto/Faker @@ -122,3 +122,4 @@ for your test fixtures. .. _`PhpSpec`: http://www.phpspec.net/ .. _`Mink`: http://mink.behat.org .. _`smoke testing`: https://en.wikipedia.org/wiki/Smoke_testing_(software) +.. _`HautelookAliceBundle`: https://github.com/hautelook/AliceBundle From 621336dbc7ca367386a108efb3431083d0f0a9cf Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 19 Dec 2015 17:31:23 +0100 Subject: [PATCH 02/25] Rewrite message --- best_practices/tests.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/best_practices/tests.rst b/best_practices/tests.rst index 2ab5f1eee34..0fc3602bf41 100644 --- a/best_practices/tests.rst +++ b/best_practices/tests.rst @@ -113,8 +113,8 @@ pure JavaScript-based testing tools. Learn More about Functional Tests --------------------------------- -Consider using `Faker`_, `Alice`_ or `HautelookAliceBundle`_ libraries to generate real-looking data -for your test fixtures. +Consider using the `HautelookAliceBundle`_ to generate real-looking data for +your test fixtures using `Faker`_ and `Alice`_. .. _`Faker`: https://github.com/fzaninotto/Faker .. _`Alice`: https://github.com/nelmio/alice From 8a5a2391b30330b953b8c3c41420414bfbb0b865 Mon Sep 17 00:00:00 2001 From: roga Date: Sun, 29 Nov 2015 15:33:11 +0000 Subject: [PATCH 03/25] Updated information about testing code coverage. --- create_framework/unit_testing.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/create_framework/unit_testing.rst b/create_framework/unit_testing.rst index 580b1d7e428..d5fe007f128 100644 --- a/create_framework/unit_testing.rst +++ b/create_framework/unit_testing.rst @@ -26,6 +26,11 @@ using `PHPUnit`_. Create a PHPUnit configuration file in ./tests + + + ./src + + This configuration defines sensible defaults for most PHPUnit settings; more @@ -180,6 +185,12 @@ Open ``example.com/cov/src/Simplex/Framework.php.html`` in a browser and check that all the lines for the Framework class are green (it means that they have been visited when the tests were executed). +Alternatively you can output the result directly to the console: + +.. code-block:: bash + + $ phpunit --coverage-text + Thanks to the simple object-oriented code that we have written so far, we have been able to write unit-tests to cover all possible use cases of our framework; test doubles ensured that we were actually testing our code and not From ac0fdbcb125ceb1c6e14bc240b434319e0632439 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Tue, 18 Nov 2014 20:02:57 +0100 Subject: [PATCH 04/25] Documented label_format option --- components/translation/usage.rst | 2 + reference/forms/types/checkbox.rst | 3 ++ reference/forms/types/choice.rst | 3 ++ reference/forms/types/collection.rst | 3 ++ reference/forms/types/country.rst | 3 ++ reference/forms/types/currency.rst | 3 ++ reference/forms/types/email.rst | 3 ++ reference/forms/types/entity.rst | 3 ++ reference/forms/types/file.rst | 3 ++ reference/forms/types/form.rst | 3 ++ reference/forms/types/integer.rst | 3 ++ reference/forms/types/language.rst | 3 ++ reference/forms/types/locale.rst | 3 ++ reference/forms/types/money.rst | 3 ++ reference/forms/types/number.rst | 3 ++ .../forms/types/options/label_format.rst.inc | 47 +++++++++++++++++++ reference/forms/types/password.rst | 3 ++ reference/forms/types/percent.rst | 3 ++ reference/forms/types/radio.rst | 3 ++ reference/forms/types/search.rst | 3 ++ reference/forms/types/submit.rst | 3 ++ reference/forms/types/text.rst | 3 ++ reference/forms/types/textarea.rst | 3 ++ reference/forms/types/timezone.rst | 3 ++ reference/forms/types/url.rst | 3 ++ reference/twig_reference.rst | 2 + 26 files changed, 120 insertions(+) create mode 100644 reference/forms/types/options/label_format.rst.inc diff --git a/components/translation/usage.rst b/components/translation/usage.rst index 3cf13b9fb7d..eab38dc1b80 100644 --- a/components/translation/usage.rst +++ b/components/translation/usage.rst @@ -139,6 +139,8 @@ recommended format. These files are parsed by one of the loader classes. 'symfony.great' => 'J\'aime Symfony', ); +.. _translation-real-vs-keyword-messages: + .. sidebar:: Using Real or Keyword Messages This example illustrates the two different philosophies when creating diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index b0c657a2add..69b5670c42b 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -22,6 +22,7 @@ true, if the box is unchecked, the value will be set to false. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -71,6 +72,8 @@ type: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index 1d37c9c6f6f..a5ad07341b0 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -37,6 +37,7 @@ To use this field, you must specify *either* ``choices`` or ``choice_loader`` op | | - `inherit_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -337,6 +338,8 @@ type: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index 6bd1e0282d5..b5036c7785f 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -29,6 +29,7 @@ photos). | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `required`_ | +-------------+-----------------------------------------------------------------------------+ @@ -389,6 +390,8 @@ error_bubbling .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/required.rst.inc diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst index 557f497676c..405e598362b 100644 --- a/reference/forms/types/country.rst +++ b/reference/forms/types/country.rst @@ -41,6 +41,7 @@ you should just use the ``choice`` type directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -102,6 +103,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst index 2d2f4748106..2a8dffd71e5 100644 --- a/reference/forms/types/currency.rst +++ b/reference/forms/types/currency.rst @@ -34,6 +34,7 @@ you should just use the ``choice`` type directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -92,6 +93,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index 0d6f548a033..ee174e6922c 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -17,6 +17,7 @@ The ``email`` field is a text field that is rendered using the HTML5 | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | @@ -54,6 +55,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/max_length.rst.inc diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst index 01ce0f7862d..9c2d9c5aa43 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -37,6 +37,7 @@ objects from the database. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -243,6 +244,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index aac88bc7627..d946dfde4f7 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -20,6 +20,7 @@ The ``file`` type represents a file input in your form. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -125,6 +126,8 @@ type: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index 66ba30ca19c..a2ed009fb9d 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -24,6 +24,7 @@ on all types for which ``form`` is the parent type. | | - `invalid_message`_ | | | - `invalid_message_parameters`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `method`_ | @@ -110,6 +111,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. _reference-form-option-mapped: .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index 1b32e43b3f5..70c2e1561fa 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -32,6 +32,7 @@ integers. By default, all non-integer values (e.g. 6.78) will round down | | - `invalid_message_parameters`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -112,6 +113,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst index dd00048f977..8f43a6bcc3c 100644 --- a/reference/forms/types/language.rst +++ b/reference/forms/types/language.rst @@ -42,6 +42,7 @@ you should just use the ``choice`` type directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -103,6 +104,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst index 2a723382d4e..1fc34fc1520 100644 --- a/reference/forms/types/locale.rst +++ b/reference/forms/types/locale.rst @@ -44,6 +44,7 @@ you should just use the ``choice`` type directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -105,6 +106,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst index ae322be16f6..68fa455909b 100644 --- a/reference/forms/types/money.rst +++ b/reference/forms/types/money.rst @@ -31,6 +31,7 @@ how the input and output of the data is handled. | | - `invalid_message_parameters`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -125,6 +126,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst index a60746824b0..937a6ff6fd4 100644 --- a/reference/forms/types/number.rst +++ b/reference/forms/types/number.rst @@ -27,6 +27,7 @@ that you want to use for your number. | | - `invalid_message_parameters`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -107,6 +108,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/options/label_format.rst.inc b/reference/forms/types/options/label_format.rst.inc new file mode 100644 index 00000000000..73f7eee0e7e --- /dev/null +++ b/reference/forms/types/options/label_format.rst.inc @@ -0,0 +1,47 @@ +label_format +~~~~~~~~~~~~ + +.. versionadded:: 2.6 + The ``label_format`` option was introduced in Symfony 2.6. + +**type**: ``string`` **default**: ``null`` + +Configures the string used as the label of the field, in case the ``label`` +option was not set. This is useful when using +:ref:`keyword translation messages `. + +If you're using keyword translation messages as labels, you often end up having +multiple keyword messages for the same label (e.g. ``profile_address_street``, +``invoice_address_street``). This is because the label is build for each "path" +to a field. To avoid duplicated keyword messages, you can configure the label +format to a static value, like:: + + // ... + $profileFormBuilder->add('address', new AddressType(), array( + 'label_format' => 'form.address.%name%', + )); + + $invoiceFormBuilder->add('invoice', new AddressType(), array( + 'label_format' => 'form.address.%name%', + )); + +This option is inherited by the child types. With the code above, the label of +the ``street`` field of both forms will use the ``form.address.street`` keyword +message. + +Two variables are available in the label format: + +``%id%`` + A unique identifier for the field, consisting of the complete path to the + field and the field name (e.g. ``profile_address_street``); +``%name%`` + The field name (e.g. ``street``). + +The default value (``null``) results in a +:ref:`"humanized" version ` of the field name. + +.. note:: + + The ``label_format`` option is evaluated in the form theme. Make sure to + update your templates in case you + :doc:`customized form theming `. diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst index 137d0c70dcc..4c2b4eb3bff 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -20,6 +20,7 @@ The ``password`` field renders an input password text box. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ | @@ -83,6 +84,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/max_length.rst.inc diff --git a/reference/forms/types/percent.rst b/reference/forms/types/percent.rst index 843b65f66f2..a96cb1258eb 100644 --- a/reference/forms/types/percent.rst +++ b/reference/forms/types/percent.rst @@ -30,6 +30,7 @@ This field adds a percentage sign "``%``" after the input box. | | - `invalid_message_parameters`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ | | | - `required`_ | @@ -109,6 +110,8 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/radio.rst b/reference/forms/types/radio.rst index 771f5b13490..2f6f3926f22 100644 --- a/reference/forms/types/radio.rst +++ b/reference/forms/types/radio.rst @@ -29,6 +29,7 @@ If you want to have a boolean field, use :doc:`checkbox `". Filters ------- +.. _reference-twig-humanize-filter: + humanize ~~~~~~~~ From cf0a650c18ffef7abafeb800a2d9a45690f6cb9b Mon Sep 17 00:00:00 2001 From: Vincent AUBERT Date: Sat, 26 Dec 2015 20:07:09 +0100 Subject: [PATCH 05/25] fixes #5971 --- components/form/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/form/introduction.rst b/components/form/introduction.rst index b654f7bee0a..9f63badfc5d 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -146,12 +146,12 @@ and validated when binding the form. .. tip:: If you're not using the HttpFoundation component, you can use - :class:`Symfony\\Component\\Form\\Extension\\Csrf\\CsrfProvider\\DefaultCsrfProvider` + :class:`Symfony\\Component\\Security\\Csrf\\TokenStorage\\NativeSessionTokenStorage` instead, which relies on PHP's native session handling:: - use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider; + use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage; - $csrfProvider = new DefaultCsrfProvider($csrfSecret); + $csrfProvider = new NativeSessionTokenStorage(); Twig Templating ~~~~~~~~~~~~~~~ From 946c5c2ed54ff06e70cbad4d32f57b26656e7c8e Mon Sep 17 00:00:00 2001 From: WouterJ Date: Fri, 18 Dec 2015 11:42:20 +0100 Subject: [PATCH 06/25] Added note about the hash_equals polyfill --- .../security/custom_authentication_provider.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cookbook/security/custom_authentication_provider.rst b/cookbook/security/custom_authentication_provider.rst index 22e190a9ba9..89f28e79f86 100644 --- a/cookbook/security/custom_authentication_provider.rst +++ b/cookbook/security/custom_authentication_provider.rst @@ -289,6 +289,18 @@ the ``PasswordDigest`` header value matches with the user's password. provider for the given token. In the case of multiple providers, the authentication manager will then move to the next provider in the list. +.. note:: + + While the :phpfunction:`hash_equals` function was introduced in PHP 5.6, + you are safe to use it with any PHP version in your Symfony application. In + PHP versions prior to 5.6, `Symfony Polyfill`_ (which is included in + Symfony) will define the function for you. + + .. versionadded:: 2.8 + Symfony Polyfill is included by default since Symfony 2.8. Prior to Symfony 2.8, + you have to execute ``composer require symfony/polyfill-php56`` to be able to + use ``hash_equals`` on older PHP versions. + The Factory ----------- @@ -666,3 +678,4 @@ in the factory and consumed or passed to the other classes in the container. .. _`WSSE`: http://www.xml.com/pub/a/2003/12/17/dive.html .. _`nonce`: https://en.wikipedia.org/wiki/Cryptographic_nonce .. _`timing attacks`: https://en.wikipedia.org/wiki/Timing_attack +.. _`Symfony Polyfill`: https://github.com/symfony/polyfill From 914523cf0e0d18f1439f7f6db41b8f1eaade6e3b Mon Sep 17 00:00:00 2001 From: DerStoffel Date: Thu, 21 Jan 2016 22:13:38 +0100 Subject: [PATCH 07/25] Add annotation to glossary (rebased) --- glossary.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/glossary.rst b/glossary.rst index 53da796cfb2..ab895bf2731 100644 --- a/glossary.rst +++ b/glossary.rst @@ -125,6 +125,11 @@ Glossary Symfony's configuration files. See the :doc:`/components/yaml/introduction` chapter. + Annotation + Annotations are metadata written alongside your code. They can either be explanatory and will be + ignored during execution or add functionality to the line of code directly below as a means of + configuration. For example, the annotation ``@var`` describes the type of a variable, whereas in + Symfony2 ``@Assert`` can add validation to a member variable of a class (see :doc:`/book/validation` chapter). .. _`service-oriented architecture`: https://wikipedia.org/wiki/Service-oriented_architecture .. _`HTTP Wikipedia`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol From b113f72bec36034edbae47fd1ed0f7097b807dcb Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 3 Nov 2015 09:59:21 +0100 Subject: [PATCH 08/25] Reworded the "How to use Gmail" cookbook article --- cookbook/email/gmail.rst | 92 ++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/cookbook/email/gmail.rst b/cookbook/email/gmail.rst index 9f925cad224..c6fbcbd1b04 100644 --- a/cookbook/email/gmail.rst +++ b/cookbook/email/gmail.rst @@ -8,11 +8,6 @@ During development, instead of using a regular SMTP server to send emails, you might find using Gmail easier and more practical. The SwiftmailerBundle makes it really easy. -.. tip:: - - Instead of using your regular Gmail account, it's of course recommended - that you create a special account. - In the development configuration file, change the ``transport`` setting to ``gmail`` and set the ``username`` and ``password`` to the Google credentials: @@ -55,33 +50,84 @@ In the development configuration file, change the ``transport`` setting to 'password' => 'your_gmail_password', )); -You're done! +If you are using the Symfony Standard Edition, it's more convenient to configure +these options in the ``parameters.yml.dist`` file: -.. tip:: +.. code-block:: yaml - If you are using the Symfony Standard Edition, configure the parameters in ``parameters.yml``: + # app/config/parameters.yml.dist + parameters: + # ... + mailer_user: your_gmail_username + mailer_password: your_gmail_password + +.. configuration-block:: .. code-block:: yaml - # app/config/parameters.yml - parameters: - # ... - mailer_transport: gmail - mailer_host: ~ - mailer_user: your_gmail_username - mailer_password: your_gmail_password + # app/config/config_dev.yml + swiftmailer: + transport: gmail + username: '%mailer_user%' + password: '%mailer_password%' + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/config_dev.php + $container->loadFromExtension('swiftmailer', array( + 'transport' => 'gmail', + 'username' => '%mailer_user%', + 'password' => '%mailer_password%', + )); + +Redefining the Default Configuration Parameters +----------------------------------------------- + +The ``gmail`` transport is simply a shortcut that uses the ``smtp`` transport +and sets these options: + +============== ================== +Option Value +============== ================== +``encryption`` ``ssl`` +``auth_mode`` ``login`` +``host`` ``smtp.gmail.com`` +============== ================== + +If your application uses ``tls`` encryption or ``oauth`` authentication, you +must override the default options by defining the ``encryption`` and ``auth_mode`` +parameters. -.. note:: +If you are using 2-Step-Verification, you must `generate an App password`_ and +use this as your ``mailer_password`` value. - The ``gmail`` transport is simply a shortcut that uses the ``smtp`` transport - and sets ``encryption``, ``auth_mode`` and ``host`` to work with Gmail. +If your Gmail account uses 2-Step-Verification, you must `generate an App password`_ +and use it as the value of the ``mailer_password`` parameter. You must also ensure +that you `allow less secure apps to access your Gmail account`_. -.. note:: +.. seealso:: - Depending on your Gmail account settings, you may get authentication errors - within your app. If your Gmail account uses 2-Step-Verification, you should - `generate an App password`_ to use for your ``mailer_password`` parameter. - You should also ensure that you `allow less secure apps to access your Gmail account`_. + :doc:`Swiftmailer configuration reference ` .. _`generate an App password`: https://support.google.com/accounts/answer/185833 .. _`allow less secure apps to access your Gmail account`: https://support.google.com/accounts/answer/6010255 From 6c07b60db8a67211e6d6b6675bda23d72dfeab6a Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 11:43:34 +0100 Subject: [PATCH 09/25] [#5856] Applied final comments --- cookbook/email/gmail.rst | 95 +++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/cookbook/email/gmail.rst b/cookbook/email/gmail.rst index c6fbcbd1b04..5fc60b3fda4 100644 --- a/cookbook/email/gmail.rst +++ b/cookbook/email/gmail.rst @@ -50,55 +50,57 @@ In the development configuration file, change the ``transport`` setting to 'password' => 'your_gmail_password', )); -If you are using the Symfony Standard Edition, it's more convenient to configure -these options in the ``parameters.yml.dist`` file: +.. tip:: -.. code-block:: yaml - - # app/config/parameters.yml.dist - parameters: - # ... - mailer_user: your_gmail_username - mailer_password: your_gmail_password - -.. configuration-block:: + It's more convenient to configure these options in the ``parameters.yml`` + file: .. code-block:: yaml - # app/config/config_dev.yml - swiftmailer: - transport: gmail - username: '%mailer_user%' - password: '%mailer_password%' - - .. code-block:: xml - - - - - - - - - - .. code-block:: php - - // app/config/config_dev.php - $container->loadFromExtension('swiftmailer', array( - 'transport' => 'gmail', - 'username' => '%mailer_user%', - 'password' => '%mailer_password%', - )); + # app/config/parameters.yml + parameters: + # ... + mailer_user: your_gmail_username + mailer_password: your_gmail_password + + .. configuration-block:: + + .. code-block:: yaml + + # app/config/config_dev.yml + swiftmailer: + transport: gmail + username: '%mailer_user%' + password: '%mailer_password%' + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/config_dev.php + $container->loadFromExtension('swiftmailer', array( + 'transport' => 'gmail', + 'username' => '%mailer_user%', + 'password' => '%mailer_password%', + )); Redefining the Default Configuration Parameters ----------------------------------------------- @@ -127,7 +129,8 @@ that you `allow less secure apps to access your Gmail account`_. .. seealso:: - :doc:`Swiftmailer configuration reference ` + see the :doc:`Swiftmailer configuration reference ` + for more details. .. _`generate an App password`: https://support.google.com/accounts/answer/185833 .. _`allow less secure apps to access your Gmail account`: https://support.google.com/accounts/answer/6010255 From 906d55a99db90367a0785e6d3f33d34f5b8f7f47 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Mon, 21 Dec 2015 17:41:36 +0100 Subject: [PATCH 10/25] Update Testing Form Types article for 2.8 refactorings --- cookbook/form/unit_testing.rst | 79 +++++++++++++++++----------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/cookbook/form/unit_testing.rst b/cookbook/form/unit_testing.rst index c8c2bf51e70..879ea97e1ed 100644 --- a/cookbook/form/unit_testing.rst +++ b/cookbook/form/unit_testing.rst @@ -52,8 +52,7 @@ The simplest ``TypeTestCase`` implementation looks like the following:: 'test2' => 'test2', ); - $type = TestedType::class; - $form = $this->factory->create($type); + $form = $this->factory->create(TestedType::class); $object = TestObject::fromArray($formData); @@ -78,8 +77,7 @@ First you verify if the ``FormType`` compiles. This includes basic class inheritance, the ``buildForm`` function and options resolution. This should be the first test you write:: - $type = TestedType::class; - $form = $this->factory->create($type); + $form = $this->factory->create(TestedType::class); This test checks that none of your data transformers used by the form failed. The :method:`Symfony\\Component\\Form\\FormInterface::isSynchronized` @@ -109,55 +107,55 @@ widgets you want to display are available in the children property:: $this->assertArrayHasKey($key, $children); } -Adding a Type your Form Depends on ----------------------------------- +Testings Types from the Service Container +----------------------------------------- -Your form may depend on other types that are defined as services. It -might look like this:: +Your form may be used as a service, as it depends on other services (e.g. the +Doctrine entity manager). In these cases, using the above code won't work, as +the Form component just instantiates the form type without passing any +arguments to the constructor. - // src/AppBundle/Form/Type/TestedType.php - - // ... the buildForm method - $builder->add('app_test_child_type'); - -To create your form correctly, you need to make the type available to the -form factory in your test. The easiest way is to register it manually -before creating the parent form using the ``PreloadedExtension`` class:: +To solve this, you have to mock the injected dependencies, instantiate your own +form type and use the :class:`Symfony\\Component\\Form\\PreloadedExtension` to +make sure the ``FormRegistry`` uses the created instance:: // src/AppBundle/Tests/Form/Type/TestedTypeTests.php namespace AppBundle\Tests\Form\Type; - use AppBundle\Form\Type\TestedType; - use AppBundle\Model\TestObject; - use Symfony\Component\Form\Test\TypeTestCase; use Symfony\Component\Form\PreloadedExtension; + // ... class TestedTypeTest extends TypeTestCase { + private $entityManager; + + protected function setUp() + { + // mock any dependencies + $this->entityManager = $this->getMock('Doctrine\Common\Persistence\ObjectManager'); + } + protected function getExtensions() { - $childType = TestChildType::class; + // create a type instance with the mocked dependencies + $type = new TestedType($this->entityManager); - return array(new PreloadedExtension(array( - $childType->getName() => $childType, - ), array())); + return array( + // register the type instances with the PreloadedExtension + new PreloadedExtension(array($type), array()), + ); } public function testSubmitValidData() { - $type = TestedType::class; - $form = $this->factory->create($type); + // Instead of creating a new instance, the one created in + // getExtensions() will be used. + $form = $this->factory->create(TestedType::class); // ... your test } } -.. caution:: - - Make sure the child type you add is well tested. Otherwise you may - be getting errors that are not related to the form you are currently - testing but to its children. - Adding Custom Extensions ------------------------ @@ -173,23 +171,25 @@ allows you to return a list of extensions to register:: // src/AppBundle/Tests/Form/Type/TestedTypeTests.php namespace AppBundle\Tests\Form\Type; - use AppBundle\Form\Type\TestedType; - use AppBundle\Model\TestObject; + // ... use Symfony\Component\Form\Extension\Validator\ValidatorExtension; - use Symfony\Component\Form\Forms; - use Symfony\Component\Form\FormBuilder; - use Symfony\Component\Form\Test\TypeTestCase; use Symfony\Component\Validator\ConstraintViolationList; class TestedTypeTest extends TypeTestCase { + private $validator; + protected function getExtensions() { - $validator = $this->getMock('\Symfony\Component\Validator\Validator\ValidatorInterface'); - $validator->method('validate')->will($this->returnValue(new ConstraintViolationList())); + $this->validator = $this->getMock( + 'Symfony\Component\Validator\Validator\ValidatorInterface' + ); + $this->validator + ->method('validate') + ->will($this->returnValue(new ConstraintViolationList())); return array( - new ValidatorExtension($validator), + new ValidatorExtension($this->validator), ); } @@ -211,7 +211,6 @@ a good opportunity to use them:: class TestedTypeTest extends TypeTestCase { - /** * @dataProvider getValidTestData */ From 984c49ed9c35353521ace4991345090f4584f70c Mon Sep 17 00:00:00 2001 From: Zac Sturgess Date: Mon, 4 Jan 2016 16:39:28 +0000 Subject: [PATCH 11/25] Fix #6103 --- components/security/secure_tools.rst | 56 +++++++++++++--------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/components/security/secure_tools.rst b/components/security/secure_tools.rst index f43a4f2c7ed..d8ea47f9c9a 100644 --- a/components/security/secure_tools.rst +++ b/components/security/secure_tools.rst @@ -1,5 +1,5 @@ -Securely Comparing Strings and Generating Random Numbers -======================================================== +Securely Generating Random Values +================================= The Symfony Security component comes with a collection of nice utilities related to security. These utilities are used by Symfony, but you should @@ -21,45 +21,41 @@ algorithm; you can use the same strategy in your own code thanks to the // is some known string (e.g. password) equal to some user input? $bool = StringUtils::equals($knownString, $userInput); -Generating a Secure random Number +Generating a Secure Random String ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Whenever you need to generate a secure random number, you are highly -encouraged to use the Symfony -:class:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom` class:: +Whenever you need to generate a secure random string, you are highly +encouraged to use the +:phpfunction:`random_bytes` function:: - use Symfony\Component\Security\Core\Util\SecureRandom; + $random = random_bytes(10); - $generator = new SecureRandom(); - $random = $generator->nextBytes(10); +The function returns a random string, suitable for cryptographic use, of +the number bytes passed as an argument (10 in the above example). -The -:method:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom::nextBytes` -method returns a random string composed of the number of characters passed as -an argument (10 in the above example). +.. tip:: -The SecureRandom class works better when OpenSSL is installed. But when it's -not available, it falls back to an internal algorithm, which needs a seed file -to work correctly. Just pass a file name to enable it:: + The ``random_bytes()`` function returns a binary string which may contain the + ``\0`` character. This can cause trouble in several common scenarios, such + as storing this value in a database or including it as part of the URL. The + solution is to encode or hash the value returned by ``random_bytes()`` (to do that, you + can use a simple ``base64_encode()`` PHP function). - use Symfony\Component\Security\Core\Util\SecureRandom; +Generating a Secure Random Number +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - $generator = new SecureRandom('/some/path/to/store/the/seed.txt'); +If you need to generate a cryptographically secure random integer, you should +use the +:phpfunction:`random_int` function:: - $random = $generator->nextBytes(10); - $hashedRandom = md5($random); // see tip below + $random = random_int(1, 10); .. note:: - If you're using the Symfony Framework, you can get a secure random number - generator via the ``security.secure_random`` service. - -.. tip:: - - The ``nextBytes()`` method returns a binary string which may contain the - ``\0`` character. This can cause trouble in several common scenarios, such - as storing this value in a database or including it as part of the URL. The - solution is to hash the value returned by ``nextBytes()`` (to do that, you - can use a simple ``md5()`` PHP function). + PHP 7 and up provide the ``random_bytes()`` and ``random_int()`` functions natively, + for older versions of PHP a polyfill is provided by the `Symfony Polyfill Component`_ + and the `paragonie/random_compat package`_. .. _`Timing attack`: https://en.wikipedia.org/wiki/Timing_attack +.. _`Symfony Polyfill Component`: https://github.com/symfony/polyfill +.. _`paragonie/random_compat package`: https://github.com/paragonie/random_compat From d6958d657b30e152dfe84a128e840eb568648e2b Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 11:58:02 +0100 Subject: [PATCH 12/25] [#6104] Minor formatting fixes --- components/security/secure_tools.rst | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/components/security/secure_tools.rst b/components/security/secure_tools.rst index d8ea47f9c9a..338a18a449b 100644 --- a/components/security/secure_tools.rst +++ b/components/security/secure_tools.rst @@ -1,5 +1,5 @@ -Securely Generating Random Values -================================= +Securely Comparing Strings and Generating Random Values +======================================================= The Symfony Security component comes with a collection of nice utilities related to security. These utilities are used by Symfony, but you should @@ -25,8 +25,7 @@ Generating a Secure Random String ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Whenever you need to generate a secure random string, you are highly -encouraged to use the -:phpfunction:`random_bytes` function:: +encouraged to use the :phpfunction:`random_bytes` function:: $random = random_bytes(10); @@ -35,26 +34,26 @@ the number bytes passed as an argument (10 in the above example). .. tip:: - The ``random_bytes()`` function returns a binary string which may contain the - ``\0`` character. This can cause trouble in several common scenarios, such - as storing this value in a database or including it as part of the URL. The - solution is to encode or hash the value returned by ``random_bytes()`` (to do that, you - can use a simple ``base64_encode()`` PHP function). + The ``random_bytes()`` function returns a binary string which may contain + the ``\0`` character. This can cause trouble in several common scenarios, + such as storing this value in a database or including it as part of the + URL. The solution is to encode or hash the value returned by + ``random_bytes()`` (to do that, you can use a simple ``base64_encode()`` + PHP function). Generating a Secure Random Number ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you need to generate a cryptographically secure random integer, you should -use the -:phpfunction:`random_int` function:: +use the :phpfunction:`random_int` function:: $random = random_int(1, 10); .. note:: - PHP 7 and up provide the ``random_bytes()`` and ``random_int()`` functions natively, - for older versions of PHP a polyfill is provided by the `Symfony Polyfill Component`_ - and the `paragonie/random_compat package`_. + PHP 7 and up provide the ``random_bytes()`` and ``random_int()`` functions + natively, for older versions of PHP a polyfill is provided by the + `Symfony Polyfill Component`_ and the `paragonie/random_compat package`_. .. _`Timing attack`: https://en.wikipedia.org/wiki/Timing_attack .. _`Symfony Polyfill Component`: https://github.com/symfony/polyfill From a15f856897303b26ea15b93de61e18c590146fee Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sat, 16 Jan 2016 16:17:28 +0100 Subject: [PATCH 13/25] [reference] [form] [options] fix #6153 --- reference/forms/types/options/error_mapping.rst.inc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/reference/forms/types/options/error_mapping.rst.inc b/reference/forms/types/options/error_mapping.rst.inc index 5be15490508..1d71c390bf3 100644 --- a/reference/forms/types/options/error_mapping.rst.inc +++ b/reference/forms/types/options/error_mapping.rst.inc @@ -34,7 +34,14 @@ Here are the rules for the left and the right side of the mapping: object, the property path is ``[indexName]``; * You can construct nested property paths by concatenating them, separating properties by dots. For example: ``addresses[work].matchingCityAndZipCode``; -* The left side of the error mapping also accepts a dot ``.``, which refers - to the field itself. That means that any error added to the field is added - to the given nested field instead; * The right side contains simply the names of fields in the form. + +Additionally, you can set the left side to dot (``.``), which refers to any +unmapped property or method needing validation to the given nested field instead +of bubbling them to the form:: + + $resolver->setDefaults(array( + 'error_mapping' => array( + '.' => 'city', + ), + )); From 1139127a4d281d8ea8d275c6b99f6550a57eabdd Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 12:07:11 +0100 Subject: [PATCH 14/25] [#6156] Apply xabbuh's proposal --- reference/forms/types/options/error_mapping.rst.inc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/reference/forms/types/options/error_mapping.rst.inc b/reference/forms/types/options/error_mapping.rst.inc index 1d71c390bf3..1e85ed98459 100644 --- a/reference/forms/types/options/error_mapping.rst.inc +++ b/reference/forms/types/options/error_mapping.rst.inc @@ -36,9 +36,10 @@ Here are the rules for the left and the right side of the mapping: properties by dots. For example: ``addresses[work].matchingCityAndZipCode``; * The right side contains simply the names of fields in the form. -Additionally, you can set the left side to dot (``.``), which refers to any -unmapped property or method needing validation to the given nested field instead -of bubbling them to the form:: +By default, errors for any property that is not mapped will bubble up to the +parent form. You can use the dot (``.``) on the left side to map errors of all +unmapped properties to a particular field. For instance, to map all these +errors to the ``city`` field, use:: $resolver->setDefaults(array( 'error_mapping' => array( From 7a4d9fc0eff18f493ea476fbc5e0b7513711fafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=83=C2=A9vin=20Dunglas?= Date: Fri, 29 May 2015 14:42:04 +0200 Subject: [PATCH 15/25] [FrameworkBundle] Name converter of Serializer --- components/serializer.rst | 2 ++ cookbook/serializer.rst | 4 +++ reference/configuration/framework.rst | 49 +++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index 235ce8acf58..2d8980684b4 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -344,6 +344,8 @@ method on the normalizer definition:: $serializer = new Serializer(array($normalizer), array($encoder)); $serializer->serialize($person, 'json'); // Output: {"name":"foo","sportsman":false} +.. _component-serializer-converting-property-names-when-serializing-and-deserializing: + Converting Property Names when Serializing and Deserializing ------------------------------------------------------------ diff --git a/cookbook/serializer.rst b/cookbook/serializer.rst index 2e12c6cf641..93aba022a29 100644 --- a/cookbook/serializer.rst +++ b/cookbook/serializer.rst @@ -124,6 +124,8 @@ Here is an example on how to load the $definition->addTag('serializer.normalizer'); $container->setDefinition('get_set_method_normalizer', $definition); +.. _cookbook-serializer-using-serialization-groups-annotations: + Using Serialization Groups Annotations -------------------------------------- @@ -170,6 +172,8 @@ to your class and choose which groups to use when serializing:: 'json', array('groups' => array('group1') ); +.. _cookbook-serializer-enabling-metadata-cache: + Enabling the Metadata Cache --------------------------- diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 0ef27c453d2..3d4d68fc916 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -92,7 +92,7 @@ Configuration * `validation`_ * :ref:`enabled ` * :ref:`cache ` - * `enable_annotations`_ + * :ref:`enable_annotations ` * `translation_domain`_ * `strict_email`_ * `api`_ @@ -102,6 +102,9 @@ Configuration * `debug`_ * `serializer`_ * :ref:`enabled ` + * :ref:`cache ` + * :ref:`enable_annotations ` + * `name_converter`_ secret ~~~~~~ @@ -1372,6 +1375,8 @@ cache The service that is used to persist class metadata in a cache. The service has to implement the :class:`Symfony\\Component\\Validator\\Mapping\\Cache\\CacheInterface`. +.. _reference-validation-enable_annotations: + enable_annotations .................. @@ -1478,7 +1483,47 @@ enabled Whether to enable the ``serializer`` service or not in the service container. -For more details, see :doc:`/cookbook/serializer`. +.. _reference-serializer-cache: + +cache +..... + +**type**: ``string`` + +The service that is used to persist class metadata in a cache. The service +has to implement the :class:`Doctrine\\Common\\Cache\\Cache` interface. + +.. seealso:: + + For more information, see :ref:`cookbook-serializer-enabling-metadata-cache`. + +.. _reference-serializer-enable_annotations: + +enable_annotations +.................. + +**type**: ``boolean`` **default**: ``false`` + +If this option is enabled, serialization groups can be defined using annotations. + +.. seealso:: + + For more information, see :ref:`cookbook-serializer-using-serialization-groups-annotations`. + +name_converter +.............. + +**type**: ``string`` + +The name converter to use. +The :class:`Symfony\\Component\\Serializer\\NameConverter\\CamelCaseToSnakeCaseNameConverter` +name converter can enabled by using the ``serializer.name_converter.camel_case_to_snake_case`` +value. + +.. seealso:: + + For more information, see + :ref:`component-serializer-converting-property-names-when-serializing-and-deserializing`. Full Default Configuration -------------------------- From 10e6b30866a317dd5091078eaf7de15412e32a85 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sun, 10 Jan 2016 04:38:12 +0100 Subject: [PATCH 16/25] Add annotations block and fix regex for redirecting URLs with trailing slash --- cookbook/routing/redirect_trailing_slash.rst | 31 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/cookbook/routing/redirect_trailing_slash.rst b/cookbook/routing/redirect_trailing_slash.rst index 51d29d120bb..6b78dd718d6 100644 --- a/cookbook/routing/redirect_trailing_slash.rst +++ b/cookbook/routing/redirect_trailing_slash.rst @@ -37,13 +37,38 @@ system, as explained below: .. configuration-block:: + .. code-block:: php-annotations + + // src/AppBundle/Controller/RedirectingController.php + namespace AppBundle\Controller; + + use Symfony\Bundle\FrameworkBundle\Controller\Controller; + use Symfony\Component\HttpFoundation\Request; + + class RedirectingController extends Controller + { + /** + * @Route("/{url}", name="remove_trailing_slash", + * requirements={"url" = ".*\/$"}, methods={"GET"}) + */ + public function removeTrailingSlashAction(Request $request) + { + $pathInfo = $request->getPathInfo(); + $requestUri = $request->getRequestUri(); + + $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri); + + return $this->redirect($url, 301); + } + } + .. code-block:: yaml remove_trailing_slash: path: /{url} defaults: { _controller: AppBundle:Redirecting:removeTrailingSlash } requirements: - url: .*/$ + url: .*\/$ methods: [GET] .. code-block:: xml @@ -52,7 +77,7 @@ system, as explained below: AppBundle:Redirecting:removeTrailingSlash - .*/$ + .*\/$ @@ -70,7 +95,7 @@ system, as explained below: '_controller' => 'AppBundle:Redirecting:removeTrailingSlash', ), array( - 'url' => '.*/$', + 'url' => '.*\/$', ), array(), '', From d3744cb37eb8a72677cdee2e254a077bed2d1b5c Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 14:10:57 +0100 Subject: [PATCH 17/25] [#6124] Remove some escapes --- cookbook/routing/redirect_trailing_slash.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cookbook/routing/redirect_trailing_slash.rst b/cookbook/routing/redirect_trailing_slash.rst index 6b78dd718d6..1f2f5f89614 100644 --- a/cookbook/routing/redirect_trailing_slash.rst +++ b/cookbook/routing/redirect_trailing_slash.rst @@ -53,12 +53,7 @@ system, as explained below: */ public function removeTrailingSlashAction(Request $request) { - $pathInfo = $request->getPathInfo(); - $requestUri = $request->getRequestUri(); - - $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri); - - return $this->redirect($url, 301); + // ... } } @@ -68,7 +63,7 @@ system, as explained below: path: /{url} defaults: { _controller: AppBundle:Redirecting:removeTrailingSlash } requirements: - url: .*\/$ + url: .*/$ methods: [GET] .. code-block:: xml @@ -77,7 +72,7 @@ system, as explained below: AppBundle:Redirecting:removeTrailingSlash - .*\/$ + .*/$ @@ -95,7 +90,7 @@ system, as explained below: '_controller' => 'AppBundle:Redirecting:removeTrailingSlash', ), array( - 'url' => '.*\/$', + 'url' => '.*/$', ), array(), '', From 536fa8aaf829df5251605723e9f5c1ca62f4ec9f Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 14:24:42 +0100 Subject: [PATCH 18/25] [#6092] Fix indentation --- create_framework/unit_testing.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/create_framework/unit_testing.rst b/create_framework/unit_testing.rst index d5fe007f128..82efc2f0fef 100644 --- a/create_framework/unit_testing.rst +++ b/create_framework/unit_testing.rst @@ -26,10 +26,11 @@ using `PHPUnit`_. Create a PHPUnit configuration file in ./tests + - - ./src - + + ./src + From 9b2c9f4a729b9412b3811aa6bbc61fad4aef9feb Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Fri, 10 Jul 2015 10:12:10 +0200 Subject: [PATCH 19/25] Always use 127.0.0.1 as a trusted proxy Apparently the behaviour changed in Symfony 2.7. Before, the solution just worked perfectly with a Amazon ELB. After upgrading to Symfony 2.7 the subrequests weren't trusted anymore because they set the `REMOTE_ADDR` to `127.0.0.1` --- cookbook/request/load_balancer_reverse_proxy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index a57bf88f0f2..343c9c35fa8 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -83,7 +83,7 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. // web/app.php // ... - Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR'))); + Request::setTrustedProxies(array('127.0.0.1', $request->server->get('REMOTE_ADDR'))); $response = $kernel->handle($request); // ... From 383401da77c027eb2c86602ddc0970e687adbac2 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 15:18:26 +0100 Subject: [PATCH 20/25] [#6077] Fix code to not use deprecated classes --- components/form/introduction.rst | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/components/form/introduction.rst b/components/form/introduction.rst index 9f63badfc5d..08137d1b3ca 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -113,35 +113,34 @@ CSRF Protection ~~~~~~~~~~~~~~~ Protection against CSRF attacks is built into the Form component, but you need -to explicitly enable it or replace it with a custom solution. The following -snippet adds CSRF protection to the form factory:: +to explicitly enable it or replace it with a custom solution. If you want to +use the built-in support, require the Security CSRF component by executing +``composer require symfony/security-csrf``. + +The following snippet adds CSRF protection to the form factory:: use Symfony\Component\Form\Forms; - use Symfony\Component\Form\Extension\Csrf\CsrfExtension; - use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; use Symfony\Component\HttpFoundation\Session\Session; - - // generate a CSRF secret from somewhere - $csrfSecret = ''; + use Symfony\Component\Security\Extension\Csrf\CsrfExtension; + use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; + use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator; + use Symfony\Component\Security\Csrf\CsrfTokenManager; // create a Session object from the HttpFoundation component $session = new Session(); - $csrfProvider = new SessionCsrfProvider($session, $csrfSecret); + $csrfGenerator = new UriSafeTokenGenerator(); + $csrfStorage = new SessionTokenStorage($session); + $csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage); $formFactory = Forms::createFormFactoryBuilder() // ... - ->addExtension(new CsrfExtension($csrfProvider)) + ->addExtension(new CsrfExtension($csrfStorage)) ->getFormFactory(); -To secure your application against CSRF attacks, you need to define a CSRF -secret. Generate a random string with at least 32 characters, insert it in the -above snippet and make sure that nobody except your web server can access -the secret. - Internally, this extension will automatically add a hidden field to every -form (called ``_token`` by default) whose value is automatically generated -and validated when binding the form. +form (called ``_token`` by default) whose value is automatically generated by +the CSRF generator and validated when binding the form. .. tip:: @@ -151,7 +150,8 @@ and validated when binding the form. use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage; - $csrfProvider = new NativeSessionTokenStorage(); + $csrfStorage = new NativeSessionTokenStorage(); + // ... Twig Templating ~~~~~~~~~~~~~~~ From 887e8baeb248e71b1d111673203e5b6ca1f59c22 Mon Sep 17 00:00:00 2001 From: xelan Date: Fri, 25 Sep 2015 15:07:11 +0200 Subject: [PATCH 21/25] Describe configuration behaviour with multiple mailers --- reference/configuration/swiftmailer.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reference/configuration/swiftmailer.rst b/reference/configuration/swiftmailer.rst index bae46b9ba33..39d1ea1c8a7 100644 --- a/reference/configuration/swiftmailer.rst +++ b/reference/configuration/swiftmailer.rst @@ -303,3 +303,10 @@ Each mailer is registered as a service:: // returns the second mailer $container->get('swiftmailer.mailer.second_mailer'); + +.. caution:: + + When configuring multiple mailers, options must be placed under the appropriate + mailer key of the configuration. Options placed directly under the ``swiftmailer`` + key will not be applied to all mailers, but will configure a mailer named + ``default`` instead. From 34c0771dbbc56e405ebfc3c4f5bab84685e0ab30 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 15:30:10 +0100 Subject: [PATCH 22/25] [#5724] Simplify caution message --- reference/configuration/swiftmailer.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/reference/configuration/swiftmailer.rst b/reference/configuration/swiftmailer.rst index e7d1487e488..f3e99a3b9fa 100644 --- a/reference/configuration/swiftmailer.rst +++ b/reference/configuration/swiftmailer.rst @@ -306,7 +306,6 @@ Each mailer is registered as a service:: .. caution:: - When configuring multiple mailers, options must be placed under the appropriate - mailer key of the configuration. Options placed directly under the ``swiftmailer`` - key will not be applied to all mailers, but will configure a mailer named - ``default`` instead. + When configuring multiple mailers, options must be placed under the + appropriate mailer key of the configuration instead of directly under the + ``swiftmailer`` key. From 353df25d9a60b5f8f04e081d2928e79b053f7d46 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 28 Nov 2015 16:39:11 +0100 Subject: [PATCH 23/25] Document automatic registration of extension compiler passes --- .../dependency_injection/compilation.rst | 112 ++++++++++++------ components/dependency_injection/tags.rst | 21 +++- .../service_container/compiler_passes.rst | 26 ++-- 3 files changed, 107 insertions(+), 52 deletions(-) diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index d3ccfd13a4c..621c674080f 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -306,46 +306,94 @@ For more details, see :doc:`/cookbook/bundles/prepend_extension`, which is specific to the Symfony Framework, but contains more details about this feature. -Creating a Compiler Pass ------------------------- +.. _creating-a-compiler-pass: +.. _components-di-compiler-pass: -You can also create and register your own compiler passes with the container. -To create a compiler pass it needs to implement the -:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` -interface. The compiler pass gives you an opportunity to manipulate the -service definitions that have been compiled. This can be very powerful, -but is not something needed in everyday use. +Execute Code During Compilation +------------------------------- -The compiler pass must have the ``process`` method which is passed the container -being compiled:: +You can also execute custom code during compilation by writing your own +compiler pass. By implementing +:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` +in your extension, the added ``process()`` method will be called during +compilation:: + // ... use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; - use Symfony\Component\DependencyInjection\ContainerBuilder; - class CustomCompilerPass implements CompilerPassInterface + class AcmeDemoExtension implements ExtensionInterface, CompilerPassInterface { public function process(ContainerBuilder $container) { - // ... + // ... do something during the compilation } + + // ... } +.. versionadded:: 2.8 + Prior to Symfony 2.8, extensions implementing ``CompilerPassInterface`` + were not automatically registered. You needed to register them as explained + in :ref:`the next section `. + +As ``process()`` is called *after* all extensions are loaded, it allows you to +edit service definitions of other extensions as well as retrieving information +about service definitions. + The container's parameters and definitions can be manipulated using the -methods described in the :doc:`/components/dependency_injection/definitions`. -One common thing to do in a compiler pass is to search for all services -that have a certain tag in order to process them in some way or dynamically -plug each into some other service. +methods described in :doc:`/components/dependency_injection/definitions`. + +.. note:: + + Please note that the ``process()`` method in the extension class is + called during the optimization step. You can read + :ref:`the next section ` if you + need to edit the container during another step. + +.. note:: + + As a rule, only work with services definition in a compiler pass and do not + create service instances. In practice, this means using the methods + ``has()``, ``findDefinition()``, ``getDefinition()``, ``setDefinition()``, + etc. instead of ``get()``, ``set()``, etc. + +.. tip:: + + Make sure your compiler pass does not require services to exist. Abort the + method call if some required service is not available. -Registering a Compiler Pass ---------------------------- +A common use-case of compiler passes is to search for all service definitions +that have a certain tag in order to process dynamically plug each into some +other service. See the section on :ref:`service tags ` +for an example. -You need to register your custom pass with the container. Its process method -will then be called when the container is compiled:: +.. _components-di-separate-compiler-passes: + +Creating Separate Compiler Passes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes, you need to do more than one thing during compliation, want to use +compiler passes without an extension or you need to execute some code at +another step in the compilation process. In these cases, you can create a new +class implementing the ``CompilerPassInterface``:: + + use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + use Symfony\Component\DependencyInjection\ContainerBuilder; + + class CustomPass implements CompilerPassInterface + { + public function process(ContainerBuilder $container) + { + // ... do something during the compilation + } + } + +You then need to register your custom pass with the container:: use Symfony\Component\DependencyInjection\ContainerBuilder; $container = new ContainerBuilder(); - $container->addCompilerPass(new CustomCompilerPass); + $container->addCompilerPass(new CustomPass()); .. note:: @@ -354,17 +402,16 @@ will then be called when the container is compiled:: more details. Controlling the Pass Ordering -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +............................. The default compiler passes are grouped into optimization passes and removal passes. The optimization passes run first and include tasks such as resolving references within the definitions. The removal passes perform tasks such -as removing private aliases and unused services. You can choose where in -the order any custom passes you add are run. By default they will be run -before the optimization passes. +as removing private aliases and unused services. When registering compiler +passes using ``addCompilerPass()``, you can configure when your compiler pass +is run. By default, they are run before the optimization passes. -You can use the following constants as the second argument when registering -a pass with the container to control where it goes in the order: +You can use the following constants to determine when your pass is executed: * ``PassConfig::TYPE_BEFORE_OPTIMIZATION`` * ``PassConfig::TYPE_OPTIMIZE`` @@ -373,14 +420,11 @@ a pass with the container to control where it goes in the order: * ``PassConfig::TYPE_AFTER_REMOVING`` For example, to run your custom pass after the default removal passes have -been run:: +been run, use:: - use Symfony\Component\DependencyInjection\ContainerBuilder; - use Symfony\Component\DependencyInjection\Compiler\PassConfig; - - $container = new ContainerBuilder(); + // ... $container->addCompilerPass( - new CustomCompilerPass, + new CustomPass(), PassConfig::TYPE_AFTER_REMOVING ); diff --git a/components/dependency_injection/tags.rst b/components/dependency_injection/tags.rst index 83deec45395..c293c58c011 100644 --- a/components/dependency_injection/tags.rst +++ b/components/dependency_injection/tags.rst @@ -117,11 +117,14 @@ Notice that each was given a tag named ``acme_mailer.transport``. This is the custom tag that you'll use in your compiler pass. The compiler pass is what makes this tag "mean" something. -Create a ``CompilerPass`` -------------------------- +.. _components-di-compiler-pass-tags: +.. _create-a-compilerpass: -Your compiler pass can now ask the container for any services with the -custom tag:: +Create a Compiler Pass +---------------------- + +You can now use a :ref:`compiler pass ` to ask the +container for any services with the ``acme_mailer.transport`` tag:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -154,7 +157,7 @@ custom tag:: The ``process()`` method checks for the existence of the ``acme_mailer.transport_chain`` service, then looks for all services tagged ``acme_mailer.transport``. It adds to the definition of the ``acme_mailer.transport_chain`` service a -call to ``addTransport()`` for each "acme_mailer.transport" service it has +call to ``addTransport()`` for each ``acme_mailer.transport`` service it has found. The first argument of each of these calls will be the mailer transport service itself. @@ -175,6 +178,13 @@ run when the container is compiled:: framework. See :doc:`/cookbook/service_container/compiler_passes` for more details. +.. tip:: + + When implementing the ``CompilerPassInterface`` in a service extension, you + do not need to register it. See the + :ref:`components documentation ` for more + information. + Adding Additional Attributes on Tags ------------------------------------ @@ -296,4 +306,3 @@ The double loop may be confusing. This is because a service can have more than one tag. You tag a service twice or more with the ``acme_mailer.transport`` tag. The second foreach loop iterates over the ``acme_mailer.transport`` tags set for the current service and gives you the attributes. - diff --git a/cookbook/service_container/compiler_passes.rst b/cookbook/service_container/compiler_passes.rst index cf629a695ef..d5b7595adc4 100644 --- a/cookbook/service_container/compiler_passes.rst +++ b/cookbook/service_container/compiler_passes.rst @@ -7,25 +7,27 @@ How to Work with Compiler Passes in Bundles Compiler passes give you an opportunity to manipulate other service definitions that have been registered with the service container. You -can read about how to create them in the components section ":doc:`/components/dependency_injection/compilation`". -To register a compiler pass from a bundle you need to add it to the build -method of the bundle definition class:: +can read about how to create them in the components section +":ref:`components-di-compiler-pass`". - // src/Acme/MailerBundle/AcmeMailerBundle.php - namespace Acme\MailerBundle; +When using :ref:`separate compiler passes `, +you need to register them in the ``build()`` method of the bundle class (this +is not needed when implementing the ``process()`` method in the extension):: + + // src/AppBundle/AppBundle.php + namespace AppBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; + use AppBundle\DependencyInjection\Compiler\CustomPass; - use Acme\MailerBundle\DependencyInjection\Compiler\CustomCompilerPass; - - class AcmeMailerBundle extends Bundle + class AppBundle extends Bundle { public function build(ContainerBuilder $container) { parent::build($container); - $container->addCompilerPass(new CustomCompilerPass()); + $container->addCompilerPass(new CustomPass()); } } @@ -33,6 +35,6 @@ One of the most common use-cases of compiler passes is to work with tagged servi (read more about tags in the components section ":doc:`/components/dependency_injection/tags`"). If you are using custom tags in a bundle then by convention, tag names consist of the name of the bundle (lowercase, underscores as separators), followed -by a dot, and finally the "real" name. For example, if you want to introduce -some sort of "transport" tag in your AcmeMailerBundle, you should call it -``acme_mailer.transport``. +by a dot and finally the "real" name. For example, if you want to introduce +some sort of "mail_transport" tag in your AppBundle, you should call it +``app.mail_transport``. From b4a950ba0c48c16539f4aa49378a6e50fcf13018 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Sat, 5 Dec 2015 11:03:39 +0100 Subject: [PATCH 24/25] Update security.rst --- book/security.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/book/security.rst b/book/security.rst index 8cf0a2b4174..02df56fc781 100644 --- a/book/security.rst +++ b/book/security.rst @@ -508,8 +508,9 @@ else, you'll want to encode their passwords. The best algorithm to use is .. include:: /cookbook/security/_ircmaxwell_password-compat.rst.inc Of course, your users' passwords now need to be encoded with this exact algorithm. -For hardcoded users, you can use an `online tool`_, which will give you something -like this: +For hardcoded users, you can use an `online tool`_ (this is a public tool and it should not be used with real passwords because of the risk of farming or other possible security issues). + +It will give you something like this: .. configuration-block:: From d2c3e2627a7ee66453603651801c0006e639b9b7 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 6 Feb 2016 16:41:53 +0100 Subject: [PATCH 25/25] [#5958] Make warning a bit shorter --- book/security.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/security.rst b/book/security.rst index 02df56fc781..0f0320643ca 100644 --- a/book/security.rst +++ b/book/security.rst @@ -508,7 +508,8 @@ else, you'll want to encode their passwords. The best algorithm to use is .. include:: /cookbook/security/_ircmaxwell_password-compat.rst.inc Of course, your users' passwords now need to be encoded with this exact algorithm. -For hardcoded users, you can use an `online tool`_ (this is a public tool and it should not be used with real passwords because of the risk of farming or other possible security issues). +For hardcoded users, you can use an `online tool`_ (as it's a public tool, +avoid using real passwords). It will give you something like this: