Skip to content

Rebased "add shortcut methods" #5046

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions book/controller.rst
Original file line number Diff line number Diff line change
Expand Up @@ -429,35 +429,47 @@ A great way to see the core functionality in action is to look in the
Redirecting
~~~~~~~~~~~

If you want to redirect the user to another page, use the
:method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::redirect`
method::
If you want to redirect the user to another page, use the ``redirectToRoute()`` method::

public function indexAction()
{
return $this->redirect($this->generateUrl('homepage'));
return $this->redirectToRoute('homepage');

// redirectToRoute is equivalent to using redirect() and generateUrl() together:
// return $this->redirect($this->generateUrl('homepage'), 301);
}

The ``generateUrl()`` method is just a helper function that generates the URL
for a given route. For more information, see the :doc:`Routing </book/routing>`
chapter.
.. versionadded:: 2.6
The ``redirectToRoute()`` method was added in Symfony 2.6. Previously (and still now), you
could use ``redirect()`` and ``generateUrl()`` together for this (see the example above).

Or, if you want to redirect externally, just use ``redirect()`` and pass it the URL::

public function indexAction()
{
return $this->redirect('http://symfony.com/doc');
}

By default, the ``redirect()`` method performs a 302 (temporary) redirect. To
By default, the ``redirectToRoute()`` method performs a 302 (temporary) redirect. To
perform a 301 (permanent) redirect, modify the second argument::

public function indexAction()
{
return $this->redirect($this->generateUrl('homepage'), 301);
return $this->redirectToRoute('homepage', array(), 301);
}

.. tip::

The ``redirect()`` method is simply a shortcut that creates a ``Response``
object that specializes in redirecting the user. It's equivalent to::
The ``redirectToRoute()`` method is simply a shortcut that creates a
``Response`` object that specializes in redirecting the user. It's
equivalent to::

use Symfony\Component\HttpFoundation\RedirectResponse;

return new RedirectResponse($this->generateUrl('homepage'));
public function indexAction()
{
return new RedirectResponse($this->generateUrl('homepage'));
}

.. index::
single: Controller; Rendering templates
Expand Down Expand Up @@ -623,12 +635,14 @@ For example, imagine you're processing a form submit::
if ($form->isValid()) {
// do some sort of processing

$request->getSession()->getFlashBag()->add(
$this->addFlash(
'notice',
'Your changes were saved!'
);

return $this->redirect($this->generateUrl(...));
// $this->addFlash is equivalent to $this->get('session')->getFlashBag()->add

return $this->redirectToRoute(...);
}

return $this->render(...);
Expand All @@ -638,8 +652,8 @@ After processing the request, the controller sets a ``notice`` flash message
in the session and then redirects. The name (``notice``) isn't significant -
it's just something you invent and reference next.

In the template of the next page (or even better, in your base layout template),
the following code will render the ``notice`` message:
In the template of the next action, the following code could be used to render
the ``notice`` message:

.. configuration-block::

Expand Down
2 changes: 1 addition & 1 deletion book/doctrine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ you have a route that maps a product id to an update action in a controller::
$product->setName('New product name!');
$em->flush();

return $this->redirect($this->generateUrl('homepage'));
return $this->redirectToRoute('homepage');
}

Updating an object involves just three steps:
Expand Down
6 changes: 3 additions & 3 deletions book/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ controller::
if ($form->isValid()) {
// perform some action, such as saving the task to the database

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}

// ...
Expand Down Expand Up @@ -319,7 +319,7 @@ querying if the "Save and add" button was clicked::
? 'task_new'
: 'task_success';

return $this->redirect($this->generateUrl($nextAction));
return $this->redirectToRoute($nextAction);
}

.. index::
Expand Down Expand Up @@ -1233,7 +1233,7 @@ it after a form submission can be done when the form is valid::
$em->persist($task);
$em->flush();

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}

If, for some reason, you don't have access to your original ``$task`` object,
Expand Down
2 changes: 1 addition & 1 deletion book/propel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ have a route that maps a product id to an update action in a controller::
$product->setName('New product name!');
$product->save();

return $this->redirect($this->generateUrl('homepage'));
return $this->redirectToRoute('homepage');
}

Updating an object involves just three steps:
Expand Down
24 changes: 13 additions & 11 deletions book/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -813,23 +813,25 @@ You can easily deny access from inside a controller::

public function helloAction($name)
{
if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
throw $this->createAccessDeniedException();
}
// The second parameter is used to specify on what object the role is tested.
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');

// Old way :
// if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
// throw $this->createAccessDeniedException('Unable to access this page!');
// }

// ...
}

.. versionadded:: 2.6
The ``security.authorization_checker`` service was introduced in Symfony 2.6. Prior
to Symfony 2.6, you had to use the ``isGranted()`` method of the ``security.context`` service.

.. versionadded:: 2.5
The ``createAccessDeniedException`` method was introduced in Symfony 2.5.
The ``denyAccessUnlessGranted()`` method was introduced in Symfony 2.6. Previously (and
still now), you could check access directly and throw the ``AccessDeniedException`` as shown
in the example above).

The :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::createAccessDeniedException`
method creates a special :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`
object, which ultimately triggers a 403 HTTP response inside Symfony.
In both cases, a special
:class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`
is thrown, which ultimately triggers a 403 HTTP response inside Symfony.

