/** * @param array $id * @return array * @throws Rest_Model_Exception */ public function get(array $id, array $params = null) { if (isset($params['entourage'])) { require_once 'models/AclHandler/Entourage.php'; $entourageHandler = new Default_Model_AclHandler_Entourage($this->getAcl(), $this->getAclContextUser()); return $entourageHandler->get($id, array($this, $params['entourage'])); } try { $this->_assertAllowed('get', $id); } catch (Rest_Model_UnauthorizedException $e) { // resources are secret if not Acl approved, say it doesn't exist throw new Rest_Model_NotFoundException(); } $item = $this->_get($id); $this->_assertDependencyAllowed('get', $item); return $item; }
/** * @param array $params * @return array */ public function getList(array $params = null) { require_once 'Util/Sql.php'; require_once 'Util/Array.php'; $params = is_array($params) ? $params : array(); if (isset($params['entourage'])) { require_once 'models/AclHandler/Entourage.php'; $entourageHandler = new Default_Model_AclHandler_Entourage($this->getAcl(), $this->getAclContextUser()); $data = $entourageHandler->getList(array($this->_resourceName => $params)); return $data[$this->_resourceName]; } if (isset($params['where'])) { // use default properties to search against if none are provided if (!is_array($params['where'])) { // no where terms specified, use the defaults at the 'or' level $defaultWhereStruct = array(); foreach ($this->_defaultListWhere as $whereTerm) { $defaultWhereStruct[] = array($whereTerm => $params['where']); } $params['where'] = array($defaultWhereStruct); } } else { $params['where'] = array(); } if (!isset($params['sort']) || (!is_string($params['sort']) && !is_array($params['sort']))) { $params['sort'] = $this->_defaultListSort; } $params['sort'] = Util_Sql::generateSqlOrderBy($params['sort'], $this->getPropertyKeys()); // expected that: 0 < limit <= _listMaxLength if (!isset($params['limit']) || 0 >= $params['limit'] || $this->_listMaxLength < $params['limit']) { $params['limit'] = $this->_listMaxLength; } $params['limit'] = (integer) $params['limit']; // group by if (!isset($params['groupBy']) || !in_array($params['groupBy'], $this->getPropertyKeys())) { $params['groupBy'] = null; } // order of elements before group by, determines which row gets used // by group by from within the group, the last in the group wins if (!isset($params['condenseOn']) || (!is_string($params['condenseOn']) && !is_array($params['condenseOn']))) { $params['condenseOn'] = $this->_defaultListSort; } $params['condenseOn'] = Util_Sql::generateSqlOrderBy($params['condenseOn'], $this->getPropertyKeys()); // properties is expected to be an array of string property keys or a // string of space separated property keys // // array('id', 'discussion_id', 'comment', 'modified') // - or - // 'id discussion_id comment modified' { if (!isset($params['properties'])) { $params['properties'] = $this->getPropertyKeys(); } if (!is_array($params['properties'])) { $params['properties'] = explode(' ', $params['properties']); } $validatedProps = array_intersect($this->getPropertyKeys(), $params['properties']); if (count($validatedProps) != count($params['properties'])) { require_once 'Rest/Model/BadRequestException.php'; throw new Rest_Model_BadRequestException('[' . implode(', ', array_diff($params['properties'], $validatedProps)) . '] are not valid properties for ' . $this->_resourceName); } } // this is an optimization. Imposes a slight overhead performance hit, // but for queries where there is very restrictive dependency and a // large resource set being scanned, this optimization is very important if (0 < count($this->_permissionDependency)) { // go through all the dependies and make sure there are WHERE // clauses for them foreach ($this->_permissionDependency as $depResource => $depAssoc) { foreach ($depAssoc as $depId => $resourceId) { // if there is a WHERE already for the resource id // associated with the dependency, then can't optimize further if (in_array($resourceId, array_keys($params['where']))) { continue; } $parentResourceHandler = $this->_createAclHandler($depResource); $list = Util_Array::arrayFromKeyValuesOfSet($depId, $parentResourceHandler->getList(array('limit' => $this->_listMaxLength))); if (0 == count($list)) { // none of the dependencies, done return array(); } if ($this->_listMaxLength == count($list)) { // optimization isn't optimal in this situation abort // for dependency association continue; } $params['where'][$resourceId] = $list; } } } $whereSqlAndParam = Util_Sql::generateSqlWheresAndParams($params['where'], $this->getPropertyKeys()); $limit = $params['limit']; $dbLimit = floor($limit * $this->_listPermissionFilteredRate); $cumulativeRowSet = array(); $offset = 0; do { $sql = ''; // do sub select in order to handle sub ordering in group and get // the row we want $sql .= (($params['groupBy'] && $params['condenseOn']) ? ' SELECT * FROM (' : ''); // RESOURCE $sql .= $this->_getListResourceSqlFragment(); $sql .= '' // ACL . $this->_getGenericAclListJoins() // ACL . ' WHERE ' . $this->_getGenericAclListWheres() // RESOURCE . ' AND ' . $whereSqlAndParam['sql'] . ($params['groupBy'] ? (($params['condenseOn'] ? (' ORDER BY ' . implode(', ', $params['condenseOn']) . ')') : '') . ' GROUP BY ' . $params['groupBy']) : '') . ' ORDER BY ' . implode(', ', $params['sort']) . ' LIMIT ' . $dbLimit . ' OFFSET ' . $offset . ''; $query = $this->_getDbHandler()->prepare($sql); $query->execute(array_merge($this->_getGenericAclListParams(), $whereSqlAndParam['param'])); $rowSet = $query->fetchAll(PDO::FETCH_ASSOC); $countUnfiltered = count($rowSet); $this->_filterDependenciesNotAllowed($rowSet); $cumulativeRowSet += $rowSet; $countCumulativeFiltered = count($cumulativeRowSet); $offset += $dbLimit; } while ($countCumulativeFiltered < $limit && $countUnfiltered == $dbLimit); // ensure that only the desired properties are returned if (!empty($cumulativeRowSet) && count($params['properties']) != count($cumulativeRowSet[0])) { foreach ($cumulativeRowSet as &$row) { $row = array_intersect_key($row, array_flip($params['properties'])); } } return array_slice($cumulativeRowSet, 0, $limit); }