/** * send notifications * * @param Calendar_Model_Event $_event * @param Tinebase_Model_FullAccount $_updater * @param Sting $_action * @param Calendar_Model_Event $_oldEvent * @param Tinebase_Model_Alarm $_alarm * @return void */ public function doSendNotifications($_event, $_updater, $_action, $_oldEvent = NULL, $_alarm = NULL) { // we only send notifications to attendee if (!$_event->attendee instanceof Tinebase_Record_RecordSet) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Event has no attendee"); } return; } if ($_event->dtend === NULL) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($_event->toArray(), TRUE)); } throw new Tinebase_Exception_UnexpectedValue('no dtend set in event'); } if (Tinebase_DateTime::now()->subHour(1)->isLater($_event->dtend)) { if ($_action == 'alarm' || !($_event->isRecurException() || $_event->rrule)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Skip notifications to past events"); } return; } } $notificationPeriodConfig = Calendar_Config::getInstance()->get(Calendar_Config::MAX_NOTIFICATION_PERIOD_FROM); if (Tinebase_DateTime::now()->subWeek($notificationPeriodConfig)->isLater($_event->dtend)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Skip notifications to past events (MAX_NOTIFICATION_PERIOD_FROM: " . $notificationPeriodConfig . " week(s))"); } return; } // lets resolve attendee once as batch to fill cache $attendee = clone $_event->attendee; Calendar_Model_Attender::resolveAttendee($attendee); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " " . print_r($_event->toArray(), true)); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Notification action: " . $_action); } switch ($_action) { case 'alarm': foreach ($_event->attendee as $attender) { if (Calendar_Model_Attender::isAlarmForAttendee($attender, $_alarm)) { $this->sendNotificationToAttender($attender, $_event, $_updater, $_action, self::NOTIFICATION_LEVEL_NONE); } } break; case 'booked': case 'created': case 'deleted': foreach ($_event->attendee as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, $_action, self::NOTIFICATION_LEVEL_INVITE_CANCEL); } break; case 'changed': $attendeeMigration = Calendar_Model_Attender::getMigration($_oldEvent->attendee, $_event->attendee); foreach ($attendeeMigration['toCreate'] as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, 'created', self::NOTIFICATION_LEVEL_INVITE_CANCEL); } foreach ($attendeeMigration['toDelete'] as $attender) { $this->sendNotificationToAttender($attender, $_oldEvent, $_updater, 'deleted', self::NOTIFICATION_LEVEL_INVITE_CANCEL); } // NOTE: toUpdate are all attendee to be notified if (count($attendeeMigration['toUpdate']) > 0) { $updates = $this->_getUpdates($_event, $_oldEvent); if (empty($updates)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " empty update, nothing to notify about"); return; } // compute change type if (count(array_intersect(array('dtstart', 'dtend'), array_keys($updates))) > 0) { $notificationLevel = self::NOTIFICATION_LEVEL_EVENT_RESCHEDULE; } else { if (count(array_diff(array_keys($updates), array('attendee'))) > 0) { $notificationLevel = self::NOTIFICATION_LEVEL_EVENT_UPDATE; } else { $notificationLevel = self::NOTIFICATION_LEVEL_ATTENDEE_STATUS_UPDATE; } } // send notifications foreach ($attendeeMigration['toUpdate'] as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, 'changed', $notificationLevel, $updates); } } break; default: if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " unknown action '{$_action}'"); } break; } // SEND REPLY/COUNTER to external organizer if ($_event->organizer && !$_event->resolveOrganizer()->account_id && count($_event->attendee) == 1) { $updates = array('attendee' => array('toUpdate' => $_event->attendee)); $organizer = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => $_event->resolveOrganizer())); $this->sendNotificationToAttender($organizer, $_event, $_updater, 'changed', self::NOTIFICATION_LEVEL_ATTENDEE_STATUS_UPDATE, $updates); } }