Exemplo n.º 1
0
 /**
  * Compute an HTTP GET method.
  *
  * @param  Request   $request     HTTP request.
  * @param  Response  $response    HTTP response.
  * @return bool
  * @throws Exception\Dav\Exception
  */
 function httpGet(Request $request, Response $response)
 {
     if (System\Collection::NAME . '/' . Node::NAME !== $request->getPath()) {
         return;
     }
     $queries = $request->getQueryParameters();
     if (isset($queries['test']) && 'mail' === $queries['test'] && isset($queries['payload'])) {
         $payload = @json_decode($queries['payload']);
         if (!$payload || !isset($payload->transport) || !isset($payload->username) || !isset($payload->password)) {
             throw new Exception\Dav\Exception('Payload is corrupted.');
         }
         Mail\Message::setDefaultTransport(new Mail\Transport\Smtp(new Socket\Client('tcp://' . $payload->transport), $payload->username, $payload->password));
         $message = new Mail\Message();
         $message['from'] = 'sabre/katana <' . $payload->username . '>';
         $message['to'] = $payload->username;
         $message['subject'] = 'Test mail from sabre/katana';
         $message->addContent(new Mail\Content\Text('Hey!' . "\n\n" . 'If you receive this email, it means that your ' . 'sabre/katana server is able to send emails! ' . "\n\n" . 'Congratulations :-).'));
         $message->send();
         $response->setHeader('Content-Type', 'application/json');
         $response->setBody(json_encode(true));
         return false;
     }
     $configuration = ['database' => ['dsn' => $this->configuration->database->dsn, 'username' => $this->configuration->database->username], 'mail' => ['address' => '', 'port' => '', 'username' => '', 'password' => '']];
     if (isset($this->configuration->mail)) {
         $socket = new Socket('tcp://' . $this->configuration->mail->transport);
         $configuration['mail']['address'] = $socket->getAddress();
         $configuration['mail']['port'] = $socket->hasPort() ? $socket->getPort() : 587;
         $configuration['mail']['username'] = $this->configuration->mail->username;
         $configuration['mail']['password'] = $this->configuration->mail->password;
         unset($socket);
     }
     $response->setHeader('Content-Type', 'application/json');
     $response->setBody(json_encode($configuration));
     return false;
 }
