【问题标题】:Symfony2: Pass a second object to a VoterSymfony2:将第二个对象传递给选民
【发布时间】:2017-02-21 07:07:23
【问题描述】:
我正在使用投票器来确定登录用户是否可以编辑给定对象。其中一个标准需要与另一个对象进行比较,但我不确定如何将其传递给选民。我不能使用构造函数参数,因为它不是预定义的值。
基本上我想做这样的事情:
protected function voteOnAttribute($attribute, $subject, TokenInterface $token, $comparedObject)
{ if ($subject->getProperty1 == $comparedObject)
{return true;}
}
任何帮助将不胜感激。
【问题讨论】:
标签:
symfony-2.8
symfony-security
【解决方案1】:
有点晚了,但也许这个答案会对某人有所帮助。
您可以做的一件事是传递单个 $subject 对象的一组值实例。
例如,在 Twig 中,您将函数用作:
{% set data = { 'subject': yourRealSubject, 'compared_object': comparedObject } %}
{% if is_granted('can_edit', data) %}
...
...
{% endif %}
(您可以在 PHP 代码中执行相同的操作)。
那么在你的选民中:
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 ...
}
}
【解决方案2】:
我的建议是创建“主题”的附加属性,您可以在其中放置“比较对象”。
// 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...
}