xref: /plugin/davcal/vendor/sabre/dav/lib/CalDAV/CalendarObject.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehler/**
6*a1a3b679SAndreas Boehler * The CalendarObject represents a single VEVENT or VTODO within a Calendar.
7*a1a3b679SAndreas Boehler *
8*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
9*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
10*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
11*a1a3b679SAndreas Boehler */
12*a1a3b679SAndreas Boehlerclass CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL {
13*a1a3b679SAndreas Boehler
14*a1a3b679SAndreas Boehler    /**
15*a1a3b679SAndreas Boehler     * Sabre\CalDAV\Backend\BackendInterface
16*a1a3b679SAndreas Boehler     *
17*a1a3b679SAndreas Boehler     * @var Sabre\CalDAV\Backend\AbstractBackend
18*a1a3b679SAndreas Boehler     */
19*a1a3b679SAndreas Boehler    protected $caldavBackend;
20*a1a3b679SAndreas Boehler
21*a1a3b679SAndreas Boehler    /**
22*a1a3b679SAndreas Boehler     * Array with information about this CalendarObject
23*a1a3b679SAndreas Boehler     *
24*a1a3b679SAndreas Boehler     * @var array
25*a1a3b679SAndreas Boehler     */
26*a1a3b679SAndreas Boehler    protected $objectData;
27*a1a3b679SAndreas Boehler
28*a1a3b679SAndreas Boehler    /**
29*a1a3b679SAndreas Boehler     * Array with information about the containing calendar
30*a1a3b679SAndreas Boehler     *
31*a1a3b679SAndreas Boehler     * @var array
32*a1a3b679SAndreas Boehler     */
33*a1a3b679SAndreas Boehler    protected $calendarInfo;
34*a1a3b679SAndreas Boehler
35*a1a3b679SAndreas Boehler    /**
36*a1a3b679SAndreas Boehler     * Constructor
37*a1a3b679SAndreas Boehler     *
38*a1a3b679SAndreas Boehler     * The following properties may be passed within $objectData:
39*a1a3b679SAndreas Boehler     *
40*a1a3b679SAndreas Boehler     *   * calendarid - This must refer to a calendarid from a caldavBackend
41*a1a3b679SAndreas Boehler     *   * uri - A unique uri. Only the 'basename' must be passed.
42*a1a3b679SAndreas Boehler     *   * calendardata (optional) - The iCalendar data
43*a1a3b679SAndreas Boehler     *   * etag - (optional) The etag for this object, MUST be encloded with
44*a1a3b679SAndreas Boehler     *            double-quotes.
45*a1a3b679SAndreas Boehler     *   * size - (optional) The size of the data in bytes.
46*a1a3b679SAndreas Boehler     *   * lastmodified - (optional) format as a unix timestamp.
47*a1a3b679SAndreas Boehler     *   * acl - (optional) Use this to override the default ACL for the node.
48*a1a3b679SAndreas Boehler     *
49*a1a3b679SAndreas Boehler     * @param Backend\BackendInterface $caldavBackend
50*a1a3b679SAndreas Boehler     * @param array $calendarInfo
51*a1a3b679SAndreas Boehler     * @param array $objectData
52*a1a3b679SAndreas Boehler     */
53*a1a3b679SAndreas Boehler    function __construct(Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData) {
54*a1a3b679SAndreas Boehler
55*a1a3b679SAndreas Boehler        $this->caldavBackend = $caldavBackend;
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler        if (!isset($objectData['uri'])) {
58*a1a3b679SAndreas Boehler            throw new \InvalidArgumentException('The objectData argument must contain an \'uri\' property');
59*a1a3b679SAndreas Boehler        }
60*a1a3b679SAndreas Boehler
61*a1a3b679SAndreas Boehler        $this->calendarInfo = $calendarInfo;
62*a1a3b679SAndreas Boehler        $this->objectData = $objectData;
63*a1a3b679SAndreas Boehler
64*a1a3b679SAndreas Boehler    }
65*a1a3b679SAndreas Boehler
66*a1a3b679SAndreas Boehler    /**
67*a1a3b679SAndreas Boehler     * Returns the uri for this object
68*a1a3b679SAndreas Boehler     *
69*a1a3b679SAndreas Boehler     * @return string
70*a1a3b679SAndreas Boehler     */
71*a1a3b679SAndreas Boehler    function getName() {
72*a1a3b679SAndreas Boehler
73*a1a3b679SAndreas Boehler        return $this->objectData['uri'];
74*a1a3b679SAndreas Boehler
75*a1a3b679SAndreas Boehler    }
76*a1a3b679SAndreas Boehler
77*a1a3b679SAndreas Boehler    /**
78*a1a3b679SAndreas Boehler     * Returns the ICalendar-formatted object
79*a1a3b679SAndreas Boehler     *
80*a1a3b679SAndreas Boehler     * @return string
81*a1a3b679SAndreas Boehler     */
82*a1a3b679SAndreas Boehler    function get() {
83*a1a3b679SAndreas Boehler
84*a1a3b679SAndreas Boehler        // Pre-populating the 'calendardata' is optional, if we don't have it
85*a1a3b679SAndreas Boehler        // already we fetch it from the backend.
86*a1a3b679SAndreas Boehler        if (!isset($this->objectData['calendardata'])) {
87*a1a3b679SAndreas Boehler            $this->objectData = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
88*a1a3b679SAndreas Boehler        }
89*a1a3b679SAndreas Boehler        return $this->objectData['calendardata'];
90*a1a3b679SAndreas Boehler
91*a1a3b679SAndreas Boehler    }
92*a1a3b679SAndreas Boehler
93*a1a3b679SAndreas Boehler    /**
94*a1a3b679SAndreas Boehler     * Updates the ICalendar-formatted object
95*a1a3b679SAndreas Boehler     *
96*a1a3b679SAndreas Boehler     * @param string|resource $calendarData
97*a1a3b679SAndreas Boehler     * @return string
98*a1a3b679SAndreas Boehler     */
99*a1a3b679SAndreas Boehler    function put($calendarData) {
100*a1a3b679SAndreas Boehler
101*a1a3b679SAndreas Boehler        if (is_resource($calendarData)) {
102*a1a3b679SAndreas Boehler            $calendarData = stream_get_contents($calendarData);
103*a1a3b679SAndreas Boehler        }
104*a1a3b679SAndreas Boehler        $etag = $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'], $this->objectData['uri'], $calendarData);
105*a1a3b679SAndreas Boehler        $this->objectData['calendardata'] = $calendarData;
106*a1a3b679SAndreas Boehler        $this->objectData['etag'] = $etag;
107*a1a3b679SAndreas Boehler
108*a1a3b679SAndreas Boehler        return $etag;
109*a1a3b679SAndreas Boehler
110*a1a3b679SAndreas Boehler    }
111*a1a3b679SAndreas Boehler
112*a1a3b679SAndreas Boehler    /**
113*a1a3b679SAndreas Boehler     * Deletes the calendar object
114*a1a3b679SAndreas Boehler     *
115*a1a3b679SAndreas Boehler     * @return void
116*a1a3b679SAndreas Boehler     */
117*a1a3b679SAndreas Boehler    function delete() {
118*a1a3b679SAndreas Boehler
119*a1a3b679SAndreas Boehler        $this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
120*a1a3b679SAndreas Boehler
121*a1a3b679SAndreas Boehler    }
122*a1a3b679SAndreas Boehler
123*a1a3b679SAndreas Boehler    /**
124*a1a3b679SAndreas Boehler     * Returns the mime content-type
125*a1a3b679SAndreas Boehler     *
126*a1a3b679SAndreas Boehler     * @return string
127*a1a3b679SAndreas Boehler     */
128*a1a3b679SAndreas Boehler    function getContentType() {
129*a1a3b679SAndreas Boehler
130*a1a3b679SAndreas Boehler        $mime = 'text/calendar; charset=utf-8';
131*a1a3b679SAndreas Boehler        if (isset($this->objectData['component']) && $this->objectData['component']) {
132*a1a3b679SAndreas Boehler            $mime .= '; component=' . $this->objectData['component'];
133*a1a3b679SAndreas Boehler        }
134*a1a3b679SAndreas Boehler        return $mime;
135*a1a3b679SAndreas Boehler
136*a1a3b679SAndreas Boehler    }
137*a1a3b679SAndreas Boehler
138*a1a3b679SAndreas Boehler    /**
139*a1a3b679SAndreas Boehler     * Returns an ETag for this object.
140*a1a3b679SAndreas Boehler     *
141*a1a3b679SAndreas Boehler     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
142*a1a3b679SAndreas Boehler     *
143*a1a3b679SAndreas Boehler     * @return string
144*a1a3b679SAndreas Boehler     */
145*a1a3b679SAndreas Boehler    function getETag() {
146*a1a3b679SAndreas Boehler
147*a1a3b679SAndreas Boehler        if (isset($this->objectData['etag'])) {
148*a1a3b679SAndreas Boehler            return $this->objectData['etag'];
149*a1a3b679SAndreas Boehler        } else {
150*a1a3b679SAndreas Boehler            return '"' . md5($this->get()) . '"';
151*a1a3b679SAndreas Boehler        }
152*a1a3b679SAndreas Boehler
153*a1a3b679SAndreas Boehler    }
154*a1a3b679SAndreas Boehler
155*a1a3b679SAndreas Boehler    /**
156*a1a3b679SAndreas Boehler     * Returns the last modification date as a unix timestamp
157*a1a3b679SAndreas Boehler     *
158*a1a3b679SAndreas Boehler     * @return int
159*a1a3b679SAndreas Boehler     */
160*a1a3b679SAndreas Boehler    function getLastModified() {
161*a1a3b679SAndreas Boehler
162*a1a3b679SAndreas Boehler        return $this->objectData['lastmodified'];
163*a1a3b679SAndreas Boehler
164*a1a3b679SAndreas Boehler    }
165*a1a3b679SAndreas Boehler
166*a1a3b679SAndreas Boehler    /**
167*a1a3b679SAndreas Boehler     * Returns the size of this object in bytes
168*a1a3b679SAndreas Boehler     *
169*a1a3b679SAndreas Boehler     * @return int
170*a1a3b679SAndreas Boehler     */
171*a1a3b679SAndreas Boehler    function getSize() {
172*a1a3b679SAndreas Boehler
173*a1a3b679SAndreas Boehler        if (array_key_exists('size', $this->objectData)) {
174*a1a3b679SAndreas Boehler            return $this->objectData['size'];
175*a1a3b679SAndreas Boehler        } else {
176*a1a3b679SAndreas Boehler            return strlen($this->get());
177*a1a3b679SAndreas Boehler        }
178*a1a3b679SAndreas Boehler
179*a1a3b679SAndreas Boehler    }
180*a1a3b679SAndreas Boehler
181*a1a3b679SAndreas Boehler    /**
182*a1a3b679SAndreas Boehler     * Returns the owner principal
183*a1a3b679SAndreas Boehler     *
184*a1a3b679SAndreas Boehler     * This must be a url to a principal, or null if there's no owner
185*a1a3b679SAndreas Boehler     *
186*a1a3b679SAndreas Boehler     * @return string|null
187*a1a3b679SAndreas Boehler     */
188*a1a3b679SAndreas Boehler    function getOwner() {
189*a1a3b679SAndreas Boehler
190*a1a3b679SAndreas Boehler        return $this->calendarInfo['principaluri'];
191*a1a3b679SAndreas Boehler
192*a1a3b679SAndreas Boehler    }
193*a1a3b679SAndreas Boehler
194*a1a3b679SAndreas Boehler    /**
195*a1a3b679SAndreas Boehler     * Returns a group principal
196*a1a3b679SAndreas Boehler     *
197*a1a3b679SAndreas Boehler     * This must be a url to a principal, or null if there's no owner
198*a1a3b679SAndreas Boehler     *
199*a1a3b679SAndreas Boehler     * @return string|null
200*a1a3b679SAndreas Boehler     */
201*a1a3b679SAndreas Boehler    function getGroup() {
202*a1a3b679SAndreas Boehler
203*a1a3b679SAndreas Boehler        return null;
204*a1a3b679SAndreas Boehler
205*a1a3b679SAndreas Boehler    }
206*a1a3b679SAndreas Boehler
207*a1a3b679SAndreas Boehler    /**
208*a1a3b679SAndreas Boehler     * Returns a list of ACE's for this node.
209*a1a3b679SAndreas Boehler     *
210*a1a3b679SAndreas Boehler     * Each ACE has the following properties:
211*a1a3b679SAndreas Boehler     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
212*a1a3b679SAndreas Boehler     *     currently the only supported privileges
213*a1a3b679SAndreas Boehler     *   * 'principal', a url to the principal who owns the node
214*a1a3b679SAndreas Boehler     *   * 'protected' (optional), indicating that this ACE is not allowed to
215*a1a3b679SAndreas Boehler     *      be updated.
216*a1a3b679SAndreas Boehler     *
217*a1a3b679SAndreas Boehler     * @return array
218*a1a3b679SAndreas Boehler     */
219*a1a3b679SAndreas Boehler    function getACL() {
220*a1a3b679SAndreas Boehler
221*a1a3b679SAndreas Boehler        // An alternative acl may be specified in the object data.
222*a1a3b679SAndreas Boehler        if (isset($this->objectData['acl'])) {
223*a1a3b679SAndreas Boehler            return $this->objectData['acl'];
224*a1a3b679SAndreas Boehler        }
225*a1a3b679SAndreas Boehler
226*a1a3b679SAndreas Boehler        // The default ACL
227*a1a3b679SAndreas Boehler        return [
228*a1a3b679SAndreas Boehler            [
229*a1a3b679SAndreas Boehler                'privilege' => '{DAV:}read',
230*a1a3b679SAndreas Boehler                'principal' => $this->calendarInfo['principaluri'],
231*a1a3b679SAndreas Boehler                'protected' => true,
232*a1a3b679SAndreas Boehler            ],
233*a1a3b679SAndreas Boehler            [
234*a1a3b679SAndreas Boehler                'privilege' => '{DAV:}write',
235*a1a3b679SAndreas Boehler                'principal' => $this->calendarInfo['principaluri'],
236*a1a3b679SAndreas Boehler                'protected' => true,
237*a1a3b679SAndreas Boehler            ],
238*a1a3b679SAndreas Boehler            [
239*a1a3b679SAndreas Boehler                'privilege' => '{DAV:}read',
240*a1a3b679SAndreas Boehler                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
241*a1a3b679SAndreas Boehler                'protected' => true,
242*a1a3b679SAndreas Boehler            ],
243*a1a3b679SAndreas Boehler            [
244*a1a3b679SAndreas Boehler                'privilege' => '{DAV:}write',
245*a1a3b679SAndreas Boehler                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
246*a1a3b679SAndreas Boehler                'protected' => true,
247*a1a3b679SAndreas Boehler            ],
248*a1a3b679SAndreas Boehler            [
249*a1a3b679SAndreas Boehler                'privilege' => '{DAV:}read',
250*a1a3b679SAndreas Boehler                'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
251*a1a3b679SAndreas Boehler                'protected' => true,
252*a1a3b679SAndreas Boehler            ],
253*a1a3b679SAndreas Boehler
254*a1a3b679SAndreas Boehler        ];
255*a1a3b679SAndreas Boehler
256*a1a3b679SAndreas Boehler    }
257*a1a3b679SAndreas Boehler
258*a1a3b679SAndreas Boehler    /**
259*a1a3b679SAndreas Boehler     * Updates the ACL
260*a1a3b679SAndreas Boehler     *
261*a1a3b679SAndreas Boehler     * This method will receive a list of new ACE's.
262*a1a3b679SAndreas Boehler     *
263*a1a3b679SAndreas Boehler     * @param array $acl
264*a1a3b679SAndreas Boehler     * @return void
265*a1a3b679SAndreas Boehler     */
266*a1a3b679SAndreas Boehler    function setACL(array $acl) {
267*a1a3b679SAndreas Boehler
268*a1a3b679SAndreas Boehler        throw new \Sabre\DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
269*a1a3b679SAndreas Boehler
270*a1a3b679SAndreas Boehler    }
271*a1a3b679SAndreas Boehler
272*a1a3b679SAndreas Boehler    /**
273*a1a3b679SAndreas Boehler     * Returns the list of supported privileges for this node.
274*a1a3b679SAndreas Boehler     *
275*a1a3b679SAndreas Boehler     * The returned data structure is a list of nested privileges.
276*a1a3b679SAndreas Boehler     * See \Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
277*a1a3b679SAndreas Boehler     * standard structure.
278*a1a3b679SAndreas Boehler     *
279*a1a3b679SAndreas Boehler     * If null is returned from this method, the default privilege set is used,
280*a1a3b679SAndreas Boehler     * which is fine for most common usecases.
281*a1a3b679SAndreas Boehler     *
282*a1a3b679SAndreas Boehler     * @return array|null
283*a1a3b679SAndreas Boehler     */
284*a1a3b679SAndreas Boehler    function getSupportedPrivilegeSet() {
285*a1a3b679SAndreas Boehler
286*a1a3b679SAndreas Boehler        return null;
287*a1a3b679SAndreas Boehler
288*a1a3b679SAndreas Boehler    }
289*a1a3b679SAndreas Boehler
290*a1a3b679SAndreas Boehler}
291