Skip to content

Commit

Permalink
Merge branch '2.8'
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Nov 26, 2015
2 parents 267e898 + 5a361ee commit af97ce1
Show file tree
Hide file tree
Showing 44 changed files with 591 additions and 205 deletions.
4 changes: 2 additions & 2 deletions book/doctrine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,10 @@ Take a look at the previous example in more detail:
responsible for handling the process of persisting and fetching objects
to and from the database.

* **line 16** The ``persist()`` method tells Doctrine to "manage" the ``$product``
* **line 17** The ``persist()`` method tells Doctrine to "manage" the ``$product``
object. This does not actually cause a query to be made to the database (yet).

* **line 17** When the ``flush()`` method is called, Doctrine looks through
* **line 18** When the ``flush()`` method is called, Doctrine looks through
all of the objects that it's managing to see if they need to be persisted
to the database. In this example, the ``$product`` object has not been
persisted yet, so the entity manager executes an ``INSERT`` query and a
Expand Down
25 changes: 7 additions & 18 deletions book/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1473,25 +1473,14 @@ route. With this information, any URL can easily be generated::

.. note::

In controllers that don't extend Symfony's base
:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller`,
you can use the ``router`` service's
:method:`Symfony\\Component\\Routing\\Router::generate` method::
The ``generateUrl()`` method defined in the base
:class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller` class is
just a shortcut for this code::

use Symfony\Component\DependencyInjection\ContainerAware;

class MainController extends ContainerAware
{
public function showAction($slug)
{
// ...

$url = $this->container->get('router')->generate(
'blog_show',
array('slug' => 'my-blog-post')
);
}
}
$url = $this->container->get('router')->generate(
'blog_show',
array('slug' => 'my-blog-post')
);

In an upcoming section, you'll learn how to generate URLs from inside templates.

Expand Down
16 changes: 7 additions & 9 deletions book/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ Access Control in Templates
...........................

If you want to check if the current user has a role inside a template, use
the built-in helper function:
the built-in ``is_granted()`` helper function:

.. configuration-block::

Expand All @@ -900,20 +900,18 @@ the built-in helper function:
<a href="...">Delete</a>
<?php endif ?>

If you use this function and you are *not* behind a firewall, an exception will
be thrown. Again, it's almost always a good idea to have a main firewall that
covers all URLs (as shown before in this chapter).

.. caution::
.. note::

Be careful with this in your base layout or on your error pages! Because of
some internal Symfony details, to avoid broken error pages in the ``prod``
environment, wrap calls in these templates with a check for ``app.user``:
In Symfony versions previous to 2.8, using the ``is_granted()`` function
in a page that wasn't behind a firewall resulted in an exception. That's why
you also needed to check first for the existence of the user:

.. code-block:: html+twig

{% if app.user and is_granted('ROLE_ADMIN') %}

Starting from Symfony 2.8, the ``app.user and ...`` check is no longer needed.

Securing other Services
.......................

Expand Down
22 changes: 12 additions & 10 deletions book/service_container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,10 @@ The service container is built using a single configuration resource
be imported from inside this file in one way or another. This gives you absolute
flexibility over the services in your application.

External service configuration can be imported in two different ways. The first
method, commonly used to import container configuration from the bundles you've
created - is via the ``imports`` directive. The second method, although slightly more
complex offers more flexibility and is commonly used to import third-party bundle
External service configuration can be imported in two different ways. The first
method, commonly used to import container configuration from the bundles you've
created - is via the ``imports`` directive. The second method, although slightly more
complex offers more flexibility and is commonly used to import third-party bundle
configuration. Read on to learn more about both methods.

.. index::
Expand Down Expand Up @@ -1104,13 +1104,15 @@ to be used for a specific purpose. Take the following example:
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<service
id="foo.twig.extension"
class="Acme\HelloBundle\Extension\FooExtension"
public="false">
<services>
<service
id="foo.twig.extension"
class="Acme\HelloBundle\Extension\FooExtension"
public="false">
<tag name="twig.extension" />
</service>
<tag name="twig.extension" />
</service>
</services>
</container>
.. code-block:: php
Expand Down
2 changes: 1 addition & 1 deletion book/templating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ if you are using Twig (or the third argument if you are using PHP) to ``true``:

.. code-block:: html+jinja

<img src="{{ asset('images/logo.png', absolute=true) }}" alt="Symfony!" />
<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />

.. code-block:: html+php

Expand Down
2 changes: 1 addition & 1 deletion components/console/helpers/debug_formatter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Stopping a Program
------------------

