1<?php
2
3namespace Sabre\CalDAV\Xml\Notification;
4
5use Sabre\Xml\Writer;
6use Sabre\CalDAV\SharingPlugin as SharingPlugin;
7use Sabre\CalDAV;
8
9/**
10 * This class represents the cs:invite-notification notification element.
11 *
12 * This element is defined here:
13 * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
14 *
15 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
16 * @author Evert Pot (http://evertpot.com/)
17 * @license http://sabre.io/license/ Modified BSD License
18 */
19class Invite implements NotificationInterface {
20
21    /**
22     * A unique id for the message
23     *
24     * @var string
25     */
26    protected $id;
27
28    /**
29     * Timestamp of the notification
30     *
31     * @var DateTime
32     */
33    protected $dtStamp;
34
35    /**
36     * A url to the recipient of the notification. This can be an email
37     * address (mailto:), or a principal url.
38     *
39     * @var string
40     */
41    protected $href;
42
43    /**
44     * The type of message, see the SharingPlugin::STATUS_* constants.
45     *
46     * @var int
47     */
48    protected $type;
49
50    /**
51     * True if access to a calendar is read-only.
52     *
53     * @var bool
54     */
55    protected $readOnly;
56
57    /**
58     * A url to the shared calendar.
59     *
60     * @var string
61     */
62    protected $hostUrl;
63
64    /**
65     * Url to the sharer of the calendar
66     *
67     * @var string
68     */
69    protected $organizer;
70
71    /**
72     * The name of the sharer.
73     *
74     * @var string
75     */
76    protected $commonName;
77
78    /**
79     * The name of the sharer.
80     *
81     * @var string
82     */
83    protected $firstName;
84
85    /**
86     * The name of the sharer.
87     *
88     * @var string
89     */
90    protected $lastName;
91
92    /**
93     * A description of the share request
94     *
95     * @var string
96     */
97    protected $summary;
98
99    /**
100     * The Etag for the notification
101     *
102     * @var string
103     */
104    protected $etag;
105
106    /**
107     * The list of supported components
108     *
109     * @var Sabre\CalDAV\Property\SupportedCalendarComponentSet
110     */
111    protected $supportedComponents;
112
113    /**
114     * Creates the Invite notification.
115     *
116     * This constructor receives an array with the following elements:
117     *
118     *   * id           - A unique id
119     *   * etag         - The etag
120     *   * dtStamp      - A DateTime object with a timestamp for the notification.
121     *   * type         - The type of notification, see SharingPlugin::STATUS_*
122     *                    constants for details.
123     *   * readOnly     - This must be set to true, if this is an invite for
124     *                    read-only access to a calendar.
125     *   * hostUrl      - A url to the shared calendar.
126     *   * organizer    - Url to the sharer principal.
127     *   * commonName   - The real name of the sharer (optional).
128     *   * firstName    - The first name of the sharer (optional).
129     *   * lastName     - The last name of the sharer (optional).
130     *   * summary      - Description of the share, can be the same as the
131     *                    calendar, but may also be modified (optional).
132     *   * supportedComponents - An instance of
133     *                    Sabre\CalDAV\Property\SupportedCalendarComponentSet.
134     *                    This allows the client to determine which components
135     *                    will be supported in the shared calendar. This is
136     *                    also optional.
137     *
138     * @param array $values All the options
139     */
140    function __construct(array $values) {
141
142        $required = [
143            'id',
144            'etag',
145            'href',
146            'dtStamp',
147            'type',
148            'readOnly',
149            'hostUrl',
150            'organizer',
151        ];
152        foreach ($required as $item) {
153            if (!isset($values[$item])) {
154                throw new \InvalidArgumentException($item . ' is a required constructor option');
155            }
156        }
157
158        foreach ($values as $key => $value) {
159            if (!property_exists($this, $key)) {
160                throw new \InvalidArgumentException('Unknown option: ' . $key);
161            }
162            $this->$key = $value;
163        }
164
165    }
166
167    /**
168     * The xmlSerialize metod is called during xml writing.
169     *
170     * Use the $writer argument to write its own xml serialization.
171     *
172     * An important note: do _not_ create a parent element. Any element
173     * implementing XmlSerializble should only ever write what's considered
174     * its 'inner xml'.
175     *
176     * The parent of the current element is responsible for writing a
177     * containing element.
178     *
179     * This allows serializers to be re-used for different element names.
180     *
181     * If you are opening new elements, you must also close them again.
182     *
183     * @param Writer $writer
184     * @return void
185     */
186    function xmlSerialize(Writer $writer) {
187
188        $writer->writeElement('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-notification');
189
190    }
191
192    /**
193     * This method serializes the entire notification, as it is used in the
194     * response body.
195     *
196     * @param Writer $writer
197     * @return void
198     */
199    function xmlSerializeFull(Writer $writer) {
200
201        $cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}';
202
203        $this->dtStamp->setTimezone(new \DateTimezone('GMT'));
204        $writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z'));
205
206        $writer->startElement($cs . 'invite-notification');
207
208        $writer->writeElement($cs . 'uid', $this->id);
209        $writer->writeElement('{DAV:}href', $this->href);
210
211        switch ($this->type) {
212
213            case SharingPlugin::STATUS_ACCEPTED :
214                $writer->writeElement($cs . 'invite-accepted');
215                break;
216            case SharingPlugin::STATUS_DECLINED :
217                $writer->writeElement($cs . 'invite-declined');
218                break;
219            case SharingPlugin::STATUS_DELETED :
220                $writer->writeElement($cs . 'invite-deleted');
221                break;
222            case SharingPlugin::STATUS_NORESPONSE :
223                $writer->writeElement($cs . 'invite-noresponse');
224                break;
225
226        }
227
228        $writer->writeElement($cs . 'hosturl', [
229            '{DAV:}href' => $writer->contextUri . $this->hostUrl
230            ]);
231
232        if ($this->summary) {
233            $writer->writeElement($cs . 'summary', $this->summary);
234        }
235
236        $writer->startElement($cs . 'access');
237        if ($this->readOnly) {
238            $writer->writeElement($cs . 'read');
239        } else {
240            $writer->writeElement($cs . 'read-write');
241        }
242        $writer->endElement(); // access
243
244        $writer->startElement($cs . 'organizer');
245        // If the organizer contains a 'mailto:' part, it means it should be
246        // treated as absolute.
247        if (strtolower(substr($this->organizer, 0, 7)) === 'mailto:') {
248            $writer->writeElement('{DAV:}href', $this->organizer);
249        } else {
250            $writer->writeElement('{DAV:}href', $writer->contextUri . $this->organizer);
251        }
252        if ($this->commonName) {
253            $writer->writeElement($cs . 'common-name', $this->commonName);
254        }
255        if ($this->firstName) {
256            $writer->writeElement($cs . 'first-name', $this->firstName);
257        }
258        if ($this->lastName) {
259            $writer->writeElement($cs . 'last-name', $this->lastName);
260        }
261        $writer->endElement(); // organizer
262
263        if ($this->commonName) {
264            $writer->writeElement($cs . 'organizer-cn', $this->commonName);
265        }
266        if ($this->firstName) {
267            $writer->writeElement($cs . 'organizer-first', $this->firstName);
268        }
269        if ($this->lastName) {
270            $writer->writeElement($cs . 'organizer-last', $this->lastName);
271        }
272        if ($this->supportedComponents) {
273            $writer->writeElement('{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set', $this->supportedComponents);
274        }
275
276        $writer->endElement(); // invite-notification
277
278    }
279
280    /**
281     * Returns a unique id for this notification
282     *
283     * This is just the base url. This should generally be some kind of unique
284     * id.
285     *
286     * @return string
287     */
288    function getId() {
289
290        return $this->id;
291
292    }
293
294    /**
295     * Returns the ETag for this notification.
296     *
297     * The ETag must be surrounded by literal double-quotes.
298     *
299     * @return string
300     */
301    function getETag() {
302
303        return $this->etag;
304
305    }
306
307}
308