The updating/removing of ACE's is a bit harder than creating a new one. Therefore I just wanted to share a simple example. This code comes from a UserController where a User object can be assigned to one or multiple companies which (s)he should be able to manage.
public function updateAction($id) { $em = $this->getDoctrine()->getEntityManager(); $entity = $em->getRepository('MyBundle:User')->find($id); if (!$entity) { throw $this->createNotFoundException('Unable to find User'); } $prevCompanies = $entity->getCompanies()->toArray(); $editForm = $this->createForm(new UserType(), $entity); $deleteForm = $this->createDeleteForm($id); $request = $this->getRequest(); $editForm->bindRequest($request); if ($editForm->isValid()) { $em->persist($entity); $em->flush(); /** * ACL MAGIC */ $aclProvider = $this->get('security.acl.provider'); $securityIdentity = UserSecurityIdentity::fromAccount($entity); // Store the currently selected companies to figure out later // which entries have been removed $newCompanyIds = array(); $companies = $entity->getCompanies(); foreach($companies as $company) { $newCompanyIds[] = $company->getId(); $objectIdentity = ObjectIdentity::fromDomainObject($company); try { // If there is no ACL for the company yet, an // AclNotFoundException is thrown $acl = $aclProvider->findAcl( $objectIdentity, array($securityIdentity) ); // For some reason we need to use an index to update an // ACE, so we need to use an index, so start looping foreach($acl->getObjectAces() as $index => $ace) { $aceSecurityId = $ace->getSecurityIdentity(); if($aceSecurityId ->equals($securityIdentity)) { $acl->updateObjectAce( $index, MaskBuilder::MASK_OPERATOR ); } } $aclProvider->updateAcl($acl); } catch (AclNotFoundException $e) { // No existing ACL found so create a new one $acl = $aclProvider->createAcl($objectIdentity); $acl->insertObjectAce( $securityIdentity, MaskBuilder::MASK_OPERATOR ); $aclProvider->updateAcl($acl); } } foreach($prevCompanies as $company) { if(!in_array($company->getId(),$newCompanyIds)) { $objIdentity = ObjectIdentity::fromDomainObject($company); try { $acl = $aclProvider->findAcl( $objIdentity, array($securityIdentity) ); // For some reason we need to use an index to delete // an ACE, so we need to use an index, so start // looping foreach($acl->getObjectAces() as $index => $ace) { $aceSecurityId = $ace->getSecurityIdentity(); if($aceSecurityId->equals($securityIdentity)) { $acl->deleteObjectAce($index); } } $aclProvider->updateAcl($acl); } catch (AclNotFoundException $e) { // We should never get here! Added because some // companies already existed before the ACL code was // added } } } /** * End of ACL MAGIC */ return $this->redirect( $this->generateUrl('admin_user_edit', array('id' => $id)) ); } return $this->render('MyBundle:User:edit.html.twig', array( 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), )); }
Thanks for this post! This is a good article for understanding ACL magic.
ReplyDeleteYes, my doctor is expert in acls. Thanks for such a good article.
ReplyDelete