/** * Removes accounts where current user has no access to * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param string $_action get|update * * @todo move logic to Felamimail_Model_MessageFilter */ public function checkFilterACL(Tinebase_Model_Filter_FilterGroup $_filter, $_action = 'get') { $accountFilter = $_filter->getFilter('account_id'); // force a $accountFilter filter (ACL) / all accounts of user if ($accountFilter === NULL || $accountFilter['operator'] !== 'equals' || !empty($accountFilter['value'])) { $_filter->createFilter('account_id', 'equals', array()); } }
/** * the constructor * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Controller_Record_Interface $_controller (optional) * @param array $_additionalOptions (optional) additional options */ public function __construct(Tinebase_Model_Filter_FilterGroup $_filter, Tinebase_Controller_Record_Interface $_controller = NULL, $_additionalOptions = array()) { $periodFilter = $_filter->getFilter('period'); if ($periodFilter) { $this->_from = $periodFilter->getFrom(); $this->_until = $periodFilter->getUntil(); } parent::__construct($_filter, $_controller, $_additionalOptions); }
/** * append record paths (if path filter is set) * * @param Tinebase_Record_RecordSet $_records * @param Tinebase_Model_Filter_FilterGroup $_filter * * TODO move to generic json converter */ protected function _appendRecordPaths($_records, $_filter) { if ($_filter && $_filter->getFilter('path', false, true) !== null) { $recordPaths = Tinebase_Record_Path::getInstance()->getPathsForRecords($_records); foreach ($_records as $record) { $record->paths = $recordPaths->filter('record_id', $record->getId()); } } }
/** * the constructor * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Controller_Record_Interface $_controller (optional) * @param array $_additionalOptions (optional) additional options */ public function init(Tinebase_Model_Filter_FilterGroup $_filter, Tinebase_Controller_Record_Interface $_controller = NULL, $_additionalOptions = array()) { $this->_applicationName = 'Calendar'; $this->_modelName = 'Event'; $periodFilter = $_filter->getFilter('period', false, true); if ($periodFilter) { $this->_from = $periodFilter->getFrom(); $this->_until = $periodFilter->getUntil(); } parent::__construct($_filter, $_controller, $_additionalOptions); }
/** * get list of records * * @param Tinebase_Model_Filter_FilterGroup|optional $_filter * @param Tinebase_Model_Pagination|optional $_pagination * @param boolean|array $_getRelations * @param boolean $_onlyIds * @param string $_action for right/acl check * @return Tinebase_Record_RecordSet|array */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Record_Interface $_pagination = NULL, $_getRelations = FALSE, $_onlyIds = FALSE, $_action = 'get') { //@TODO support more appfilter combinations when needed $appFilter = $_filter->getFilter('application_id'); $app = Tinebase_Application::getInstance()->getApplicationById($appFilter->getValue()); $appname = $app->name; if (!Tinebase_Core::getUser()->hasRight($appname, 'admin')) { throw new Tinebase_Exception_AccessDenied("You do not have admin rights for {$appname}"); } $configRecords = new Tinebase_Record_RecordSet('Tinebase_Model_Config'); $appConfigObject = Tinebase_Config::getAppConfig($appname); $appConfigDefinitions = $appConfigObject->getProperties(); $appDBConfig = $this->_configBackend->search($_filter); foreach ($appConfigDefinitions as $name => $definition) { if (array_key_exists('setByAdminModule', $definition) && $definition['setByAdminModule']) { $configFromFile = $appConfigObject->getConfigFileSection($name); $configFromDb = $appDBConfig->filter('name', $name)->getFirstRecord(); if ($configFromDb && !$configFromFile) { $configRecord = $this->_mergeDefinition($configFromDb, $definition); $configRecord->source = Tinebase_Model_Config::SOURCE_DB; } else { $definition['id'] = 'virtual-' . $name; $definition['application_id'] = $app->getId(); $definition['name'] = $name; $definition['value'] = json_encode($configFromFile); $definition['source'] = is_null($configFromFile) ? Tinebase_Model_Config::SOURCE_DEFAULT : Tinebase_Model_Config::SOURCE_FILE; $configRecord = new Tinebase_Model_Config($definition); } // exclude config's which the admin can't set if ($configRecord->source != Tinebase_Model_Config::SOURCE_FILE) { $configRecords->addRecord($configRecord); } } } return $configRecords; }
/** * returns multiple records prepared for json transport * * @param Tinebase_Record_RecordSet $_records Tinebase_Record_Abstract * @param Tinebase_Model_Filter_FilterGroup $_filter * @return array data */ protected function _multipleRecordsToJson(Tinebase_Record_RecordSet $_records, $_filter = NULL) { if (count($_records) == 0) { return array(); } switch ($_records->getRecordClassName()) { case 'Tinebase_Model_Preference': $accountFilterArray = $_filter->getFilter('account')->toArray(); $adminMode = $accountFilterArray['value']['accountId'] == 0 && $accountFilterArray['value']['accountType'] == Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE; foreach ($_records as $record) { if (!isset($app) || $record->application_id != $app->getId()) { $app = Tinebase_Application::getInstance()->getApplicationById($record->application_id); } $preference = Tinebase_Core::getPreference($app->name, TRUE); $preference->resolveOptions($record); if ($record->type == Tinebase_Model_Preference::TYPE_DEFAULT || !$adminMode && $record->type == Tinebase_Model_Preference::TYPE_ADMIN) { $record->value = Tinebase_Model_Preference::DEFAULT_VALUE; } } break; } $result = parent::_multipleRecordsToJson($_records, $_filter); return $result; }
/** * Get filter model and pagination model and parse the rules * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Model_Pagination $_pagination * @return string * * @todo exclude $_pagination from this method */ protected function _parseFilterGroup(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Model_Pagination $_pagination = NULL) { $return = array(); $return['filters'] = array(); $return['paths'] = array(); $return['paths'] = array_merge($return['paths'], (array) $this->_processPathFilters($_filter->getFilter('path', true))); foreach (array('to', 'cc', 'bcc', 'flags') as $field) { $return['filters'] = array_merge($return['filters'], (array) $this->_generateImapSearch($_filter->getFilter($field, true), $_pagination)); } foreach ($_filter->getFilterObjects() as $filter) { if ($filter instanceof Tinebase_Model_Filter_FilterGroup) { $return = $this->_parseFilterGroup($filter, $_pagination); } else { if ($filter instanceof Tinebase_Model_Filter_Id) { if ($filter->getField() == 'folder_id') { $apaths = $this->_getAllFolders(); $i = $filter->getvalue(); foreach ($apaths as $value) { $a1 = explode('/', $value); if ($i == $a1[count($a1) - 1]) { $return['paths'] = $this->_getFoldersInfo(array($value)); break; } } } else { $return['filters'] = 'Id'; } } else { if ($filter instanceof Tinebase_Model_Filter_Abstract) { $return['filters'] = array_merge($return['filters'], (array) $this->_generateImapSearch($filter, $_pagination)); } } } } return $return; }
/** * search tree nodes * * @param Tinebase_Model_Filter_FilterGroup|optional $_filter * @param Tinebase_Model_Pagination|optional $_pagination * @param bool $_getRelations * @param bool $_onlyIds * @param string|optional $_action * @return Tinebase_Record_RecordSet of Tinebase_Model_Tree_Node */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Record_Interface $_pagination = NULL, $_getRelations = FALSE, $_onlyIds = FALSE, $_action = 'get') { // perform recursive search on recursive filter set if ($_filter->getFilter('recursive')) { return $this->_searchNodesRecursive($_filter, $_pagination); } else { $path = $this->_checkFilterACL($_filter, $_action); } if ($path->containerType === Tinebase_Model_Tree_Node_Path::TYPE_ROOT) { $result = $this->_getRootNodes(); } else { if ($path->containerType === Tinebase_Model_Container::TYPE_PERSONAL && !$path->containerOwner) { if (!file_exists($path->statpath)) { $this->_backend->mkdir($path->statpath); } $result = $this->_getOtherUserNodes(); } else { try { $result = $this->_backend->searchNodes($_filter, $_pagination); } catch (Tinebase_Exception_NotFound $tenf) { // create basic nodes like personal|shared|user root if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $path->statpath); } if ($path->name === Tinebase_Model_Container::TYPE_SHARED || $path->statpath === $this->_backend->getApplicationBasePath(Tinebase_Application::getInstance()->getApplicationByName($this->_applicationName), Tinebase_Model_Container::TYPE_PERSONAL) . '/' . Tinebase_Core::getUser()->getId()) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Creating new path ' . $path->statpath); } $this->_backend->mkdir($path->statpath); $result = $this->_backend->searchNodes($_filter, $_pagination); } else { throw $tenf; } } $this->resolveContainerAndAddPath($result, $path); $this->_sortContainerNodes($result, $path, $_pagination); } } return $result; }
/** * Gets total count of search with $_filter * * @param Tinebase_Model_Filter_FilterGroup $_filter * @return int|array */ public function searchCount(Tinebase_Model_Filter_FilterGroup $_filter) { $getDeleted = !!$_filter && $_filter->getFilter('is_deleted'); $defaultCountCol = $this->_defaultCountCol == '*' ? '*' : $this->_db->quoteIdentifier($this->_defaultCountCol); $searchCountCols = array('count' => 'COUNT(' . $defaultCountCol . ')'); foreach ($this->_additionalSearchCountCols as $column => $select) { $searchCountCols['sum_' . $column] = new Zend_Db_Expr('SUM(' . $this->_db->quoteIdentifier($column) . ')'); } list($subSelectColumns) = $this->_getColumnsToFetch(self::IDCOL, $_filter); if (!empty($this->_additionalSearchCountCols)) { $subSelectColumns = array_merge($subSelectColumns, $this->_additionalSearchCountCols); } $subSelect = $this->_getSelect($subSelectColumns, $getDeleted); $this->_addFilter($subSelect, $_filter); Tinebase_Backend_Sql_Abstract::traitGroup($subSelect); $countSelect = $this->_db->select()->from($subSelect, $searchCountCols); if (!empty($this->_additionalSearchCountCols)) { $result = $this->_db->fetchRow($countSelect); } else { $result = $this->_db->fetchOne($countSelect); } return $result; }
/** * Removes accounts where current user has no access to * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param string $_action get|update */ public function checkFilterACL(Tinebase_Model_Filter_FilterGroup $_filter, $_action = 'get') { $userFilter = $_filter->getFilter('user_id'); // force a $userFilter filter (ACL) if ($userFilter === NULL || $userFilter->getOperator() !== 'equals' || $userFilter->getValue() !== $this->_currentAccount->getId()) { $userFilter = $_filter->createFilter('user_id', 'equals', $this->_currentAccount->getId()); $_filter->addFilter($userFilter); } }
/** * Calendar optimized search function * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Model_Pagination $_pagination * @param boolean $_onlyIds * @param bool $_getDeleted * @return Tinebase_Record_RecordSet|array */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Model_Pagination $_pagination = NULL, $_onlyIds = FALSE, $_getDeleted = FALSE) { if ($_pagination === NULL) { $_pagination = new Tinebase_Model_Pagination(); } // we use a an extra select to reduce data amount where grants etc. have to be computed for. // the exdate is already appended here, to reduce virtual row numbers later $subselect = $this->_getSelectSimple('id', $_getDeleted); $subselect->joinLeft(array('exdate' => $this->_tablePrefix . 'cal_exdate'), $this->_db->quoteIdentifier('exdate.cal_event_id') . ' = ' . $this->_db->quoteIdentifier($this->_tableName . '.id'), array('exdate' => Tinebase_Backend_Sql_Command::getAggregateFunction($this->_db, $this->_db->quoteIdentifier('exdate.exdate')))); // this attendee join has nothing to do with grants but is here for attendee/status/... filters $subselect->joinLeft(array('attendee' => $this->_tablePrefix . 'cal_attendee'), $this->_db->quoteIdentifier('attendee.cal_event_id') . ' = ' . $this->_db->quoteIdentifier('cal_events.id'), array()); if (!$_getDeleted) { $subselect->joinLeft(array('dispcontainer' => $this->_tablePrefix . 'container'), $this->_db->quoteIdentifier('dispcontainer.id') . ' = ' . $this->_db->quoteIdentifier('attendee.displaycontainer_id'), array()); $subselect->where($this->_db->quoteIdentifier('dispcontainer.is_deleted') . ' = 0 OR ' . $this->_db->quoteIdentifier('dispcontainer.is_deleted') . 'IS NULL'); } // remove grantsfilter here as we need it in the main select $grantsFilter = $_filter->getFilter('grants'); if ($grantsFilter) { $_filter->removeFilter('grants'); } $this->_addFilter($subselect, $_filter); $_pagination->appendPaginationSql($subselect); $subselect->group($this->_tableName . '.' . 'id'); $stmt = $this->_db->query($subselect); $rows = (array) $stmt->fetchAll(Zend_Db::FETCH_ASSOC); $ids = array(); $exdates = array(); foreach ($rows as $row) { $ids[] = $row['id']; $exdates[$row['id']] = $row['exdate']; } $select = $this->_getSelectSimple('*', $_getDeleted); $select->where($this->_db->quoteInto("{$this->_db->quoteIdentifier('cal_events.id')} IN (?)", !empty($ids) ? $ids : ' ')); $_pagination->appendPaginationSql($select); // append grants filters : only take limited set of attendee into account for grants computation $attenderFilter = $_filter->getFilter('attender'); if (!$attenderFilter) { // if a container filter is set, take owners of personal containers (solve secretary scenario) $containerFilter = $_filter->getFilter('container_id'); if ($containerFilter && $containerFilter instanceof Calendar_Model_CalendarFilter) { $attenderFilter = $containerFilter->getRelatedAttendeeFilter(); } else { $attenderFilter = new Calendar_Model_AttenderFilter('attender', 'equals', array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => Tinebase_Core::getUser()->contact_id)); } } $this->_appendEffectiveGrantCalculationSql($select, $attenderFilter); if ($grantsFilter) { $grantsFilter->appendFilterSql($select, $this); } $select->group($this->_tableName . '.' . 'id'); $this->_traitGroup($select); $stmt = null; // solve PHP bug @see {http://bugs.php.net/bug.php?id=35793} $stmt = $this->_db->query($select); $rows = (array) $stmt->fetchAll(Zend_Db::FETCH_ASSOC); if ($_onlyIds) { $identifier = is_bool($_onlyIds) ? $this->_getRecordIdentifier() : $_onlyIds; $result = array(); foreach ($rows as $row) { $result[] = $row[$identifier]; } } else { foreach ($rows as &$row) { $row['exdate'] = $exdates[$row[$this->_getRecordIdentifier()]]; } $result = $this->_rawDataToRecordSet($rows); } return $result; }
/** * search tree nodes * * @param Tinebase_Model_Filter_FilterGroup|optional $_filter * @param Tinebase_Model_Pagination|optional $_pagination * @param bool $_getRelations * @param bool $_onlyIds * @param string|optional $_action * @return Tinebase_Record_RecordSet of Tinebase_Model_Tree_Node */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Record_Interface $_pagination = NULL, $_getRelations = FALSE, $_onlyIds = FALSE, $_action = 'get') { $query = ''; $path = null; if ($_filter->getFilter('query') && $_filter->getFilter('query')->getValue()) { $query = $_filter->getFilter('query')->getValue(); } if ($_filter->getFilter('path') && $_filter->getFilter('path')->getValue()) { $path = $_filter->getFilter('path')->getValue(); } if ($path === '/' || $path == NULL) { return $this->_getRootAdapterNodes(); } $backend = $this->getAdapterBackend($path); $folderFiles = $backend->search($query, $this->removeUserBasePath($path)); $result = new Tinebase_Record_RecordSet('Tinebase_Model_Tree_Node', array(), TRUE); foreach ($folderFiles as $folderFile) { $result->addRecord($this->_createNodeFromRawData($folderFile, $backend->getName())); } if ($_filter->getFilter('type') && $_filter->getFilter('type')->getValue()) { $result = $result->filter('type', $_filter->getFilter('type')->getValue()); } $this->_searchTotalCount = $result->count(); $result->limitByPagination($_pagination); $result->sort($_pagination->sort, $_pagination->dir); return $result; }