/** * 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; }