1<?php
2
3declare(strict_types=1);
4
5namespace Sabre\DAV\Xml\Property;
6
7use Sabre\DAV;
8use Sabre\DAV\Locks\LockInfo;
9use Sabre\Xml\Element\XmlFragment;
10use Sabre\Xml\Writer;
11use Sabre\Xml\XmlSerializable;
12
13/**
14 * Represents {DAV:}lockdiscovery property.
15 *
16 * This property is defined here:
17 * http://tools.ietf.org/html/rfc4918#section-15.8
18 *
19 * This property contains all the open locks on a given resource
20 *
21 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
22 * @author Evert Pot (http://www.rooftopsolutions.nl/)
23 * @license http://sabre.io/license/ Modified BSD License
24 */
25class LockDiscovery implements XmlSerializable
26{
27    /**
28     * locks.
29     *
30     * @var LockInfo[]
31     */
32    public $locks;
33
34    /**
35     * Hides the {DAV:}lockroot element from the response.
36     *
37     * It was reported that showing the lockroot in the response can break
38     * Office 2000 compatibility.
39     *
40     * @var bool
41     */
42    public static $hideLockRoot = false;
43
44    /**
45     * __construct.
46     *
47     * @param LockInfo[] $locks
48     */
49    public function __construct($locks)
50    {
51        $this->locks = $locks;
52    }
53
54    /**
55     * The serialize method is called during xml writing.
56     *
57     * It should use the $writer argument to encode this object into XML.
58     *
59     * Important note: it is not needed to create the parent element. The
60     * parent element is already created, and we only have to worry about
61     * attributes, child elements and text (if any).
62     *
63     * Important note 2: If you are writing any new elements, you are also
64     * responsible for closing them.
65     */
66    public function xmlSerialize(Writer $writer)
67    {
68        foreach ($this->locks as $lock) {
69            $writer->startElement('{DAV:}activelock');
70
71            $writer->startElement('{DAV:}lockscope');
72            if (LockInfo::SHARED === $lock->scope) {
73                $writer->writeElement('{DAV:}shared');
74            } else {
75                $writer->writeElement('{DAV:}exclusive');
76            }
77
78            $writer->endElement(); // {DAV:}lockscope
79
80            $writer->startElement('{DAV:}locktype');
81            $writer->writeElement('{DAV:}write');
82            $writer->endElement(); // {DAV:}locktype
83
84            if (!self::$hideLockRoot) {
85                $writer->startElement('{DAV:}lockroot');
86                $writer->writeElement('{DAV:}href', $writer->contextUri.$lock->uri);
87                $writer->endElement(); // {DAV:}lockroot
88            }
89            $writer->writeElement('{DAV:}depth', (DAV\Server::DEPTH_INFINITY == $lock->depth ? 'infinity' : $lock->depth));
90            $writer->writeElement('{DAV:}timeout', (LockInfo::TIMEOUT_INFINITE === $lock->timeout ? 'Infinite' : 'Second-'.$lock->timeout));
91
92            // optional according to https://tools.ietf.org/html/rfc4918#section-6.5
93            if (null !== $lock->token && '' !== $lock->token) {
94                $writer->startElement('{DAV:}locktoken');
95                $writer->writeElement('{DAV:}href', 'opaquelocktoken:'.$lock->token);
96                $writer->endElement(); // {DAV:}locktoken
97            }
98
99            if ($lock->owner) {
100                $writer->writeElement('{DAV:}owner', new XmlFragment($lock->owner));
101            }
102            $writer->endElement(); // {DAV:}activelock
103        }
104    }
105}
106