Skip to content

Commit 7bb2785

Browse files
committed
Merge branch '2.8'
* 2.8: (35 commits) [#5922] Tweaks thanks to reviewers Many tweaks thanks to a great review language tweak several other tweaks Completely updating the form type reference section for the text -> TextType changes Use path() and url() PHP templating helpers Update voter section of best practices Added minimal cookbook article about shared Document deprecation of supports{Attribute,Class}() methods Document Security key to secret renamings Use new Simple{Form,Pre}AuthenticatorInterface namespaces tweaks thanks to Javier adding a section about calling isGranted() from within a voter Reworking the voter article for the new Voter class fixing build error Another huge batch of changes for the form type changes in 2.8 minor tweaks #5834 Fixing bad merge removing link to an old, non-existent article Many fixes thanks to great review from ogizanagi, javiereguiluz and others ...
2 parents af97ce1 + 41670b0 commit 7bb2785

File tree

91 files changed

+2268
-939
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+2268
-939
lines changed

best_practices/forms.rst

+13-32
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@ form in its own PHP class::
2222
use Symfony\Component\Form\AbstractType;
2323
use Symfony\Component\Form\FormBuilderInterface;
2424
use Symfony\Component\OptionsResolver\OptionsResolver;
25+
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
26+
use Symfony\Component\Form\Extension\Core\Type\EmailType;
27+
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
2528

2629
class PostType extends AbstractType
2730
{
2831
public function buildForm(FormBuilderInterface $builder, array $options)
2932
{
3033
$builder
3134
->add('title')
32-
->add('summary', 'textarea')
33-
->add('content', 'textarea')
34-
->add('authorEmail', 'email')
35-
->add('publishedAt', 'datetime')
35+
->add('summary', TextareaType::class)
36+
->add('content', TextareaType::class)
37+
->add('authorEmail', EmailType::class)
38+
->add('publishedAt', DateTimeType::class)
3639
;
3740
}
3841

@@ -42,22 +45,17 @@ form in its own PHP class::
4245
'data_class' => 'AppBundle\Entity\Post'
4346
));
4447
}
45-
46-
public function getName()
47-
{
48-
return 'post';
49-
}
5048
}
5149

52-
To use the class, use ``createForm`` and instantiate the new class::
50+
To use the class, use ``createForm`` and pass the fully qualified class name::
5351

5452
use AppBundle\Form\PostType;
5553
// ...
5654

5755
public function newAction(Request $request)
5856
{
5957
$post = new Post();
60-
$form = $this->createForm(new PostType(), $post);
58+
$form = $this->createForm(PostType::class, $post);
6159

6260
// ...
6361
}
@@ -97,7 +95,7 @@ directly in your form class, this would effectively limit the scope of that form
9795
{
9896
$builder
9997
// ...
100-
->add('save', 'submit', array('label' => 'Create Post'))
98+
->add('save', SubmitType::class, array('label' => 'Create Post'))
10199
;
102100
}
103101
@@ -112,6 +110,7 @@ some developers configure form buttons in the controller::
112110

113111
use Symfony\Component\HttpFoundation\Request;
114112
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
113+
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
115114
use AppBundle\Entity\Post;
116115
use AppBundle\Form\PostType;
117116

