1<?php
2
3namespace Sabre\DAV\Xml\Element;
4
5use Sabre\DAV\Exception\BadRequest;
6use Sabre\DAV\Sharing\Plugin;
7use Sabre\DAV\Xml\Property\Href;
8use Sabre\DAV\Xml\Property\ShareAccess;
9use Sabre\Xml\Deserializer;
10use Sabre\Xml\Element;
11use Sabre\Xml\Reader;
12use Sabre\Xml\Writer;
13
14/**
15 * This class represents the {DAV:}sharee element.
16 *
17 * @copyright Copyright (C) fruux GmbH. (https://fruux.com/)
18 * @author Evert Pot (http://evertpot.com/)
19 * @license http://sabre.io/license/ Modified BSD License
20 */
21class Sharee implements Element {
22
23    /**
24     * A URL. Usually a mailto: address, could also be a principal url.
25     * This uniquely identifies the sharee.
26     *
27     * @var string
28     */
29    public $href;
30
31    /**
32     * A local principal path. The server will do its best to locate the
33     * principal uri based on the given uri. If we could find a local matching
34     * principal uri, this property will contain the value.
35     *
36     * @var string|null
37     */
38    public $principal;
39
40    /**
41     * A list of WebDAV properties that describe the sharee. This might for
42     * example contain a {DAV:}displayname with the real name of the user.
43     *
44     * @var array
45     */
46    public $properties = [];
47
48    /**
49     * Share access level. One of the Sabre\DAV\Sharing\Plugin::ACCESS
50     * constants.
51     *
52     * Can be one of:
53     *
54     * ACCESS_READ
55     * ACCESS_READWRITE
56     * ACCESS_SHAREDOWNER
57     * ACCESS_NOACCESS
58     *
59     * depending on context.
60     *
61     * @var int
62     */
63    public $access;
64
65    /**
66     * When a sharee is originally invited to a share, the sharer may add
67     * a comment. This will be placed in this property.
68     *
69     * @var string
70     */
71    public $comment;
72
73    /**
74     * The status of the invite, should be one of the
75     * Sabre\DAV\Sharing\Plugin::INVITE constants.
76     *
77     * @var int
78     */
79    public $inviteStatus;
80
81    /**
82     * Creates the object
83     *
84     * $properties will be used to populate all internal properties.
85     *
86     * @param array $properties
87     */
88    function __construct(array $properties = []) {
89
90        foreach ($properties as $k => $v) {
91
92            if (property_exists($this, $k)) {
93                $this->$k = $v;
94            } else {
95                throw new \InvalidArgumentException('Unknown property: ' . $k);
96            }
97
98        }
99
100    }
101
102    /**
103     * The xmlSerialize method is called during xml writing.
104     *
105     * Use the $writer argument to write its own xml serialization.
106     *
107     * An important note: do _not_ create a parent element. Any element
108     * implementing XmlSerializable should only ever write what's considered
109     * its 'inner xml'.
110     *
111     * The parent of the current element is responsible for writing a
112     * containing element.
113     *
114     * This allows serializers to be re-used for different element names.
115     *
116     * If you are opening new elements, you must also close them again.
117     *
118     * @param Writer $writer
119     * @return void
120     */
121    function xmlSerialize(Writer $writer) {
122
123
124        $writer->write([
125            new Href($this->href),
126            '{DAV:}prop'         => $this->properties,
127            '{DAV:}share-access' => new ShareAccess($this->access),
128        ]);
129        switch ($this->inviteStatus) {
130            case Plugin::INVITE_NORESPONSE :
131                $writer->writeElement('{DAV:}invite-noresponse');
132                break;
133            case Plugin::INVITE_ACCEPTED :
134                $writer->writeElement('{DAV:}invite-accepted');
135                break;
136            case Plugin::INVITE_DECLINED :
137                $writer->writeElement('{DAV:}invite-declined');
138                break;
139            case Plugin::INVITE_INVALID :
140                $writer->writeElement('{DAV:}invite-invalid');
141                break;
142        }
143
144    }
145
146    /**
147     * The deserialize method is called during xml parsing.
148     *
149     * This method is called statically, this is because in theory this method
150     * may be used as a type of constructor, or factory method.
151     *
152     * Often you want to return an instance of the current class, but you are
153     * free to return other data as well.
154     *
155     * You are responsible for advancing the reader to the next element. Not
156     * doing anything will result in a never-ending loop.
157     *
158     * If you just want to skip parsing for this element altogether, you can
159     * just call $reader->next();
160     *
161     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
162     * the next element.
163     *
164     * @param Reader $reader
165     * @return mixed
166     */
167    static function xmlDeserialize(Reader $reader) {
168
169        // Temporarily override configuration
170        $reader->pushContext();
171        $reader->elementMap['{DAV:}share-access'] = 'Sabre\DAV\Xml\Property\ShareAccess';
172        $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\keyValue';
173
174        $elems = Deserializer\keyValue($reader, 'DAV:');
175
176        // Restore previous configuration
177        $reader->popContext();
178
179        $sharee = new self();
180        if (!isset($elems['href'])) {
181            throw new BadRequest('Every {DAV:}sharee must have a {DAV:}href child-element');
182        }
183        $sharee->href = $elems['href'];
184
185        if (isset($elems['prop'])) {
186            $sharee->properties = $elems['prop'];
187        }
188        if (isset($elems['comment'])) {
189            $sharee->comment = $elems['comment'];
190        }
191        if (!isset($elems['share-access'])) {
192            throw new BadRequest('Every {DAV:}sharee must have a {DAV:}share-access child element');
193        }
194        $sharee->access = $elems['share-access']->getValue();
195        return $sharee;
196
197    }
198
199}
200