Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6ef6a04

Browse filesBrowse files
committed
Merge branch '2.7'
* 2.7: (36 commits) Fixing bad reference [#4743] parts -> part - subjective, but this sounds slightly better to me Update web_server_configuration.rst Update web_server_configuration.rst Update web_server_configuration.rst Add exception to console exception log [#4454] Re-wording section, but it may not actually be accurate More concrete explanation of validation groups Adding missing index/map documents [#4611] A few more tweaks and fixes Basically copying a section about upgrading other libraries down into the minor version section [#4611] Removing a few entries I meant to remove before [#4611] Making many tweaks thanks to guys like Javier, Wouter, Christian (xabbuh) and Stof Adding a guide about upgrading Fix typo and remove redundant sentence Formatting fix document the `2.5` validation options [Reference] Add default_locale config description Clarify tip for creating a new AppBundle Update forms.rst ...
2 parents fcfea43 + 1f760c8 commit 6ef6a04
Copy full SHA for 6ef6a04

File tree

Expand file treeCollapse file tree

20 files changed

+566
-180
lines changed
Filter options
Expand file treeCollapse file tree

20 files changed

+566
-180
lines changed

‎best_practices/creating-the-project.rst

Copy file name to clipboardExpand all lines: best_practices/creating-the-project.rst
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ that follows these best practices:
152152
153153
.. tip::
154154

155-
If you are using Symfony 2.6 or a newer version, the ``AppBundle`` bundle
156-
is already generated for you. If you are using an older Symfony version,
155+
If your Symfony installation doesn't come with a pre-generated ``AppBundle``,
157156
you can generate it by hand executing this command:
158157

159158
.. code-block:: bash

‎best_practices/forms.rst

Copy file name to clipboardExpand all lines: best_practices/forms.rst
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Building Forms
1313
Define your forms as PHP classes.
1414

1515
The Form component allows you to build forms right inside your controller
16-
code. Honestly, unless you need to reuse the form somewhere else, that's
17-
totally fine. But for organization and reuse, we recommend that you define each
16+
code. This is perfectly fine if you don't need to reuse the form somewhere else.
17+
But for organization and reuse, we recommend that you define each
1818
form in its own PHP class::
1919

2020
namespace AppBundle\Form;

‎best_practices/templates.rst

Copy file name to clipboardExpand all lines: best_practices/templates.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ name is irrelevant because you never use it in your own code):
153153
app.twig.app_extension:
154154
class: AppBundle\Twig\AppExtension
155155
arguments: ["@markdown"]
156+
public: false
156157
tags:
157158
- { name: twig.extension }
158159

‎book/forms.rst

Copy file name to clipboardExpand all lines: book/forms.rst
+32-3Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ to an array callback::
526526

527527
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
528528

