Skip to content

Commit fe09b0b

Browse files
icewind1991phil-davis
authored andcommitted
fix: getNodeForPath caching (#1545)
* fix getNodeForPath caching * add test that cached parent nodes are used in Tree::getNodeForPath
1 parent 36431ec commit fe09b0b

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

lib/DAV/Tree.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,21 @@ public function getNodeForPath($path)
6262
return $this->rootNode;
6363
}
6464

65-
$parts = explode('/', $path);
6665
$node = $this->rootNode;
6766

67+
// look for any cached parent and collect the parts below the parent
68+
$parts = [];
69+
$remainingPath = $path;
70+
do {
71+
list($remainingPath, $baseName) = Uri\split($remainingPath);
72+
array_unshift($parts, $baseName);
73+
74+
if (isset($this->cache[$remainingPath])) {
75+
$node = $this->cache[$remainingPath];
76+
break;
77+
}
78+
} while ('' !== $remainingPath);
79+
6880
while (count($parts)) {
6981
if (!($node instanceof ICollection)) {
7082
throw new Exception\NotFound('Could not find node at path: '.$path);

tests/Sabre/DAV/TreeTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ public function testGetSubTreeNode()
107107
$this->assertInstanceOf(INode::class, $tree->getNodeForPath('subtree/sub/1'));
108108
$this->assertInstanceOf(INode::class, $tree->getNodeForPath('subtree/2/3'));
109109
}
110+
111+
public function testGetNodeCacheParent()
112+
{
113+
$tree = new TreeMock();
114+
115+
/** @var TreeDirectoryTester $root */
116+
$root = $tree->getNodeForPath('');
117+
$root->createDirectory('new');
118+
$parent = $tree->getNodeForPath('new');
119+
$parent->createDirectory('child');
120+
121+
// make it so we can't create the 'new' folder again
122+
unset($root->newDirectories['new']);
123+
124+
// we should still be able to query child items from the 'new' folder because it is cached in the tree
125+
$this->assertInstanceOf(INode::class, $tree->getNodeForPath('new/child'));
126+
}
110127
}
111128

112129
class TreeMock extends Tree

0 commit comments

Comments
 (0)