Skip to content

Commit 16cc4bc

Browse files
committed
Merge branch '2.8' into 3.0
Conflicts: cookbook/form/unit_testing.rst
2 parents e901fbc + b56880b commit 16cc4bc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+476
-173
lines changed

Diff for: best_practices/tests.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ pure JavaScript-based testing tools.
113113
Learn More about Functional Tests
114114
---------------------------------
115115

116-
Consider using `Faker`_ and `Alice`_ libraries to generate real-looking data
117-
for your test fixtures.
116+
Consider using the `HautelookAliceBundle`_ to generate real-looking data for
117+
your test fixtures using `Faker`_ and `Alice`_.
118118

119119
.. _`Faker`: https://github.com/fzaninotto/Faker
120120
.. _`Alice`: https://github.com/nelmio/alice
121121
.. _`PhpUnit`: https://phpunit.de/
122122
.. _`PhpSpec`: http://www.phpspec.net/
123123
.. _`Mink`: http://mink.behat.org
124124
.. _`smoke testing`: https://en.wikipedia.org/wiki/Smoke_testing_(software)
125+
.. _`HautelookAliceBundle`: https://github.com/hautelook/AliceBundle

Diff for: book/security.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ else, you'll want to encode their passwords. The best algorithm to use is
511511
));
512512
513513
Of course, your users' passwords now need to be encoded with this exact algorithm.
514-
For hardcoded users, since 2.7 you can use the built-in command :
514+
For hardcoded users, since 2.7 you can use the built-in command:
515515

516516
.. code-block:: bash
517517

Diff for: components/dependency_injection/compilation.rst

+78-34
Original file line numberDiff line numberDiff line change
@@ -306,46 +306,94 @@ For more details, see :doc:`/cookbook/bundles/prepend_extension`, which
306306
is specific to the Symfony Framework, but contains more details about this
307307
feature.
308308

309-
Creating a Compiler Pass
310-
------------------------
309+
.. _creating-a-compiler-pass:
310+
.. _components-di-compiler-pass:
311311

312-
You can also create and register your own compiler passes with the container.
313-
To create a compiler pass it needs to implement the
314-
:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
315-
interface. The compiler pass gives you an opportunity to manipulate the
316-
service definitions that have been compiled. This can be very powerful,
317-
but is not something needed in everyday use.
312+
Execute Code During Compilation
313+
-------------------------------
318314

319-
The compiler pass must have the ``process`` method which is passed the container
320-
being compiled::
315+
You can also execute custom code during compilation by writing your own
316+
compiler pass. By implementing
317+
:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
318+
in your extension, the added ``process()`` method will be called during
319+
compilation::
321320

321+
// ...
322322
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
323-
use Symfony\Component\DependencyInjection\ContainerBuilder;
324323

325-
class CustomCompilerPass implements CompilerPassInterface
324+
class AcmeDemoExtension implements ExtensionInterface, CompilerPassInterface
326325
{
327326
public function process(ContainerBuilder $container)
328327
{
329-
// ...
328+
// ... do something during the compilation
330329
}
330+
331+
// ...
331332
}
332333

334+
.. versionadded:: 2.8
335+
Prior to Symfony 2.8, extensions implementing ``CompilerPassInterface``
336+
were not automatically registered. You needed to register them as explained
337+
in :ref:`the next section <components-di-separate-compiler-passes>`.
338+
339+
As ``process()`` is called *after* all extensions are loaded, it allows you to
340+
edit service definitions of other extensions as well as retrieving information
341+
about service definitions.
342+
333343
The container's parameters and definitions can be manipulated using the
334-
methods described in the :doc:`/components/dependency_injection/definitions`.
335-
One common thing to do in a compiler pass is to search for all services
336-
that have a certain tag in order to process them in some way or dynamically
337-
plug each into some other service.
344+
methods described in :doc:`/components/dependency_injection/definitions`.
345+
346+
.. note::
347+
348+
Please note that the ``process()`` method in the extension class is
349+
called during the optimization step. You can read
350+
:ref:`the next section <components-di-separate-compiler-passes>` if you
351+
need to edit the container during another step.
352+
353+
.. note::
354+
355+
As a rule, only work with services definition in a compiler pass and do not
356+
create service instances. In practice, this means using the methods
357+
``has()``, ``findDefinition()``, ``getDefinition()``, ``setDefinition()``,
358+
etc. instead of ``get()``, ``set()``, etc.
359+
360+
.. tip::
361+
362+
Make sure your compiler pass does not require services to exist. Abort the
363+
method call if some required service is not available.
338364