529+
// ...
529530
public function setDefaultOptions(OptionsResolverInterface $resolver)
530531
{
531532
$resolver->setDefaults(array(
@@ -541,23 +542,51 @@ This will call the static method ``determineValidationGroups()`` on the
541542
The Form object is passed as an argument to that method (see next example).
542543
You can also define whole logic inline by using a ``Closure``::
543544

545+
use Acme\AcmeBundle\Entity\Client;
544546
use Symfony\Component\Form\FormInterface;
545547
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
546548

549+
// ...
547550
public function setDefaultOptions(OptionsResolverInterface $resolver)
548551
{
549552
$resolver->setDefaults(array(
550553
'validation_groups' => function(FormInterface $form) {
551554
$data = $form->getData();
552-
if (Entity\Client::TYPE_PERSON == $data->getType()) {
555+
if (Client::TYPE_PERSON == $data->getType()) {
553556
return array('person');
554-
} else {
555-
return array('company');
556557
}
558+
559+
return array('company');
560+
},
561+
));
562+
}
563+
564+
Using the ``validation_groups`` option overrides the default validation
565+
group which is being used. If you want to validate the default constraints
566+
of the entity as well you have to adjust the option as follows::
567+
568+
use Acme\AcmeBundle\Entity\Client;
569+
use Symfony\Component\Form\FormInterface;
570+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
571+
572+
// ...
573+
public function setDefaultOptions(OptionsResolverInterface $resolver)
574+
{
575+
$resolver->setDefaults(array(
576+
'validation_groups' => function(FormInterface $form) {
577+
$data = $form->getData();
578+
if (Client::TYPE_PERSON == $data->getType()) {
579+
return array('Default', 'person');
580+
}
581+
582+
return array('Default', 'company');
557583
},
558584
));
559585
}
560586

587+
You can find more information about how the validation groups and the default constraints
588+
work in the book section about :ref:`validation groups <book-validation-validation-groups>`.
589+
561590
.. index::
562591
single: Forms; Validation groups based on clicked button
563592

‎book/http_cache.rst

Copy file name to clipboardExpand all lines: book/http_cache.rst
+120-71Lines changed: 120 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,14 @@ its creation more manageable::
333333
// set a custom Cache-Control directive
334334
$response->headers->addCacheControlDirective('must-revalidate', true);
335335

336-
Public vs private Responses
336+
.. tip::
337+
338+
If you need to set cache headers for many different controller actions,
339+
you might want to look into the FOSHttpCacheBundle_. It provides a way
340+
to define cache headers based on the URL pattern and other request
341+
properties.
342+
343+
Public vs Private Responses
337344
~~~~~~~~~~~~~~~~~~~~~~~~~~~
338345

339346
Both gateway and proxy caches are considered "shared" caches as the cached
@@ -399,9 +406,10 @@ header when none is set by the developer by following these rules:
399406
``private`` directive automatically (except when ``s-maxage`` is set).
400407

401408
.. _http-expiration-validation:
409+
.. _http-expiration-and-validation:
402410

403-
HTTP Expiration and Validation
404-
------------------------------
411+
HTTP Expiration, Validation and Invalidation
412+
--------------------------------------------
405413

406414
The HTTP specification defines two caching models:
407415

@@ -418,7 +426,9 @@ The HTTP specification defines two caching models:
418426
header) to check if the page has changed since being cached.
419427

420428
The goal of both models is to never generate the same response twice by relying
421-
on a cache to store and return "fresh" responses.
429+
on a cache to store and return "fresh" responses. To achieve long caching times
430+
but still provide updated content immediately, *cache invalidation* is
431+
sometimes used.
422432

423433
.. sidebar:: Reading the HTTP Specification
424434

@@ -772,7 +782,7 @@ at some interval (the expiration) to verify that the content is still valid.
772782
annotations. See the `FrameworkExtraBundle documentation`_.
773783

774784
.. index::
775-
pair: Cache; Configuration
785+
pair: Cache; Configuration
776786

777787
More Response Methods
778788
~~~~~~~~~~~~~~~~~~~~~
@@ -800,8 +810,110 @@ Additionally, most cache-related HTTP headers can be set via the single
800810
));
801811

802812
.. index::
803-
single: Cache; ESI
804-
single: ESI
813+
single: Cache; Invalidation
814+
815+
.. _http-cache-invalidation:
816+
817+
Cache Invalidation
818+
~~~~~~~~~~~~~~~~~~
819+
820+
"There are only two hard things in Computer Science: cache invalidation
821+
and naming things." -- Phil Karlton
822+
823+
Once an URL is cached by a gateway cache, the cache will not ask the
824+
application for that content anymore. This allows the cache to provide fast
825+
responses and reduces the load on your application. However, you risk
826+
delivering outdated content. A way out of this dilemma is to use long
827+
cache lifetimes, but to actively notify the gateway cache when content
828+
changes. Reverse proxies usually provide a channel to receive such
829+
notifications, typically through special HTTP requests.
830+
831+
.. caution::
832+
833+
While cache invalidation is powerful, avoid it when possible. If you fail
834+
to invalidate something, outdated caches will be served for a potentially
835+
long time. Instead, use short cache lifetimes or use the validation model,
836+
and adjust your controllers to perform efficient validation checks as
837+
explained in :ref:`optimizing-cache-validation`.
838+
839+
Furthermore, since invalidation is a topic specific to each type of reverse
840+
proxy, using this concept will tie you to a specific reverse proxy or need
841+
additional efforts to support different proxies.
842+
843+
Sometimes, however, you need that extra performance you can get when
844+
explicitly invalidating. For invalidation, your application needs to detect
845+
when content changes and tell the cache to remove the URLs which contain
846+
that data from its cache.
847+
848+
.. tip::
849+
850+
If you want to use cache invalidation, have a look at the
851+
`FOSHttpCacheBundle`_. This bundle provides services to help with various
852+
cache invalidation concepts, and also documents the configuration for the
853+
a couple of common caching proxies.
854+
855+
If one content corresponds to one URL, the ``PURGE`` model works well.
856+
You send a request to the cache proxy with the HTTP method ``PURGE`` (using
857+
the word "PURGE" is a convention, technically this can be any string) instead
858+
of ``GET`` and make the cache proxy detect this and remove the data from the
859+
cache instead of going to Symfony to get a response.
860+
861+
Here is how you can configure the Symfony reverse proxy to support the
862+
``PURGE`` HTTP method::
863+
864+
// app/AppCache.php
865+
866+
// ...
867+
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
868+
use Symfony\Component\HttpFoundation\Request;
869+
use Symfony\Component\HttpFoundation\Response;
870+
871+
class AppCache extends HttpCache
872+
{
873+
protected function invalidate(Request $request, $catch = false)
874+
{
875+
if ('PURGE' !== $request->getMethod()) {
876+
return parent::invalidate($request, $catch);
877+
}
878+
879+
if ('127.0.0.1' !== $request->getClientIp()) {
880+
return new Response('Invalid HTTP method', Response::HTTP_BAD_REQUEST);
881+
}
882+
883+
$response = new Response();
884+
if ($this->getStore()->purge($request->getUri())) {
885+
$response->setStatusCode(200, 'Purged');
886+
} else {
887+
$response->setStatusCode(200, 'Not found');
888+
}
889+
890+
return $response;
891+
}
892+
}
893+
894+
.. caution::
895+
896+
You must protect the ``PURGE`` HTTP method somehow to avoid random people
897+
purging your cached data.
898+
899+
**Purge** instructs the cache to drop a resource in *all its variants*
900+
(according to the ``Vary`` header, see above). An alternative to purging is
901+
**refreshing** a content. Refreshing means that the caching proxy is
902+
instructed to discard its local cache and fetch the content again. This way,
903+
the new content is already available in the cache. The drawback of refreshing
904+
is that variants are not invalidated.
905+
906+
In many applications, the same content bit is used on various pages with
907+
different URLs. More flexible concepts exist for those cases:
908+
909+
* **Banning** invalidates responses matching regular expressions on the
910+
URL or other criteria;
911+
* **Cache tagging** lets you add a tag for each content used in a response
912+
so that you can invalidate all URLs containing a certain content.
913+
914+
.. index::
915+
single: Cache; ESI
916+
single: ESI
805917

806918
.. _edge-side-includes:
807919

@@ -1048,70 +1160,6 @@ The ``render_esi`` helper supports two other useful options:
10481160
of ``continue`` indicating that, in the event of a failure, the gateway cache
10491161
will simply remove the ESI tag silently.
10501162

1051-
.. index::
1052-
single: Cache; Invalidation
1053-
1054-
.. _http-cache-invalidation:
1055-
1056-
Cache Invalidation
1057-
------------------
1058-
1059-
"There are only two hard things in Computer Science: cache invalidation
1060-
and naming things." -- Phil Karlton
1061-
1062-
You should never need to invalidate cached data because invalidation is already
1063-
taken into account natively in the HTTP cache models. If you use validation,
1064-
you never need to invalidate anything by definition; and if you use expiration
1065-
and need to invalidate a resource, it means that you set the expires date
1066-
too far away in the future.
1067-
1068-
.. note::
1069-
1070-
Since invalidation is a topic specific to each type of reverse proxy,
1071-
if you don't worry about invalidation, you can switch between reverse
1072-
proxies without changing anything in your application code.
1073-
1074-
Actually, all reverse proxies provide ways to purge cached data, but you
1075-
should avoid them as much as possible. The most standard way is to purge the
1076-
cache for a given URL by requesting it with the special ``PURGE`` HTTP method.
1077-
1078-
Here is how you can configure the Symfony reverse proxy to support the
1079-
``PURGE`` HTTP method::
1080-
1081-
// app/AppCache.php
1082-
1083-
// ...
1084-
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
1085-
use Symfony\Component\HttpFoundation\Request;
1086-
use Symfony\Component\HttpFoundation\Response;
1087-
1088-
class AppCache extends HttpCache
1089-
{
1090-
protected function invalidate(Request $request, $catch = false)
1091-
{
1092-
if ('PURGE' !== $request->getMethod()) {
1093-
return parent::invalidate($request, $catch);
1094-
}
1095-
1096-
$response = new Response();
1097-
if ($this->getStore()->purge($request->getUri())) {
1098-
$response->setStatusCode(Response::HTTP_OK, 'Purged');
1099-
} else {
1100-
$response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not purged');
1101-
}
1102-
1103-
return $response;
1104-
}
1105-
}
1106-
1107-
.. versionadded:: 2.4
1108-
Support for HTTP status code constants was introduced in Symfony 2.4.
1109-
1110-
.. caution::
1111-
1112-
You must protect the ``PURGE`` HTTP method somehow to avoid random people
1113-
purging your cached data.
1114-
11151163
Summary
11161164
-------
11171165

@@ -1139,3 +1187,4 @@ Learn more from the Cookbook
11391187
.. _`P6 - Caching: Browser and intermediary caches`: http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache
11401188
.. _`FrameworkExtraBundle documentation`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/cache.html
11411189
.. _`ESI`: http://www.w3.org/TR/esi-lang
1190+
.. _`FOSHttpCacheBundle`: http://foshttpcachebundle.readthedocs.org/

‎book/security.rst

Copy file name to clipboardExpand all lines: book/security.rst
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,7 @@ Next, you'll need to create a route for this URL (but not a controller):
11481148
return $collection;
11491149
11501150
And that's it! By sending a user to ``/logout`` (or whatever you configure
1151-
the ``path`` to be), Symfony will un-authenticate the current user. and
1152-
redirect them the homepage (the value defined by ``target``).
1151+
the ``path`` to be), Symfony will un-authenticate the current user.
11531152

