Esempio n. 1
0
 /**
  * Gets the ACLs that belong to the given object identities
  *
  * We have to implement this method due a bug in AclProvider::findAcls:
  *     when $oids array length > AclProvider::MAX_BATCH_SIZE and no any ACLs were found for any bath, the findAcls
  *     method throws AclNotFoundException rather than continue loading ACLs for other batched and throw
  *     this exception only when no any ACLs found for all batches. But if at least one ACL (but not all) was found
  *     this method should throw NotAllAclsFoundException.
  *
  * @param OID[] $oids
  * @param SID[] $sids
  * @return \SplObjectStorage mapping the passed object identities to ACLs
  * @throws AclNotFoundException
  * @throws NotAllAclsFoundException
  */
 protected function doFindAcls(array $oids, array $sids)
 {
     // split object identities to batches (batch size must be less than or equal AclProvider::MAX_BATCH_SIZE)
     $oidsBatches = array();
     $batchIndex = 0;
     $oidsBatches[$batchIndex] = array();
     $index = 0;
     foreach ($oids as $oid) {
         /**
          * We can not use AclProvider::MAX_BATCH_SIZE of Symfony ACL due to a bug check in the cache
          */
         if ($index >= self::MAX_BATCH_SIZE) {
             $index = 0;
             $batchIndex++;
         }
         $oidsBatches[$batchIndex][] = $oid;
         $index++;
     }
     $result = null;
     foreach ($oidsBatches as $oidsBatch) {
         try {
             $acls = $this->aclProvider->findAcls($oidsBatch, $sids);
             if ($result === null) {
                 $result = $acls;
             } else {
                 foreach ($acls as $aclOid) {
                     $result->attach($aclOid, $acls->offsetGet($aclOid));
                 }
             }
         } catch (AclNotFoundException $ex) {
             if ($ex instanceof NotAllAclsFoundException) {
                 if ($result === null) {
                     $result = $ex->getPartialResult();
                 } else {
                     $partialResult = $ex->getPartialResult();
                     foreach ($partialResult as $aclOid) {
                         $result->attach($aclOid, $partialResult->offsetGet($aclOid));
                     }
                 }
             } else {
                 if ($result === null) {
                     $result = new \SplObjectStorage();
                 }
             }
         }
     }
     // check that we got ACLs for all the identities
     foreach ($oids as $oid) {
         if (!$result->contains($oid)) {
             if (1 === count($oids)) {
                 throw new AclNotFoundException(sprintf('No ACL found for %s.', $oid));
             }
             $partialResultEx = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
             $partialResultEx->setPartialResult($result);
             throw $partialResultEx;
         }
     }
     return $result;
 }
Esempio n. 2
0
 /**
  * {@inheritDoc}
  */
 public function findAcls(array $oids, array $sids = array())
 {
     $result = new \SplObjectStorage();
     $currentBatch = array();
     $oidLookup = array();
     for ($i = 0, $c = count($oids); $i < $c; $i++) {
         $oid = $oids[$i];
         $oidLookupKey = $oid->getIdentifier() . $oid->getType();
         $oidLookup[$oidLookupKey] = $oid;
         $aclFound = false;
         // check if result already contains an ACL
         if ($result->contains($oid)) {
             $aclFound = true;
         }
         // check if this ACL has already been hydrated
         if (!$aclFound && isset($this->loadedAcls[$oid->getType()][$oid->getIdentifier()])) {
             $acl = $this->loadedAcls[$oid->getType()][$oid->getIdentifier()];
             if (!$acl->isSidLoaded($sids)) {
                 // FIXME: we need to load ACEs for the missing SIDs. This is never
                 //        reached by the default implementation, since we do not
                 //        filter by SID
                 throw new \RuntimeException('This is not supported by the default implementation.');
             } else {
                 $result->attach($oid, $acl);
                 $aclFound = true;
             }
         }
         // check if we can locate the ACL in the cache
         if (!$aclFound && null !== $this->aclCache) {
             $acl = $this->aclCache->getFromCacheByIdentity($oid);
             if (null !== $acl) {
                 if ($acl->isSidLoaded($sids)) {
                     // check if any of the parents has been loaded since we need to
                     // ensure that there is only ever one ACL per object identity
                     $parentAcl = $acl->getParentAcl();
                     while (null !== $parentAcl) {
                         $parentOid = $parentAcl->getObjectIdentity();
                         if (isset($this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()])) {
                             $acl->setParentAcl($this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()]);
                             break;
                         } else {
                             $this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()] = $parentAcl;
                             $this->updateAceIdentityMap($parentAcl);
                         }
                         $parentAcl = $parentAcl->getParentAcl();
                     }
                     $this->loadedAcls[$oid->getType()][$oid->getIdentifier()] = $acl;
                     $this->updateAceIdentityMap($acl);
                     $result->attach($oid, $acl);
                     $aclFound = true;
                 } else {
                     $this->aclCache->evictFromCacheByIdentity($oid);
                     foreach ($this->findChildren($oid) as $childOid) {
                         $this->aclCache->evictFromCacheByIdentity($childOid);
                     }
                 }
             }
         }
         // looks like we have to load the ACL from the database
         if (!$aclFound) {
             $currentBatch[] = $oid;
         }
         // Is it time to load the current batch?
         if ((self::MAX_BATCH_SIZE === count($currentBatch) || $i + 1 === $c) && count($currentBatch) > 0) {
             $loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
             foreach ($loadedBatch as $loadedOid) {
                 $loadedAcl = $loadedBatch->offsetGet($loadedOid);
                 if (null !== $this->aclCache) {
                     $this->aclCache->putInCache($loadedAcl);
                 }
                 if (isset($oidLookup[$loadedOid->getIdentifier() . $loadedOid->getType()])) {
                     $result->attach($loadedOid, $loadedAcl);
                 }
             }
             $currentBatch = array();
         }
     }
     // check that we got ACLs for all the identities
     foreach ($oids as $oid) {
         if (!$result->contains($oid)) {
             if (1 === count($oids)) {
                 throw new AclNotFoundException(sprintf('No ACL found for %s.', $oid));
             }
             $partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
             $partialResultException->setPartialResult($result);
             throw $partialResultException;
         }
     }
     return $result;
 }
 /**
  * @param  array                    $src
  * @throws NotAllAclsFoundException
  * @return \SplObjectStorage
  */
 public static function getAcls(array $src)
 {
     $isPartial = false;
     $acls = new \SplObjectStorage();
     foreach ($src as $item) {
         if ($item['acl'] !== null) {
             $acls->attach($item['oid'], $item['acl']);
         } else {
             $isPartial = true;
         }
     }
     if ($isPartial) {
         $ex = new NotAllAclsFoundException();
         $ex->setPartialResult($acls);
         throw $ex;
     }
     return $acls;
 }