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