When a program is stopped, you can use
:method:`Symfony\\Component\\Console\\Helper\\DebugFormatterHelper::run` to
:method:`Symfony\\Component\\Console\\Helper\\DebugFormatterHelper::stop` to
notify this to the users::

// ...
Expand Down
91 changes: 91 additions & 0 deletions components/console/helpers/table.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,94 @@ Here is a full list of things you can customize:
$table->setStyle('colorful');

This method can also be used to override a built-in style.

Spanning Multiple Columns and Rows
----------------------------------

.. versionadded:: 2.7
Spanning multiple columns and rows was introduced in Symfony 2.7.

To make a table cell that spans multiple columns you can use a :class:`Symfony\\Component\\Console\\Helper\\TableCell`::

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Helper\TableCell;

$table = new Table($output);
$table
->setHeaders(array('ISBN', 'Title', 'Author'))
->setRows(array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
new TableSeparator(),
array(new TableCell('This value spans 3 columns.', array('colspan' => 3))),
))
;
$table->render();

This results in:

.. code-block:: text
+---------------+---------------+-----------------+
| ISBN | Title | Author |
+---------------+---------------+-----------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+---------------+---------------+-----------------+
| This value spans 3 columns. |
+---------------+---------------+-----------------+
.. tip::

You can create a multiple-line page title using a header cell that spans
the enire table width::

$table->setHeaders(array(
array(new TableCell('Main table title', array('colspan' => 3))),
array('ISBN', 'Title', 'Author'),
))
// ...

This generates:

.. code-block:: text
+-------+-------+--------+
| Main table title |
+-------+-------+--------+
| ISBN | Title | Author |
+-------+-------+--------+
| ... |
+-------+-------+--------+
In a similar way you can span multiple rows::

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableCell;

$table = new Table($output);
$table
->setHeaders(array('ISBN', 'Title', 'Author'))
->setRows(array(
array(
'978-0521567817',
'De Monarchia',
new TableCell("Dante Alighieri\nspans multiple rows", array('rowspan' => 2)),
),
array('978-0804169127', 'Divine Comedy'),
))
;
$table->render();

This outputs:

.. code-block:: text
+----------------+---------------+---------------------+
| ISBN | Title | Author |
+----------------+---------------+---------------------+
| 978-0521567817 | De Monarchia | Dante Alighieri |
| 978-0804169127 | Divine Comedy | spans multiple rows |
+----------------+---------------+---------------------+
You can use the ``colspan`` and ``rowspan`` options at the same time which allows
you to create any table layout you may wish.
2 changes: 2 additions & 0 deletions contributing/code/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ Security Advisories
This section indexes security vulnerabilities that were fixed in Symfony
releases, starting from Symfony 1.0.0:

* November 23, 2015: `CVE-2015-8125: Potential Remote Timing Attack Vulnerability in Security Remember-Me Service <http://symfony.com/blog/cve-2015-8125-potential-remote-timing-attack-vulnerability-in-security-remember-me-service>`_ (2.3.35, 2.6.12 and 2.7.7)
* November 23, 2015: `CVE-2015-8124: Session Fixation in the "Remember Me" Login Feature <http://symfony.com/blog/cve-2015-8124-session-fixation-in-the-remember-me-login-feature>`_ (2.3.35, 2.6.12 and 2.7.7)
* May 26, 2015: `CVE-2015-4050: ESI unauthorized access <https://symfony.com/blog/cve-2015-4050-esi-unauthorized-access>`_ (Symfony 2.3.29, 2.5.12 and 2.6.8)
* April 1, 2015: `CVE-2015-2309: Unsafe methods in the Request class <https://symfony.com/blog/cve-2015-2309-unsafe-methods-in-the-request-class>`_ (Symfony 2.3.27, 2.5.11 and 2.6.6)
* April 1, 2015: `CVE-2015-2308: Esi Code Injection <https://symfony.com/blog/cve-2015-2308-esi-code-injection>`_ (Symfony 2.3.27, 2.5.11 and 2.6.6)
Expand Down
3 changes: 1 addition & 2 deletions cookbook/configuration/override_dir_structure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ The change in the ``composer.json`` will look like this:
...
}
In ``app/autoload.php``, you need to modify the path leading to the
``vendor/autoload.php`` file::
Then, update the path to the ``autoload.php`` file in ``app/autoload.php``::

// app/autoload.php
// ...
Expand Down
20 changes: 1 addition & 19 deletions cookbook/controller/error_pages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ To override the 404 error template for HTML pages, create a new
<h1>Page not found</h1>

