<?php
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @copyright Copyright (c) 2023 Robin Appelman <robin@icewind.nl>
*
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <vincent@nextcloud.com>
+ * @author Robin Appelman <robin@icewind.nl>
*
* @license AGPL-3.0
*
*
* 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/>
- *
*/
namespace OCA\DAV\SystemTag;
$this->user = $user;
}
- public function getTags() {
+ /**
+ * @return ISystemTag[]
+ */
+ public function getTags(): array {
return $this->tags;
}
* @param string $name The new name
*
* @throws MethodNotAllowed not allowed to rename node
+ *
+ * @return never
*/
public function setName($name) {
throw new MethodNotAllowed();
/**
* Returns null, not supported
*
+ * @return null
*/
public function getLastModified() {
return null;
/**
* Delete tag to object association
+ *
+ * @return void
*/
public function delete() {
try {
* @param string $name The new name
*
* @throws MethodNotAllowed not allowed to rename node
+ *
+ * @return never
*/
public function setName($name) {
throw new MethodNotAllowed();
* @param string $name new tag name
* @param bool $userVisible user visible
* @param bool $userAssignable user assignable
+ *
* @throws NotFound whenever the given tag id does not exist
* @throws Forbidden whenever there is no permission to update said tag
* @throws Conflict whenever a tag already exists with the given attributes
*/
- public function update($name, $userVisible, $userAssignable) {
+ public function update($name, $userVisible, $userAssignable): void {
try {
if (!$this->tagManager->canUserSeeTag($this->tag, $this->user)) {
throw new NotFound('Tag with id ' . $this->tag->getId() . ' does not exist');
/**
* Returns null, not supported
*
+ * @return null
*/
public function getLastModified() {
return null;
}
+ /**
+ * @return void
+ */
public function delete() {
try {
if (!$this->isAdmin) {
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Connector\Sabre\Node;
use OCP\IGroupManager;
+use OCP\IUser;
use OCP\IUserSession;
use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
*/
protected $groupManager;
- /** @var array<int, int[]> */
+ /** @var array<int, string[]> */
private array $cachedTagMappings = [];
- /** @var array<int, ISystemTag> */
+ /** @var array<string, ISystemTag> */
private array $cachedTags = [];
private ISystemTagObjectMapper $tagMapper;
*
* @param PropFind $propFind
* @param \Sabre\DAV\INode $node
+ *
+ * @return void
*/
public function handleGetProperties(
PropFind $propFind,
if ($node instanceof Directory
&& $propFind->getDepth() !== 0
&& !is_null($propFind->getStatus(self::SYSTEM_TAGS_PROPERTYNAME))) {
+ $fileIds = [$node->getId()];
+
// note: pre-fetching only supported for depth <= 1
$folderContent = $node->getNode()->getDirectoryListing();
- $fileIds[] = (int)$node->getId();
foreach ($folderContent as $info) {
- $fileIds[] = (int)$info->getId();
+ $fileIds[] = $info->getId();
}
+
$tags = $this->tagMapper->getTagIdsForObjects($fileIds, 'files');
$this->cachedTagMappings = $this->cachedTagMappings + $tags;
$emptyFileIds = array_diff($fileIds, array_keys($tags));
+
// also cache the ones that were not found
foreach ($emptyFileIds as $fileId) {
$this->cachedTagMappings[$fileId] = [];
}
$propFind->handle(self::SYSTEM_TAGS_PROPERTYNAME, function () use ($node) {
- $tags = $this->getTagsForFile($node->getId());
- return new SystemTagList($tags, $this->tagManager, $this->userSession->getUser());
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return;
+ }
+
+ $tags = $this->getTagsForFile($node->getId(), $user);
+ return new SystemTagList($tags, $this->tagManager, $user);
});
}
* @param int $fileId
* @return ISystemTag[]
*/
- private function getTagsForFile(int $fileId): array {
- $user = $this->userSession->getUser();
+ private function getTagsForFile(int $fileId, IUser $user): array {
+
if (isset($this->cachedTagMappings[$fileId])) {
$tagIds = $this->cachedTagMappings[$fileId];
} else {
$tagIds = [];
}
}
- $tags = array_filter(array_map(function($tagId) {
+
+ $tags = array_filter(array_map(function(string $tagId) {
return $this->cachedTags[$tagId] ?? null;
}, $tagIds));
- $uncachedTagIds = array_filter($tagIds, function($tagId): bool {
+ $uncachedTagIds = array_filter($tagIds, function(string $tagId): bool {
return !isset($this->cachedTags[$tagId]);
});
+
if (count($uncachedTagIds)) {
$retrievedTags = $this->tagManager->getTagsByIds($uncachedTagIds);
foreach ($retrievedTags as $tag) {
}
$tags += $retrievedTags;
}
+
return array_filter($tags, function(ISystemTag $tag) use ($user) {
return $this->tagManager->canUserSeeTag($tag, $user);
});
/**
* @param string $name
* @param resource|string $data Initial payload
+ *
* @throws Forbidden
+ *
+ * @return never
*/
public function createFile($name, $data = null) {
throw new Forbidden('Cannot create tags by id');
/**
* @param string $name
+ *
+ * @return never
*/
public function createDirectory($name) {
throw new Forbidden('Permission denied to create collections');
/**
* @param string $name
+ *
+ * @return SystemTagNode
*/
public function getChild($name) {
try {
}
}
+ /**
+ * @return SystemTagNode[]
+ *
+ * @psalm-return array<SystemTagNode>
+ */
public function getChildren() {
$visibilityFilter = true;
if ($this->isAdmin()) {
}
}
+ /**
+ * @return never
+ */
public function delete() {
throw new Forbidden('Permission denied to delete this collection');
}
+ /**
+ * @return string
+ *
+ * @psalm-return 'systemtags'
+ */
public function getName() {
return 'systemtags';
}
+ /**
+ * @return never
+ */
public function setName($name) {
throw new Forbidden('Permission denied to rename this collection');
}
/**
* Returns the last modification time, as a unix timestamp
*
- * @return int
+ * @return null
*/
public function getLastModified() {
return null;
$this->user = $user;
}
+ /**
+ * @return void
+ */
public function createFile($name, $data = null) {
$tagId = $name;
try {
}
}
+ /**
+ * @return never
+ */
public function createDirectory($name) {
throw new Forbidden('Permission denied to create collections');
}
+ /**
+ * @return SystemTagMappingNode
+ */
public function getChild($tagName) {
try {
if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagName, true)) {
}
}
+ /**
+ * @return SystemTagMappingNode[]
+ *
+ * @psalm-return list<SystemTagMappingNode>
+ */
public function getChildren() {
$tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType));
if (empty($tagIds)) {
}
}
+ /**
+ * @return never
+ */
public function delete() {
throw new Forbidden('Permission denied to delete this collection');
}
return $this->objectId;
}
+ /**
+ * @return never
+ */
public function setName($name) {
throw new Forbidden('Permission denied to rename this collection');
}
/**
* Returns the last modification time, as a unix timestamp
*
- * @return int
+ * @return null
*/
public function getLastModified() {
return null;
/**
* @param string $name
* @param resource|string $data Initial payload
- * @return null|string
+ *
+ * @return never
+ *
* @throws Forbidden
*/
public function createFile($name, $data = null) {
/**
* @param string $name
+ *
* @throws Forbidden
+ *
+ * @return never
*/
public function createDirectory($name) {
throw new Forbidden('Permission denied to create collections');
);
}
+ /**
+ * @return never
+ */
public function getChildren() {
// do not list object ids
throw new MethodNotAllowed();
return call_user_func($this->childExistsFunction, $name);
}
+ /**
+ * @return never
+ */
public function delete() {
throw new Forbidden('Permission denied to delete this collection');
}
/**
* @param string $name
+ *
* @throws Forbidden
+ *
+ * @return never
*/
public function setName($name) {
throw new Forbidden('Permission denied to rename this collection');
/**
* Returns the last modification time, as a unix timestamp
*
- * @return int
+ * @return null
*/
public function getLastModified() {
return null;
*/
private $plugin;
- private ISystemTagObjectMapper $tagMapper;
+ /**
+ * @var ISystemTagObjectMapper
+ */
+ private $tagMapper;
protected function setUp(): void {
parent::setUp();
->expects($this->any())
->method('isLoggedIn')
->willReturn(true);
- $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class);
+ $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class)
+ ->getMock();
$this->plugin = new \OCA\DAV\SystemTag\SystemTagPlugin(
$this->tagManager,
* @param ISystemTag $tag tag to check permission for
* @param IUser $user user to check permission for
*
- * @return true if the user is allowed to assign/unassign the tag, false otherwise
+ * @return bool true if the user is allowed to assign/unassign the tag, false otherwise
*
* @since 9.1.0
*/
* @param ISystemTag $tag tag to check permission for
* @param IUser $user user to check permission for
*
- * @return true if the user can see the tag, false otherwise
+ * @return bool true if the user can see the tag, false otherwise
*
* @since 9.1.0
*/