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