/** * handle alarms / Reminder * * @param SimpleXMLElement $xmlData * @param Calendar_Model_Event $event */ protected function _handleAlarms($data, $event) { // NOTE: existing alarms are already filtered for CU by MSEF $event->alarms = $event->alarms instanceof Tinebase_Record_RecordSet ? $event->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $event->alarms->sort('alarm_time'); $currentAlarm = $event->alarms->getFirstRecord(); $alarm = NULL; if (isset($data->reminder)) { $dtstart = clone $event->dtstart; $alarm = new Tinebase_Model_Alarm(array('alarm_time' => $dtstart->subMinute($data->reminder), 'minutes_before' => in_array($data->reminder, array(0, 5, 15, 30, 60, 120, 720, 1440, 2880)) ? $data->reminder : 'custom', 'model' => 'Calendar_Model_Event')); $alarmUpdate = Calendar_Controller_Alarm::getMatchingAlarm($event->alarms, $alarm); if (!$alarmUpdate) { // alarm not existing -> add it $event->alarms->addRecord($alarm); if ($currentAlarm) { // ActiveSync supports one alarm only -> current got deleted $event->alarms->removeRecord($currentAlarm); } } } else { if ($currentAlarm) { // current alarm got removed $event->alarms->removeRecord($currentAlarm); } } }
/** * converts an iTIP event to a tine20 event * * @param Calendar_Model_Event $_event * @param Calendar_Model_Event $_currentEvent (not iTIP!) */ protected function _fromiTIP($_event, $_currentEvent) { if (!$_event->rrule) { $_event->exdate = NULL; } if ($_event->exdate instanceof Tinebase_Record_RecordSet) { try { $currExdates = $this->_eventController->getRecurExceptions($_event, TRUE); $this->getAlarms($currExdates); $currClientExdates = $this->_eventController->getRecurExceptions($_event, TRUE, $this->getEventFilter()); $this->getAlarms($currClientExdates); } catch (Tinebase_Exception_NotFound $e) { $currExdates = NULL; $currClientExdates = NULL; } foreach ($_event->exdate as $idx => $exdate) { try { $this->_prepareException($_event, $exdate); } catch (Exception $e) { } $currExdate = $currExdates instanceof Tinebase_Record_RecordSet ? $currExdates->filter('recurid', $exdate->recurid)->getFirstRecord() : NULL; if ($exdate->is_deleted) { // reset implicit filter fallouts and mark as don't touch (seq = -1) $currClientExdate = $currClientExdates instanceof Tinebase_Record_RecordSet ? $currClientExdates->filter('recurid', $exdate->recurid)->getFirstRecord() : NULL; if ($currClientExdate && $currClientExdate->is_deleted) { $_event->exdate[$idx] = $currExdate; $currExdate->seq = -1; continue; } } $this->_fromiTIP($exdate, $currExdate ? $currExdate : clone $_currentEvent); } } // assert organizer $_event->organizer = $_event->organizer ?: ($_currentEvent->organizer ?: $this->_calendarUser->user_id); $this->_addAttendeeWithoutEmail($_event, $_currentEvent); $CUAttendee = Calendar_Model_Attender::getAttendee($_event->attendee, $this->_calendarUser); $currentCUAttendee = Calendar_Model_Attender::getAttendee($_currentEvent->attendee, $this->_calendarUser); $isOrganizer = $_event->isOrganizer($this->_calendarUser); // remove perspective if ($CUAttendee && !$isOrganizer) { $CUAttendee->transp = $_event->transp; $_event->transp = $_currentEvent->transp ? $_currentEvent->transp : $_event->transp; } // apply changes to original alarms $_currentEvent->alarms = $_currentEvent->alarms instanceof Tinebase_Record_RecordSet ? $_currentEvent->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $_event->alarms = $_event->alarms instanceof Tinebase_Record_RecordSet ? $_event->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); foreach ($_currentEvent->alarms as $currentAlarm) { if (Calendar_Model_Attender::isAlarmForAttendee($this->_calendarUser, $currentAlarm)) { $alarmUpdate = Calendar_Controller_Alarm::getMatchingAlarm($_event->alarms, $currentAlarm); if ($alarmUpdate) { // we could map the alarm => save ack & snooze options if ($dtAck = Calendar_Controller_Alarm::getAcknowledgeTime($alarmUpdate)) { Calendar_Controller_Alarm::setAcknowledgeTime($currentAlarm, $dtAck, $this->getCalendarUser()->user_id); } if ($dtSnooze = Calendar_Controller_Alarm::getSnoozeTime($alarmUpdate)) { Calendar_Controller_Alarm::setSnoozeTime($currentAlarm, $dtSnooze, $this->getCalendarUser()->user_id); } $_event->alarms->removeRecord($alarmUpdate); } else { // alarm is to be skiped/deleted if (!$currentAlarm->getOption('attendee')) { Calendar_Controller_Alarm::skipAlarm($currentAlarm, $this->_calendarUser); } else { $_currentEvent->alarms->removeRecord($currentAlarm); } } } } if (!$isOrganizer) { $_event->alarms->setOption('attendee', Calendar_Controller_Alarm::attendeeToOption($this->_calendarUser)); } $_event->alarms->merge($_currentEvent->alarms); // assert organizer for personal calendars to be calendar owner if ($this->_currentEventFacadeContainer && $this->_currentEventFacadeContainer->getId() == $_event->container_id && $this->_currentEventFacadeContainer->type == Tinebase_Model_Container::TYPE_PERSONAL && !$_event->hasExternalOrganizer()) { $_event->organizer = $this->_calendarUser->user_id; } // in MS world only cal_user can do status updates if ($CUAttendee) { $CUAttendee->status_authkey = $currentCUAttendee ? $currentCUAttendee->status_authkey : NULL; } }
/** * testAlarmAckInRecurException * * @see 0009396: alarm_ack_time and alarm_snooze_time are not updated */ public function testAlarmAckInRecurException() { $event = $this->testCreate(); // save event as sclever to ack sclevers alarm Tinebase_Core::set(Tinebase_Core::USER, $this->_personas['sclever']); $exdateAlarms = $event->exdate->getFirstRecord()->alarms; $ackTime = Tinebase_DateTime::now(); $scleverAlarm = new Tinebase_Model_Alarm(array('model' => 'Calendar_Model_Event', 'alarm_time' => $ackTime, 'minutes_before' => 90)); $ackAlarm = Calendar_Controller_Alarm::getMatchingAlarm($exdateAlarms, $scleverAlarm); Calendar_Controller_Alarm::setAcknowledgeTime($ackAlarm, $ackTime); $updatedEvent = $this->_uit->update($event); $this->assertEquals(3, count($updatedEvent->alarms)); $updatedAlarm = Calendar_Controller_Alarm::getMatchingAlarm($updatedEvent->exdate->getFirstRecord()->alarms, $scleverAlarm); $this->assertEquals($ackTime, Calendar_Controller_Alarm::getAcknowledgeTime($updatedAlarm)); // check alarm ack client + ip $accessLog = Tinebase_Core::get(Tinebase_Core::USERACCESSLOG); $this->assertEquals($accessLog->ip, $updatedAlarm->getOption(Tinebase_Model_Alarm::OPTION_ACK_IP), 'ip not found in options: ' . print_r($updatedAlarm->toArray(), true)); $expectedClient = 'type: ' . $accessLog->clienttype . '|useragent: ' . $_SERVER['HTTP_USER_AGENT']; $this->assertEquals($expectedClient, $updatedAlarm->getOption(Tinebase_Model_Alarm::OPTION_ACK_CLIENT), 'clienttype not found in options: ' . print_r($updatedAlarm->toArray(), true)); }