Skip to content

Commit 044a6bd

Browse files
committed
Merge remote-tracking branch 'upstream/3.3' into 3.3
2 parents 7660376 + 77d7f7f commit 044a6bd

File tree

72 files changed

+634
-300
lines changed

Some content is hidden

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

72 files changed

+634
-300
lines changed
Loading
14.2 KB
Loading

best_practices/controllers.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ for the homepage of our app:
9595
9696
namespace AppBundle\Controller;
9797
98+
use AppBundle\Entity\Post;
9899
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
99100
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
100101
@@ -106,7 +107,7 @@ for the homepage of our app:
106107
public function indexAction()
107108
{
108109
$posts = $this->getDoctrine()
109-
->getRepository('AppBundle:Post')
110+
->getRepository(Post::class)
110111
->findLatest();
111112
112113
return $this->render('default/index.html.twig', array(
@@ -186,7 +187,7 @@ manually. In our application, we have this situation in ``CommentController``:
186187
public function newAction(Request $request, $postSlug)
187188
{
188189
$post = $this->getDoctrine()
189-
->getRepository('AppBundle:Post')
190+
->getRepository(Post::class)
190191
->findOneBy(array('slug' => $postSlug));
191192
192193
if (!$post) {

best_practices/forms.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ and a ``createAction()`` that *only* processes the form submit. Both those
204204
actions will be almost identical. So it's much simpler to let ``newAction()``
205205
handle everything.
206206

207-
Second, we recommend using ``$form->isSubmitted()`` in the ``if`` statement
208-
for clarity. This isn't technically needed, since ``isValid()`` first calls
209-
``isSubmitted()``. But without this, the flow doesn't read well as it *looks*
210-
like the form is *always* processed (even on the GET request).
207+
Second, is it required to call ``$form->isSubmitted()`` in the ``if`` statement
208+
before calling ``isValid()``. Calling ``isValid()`` with an unsubmitted form
209+
is deprecated since version 3.2 and will throw an exception in 4.0.

best_practices/security.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ more advanced use-case, you can always do the same security check in PHP:
227227
public function editAction($id)
228228
{
229229
$post = $this->getDoctrine()
230-
->getRepository('AppBundle:Post')
230+
->getRepository(Post::class)
231231
->find($id);
232232
233233
if (!$post) {

best_practices/templates.rst

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,20 @@ Template Locations
3030
Store all your application's templates in ``app/Resources/views/`` directory.
3131

3232
Traditionally, Symfony developers stored the application templates in the
33-
``Resources/views/`` directory of each bundle. Then they used the logical name
34-
to refer to them (e.g. ``AcmeDemoBundle:Default:index.html.twig``).
33+
``Resources/views/`` directory of each bundle. Then they used the Twig namespaced
34+
path to refer to them (e.g. ``@AcmeDemo/Default/index.html.twig``).
3535

3636
But for the templates used in your application, it's much more convenient
3737
to store them in the ``app/Resources/views/`` directory. For starters, this
3838
drastically simplifies their logical names:
3939

40-
================================================= ==================================
41-
Templates Stored inside Bundles Templates Stored in ``app/``
42-
================================================= ==================================
43-
``AcmeDemoBundle:Default:index.html.twig`` ``default/index.html.twig``
44-
``::layout.html.twig`` ``layout.html.twig``
45-
``AcmeDemoBundle::index.html.twig`` ``index.html.twig``
46-
``AcmeDemoBundle:Default:subdir/index.html.twig`` ``default/subdir/index.html.twig``
47-
``AcmeDemoBundle:Default/subdir:index.html.twig`` ``default/subdir/index.html.twig``
48-
================================================= ==================================
40+
============================================ ==================================
41+
Templates Stored inside Bundles Templates Stored in ``app/``
42+
============================================ ==================================
43+
``@AcmeDemo/index.html.twig`` ``index.html.twig``
44+
``@AcmeDemo/Default/index.html.twig`` ``default/index.html.twig``
45+
``@AcmeDemo/Default/subdir/index.html.twig`` ``default/subdir/index.html.twig``
46+
============================================ ==================================
4947

5048
Another advantage is that centralizing your templates simplifies the work
5149
of your designers. They don't need to look for templates in lots of directories
@@ -121,7 +119,7 @@ class in the constructor of the Twig extension:
121119
new \Twig_SimpleFilter(
122120
'md2html',
123121
array($this, 'markdownToHtml'),
124-
array('is_safe' => array('html'))
122+
array('is_safe' => array('html'), 'pre_escape' => 'html')
125123
),
126124
);
127125
}

bundles/best_practices.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ The ``composer.json`` file should include at least the following metadata:
429429
In order to make it easier for developers to find your bundle, register it on
430430
`Packagist`_, the official repository for Composer packages.
431431

432+
Resources
433+
---------
434+
435+
If the bundle references any resources (config files, translation files, etc.),
436+
don't use physical paths (e.g. ``__DIR__/config/services.xml``) but logical
437+
paths (e.g. ``@AppBundle/Resources/config/services.xml``).
438+
439+
The logical paths are required because of the bundle overriding mechanism that
440+
lets you override any resource/file of any bundle. See :ref:`http-kernel-resource-locator`
441+
for more details about transforming physical paths into logical paths.
442+
443+
Beware that templates use a simplified version of the logical path shown above.
444+
For example, an ``index.html.twig`` template located in the ``Resources/views/Default/``
445+
directory of the AppBundle, is referenced as ``@App/Default/index.html.twig``.
446+
432447
Learn more
433448
----------
434449

bundles/override.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ How to Override any Part of a Bundle
77
This document is a quick reference for how to override different parts of
88
third-party bundles.
99

10+
.. tip::
11+
12+
The bundle overriding mechanism means that you cannot use physical paths to
13+
refer to bundle's resources (e.g. ``__DIR__/config/services.xml``). Always
14+
use logical paths in your bundles (e.g. ``@AppBundle/Resources/config/services.xml``)
15+
and call the :ref:`locateResource() method <http-kernel-resource-locator>`
16+
to turn them into physical paths when needed.
17+
1018
Templates
1119
---------
1220

components/console/helpers/questionhelper.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,15 @@ convenient for passwords::
212212
On Windows systems, this ``stty`` command may generate gibberish output and
213213
mangle the input text. If that's your case, disable it with this command::
214214

215+
use Symfony\Component\Console\Helper\QuestionHelper;
215216
use Symfony\Component\Console\Question\ChoiceQuestion;
216217

217218
// ...
218219
public function execute(InputInterface $input, OutputInterface $output)
219220
{
220221
// ...
221222
$helper = $this->getHelper('question');
222-
$helper->disableStty();
223+
QuestionHelper::disableStty();
223224

224225
// ...
225226
}

components/dom_crawler.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,19 @@ given text. This method is especially useful because you can use it to return
396396
a :class:`Symfony\\Component\\DomCrawler\\Form` object that represents the
397397
form that the button lives in::
398398

399-
$form = $crawler->selectButton('validate')->form();
399+
// button example: <button id="my-super-button" type="submit">My super button</button>
400+
401+
// you can get button by its label
402+
$form = $crawler->selectButton('My super button')->form();
403+
404+
// or by button id (#my-super-button) if the button doesn't have a label
405+
$form = $crawler->selectButton('my-super-button')->form();
406+
407+
// or you can filter the whole form, for example a form has a class attribute: <form class="form-vertical" method="POST">
408+
$crawler->filter('.form-vertical')->form();
400409

401410
// or "fill" the form fields with data
402-
$form = $crawler->selectButton('validate')->form(array(
411+
$form = $crawler->selectButton('my-super-button')->form(array(
403412
'name' => 'Ryan',
404413
));
405414

components/expression_language/ast.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ method after parsing any expression to get its AST::
2121
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
2222

2323
$ast = (new ExpressionLanguage())
24-
->parse('1 + 2')
24+
->parse('1 + 2', array())
2525
->getNodes()
2626
;
2727

@@ -41,7 +41,7 @@ method to turn the AST into an array::
4141
// ...
4242

4343
$astAsArray = (new ExpressionLanguage())
44-
->parse('1 + 2')
44+
->parse('1 + 2', array())
4545
->getNodes()
4646
->toArray()
4747
;

components/form.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ is created from the form factory.
418418
->add('dueDate', DateType::class)
419419
->getForm();
420420
421-
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
421+
return $this->render('@AcmeTask/Default/new.html.twig', array(
422422
'form' => $form->createView(),
423423
));
424424
}

components/http_foundation.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,12 @@ represented by a PHP callable instead of a string::
468468
you must call ``ob_flush()`` before ``flush()``.
469469

470470
Additionally, PHP isn't the only layer that can buffer output. Your web
471-
server might also buffer based on its configuration. What's more, if you
472-
use FastCGI, buffering can't be disabled at all.
471+
server might also buffer based on its configuration. Some servers, such as
472+
Nginx, let you disable buffering at config level or adding a special HTTP
473+
header in the response::
474+
475+
// disables FastCGI buffering in Nginx only for this response
476+
$response->headers->set('X-Accel-Buffering', 'no')
473477

474478
.. _component-http-foundation-serving-files:
475479

components/http_kernel.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,32 @@ look like this::
742742
// ...
743743
}
744744

745+
.. _http-kernel-resource-locator:
746+
747+
Locating Resources
748+
------------------
749+
750+
The HttpKernel component is responsible of the bundle mechanism used in Symfony
751+
applications. The key feature of the bundles is that they allow to override any
752+
resource used by the application (config files, templates, controllers,
753+
translation files, etc.)
754+
755+
This overriding mechanism works because resources are referenced not by their
756+
physical path but by their logical path. For example, the ``services.xml`` file
757+
stored in the ``Resources/config/`` directory of a bundle called AppBundle is
758+
referenced as ``@AppBundle/Resources/config/services.xml``. This logical path
759+
will work when the application overrides that file and even if you change the
760+
directory of AppBundle.
761+
762+
The HttpKernel component provides a method called :method:`Symfony\\Component\\HttpKernel\\Kernel::locateResource`
763+
which can be used to transform logical paths into physical paths::
764+
765+
use Symfony\Component\HttpKernel\HttpKernel;
766+
767+
// ...
768+
$kernel = new HttpKernel($dispatcher, $resolver);
769+
$path = $kernel->locateResource('@AppBundle/Resources/config/services.xml');
770+
745771
Learn more
746772
----------
747773

components/phpunit_bridge.rst

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,16 @@ to register a new `test listener`_ called ``SymfonyTestsListener``:
5656
Usage
5757
-----
5858

59-
Once the component is installed, it automatically registers a
60-
`PHPUnit event listener`_ which in turn registers a `PHP error handler`_
61-
called :class:`Symfony\\Bridge\\PhpUnit\\DeprecationErrorHandler`. After
62-
running your PHPUnit tests, you will get a report similar to this one:
59+
Once the component is installed, a ``simple-phpunit`` script is created in the
60+
``vendor/`` directory to run tests. This script wraps the original PHPUnit binary
61+
to provide more features:
62+
63+
.. code-block:: terminal
64+
65+
$ cd my-project/
66+
$ ./vendor/bin/simple-phpunit
67+
68+
After running your PHPUnit tests, you will get a report similar to this one:
6369

6470
.. image:: /_images/components/phpunit_bridge/report.png
6571

@@ -76,6 +82,21 @@ The summary includes:
7682
Deprecation notices are all other (non-legacy) notices, grouped by message,
7783
test class and method.
7884

85+
.. note::
86+
87+
If you don't want to use the ``simple-phpunit`` script, register the following
88+
`PHPUnit event listener`_ in your PHPUnit configuration file to get the same
89+
report about deprecations (which is created by a `PHP error handler`_
90+
called :class:`Symfony\\Bridge\\PhpUnit\\DeprecationErrorHandler`):
91+
92+
.. code-block:: xml
93+
94+
<!-- phpunit.xml.dist -->
95+
<!-- ... -->
96+
<listeners>
97+
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
98+
</listeners>
99+
79100
Trigger Deprecation Notices
80101
---------------------------
81102

components/property_info.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,17 @@ Using PHP reflection, the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\R
348348
provides list, type and access information from setter and accessor methods.
349349
It can also provide return and scalar types for PHP 7+.
350350

351-
This service is automatically registered with the ``property_info`` service in
352-
the Symfony Framework.
351+
.. note::
352+
353+
When using the Symfony framework, this service is automatically registered
354+
when the ``property_info`` feature is enabled:
355+
356+
.. code-block:: yaml
357+
358+
# app/config/config.yml
359+
framework:
360+
property_info:
361+
enabled: true
353362
354363
.. code-block:: php
355364

components/security/authorization.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ on a "remember-me" cookie, or even authenticated anonymously?
110110
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
111111
112112
$anonymousClass = AnonymousToken::class;
113-
$rememberMeClass = RememberMeToken::Class;
113+
$rememberMeClass = RememberMeToken::class;
114114
115115
$trustResolver = new AuthenticationTrustResolver($anonymousClass, $rememberMeClass);
116116

configuration/multiple_kernels.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,43 @@ In order to solve this issue, add the following configuration to your kernel:
178178
# allows to use app/Resources/views/ templates in the ApiKernel
179179
"%kernel.project_dir%/app/Resources/views": ~
180180
181+
Running Tests Using a Different Kernel
182+
--------------------------------------
183+
184+
In Symfony applications, functional tests extend by default from the
185+
:class:`Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase` class. Inside that
186+
class, a method called ``getKernelClass()`` tries to find the class of the kernel
187+
to use to run the application during tests. The logic of this method does not
188+
support multiple kernel applications, so your tests won't use the right kernel.
189+
190+
The solution is to create a custom base class for functional tests extending
191+
from ``WebTestCase`` class and overriding the ``getKernelClass()`` method to
192+
return the fully qualified class name of the kernel to use::
193+
194+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
195+
196+
// tests needing the ApiKernel to work, now must extend this
197+
// ApiTestCase class instead of the default WebTestCase class
198+
class ApiTestCase extends WebTestCase
199+
{
200+
protected static function getKernelClass()
201+
{
202+
return 'ApiKernel';
203+
}
204+
205+
// this is needed because the KernelTestCase class keeps a reference to
206+
// the previously created kernel in its static $kernel property. Thus,
207+
// if your functional tests do not run in isolated processes, a later run
208+
// test for a different kernel will reuse the previously created instance,
209+
// which points to a different kernel
210+
protected function tearDown()
211+
{
212+
parent::tearDown();
213+
214+
static::$class = null;
215+
}
216+
}
217+
181218
Adding more Kernels to the Application
182219
--------------------------------------
183220

console/input.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,12 @@ There are three argument variants you can use:
9191
provided;
9292

9393
``InputArgument::OPTIONAL``
94-
The argument is optional and therefore can be omitted;
94+
The argument is optional and therefore can be omitted. This is the default
95+
behavior of arguments;
9596

9697
``InputArgument::IS_ARRAY``
9798
The argument can contain any number of values. For that reason, it must be
98-
used at the end of the argument list
99+
used at the end of the argument list.
99100

100101
You can combine ``IS_ARRAY`` with ``REQUIRED`` and ``OPTIONAL`` like this::
101102

@@ -177,11 +178,15 @@ There are four option variants you can use:
177178

178179
``InputOption::VALUE_IS_ARRAY``
179180
This option accepts multiple values (e.g. ``--dir=/foo --dir=/bar``);
181+
180182
``InputOption::VALUE_NONE``
181-
Do not accept input for this option (e.g. ``--yell``);
183+
Do not accept input for this option (e.g. ``--yell``). This is the default
184+
behavior of options;
185+
182186
``InputOption::VALUE_REQUIRED``
183187
This value is required (e.g. ``--iterations=5``), the option itself is
184188
still optional;
189+
185190
``InputOption::VALUE_OPTIONAL``
186191
This option may or may not have a value (e.g. ``--yell`` or
187192
``--yell=loud``).

console/lockable_trait.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ that adds two convenient methods to lock and release commands::
3030
}
3131

3232
// If you prefer to wait until the lock is released, use this:
33-
// $this->lock(true);
33+
// $this->lock(null, true);
3434

3535
// ...
3636

0 commit comments

Comments
 (0)