1<?php
2
3namespace Sabre\DAV\Xml\Property;
4
5use Sabre\DAV\Browser\HtmlOutput;
6use Sabre\DAV\Browser\HtmlOutputHelper;
7use Sabre\Uri;
8use Sabre\Xml\Element;
9use Sabre\Xml\Reader;
10use Sabre\Xml\Writer;
11
12/**
13 * Href property
14 *
15 * This class represents any WebDAV property that contains a {DAV:}href
16 * element, and there are many.
17 *
18 * It can support either 1 or more hrefs. If while unserializing no valid
19 * {DAV:}href elements were found, this property will unserialize itself as
20 * null.
21 *
22 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
23 * @author Evert Pot (http://www.rooftopsolutions.nl/)
24 * @license http://sabre.io/license/ Modified BSD License
25 */
26class Href implements Element, HtmlOutput {
27
28    /**
29     * List of uris
30     *
31     * @var array
32     */
33    protected $hrefs;
34
35    /**
36     * Constructor
37     *
38     * You must either pass a string for a single href, or an array of hrefs.
39     *
40     * If auto-prefix is set to false, the hrefs will be treated as absolute
41     * and not relative to the servers base uri.
42     *
43     * @param string|string[] $hrefs
44     */
45    function __construct($hrefs) {
46
47        if (is_string($hrefs)) {
48            $hrefs = [$hrefs];
49        }
50        $this->hrefs = $hrefs;
51
52    }
53
54    /**
55     * Returns the first Href.
56     *
57     * @return string
58     */
59    function getHref() {
60
61        return $this->hrefs[0];
62
63    }
64
65    /**
66     * Returns the hrefs as an array
67     *
68     * @return array
69     */
70    function getHrefs() {
71
72        return $this->hrefs;
73
74    }
75
76    /**
77     * The xmlSerialize method is called during xml writing.
78     *
79     * Use the $writer argument to write its own xml serialization.
80     *
81     * An important note: do _not_ create a parent element. Any element
82     * implementing XmlSerializable should only ever write what's considered
83     * its 'inner xml'.
84     *
85     * The parent of the current element is responsible for writing a
86     * containing element.
87     *
88     * This allows serializers to be re-used for different element names.
89     *
90     * If you are opening new elements, you must also close them again.
91     *
92     * @param Writer $writer
93     * @return void
94     */
95    function xmlSerialize(Writer $writer) {
96
97        foreach ($this->getHrefs() as $href) {
98            $href = Uri\resolve($writer->contextUri, $href);
99            $writer->writeElement('{DAV:}href', $href);
100        }
101
102    }
103
104    /**
105     * Generate html representation for this value.
106     *
107     * The html output is 100% trusted, and no effort is being made to sanitize
108     * it. It's up to the implementor to sanitize user provided values.
109     *
110     * The output must be in UTF-8.
111     *
112     * The baseUri parameter is a url to the root of the application, and can
113     * be used to construct local links.
114     *
115     * @param HtmlOutputHelper $html
116     * @return string
117     */
118    function toHtml(HtmlOutputHelper $html) {
119
120        $links = [];
121        foreach ($this->getHrefs() as $href) {
122            $links[] = $html->link($href);
123        }
124        return implode('<br />', $links);
125
126    }
127
128    /**
129     * The deserialize method is called during xml parsing.
130     *
131     * This method is called statically, this is because in theory this method
132     * may be used as a type of constructor, or factory method.
133     *
134     * Often you want to return an instance of the current class, but you are
135     * free to return other data as well.
136     *
137     * You are responsible for advancing the reader to the next element. Not
138     * doing anything will result in a never-ending loop.
139     *
140     * If you just want to skip parsing for this element altogether, you can
141     * just call $reader->next();
142     *
143     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
144     * the next element.
145     *
146     * @param Reader $reader
147     * @return mixed
148     */
149    static function xmlDeserialize(Reader $reader) {
150
151        $hrefs = [];
152        foreach ((array)$reader->parseInnerTree() as $elem) {
153            if ($elem['name'] !== '{DAV:}href')
154                continue;
155
156            $hrefs[] = $elem['value'];
157
158        }
159        if ($hrefs) {
160            return new self($hrefs, false);
161        }
162
163    }
164
165}
166