summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/Files/View.php15
-rw-r--r--tests/lib/Files/ViewTest.php71
2 files changed, 81 insertions, 5 deletions
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 67f89180994..3ce21a3489b 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -2104,14 +2104,19 @@ class View {
* @return bool
*/
private function createParentDirectories($filePath) {
- $parentDirectory = dirname($filePath);
- while(!$this->file_exists($parentDirectory)) {
- $result = $this->createParentDirectories($parentDirectory);
- if($result === false) {
+ $directoryParts = explode('/', $filePath);
+ $directoryParts = array_filter($directoryParts);
+ foreach($directoryParts as $key => $part) {
+ $currentPathElements = array_slice($directoryParts, 0, $key);
+ $currentPath = '/' . implode('/', $currentPathElements);
+ if($this->is_file($currentPath)) {
return false;
}
+ if(!$this->file_exists($currentPath)) {
+ $this->mkdir($currentPath);
+ }
}
- $this->mkdir($filePath);
+
return true;
}
}
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index 4c264472385..8ec9619087c 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -12,6 +12,7 @@ use OC\Files\Cache\Watcher;
use OC\Files\Storage\Common;
use OC\Files\Mount\MountPoint;
use OC\Files\Storage\Temporary;
+use OC\Files\View;
use OCP\Files\Config\IMountProvider;
use OCP\Files\FileInfo;
use OCP\Lock\ILockingProvider;
@@ -2499,4 +2500,74 @@ class ViewTest extends \Test\TestCase {
$this->assertNotEquals($rootInfo->getEtag(), $newInfo->getEtag());
$this->assertEquals(0, $newInfo->getSize());
}
+
+ public function testCreateParentDirectories() {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'is_file',
+ 'file_exists',
+ 'mkdir',
+ ])
+ ->getMock();
+
+ $view
+ ->expects($this->at(0))
+ ->method('is_file')
+ ->with('/new')
+ ->willReturn(false);
+ $view
+ ->expects($this->at(1))
+ ->method('file_exists')
+ ->with('/new')
+ ->willReturn(true);
+ $view
+ ->expects($this->at(2))
+ ->method('is_file')
+ ->with('/new/folder')
+ ->willReturn(false);
+ $view
+ ->expects($this->at(3))
+ ->method('file_exists')
+ ->with('/new/folder')
+ ->willReturn(false);
+ $view
+ ->expects($this->at(4))
+ ->method('mkdir')
+ ->with('/new/folder');
+ $view
+ ->expects($this->at(5))
+ ->method('is_file')
+ ->with('/new/folder/structure')
+ ->willReturn(false);
+ $view
+ ->expects($this->at(6))
+ ->method('file_exists')
+ ->with('/new/folder/structure')
+ ->willReturn(false);
+ $view
+ ->expects($this->at(7))
+ ->method('mkdir')
+ ->with('/new/folder/structure');
+
+ $this->assertTrue(self::invokePrivate($view, 'createParentDirectories', ['/new/folder/structure']));
+ }
+
+ public function testCreateParentDirectoriesWithExistingFile() {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'is_file',
+ 'file_exists',
+ 'mkdir',
+ ])
+ ->getMock();
+
+ $view
+ ->expects($this->once())
+ ->method('is_file')
+ ->with('/file.txt')
+ ->willReturn(true);
+ $this->assertFalse(self::invokePrivate($view, 'createParentDirectories', ['/file.txt/folder/structure']));
+ }
}