That's it! If the user isn't logged in yet, they will be asked to login (e.g.
redirected to the login page). If they *are* logged in, they'll be shown
Expand Down
2 changes: 1 addition & 1 deletion book/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ workflow looks like the following from inside a controller::
if ($form->isValid()) {
// the validation passed, do something with the $author object

return $this->redirect($this->generateUrl(...));
return $this->redirectToRoute(...);
}

return $this->render('BlogBundle:Author:form.html.twig', array(
Expand Down
2 changes: 1 addition & 1 deletion components/form/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ method:

// ... perform some action, such as saving the data to the database

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}

// ...
Expand Down
6 changes: 3 additions & 3 deletions cookbook/doctrine/file_uploads.rst
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ The following controller shows you how to handle the entire process::
$em->persist($document);
$em->flush();

return $this->redirect($this->generateUrl(...));
return $this->redirectToRoute(...);
}

return array('form' => $form->createView());
Expand All @@ -267,7 +267,7 @@ in a moment to handle the file upload::
$em->persist($document);
$em->flush();

return $this->redirect(...);
return $this->redirectToRoute(...);
}

The ``upload()`` method will take advantage of the :class:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile`
Expand Down Expand Up @@ -432,7 +432,7 @@ call to ``$document->upload()`` should be removed from the controller::
$em->persist($document);
$em->flush();

return $this->redirect(...);
return $this->redirectToRoute(...);
}

.. note::
Expand Down
2 changes: 1 addition & 1 deletion cookbook/doctrine/registration_form.rst
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ the validation and saves the data into the database::
$em->persist($registration->getUser());
$em->flush();

return $this->redirect(...);
return $this->redirectToRoute(...);
}

return $this->render(
Expand Down
6 changes: 2 additions & 4 deletions cookbook/expression/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ accepts an :class:`Symfony\\Component\\ExpressionLanguage\\Expression` object::

public function indexAction()
{
if (!$this->get('security.authorization_checker')->isGranted(new Expression(
$this->denyAccessUnlessGranted(new Expression(
'"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())'
))) {
throw $this->createAccessDeniedException();
}
));

// ...
}
Expand Down
6 changes: 3 additions & 3 deletions cookbook/form/direct_submit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ submissions::
if ($form->isValid()) {
// perform some action...

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}

return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
Expand Down Expand Up @@ -66,7 +66,7 @@ method, pass the submitted data directly to
if ($form->isValid()) {
// perform some action...

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}
}

Expand Down Expand Up @@ -111,7 +111,7 @@ a convenient shortcut to the previous example::
if ($form->isValid()) {
// perform some action...

return $this->redirect($this->generateUrl('task_success'));
return $this->redirectToRoute('task_success');
}
}

Expand Down
2 changes: 1 addition & 1 deletion cookbook/form/form_collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ the relationship between the removed ``Tag`` and ``Task`` object.
$em->flush();

// redirect back to some edit page
return $this->redirect($this->generateUrl('task_edit', array('id' => $id)));
return $this->redirectToRoute('task_edit', array('id' => $id));
}

// render some form template
Expand Down
10 changes: 1 addition & 9 deletions cookbook/security/remember_me.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,11 @@ In the following example, the action is only allowed if the user has the

public function editAction()
{
if (false === $this->get('security.authorization_checker')->isGranted(
'IS_AUTHENTICATED_FULLY'
)) {
throw new AccessDeniedException();
}
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

// ...
}

.. versionadded:: 2.6
The ``security.authorization_checker`` service was introduced in Symfony 2.6. Prior
to Symfony 2.6, you had to use the ``isGranted()`` method of the ``security.context`` service.

If your application is based on the Symfony Standard Edition, you can also secure
your controller using annotations:

Expand Down
28 changes: 11 additions & 17 deletions cookbook/security/securing_services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,34 @@
How to Secure any Service or Method in your Application
=======================================================

In the security chapter, you can see how to :ref:`secure a controller <book-security-securing-controller>`
by requesting the ``security.authorization_checker`` service from the Service Container
and checking the current user's role::
In the security chapter, you can see how to
:ref:`secure a controller <book-security-securing-controller>` by requesting
the ``security.authorization_checker`` service from the Service Container and
checking the current user's role::

// ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

public function helloAction($name)
{
if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}
$this->denyAccessUnlessGranted('ROLE_ADMIN');

// ...
}

.. versionadded:: 2.6
The ``security.authorization_checker`` service was introduced in Symfony 2.6. Prior
to Symfony 2.6, you had to use the ``isGranted()`` method of the ``security.context`` service.

You can also secure *any* service in a similar way by injecting the ``security.authorization_checker``
You can also secure *any* service by injecting the ``security.authorization_checker``
service into it. For a general introduction to injecting dependencies into
services see the :doc:`/book/service_container` chapter of the book. For
example, suppose you have a ``NewsletterManager`` class that sends out emails
and you want to restrict its use to only users who have some ``ROLE_NEWSLETTER_ADMIN``
role. Before you add security, the class looks something like this:

.. code-block:: php
and you want to restrict its use to only users who have some
``ROLE_NEWSLETTER_ADMIN`` role. Before you add security, the class looks
something like this::

// src/AppBundle/Newsletter/NewsletterManager.php
namespace AppBundle\Newsletter;

class NewsletterManager
{

public function sendNewsletter()
{
// ... where you actually do the work
Expand All @@ -55,8 +48,9 @@ check, this is an ideal candidate for constructor injection, which guarantees
that the authorization checker object will be available inside the ``NewsletterManager``
class::

namespace AppBundle\Newsletter;
// src/AppBundle/Newsletter/NewsletterManager.php

// ...
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class NewsletterManager
Expand Down