Inheritance: extends Model
Beispiel #1
0
 protected function modifyCondition(&$condition)
 {
     if (!$condition) {
         $condition = new Condition(null, $this->jarves);
     }
     $languages = $this->jarves->getSystemConfig()->getLanguages();
     $languages = preg_replace('/\\W+/', ',', $languages);
     $languages = explode(',', $languages);
     foreach ($languages as $lang) {
         $condition->addOr(['code', '=', $lang]);
     }
 }
Beispiel #2
0
 public function testConditionToSql()
 {
     $condition = new Condition();
     $condition2 = new Condition();
     $condition2->addAnd(['title', '=', 'TestNode tree']);
     $condition->addAnd($condition2);
     $condition->addOr(['1', '=', '1']);
     $params = [];
     $sql = $this->getConditionOperator()->standardConditionToSql($condition, $params, 'jarves/node');
     $expectedArray = [[['title', '=', 'TestNode tree']], 'OR', ['1', '=', '1']];
     $this->assertEquals($expectedArray, $condition->toArray());
     $this->assertEquals([':p1' => 'TestNode tree'], $params);
     $this->assertEquals(' system_node.title = :p1  OR 1= 1', $sql);
 }
Beispiel #3
0
 /**
  * Propel uses for his nested-set objects `lft` and `rgt` fields.
  * So we include with this condition all entries 'inside' the entry
  * defined through $condition.
  *
  * @param Condition $condition
  * @return Condition
  */
 public function getNestedSubCondition(Condition $condition)
 {
     $result = new Condition(null, $this->jarves);
     $sub = new ConditionSubSelect(null, $this->jarves);
     $sub->select('sub.lft');
     $sub->addSelfJoin('sub', 'sub.lft BETWEEN %table%.lft+1 AND %table%.rgt-1');
     $sub->setRules($condition->getRules());
     $subCondition = new Condition();
     $subCondition->addAnd(['lft', 'IN', $sub]);
     $result->addAnd($subCondition);
     return $result;
 }
Beispiel #4
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;
 }
Beispiel #5
0
 /**
  * @param Condition|array $condition
  *
  * @return array
  */
 private function normalizeToArray($condition)
 {
     if (!$condition) {
         return [];
     }
     if ($condition instanceof Condition) {
         return $condition->getRules();
     } else {
         if (!is_array($condition[0]) && !$condition[0] instanceof Condition) {
             $condition = [$condition];
         }
         return $condition;
     }
 }
Beispiel #6
0
 /**
  * {@inheritDoc}
  */
 public function getBranch($pk = null, Condition $condition = null, $depth = 1, $scope = null, $options = null)
 {
     if ($pk) {
         $path = $this->getPathFromPK($pk);
     } else {
         $path = '/';
     }
     if ($depth === null) {
         $depth = 1;
     }
     try {
         $files = $this->webFilesystem->getFiles($path);
     } catch (NotADirectoryException $e) {
         return null;
     }
     $c = 0;
     //        $offset = $options['offset'];
     //        $limit = $options['limit'];
     $result = array();
     $blacklistedFiles = array();
     $showHiddenFiles = false;
     //todo
     foreach ($files as $file) {
         $file = $file->toArray();
         if (isset($blacklistedFiles[$file['path']]) | (!$showHiddenFiles && substr($file['name'], 0, 1) == '.')) {
             continue;
         }
         if ($condition && $condition->hasRules() && !$condition->satisfy($file, 'jarves/file')) {
             continue;
         }
         $file['writeAccess'] = $this->acl->isUpdatable('jarves/file', array('path' => $file['path']));
         $c++;
         //            if ($offset && $offset >= $c) {
         //                continue;
         //            }
         //            if ($limit && $limit < $c) {
         //                break;
         //            }
         if ($depth > 0) {
             $children = array();
             if ($file['type'] == 'dir') {
                 try {
                     $children = self::getBranch(array('path' => $file['path']), $condition, $depth - 1);
                 } catch (FileNotFoundException $e) {
                     $children = null;
                 }
             }
             $file['_childrenCount'] = count($children);
             if ($depth > 1 && $file['type'] == 'dir') {
                 $file['_children'] = $children;
             }
         }
         $result[] = $file;
     }
     return $result;
 }
