diff options
Diffstat (limited to 'lib/private/Files/FileInfo.php')
-rw-r--r-- | lib/private/Files/FileInfo.php | 206 |
1 files changed, 91 insertions, 115 deletions
diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index 6389544184f..0679dc1ae72 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -1,49 +1,26 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Piotr M <mrow4a@yahoo.com> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author tbartenstein <tbartenstein@users.noreply.github.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OC\Files; +use OC\Files\Mount\HomeMountPoint; +use OCA\Files_Sharing\External\Mount; +use OCA\Files_Sharing\ISharedMountPoint; use OCP\Files\Cache\ICacheEntry; use OCP\Files\Mount\IMountPoint; use OCP\IUser; +/** + * @template-implements \ArrayAccess<string,mixed> + */ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { + private array|ICacheEntry $data; /** - * @var array $data - */ - private $data; - - /** - * @var string $path + * @var string */ private $path; @@ -53,7 +30,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { private $storage; /** - * @var string $internalPath + * @var string */ private $internalPath; @@ -62,37 +39,32 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { */ private $mount; - /** - * @var IUser - */ - private $owner; + private ?IUser $owner; /** * @var string[] */ - private $childEtags = []; + private array $childEtags = []; /** * @var IMountPoint[] */ - private $subMounts = []; + private array $subMounts = []; - private $subMountsUsed = false; + private bool $subMountsUsed = false; /** * The size of the file/folder without any sub mount - * - * @var int */ - private $rawSize = 0; + private int|float $rawSize = 0; /** * @param string|boolean $path * @param Storage\Storage $storage * @param string $internalPath * @param array|ICacheEntry $data - * @param \OCP\Files\Mount\IMountPoint $mount - * @param \OCP\IUser|null $owner + * @param IMountPoint $mount + * @param ?IUser $owner */ public function __construct($path, $storage, $internalPath, $data, $mount, $owner = null) { $this->path = $path; @@ -101,10 +73,17 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { $this->data = $data; $this->mount = $mount; $this->owner = $owner; - $this->rawSize = $this->data['size'] ?? 0; + if (isset($this->data['unencrypted_size']) && $this->data['unencrypted_size'] !== 0) { + $this->rawSize = $this->data['unencrypted_size']; + } else { + $this->rawSize = $this->data['size'] ?? 0; + } } public function offsetSet($offset, $value): void { + if (is_null($offset)) { + throw new \TypeError('Null offset not supported'); + } $this->data[$offset] = $value; } @@ -116,26 +95,15 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { unset($this->data[$offset]); } - /** - * @return mixed - */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) { - if ($offset === 'type') { - return $this->getType(); - } elseif ($offset === 'etag') { - return $this->getEtag(); - } elseif ($offset === 'size') { - return $this->getSize(); - } elseif ($offset === 'mtime') { - return $this->getMTime(); - } elseif ($offset === 'permissions') { - return $this->getPermissions(); - } elseif (isset($this->data[$offset])) { - return $this->data[$offset]; - } else { - return null; - } + public function offsetGet(mixed $offset): mixed { + return match ($offset) { + 'type' => $this->getType(), + 'etag' => $this->getEtag(), + 'size' => $this->getSize(), + 'mtime' => $this->getMTime(), + 'permissions' => $this->getPermissions(), + default => $this->data[$offset] ?? null, + }; } /** @@ -145,9 +113,6 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { return $this->path; } - /** - * @return \OCP\Files\Storage - */ public function getStorage() { return $this->storage; } @@ -165,7 +130,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return int|null */ public function getId() { - return isset($this->data['fileid']) ? (int) $this->data['fileid'] : null; + return isset($this->data['fileid']) ? (int)$this->data['fileid'] : null; } /** @@ -186,14 +151,16 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return string */ public function getName() { - return isset($this->data['name']) ? $this->data['name'] : basename($this->getPath()); + return empty($this->data['name']) + ? basename($this->getPath()) + : $this->data['name']; } /** * @return string */ public function getEtag() { - $this->updateEntryfromSubMounts(); + $this->updateEntryFromSubMounts(); if (count($this->childEtags) > 0) { $combinedEtag = $this->data['etag'] . '::' . implode('::', $this->childEtags); return md5($combinedEtag); @@ -203,12 +170,18 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } /** - * @return int + * @param bool $includeMounts + * @return int|float */ public function getSize($includeMounts = true) { if ($includeMounts) { - $this->updateEntryfromSubMounts(); - return isset($this->data['size']) ? 0 + $this->data['size'] : 0; + $this->updateEntryFromSubMounts(); + + if ($this->isEncrypted() && isset($this->data['unencrypted_size']) && $this->data['unencrypted_size'] > 0) { + return $this->data['unencrypted_size']; + } else { + return isset($this->data['size']) ? 0 + $this->data['size'] : 0; + } } else { return $this->rawSize; } @@ -218,35 +191,29 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return int */ public function getMTime() { - $this->updateEntryfromSubMounts(); - return (int) $this->data['mtime']; + $this->updateEntryFromSubMounts(); + return (int)$this->data['mtime']; } /** * @return bool */ public function isEncrypted() { - return $this->data['encrypted']; + return $this->data['encrypted'] ?? false; } /** - * Return the currently version used for the HMAC in the encryption app - * - * @return int + * Return the current version used for the HMAC in the encryption app */ - public function getEncryptedVersion() { - return isset($this->data['encryptedVersion']) ? (int) $this->data['encryptedVersion'] : 1; + public function getEncryptedVersion(): int { + return isset($this->data['encryptedVersion']) ? (int)$this->data['encryptedVersion'] : 1; } /** * @return int */ public function getPermissions() { - $perms = (int) $this->data['permissions']; - if (\OCP\Util::isSharingDisabledForUser() || ($this->isShared() && !\OC\Share\Share::isResharingAllowed())) { - $perms = $perms & ~\OCP\Constants::PERMISSION_SHARE; - } - return $perms; + return (int)$this->data['permissions']; } /** @@ -314,27 +281,12 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return bool */ public function isShared() { - $sid = $this->getStorage()->getId(); - if (!is_null($sid)) { - $sid = explode(':', $sid); - return ($sid[0] === 'shared'); - } - - return false; + return $this->mount instanceof ISharedMountPoint; } public function isMounted() { - $storage = $this->getStorage(); - if ($storage->instanceOfStorage('\OCP\Files\IHomeStorage')) { - return false; - } - $sid = $storage->getId(); - if (!is_null($sid)) { - $sid = explode(':', $sid); - return ($sid[0] !== 'home' and $sid[0] !== 'shared'); - } - - return false; + $isHome = $this->mount instanceof HomeMountPoint; + return !$isHome && !$this->isShared(); } /** @@ -349,7 +301,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { /** * Get the owner of the file * - * @return \OCP\IUser + * @return ?IUser */ public function getOwner() { return $this->owner; @@ -362,7 +314,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { $this->subMounts = $mounts; } - private function updateEntryfromSubMounts() { + private function updateEntryFromSubMounts(): void { if ($this->subMountsUsed) { return; } @@ -386,14 +338,26 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @param string $entryPath full path of the child entry */ public function addSubEntry($data, $entryPath) { - $this->data['size'] += isset($data['size']) ? $data['size'] : 0; + if (!$data) { + return; + } + $hasUnencryptedSize = isset($data['unencrypted_size']) && $data['unencrypted_size'] > 0; + if ($hasUnencryptedSize) { + $subSize = $data['unencrypted_size']; + } else { + $subSize = $data['size'] ?: 0; + } + $this->data['size'] += $subSize; + if ($hasUnencryptedSize) { + $this->data['unencrypted_size'] += $subSize; + } if (isset($data['mtime'])) { $this->data['mtime'] = max($this->data['mtime'], $data['mtime']); } if (isset($data['etag'])) { // prefix the etag with the relative path of the subentry to propagate etag on mount moves $relativeEntryPath = substr($entryPath, strlen($this->getPath())); - // attach the permissions to propagate etag on permision changes of submounts + // attach the permissions to propagate etag on permission changes of submounts $permissions = isset($data['permissions']) ? $data['permissions'] : 0; $this->childEtags[] = $relativeEntryPath . '/' . $data['etag'] . $permissions; } @@ -411,10 +375,22 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } public function getCreationTime(): int { - return (int) $this->data['creation_time']; + return (int)$this->data['creation_time']; } public function getUploadTime(): int { - return (int) $this->data['upload_time']; + return (int)$this->data['upload_time']; + } + + public function getParentId(): int { + return $this->data['parent'] ?? -1; + } + + /** + * @inheritDoc + * @return array<string, int|string|bool|float|string[]|int[]> + */ + public function getMetadata(): array { + return $this->data['metadata'] ?? []; } } |