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