Symfony2 自定义选民:无法从选民内部访问 getDoctrine
Posted
技术标签:
【中文标题】Symfony2 自定义选民:无法从选民内部访问 getDoctrine【英文标题】:Symfony2 custom Voter: cannot have access to getDoctrine from inside the Voter 【发布时间】:2015-02-15 01:02:39 【问题描述】:我正在尝试实现自定义投票器。
从控制器我这样称呼它:
$prj = $this->getDoctrine()->getRepository('AppBundle:Project')->findOneById($id);
if (false === $this->get('security.authorization_checker')->isGranted('responsible', $prj))
throw new AccessDeniedException('Unauthorised access!');
第一行正确地检索了项目对象(我用转储检查了)。
问题发生在选民内部
<?php
namespace AppBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class ProjectVoter implements VoterInterface
const RESPONSIBLE = 'responsible';
const ACCOUNTABLE = 'accountable';
const SUPPORT = 'support';
const CONSULTED = 'consulted';
const INFORMED = 'informed';
public function supportsAttribute($attribute)
return in_array($attribute, array(
self::RESPONSIBLE,
self::ACCOUNTABLE,
self::SUPPORT,
self::CONSULTED,
self::INFORMED,
));
public function supportsClass($class)
$supportedClass = 'AppBundle\Entity\Project';
return $supportedClass === $class || is_subclass_of($class, $supportedClass);
/**
* @var \AppBundle\Entity\Project $project
*/
public function vote(TokenInterface $token, $project, array $attributes)
// check if class of this object is supported by this voter
if (!$this->supportsClass(get_class($project)))
return VoterInterface::ACCESS_ABSTAIN;
// check if the voter is used correct, only allow one attribute
// this isn't a requirement, it's just one easy way for you to
// design your voter
if (1 !== count($attributes))
throw new \InvalidArgumentException(
'Only one attribute is allowed'
); //in origin it was 'for VIEW or EDIT, which were the supported attributes
// set the attribute to check against
$attribute = $attributes[0];
// check if the given attribute is covered by this voter
if (!$this->supportsAttribute($attribute))
return VoterInterface::ACCESS_ABSTAIN;
// get current logged in user
$user = $token->getUser();
// make sure there is a user object (i.e. that the user is logged in)
if (!$user instanceof UserInterface)
return VoterInterface::ACCESS_DENIED;
$em = $this->getDoctrine()->getManager();
$projects = $em->getRepository('AppBundle:Project')->findPrjByUserAndRole($user, $attribute);
foreach ($projects as $key => $prj)
if ($prj['id'] === $project['id'])
$granted = true;
$index = $key; // save the index of the last time a specifif project changed status
if($projects[$index]['is_active']===true) //if the last status is active
return VoterInterface::ACCESS_GRANTED;
else
return VoterInterface::ACCESS_DENIED;
我收到以下错误
试图在类上调用方法“getDoctrine” “AppBundle\Security\Authorization\Voter\ProjectVoter”。
我知道控制器扩展了控制器,这就是为什么我可以在那里使用“getDoctrine”。如何从 Voter 内部访问我的数据库?
【问题讨论】:
【参考方案1】:我解决了。这很奇怪:我花了几个小时或几天的时间来解决一个问题,然后在这里发布一个问题,我自己在一个小时内解决它:/
我需要在我的选民类中添加以下内容:
public function __construct(EntityManager $em)
$this->em = $em;
我需要在顶部添加以下内容:
use Doctrine\ORM\EntityManager;
我还需要在 service.yml 中添加参数
security.access.project_voter:
class: AppBundle\Security\Authorization\Voter\ProjectVoter
arguments: [ @doctrine.orm.entity_manager ]
public: false
tags:
- name: security.voter
【讨论】:
是的,任何时候你想在自己的服务中使用另一个服务,你需要先注入它,就像你上面做的那样。 在 symfony 3 上,您需要为参数arguments: [ "@doctrine.orm.entity_manager" ]
添加双引号,否则会失败以上是关于Symfony2 自定义选民:无法从选民内部访问 getDoctrine的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法从 Instagram 故事中检索民意调查选民名单?