*/ class MutableAcl extends Acl implements MutableAclInterface { /** * The id of the current ACL. * * It's the id of the ObjectIdentity model. * * @var int */ protected $id; /** * A reference to the ObjectIdentity this ACL is mapped to. * * @var \Propel\Bundle\PropelBundle\Model\Acl\ObjectIdentity */ protected $modelObjectIdentity; /** * A connection to be used for all changes on the ACL. * * @var ConnectionInterface */ protected $con; /** * Constructor. * * @param ObjectCollection $entries * @param \Symfony\Component\Security\Acl\Model\ObjectIdentityInterface $objectIdentity * @param \Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface $permissionGrantingStrategy * @param array $loadedSecurityIdentities * @param \Symfony\Component\Security\Acl\Model\AclInterface $parentAcl * @param bool $inherited * @param ConnectionInterface $con */ public function __construct(ObjectCollection $entries, ObjectIdentityInterface $objectIdentity, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $loadedSecurityIdentities = array(), AclInterface $parentAcl = null, $inherited = true, ConnectionInterface $con = null) { parent::__construct($entries, $objectIdentity, $permissionGrantingStrategy, $loadedSecurityIdentities, $parentAcl, $inherited); $this->modelObjectIdentity = ObjectIdentityQuery::create() ->filterByAclObjectIdentity($objectIdentity, $con) ->findOneOrCreate($con) ; if ($this->modelObjectIdentity->isNew()) { $this->modelObjectIdentity->save($con); } $this->id = $this->modelObjectIdentity->getId(); $this->con = $con; } /** * Returns the primary key of this ACL * * @return integer */ public function getId() { return $this->id; } /** * Sets whether entries are inherited * * @param bool $boolean */ public function setEntriesInheriting($boolean) { $this->inherited = $boolean; } /** * Sets the parent ACL * * @param \Symfony\Component\Security\Acl\Model\AclInterface|null $acl */ public function setParentAcl(AclInterface $acl = null) { $this->parentAcl = $acl; } /** * Deletes a class-based ACE * * @param integer $index */ public function deleteClassAce($index) { $this->deleteIndex($this->classAces, $index); } /** * Deletes a class-field-based ACE * * @param integer $index * @param string $field */ public function deleteClassFieldAce($index, $field) { $this ->validateField($this->classFieldAces, $field) ->deleteIndex($this->classFieldAces[$field], $index) ; } /** * Deletes an object-based ACE * * @param integer $index */ public function deleteObjectAce($index) { $this->deleteIndex($this->objectAces, $index); } /** * Deletes an object-field-based ACE * * @param integer $index * @param string $field */ public function deleteObjectFieldAce($index, $field) { $this ->validateField($this->objectFieldAces, $field) ->deleteIndex($this->objectFieldAces[$field], $index) ; } /** * Inserts a class-based ACE * * @param \Symfony\Component\Security\Acl\Model\SecurityIdentityInterface $securityIdentity * @param integer $mask * @param integer $index * @param bool $granting * @param string $strategy */ public function insertClassAce(SecurityIdentityInterface $securityIdentity, $mask, $index = 0, $granting = true, $strategy = null) { $this->insertToList($this->classAces, $index, $this->createAce($mask, $index, $securityIdentity, $strategy, $granting)); } /** * Inserts a class-field-based ACE * * @param string $field * @param \Symfony\Component\Security\Acl\Model\SecurityIdentityInterface $securityIdentity * @param integer $mask * @param integer $index * @param boolean $granting * @param string $strategy */ public function insertClassFieldAce($field, SecurityIdentityInterface $securityIdentity, $mask, $index = 0, $granting = true, $strategy = null) { if (!isset($this->classFieldAces[$field])) { $this->classFieldAces[$field] = array(); } $this->insertToList($this->classFieldAces[$field], $index, $this->createAce($mask, $index, $securityIdentity, $strategy, $granting, $field)); } /** * Inserts an object-based ACE * * @param \Symfony\Component\Security\Acl\Model\SecurityIdentityInterface $securityIdentity * @param integer $mask * @param integer $index * @param boolean $granting * @param string $strategy */ public function insertObjectAce(SecurityIdentityInterface $securityIdentity, $mask, $index = 0, $granting = true, $strategy = null) { $this->insertToList($this->objectAces, $index, $this->createAce($mask, $index, $securityIdentity, $strategy, $granting)); } /** * Inserts an object-field-based ACE * * @param string $field * @param \Symfony\Component\Security\Acl\Model\SecurityIdentityInterface $securityIdentity * @param integer $mask * @param integer $index * @param boolean $granting * @param string $strategy */ public function insertObjectFieldAce($field, SecurityIdentityInterface $securityIdentity, $mask, $index = 0, $granting = true, $strategy = null) { if (!isset($this->objectFieldAces[$field])) { $this->objectFieldAces[$field] = array(); } $this->insertToList($this->objectFieldAces[$field], $index, $this->createAce($mask, $index, $securityIdentity, $strategy, $granting, $field)); } /** * Updates a class-based ACE * * @param integer $index * @param integer $mask * @param string $strategy if null the strategy should not be changed */ public function updateClassAce($index, $mask, $strategy = null) { $this->updateAce($this->classAces, $index, $mask, $strategy); } /** * Updates a class-field-based ACE * * @param integer $index * @param string $field * @param integer $mask * @param string $strategy if null the strategy should not be changed */ public function updateClassFieldAce($index, $field, $mask, $strategy = null) { $this ->validateField($this->classFieldAces, $field) ->updateAce($this->classFieldAces[$field], $index, $mask, $strategy) ; } /** * Updates an object-based ACE * * @param integer $index * @param integer $mask * @param string $strategy if null the strategy should not be changed */ public function updateObjectAce($index, $mask, $strategy = null) { $this->updateAce($this->objectAces, $index, $mask, $strategy); } /** * Updates an object-field-based ACE * * @param integer $index * @param string $field * @param integer $mask * @param string $strategy if null the strategy should not be changed */ public function updateObjectFieldAce($index, $field, $mask, $strategy = null) { $this->validateField($this->objectFieldAces, $field); $this->updateAce($this->objectFieldAces[$field], $index, $mask, $strategy); } /** * String representation of object * * @link http://php.net/manual/en/serializable.serialize.php * * @return string the string representation of the object or &null; */ public function serialize() { return serialize(array( $this->id, $this->modelObjectIdentity, $this->model, $this->classAces, $this->classFieldAces, $this->objectAces, $this->objectFieldAces, $this->objectIdentity, $this->parentAcl, $this->permissionGrantingStrategy, $this->inherited, $this->loadedSecurityIdentities, )); } /** * Constructs the object * * @link http://php.net/manual/en/serializable.unserialize.php * * @param string $serialized * * @return mixed the original value unserialized. */ public function unserialize($serialized) { list( $this->id, $this->modelObjectIdentity, $this->model, $this->classAces, $this->classFieldAces, $this->objectAces, $this->objectFieldAces, $this->objectIdentity, $this->parentAcl, $this->permissionGrantingStrategy, $this->inherited, $this->loadedSecurityIdentities, ) = unserialize($serialized); return $this; } /** * Insert a given entry into the list on the given index by shifting all others. * * @param array $list * @param int $index * @param \Propel\Bundle\PropelBundle\Model\Acl\Entry\Entry $entry * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function insertToList(array &$list, $index, Entry $entry) { $this->isWithinBounds($list, $index); if ($entry instanceof FieldEntry) { $this->updateFields($entry->getField()); } $list = array_merge( array_slice($list, 0, $index), array($entry), array_splice($list, $index) ); return $this; } /** * Update a single ACE of this ACL. * * @param array $list * @param int $index * @param int $mask * @param string $strategy * @param string $field * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function updateAce(array &$list, $index, $mask, $strategy = null) { $this->validateIndex($list, $index); $entry = ModelEntry::fromAclEntry($list[$index]); // Apply updates $entry->setMask($mask); if (null !== $strategy) { $entry->setGrantingStrategy($strategy); } $list[$index] = ModelEntry::toAclEntry($entry, $this); return $this; } /** * Delete the ACE of the given list and index. * * The list will be re-ordered to have a valid 0..x list. * * @param array $list * @param $index * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function deleteIndex(array &$list, $index) { $this->validateIndex($list, $index); unset($list[$index]); $this->reorderList($list, $index-1); return $this; } /** * Validate the index on the given list of ACEs. * * @throws \OutOfBoundsException * * @param array $list * @param int $index * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function isWithinBounds(array &$list, $index) { // No count()-1, the count is one ahead of index, and could create the next valid entry! if ($index < 0 or $index > count($list)) { throw new \OutOfBoundsException(sprintf('The index must be in the interval [0, %d].', count($list))); } return $this; } /** * Check the index for existence in the given list. * * @throws \OutOfBoundsException * * @param array $list * @param $index * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function validateIndex(array &$list, $index) { if (!isset($list[$index])) { throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index)); } return $this; } /** * Validate the given field to be present. * * @throws \InvalidArgumentException * * @param array $list * @param string $field * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function validateField(array &$list, $field) { if (!isset($list[$field])) { throw new \InvalidArgumentException(sprintf('The given field "%s" does not exist.', $field)); } return $this; } /** * Order the given list to have numeric indexes from 0..x * * @param array $list * @param int $index The right boundary to which the list is valid. * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\MutableAcl $this */ protected function reorderList(array &$list, $index) { $list = array_merge( array_slice($list, 0, $index+1), // +1 to get length array_splice($list, $index+1) // +1 to get first index to re-order ); return $this; } /** * Create a new ACL Entry. * * @param int $mask * @param int $index * @param \Symfony\Component\Security\Acl\Model\SecurityIdentityInterface $securityIdentity * @param string $strategy * @param bool $granting * @param string $field * * @return \Propel\Bundle\PropelBundle\Security\Acl\Domain\Entry|\Propel\Bundle\PropelBundle\Security\Acl\Domain\FieldEntry */ protected function createAce($mask, $index, SecurityIdentityInterface $securityIdentity, $strategy = null, $granting = true, $field = null) { if (!is_int($mask)) { throw new \InvalidArgumentException('The given mask is not valid. Please provide an integer.'); } // Compatibility with default implementation if (null === $strategy) { if (true === $granting) { $strategy = PermissionGrantingStrategy::ALL; } else { $strategy = PermissionGrantingStrategy::ANY; } } $model = new ModelEntry(); $model ->setAceOrder($index) ->setMask($mask) ->setGrantingStrategy($strategy) ->setGranting($granting) ->setSecurityIdentity(SecurityIdentity::fromAclIdentity($securityIdentity)) ; if (null !== $field) { $model->setFieldName($field); return new FieldEntry($model, $this); } return new Entry($model, $this); } }