/** * enforce acl restrictions to alarm options * * @param Calendar_Model_Event $_event * @param Calendar_Model_Event $_currentEvent * @return bool true if alarms have updates */ public static function enforceACL($_event, $_currentEvent = NULL) { $alarms = $_event->alarms instanceof Tinebase_Record_RecordSet ? $_event->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $currentAlarms = $_currentEvent && $_currentEvent->alarms instanceof Tinebase_Record_RecordSet ? $_currentEvent->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); // 1. assemble attendeeSet curruser has rights for // 2. enforcethe rights ;-) if ($_currentEvent) { $alarms->record_id = $_currentEvent->getId(); } }
/** * computes monthly (byday) recurring events and inserts them into given $_recurSet * * @param Calendar_Model_Event $_event * @param Calendar_Model_Rrule $_rrule * @param array $_exceptionRecurIds * @param Tinebase_DateTime $_from * @param Tinebase_DateTime $_until * @param Tinebase_Record_RecordSet $_recurSet * @return void */ protected static function _computeRecurMonthlyByDay($_event, $_rrule, $_exceptionRecurIds, $_from, $_until, $_recurSet) { $eventInOrganizerTZ = clone $_event; $eventInOrganizerTZ->setTimezone($_event->originator_tz); $computationStartDateArray = self::date2array($eventInOrganizerTZ->dtstart); // if period contains base events dtstart, we let computation start one intervall to early to catch // the cases when dtstart of base event not equals the first instance. If it fits, we filter the additional // instance out later if ($eventInOrganizerTZ->dtstart->isLater($_from) && $eventInOrganizerTZ->dtstart->isEarlier($_until)) { $computationStartDateArray = self::addMonthIgnoringDay($computationStartDateArray, -1 * $_rrule->interval); } $computationEndDate = $_event->rrule_until instanceof DateTime && $_until->isLater($_event->rrule_until) ? $_event->rrule_until : $_until; // if dtstart is before $_from, we compute the offset where to start our calculations if ($eventInOrganizerTZ->dtstart->isEarlier($_from)) { $computationOffsetMonth = self::getMonthDiff($eventInOrganizerTZ->dtend, $_from); // NOTE: $computationOffsetMonth must be multiple of interval! $computationOffsetMonth = floor($computationOffsetMonth / $_rrule->interval) * $_rrule->interval; $computationStartDateArray = self::addMonthIgnoringDay($computationStartDateArray, $computationOffsetMonth - $_rrule->interval); } $eventLength = $eventInOrganizerTZ->dtstart->diff($eventInOrganizerTZ->dtend); $computationStartDateArray['day'] = 1; $byDayInterval = (int) substr($_rrule->byday, 0, -2); $byDayWeekday = substr($_rrule->byday, -2); if ($byDayInterval === 0 || !(isset(self::$WEEKDAY_DIGIT_MAP[$byDayWeekday]) || array_key_exists($byDayWeekday, self::$WEEKDAY_DIGIT_MAP))) { throw new Exception('mal formated rrule byday part: "' . $_rrule->byday . '"'); } while (true) { $computationStartDateArray = self::addMonthIgnoringDay($computationStartDateArray, $_rrule->interval); $computationStartDate = self::array2date($computationStartDateArray, $eventInOrganizerTZ->originator_tz); $recurEvent = self::cloneEvent($eventInOrganizerTZ); $recurEvent->dtstart = clone $computationStartDate; if ($byDayInterval < 0) { $recurEvent->dtstart = self::array2date(self::addMonthIgnoringDay($computationStartDateArray, 1), $eventInOrganizerTZ->originator_tz); $recurEvent->dtstart->subDay(1); } self::skipWday($recurEvent->dtstart, $byDayWeekday, $byDayInterval, TRUE); // we calculate dtend from the event length, as events during a dst boundary could get dtend less than dtstart otherwise $recurEvent->dtend = clone $recurEvent->dtstart; $recurEvent->dtend->add($eventLength); $recurEvent->setTimezone('UTC'); if ($computationEndDate->isEarlier($recurEvent->dtstart)) { break; } // skip non existing dates if ($computationStartDate->get('m') != $recurEvent->dtstart->get('m')) { continue; } // skip events ending before our period. // NOTE: such events could be included, cause our offset only calcs months and not seconds if ($_from->compare($recurEvent->dtend) >= 0) { continue; } // skip instances begining before the baseEvent if ($recurEvent->dtstart->compare($_event->dtstart) < 0) { continue; } // skip if event equal baseevent if ($_event->dtstart->equals($recurEvent->dtstart)) { continue; } $recurEvent->setRecurId($_event->getId()); if (!in_array($recurEvent->recurid, $_exceptionRecurIds)) { self::addRecurrence($recurEvent, $_recurSet); } } }
/** * prepares an exception instance for persistence * * @param Calendar_Model_Event $_baseEvent * @param Calendar_Model_Event $_exception * @return void * @throws Tinebase_Exception_InvalidArgument */ protected function _prepareException(Calendar_Model_Event $_baseEvent, Calendar_Model_Event $_exception) { if (!$_baseEvent->uid) { throw new Tinebase_Exception_InvalidArgument('base event has no uid'); } if ($_exception->is_deleted == false) { $_exception->container_id = $_baseEvent->container_id; } $_exception->uid = $_baseEvent->uid; $_exception->base_event_id = $_baseEvent->getId(); $_exception->recurid = $_baseEvent->uid . '-' . $_exception->getOriginalDtStart()->format(Tinebase_Record_Abstract::ISO8601LONG); // NOTE: we always refetch the base event as it might be touched in the meantime $currBaseEvent = $this->_eventController->get($_baseEvent, null, false); $_exception->last_modified_time = $currBaseEvent->last_modified_time; }
/** * gets attendee of a given event * * @param Calendar_Model_Event $_event * @return Tinebase_Record_RecordSet */ public function getEventAttendee(Calendar_Model_Event $_event) { $attendee = $this->_attendeeBackend->getMultipleByProperty($_event->getId(), Calendar_Backend_Sql_Attendee::FOREIGNKEY_EVENT); return $attendee; }
/** * create event exception * * @param Calendar_Model_Event $event * @return Calendar_Model_Event */ protected function _createEventException($event) { $newException = clone $event; $newException->id = NULL; $newException->base_event_id = $event->getId(); $newException->recurid = clone $newException->dtstart; $newException->recurid->addDay(3); $newException->dtstart->addDay(3)->addHour(2); $newException->dtend->addDay(3)->addHour(2); $newException->summary = 'new exception'; $newException->exdate = NULL; return $newException; }
/** * converts events to calendar objects * * @param Calendar_Model_Event $event (from MSFacade atm.) */ protected function _convertCalendarObject($event) { $eventId = $event->getId(); $lastModified = $event->last_modified_time ? $event->last_modified_time : $event->creation_time; // we always use a event set to return exdates at once $eventSet = new Tinebase_Record_RecordSet('Calendar_Model_Event', array($event)); if ($event->rrule) { foreach ($event->exdate as $exEvent) { if (!$exEvent->is_deleted) { $eventSet->addRecord($exEvent); $event->exdate->removeRecord($exEvent); } } // remaining exdates are fallouts $event->exdate = $event->exdate->getOriginalDtStart(); } $exporter = new Calendar_Export_Ical(); $ics = $exporter->eventToIcal($eventSet); // work arround broken exdate handling in apple ical // -> not neccesary at the moment this is done generally in ics export return array('id' => $eventId, 'uri' => $eventId, 'lastmodified' => $lastModified->getTimeStamp(), 'calendardata' => $ics); }
/** * increases content sequence of attender display container * * @param Calendar_Model_Attender $attender * @param Calendar_Model_Event $event * @param string $action */ protected function _increaseDisplayContainerContentSequence($attender, $event, $action = Tinebase_Model_ContainerContent::ACTION_UPDATE) { if ($event->container_id === $attender->displaycontainer_id || empty($attender->displaycontainer_id)) { // no need to increase sequence return; } Tinebase_Container::getInstance()->increaseContentSequence($attender->displaycontainer_id, $action, $event->getId()); }