Skip to content

Commit 27b6628

Browse files
committed
[Security] improve VoteObject adding extraData
1 parent 32ee550 commit 27b6628

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

security/voters.rst

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ would look like this::
212212
}
213213
}
214214

215+
.. tip::
216+
217+
Votes define an ``$extraData`` property that you can use to store any data
218+
that you might need later::
219+
220+
$vote->extraData['key'] = 'value'; // values can be of any type
221+
222+
.. versionadded:: 7.4
223+
224+
The ``$extraData`` property was introduced in Symfony 7.4.
225+
215226
That's it! The voter is done! Next, :ref:`configure it <declaring-the-voter-as-a-service>`.
216227

217228
To recap, here's what's expected from the two abstract methods:
@@ -512,6 +523,60 @@ option to use a custom service (your service must implement the
512523
;
513524
};
514525
526+
When creating custom decision strategies, you can store additional data in votes
527+
to be used later when making a decision. For example, if not all votes should
528+
have the same weight, you could store a ``score`` value for each vote::
529+
530+
// src/Security/PostVoter.php
531+
namespace App\Security;
532+
533+
use App\Entity\Post;
534+
use App\Entity\User;
535+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
536+
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
537+
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
538+
539+
class PostVoter extends Voter
540+
{
541+
// ...
542+
543+
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
544+
{
545+
// ...
546+
$vote->extraData['score'] = 10;
547+
548+
// ...
549+
}
550+
}
551+
552+
Then, access that value when counting votes to make a decision::
553+
554+
// src/Security/MyCustomAccessDecisionStrategy.php
555+
use Symfony\Component\Security\Core\Authorization\Strategy\AccessDecisionStrategyInterface;
556+
557+
class MyCustomAccessDecisionStrategy implemenets AccessDecisionStrategyInterface
558+
{
559+
public function decide(\Traversable $results, $accessDecision = null): bool
560+
{
561+
$score = 0;
562+
563+
foreach ($results as $key => $result) {
564+
$vote = $accessDecision->votes[$key];
565+
if (array_key_exists('score', $vote->extraData)) {
566+
$score += $vote->extraData['score'];
567+
} else {
568+
$score += $vote->result;
569+
}
570+
}
571+
572+
// ...
573+
}
574+
}
575+
576+
.. versionadded:: 7.4
577+
578+
The feature to store arbitrary data inside votes was introduced in Symfony 7.4.
579+
515580
Custom Access Decision Manager
516581
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
517582

0 commit comments

Comments
 (0)