create() public static method

public static create ( mixed $condition = null, Jarves $jarves = null ) : Condition
$condition mixed
$jarves Jarves\Jarves
return Condition
Ejemplo n.º 1
0
 /**
  * @param ACLRequest $aclRequest
  *
  * @return bool
  */
 public function check(ACLRequest $aclRequest)
 {
     $objectKey = Objects::normalizeObjectKey($aclRequest->getObjectKey());
     $targetType = $aclRequest->getTargetType();
     $targetId = $aclRequest->getTargetId();
     $pk = $aclRequest->getPrimaryKey();
     $field = $aclRequest->getField();
     $pk = $this->objects->normalizePkString($objectKey, $pk);
     if (ACL::TARGET_TYPE_USER === $targetType && null === $targetId) {
         //0 means guest
         $targetId = $this->pageStack->getUser() ? $this->pageStack->getUser()->getId() : 0;
     }
     $user = $this->pageStack->getUser();
     if ($user) {
         $groupIds = $user->getGroupIds();
         if (false !== strpos(',' . $groupIds . ',', ',1,')) {
             //user is in the admin group, so he has always access.
             return true;
         }
     }
     if (ACL::TARGET_TYPE_USER === $targetType && 1 === $targetId) {
         //user admin has always access
         return true;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && 1 === $targetId) {
         //group admin has always access
         return true;
     }
     if (0 === $targetId) {
         //guests do always have no access
         return false;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && !$targetId) {
         throw new \InvalidArgumentException('For type TARGET_TYPE_GROUP a targetId is required.');
     }
     $cacheKey = null;
     if ($pk && $this->getCaching()) {
         $pkString = $this->objects->getObjectUrlId($objectKey, $pk);
         $cacheKey = md5($targetType . '.' . $targetId . '.' . $objectKey . '/' . $pkString . '/' . json_encode($field));
         $cached = $this->cacher->getDistributedCache('core/acl/' . $cacheKey);
         if (null !== $cached) {
             return $cached;
         }
     }
     $rules = self::getRules($objectKey, $aclRequest->getMode(), $targetType, $targetId);
     if (count($rules) === 0) {
         //no rules found, so we have no access
         return false;
     }
     $access = null;
     $currentObjectPk = $pk;
     $definition = $this->objects->getDefinition($objectKey);
     $not_found = true;
     //starts directly as if we were in the parent checking.
     $parent_acl = $aclRequest->isAsParent();
     $fCount = null;
     $fKey = null;
     $fValue = null;
     $fIsArray = is_array($field);
     if ($fIsArray) {
         $fCount = count($field);
         $fKey = key($field);
         $fValue = current($field);
         if (is_int($fKey)) {
             $fKey = $fValue;
             $fValue = null;
         }
     }
     $depth = 0;
     $match = false;
     $originObjectItemPk = $currentObjectPk;
     while ($not_found) {
         $currentObjectPkString = null;
         if ($currentObjectPk) {
             $currentObjectPkString = $this->objects->getObjectUrlId($objectKey, $currentObjectPk);
         }
         $depth++;
         if ($depth > 50) {
             $not_found = false;
             break;
         }
         foreach ($rules as $aclRule) {
             if ($parent_acl && !$aclRule['sub']) {
                 //as soon we enter the parent_acl mode we only take acl rules into consideration
                 //that are also valid for children (sub=true)
                 continue;
             }
             $match = false;
             /*
              * CUSTOM CONSTRAINT
              */
             if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION) {
                 $objectItem = null;
                 if ($originObjectItemPk === $currentObjectPk && null !== $aclRequest->getPrimaryObjectItem()) {
                     $objectItem = $aclRequest->getPrimaryObjectItem();
                 } else {
                     if ($originObjectItemPk) {
                         $objectItem = $this->objects->get($objectKey, $currentObjectPk);
                     }
                 }
                 if ($objectItem && $this->conditionOperator->satisfy($aclRule['constraint_code'], $objectItem, $objectKey)) {
                     $match = true;
                 }
                 /*
                  * EXACT
                  */
             } else {
                 if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT) {
                     if ($currentObjectPk && $aclRule['constraint_code'] === $currentObjectPkString) {
                         $match = true;
                     }
                     /**
                      * ALL
                      */
                 } else {
                     $match = true;
                 }
             }
             if (!$match && $aclRule['sub'] && $currentObjectPk) {
                 // we need to check if a parent matches this $acl as we have sub=true
                 $parentItem = $this->objects->normalizePkString($objectKey, $currentObjectPk);
                 $parentCondition = Condition::create($aclRule['constraint_code']);
                 $parentOptions['fields'] = $this->conditionOperator->extractFields($parentCondition);
                 while ($parentItem = $this->objects->getParent($objectKey, $this->objects->getObjectPk($objectKey, $parentItem), $parentOptions)) {
                     if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION && $this->conditionOperator->satisfy($parentCondition, $parentItem)) {
                         $match = true;
                         break;
                     } else {
                         if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT && $aclRule['constraint_code'] === $this->objects->getObjectUrlId($objectKey, $parentItem)) {
                             $match = true;
                             break;
                         }
                     }
                 }
             }
             if ($match) {
                 //match, check all $field
                 $field2Key = $field;
                 if ($field) {
                     if ($fIsArray && $fCount === 1) {
                         if (is_string($fKey) && is_array($aclRule['fields'][$fKey])) {
                             //this field has limits
                             if (($field2Acl = $aclRule['fields'][$fKey]) !== null) {
                                 if (is_array($field2Acl[0])) {
                                     //complex field rule, $field2Acl = ([{access: no, condition: [['id', '>', 2], ..]}, {}, ..])
                                     foreach ($field2Acl as $fRule) {
                                         $satisfy = false;
                                         if (($f = $definition->getField($fKey)) && $f->getType() === 'object') {
                                             $uri = $f->getObject() . '/' . $fValue;
                                             $uriObject = $this->objects->getFromUrl($uri);
                                             $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $uriObject);
                                         } else {
                                             if (null !== $fValue) {
                                                 $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $field);
                                             }
                                         }
                                         if ($satisfy) {
                                             return $fRule['access'] === 1 ? true : false;
                                         }
                                     }
                                     //if no field rules fits, we consider the whole rule
                                     if ($aclRule['access'] !== 2) {
                                         return $aclRule['access'] === 1 ? true : false;
                                     }
                                 } else {
                                     //simple field rule $field2Acl = ({"value1": yes, "value2": no}
                                     if ($field2Acl[$fKey] !== null) {
                                         return $field2Acl[$fKey] === 1 ? true : false;
                                     } else {
                                         //current($field) is not exactly defined in $field2Acl, so we set $access to $acl['access']
                                         //
                                         //if access = 2 then wo do not know it, cause 2 means 'inherited', so maybe
                                         //a other rule has more detailed rule
                                         if ($aclRule['access'] !== 2) {
                                             $access = $aclRule['access'] === 1 ? true : false;
                                             break;
                                         }
                                     }
                                 }
                             }
                         } else {
                             //this field has only true or false
                             $field2Key = $fKey;
                         }
                     }
                     if (!is_array($field2Key)) {
                         if ($aclRule['fields'] && ($field2Acl = $aclRule['fields'][$field2Key]) !== null && !is_array($aclRule['fields'][$field2Key])) {
                             $access = $field2Acl === 1 ? true : false;
                             break;
                         } else {
                             //$field is not exactly defined, so we set $access to $acl['access']
                             //and maybe a rule with the same code has the field defined
                             // if access = 2 then this rule is only for exactly define fields
                             if ($aclRule['access'] !== 2) {
                                 $access = $aclRule['access'] === 1 ? true : false;
                                 break;
                             }
                         }
                     }
                 } else {
                     $access = $aclRule['access'] === 1 ? true : false;
                     break;
                 }
             }
         }
         //foreach
         if (null === $access && $definition->isNested() && $pk) {
             //$access has not defined yet (no rule matched yet). Check if nested and $pk is given
             //load its root and check again
             if (null === ($currentObjectPk = $this->objects->getParentPk($objectKey, $currentObjectPk))) {
                 $access = $aclRequest->isRootHasAccess() ? true : $access;
                 break;
             }
             $parent_acl = true;
         } else {
             break;
         }
     }
     $access = (bool) $access;
     if ($pk && $this->getCaching()) {
         $this->cacher->setDistributedCache('core/acl/' . $cacheKey, $access);
     }
     return $access;
 }
