【问题标题】:Symfony ACL => ObjectIdentity() is already associated with an ACLSymfony ACL => ObjectIdentity() 已经与 ACL 关联
【发布时间】:2012-12-09 02:37:27
【问题描述】:

我想在 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);
}

【问题讨论】:

    标签: symfony acl symfony-2.1 fixtures


    【解决方案1】:

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

    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”

    【讨论】:

      【解决方案2】:

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

      $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);
      }
      

      希望这会有所帮助;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-15
        • 1970-01-01
        • 2020-11-27
        • 1970-01-01
        • 2020-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多