Exemplo n.º 2
0
 /**
  * Send the IMip message.
  *
  * @param  ITip\Message  $itip    ITip message.
  * @return void
  */
 function schedule(ITip\Message $itip)
 {
     // Not sending any emails if the system considers the update
     // insignificant.
     if (false === $itip->significantChange) {
         if (empty($itip->scheduleStatus)) {
             $itip->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email.';
         }
         return;
     }
     $deliveredLocally = '1.2' === $itip->getScheduleStatus();
     $senderName = $itip->senderName;
     $recipientName = $itip->recipientName;
     // 7 is the length of `mailto:`.
     $senderEmail = substr($itip->sender, 7);
     $recipientEmail = substr($itip->recipient, 7);
     $subject = 'sabre/katana iTIP message';
     $summary = (string) $itip->message->VEVENT->SUMMARY;
     switch (strtoupper($itip->method)) {
         case 'REPLY':
             // In the case of a reply, we need to find the `PARTSTAT` from
             // the user.
             $partstat = (string) $itip->message->VEVENT->ATTENDEE['PARTSTAT'];
             switch (strtoupper($partstat)) {
                 case 'DECLINED':
                     $subject = $senderName . ' declined your invitation to "' . $summary . '"';
                     $action = 'DECLINED';
                     break;
                 case 'ACCEPTED':
                     $subject = $senderName . ' accepted your invitation to "' . $summary . '"';
                     $action = 'ACCEPTED';
                     break;
                 case 'TENTATIVE':
                     $subject = $senderName . ' tentatively accepted your invitation to "' . $summary . '"';
                     $action = 'TENTATIVE';
                     break;
                 default:
                     $itip->scheduleStatus = '5.0;Email not deliered. We didn\'t understand this PARTSTAT.';
                     return;
             }
             break;
         case 'REQUEST':
             $subject = $senderName . ' invited you to "' . $summary . '"';
             $action = 'REQUEST';
             break;
         case 'CANCEL':
             $subject = '"' . $summary . '" has been canceled.';
             $action = 'CANCEL';
             break;
         default:
             $itip->scheduleStatus = '5.0;Email not delivered. Unsupported METHOD.';
             return;
     }
     $streamsToClose = [];
     $katanaLogo = new Mail\Content\Attachment($streamsToClose[] = new File\Read('katana://public/static/image/katana_logo_full.png'), 'Logo_of_sabre_katana.png');
     $katanaLogoUrl = $katanaLogo->getIdUrl();
     $dateTime = isset($itip->message->VEVENT->DTSTART) ? $itip->message->VEVENT->DTSTART->getDateTime() : new \DateTime('now');
     $allDay = isset($itip->message->VEVENT->DTSTART) && false === $itip->message->VEVENT->DTSTART->hasTime();
     $attendees = [];
     if (isset($itip->message->VEVENT->ATTENDEE)) {
         $_attendees =& $itip->message->VEVENT->ATTENDEE;
         for ($i = 0, $max = count($_attendees); $i < $max; ++$i) {
             $attendee = $_attendees[$i];
             $attendees[] = ['cn' => isset($attendee['CN']) ? (string) $attendee['CN'] : (string) $attendee['EMAIL'], 'email' => isset($attendee['EMAIL']) ? (string) $attendee['EMAIL'] : null, 'role' => isset($attendee['ROLE']) ? (string) $attendee['ROLE'] : null];
         }
     }
     usort($attendees, function ($a, $b) {
         if ('CHAIR' === $a['role']) {
             return -1;
         }
         return 1;
     });
     $notEmpty = function ($property, $else) use($itip) {
         if (isset($itip->message->VEVENT->{$property})) {
             $handle = (string) $itip->message->VEVENT->{$property};
             if (!empty($handle)) {
                 return $handle;
             }
         }
         return $else;
     };
     $url = $notEmpty('URL', false);
     $description = $notEmpty('DESCRIPTION', false);
     $location = $notEmpty('LOCATION', false);
     $locationImage = null;
     $locationImageUrl = false;
     $locationLink = false;
     if (isset($itip->message->VEVENT->{'X-APPLE-STRUCTURED-LOCATION'})) {
         $match = preg_match('/^(geo:)?(?<latitude>\\-?\\d+\\.\\d+),(?<longitude>\\-?\\d+\\.\\d+)$/', (string) $itip->message->VEVENT->{'X-APPLE-STRUCTURED-LOCATION'}, $coordinates);
         if (0 !== $match) {
             $zoom = 16;
             $width = 500;
             $height = 220;
             $locationImage = new Mail\Content\Attachment($streamsToClose[] = new File\Read('http://api.tiles.mapbox.com/v4' . '/mapbox.streets' . '/pin-m-star+285A98' . '(' . $coordinates['longitude'] . ',' . $coordinates['latitude'] . ')' . '/' . $coordinates['longitude'] . ',' . $coordinates['latitude'] . ',' . $zoom . '/' . $width . 'x' . $height . '.png' . '?access_token=pk.eyJ1IjoiZHRvYnNjaGFsbCIsImEiOiIzMzdhNTRhNGNjOGFjOGQ4MDM5ZTJhNGZjYjNmNmE5OCJ9.7ZQOdfvoZW0XIbvjN54Wrg'), 'Map.png', 'image/png');
             $locationImageUrl = $locationImage->getIdUrl();
             $locationLink = 'http://www.openstreetmap.org' . '/?mlat=' . $coordinates['latitude'] . '&mlon=' . $coordinates['longitude'] . '#map=' . $zoom . '/' . $coordinates['latitude'] . '/' . $coordinates['longitude'];
         }
     }
     $configuration = $this->getConfiguration()->mail;
     Mail\Message::setDefaultTransport(new Mail\Transport\Smtp(new Socket\Client('tcp://' . $configuration->transport), $configuration->username, $configuration->password));
     $message = new Mail\Message();
     $message['from'] = $senderName . ' (via sabre/katana) <' . $configuration->username . '>';
     // reply-to
     $message['to'] = $recipientName . '<' . $recipientEmail . '>';
     $message['subject'] = $subject;
     // return-path
     $textBody = function () use($senderName, $summary, $action, $dateTime, $allDay, $attendees, $location, $url, $description) {
         ob_start();
         require 'katana://resource/view/caldav_scheduling.txt';
         $out = ob_get_contents();
         ob_end_clean();
         return $out;
     };
     $htmlBody = function () use($senderName, $summary, $action, $katanaLogoUrl, $dateTime, $allDay, $attendees, $location, $locationImageUrl, $locationLink, $url, $description) {
         ob_start();
         require 'katana://resource/view/caldav_scheduling.html';
         $out = ob_get_contents();
         ob_end_clean();
         return $out;
     };
     $relatedContent = [new Mail\Content\Html($htmlBody()), $katanaLogo];
     if (null !== $locationImage) {
         $relatedContent[] = $locationImage;
     }
     $message->addContent(new Mail\Content\Alternative([new Mail\Content\Text($textBody()), new Mail\Content\Related($relatedContent)]));
     if (false === $deliveredLocally) {
         $bodyAsStream = new Stringbuffer\Read();
         $bodyAsStream->initializeWith($itip->message->serialize());
         $attachment = new Mail\Content\Attachment($bodyAsStream, 'Event.ics', 'text/calendar; method=' . (string) $itip->method . '; charset=UTF-8');
         $message->addContent($attachment);
     }
     $message->send();
     foreach ($streamsToClose as $stream) {
         $stream->close();
     }
     if (false === $deliveredLocally) {
         $itip->scheduleStatus = '1.1;Scheduling message is sent via iMip.';
     }
 }