339-
Registering a Compiler Pass
340-
---------------------------
365+
A common use-case of compiler passes is to search for all service definitions
366+
that have a certain tag in order to process dynamically plug each into some
367+
other service. See the section on :ref:`service tags <components-di-compiler-pass-tags>`
368+
for an example.
341369

342-
You need to register your custom pass with the container. Its process method
343-
will then be called when the container is compiled::
370+
.. _components-di-separate-compiler-passes:
371+
372+
Creating Separate Compiler Passes
373+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374+
375+
Sometimes, you need to do more than one thing during compliation, want to use
376+
compiler passes without an extension or you need to execute some code at
377+
another step in the compilation process. In these cases, you can create a new
378+
class implementing the ``CompilerPassInterface``::
379+
380+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
381+
use Symfony\Component\DependencyInjection\ContainerBuilder;
382+
383+
class CustomPass implements CompilerPassInterface
384+
{
385+
public function process(ContainerBuilder $container)
386+
{
387+
// ... do something during the compilation
388+
}
389+
}
390+
391+
You then need to register your custom pass with the container::
344392

345393
use Symfony\Component\DependencyInjection\ContainerBuilder;
346394

347395
$container = new ContainerBuilder();
348-
$container->addCompilerPass(new CustomCompilerPass);
396+
$container->addCompilerPass(new CustomPass());
349397

350398
.. note::
351399

@@ -354,17 +402,16 @@ will then be called when the container is compiled::
354402
more details.
355403

356404
Controlling the Pass Ordering
357-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
405+
.............................
358406

359407
The default compiler passes are grouped into optimization passes and removal
360408
passes. The optimization passes run first and include tasks such as resolving
361409
references within the definitions. The removal passes perform tasks such
362-
as removing private aliases and unused services. You can choose where in
363-
the order any custom passes you add are run. By default they will be run
364-
before the optimization passes.
410+
as removing private aliases and unused services. When registering compiler
411+
passes using ``addCompilerPass()``, you can configure when your compiler pass
412+
is run. By default, they are run before the optimization passes.
365413

366-
You can use the following constants as the second argument when registering
367-
a pass with the container to control where it goes in the order:
414+
You can use the following constants to determine when your pass is executed:
368415

369416
* ``PassConfig::TYPE_BEFORE_OPTIMIZATION``
370417
* ``PassConfig::TYPE_OPTIMIZE``
@@ -373,14 +420,11 @@ a pass with the container to control where it goes in the order:
373420
* ``PassConfig::TYPE_AFTER_REMOVING``
374421

375422
For example, to run your custom pass after the default removal passes have
376-
been run::
423+
been run, use::
377424

378-
use Symfony\Component\DependencyInjection\ContainerBuilder;
379-
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
380-
381-
$container = new ContainerBuilder();
425+
// ...
382426
$container->addCompilerPass(
383-
new CustomCompilerPass,
427+
new CustomPass(),
384428
PassConfig::TYPE_AFTER_REMOVING
385429
);
386430

Diff for: components/dependency_injection/tags.rst

+15-6
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,14 @@ Notice that each was given a tag named ``acme_mailer.transport``. This is
117117
the custom tag that you'll use in your compiler pass. The compiler pass
118118
is what makes this tag "mean" something.
119119

120-
Create a ``CompilerPass``
121-
-------------------------
120+
.. _components-di-compiler-pass-tags:
121+
.. _create-a-compilerpass:
122122

123-
Your compiler pass can now ask the container for any services with the
124-
custom tag::
123+
Create a Compiler Pass
124+
----------------------
125+
126+
You can now use a :ref:`compiler pass <components-di-separate-compiler-passes>` to ask the
127+
container for any services with the ``acme_mailer.transport`` tag::
125128

