Skip to content

Commit

Permalink
Merge pull request #864 from nextcloud/fix/lazy_folder
Browse files Browse the repository at this point in the history
fix(CollectiveFolderManager): Use our own LazyFolder implementation
  • Loading branch information
mejo- authored Sep 7, 2023
2 parents 9b99cc5 + b388e9b commit 8794c83
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 13 deletions.
15 changes: 4 additions & 11 deletions lib/Mount/CollectiveFolderManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace OCA\Collectives\Mount;

use OC\Files\Node\LazyFolder;
use OC\Files\Storage\Wrapper\Jail;
use OC\Files\Storage\Wrapper\PermissionsMask;
use OCA\Collectives\ACL\ACLStorageWrapper25;
Expand Down Expand Up @@ -35,8 +34,7 @@ class CollectiveFolderManager {
private IRequest $request;
private ?string $rootPath = null;

/** @var int|null */
private $rootFolderStorageId = null;
private ?int $rootFolderStorageId = null;

/**
* CollectiveFolderManager constructor.
Expand Down Expand Up @@ -78,14 +76,7 @@ public function getRootPath(): string {
* @return Folder
*/
public function getRootFolder(): Folder {
$rootFolder = $this->rootFolder;
return (new LazyFolder(function () use ($rootFolder) {
try {
return $rootFolder->get($this->getRootPath());
} catch (NotFoundException $e) {
return $rootFolder->newFolder($this->getRootPath());
}
}));
return new LazyFolder($this->rootFolder, $this->getRootPath());
}

/**
Expand Down Expand Up @@ -120,6 +111,8 @@ private function getCurrentUID(): ?string {
* @return IMountPoint|null
* @throws InvalidPathException
* @throws NotFoundException
*
*
*/
public function getMount(int $id,
string $mountPoint,
Expand Down
263 changes: 263 additions & 0 deletions lib/Mount/LazyFolder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
<?php

declare(strict_types=1);

namespace OCA\Collectives\Mount;

use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;

class LazyFolder implements Folder {
private IRootFolder $rootFolder;
private string $rootPath;
private ?Folder $folder = null;

public function __construct(IRootFolder $rootFolder, string $rootPath) {
$this->rootFolder = $rootFolder;
$this->rootPath = $rootPath;
}

/**
* @return Folder
* @throws NotPermittedException
*/
private function getFolder(): Folder {
if ($this->folder === null) {
try {
$folder = $this->rootFolder->get($this->rootPath);
if (!$folder instanceof Folder) {
throw new NotFoundException('Not a folder: ' . $folder->getPath());
}
$this->folder = $folder;
} catch (NotFoundException $e) {
$this->folder = $this->rootFolder->newFolder($this->rootPath);
}
}

return $this->folder;
}

/**
* Magic method to first get the real rootFolder and then
* call $method with $args on it
*
* @param $method
* @param $args
* @return mixed
*/
public function __call($method, $args) {
$folder = $this->getFolder();

return call_user_func_array([$folder, $method], $args);
}

public function getMtime() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getMimetype() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getMimePart() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isEncrypted() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getType() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isShared() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isMounted() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getMountPoint() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getOwner() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getChecksum() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getExtension(): string {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getCreationTime(): int {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getUploadTime(): int {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getParentId(): int {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getFullPath($path) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getRelativePath($path) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isSubNode($node) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getDirectoryListing() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function get($path) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function nodeExists($path) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function newFolder($path) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function newFile($path, $content = null) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function search($query) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function searchByMime($mimetype) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function searchByTag($tag, $userId) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getById($id) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getFreeSpace() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isCreatable() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getNonExistingName($name) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getRecent($limit, $offset = 0) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function move($targetPath) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function delete() {
$this->__call(__FUNCTION__, func_get_args());
}

public function copy($targetPath) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function touch($mtime = null) {
$this->__call(__FUNCTION__, func_get_args());
}

public function getStorage() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getPath() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getInternalPath() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getId() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function stat() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getSize($includeMounts = true) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getEtag() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getPermissions() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isReadable() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isUpdateable() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isDeletable() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function isShareable() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getParent() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function getName() {
return $this->__call(__FUNCTION__, func_get_args());
}

public function lock($type) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function changeLock($targetType) {
return $this->__call(__FUNCTION__, func_get_args());
}

public function unlock($type) {
return $this->__call(__FUNCTION__, func_get_args());
}
}
3 changes: 2 additions & 1 deletion lib/Trash/PageTrashBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ public function getTrashItemByCollectiveAndId(IUser $user, int $collectiveId, in
$trashNode = $this->getTrashNodeById($user, $fileId);
// Get parent folder for index pages
if ($trashNode instanceof File && NodeHelper::isIndexPage($trashNode)) {
$trashNode = $trashNode->getParent();
// The extra `get()` is required to resolve the lazy folder from getParent()
$trashNode = $trashNode->getParent()->get('');
}
$trashItem = $this->trashManager->getTrashItemByFileId($trashNode->getId());
if ($trashItem && method_exists($trashNode, 'getFileInfo')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Feature: pages
Feature: pagesDisabledTrashbin

Scenario: Disable trashbin and versions apps
When app "files_trashbin" is "disabled"
Expand Down

0 comments on commit 8794c83

Please sign in to comment.