1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV\Schedule; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\DAV; 6*a1a3b679SAndreas Boehleruse Sabre\VObject\ITip; 7*a1a3b679SAndreas Boehler 8*a1a3b679SAndreas Boehler/** 9*a1a3b679SAndreas Boehler * iMIP handler. 10*a1a3b679SAndreas Boehler * 11*a1a3b679SAndreas Boehler * This class is responsible for sending out iMIP messages. iMIP is the 12*a1a3b679SAndreas Boehler * email-based transport for iTIP. iTIP deals with scheduling operations for 13*a1a3b679SAndreas Boehler * iCalendar objects. 14*a1a3b679SAndreas Boehler * 15*a1a3b679SAndreas Boehler * If you want to customize the email that gets sent out, you can do so by 16*a1a3b679SAndreas Boehler * extending this class and overriding the sendMessage method. 17*a1a3b679SAndreas Boehler * 18*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/). 19*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 20*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 21*a1a3b679SAndreas Boehler */ 22*a1a3b679SAndreas Boehlerclass IMipPlugin extends DAV\ServerPlugin { 23*a1a3b679SAndreas Boehler 24*a1a3b679SAndreas Boehler /** 25*a1a3b679SAndreas Boehler * Email address used in From: header. 26*a1a3b679SAndreas Boehler * 27*a1a3b679SAndreas Boehler * @var string 28*a1a3b679SAndreas Boehler */ 29*a1a3b679SAndreas Boehler protected $senderEmail; 30*a1a3b679SAndreas Boehler 31*a1a3b679SAndreas Boehler /** 32*a1a3b679SAndreas Boehler * ITipMessage 33*a1a3b679SAndreas Boehler * 34*a1a3b679SAndreas Boehler * @var ITip\Message 35*a1a3b679SAndreas Boehler */ 36*a1a3b679SAndreas Boehler protected $itipMessage; 37*a1a3b679SAndreas Boehler 38*a1a3b679SAndreas Boehler /** 39*a1a3b679SAndreas Boehler * Creates the email handler. 40*a1a3b679SAndreas Boehler * 41*a1a3b679SAndreas Boehler * @param string $senderEmail. The 'senderEmail' is the email that shows up 42*a1a3b679SAndreas Boehler * in the 'From:' address. This should 43*a1a3b679SAndreas Boehler * generally be some kind of no-reply email 44*a1a3b679SAndreas Boehler * address you own. 45*a1a3b679SAndreas Boehler */ 46*a1a3b679SAndreas Boehler function __construct($senderEmail) { 47*a1a3b679SAndreas Boehler 48*a1a3b679SAndreas Boehler $this->senderEmail = $senderEmail; 49*a1a3b679SAndreas Boehler 50*a1a3b679SAndreas Boehler } 51*a1a3b679SAndreas Boehler 52*a1a3b679SAndreas Boehler /* 53*a1a3b679SAndreas Boehler * This initializes the plugin. 54*a1a3b679SAndreas Boehler * 55*a1a3b679SAndreas Boehler * This function is called by Sabre\DAV\Server, after 56*a1a3b679SAndreas Boehler * addPlugin is called. 57*a1a3b679SAndreas Boehler * 58*a1a3b679SAndreas Boehler * This method should set up the required event subscriptions. 59*a1a3b679SAndreas Boehler * 60*a1a3b679SAndreas Boehler * @param DAV\Server $server 61*a1a3b679SAndreas Boehler * @return void 62*a1a3b679SAndreas Boehler */ 63*a1a3b679SAndreas Boehler function initialize(DAV\Server $server) { 64*a1a3b679SAndreas Boehler 65*a1a3b679SAndreas Boehler $server->on('schedule', [$this, 'schedule'], 120); 66*a1a3b679SAndreas Boehler 67*a1a3b679SAndreas Boehler } 68*a1a3b679SAndreas Boehler 69*a1a3b679SAndreas Boehler /** 70*a1a3b679SAndreas Boehler * Returns a plugin name. 71*a1a3b679SAndreas Boehler * 72*a1a3b679SAndreas Boehler * Using this name other plugins will be able to access other plugins 73*a1a3b679SAndreas Boehler * using \Sabre\DAV\Server::getPlugin 74*a1a3b679SAndreas Boehler * 75*a1a3b679SAndreas Boehler * @return string 76*a1a3b679SAndreas Boehler */ 77*a1a3b679SAndreas Boehler function getPluginName() { 78*a1a3b679SAndreas Boehler 79*a1a3b679SAndreas Boehler return 'imip'; 80*a1a3b679SAndreas Boehler 81*a1a3b679SAndreas Boehler } 82*a1a3b679SAndreas Boehler 83*a1a3b679SAndreas Boehler /** 84*a1a3b679SAndreas Boehler * Event handler for the 'schedule' event. 85*a1a3b679SAndreas Boehler * 86*a1a3b679SAndreas Boehler * @param ITip\Message $iTipMessage 87*a1a3b679SAndreas Boehler * @return void 88*a1a3b679SAndreas Boehler */ 89*a1a3b679SAndreas Boehler function schedule(ITip\Message $iTipMessage) { 90*a1a3b679SAndreas Boehler 91*a1a3b679SAndreas Boehler // Not sending any emails if the system considers the update 92*a1a3b679SAndreas Boehler // insignificant. 93*a1a3b679SAndreas Boehler if (!$iTipMessage->significantChange) { 94*a1a3b679SAndreas Boehler if (!$iTipMessage->scheduleStatus) { 95*a1a3b679SAndreas Boehler $iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email'; 96*a1a3b679SAndreas Boehler } 97*a1a3b679SAndreas Boehler return; 98*a1a3b679SAndreas Boehler } 99*a1a3b679SAndreas Boehler 100*a1a3b679SAndreas Boehler $summary = $iTipMessage->message->VEVENT->SUMMARY; 101*a1a3b679SAndreas Boehler 102*a1a3b679SAndreas Boehler if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto') 103*a1a3b679SAndreas Boehler return; 104*a1a3b679SAndreas Boehler 105*a1a3b679SAndreas Boehler if (parse_url($iTipMessage->recipient, PHP_URL_SCHEME) !== 'mailto') 106*a1a3b679SAndreas Boehler return; 107*a1a3b679SAndreas Boehler 108*a1a3b679SAndreas Boehler $sender = substr($iTipMessage->sender, 7); 109*a1a3b679SAndreas Boehler $recipient = substr($iTipMessage->recipient, 7); 110*a1a3b679SAndreas Boehler 111*a1a3b679SAndreas Boehler if ($iTipMessage->senderName) { 112*a1a3b679SAndreas Boehler $sender = $iTipMessage->senderName . ' <' . $sender . '>'; 113*a1a3b679SAndreas Boehler } 114*a1a3b679SAndreas Boehler if ($iTipMessage->recipientName) { 115*a1a3b679SAndreas Boehler $recipient = $iTipMessage->recipientName . ' <' . $recipient . '>'; 116*a1a3b679SAndreas Boehler } 117*a1a3b679SAndreas Boehler 118*a1a3b679SAndreas Boehler $subject = 'SabreDAV iTIP message'; 119*a1a3b679SAndreas Boehler switch (strtoupper($iTipMessage->method)) { 120*a1a3b679SAndreas Boehler case 'REPLY' : 121*a1a3b679SAndreas Boehler $subject = 'Re: ' . $summary; 122*a1a3b679SAndreas Boehler break; 123*a1a3b679SAndreas Boehler case 'REQUEST' : 124*a1a3b679SAndreas Boehler $subject = $summary; 125*a1a3b679SAndreas Boehler break; 126*a1a3b679SAndreas Boehler case 'CANCEL' : 127*a1a3b679SAndreas Boehler $subject = 'Cancelled: ' . $summary; 128*a1a3b679SAndreas Boehler break; 129*a1a3b679SAndreas Boehler } 130*a1a3b679SAndreas Boehler 131*a1a3b679SAndreas Boehler $headers = [ 132*a1a3b679SAndreas Boehler 'Reply-To: ' . $sender, 133*a1a3b679SAndreas Boehler 'From: ' . $this->senderEmail, 134*a1a3b679SAndreas Boehler 'Content-Type: text/calendar; charset=UTF-8; method=' . $iTipMessage->method, 135*a1a3b679SAndreas Boehler ]; 136*a1a3b679SAndreas Boehler if (DAV\Server::$exposeVersion) { 137*a1a3b679SAndreas Boehler $headers[] = 'X-Sabre-Version: ' . DAV\Version::VERSION; 138*a1a3b679SAndreas Boehler } 139*a1a3b679SAndreas Boehler $this->mail( 140*a1a3b679SAndreas Boehler $recipient, 141*a1a3b679SAndreas Boehler $subject, 142*a1a3b679SAndreas Boehler $iTipMessage->message->serialize(), 143*a1a3b679SAndreas Boehler $headers 144*a1a3b679SAndreas Boehler ); 145*a1a3b679SAndreas Boehler $iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip'; 146*a1a3b679SAndreas Boehler 147*a1a3b679SAndreas Boehler } 148*a1a3b679SAndreas Boehler 149*a1a3b679SAndreas Boehler // @codeCoverageIgnoreStart 150*a1a3b679SAndreas Boehler // This is deemed untestable in a reasonable manner 151*a1a3b679SAndreas Boehler 152*a1a3b679SAndreas Boehler /** 153*a1a3b679SAndreas Boehler * This function is responsible for sending the actual email. 154*a1a3b679SAndreas Boehler * 155*a1a3b679SAndreas Boehler * @param string $to Recipient email address 156*a1a3b679SAndreas Boehler * @param string $subject Subject of the email 157*a1a3b679SAndreas Boehler * @param string $body iCalendar body 158*a1a3b679SAndreas Boehler * @param array $headers List of headers 159*a1a3b679SAndreas Boehler * @return void 160*a1a3b679SAndreas Boehler */ 161*a1a3b679SAndreas Boehler protected function mail($to, $subject, $body, array $headers) { 162*a1a3b679SAndreas Boehler 163*a1a3b679SAndreas Boehler mail($to, $subject, $body, implode("\r\n", $headers)); 164*a1a3b679SAndreas Boehler 165*a1a3b679SAndreas Boehler } 166*a1a3b679SAndreas Boehler 167*a1a3b679SAndreas Boehler // @codeCoverageIgnoreEnd 168*a1a3b679SAndreas Boehler 169*a1a3b679SAndreas Boehler /** 170*a1a3b679SAndreas Boehler * Returns a bunch of meta-data about the plugin. 171*a1a3b679SAndreas Boehler * 172*a1a3b679SAndreas Boehler * Providing this information is optional, and is mainly displayed by the 173*a1a3b679SAndreas Boehler * Browser plugin. 174*a1a3b679SAndreas Boehler * 175*a1a3b679SAndreas Boehler * The description key in the returned array may contain html and will not 176*a1a3b679SAndreas Boehler * be sanitized. 177*a1a3b679SAndreas Boehler * 178*a1a3b679SAndreas Boehler * @return array 179*a1a3b679SAndreas Boehler */ 180*a1a3b679SAndreas Boehler function getPluginInfo() { 181*a1a3b679SAndreas Boehler 182*a1a3b679SAndreas Boehler return [ 183*a1a3b679SAndreas Boehler 'name' => $this->getPluginName(), 184*a1a3b679SAndreas Boehler 'description' => 'Email delivery (rfc6037) for CalDAV scheduling', 185*a1a3b679SAndreas Boehler 'link' => 'http://sabre.io/dav/scheduling/', 186*a1a3b679SAndreas Boehler ]; 187*a1a3b679SAndreas Boehler 188*a1a3b679SAndreas Boehler } 189*a1a3b679SAndreas Boehler 190*a1a3b679SAndreas Boehler} 191