ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Tree.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\DAV;
4 
6 
17 class Tree {
18 
24  protected $rootNode;
25 
32  protected $cache = [];
33 
42 
43  $this->rootNode = $rootNode;
44 
45  }
46 
53  function getNodeForPath($path) {
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 }
nodeExists($path)
This function allows you to check if a node exists.
Definition: Tree.php:94
$path
Definition: aliased.php:25
getName()
Returns the name of the node.
This class represents a set of properties that are going to be updated.
Definition: PropPatch.php:20
$result
if($argc< 2) $paths
Definition: migrateto20.php:44
copy($sourcePath, $destinationPath)
Copies a file from path to another.
Definition: Tree.php:122
$destination
getNodeForPath($path)
Returns the INode object for the requested path.
Definition: Tree.php:53
$stream
PHP stream implementation.
The ICollection Interface.
Definition: ICollection.php:14
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
$base
Definition: index.php:4
By implementing this interface, a collection can effectively say "other nodes may be moved into this ...
Definition: IMoveTarget.php:20
$sourceDir
Definition: buildPhar.php:15
This interface represents a file in the directory tree.
Definition: IFile.php:16
The INode interface is the base interface, and the parent class of both ICollection and IFile...
Definition: INode.php:12
move($sourcePath, $destinationPath)
Moves a file from one location to another.
Definition: Tree.php:143
getChildren($path)
Returns a list of childnodes for a given path.
Definition: Tree.php:192
IProperties interface.
Definition: IProperties.php:14
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
createFile($name, $data=null)
Creates a new file in the directory.
$source
Definition: linkback.php:22
__construct(ICollection $rootNode)
Creates the object.
Definition: Tree.php:41
createDirectory($name)
Creates a new subdirectory.
getChild($name)
Returns a specific child node, referenced by its name.
static splitPath($path)
Returns the &#39;dirname&#39; and &#39;basename&#39; for a path.
Definition: URLUtil.php:83
The tree object is responsible for basic tree operations.
Definition: Tree.php:17
$data
Definition: bench.php:6