/** * export events * * @param string $filter JSON encoded string with items ids for multi export or item filter * @param string $options format or export definition id */ public function exportEvents($filter, $options) { $decodedFilter = Zend_Json::decode($filter); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Export filter: ' . print_r($decodedFilter, TRUE)); } if (!is_array($decodedFilter)) { $decodedFilter = array(array('field' => 'id', 'operator' => 'equals', 'value' => $decodedFilter)); } $filter = new Calendar_Model_EventFilter(); $filter->setFromArrayInUsersTimezone($decodedFilter); parent::_export($filter, Zend_Json::decode($options), Calendar_Controller_Event::getInstance()); }
/** * set current event filter for exdate computations * * @param Calendar_Model_EventFilter * @return Calendar_Model_EventFilter */ public function setEventFilter($_filter) { $oldFilter = $this->_eventFilter; if ($_filter !== NULL) { if (!$_filter instanceof Calendar_Model_EventFilter) { throw new Tinebase_Exception_UnexpectedValue('not a valid filter'); } $this->_eventFilter = clone $_filter; $periodFilters = $this->_eventFilter->getFilter('period', TRUE, TRUE); foreach ((array) $periodFilters as $periodFilter) { $periodFilter->setDisabled(); } } else { $this->_eventFilter = NULL; } return $oldFilter; }
/** * merge recurrences amd remove all events that do not match period filter * * @param Tinebase_Record_RecordSet $_events * @param Calendar_Model_EventFilter $_filter */ public static function mergeAndRemoveNonMatchingRecurrences(Tinebase_Record_RecordSet $_events, Calendar_Model_EventFilter $_filter = null) { if (!$_filter) { return; } $period = $_filter->getFilter('period', false, true); if ($period) { self::mergeRecurrenceSet($_events, $period->getFrom(), $period->getUntil()); foreach ($_events as $event) { if (!$event->isInPeriod($period)) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . ' (' . __LINE__ . ') Removing not matching event ' . $event->summary); } $_events->removeRecord($event); } } } }
/** * Search for events matching given arguments * * @param array $_filter * @param array $_paging * @return array */ public function searchEvents($filter, $paging) { $controller = Calendar_Controller_Event::getInstance(); $decodedPagination = is_array($paging) ? $paging : Zend_Json::decode($paging); $pagination = new Tinebase_Model_Pagination($decodedPagination); $clientFilter = $filter = $this->_decodeFilter($filter, 'Calendar_Model_EventFilter'); // find out if fixed calendars should be used $fixedCalendars = Calendar_Config::getInstance()->get(Calendar_Config::FIXED_CALENDARS); $useFixedCalendars = is_array($fixedCalendars) && !empty($fixedCalendars); $periodFilter = $filter->getFilter('period'); // add period filter per default to prevent endless search if (!$periodFilter) { $periodFilter = $this->_getDefaultPeriodFilter(); // periodFilter will be added to fixed filter when using fixed calendars if (!$useFixedCalendars) { $filter->addFilter($periodFilter); } } // add fixed calendar on demand if ($useFixedCalendars) { $fixed = new Calendar_Model_EventFilter(array(), 'AND'); $fixed->addFilter(new Tinebase_Model_Filter_Text('container_id', 'in', $fixedCalendars)); $fixed->addFilter($periodFilter); $og = new Calendar_Model_EventFilter(array(), 'OR'); $og->addFilterGroup($fixed); $og->addFilterGroup($clientFilter); $filter = new Calendar_Model_EventFilter(array(), 'AND'); $filter->addFilterGroup($og); } $records = $controller->search($filter, $pagination, FALSE); $result = $this->_multipleRecordsToJson($records, $clientFilter, $pagination); return array('results' => $result, 'totalcount' => count($result), 'filter' => $clientFilter->toArray(TRUE)); }
/** * delete duplicate events defined by an event filter * * @param Calendar_Model_EventFilter $filter * @param boolean $dryrun * @return integer number of deleted events */ public function deleteDuplicateEvents($filter, $dryrun = TRUE) { if ($dryrun && Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' - Running in dry run mode - using filter: ' . print_r($filter->toArray(), true)); } $duplicateFields = array('summary', 'dtstart', 'dtend'); $select = $this->_db->select(); $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName), $duplicateFields); $select->where($this->_db->quoteIdentifier($this->_tableName . '.is_deleted') . ' = 0'); $this->_addFilter($select, $filter); $select->group($duplicateFields)->having('count(*) > 1'); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $select); } $rows = $this->_fetch($select, self::FETCH_ALL); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($rows, TRUE)); } $toDelete = array(); foreach ($rows as $row) { $index = $row['summary'] . ' / ' . $row['dtstart'] . ' - ' . $row['dtend']; $filter = new Calendar_Model_EventFilter(array(array('field' => 'summary', 'operator' => 'equals', 'value' => $row['summary']), array('field' => 'dtstart', 'operator' => 'equals', 'value' => new Tinebase_DateTime($row['dtstart'])), array('field' => 'dtend', 'operator' => 'equals', 'value' => new Tinebase_DateTime($row['dtend'])))); $pagination = new Tinebase_Model_Pagination(array('sort' => array($this->_tableName . '.last_modified_time', $this->_tableName . '.creation_time'))); $select = $this->_db->select(); $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName)); $select->where($this->_db->quoteIdentifier($this->_tableName . '.is_deleted') . ' = 0'); $this->_addFilter($select, $filter); $pagination->appendPaginationSql($select); $rows = $this->_fetch($select, self::FETCH_ALL); $events = $this->_rawDataToRecordSet($rows); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($events->toArray(), TRUE)); } $deleteIds = $events->getArrayOfIds(); // keep the first array_shift($deleteIds); if (!empty($deleteIds)) { $deleteContainerIds = $events->container_id; $origContainer = array_shift($deleteContainerIds); if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Deleting ' . count($deleteIds) . ' duplicates of: ' . $index . ' in container_ids ' . implode(',', $deleteContainerIds) . ' (origin container: ' . $origContainer . ')'); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($deleteIds, TRUE)); } $toDelete = array_merge($toDelete, $deleteIds); } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' No duplicates found for ' . $index); } } } if (empty($toDelete)) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' No duplicates found.'); } $result = 0; } else { $result = $dryrun ? count($toDelete) : $this->delete($toDelete); } return $result; }
/** * Gets one entry (by property) * * @param mixed $_value * @param string $_property * @param bool $_getDeleted * @return Tinebase_Record_Interface * @throws Tinebase_Exception_NotFound */ public function getByProperty($_value, $_property = 'name', $_getDeleted = FALSE) { //$pagination = new Tinebase_Model_Pagination(array('limit' => 1)); $filters = new Calendar_Model_EventFilter(); $filter = new Tinebase_Model_Filter_Text($_property, 'equals', $_value); $filters->addFilter($filter); // for get operations we need to take all attendee into account $filters->addFilter($filters->createFilter('attender', 'specialNode', 'all')); $resultSet = $this->search($filters, NULL, FALSE, $_getDeleted); switch (count($resultSet)) { case 0: throw new Tinebase_Exception_NotFound($this->_modelName . " record with {$_property} " . $_value . ' not found!'); break; case 1: $result = $resultSet->getFirstRecord(); break; default: throw new Tinebase_Exception_UnexpectedValue(' in total ' . count($resultSet) . ' where found. But only one should!'); } return $result; }
/** * Search for events matching given arguments * * @param array $_filter * @param array $_paging * @return array */ public function searchEvents($filter, $paging) { $controller = Calendar_Controller_Event::getInstance(); $decodedPagination = is_array($paging) ? $paging : Zend_Json::decode($paging); $pagination = new Tinebase_Model_Pagination($decodedPagination); $clientFilter = $filter = $this->_decodeFilter($filter, 'Calendar_Model_EventFilter'); // add fixed calendar on demand $fixedCalendars = Tinebase_Config::getInstance()->getConfigAsArray('fixedCalendars', 'Calendar'); if (is_array($fixedCalendars) && !empty($fixedCalendars)) { $fixed = new Calendar_Model_EventFilter(array(), 'AND'); $fixed->addFilter(new Tinebase_Model_Filter_Text('container_id', 'in', $fixedCalendars)); $periodFilter = $filter->getFilter('period'); if ($periodFilter) { $fixed->addFilter($periodFilter); } $og = new Calendar_Model_EventFilter(array(), 'OR'); $og->addFilterGroup($fixed); $og->addFilterGroup($clientFilter); $filter = new Calendar_Model_EventFilter(array(), 'AND'); $filter->addFilterGroup($og); } $records = $controller->search($filter, $pagination, FALSE); $result = $this->_multipleRecordsToJson($records, $clientFilter, $pagination); return array('results' => $result, 'totalcount' => count($result), 'filter' => $clientFilter->toArray(TRUE)); }
/** * find existing event by uid * * @param $_iMIP * @param bool $_refetch * @param bool $_getDeleted * @return NULL|Tinebase_Record_Abstract */ public function getExistingEvent($_iMIP, $_refetch = FALSE, $_getDeleted = FALSE) { if ($_refetch || !$_iMIP->existing_event instanceof Calendar_Model_Event) { $iMIPEvent = $_iMIP->getEvent(); $filters = new Calendar_Model_EventFilter(array(array('field' => 'uid', 'operator' => 'equals', 'value' => $iMIPEvent->uid))); if ($_getDeleted) { $deletedFilter = new Tinebase_Model_Filter_Bool('is_deleted', 'equals', Tinebase_Model_Filter_Bool::VALUE_NOTSET); $filters->addFilter($deletedFilter); } $events = Calendar_Controller_MSEventFacade::getInstance()->search($filters); // NOTE: cancelled attendees from ext. organizers don't have read grant // find a better way to check grants if (!$_getDeleted) { $events = $events->filter(Tinebase_Model_Grants::GRANT_READ, TRUE); } $event = $events->getFirstRecord(); Calendar_Model_Attender::resolveAttendee($event['attendee']); $_iMIP->existing_event = $event; } return $_iMIP->existing_event; }
/** * returns all persistent recur exceptions of recur series * * NOTE: deleted instances are saved in the base events exception property * NOTE: returns all exceptions regardless of current filters and access restrictions * * @param Calendar_Model_Event $_event * @param boolean $_fakeDeletedInstances * @param Calendar_Model_EventFilter $_eventFilter * @return Tinebase_Record_RecordSet of Calendar_Model_Event */ public function getRecurExceptions($_event, $_fakeDeletedInstances = FALSE, $_eventFilter = NULL) { $baseEventId = $_event->base_event_id ?: $_event->id; $exceptionFilter = new Calendar_Model_EventFilter(array(array('field' => 'base_event_id', 'operator' => 'equals', 'value' => $baseEventId), array('field' => 'recurid', 'operator' => 'notnull', 'value' => NULL))); if ($_eventFilter instanceof Calendar_Model_EventFilter) { $exceptionFilter->addFilterGroup($_eventFilter); } $exceptions = $this->_backend->search($exceptionFilter); if ($_fakeDeletedInstances) { $baseEvent = $this->getRecurBaseEvent($_event); $this->fakeDeletedExceptions($baseEvent, $exceptions); } $exceptions->exdate = NULL; $exceptions->rrule = NULL; $exceptions->rrule_until = NULL; return $exceptions; }
/** * fetches all eventids for given filter * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param string $action */ protected function _getEventIds($_filter, $_action) { if (!$_filter instanceof Calendar_Model_EventFilter) { $_filter = new Calendar_Model_EventFilter(); } $recurIdFilter = new Tinebase_Model_Filter_Text('recurid', 'isnull', null); $_filter->addFilter($recurIdFilter); $baseEventIds = $this->_eventController->search($_filter, NULL, FALSE, TRUE, $_action); $_filter->removeFilter($recurIdFilter); $baseEventUIDs = $this->_eventController->search(new Calendar_Model_EventFilter(array(array('field' => 'id', 'operator' => 'in', 'value' => $baseEventIds))), NULL, FALSE, 'uid', $_action); // add exceptions where the user has no access to the base event as baseEvents $uidFilter = new Tinebase_Model_Filter_Text('uid', 'notin', $baseEventUIDs); $recurIdFilter = new Tinebase_Model_Filter_Text('recurid', 'notnull', null); $_filter->addFilter($uidFilter); $_filter->addFilter($recurIdFilter); $baselessExceptionIds = $this->_eventController->search($_filter, NULL, FALSE, TRUE, $_action); $_filter->removeFilter($uidFilter); $_filter->removeFilter($recurIdFilter); return array_unique(array_merge($baseEventIds, $baselessExceptionIds)); }