11541153
Once the user has been logged out, they will be redirected to whatever path
11551154
is defined by the ``target`` parameter above (e.g. the ``homepage``).

‎book/validation.rst

Copy file name to clipboardExpand all lines: book/validation.rst
+29-1Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,11 +817,39 @@ With this configuration, there are three validation groups:
817817
that belong to no other group.
818818

819819
``User``
820-
Equivalent to all constraints of the ``User`` object in the ``Default`` group.
820+
Equivalent to all constraints of the ``User`` object in the ``Default``
821+
group. This is always the name of the class. The difference between this
822+
and ``Default`` is explained below.
821823

822824
``registration``
823825
Contains the constraints on the ``email`` and ``password`` fields only.
824826

827+
Constraints in the ``Default`` group of a class are the constraints that have either no
828+
explicit group configured or that are configured to a group equal to the class name or
829+
the string ``Default``.
830+
831+
.. caution::
832+
833+
When validating *just* the User object, there is no difference between the ``Default`` group
834+
and the ``User`` group. But, there is a difference if ``User`` has embedded objects. For example,
835+
imagine ``User`` has an ``address`` property that contains some ``Address`` object and that
836+
you've added the :doc:`/reference/constraints/Valid` constraint to this property so that it's
837+
validated when you validate the ``User`` object.
838+
839+
If you validate ``User`` using the ``Default`` group, then any constraints on the ``Address``
840+
class that are in the ``Default`` group *will* be used. But, if you validate ``User`` using the
841+
``User`` validation group, then only constraints on the ``Address`` class with the ``User``
842+
group will be validated.
843+
844+
In other words, the ``Default`` group and the class name group (e.g. ``User``) are identical,
845+
except when the class is embedded in another object that's actually the one being validated.
846+
847+
If you have inheritance (e.g. ``User extends BaseUser``) and you validate
848+
with the class name of the subclass (i.e. ``User``), then all constraints
849+
in the ``User`` and ``BaseUser`` will be validated. However, if you validate
850+
using the base class (i.e. ``BaseUser``), then only the constraints in
851+
the ``BaseUser`` group will be validated.
852+
825853
To tell the validator to use a specific group, pass one or more group names
826854
as the third argument to the ``validate()`` method::
827855

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.