126129
use Symfony\Component\DependencyInjection\ContainerBuilder;
127130
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
@@ -154,7 +157,7 @@ custom tag::
154157
The ``process()`` method checks for the existence of the ``acme_mailer.transport_chain``
155158
service, then looks for all services tagged ``acme_mailer.transport``. It
156159
adds to the definition of the ``acme_mailer.transport_chain`` service a
157-
call to ``addTransport()`` for each "acme_mailer.transport" service it has
160+
call to ``addTransport()`` for each ``acme_mailer.transport`` service it has
158161
found. The first argument of each of these calls will be the mailer transport
159162
service itself.
160163

@@ -175,6 +178,13 @@ run when the container is compiled::
175178
framework. See :doc:`/cookbook/service_container/compiler_passes` for
176179
more details.
177180

181+
.. tip::
182+
183+
When implementing the ``CompilerPassInterface`` in a service extension, you
184+
do not need to register it. See the
185+
:ref:`components documentation <components-di-compiler-pass>` for more
186+
information.
187+
178188
Adding Additional Attributes on Tags
179189
------------------------------------
180190

@@ -296,4 +306,3 @@ The double loop may be confusing. This is because a service can have more
296306
than one tag. You tag a service twice or more with the ``acme_mailer.transport``
297307
tag. The second foreach loop iterates over the ``acme_mailer.transport``
298308
tags set for the current service and gives you the attributes.
299-

Diff for: components/form/introduction.rst

+19-19
Original file line numberDiff line numberDiff line change
@@ -113,45 +113,45 @@ CSRF Protection
113113
~~~~~~~~~~~~~~~
114114

115115
Protection against CSRF attacks is built into the Form component, but you need
116-
to explicitly enable it or replace it with a custom solution. The following
117-
snippet adds CSRF protection to the form factory::
116+
to explicitly enable it or replace it with a custom solution. If you want to
117+
use the built-in support, require the Security CSRF component by executing
118+
``composer require symfony/security-csrf``.
119+
120+
The following snippet adds CSRF protection to the form factory::
118121

119122
use Symfony\Component\Form\Forms;
120-
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
121-
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider;
122123
use Symfony\Component\HttpFoundation\Session\Session;
123-
124-
// generate a CSRF secret from somewhere
125-
$csrfSecret = '<generated token>';
124+
use Symfony\Component\Security\Extension\Csrf\CsrfExtension;
125+
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
126+
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
127+
use Symfony\Component\Security\Csrf\CsrfTokenManager;
126128

127129
// create a Session object from the HttpFoundation component
128130
$session = new Session();
129131

130-
$csrfProvider = new SessionCsrfProvider($session, $csrfSecret);
132+
$csrfGenerator = new UriSafeTokenGenerator();
133+
$csrfStorage = new SessionTokenStorage($session);
134+
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);
131135

132136
$formFactory = Forms::createFormFactoryBuilder()
133137
// ...
134-
->addExtension(new CsrfExtension($csrfProvider))
138+
->addExtension(new CsrfExtension($csrfStorage))
135139
->getFormFactory();
136140

137-
To secure your application against CSRF attacks, you need to define a CSRF
138-
secret. Generate a random string with at least 32 characters, insert it in the
139-
above snippet and make sure that nobody except your web server can access
140-
the secret.
141-
142141
Internally, this extension will automatically add a hidden field to every
143-
form (called ``_token`` by default) whose value is automatically generated
144-
and validated when binding the form.
142+
form (called ``_token`` by default) whose value is automatically generated by
143+
the CSRF generator and validated when binding the form.
145144

146145
.. tip::
147146

148147
If you're not using the HttpFoundation component, you can use
149-
:class:`Symfony\\Component\\Form\\Extension\\Csrf\\CsrfProvider\\DefaultCsrfProvider`
148+
:class:`Symfony\\Component\\Security\\Csrf\\TokenStorage\\NativeSessionTokenStorage`
150149
instead, which relies on PHP's native session handling::
151150

152-
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider;
151+
use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
153152

154-
$csrfProvider = new DefaultCsrfProvider($csrfSecret);
153+
$csrfStorage = new NativeSessionTokenStorage();
154+
// ...
155155

