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) 2007-2015 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 (rfc6037) for CalDAV scheduling',
185            'link'        => 'http://sabre.io/dav/scheduling/',
186        ];
187
188    }
189
190}
191