Skip to content

Commit

Permalink
Merge branch '2.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed Dec 26, 2013
2 parents 6bdcdb1 + 479ec86 commit 6b7d307
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 37 deletions.
13 changes: 4 additions & 9 deletions book/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,10 @@ Disabling Validation
~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.3
The ability to set ``validation_groups`` to false was added in Symfony 2.3,
although setting it to an empty array achieved the same result in previous
versions.
The ability to set ``validation_groups`` to false was added in Symfony 2.3.

Sometimes it is useful to suppress the validation of a form altogether. For
these cases, you can skip the call to :method:`Symfony\\Component\\Form\\FormInterface::isValid`
in your controller. If this is not possible, you can alternatively set the
``validation_groups`` option to ``false`` or an empty array::
these cases you can set the ``validation_groups`` option to ``false``::

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

Expand All @@ -497,9 +493,8 @@ in your controller. If this is not possible, you can alternatively set the

Note that when you do that, the form will still run basic integrity checks,
for example whether an uploaded file was too large or whether non-existing
fields were submitted. If you want to suppress validation completely, remove
the :method:`Symfony\\Component\\Form\\FormInterface::isValid` call from your
controller.
fields were submitted. If you want to suppress validation, you can use the
:ref:`POST_SUBMIT event <cookbook-dynamic-form-modification-suppressing-form-validation>`

.. index::
single: Forms; Validation groups based on submitted data
Expand Down
45 changes: 24 additions & 21 deletions book/http_cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,11 @@ The ``Cache-Control`` header is unique in that it contains not one, but various
pieces of information about the cacheability of a response. Each piece of
information is separated by a comma:

Cache-Control: private, max-age=0, must-revalidate
.. code-block:: text
Cache-Control: private, max-age=0, must-revalidate
Cache-Control: max-age=3600, must-revalidate
Cache-Control: max-age=3600, must-revalidate
Symfony provides an abstraction around the ``Cache-Control`` header to make
its creation more manageable::
Expand Down Expand Up @@ -385,7 +387,7 @@ header when none is set by the developer by following these rules:
* If ``Cache-Control`` is empty (but one of the other cache headers is present),
its value is set to ``private, must-revalidate``;

* But if at least one ``Cache-Control`` directive is set, and no 'public' or
* But if at least one ``Cache-Control`` directive is set, and no ``public`` or
``private`` directives have been explicitly added, Symfony2 adds the
``private`` directive automatically (except when ``s-maxage`` is set).

Expand Down Expand Up @@ -667,7 +669,7 @@ exposing a simple and efficient pattern::
// a database or a key-value store for instance)
$article = ...;

// create a Response with a ETag and/or a Last-Modified header
// create a Response with an ETag and/or a Last-Modified header
$response = new Response();
$response->setETag($article->computeETag());
$response->setLastModified($article->getPublishedAt());
Expand All @@ -679,17 +681,17 @@ exposing a simple and efficient pattern::
if ($response->isNotModified($request)) {
// return the 304 Response immediately
return $response;
} else {
// do more work here - like retrieving more data
$comments = ...;

// or render a template with the $response you've already started
return $this->render(
'MyBundle:MyController:article.html.twig',
array('article' => $article, 'comments' => $comments),
$response
);
}

// do more work here - like retrieving more data
$comments = ...;

// or render a template with the $response you've already started
return $this->render(
'MyBundle:MyController:article.html.twig',
array('article' => $article, 'comments' => $comments),
$response
);
}

When the ``Response`` is not modified, the ``isNotModified()`` automatically sets
Expand Down Expand Up @@ -956,8 +958,9 @@ component cache will only last for 60 seconds.
When using a controller reference, the ESI tag should reference the embedded
action as an accessible URL so the gateway cache can fetch it independently of
the rest of the page. Symfony2 takes care of generating a unique URL for any
controller reference and it is able to route them properly thanks to a
listener that must be enabled in your configuration:
controller reference and it is able to route them properly thanks to the
:class:`Symfony\\Component\\HttpKernel\\EventListener\\FragmentListener`
that must be enabled in your configuration:

.. configuration-block::

Expand Down Expand Up @@ -1063,10 +1066,10 @@ Here is how you can configure the Symfony2 reverse proxy to support the
}

$response = new Response();
if (!$this->getStore()->purge($request->getUri())) {
$response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not purged');
} else {
if ($this->getStore()->purge($request->getUri())) {
$response->setStatusCode(Response::HTTP_OK, 'Purged');
} else {
$response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not purged');
}

return $response;
Expand Down Expand Up @@ -1104,6 +1107,6 @@ Learn more from the Cookbook
.. _`validation model`: http://tools.ietf.org/html/rfc2616#section-13.3
.. _`RFC 2616`: http://tools.ietf.org/html/rfc2616
.. _`HTTP Bis`: http://tools.ietf.org/wg/httpbis/
.. _`P4 - Conditional Requests`: http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-12
.. _`P6 - Caching: Browser and intermediary caches`: http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-12
.. _`P4 - Conditional Requests`: http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional
.. _`P6 - Caching: Browser and intermediary caches`: http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache
.. _`ESI`: http://www.w3.org/TR/esi-lang
2 changes: 1 addition & 1 deletion book/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ The job of the ``validator`` is easy: to read the constraints (i.e. rules)
of a class and verify whether or not the data on the object satisfies those
constraints. If validation fails, a non-empty list of errors
(class :class:`Symfony\\Component\\Validator\\ConstraintViolationList`) is
returned. Take this simple example from inside a controller:
returned. Take this simple example from inside a controller::

// ...
use Symfony\Component\HttpFoundation\Response;
Expand Down
32 changes: 32 additions & 0 deletions cookbook/form/dynamic_form_modification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -583,3 +583,35 @@ after the sport is selected. This should be handled by making an AJAX call
back to your application. In that controller, you can submit your form, but
instead of processing it, simply use the submitted form to render the updated
fields. The response from the AJAX call can then be used to update the view.

.. _cookbook-dynamic-form-modification-suppressing-form-validation:

Suppressing Form Validation
---------------------------

To suppress form validation you can use the ``POST_SUBMIT`` event and prevent
the :class:`Symfony\\Component\\Form\\Extension\\Validator\\EventListener\\ValidationListener`
from being called.

The reason for needing to do this is that even if you set ``group_validation``
to ``false`` there are still some integrity checks executed. For example
an uploaded file will still be checked to see if it is too large and the form
will still check to see if non-existing fields were submitted. To disable
all of this, use a listener::

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::POST_SUBMIT, function($event) {
$event->stopPropagation();
}, 900); // Always set a higher priority than ValidationListener

