Reputation: 51
I'm using a voter to determine whether or not the logged in user can edit a given object. One of the criteria requires a comparison with another object but I'm not sure how to pass this into the voter. I cannot use the constructor arguments as it is not a predefined value.
Basically I would like to do something like this:
protected function voteOnAttribute($attribute, $subject, TokenInterface $token, $comparedObject)
{ if ($subject->getProperty1 == $comparedObject)
{return true;}
}
Any help would be appreciated.
Upvotes: 4
Views: 1202
Reputation: 921
It's a bit late but maybe this answer is going to be helpfull for someone.
One thing that you can do is pass an array of values instance of a single $subject object.
For example, from Twig you use your function as:
{% set data = { 'subject': yourRealSubject, 'compared_object': comparedObject } %}
{% if is_granted('can_edit', data) %}
...
...
{% endif %}
(You can do the same from PHP code).
So then in your Voter:
class MyVoter extends Voter{
// ...
protected function voteOnAttribute($attribute, $data, TokenInterface $token) {
$subject = isset($data['subject']) ? $data['subject'] : null;
$comparedObject = isset($data['compared_object']) ? $data['compared_object'] : null;
if(!$subject || !$subject instanceof \Namespace\To\Subject){
throw new Exception('Missing or invalid subject!!!'');
}
// do whatever you want ...
}
}
Upvotes: 3
Reputation: 1047
My suggestion is to create additional property of "subject" where you can put "compared object".
// Inside action.
public function myBestAction(Request $request)
{
// My super code... e.g. we have received from ORM a $post.
// Create property on the fly to put $comparedObject.
// Perhaps creating property dynamically is not good practice, therefore you can create permanent with getter and setter.
$post->comparedObject = $comparedObject;
$this->isGranted('can_edit', $post);
}
// Now inside voter.
private function canEdit($subject)
{
$comparedObject = $subject->comparedObject;
// Compare $subject(post) with $comparedObject and return true or false...
}
Upvotes: 1