Ejemplo n.º 2
0
 /**
  *
  *   array(
  *       'items' => $items,
  *       'count' => $maxItems,
  *       'pages' => $maxPages
  *   );
  *
  * @param array $filter
  * @param integer $limit
  * @param integer $offset
  * @param string $query
  * @param string $fields
  * @param array $orderBy
  *
  * @param bool $withAcl
  * @param array $primaryKeys
  *
  * @return array
  * @throws ObjectNotFoundException
  * @throws \Exception
  */
 public function getItems($filter = null, $limit = null, $offset = null, $query = '', $fields = null, $orderBy = [], $withAcl = false, array $primaryKeys = [])
 {
     $options = array();
     $storageController = $this->objects->getStorageController($this->getObject());
     $options['offset'] = $offset;
     $options['limit'] = $limit ? $limit : $this->defaultLimit;
     $condition = $this->getCondition();
     if ($extraCondition = $this->getCustomListingCondition()) {
         $condition->mergeAnd($extraCondition);
     }
     $options['order'] = $orderBy ?: $this->getOrder();
     $options['fields'] = $this->getItemsSelection($fields);
     $options['permissionCheck'] = $this->getPermissionCheck();
     $aclRequest = ACLRequest::create($this->getObject())->onlyListingMode();
     if ($this->getPermissionCheck() && !$this->acl->check($aclRequest)) {
         return null;
     }
     if ($limit = $this->getObjectDefinition()->getLimitDataSets()) {
         $condition->mergeAnd($limit);
     }
     if ($this->getMultiLanguage() && $this->getLanguage()) {
         if ($this->getObjectDefinition()->getNestedRootAsObject() && ($rootObjectKey = $this->getObjectDefinition()->getNestedRootObject())) {
             $rootObjects = $this->objects->getList($rootObjectKey, null, ['lang' => $this->getLanguage(), 'fields' => 'id']);
             $langConditions = new Condition();
             foreach ($rootObjects as $item) {
                 $langConditions->addOr(['domain', '=', $item['id']]);
             }
             $condition->addAnd($langConditions);
         } else {
             //does the object have a lang field?
             if ($this->objectDefinition->hasField('lang') && !isset($filter['lang'])) {
                 $filter['lang'] = $this->getLanguage();
             }
         }
     }
     if ($query) {
         if ($queryCondition = $this->getQueryCondition($query, $options['fields'])) {
             $condition->mergeAnd($queryCondition);
         }
     }
     if ($primaryKeys) {
         $primaryKeyCondition = Condition::create();
         foreach ($primaryKeys as $pk) {
             $primaryKeyConditionItem = Condition::create();
             foreach ($this->getObjectDefinition()->getPrimaryKeyNames() as $primaryKeyName) {
                 if (!isset($pk[$primaryKeyName])) {
                     throw new \LogicException(sprintf('Field %s not found in primaryKey parameter (%s)', $primaryKeyName, json_encode($pk)));
                 }
                 $primaryKeyConditionItem->addAnd([$primaryKeyName, '=', $pk[$primaryKeyName]]);
             }
             $primaryKeyCondition->mergeOr($primaryKeyConditionItem);
         }
         $condition->mergeAndBegin($primaryKeyCondition);
     }
     if ($this->getPermissionCheck() && ($aclCondition = $this->acl->getListingCondition($this->getObject()))) {
         $condition->mergeAndBegin($aclCondition);
     }
     $items = $storageController->getItems($filter, $condition, $options);
     if ($withAcl && is_array($items)) {
         foreach ($items as &$item) {
             if ($item) {
                 $this->prepareRow($item);
             }
         }
     }
     return $items ?: null;
 }