// ...
}

.. caution::

By doing this, you may accidentally disable something more than just form
validation, since the ``POST_SUBMIT`` event may have other listeners.
1 change: 1 addition & 0 deletions cookbook/map.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@

* :doc:`/cookbook/profiler/data_collector`
* :doc:`/cookbook/profiler/matchers`
* :doc:`/cookbook/profiler/storage`

* :doc:`/cookbook/request/index`

Expand Down
1 change: 1 addition & 0 deletions cookbook/profiler/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ Profiler

data_collector
matchers
storage
69 changes: 69 additions & 0 deletions cookbook/profiler/storage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.. index::
single: Profiling; Storage Configuration

Switching the Profiler Storage
==============================

By default the profile stores the collected data in files in the cache directory.
You can control the storage being used through the ``dsn``, ``username``,
``password`` and ``lifetime`` options. For example, the following configuration
uses MySQL as the storage for the profiler with a lifetime of one hour:

.. configuration-block::

.. code-block:: yaml
# app/config/config.yml
framework:
profiler:
dsn: "mysql:host=localhost;dbname=%database_name%"
username: "%database_user%"
password: "%database_password%"
lifetime: 3600
.. code-block:: xml
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
>
<framework:config>
<framework:profiler
dsn="mysql:host=localhost;dbname=%database_name%"
username="%database_user%"
password="%database_password%"
lifetime="3600"
/>
</framework:config>
</container>
.. code-block:: php
// app/config/config.php
// ...
$container->loadFromExtension('framework', array(
'profiler' => array(
'dsn' => 'mysql:host=localhost;dbname=%database_name%',
'username' => '%database_user',
'password' => '%database_password%',
'lifetime' => 3600,
),
));
The :doc:`HttpKernel component </components/http_kernel/introduction>` currently
supports the following profiler storage implementations:

* :class:`Symfony\\Component\\HttpKernel\\Profiler\\FileProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\MemcachedProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\MemcacheProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\MongoDbProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\MysqlProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\RedisProfilerStorage`
* :class:`Symfony\\Component\\HttpKernel\\Profiler\\SqliteProfilerStorage`
6 changes: 3 additions & 3 deletions cookbook/security/entity_provider.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ user records and encode their password, see :ref:`book-security-encoding-user-pa

.. code-block:: bash
$ mysql> select * from acme_users;
$ mysql> SELECT * FROM acme_users;
+----+----------+------+------------------------------------------+--------------------+-----------+
| id | username | salt | password | email | is_active |
+----+----------+------+------------------------------------------+--------------------+-----------+
Expand Down Expand Up @@ -682,14 +682,14 @@ this:

.. code-block:: bash
$ mysql> select * from acme_role;
$ mysql> SELECT * FROM acme_role;
+----+-------+------------+
| id | name | role |
+----+-------+------------+
| 1 | admin | ROLE_ADMIN |
+----+-------+------------+
$ mysql> select * from user_role;
$ mysql> SELECT * FROM user_role;
+---------+---------+
| user_id | role_id |
+---------+---------+
Expand Down
9 changes: 6 additions & 3 deletions cookbook/service_container/scopes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ marked as ``synchronized``:
class: Acme\HelloBundle\Client\ClientConfiguration
scope: client
synchronized: true
synthetic: true
# ...
.. code-block:: xml
Expand All @@ -151,6 +152,7 @@ marked as ``synchronized``:
id="client_configuration"
scope="client"
synchronized="true"
synthetic="true"
class="Acme\HelloBundle\Client\ClientConfiguration"
/>
</services>
Expand All @@ -167,6 +169,7 @@ marked as ``synchronized``:
);
$definition->setScope('client');
$definition->setSynchronized(true);
$definition->setSynthetic(true);
$container->setDefinition('client_configuration', $definition);
Now, if you inject this service using setter injection, there are no drawbacks
Expand Down Expand Up @@ -196,9 +199,9 @@ and everything works without any special code in your service or in your definit
}
}

Whenever the ``client`` scope is entered or left, the service container will
automatically call the ``setClientConfiguration()`` method with the current
``client_configuration`` instance.
Whenever the ``client`` scope is active, the service container will
automatically call the ``setClientConfiguration()`` method when the
``client_configuration`` service is set in the container.

You might have noticed that the ``setClientConfiguration()`` method accepts
``null`` as a valid value for the ``client_configuration`` argument. That's
Expand Down

0 comments on commit 6b7d307

Please sign in to comment.