{# example security usage, see below #}
{% if app.user and is_granted('IS_AUTHENTICATED_FULLY') %}
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
{# ... #}
{% endif %}

Expand Down Expand Up @@ -124,24 +124,6 @@ store the HTTP status code and message respectively.
for the standard HTML exception page or ``exception.json.twig`` for the JSON
exception page.

Avoiding Exceptions when Using Security Functions in Error Templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

One of the common pitfalls when designing custom error pages is to use the
``is_granted()`` function in the error template (or in any parent template
inherited by the error template). If you do that, you'll see an exception thrown
by Symfony.

The cause of this problem is that routing is done before security. If a 404 error
occurs, the security layer isn't loaded and thus, the ``is_granted()`` function
is undefined. The solution is to add the following check before using this function:

.. code-block:: twig
{% if app.user and is_granted('...') %}
{# ... #}
{% endif %}
.. _testing-error-pages:

Testing Error Pages during Development
Expand Down
12 changes: 7 additions & 5 deletions cookbook/doctrine/event_listeners_subscribers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,14 @@ a ``postPersist`` method, which will be called when the event is dispatched::
public function postPersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();

// perhaps you only want to act on some "Product" entity
if ($entity instanceof Product) {
// ... do something with the Product
// only act on some "Product" entity
if (!$entity instanceof Product) {
return;
}

$entityManager = $args->getEntityManager();
// ... do something with the Product
}
}

Expand Down Expand Up @@ -197,10 +199,10 @@ interface and have an event method for each event it subscribes to::
public function index(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();

// perhaps you only want to act on some "Product" entity
if ($entity instanceof Product) {
$entityManager = $args->getEntityManager();
// ... do something with the Product
}
}
Expand Down
19 changes: 10 additions & 9 deletions cookbook/form/dynamic_form_modification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -411,25 +411,26 @@ it with :ref:`dic-tags-form-type`.
array('security.token_storage')
);
If you wish to create it from within a controller or any other service that has
access to the form factory, you then use::
If you wish to create it from within a service that has access to the form factory,
you then use::

use Symfony\Component\DependencyInjection\ContainerAware;
$form = $formFactory->create('friend_message');

class FriendMessageController extends ContainerAware
In a controller that extends the :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller`
class, you can simply call::

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FriendMessageController extends Controller
{
public function newAction(Request $request)
{
$form = $this->get('form.factory')->create('friend_message');
$form = $this->createForm('friend_message');

// ...
}
}

If you extend the ``Symfony\Bundle\FrameworkBundle\Controller\Controller`` class, you can simply call::

$form = $this->createForm('friend_message');

You can also easily embed the form type into another form::

// inside some other "form type" class
Expand Down
7 changes: 0 additions & 7 deletions cookbook/security/form_login_setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ In this entry, you'll build a traditional login form. Of course, when the
user logs in, you can load your users from anywhere - like the database.
See :ref:`security-user-providers` for details.

This chapter assumes that you've followed the beginning of the
:doc:`security chapter </book/security>` and have ``http_basic`` authentication
working properly.

First, enable form login under your firewall:

.. configuration-block::
Expand All @@ -29,7 +25,6 @@ First, enable form login under your firewall:
firewalls:
default:
anonymous: ~
http_basic: ~
form_login:
login_path: /login
check_path: /login_check
Expand All @@ -47,7 +42,6 @@ First, enable form login under your firewall:
<config>
<firewall name="default">
<anonymous />
<http-basic />
<form-login login-path="/login" check-path="/login_check" />
</firewall>
</config>
Expand All @@ -60,7 +54,6 @@ First, enable form login under your firewall:
'firewalls' => array(
'default' => array(
'anonymous' => null,
'http_basic' => null,
'form_login' => array(
'login_path' => '/login',
'check_path' => '/login_check',
Expand Down
2 changes: 1 addition & 1 deletion create_framework/dependency-injection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ them. Objects will be created on-demand when you access them from the
container or when the container needs them to create other objects.

For instance, to create the router listener, we tell Symfony that its class
name is ``Symfony\Component\HttpKernel\EventListener\RouterListener``, and
name is ``Symfony\Component\HttpKernel\EventListener\RouterListener`` and
that its constructor takes a matcher object (``new Reference('matcher')``). As
you can see, each object is referenced by a name, a string that uniquely
identifies each object. The name allows us to get an object and to reference
Expand Down
Loading

0 comments on commit af97ce1

Please sign in to comment.