/** * converts egw alarms into tine alarms * * @param array $_egwEventData * @return Tinebase_Record_RecordSet of Tinebase_Model_Alarm */ protected function _convertAlarms($_egwEventData) { $alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $select = $this->_egwDb->select()->from(array('alarms' => 'egw_async'))->where($this->_egwDb->quoteInto($this->_egwDb->quoteIdentifier('async_id') . ' LIKE ?', "cal:{$_egwEventData['cal_id']}:%")); $egwAlarms = $this->_egwDb->fetchAll($select, NULL, Zend_Db::FETCH_ASSOC); if (count($egwAlarms) == 0) { return $alarms; } foreach ($egwAlarms as $egwAlarm) { $egwAlarmData = unserialize($egwAlarm['async_data']); $tineAlarm = new Tinebase_Model_Alarm(array('model' => 'Calendar_Model_Event', 'alarm_time' => $this->convertDate($egwAlarmData['time']), 'minutes_before' => $egwAlarmData['offset'] / 60), TRUE); $tineAlarm->sent_status = $tineAlarm->alarm_time->isEarlier($this->_migrationStartTime) ? Tinebase_Model_Alarm::STATUS_SUCCESS : Tinebase_Model_Alarm::STATUS_PENDING; $tineAlarm->setOption('minutes_before', $tineAlarm->minutes_before); $tineAlarm->setOption('custom', false); if (isset($_egwEventData['rrule'])) { $dtstart = $this->convertDate($egwAlarmData['time'] + $egwAlarmData['offset']); $dtstart = $dtstart ? $dtstart : Tinebase_DateTime::now(); $recurId = $_egwEventData['cal_uid'] . '-' . $dtstart->get(Tinebase_Record_Abstract::ISO8601LONG); } $tineAlarm->setOption('recurid', isset($_egwEventData['rrule']) ? $recurId : NULL); $alarms->addRecord($tineAlarm); } return $alarms; }
/** * adopt alarm time to next occurrence for recurring events * * @param Tinebase_Record_Abstract $_record * @param Tinebase_Model_Alarm $_alarm * @param bool $_nextBy {instance|time} set recurr alarm to next from given instance or next by current time * @return void */ public function adoptAlarmTime(Tinebase_Record_Abstract $_record, Tinebase_Model_Alarm $_alarm, $_nextBy = 'time') { if ($_record->rrule) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adopting alarm time for next recur occurrence (by ' . $_nextBy . ')'); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_record->toArray(), TRUE)); } if ($_nextBy == 'time') { // NOTE: this also finds instances running right now $from = Tinebase_DateTime::now(); } else { $recurid = $_alarm->getOption('recurid'); $instanceStart = $recurid ? new Tinebase_DateTime(substr($recurid, -19)) : clone $_record->dtstart; $eventLength = $_record->dtstart->diff($_record->dtend); $instanceStart->setTimezone($_record->originator_tz); $from = $instanceStart->add($eventLength); $from->setTimezone('UTC'); } // compute next $exceptions = $this->getRecurExceptions($_record); $nextOccurrence = Calendar_Model_Rrule::computeNextOccurrence($_record, $exceptions, $from); if ($nextOccurrence === NULL) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Recur series is over, no more alarms pending'); } } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found next occurrence, adopting alarm to dtstart ' . $nextOccurrence->dtstart->toString()); } } // save recurid so we know for which recurrance the alarm is for $_alarm->setOption('recurid', isset($nextOccurrence) ? $nextOccurrence->recurid : NULL); $_alarm->sent_status = $nextOccurrence ? Tinebase_Model_Alarm::STATUS_PENDING : Tinebase_Model_Alarm::STATUS_SUCCESS; $_alarm->sent_message = $nextOccurrence ? '' : 'Nothing to send, series is over'; $eventStart = $nextOccurrence ? clone $nextOccurrence->dtstart : clone $_record->dtstart; } else { $eventStart = clone $_record->dtstart; } // save minutes before / compute it for custom alarms $minutesBefore = $_alarm->minutes_before == Tinebase_Model_Alarm::OPTION_CUSTOM ? ($_record->dtstart->getTimestamp() - $_alarm->alarm_time->getTimestamp()) / 60 : $_alarm->minutes_before; $minutesBefore = round($minutesBefore); $_alarm->setOption('minutes_before', $minutesBefore); $_alarm->alarm_time = $eventStart->subMinute($minutesBefore); if ($_record->rrule && $_alarm->sent_status == Tinebase_Model_Alarm::STATUS_PENDING && $_alarm->alarm_time < $_alarm->sent_time) { $this->adoptAlarmTime($_record, $_alarm, 'instance'); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' alarm: ' . print_r($_alarm->toArray(), true)); } }
/** * sets snoozed time in alarm * * @param Tinebase_Model_Alarm $alarm * @param DateTime $time * @param Tinebase_Model_User $user */ public static function setSnoozeTime($alarm, $time, $user = null) { $user = $user instanceof Tinebase_Model_User ?: Tinebase_Core::getUser(); $alarm->setOption("snoozed-{$user->contact_id}", $time->format(Tinebase_Record_Abstract::ISO8601LONG)); }
/** * adopt alarm time to next occurance for recurring events * * @param Tinebase_Record_Abstract $_record * @param Tinebase_Model_Alarm $_alarm * @param bool $_nextBy {instance|time} set recurr alarm to next from given instance or next by current time * @return void * @throws Tinebase_Exception_InvalidArgument */ public function adoptAlarmTime(Tinebase_Record_Abstract $_record, Tinebase_Model_Alarm $_alarm, $_nextBy = 'time') { if ($_record->rrule) { if ($_nextBy == 'time') { // NOTE: this also finds instances running right now $from = Tinebase_DateTime::now(); } else { $recurid = $_alarm->getOption('recurid'); $instanceStart = $recurid ? new Tinebase_DateTime(substr($recurid, -19)) : clone $_record->dtstart; $eventLength = $_record->dtstart->diff($_record->dtend); // make sure we hit the next instance $from = $instanceStart->add($eventLength)->addMinute(1); } // this would break if minutes_before > interval //$from->addMinute((int) $_alarm->getOption('minutes_before')); // compute next $exceptions = $this->getRecurExceptions($_record); $nextOccurrence = Calendar_Model_Rrule::computeNextOccurrence($_record, $exceptions, $from); // save recurid so we know for which recurrance the alarm is for $_alarm->setOption('recurid', isset($nextOccurrence) ? $nextOccurrence->recurid : NULL); $_alarm->sent_status = $nextOccurrence ? Tinebase_Model_Alarm::STATUS_PENDING : Tinebase_Model_Alarm::STATUS_SUCCESS; $_alarm->sent_message = $nextOccurrence ? '' : 'Nothing to send, series is over'; if (!$nextOccurrence) { return; } $eventStart = clone $nextOccurrence->dtstart; } else { $eventStart = clone $_record->dtstart; } // save minutes before / compute it for custom alarms $_alarm->setOption('minutes_before', $_alarm->minutes_before == Tinebase_Model_Alarm::OPTION_CUSTOM ? ($_record->dtstart->getTimestamp() - $_alarm->alarm_time->getTimestamp()) / 60 : $_alarm->minutes_before); $_alarm->setTime($eventStart); }