我想在Symfony 2中使用ACL并将其加载到我的灯具中。
以下代码完美无缺,但如果我取消注释array('myprivateroom', 'user1', 'view'),
,我会收到以下错误:
[Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException] ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL.
我认为问题出在$acl = $aclProvider-createAcl(ObjectIdentity::fromDomainObject($room));
,但我不知道如何解决。
public function load(ObjectManager $manager)
{
$datas = array(
array('myprivateroom', 'admin', 'owner'),
//array('myprivateroom', 'user1', 'view'),
array('mypublicroom', 'user1', 'owner'),
);
foreach ($datas as $data) {
// creating the ACL
$room = $this->getReference($data[0]);
$aclProvider = $this->container->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($room);
//problem here when I uncomment array('myprivateroom', 'user1', 'view'),
$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));
// retrieving the security identity of the user
$user = $this->getReference($data[1]);
$securityIdentity = UserSecurityIdentity::fromAccount($user);
//create mask
$builder = new MaskBuilder();
$builder->add($data[2]);
$mask = $builder->get();
// grant owner access
$acl->insertObjectAce($securityIdentity, $mask);
$aclProvider->updateAcl($acl);
}
}
更新: 如果我做2个数组,如
$datas = array(
array('myprivateroom', 'admin', 'owner'),
array('mypublicroom', 'user1', 'owner'),
);
$datas2 = array(
array('myprivateroom', 'user1', 'view'),
);
还有2个foreach但是,在第二个中,我将$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));
替换为$acl = $aclProvider->findAcl($objectIdentity);
,它完美无缺,但我不认为这是正确的方法,以下内容不起作用。
try {
$acl = $aclProvider->findAcl($objectIdentity);
} catch (AclNotFoundException $e) {
$acl = $aclProvider->createAcl($objectIdentity);
}
答案 0 :(得分:4)
我和你有完全相同的问题,我已经解决了这个问题。
try {
$acl = $this->get('security.acl.provider')->findAcl($idObjeto);
} catch (\Symfony\Component\Security\Acl\Exception\AclNotFoundException $e) {
$acl = $this->get('security.acl.provider')->createAcl($idObjeto);
}
我没有解释为什么。唯一不同的是" \ Symfony \ Component \ Security \ Acl \ Exception \ AclNotFoundException"
答案 1 :(得分:0)
我迟到了,但万一有人需要了解您的代码发生了什么。如果循环遍历此数组:
$datas = array(
array('myprivateroom', 'admin', 'owner'),
array('myprivateroom', 'user1', 'view'),
array('mypublicroom', 'user1', 'owner'),
);
您将使用:
$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));
在第一个和第二个循环上。它将尝试两次为'myprivateroom'
创建访问控制列表(ACL)。这就是为什么它会抛出一个错误,说明你已经拥有了这个Room实体的列表。
ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL
解决问题的一个好方法是尝试它是否有ACL,如果它没有,则创建它(由@JGrinon提供答案)。否则,您可以在多维数组中组织数据并循环遍历它:
// PHP array but you could use a JSON array to be clearer
$datas = array(
array('myprivateroom',
array(
array('admin', 'owner'),
array('user1', 'view1')
)
),
array('mypublicroom',
array(
array('user1', 'owner'),
)
),
);
// Call ACL Provider service before the loop
$aclProvider = $this->container->get('security.acl.provider');
// Loop through the array
foreach ($datas as $data) {
// Get the room name
$room = $this->getReference($data[0]);
$objectIdentity = ObjectIdentity::fromDomainObject($room);
// The list is created only once for each room
$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));
// Loop through the list of users and associated rights
$list = $this->getReference($data[1]);
foreach ($list as $row) {
// Retrieving the security identity of the user
$user = $row[0];
$securityIdentity = UserSecurityIdentity::fromAccount($user);
// Create Mask
$builder = new MaskBuilder();
$builder->add($row[1]);
$mask = $builder->get();
// Grant access
$acl->insertObjectAce($securityIdentity, $mask);
};
// Update Access Control List
$aclProvider->updateAcl($acl);
}
希望这会有所帮助;)