1<?php
2
3namespace Sabre\DAV\Property;
4
5use Sabre\DAV;
6
7/**
8 * Response property
9 *
10 * This class represents the {DAV:}response XML element.
11 * This is used by the Server class to encode individual items within a multistatus
12 * response.
13 *
14 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
15 * @author Evert Pot (http://evertpot.com/)
16 * @license http://sabre.io/license/ Modified BSD License
17 */
18class Response extends DAV\Property implements IHref {
19
20    /**
21     * Url for the response
22     *
23     * @var string
24     */
25    private $href;
26
27    /**
28     * Propertylist, ordered by HTTP status code
29     *
30     * @var array
31     */
32    private $responseProperties;
33
34    /**
35     * The responseProperties argument is a list of properties
36     * within an array with keys representing HTTP status codes
37     *
38     * @param string $href
39     * @param array $responseProperties
40     */
41    public function __construct($href, array $responseProperties) {
42
43        $this->href = $href;
44        $this->responseProperties = $responseProperties;
45
46    }
47
48    /**
49     * Returns the url
50     *
51     * @return string
52     */
53    public function getHref() {
54
55        return $this->href;
56
57    }
58
59    /**
60     * Returns the property list
61     *
62     * @return array
63     */
64    public function getResponseProperties() {
65
66        return $this->responseProperties;
67
68    }
69
70    /**
71     * serialize
72     *
73     * @param DAV\Server $server
74     * @param \DOMElement $dom
75     * @return void
76     */
77    public function serialize(DAV\Server $server, \DOMElement $dom) {
78
79        $document = $dom->ownerDocument;
80        $properties = $this->responseProperties;
81
82        $xresponse = $document->createElement('d:response');
83        $dom->appendChild($xresponse);
84
85        $uri = DAV\URLUtil::encodePath($this->href);
86
87        // Adding the baseurl to the beginning of the url
88        $uri = $server->getBaseUri() . $uri;
89
90        $xresponse->appendChild($document->createElement('d:href',$uri));
91
92        // The properties variable is an array containing properties, grouped by
93        // HTTP status
94        foreach($properties as $httpStatus=>$propertyGroup) {
95
96            // The 'href' is also in this array, and it's special cased.
97            // We will ignore it
98            if ($httpStatus=='href') continue;
99
100            // If there are no properties in this group, we can also just carry on
101            if (!count($propertyGroup)) continue;
102
103            $xpropstat = $document->createElement('d:propstat');
104            $xresponse->appendChild($xpropstat);
105
106            $xprop = $document->createElement('d:prop');
107            $xpropstat->appendChild($xprop);
108
109            $nsList = $server->xmlNamespaces;
110
111            foreach($propertyGroup as $propertyName=>$propertyValue) {
112
113                $propName = null;
114                preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
115
116                // special case for empty namespaces
117                if ($propName[1]=='') {
118
119                    $currentProperty = $document->createElement($propName[2]);
120                    $xprop->appendChild($currentProperty);
121                    $currentProperty->setAttribute('xmlns','');
122
123                } else {
124
125                    if (!isset($nsList[$propName[1]])) {
126                        $nsList[$propName[1]] = 'x' . count($nsList);
127                    }
128
129                    // If the namespace was defined in the top-level xml namespaces, it means
130                    // there was already a namespace declaration, and we don't have to worry about it.
131                    if (isset($server->xmlNamespaces[$propName[1]])) {
132                        $currentProperty = $document->createElement($nsList[$propName[1]] . ':' . $propName[2]);
133                    } else {
134                        $currentProperty = $document->createElementNS($propName[1],$nsList[$propName[1]].':' . $propName[2]);
135                    }
136                    $xprop->appendChild($currentProperty);
137
138                }
139
140                if (is_scalar($propertyValue)) {
141                    $text = $document->createTextNode($propertyValue);
142                    $currentProperty->appendChild($text);
143                } elseif ($propertyValue instanceof DAV\PropertyInterface) {
144                    $propertyValue->serialize($server,$currentProperty);
145                } elseif (!is_null($propertyValue)) {
146                    throw new DAV\Exception('Unknown property value type: ' . gettype($propertyValue) . ' for property: ' . $propertyName);
147                }
148
149            }
150
151            $xpropstat->appendChild($document->createElement('d:status',$server->httpResponse->getStatusMessage($httpStatus)));
152
153        }
154
155    }
156
157}
158