156156
Twig Templating
157157
~~~~~~~~~~~~~~~

Diff for: components/security/secure_tools.rst

+25-29
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,43 @@
1-
Securely Generating Random Numbers
2-
==================================
1+
Securely Generating Random Values
2+
=================================
33

44
The Symfony Security component comes with a collection of nice utilities
55
related to security. These utilities are used by Symfony, but you should
66
also use them if you want to solve the problem they address.
77

8-
Generating a Secure random Number
8+
Generating a Secure random String
99
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1010

11-
Whenever you need to generate a secure random number, you are highly
12-
encouraged to use the Symfony
13-
:class:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom` class::
11+
Whenever you need to generate a secure random string, you are highly
12+
encouraged to use the :phpfunction:`random_bytes` function::
1413

15-
use Symfony\Component\Security\Core\Util\SecureRandom;
14+
$random = random_bytes(10);
1615

17-
$generator = new SecureRandom();
18-
$random = $generator->nextBytes(10);
16+
The function returns a random string, suitable for cryptographic use, of
17+
the number bytes passed as an argument (10 in the above example).
1918

20-
The
21-
:method:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom::nextBytes`
22-
method returns a random string composed of the number of characters passed as
23-
an argument (10 in the above example).
19+
.. tip::
2420

25-
The SecureRandom class works better when OpenSSL is installed. But when it's
26-
not available, it falls back to an internal algorithm, which needs a seed file
27-
to work correctly. Just pass a file name to enable it::
21+
The ``random_bytes()`` function returns a binary string which may contain
22+
the ``\0`` character. This can cause trouble in several common scenarios,
23+
such as storing this value in a database or including it as part of the
24+
URL. The solution is to encode or hash the value returned by
25+
``random_bytes()`` (to do that, you can use a simple ``base64_encode()``
26+
PHP function).
2827

29-
use Symfony\Component\Security\Core\Util\SecureRandom;
28+
Generating a Secure Random Number
29+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3030

31-
$generator = new SecureRandom('/some/path/to/store/the/seed.txt');
31+
If you need to generate a cryptographically secure random integer, you should
32+
use the :phpfunction:`random_int` function::
3233

33-
$random = $generator->nextBytes(10);
34-
$hashedRandom = md5($random); // see tip below
34+
$random = random_int(1, 10);
3535

3636
.. note::
3737

38-
If you're using the Symfony Framework, you can get a secure random number
39-
generator via the ``security.secure_random`` service.
40-
41-
.. tip::
38+
PHP 7 and up provide the ``random_bytes()`` and ``random_int()`` functions
39+
natively, for older versions of PHP a polyfill is provided by the
40+
`Symfony Polyfill Component`_ and the `paragonie/random_compat package`_.
4241

43-
The ``nextBytes()`` method returns a binary string which may contain the
44-
``\0`` character. This can cause trouble in several common scenarios, such
45-
as storing this value in a database or including it as part of the URL. The
46-
solution is to hash the value returned by ``nextBytes()`` (to do that, you
47-
can use a simple ``md5()`` PHP function).
42+
.. _`Symfony Polyfill Component`: https://github.com/symfony/polyfill
43+
.. _`paragonie/random_compat package`: https://github.com/paragonie/random_compat

Diff for: components/serializer.rst

+2
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ method on the normalizer definition::
344344
$serializer = new Serializer(array($normalizer), array($encoder));
345345
$serializer->serialize($person, 'json'); // Output: {"name":"foo","sportsman":false}
346346

347+
.. _component-serializer-converting-property-names-when-serializing-and-deserializing:
348+
347349
Converting Property Names when Serializing and Deserializing
348350
------------------------------------------------------------
349351

Diff for: components/translation/usage.rst

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ recommended format. These files are parsed by one of the loader classes.
139139
'symfony.great' => 'J\'aime Symfony',
140140
);
141141
142+
.. _translation-real-vs-keyword-messages:
143+
142144
.. sidebar:: Using Real or Keyword Messages
143145

144146
This example illustrates the two different philosophies when creating

0 commit comments

Comments
 (0)