首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony ACL => ObjectIdentity()已与ACL关联

Symfony ACL => ObjectIdentity()已与ACL关联
EN

Stack Overflow用户
提问于 2012-12-09 10:37:28
回答 2查看 1.5K关注 0票数 2

我想在Symfony 2中使用ACL,并将它们加载到我的fixture中。

下面的代码运行良好,但是如果我取消对array('myprivateroom', 'user1', 'view'),的注释,我会得到以下错误:

代码语言:javascript
复制
[Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException]  ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL.

我认为问题就在这里,$acl = $aclProvider-createAcl(ObjectIdentity::fromDomainObject($room));,但我不知道如何解决它。

代码语言:javascript
复制
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个数组,比如

代码语言:javascript
复制
$datas = array(
    array('myprivateroom', 'admin', 'owner'),
    array('mypublicroom', 'user1', 'owner'),
);

$datas2 = array(
    array('myprivateroom', 'user1', 'view'),
);

在第二个例子中,我用$acl = $aclProvider->findAcl($objectIdentity);替换了$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));,它工作得很好,但我认为这不是正确的方法,下面的方法不起作用。

代码语言:javascript
复制
try {
    $acl = $aclProvider->findAcl($objectIdentity);
} catch (AclNotFoundException $e) {
    $acl = $aclProvider->createAcl($objectIdentity);
}
EN

回答 2

Stack Overflow用户

发布于 2013-05-15 22:12:40

我遇到了和你完全一样的问题,我已经这样解决了。

代码语言:javascript
复制
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“

票数 4
EN

Stack Overflow用户

发布于 2016-06-09 08:18:39

我来晚了一点,但以防有人需要了解你的代码发生了什么。如果您遍历此数组:

代码语言:javascript
复制
$datas = array(
    array('myprivateroom', 'admin', 'owner'),
    array('myprivateroom', 'user1', 'view'),
    array('mypublicroom', 'user1', 'owner'),
);

您将使用:

代码语言:javascript
复制
 $acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));

在第一个和第二个循环中。它将尝试为'myprivateroom'创建两次访问控制列表。这就是为什么它会抛出一个错误,告诉你已经有了这个Room实体的列表。

代码语言:javascript
复制
ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL

解决这个问题的一个好方法是,如果它有ACL,就试一试,如果没有,就创建它(答案由@JGrinon提供)。否则,您可以将数据组织在多维数组中并循环访问它:

代码语言:javascript
复制
// 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);
}

希望这能有所帮助;)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13784129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档