xref: /plugin/davcal/vendor/sabre/dav/lib/DAV/FSExt/Directory.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAV\FSExt;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV;
6*a1a3b679SAndreas Boehleruse Sabre\DAV\FS\Node;
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehler/**
9*a1a3b679SAndreas Boehler * Directory class
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 Directory extends Node implements DAV\ICollection, DAV\IQuota, DAV\IMoveTarget {
16*a1a3b679SAndreas Boehler
17*a1a3b679SAndreas Boehler    /**
18*a1a3b679SAndreas Boehler     * Creates a new file in the directory
19*a1a3b679SAndreas Boehler     *
20*a1a3b679SAndreas Boehler     * Data will either be supplied as a stream resource, or in certain cases
21*a1a3b679SAndreas Boehler     * as a string. Keep in mind that you may have to support either.
22*a1a3b679SAndreas Boehler     *
23*a1a3b679SAndreas Boehler     * After successful creation of the file, you may choose to return the ETag
24*a1a3b679SAndreas Boehler     * of the new file here.
25*a1a3b679SAndreas Boehler     *
26*a1a3b679SAndreas Boehler     * The returned ETag must be surrounded by double-quotes (The quotes should
27*a1a3b679SAndreas Boehler     * be part of the actual string).
28*a1a3b679SAndreas Boehler     *
29*a1a3b679SAndreas Boehler     * If you cannot accurately determine the ETag, you should not return it.
30*a1a3b679SAndreas Boehler     * If you don't store the file exactly as-is (you're transforming it
31*a1a3b679SAndreas Boehler     * somehow) you should also not return an ETag.
32*a1a3b679SAndreas Boehler     *
33*a1a3b679SAndreas Boehler     * This means that if a subsequent GET to this new file does not exactly
34*a1a3b679SAndreas Boehler     * return the same contents of what was submitted here, you are strongly
35*a1a3b679SAndreas Boehler     * recommended to omit the ETag.
36*a1a3b679SAndreas Boehler     *
37*a1a3b679SAndreas Boehler     * @param string $name Name of the file
38*a1a3b679SAndreas Boehler     * @param resource|string $data Initial payload
39*a1a3b679SAndreas Boehler     * @return null|string
40*a1a3b679SAndreas Boehler     */
41*a1a3b679SAndreas Boehler    function createFile($name, $data = null) {
42*a1a3b679SAndreas Boehler
43*a1a3b679SAndreas Boehler        // We're not allowing dots
44*a1a3b679SAndreas Boehler        if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..');
45*a1a3b679SAndreas Boehler        $newPath = $this->path . '/' . $name;
46*a1a3b679SAndreas Boehler        file_put_contents($newPath, $data);
47*a1a3b679SAndreas Boehler        clearstatcache(true, $newPath);
48*a1a3b679SAndreas Boehler
49*a1a3b679SAndreas Boehler        return '"' . sha1(
50*a1a3b679SAndreas Boehler            fileinode($newPath) .
51*a1a3b679SAndreas Boehler            filesize($newPath) .
52*a1a3b679SAndreas Boehler            filemtime($newPath)
53*a1a3b679SAndreas Boehler        ) . '"';
54*a1a3b679SAndreas Boehler
55*a1a3b679SAndreas Boehler    }
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler    /**
58*a1a3b679SAndreas Boehler     * Creates a new subdirectory
59*a1a3b679SAndreas Boehler     *
60*a1a3b679SAndreas Boehler     * @param string $name
61*a1a3b679SAndreas Boehler     * @return void
62*a1a3b679SAndreas Boehler     */
63*a1a3b679SAndreas Boehler    function createDirectory($name) {
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler        // We're not allowing dots
66*a1a3b679SAndreas Boehler        if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..');
67*a1a3b679SAndreas Boehler        $newPath = $this->path . '/' . $name;
68*a1a3b679SAndreas Boehler        mkdir($newPath);
69*a1a3b679SAndreas Boehler        clearstatcache(true, $newPath);
70*a1a3b679SAndreas Boehler
71*a1a3b679SAndreas Boehler    }
72*a1a3b679SAndreas Boehler
73*a1a3b679SAndreas Boehler    /**
74*a1a3b679SAndreas Boehler     * Returns a specific child node, referenced by its name
75*a1a3b679SAndreas Boehler     *
76*a1a3b679SAndreas Boehler     * This method must throw Sabre\DAV\Exception\NotFound if the node does not
77*a1a3b679SAndreas Boehler     * exist.
78*a1a3b679SAndreas Boehler     *
79*a1a3b679SAndreas Boehler     * @param string $name
80*a1a3b679SAndreas Boehler     * @throws DAV\Exception\NotFound
81*a1a3b679SAndreas Boehler     * @return DAV\INode
82*a1a3b679SAndreas Boehler     */
83*a1a3b679SAndreas Boehler    function getChild($name) {
84*a1a3b679SAndreas Boehler
85*a1a3b679SAndreas Boehler        $path = $this->path . '/' . $name;
86*a1a3b679SAndreas Boehler
87*a1a3b679SAndreas Boehler        if (!file_exists($path)) throw new DAV\Exception\NotFound('File could not be located');
88*a1a3b679SAndreas Boehler        if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..');
89*a1a3b679SAndreas Boehler
90*a1a3b679SAndreas Boehler        if (is_dir($path)) {
91*a1a3b679SAndreas Boehler
92*a1a3b679SAndreas Boehler            return new self($path);
93*a1a3b679SAndreas Boehler
94*a1a3b679SAndreas Boehler        } else {
95*a1a3b679SAndreas Boehler
96*a1a3b679SAndreas Boehler            return new File($path);
97*a1a3b679SAndreas Boehler
98*a1a3b679SAndreas Boehler        }
99*a1a3b679SAndreas Boehler
100*a1a3b679SAndreas Boehler    }
101*a1a3b679SAndreas Boehler
102*a1a3b679SAndreas Boehler    /**
103*a1a3b679SAndreas Boehler     * Checks if a child exists.
104*a1a3b679SAndreas Boehler     *
105*a1a3b679SAndreas Boehler     * @param string $name
106*a1a3b679SAndreas Boehler     * @return bool
107*a1a3b679SAndreas Boehler     */
108*a1a3b679SAndreas Boehler    function childExists($name) {
109*a1a3b679SAndreas Boehler
110*a1a3b679SAndreas Boehler        if ($name == '.' || $name == '..')
111*a1a3b679SAndreas Boehler            throw new DAV\Exception\Forbidden('Permission denied to . and ..');
112*a1a3b679SAndreas Boehler
113*a1a3b679SAndreas Boehler        $path = $this->path . '/' . $name;
114*a1a3b679SAndreas Boehler        return file_exists($path);
115*a1a3b679SAndreas Boehler
116*a1a3b679SAndreas Boehler    }
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler    /**
119*a1a3b679SAndreas Boehler     * Returns an array with all the child nodes
120*a1a3b679SAndreas Boehler     *
121*a1a3b679SAndreas Boehler     * @return DAV\INode[]
122*a1a3b679SAndreas Boehler     */
123*a1a3b679SAndreas Boehler    function getChildren() {
124*a1a3b679SAndreas Boehler
125*a1a3b679SAndreas Boehler        $nodes = [];
126*a1a3b679SAndreas Boehler        $iterator = new \FilesystemIterator(
127*a1a3b679SAndreas Boehler            $this->path,
128*a1a3b679SAndreas Boehler            \FilesystemIterator::CURRENT_AS_SELF
129*a1a3b679SAndreas Boehler          | \FilesystemIterator::SKIP_DOTS
130*a1a3b679SAndreas Boehler        );
131*a1a3b679SAndreas Boehler
132*a1a3b679SAndreas Boehler        foreach ($iterator as $entry) {
133*a1a3b679SAndreas Boehler
134*a1a3b679SAndreas Boehler            $node = $entry->getFilename();
135*a1a3b679SAndreas Boehler
136*a1a3b679SAndreas Boehler            if ($node === '.sabredav')
137*a1a3b679SAndreas Boehler                continue;
138*a1a3b679SAndreas Boehler
139*a1a3b679SAndreas Boehler            $nodes[] = $this->getChild($node);
140*a1a3b679SAndreas Boehler
141*a1a3b679SAndreas Boehler        }
142*a1a3b679SAndreas Boehler        return $nodes;
143*a1a3b679SAndreas Boehler
144*a1a3b679SAndreas Boehler    }
145*a1a3b679SAndreas Boehler
146*a1a3b679SAndreas Boehler    /**
147*a1a3b679SAndreas Boehler     * Deletes all files in this directory, and then itself
148*a1a3b679SAndreas Boehler     *
149*a1a3b679SAndreas Boehler     * @return bool
150*a1a3b679SAndreas Boehler     */
151*a1a3b679SAndreas Boehler    function delete() {
152*a1a3b679SAndreas Boehler
153*a1a3b679SAndreas Boehler        // Deleting all children
154*a1a3b679SAndreas Boehler        foreach ($this->getChildren() as $child) $child->delete();
155*a1a3b679SAndreas Boehler
156*a1a3b679SAndreas Boehler        // Removing resource info, if its still around
157*a1a3b679SAndreas Boehler        if (file_exists($this->path . '/.sabredav')) unlink($this->path . '/.sabredav');
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler        // Removing the directory itself
160*a1a3b679SAndreas Boehler        rmdir($this->path);
161*a1a3b679SAndreas Boehler
162*a1a3b679SAndreas Boehler        return true;
163*a1a3b679SAndreas Boehler
164*a1a3b679SAndreas Boehler    }
165*a1a3b679SAndreas Boehler
166*a1a3b679SAndreas Boehler    /**
167*a1a3b679SAndreas Boehler     * Returns available diskspace information
168*a1a3b679SAndreas Boehler     *
169*a1a3b679SAndreas Boehler     * @return array
170*a1a3b679SAndreas Boehler     */
171*a1a3b679SAndreas Boehler    function getQuotaInfo() {
172*a1a3b679SAndreas Boehler
173*a1a3b679SAndreas Boehler        $total = disk_total_space(realpath($this->path));
174*a1a3b679SAndreas Boehler        $free = disk_free_space(realpath($this->path));
175*a1a3b679SAndreas Boehler
176*a1a3b679SAndreas Boehler        return [
177*a1a3b679SAndreas Boehler            $total - $free,
178*a1a3b679SAndreas Boehler            $free
179*a1a3b679SAndreas Boehler        ];
180*a1a3b679SAndreas Boehler    }
181*a1a3b679SAndreas Boehler
182*a1a3b679SAndreas Boehler    /**
183*a1a3b679SAndreas Boehler     * Moves a node into this collection.
184*a1a3b679SAndreas Boehler     *
185*a1a3b679SAndreas Boehler     * It is up to the implementors to:
186*a1a3b679SAndreas Boehler     *   1. Create the new resource.
187*a1a3b679SAndreas Boehler     *   2. Remove the old resource.
188*a1a3b679SAndreas Boehler     *   3. Transfer any properties or other data.
189*a1a3b679SAndreas Boehler     *
190*a1a3b679SAndreas Boehler     * Generally you should make very sure that your collection can easily move
191*a1a3b679SAndreas Boehler     * the move.
192*a1a3b679SAndreas Boehler     *
193*a1a3b679SAndreas Boehler     * If you don't, just return false, which will trigger sabre/dav to handle
194*a1a3b679SAndreas Boehler     * the move itself. If you return true from this function, the assumption
195*a1a3b679SAndreas Boehler     * is that the move was successful.
196*a1a3b679SAndreas Boehler     *
197*a1a3b679SAndreas Boehler     * @param string $targetName New local file/collection name.
198*a1a3b679SAndreas Boehler     * @param string $sourcePath Full path to source node
199*a1a3b679SAndreas Boehler     * @param DAV\INode $sourceNode Source node itself
200*a1a3b679SAndreas Boehler     * @return bool
201*a1a3b679SAndreas Boehler     */
202*a1a3b679SAndreas Boehler    function moveInto($targetName, $sourcePath, DAV\INode $sourceNode) {
203*a1a3b679SAndreas Boehler
204*a1a3b679SAndreas Boehler        // We only support FSExt\Directory or FSExt\File objects, so
205*a1a3b679SAndreas Boehler        // anything else we want to quickly reject.
206*a1a3b679SAndreas Boehler        if (!$sourceNode instanceof self && !$sourceNode instanceof File) {
207*a1a3b679SAndreas Boehler            return false;
208*a1a3b679SAndreas Boehler        }
209*a1a3b679SAndreas Boehler
210*a1a3b679SAndreas Boehler        // PHP allows us to access protected properties from other objects, as
211*a1a3b679SAndreas Boehler        // long as they are defined in a class that has a shared inheritence
212*a1a3b679SAndreas Boehler        // with the current class.
213*a1a3b679SAndreas Boehler        rename($sourceNode->path, $this->path . '/' . $targetName);
214*a1a3b679SAndreas Boehler
215*a1a3b679SAndreas Boehler        return true;
216*a1a3b679SAndreas Boehler
217*a1a3b679SAndreas Boehler    }
218*a1a3b679SAndreas Boehler
219*a1a3b679SAndreas Boehler}
220