Skip to content

Commit 543b482

Browse files
authored
Merge branch '2.7' into fix_7530
2 parents 11e245b + df84f3d commit 543b482

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

+728
-451
lines changed

best_practices/controllers.rst

+3-2
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(
@@ -170,7 +171,7 @@ manually. In our application, we have this situation in ``CommentController``:
170171
public function newAction(Request $request, $postSlug)
171172
{
172173
$post = $this->getDoctrine()
173-
->getRepository('AppBundle:Post')
174+
->getRepository(Post::class)
174175
->findOneBy(array('slug' => $postSlug));
175176
176177
if (!$post) {

best_practices/security.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ more advanced use-case, you can always do the same security check in PHP:
226226
*/
227227
public function editAction($id)
228228
{
229-
$post = $this->getDoctrine()->getRepository('AppBundle:Post')
229+
$post = $this->getDoctrine()->getRepository(Post::class)
230230
->find($id);
231231
232232
if (!$post) {

best_practices/templates.rst

+10-12
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
@@ -131,7 +129,7 @@ service in the constructor of the Twig extension:
131129
new \Twig_SimpleFilter(
132130
'md2html',
133131
array($this, 'markdownToHtml'),
134-
array('is_safe' => array('html'))
132+
array('is_safe' => array('html'), 'pre_escape' => 'html')
135133
),
136134
);
137135
}

bundles/best_practices.rst

+15
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,21 @@ API is being used. The following code, would work for *all* users::
471471
}
472472
}
473473

474+
Resources
475+
---------
476+
477+
If the bundle references any resources (config files, translation files, etc.),
478+
don't use physical paths (e.g. ``__DIR__/config/services.xml``) but logical
479+
paths (e.g. ``@AppBundle/Resources/config/services.xml``).
480+
481+
The logical paths are required because of the bundle overriding mechanism that
482+
lets you override any resource/file of any bundle. See :ref:`http-kernel-resource-locator`
483+
for more details about transforming physical paths into logical paths.
484+
485+
Beware that templates use a simplified version of the logical path shown above.
486+
For example, an ``index.html.twig`` template located in the ``Resources/views/Default/``
487+
directory of the AppBundle, is referenced as ``@App/Default/index.html.twig``.
488+
474489
Learn more
475490
----------
476491

bundles/override.rst

+8
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/dialoghelper.rst

+5-1
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,15 @@ in the console, so it is a good practice to put some useful information in it. T
142142
function should also return the value of the user's input if the validation was successful.
143143

144144
You can set the max number of times to ask in the ``$attempts`` argument.
145-
If you reach this max number it will use the default value.
146145
Using ``false`` means the amount of attempts is infinite.
147146
The user will be asked as long as they provide an invalid answer and will only
148147
be able to proceed if their input is valid.
149148

149+
Each time the user is asked the question, the default one is used if no answer
150+
is supplied (and validated with the ``$validator`` callback). If the last
151+
attempt is reached, the application will throw an exception and ends its
152+
execution.
153+
150154
Validating a Hidden Response
151155
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152156

components/dom_crawler.rst

+11-2
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,19 @@ given text. This method is especially useful because you can use it to return
338338
a :class:`Symfony\\Component\\DomCrawler\\Form` object that represents the
339339
form that the button lives in::
340340

341-
$form = $crawler->selectButton('validate')->form();
341+
// button example: <button id="my-super-button" type="submit">My super button</button>
342+
343+
// you can get button by its label
344+
$form = $crawler->selectButton('My super button')->form();
345+
346+
// or by button id (#my-super-button) if the button doesn't have a label
347+
$form = $crawler->selectButton('my-super-button')->form();
348+
349+
// or you can filter the whole form, for example a form has a class attribute: <form class="form-vertical" method="POST">
350+
$crawler->filter('.form-vertical')->form();
342351

343352
// or "fill" the form fields with data
344-
$form = $crawler->selectButton('validate')->form(array(
353+
$form = $crawler->selectButton('my-super-button')->form(array(
345354
'name' => 'Ryan',
346355
));
347356

components/form.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ is created from the form factory.
408408
->add('dueDate', 'date')
409409
->getForm();
410410
411-
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
411+
return $this->render('@AcmeTask/Default/new.html.twig', array(
412412
'form' => $form->createView(),
413413
));
414414
}

components/http_foundation.rst

+6-2
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

+27-1
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ each event has their own event object:
592592
===================== ================================ ===================================================================================
593593
Name ``KernelEvents`` Constant Argument passed to the listener
594594
===================== ================================ ===================================================================================
595-
kernel.request ``KernelEvents::REQUEST`` :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent`
595+
kernel.request ``KernelEvents::REQUEST`` :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent`
596596
kernel.controller ``KernelEvents::CONTROLLER`` :class:`Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent`
597597
kernel.view ``KernelEvents::VIEW`` :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent`
598598
kernel.response ``KernelEvents::RESPONSE`` :class:`Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent`
@@ -701,6 +701,32 @@ look like this::
701701
// ...
702702
}
703703

704+
.. _http-kernel-resource-locator:
705+
706+
Locating Resources
707+
------------------
708+
709+
The HttpKernel component is responsible of the bundle mechanism used in Symfony
710+
applications. The key feature of the bundles is that they allow to override any
711+
resource used by the application (config files, templates, controllers,
712+
translation files, etc.)
713+
714+
This overriding mechanism works because resources are referenced not by their
715+
physical path but by their logical path. For example, the ``services.xml`` file
716+
stored in the ``Resources/config/`` directory of a bundle called AppBundle is
717+
referenced as ``@AppBundle/Resources/config/services.xml``. This logical path
718+
will work when the application overrides that file and even if you change the
719+
directory of AppBundle.
720+
721+
The HttpKernel component provides a method called :method:`Symfony\\Component\\HttpKernel\\Kernel::locateResource`
722+
which can be used to transform logical paths into physical paths::
723+
724+
use Symfony\Component\HttpKernel\HttpKernel;
725+
726+
// ...
727+
$kernel = new HttpKernel($dispatcher, $resolver);
728+
$path = $kernel->locateResource('@AppBundle/Resources/config/services.xml');
729+
704730
Learn more
705731
----------
706732

components/phpunit_bridge.rst

+25-4
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@ You can install the component in 2 different ways:
3737
Usage
3838
-----
3939

40-
Once the component is installed, it automatically registers a
41-
`PHPUnit event listener`_ which in turn registers a `PHP error handler`_
42-
called :class:`Symfony\\Bridge\\PhpUnit\\DeprecationErrorHandler`. After
43-
running your PHPUnit tests, you will get a report similar to this one:
40+
Once the component is installed, a ``simple-phpunit`` script is created in the
41+
``vendor/`` directory to run tests. This script wraps the original PHPUnit binary
42+
to provide more features:
43+
44+
.. code-block:: terminal
45+
46+
$ cd my-project/
47+
$ ./vendor/bin/simple-phpunit
48+
49+
After running your PHPUnit tests, you will get a report similar to this one:
4450

4551
.. image:: /_images/components/phpunit_bridge/report.png
4652

@@ -57,6 +63,21 @@ The summary includes:
5763
Deprecation notices are all other (non-legacy) notices, grouped by message,
5864
test class and method.
5965

66+
.. note::
67+
68+
If you don't want to use the ``simple-phpunit`` script, register the following
69+
`PHPUnit event listener`_ in your PHPUnit configuration file to get the same
70+
report about deprecations (which is created by a `PHP error handler`_
71+
called :class:`Symfony\\Bridge\\PhpUnit\\DeprecationErrorHandler`):
72+
73+
.. code-block:: xml
74+
75+
<!-- phpunit.xml.dist -->
76+
<!-- ... -->
77+
<listeners>
78+
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
79+
</listeners>
80+
6081
Trigger Deprecation Notices
6182
---------------------------
6283

components/security/authorization.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ on a "remember-me" cookie, or even authenticated anonymously?
122122
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
123123
124124
$anonymousClass = AnonymousToken::class;
125-
$rememberMeClass = RememberMeToken::Class;
125+
$rememberMeClass = RememberMeToken::class;
126126
127127
$trustResolver = new AuthenticationTrustResolver($anonymousClass, $rememberMeClass);
128128

components/validator.rst

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ characters long::
4646
}
4747
}
4848

49+
The validator returns the list of violations.
50+
4951
Retrieving a Validator Instance
5052
-------------------------------
5153

configuration/multiple_kernels.rst

+37
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.root_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

+8-3
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``).

0 commit comments

Comments
 (0)