ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Tree.php
Go to the documentation of this file.
1<?php
2
3namespace Sabre\DAV;
4
6
17class Tree {
18
24 protected $rootNode;
25
32 protected $cache = [];
33
42
43 $this->rootNode = $rootNode;
44
45 }
46
54
55 $path = trim($path, '/');
56 if (isset($this->cache[$path])) return $this->cache[$path];
57
58 // Is it the root node?
59 if (!strlen($path)) {
60 return $this->rootNode;
61 }
62
63 // Attempting to fetch its parent
64 list($parentName, $baseName) = URLUtil::splitPath($path);
65
66 // If there was no parent, we must simply ask it from the root node.
67 if ($parentName === "") {
68 $node = $this->rootNode->getChild($baseName);
69 } else {
70 // Otherwise, we recursively grab the parent and ask him/her.
71 $parent = $this->getNodeForPath($parentName);
72
73 if (!($parent instanceof ICollection))
74 throw new Exception\NotFound('Could not find node at path: ' . $path);
75
76 $node = $parent->getChild($baseName);
77
78 }
79
80 $this->cache[$path] = $node;
81 return $node;
82
83 }
84
94 function nodeExists($path) {
95
96 try {
97
98 // The root always exists
99 if ($path === '') return true;
100
101 list($parent, $base) = URLUtil::splitPath($path);
102
103 $parentNode = $this->getNodeForPath($parent);
104 if (!$parentNode instanceof ICollection) return false;
105 return $parentNode->childExists($base);
106
107 } catch (Exception\NotFound $e) {
108
109 return false;
110
111 }
112
113 }
114
122 function copy($sourcePath, $destinationPath) {
123
124 $sourceNode = $this->getNodeForPath($sourcePath);
125
126 // grab the dirname and basename components
127 list($destinationDir, $destinationName) = URLUtil::splitPath($destinationPath);
128
129 $destinationParent = $this->getNodeForPath($destinationDir);
130 $this->copyNode($sourceNode, $destinationParent, $destinationName);
131
132 $this->markDirty($destinationDir);
133
134 }
135
143 function move($sourcePath, $destinationPath) {
144
145 list($sourceDir) = URLUtil::splitPath($sourcePath);
146 list($destinationDir, $destinationName) = URLUtil::splitPath($destinationPath);
147
148 if ($sourceDir === $destinationDir) {
149 // If this is a 'local' rename, it means we can just trigger a rename.
150 $sourceNode = $this->getNodeForPath($sourcePath);
151 $sourceNode->setName($destinationName);
152 } else {
153 $newParentNode = $this->getNodeForPath($destinationDir);
154 $moveSuccess = false;
155 if ($newParentNode instanceof IMoveTarget) {
156 // The target collection may be able to handle the move
157 $sourceNode = $this->getNodeForPath($sourcePath);
158 $moveSuccess = $newParentNode->moveInto($destinationName, $sourcePath, $sourceNode);
159 }
160 if (!$moveSuccess) {
161 $this->copy($sourcePath, $destinationPath);
162 $this->getNodeForPath($sourcePath)->delete();
163 }
164 }
165 $this->markDirty($sourceDir);
166 $this->markDirty($destinationDir);
167
168 }
169
176 function delete($path) {
177
178 $node = $this->getNodeForPath($path);
179 $node->delete();
180
181 list($parent) = URLUtil::splitPath($path);
182 $this->markDirty($parent);
183
184 }
185
192 function getChildren($path) {
193
194 $node = $this->getNodeForPath($path);
195 $children = $node->getChildren();
196 $basePath = trim($path, '/');
197 if ($basePath !== '') $basePath .= '/';
198
199 foreach ($children as $child) {
200
201 $this->cache[$basePath . $child->getName()] = $child;
202
203 }
204 return $children;
205
206 }
207
226 function markDirty($path) {
227
228 // We don't care enough about sub-paths
229 // flushing the entire cache
230 $path = trim($path, '/');
231 foreach ($this->cache as $nodePath => $node) {
232 if ($path === '' || $nodePath == $path || strpos($nodePath, $path . '/') === 0)
233 unset($this->cache[$nodePath]);
234
235 }
236
237 }
238
254
255 // Finding common parents
256 $parents = [];
257 foreach ($paths as $path) {
258 list($parent, $node) = URLUtil::splitPath($path);
259 if (!isset($parents[$parent])) {
260 $parents[$parent] = [$node];
261 } else {
262 $parents[$parent][] = $node;
263 }
264 }
265
266 $result = [];
267
268 foreach ($parents as $parent => $children) {
269
270 $parentNode = $this->getNodeForPath($parent);
271 if ($parentNode instanceof IMultiGet) {
272 foreach ($parentNode->getMultipleChildren($children) as $childNode) {
273 $fullPath = $parent . '/' . $childNode->getName();
274 $result[$fullPath] = $childNode;
275 $this->cache[$fullPath] = $childNode;
276 }
277 } else {
278 foreach ($children as $child) {
279 $fullPath = $parent . '/' . $child;
280 $result[$fullPath] = $this->getNodeForPath($fullPath);
281 }
282 }
283
284 }
285
286 return $result;
287
288 }
289
290
299 protected function copyNode(INode $source, ICollection $destinationParent, $destinationName = null) {
300
301 if (!$destinationName) $destinationName = $source->getName();
302
303 if ($source instanceof IFile) {
304
305 $data = $source->get();
306
307 // If the body was a string, we need to convert it to a stream
308 if (is_string($data)) {
309 $stream = fopen('php://temp', 'r+');
310 fwrite($stream, $data);
311 rewind($stream);
312 $data = $stream;
313 }
314 $destinationParent->createFile($destinationName, $data);
315 $destination = $destinationParent->getChild($destinationName);
316
317 } elseif ($source instanceof ICollection) {
318
319 $destinationParent->createDirectory($destinationName);
320
321 $destination = $destinationParent->getChild($destinationName);
322 foreach ($source->getChildren() as $child) {
323
324 $this->copyNode($child, $destination);
325
326 }
327
328 }
329 if ($source instanceof IProperties && $destination instanceof IProperties) {
330
331 $props = $source->getProperties([]);
332 $propPatch = new PropPatch($props);
333 $destination->propPatch($propPatch);
334 $propPatch->commit();
335
336 }
337
338 }
339
340}
$result
$path
Definition: aliased.php:25
$source
Definition: linkback.php:22
$sourceDir
Definition: buildPhar.php:15
An exception for terminatinating execution or to throw for unit testing.
Main Exception class.
Definition: Exception.php:18
This class represents a set of properties that are going to be updated.
Definition: PropPatch.php:20
The tree object is responsible for basic tree operations.
Definition: Tree.php:17
getChildren($path)
Returns a list of childnodes for a given path.
Definition: Tree.php:192
copy($sourcePath, $destinationPath)
Copies a file from path to another.
Definition: Tree.php:122
__construct(ICollection $rootNode)
Creates the object.
Definition: Tree.php:41
getMultipleNodes($paths)
This method tells the tree system to pre-fetch and cache a list of children of a single parent.
Definition: Tree.php:253
getNodeForPath($path)
Returns the INode object for the requested path.
Definition: Tree.php:53
markDirty($path)
This method is called with every tree update.
Definition: Tree.php:226
copyNode(INode $source, ICollection $destinationParent, $destinationName=null)
copyNode
Definition: Tree.php:299
nodeExists($path)
This function allows you to check if a node exists.
Definition: Tree.php:94
move($sourcePath, $destinationPath)
Moves a file from one location to another.
Definition: Tree.php:143
URL utility class.
Definition: URLUtil.php:18
static splitPath($path)
Returns the 'dirname' and 'basename' for a path.
Definition: URLUtil.php:83
The ICollection Interface.
Definition: ICollection.php:14
getChild($name)
Returns a specific child node, referenced by its name.
createDirectory($name)
Creates a new subdirectory.
createFile($name, $data=null)
Creates a new file in the directory.
This interface represents a file in the directory tree.
Definition: IFile.php:16
By implementing this interface, a collection can effectively say "other nodes may be moved into this ...
Definition: IMoveTarget.php:20
The INode interface is the base interface, and the parent class of both ICollection and IFile.
Definition: INode.php:12
IProperties interface.
Definition: IProperties.php:14
$base
Definition: index.php:4
$destination
if($argc< 2) $paths
Definition: migrateto20.php:44
$stream
PHP stream implementation.
$data
Definition: bench.php:6