Beispiel #7
0
 /**
  * {@inheritDoc}
  */
 public function getBranch($pk = null, Condition $condition = null, $depth = 1, $scope = null, $options = null)
 {
     $result = null;
     $path = $pk['path'];
     if ($depth === null) {
         $depth = 1;
     }
     if ($path) {
         $path = '@' . trim($path, '/@');
         $path = str_replace(':', '/', $path);
     }
     $c = 0;
     $offset = $options['offset'];
     $limit = $options['limit'];
     $result = array();
     if (!$path) {
         $result = array();
         $bundles = array_keys($this->jarves->getBundles());
         foreach ($bundles as $bundleName) {
             $directory = $this->jarves->resolvePath('@' . $bundleName, 'Resources/views', true);
             if (!$this->localFilesystem->has($directory)) {
                 continue;
             }
             $file = $this->localFilesystem->getFile($directory);
             if (!$file) {
                 $result[] = $directory;
                 continue;
             }
             $file = $file->toArray();
             $file['name'] = $bundleName;
             $file['path'] = $bundleName;
             if ($offset && $offset > $c) {
                 continue;
             }
             if ($limit && $limit < $c) {
                 continue;
             }
             if ($condition && $condition->hasRules() && !$this->conditionOperator->satisfy($condition, $file)) {
                 $result[] = $directory;
                 continue;
             }
             $c++;
             if ($depth > 0) {
                 $children = self::getBranch(array('path' => $bundleName), $condition, $depth - 1);
                 $file['_childrenCount'] = count($children);
                 if ($depth > 1 && $file['type'] == 'dir') {
                     $file['_children'] = $children;
                 }
             }
         }
     } else {
         if (!($bundleName = $this->jarves->getBundleFromPath($path))) {
             return [];
         }
         $directory = $this->jarves->resolvePath($path, 'Resources/views', true) . '/';
         if (!$this->localFilesystem->has($directory)) {
             return [];
         }
         $files = $this->localFilesystem->getFiles($directory);
         foreach ($files as $file) {
             $item = $file->toArray();
             if ($condition && $condition->hasRules() && !$this->conditionOperator->satisfy($condition, $item, 'jarves/file')) {
                 continue;
             }
             $c++;
             if ($offset && $offset >= $c) {
                 continue;
             }
             if ($limit && $limit < $c) {
                 continue;
             }
             $item = array('name' => $this->buildPath($path . '/' . Tools::getRelativePath($item['path'], $directory)), 'path' => $this->buildPath($path . '/' . Tools::getRelativePath($item['path'], $directory)));
             if ($file->isDir()) {
                 $children = self::getBranch(array('path' => $item['path']), $condition, $depth - 1);
                 foreach ($children as $child) {
                     //                        $child['name'] = $item['name'] . '/' . $child['name'];
                     $result[] = $child;
                 }
             }
             if ($file->isFile()) {
                 $result[] = $item;
             }
         }
     }
     return $result;
 }
Beispiel #8
0
 public function testExtractFields()
 {
     $condition = Condition::create(['title', '=', 'test title']);
     $fields = $this->getConditionOperator()->extractFields($condition);
     $this->assertEquals(['title'], $fields);
 }
Beispiel #9
0
 /**
  * @param Condition|array $filter
  * @param string $query
  * @return int
  */
 public function getCount($filter, $query = '')
 {
     $storageController = $this->objects->getStorageController($this->getObject());
     $condition = new Condition(null, $this->jarves);
     if ($filter && is_array($filter)) {
         $this->conditionOperator->applyRulesFromPk($condition, $filter, $this->getObject());
     } else {
         if ($filter instanceof Condition) {
             $condition = $filter;
         } else {
             $condition = new Condition(null, $this->jarves);
         }
     }
     if ($limit = $this->getObjectDefinition()->getLimitDataSets()) {
         $condition->mergeAnd($limit);
     }
     if ($this->getPermissionCheck() && ($aclCondition = $this->acl->getListingCondition($this->getObject()))) {
         $condition->mergeAndBegin($aclCondition);
     }
     if ($query) {
         if ($queryCondition = $this->getQueryCondition($query, $this->getItemsSelection())) {
             $condition->mergeAnd($queryCondition);
         }
     }
     return $storageController->getCount($condition);
 }
Beispiel #10
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);
 }