Ejemplo n.º 3
0
 public function testExtractFields()
 {
     $condition = Condition::create(['title', '=', 'test title']);
     $fields = $this->getConditionOperator()->extractFields($condition);
     $this->assertEquals(['title'], $fields);
 }
Ejemplo n.º 4
0
 /**
  * @param Condition|array $condition
  * @param array $objectItem
  * @param string $objectKey
  *
  * @return bool|null
  */
 public function satisfy($condition, $objectItem, $objectKey = null)
 {
     if (is_array($condition)) {
         $condition = Condition::create($condition, $this->jarves);
     }
     $complied = null;
     $lastOperator = 'and';
     $rules = $condition->getRules();
     if (!$rules) {
         return null;
     }
     /*
      * [
      *   ['id', '=', 5],
      *   'or',
      *   ['id', '=', 6]
      * ]
      *
      * [
      *   Condition,
      *   'and',
      *   [Condition]
      * ]
      *
      *
      */
     foreach ($rules as $conditionRule) {
         if (is_string($conditionRule)) {
             $lastOperator = strtolower($conditionRule);
             continue;
         }
         $res = false;
         if (is_array($conditionRule) && is_string($conditionRule[0]) && is_string($conditionRule[1])) {
             $res = $this->checkRule($objectItem, $conditionRule, $objectKey);
         } else {
             if ($conditionRule instanceof Condition) {
                 $res = $this->satisfy($conditionRule, $objectItem, $objectKey);
             } else {
                 if (is_array($conditionRule)) {
                     //group
                     $res = $this->satisfy(Condition::create($conditionRule, $this->jarves), $objectItem, $objectKey);
                 }
             }
         }
         if (is_null($complied)) {
             $complied = $res;
         } else {
             if ($lastOperator == 'and') {
                 $complied = $complied && $res;
             }
             if ($lastOperator == 'and not') {
                 $complied = $complied && !$res;
             }
             if ($lastOperator == 'or') {
                 $complied = $complied || $res;
             }
         }
     }
     return $complied === null ? true : ($complied ? true : false);
 }