@@ -122,8 +121,8 @@ some developers configure form buttons in the controller::
122121
public function newAction(Request $request)
123122
{
124123
$post = new Post();
125-
$form = $this->createForm(new PostType(), $post);
126-
$form->add('submit', 'submit', array(
124+
$form = $this->createForm(PostType::class, $post);
125+
$form->add('submit', SubmitType::class, array(
127126
'label' => 'Create',
128127
'attr' => array('class' => 'btn btn-default pull-right')
129128
));
@@ -207,21 +206,3 @@ Second, we recommend using ``$form->isSubmitted()`` in the ``if`` statement
207206
for clarity. This isn't technically needed, since ``isValid()`` first calls
208207
``isSubmitted()``. But without this, the flow doesn't read well as it *looks*
209208
like the form is *always* processed (even on the GET request).
210-
211-
Custom Form Field Types
212-
-----------------------
213-
214-
.. best-practice::
215-
216-
Add the ``app_`` prefix to your custom form field types to avoid collisions.
217-
218-
Custom form field types inherit from the ``AbstractType`` class, which defines the
219-
``getName()`` method to configure the name of that form type. These names must
220-
be unique in the application.
221-
222-
If a custom form type uses the same name as any of the Symfony's built-in form
223-
types, it will override it. The same happens when the custom form type matches
224-
any of the types defined by the third-party bundles installed in your application.
225-
226-
Add the ``app_`` prefix to your custom form field types to avoid name collisions
227-
that can lead to hard to debug errors.

best_practices/security.rst

+45-15
Original file line numberDiff line numberDiff line change
@@ -264,37 +264,66 @@ the same ``getAuthorEmail`` logic you used above:
264264
265265
namespace AppBundle\Security;
266266
267-
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
267+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
268+
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
269+
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
268270
use Symfony\Component\Security\Core\User\UserInterface;
271+
use AppBundle\Entity\Post;
269272
270-
// AbstractVoter class requires Symfony 2.6 or higher version
271-
class PostVoter extends AbstractVoter
273+
// Voter class requires Symfony 2.8 or higher version
274+
class PostVoter extends Voter
272275
{
273276
const CREATE = 'create';
274277
const EDIT = 'edit';
275278
276-
protected function getSupportedAttributes()
279+
/**
280+
* @var AccessDecisionManagerInterface
281+
*/
282+
private $decisionManager;
283+
284+
public function __construct(AccessDecisionManagerInterface $decisionManager)
277285
{
278-
return array(self::CREATE, self::EDIT);
286+
$this->decisionManager = $decisionManager;
279287
}
280288
281-
protected function getSupportedClasses()
289+
protected function supports($attribute, $subject)
282290
{
283-
return array('AppBundle\Entity\Post');
291+
if (!in_array($attribute, array(self::CREATE, self::EDIT))) {
292+
return false;
293+
}
294+
295+
if (!$subject instanceof Post) {
296+
return false;
297+
}
298+
299+
return true;
284300
}
285301
286-
protected function isGranted($attribute, $post, $user = null)
302+
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
287303
{
304+
$user = $token->getUser();
305+
/** @var Post */
306+
$post = $subject; // $subject must be a Post instance, thanks to the supports method
307+
288308
if (!$user instanceof UserInterface) {
289309
return false;
290310
}
291311
292-
if ($attribute === self::CREATE && in_array('ROLE_ADMIN', $user->getRoles(), true)) {
293-
return true;
294-
}
295-
296-
if ($attribute === self::EDIT && $user->getEmail() === $post->getAuthorEmail()) {
297-
return true;
312+
switch ($attribute) {
313+
case self::CREATE:
314+
// if the user is an admin, allow them to create new posts
315+
if ($this->decisionManager->decide($token, array('ROLE_ADMIN'))) {
316+
return true;
317+
}
318+
319+
break;
320+
case self::EDIT:
321+
// if the user is the author of the post, allow them to edit the posts
322+
if ($user->getEmail() === $post->getAuthorEmail()) {
323+
return true;
324+
}
325+
326+
break;
298327
}
299328
300329
return false;
@@ -310,6 +339,7 @@ To enable the security voter in the application, define a new service:
310339
# ...
311340
post_voter:
312341
class: AppBundle\Security\PostVoter
342+
arguments: ['@security.access.decision_manager']
313343
public: false
314344
tags:
315345
- { name: security.voter }
@@ -337,7 +367,7 @@ via the even easier shortcut in a controller:
337367
*/
338368
public function editAction($id)
339369
{
340-
$post = // query for the post ...
370+
$post = ...; // query for the post
341371
342372
$this->denyAccessUnlessGranted('edit', $post);
343373

0 commit comments

Comments
 (0)