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