芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/www/cloud.pulsehost.co.uk/modules/CalendarMeetingsPlugin/Manager.php
oStorage->getEvent($sUserPublicId, $sCalendarId, $sEventId); if ($aData !== false) { $oVCal = $aData['vcal']; $oVCal->METHOD = 'REQUEST'; return $this->appointmentAction($sUserPublicId, $sAttendee, $sAction, $sCalendarId, $oVCal->serialize()); } return $oResult; } /** * @param string $sPartstat * @param string $sSummary */ protected function getMessageSubjectFromPartstat($sPartstat, $sSummary) { $sSubject = $sSummary; switch ($sPartstat) { case 'ACCEPTED': $sSubject = $this->GetModule()->i18N('SUBJECT_PREFFIX_ACCEPTED') . ': ' . $sSummary; break; case 'DECLINED': $sSubject = $this->GetModule()->i18N('SUBJECT_PREFFIX_DECLINED') . ': ' . $sSummary; break; case 'TENTATIVE': $sSubject = $this->GetModule()->i18N('SUBJECT_PREFFIX_TENTATIVE') . ': ' . $sSummary; break; } return $sSubject; } /** * @param User $oUser * @param string $sAttendee */ protected function getFromAccount($oUser, $sAttendee) { $oFromAccount = null; if ($oUser && $oUser->PublicId !== $sAttendee) { $oMailModule = Api::GetModule('Mail'); /** @var \Aurora\Modules\Mail\Module $oMailModule */ if ($oMailModule) { $aAccounts = $oMailModule->getAccountsManager()->getUserAccounts($oUser->Id); foreach ($aAccounts as $oAccount) { if ($oAccount instanceof MailAccount && $oAccount->Email === $sAttendee) { $oFromAccount = $oAccount; break; } } } } return $oFromAccount; } /** * Allows for responding to event invitation (accept / decline / tentative). [Aurora only.](http://dev.afterlogic.com/aurora) * * @param int|string $sUserPublicId Account object * @param string $sAttendee Attendee identified by email address * @param string $sAction Appointment actions. Accepted values: * - "ACCEPTED" * - "DECLINED" * - "TENTATIVE" * @param string $sCalendarId Calendar ID * @param string $sData ICS data of the response * @param bool $bIsLinkAction If **true**, the attendee's action on the link is assumed * @param bool $bIsExternalAttendee * * @return bool */ public function appointmentAction($sUserPublicId, $sAttendee, $sAction, $sCalendarId, $sData, $AllEvents = 2, $RecurrenceId = null, $bIsLinkAction = false, $bIsExternalAttendee = false) { $oUser = null; $bResult = false; $sEventId = null; $sTo = $sSubject = ''; $oUser = CoreModule::Decorator()->GetUserByPublicId($sUserPublicId); if (!($oUser instanceof User)) { throw new Exceptions\Exception( Enums\ErrorCodes::CannotSendAppointmentMessage, null, 'User not found' ); } if ($bIsLinkAction && !$bIsExternalAttendee) { // getting default calendar for attendee $oCalendar = $this->getDefaultCalendar($oUser->PublicId); if ($oCalendar) { $sCalendarId = $oCalendar->Id; } } /** @var \Sabre\VObject\Component\VCalendar $oVCal */ $oVCal = \Sabre\VObject\Reader::read($sData); if ($oVCal) { $sMethod = strtoupper((string) $oVCal->METHOD); $sPartstat = strtoupper($sAction); $sCN = ''; if ($sAttendee === $oUser->PublicId) { $sCN = !empty($oUser->Name) ? $oUser->Name : $sAttendee; } $bNeedsToUpdateEvent = false; // Now we need to loop through the original organizer event, to find // all the instances where we have a reply for. $masterEvent = $oVCal->getBaseComponent('VEVENT'); if (!$masterEvent) { // No master event, we can't add new instances. return false; } $sEventId = (string) $masterEvent->UID; if ($AllEvents === 2) { if ($sPartstat === 'DECLINED' || $sMethod === 'CANCEL') { if ($sCalendarId !== false) { $this->deleteEvent($sAttendee, $sCalendarId, $sEventId); } } else { $bNeedsToUpdateEvent = true; } $attendeeFound = false; if (isset($masterEvent->ATTENDEE)) { foreach ($masterEvent->ATTENDEE as $attendee) { $sEmail = str_replace('mailto:', '', strtolower($attendee->getValue())); if (strtolower($sEmail) === strtolower($sAttendee)) { $attendeeFound = true; $attendee['PARTSTAT'] = $sPartstat; $attendee['RESPONDED-AT'] = gmdate("Ymd\THis\Z"); // Un-setting the RSVP status, because we now know // that the attendee already replied. unset($attendee['RSVP']); break; } } } if (!$attendeeFound) { // Adding a new attendee. The iTip documentation calls this // a party crasher. $attendee = $masterEvent->add('ATTENDEE', $sAttendee, [ 'PARTSTAT' => $sPartstat, 'CN' => $sCN, 'RESPONDED-AT' => gmdate("Ymd\THis\Z") ]); } } $masterEvent->{'LAST-MODIFIED'} = new \DateTime('now', new \DateTimeZone('UTC')); if ($AllEvents === 1 && $RecurrenceId !== null) { if ($sPartstat === 'DECLINED' || $sMethod === 'CANCEL') { if ($sCalendarId !== false) { $oEvent = new \Aurora\Modules\Calendar\Classes\Event(); $oEvent->IdCalendar = $sCalendarId; $oEvent->Id = $sEventId; $this->updateExclusion($sAttendee, $oEvent, $RecurrenceId, true); } } else { $bNeedsToUpdateEvent = true; } $vevent = null; $index = \Aurora\Modules\Calendar\Classes\Helper::isRecurrenceExists($oVCal->VEVENT, $RecurrenceId); if ($index === false) { // If we got replies to instances that did not exist in the // original list, it means that new exceptions must be created. $recurrenceIterator = new \Sabre\VObject\Recur\EventIterator($oVCal, $masterEvent->UID); $found = false; $iterations = 1000; do { $newObject = $recurrenceIterator->getEventObject(); $recurrenceIterator->next(); if (isset($newObject->{'RECURRENCE-ID'})) { $iRecurrenceId = \Aurora\Modules\Calendar\Classes\Helper::getTimestamp($newObject->{'RECURRENCE-ID'}, $oUser->DefaultTimeZone); if ((int) $iRecurrenceId === (int) $RecurrenceId) { $found = true; } } --$iterations; } while ($recurrenceIterator->valid() && !$found && $iterations); if ($found) { unset( $newObject->RRULE, $newObject->EXDATE, $newObject->RDATE ); $vevent = $oVCal->add($newObject); } } else { $vevent = $oVCal->VEVENT[$index]; } $attendeeFound = false; if (isset($vevent->ATTENDEE)) { foreach ($vevent->ATTENDEE as $attendee) { $sEmail = str_replace('mailto:', '', strtolower($attendee->getValue())); if (strtolower($sEmail) === strtolower($sAttendee)) { $attendeeFound = true; $attendee['PARTSTAT'] = $sPartstat; $attendee['RESPONDED-AT'] = gmdate("Ymd\THis\Z"); break; } } } if ($vevent && !$attendeeFound) { // Adding a new attendee $attendee = $vevent->add('ATTENDEE', $sAttendee, [ 'PARTSTAT' => $sPartstat, 'CN' => $sCN, 'RESPONDED-AT' => gmdate("Ymd\THis\Z") ]); } } if ($sMethod === 'REQUEST') { $sMethod = 'REPLY'; } $oVCalForSend = clone $oVCal; $oVCalForSend->METHOD = $sMethod; $sTo = isset($masterEvent->ORGANIZER) ? str_replace(['mailto:', 'principals/'], '', strtolower((string) $masterEvent->ORGANIZER)) : ''; $sSummary = isset($masterEvent->SUMMARY) ? (string) $masterEvent->SUMMARY : ''; $sSubject = $this->getMessageSubjectFromPartstat($sPartstat, $sSummary); if ($bNeedsToUpdateEvent) { // update event on server unset($oVCal->METHOD); $this->oStorage->updateEventRaw( $oUser->PublicId, $sCalendarId, $sEventId, $oVCal->serialize() ); } if ($oVCalForSend) { //send message to organizer if (empty($sTo)) { throw new Exceptions\Exception( Enums\ErrorCodes::CannotSendAppointmentMessageNoOrganizer ); } $oFromAccount = $this->getFromAccount($oUser, $sAttendee); $bResult = Classes\Helper::sendAppointmentMessage( $oUser->PublicId, $sTo, $sSubject, $oVCalForSend, $sMethod, '', $oFromAccount, $sAttendee ); } } if (!$bResult) { Api::Log('Ics Appointment Action FALSE result!', LogLevel::Error); if ($sUserPublicId) { Api::Log('Email: ' . $oUser->PublicId . ', Action: ' . $sAction . ', Data:', LogLevel::Error); } Api::Log($sData, LogLevel::Error); } else { $bResult = $sEventId; } return $bResult; } }