diff --git a/best_practices/tests.rst b/best_practices/tests.rst index 16aa6d16a35..31ac439a186 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`_ and `Alice`_ 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 @@ -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 diff --git a/book/security.rst b/book/security.rst index 5a5a6bf4bcf..a2a1c591621 100644 --- a/book/security.rst +++ b/book/security.rst @@ -511,7 +511,7 @@ else, you'll want to encode their passwords. The best algorithm to use is )); Of course, your users' passwords now need to be encoded with this exact algorithm. -For hardcoded users, since 2.7 you can use the built-in command : +For hardcoded users, since 2.7 you can use the built-in command: .. code-block:: bash 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 c92cebaf3f8..2cb5713401a 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/components/form/introduction.rst b/components/form/introduction.rst index 61dac0cf6cc..73cd437659f 100644 --- a/components/form/introduction.rst +++ b/components/form/introduction.rst @@ -113,45 +113,45 @@ 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:: 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); + $csrfStorage = new NativeSessionTokenStorage(); + // ... Twig Templating ~~~~~~~~~~~~~~~ diff --git a/components/security/secure_tools.rst b/components/security/secure_tools.rst index 4363f25fa36..420a8abb218 100644 --- a/components/security/secure_tools.rst +++ b/components/security/secure_tools.rst @@ -1,47 +1,43 @@ -Securely 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 also use them if you want to solve the problem they address. -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:: + 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`_. - 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). +.. _`Symfony Polyfill Component`: https://github.com/symfony/polyfill +.. _`paragonie/random_compat package`: https://github.com/paragonie/random_compat diff --git a/components/serializer.rst b/components/serializer.rst index 8f014238475..a1a6d6ed260 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/components/translation/usage.rst b/components/translation/usage.rst index 4ad16abb4cd..7f7ba4a7546 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/cookbook/email/gmail.rst b/cookbook/email/gmail.rst index 9f925cad224..5fc60b3fda4 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,87 @@ In the development configuration file, change the ``transport`` setting to 'password' => 'your_gmail_password', )); -You're done! - .. tip:: - If you are using the Symfony Standard Edition, configure the parameters in ``parameters.yml``: + It's more convenient to configure these options in the ``parameters.yml`` + file: .. code-block:: yaml # app/config/parameters.yml parameters: # ... - mailer_transport: gmail - mailer_host: ~ - mailer_user: your_gmail_username - mailer_password: your_gmail_password - -.. note:: - - The ``gmail`` transport is simply a shortcut that uses the ``smtp`` transport - and sets ``encryption``, ``auth_mode`` and ``host`` to work with Gmail. - -.. note:: - - 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`_. + 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 +----------------------------------------------- + +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. + +If you are using 2-Step-Verification, you must `generate an App password`_ and +use this as your ``mailer_password`` value. + +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`_. + +.. seealso:: + + 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 diff --git a/cookbook/form/unit_testing.rst b/cookbook/form/unit_testing.rst index f68e874eb86..c671cadb41c 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,58 +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 - - // ... - public function buildForm(FormBuilderInterface $builder, array $options) - { - $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:: // tests/AppBundle/Form/Type/TestedTypeTests.php namespace Tests\AppBundle\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 ------------------------ @@ -176,23 +171,25 @@ allows you to return a list of extensions to register:: // tests/AppBundle/Form/Type/TestedTypeTests.php namespace Tests\AppBundle\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), ); } 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); // ... diff --git a/cookbook/routing/redirect_trailing_slash.rst b/cookbook/routing/redirect_trailing_slash.rst index 51d29d120bb..1f2f5f89614 100644 --- a/cookbook/routing/redirect_trailing_slash.rst +++ b/cookbook/routing/redirect_trailing_slash.rst @@ -37,6 +37,26 @@ 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) + { + // ... + } + } + .. code-block:: yaml remove_trailing_slash: 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 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``. diff --git a/create_framework/unit_testing.rst b/create_framework/unit_testing.rst index 580b1d7e428..82efc2f0fef 100644 --- a/create_framework/unit_testing.rst +++ b/create_framework/unit_testing.rst @@ -26,6 +26,12 @@ using `PHPUnit`_. Create a PHPUnit configuration file in ./tests + + + + ./src + + This configuration defines sensible defaults for most PHPUnit settings; more @@ -180,6 +186,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 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 diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 8e7a6416333..f3a5deacf3d 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -104,6 +104,7 @@ Configuration * :ref:`enabled ` * :ref:`cache ` * :ref:`enable_annotations ` + * `name_converter`_ secret ~~~~~~ @@ -1505,6 +1506,24 @@ If this option is enabled, serialization groups can be defined using annotations For more information, see :ref:`cookbook-serializer-using-serialization-groups-annotations`. +name_converter +.............. + +.. versionadded:: 2.8 + The ``name_converter`` setting was introduced in Symfony 2.8. + +**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 -------------------------- diff --git a/reference/configuration/swiftmailer.rst b/reference/configuration/swiftmailer.rst index 2834cd45190..f3e99a3b9fa 100644 --- a/reference/configuration/swiftmailer.rst +++ b/reference/configuration/swiftmailer.rst @@ -303,3 +303,9 @@ 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 instead of directly under the + ``swiftmailer`` key. diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index 1f1a0efa25d..38cc22a8b3c 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -73,6 +74,8 @@ These options inherit from the :doc:`FormType `: .. 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 1f70161f6d6..52063eb0c92 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -352,6 +353,8 @@ These options inherit from the :doc:`FormType `: .. 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 422f721ddcc..050f9c989af 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`_ | +-------------+-----------------------------------------------------------------------------+ @@ -404,6 +405,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 abe34f03546..43f17712d0a 100644 --- a/reference/forms/types/country.rst +++ b/reference/forms/types/country.rst @@ -40,6 +40,7 @@ the option manually, but then you should just use the ``ChoiceType`` directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -99,6 +100,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 3281314e4cf..e6456bb3e63 100644 --- a/reference/forms/types/currency.rst +++ b/reference/forms/types/currency.rst @@ -32,6 +32,7 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -88,6 +89,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 9e70150ec5a..780bc4973c0 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -17,6 +17,7 @@ The ``EmailType`` 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`_ (deprecated as of 2.8) | @@ -53,6 +54,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 4b0d7c93ebf..6db1799c6a5 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -38,6 +38,7 @@ objects from the database. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -263,6 +264,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 2f964867111..0c84aca89f8 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -20,6 +20,7 @@ The ``FileType`` represents a file input in your form. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -127,6 +128,8 @@ These options inherit from the :doc:`FormType `: .. 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 1b66ac5c626..01f1782ec40 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -24,6 +24,7 @@ on all types for which ``FormType`` is the parent. | | - `invalid_message`_ | | | - `invalid_message_parameters`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `method`_ | @@ -107,6 +108,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 19fff1d4e89..fbd1c43a779 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -111,6 +112,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 aa2ea09b44f..80e2ea4bc4a 100644 --- a/reference/forms/types/language.rst +++ b/reference/forms/types/language.rst @@ -41,6 +41,7 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -100,6 +101,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 83ae8acfa81..5d5c0984bd8 100644 --- a/reference/forms/types/locale.rst +++ b/reference/forms/types/locale.rst @@ -43,6 +43,7 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `empty_data`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `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/money.rst b/reference/forms/types/money.rst index bb9fcc88ce6..c4a9057c8c0 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -127,6 +128,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 3d67a154957..d914ab5db0b 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -106,6 +107,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/error_mapping.rst.inc b/reference/forms/types/options/error_mapping.rst.inc index 914997d2802..851f4b5287b 100644 --- a/reference/forms/types/options/error_mapping.rst.inc +++ b/reference/forms/types/options/error_mapping.rst.inc @@ -31,7 +31,15 @@ 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. + +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( + '.' => 'city', + ), + )); 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 f5db4f721be..f08fb0546f0 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -20,6 +20,7 @@ The ``PasswordType`` field renders an input password text box. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ (deprecated as of 2.8) | @@ -82,6 +83,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 14ad60281bf..58e1dca2d64 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`_ (deprecated as of 2.8) | | | - `required`_ | @@ -108,6 +109,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 cd7b0cc9d68..f06ffd55340 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:`CheckboxType `: .. 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/search.rst b/reference/forms/types/search.rst index 52b23077768..bdf569fcb4b 100644 --- a/reference/forms/types/search.rst +++ b/reference/forms/types/search.rst @@ -18,6 +18,7 @@ Read about the input search field at `DiveIntoHTML5.info`_ | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ (deprecated as of 2.8) | @@ -52,6 +53,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/submit.rst b/reference/forms/types/submit.rst index aa0d466f06b..dc20acf0b9a 100644 --- a/reference/forms/types/submit.rst +++ b/reference/forms/types/submit.rst @@ -16,6 +16,7 @@ A submit button. | options | - `disabled`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `translation_domain`_ | | | - `validation_groups`_ | +----------------------+----------------------------------------------------------------------+ @@ -45,6 +46,8 @@ Inherited Options .. include:: /reference/forms/types/options/label_attr.rst.inc +.. include:: /reference/forms/types/options/label_format.rst.inc + .. include:: /reference/forms/types/options/button_translation_domain.rst.inc validation_groups diff --git a/reference/forms/types/text.rst b/reference/forms/types/text.rst index 403d5556979..bb8d32740c4 100644 --- a/reference/forms/types/text.rst +++ b/reference/forms/types/text.rst @@ -16,6 +16,7 @@ The TextType field represents the most basic input text field. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ (deprecated as of 2.8) | @@ -55,6 +56,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/textarea.rst b/reference/forms/types/textarea.rst index 51d14af113e..38990ae3883 100644 --- a/reference/forms/types/textarea.rst +++ b/reference/forms/types/textarea.rst @@ -17,6 +17,7 @@ Renders a ``textarea`` HTML element. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ (deprecated as of 2.8) | @@ -55,6 +56,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/timezone.rst b/reference/forms/types/timezone.rst index 835e7d719c7..a25247d4ddb 100644 --- a/reference/forms/types/timezone.rst +++ b/reference/forms/types/timezone.rst @@ -36,6 +36,7 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `read_only`_ (deprecated as of 2.8) | | | - `required`_ | @@ -95,6 +96,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/url.rst b/reference/forms/types/url.rst index e34ca991ebc..626f6f33d07 100644 --- a/reference/forms/types/url.rst +++ b/reference/forms/types/url.rst @@ -20,6 +20,7 @@ have a protocol. | | - `error_mapping`_ | | | - `label`_ | | | - `label_attr`_ | +| | - `label_format`_ | | | - `mapped`_ | | | - `max_length`_ (deprecated as of 2.5) | | | - `read_only`_ (deprecated as of 2.8) | @@ -68,6 +69,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/twig_reference.rst b/reference/twig_reference.rst index 08a77b0ac7d..3fb0eb6fb2f 100644 --- a/reference/twig_reference.rst +++ b/reference/twig_reference.rst @@ -401,6 +401,8 @@ Twig. See ":ref:`Template Expressions `". Filters ------- +.. _reference-twig-humanize-filter: + humanize ~~~~~~~~