diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-10-18 08:40:59 +0200 |
---|---|---|
committer | skjnldsv <skjnldsv@protonmail.com> | 2024-10-29 09:08:30 +0100 |
commit | f24b93e5067e54244d14eb08ad8ed8330a03724b (patch) | |
tree | 5639253da4fbc06268c07e8073efcfc0a2c8dc7b /apps/dav/lib | |
parent | 0893d4b4d265a2f4ade08902cdc8abfc07975307 (diff) | |
download | nextcloud-server-f24b93e5067e54244d14eb08ad8ed8330a03724b.tar.gz nextcloud-server-f24b93e5067e54244d14eb08ad8ed8330a03724b.zip |
feat(dav): add systemtag object IDs listing
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/dav/lib')
-rw-r--r-- | apps/dav/lib/RootCollection.php | 6 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagNode.php | 29 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagObjectType.php | 57 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagPlugin.php | 28 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsByIdCollection.php | 4 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsInUseCollection.php | 6 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsObjectList.php | 40 |
7 files changed, 154 insertions, 16 deletions
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 6ede8cb683c..751ab17bb7a 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -105,11 +105,7 @@ class RootCollection extends SimpleCollection { $publicCalendarRoot = new PublicCalendarRoot($caldavBackend, $l10n, $config, $logger); - $systemTagCollection = new SystemTagsByIdCollection( - \OC::$server->getSystemTagManager(), - \OC::$server->getUserSession(), - $groupManager - ); + $systemTagCollection = Server::get(SystemTagsByIdCollection::class); $systemTagRelationsCollection = new SystemTagsRelationsCollection( \OC::$server->getSystemTagManager(), \OC::$server->getSystemTagObjectMapper(), diff --git a/apps/dav/lib/SystemTag/SystemTagNode.php b/apps/dav/lib/SystemTag/SystemTagNode.php index 9357f207779..154bfa493f2 100644 --- a/apps/dav/lib/SystemTag/SystemTagNode.php +++ b/apps/dav/lib/SystemTag/SystemTagNode.php @@ -10,8 +10,8 @@ namespace OCA\DAV\SystemTag; use OCP\IUser; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagAlreadyExistsException; - use OCP\SystemTag\TagNotFoundException; use Sabre\DAV\Exception\Conflict; use Sabre\DAV\Exception\Forbidden; @@ -21,7 +21,7 @@ use Sabre\DAV\Exception\NotFound; /** * DAV node representing a system tag, with the name being the tag id. */ -class SystemTagNode implements \Sabre\DAV\INode { +class SystemTagNode implements \Sabre\DAV\ICollection { protected int $numberOfFiles = -1; protected int $referenceFileId = -1; @@ -43,8 +43,9 @@ class SystemTagNode implements \Sabre\DAV\INode { /** * Whether to allow permissions for admins */ - protected $isAdmin, + protected bool $isAdmin, protected ISystemTagManager $tagManager, + protected ISystemTagObjectMapper $tagMapper, ) { } @@ -164,4 +165,26 @@ class SystemTagNode implements \Sabre\DAV\INode { public function setReferenceFileId(int $referenceFileId): void { $this->referenceFileId = $referenceFileId; } + + public function createFile($name, $data = null) { + throw new MethodNotAllowed(); + } + + public function createDirectory($name) { + throw new MethodNotAllowed(); + } + + public function getChild($name) { + return new SystemTagObjectType($this->tag, $name, $this->tagManager, $this->tagMapper); + } + + public function childExists($name) { + $objectTypes = $this->tagMapper->getAvailableObjectTypes(); + return in_array($name, $objectTypes); + } + + public function getChildren() { + // We currently don't have a method to list allowed tag mappings types + return [new SystemTagObjectType($this->tag, 'files', $this->tagManager, $this->tagMapper)]; + } } diff --git a/apps/dav/lib/SystemTag/SystemTagObjectType.php b/apps/dav/lib/SystemTag/SystemTagObjectType.php new file mode 100644 index 00000000000..0279e4411d8 --- /dev/null +++ b/apps/dav/lib/SystemTag/SystemTagObjectType.php @@ -0,0 +1,57 @@ +<?php +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\DAV\SystemTag; + +use OCP\SystemTag\ISystemTag; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; +use Sabre\DAV\Exception\MethodNotAllowed; + +/** + * SystemTagObjectType property + * This property represent a type of object which tags are assigned to. + */ +class SystemTagObjectType implements \Sabre\DAV\INode { + public const NS_NEXTCLOUD = 'http://nextcloud.org/ns'; + + /** @var string[] */ + private array $objectsIds = []; + + public function __construct( + private ISystemTag $tag, + private string $type, + private ISystemTagManager $tagManager, + private ISystemTagObjectMapper $tagMapper, + ) { + } + + /** + * Get the list of object ids that have this tag assigned. + */ + public function getObjectsIds(): array { + if (empty($this->objectsIds)) { + $this->objectsIds = $this->tagMapper->getObjectIdsForTags($this->tag->getId(), $this->type); + } + + return $this->objectsIds; + } + + public function delete() { + throw new MethodNotAllowed(); + } + + public function getName() { + return $this->type; + } + + public function setName($name) { + throw new MethodNotAllowed(); + } + + public function getLastModified() { + return null; + } +} diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php index 3c34f4263f6..687b47284eb 100644 --- a/apps/dav/lib/SystemTag/SystemTagPlugin.php +++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php @@ -37,6 +37,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { // namespace public const NS_OWNCLOUD = 'http://owncloud.org/ns'; + public const NS_NEXTCLOUD = 'http://nextcloud.org/ns'; public const ID_PROPERTYNAME = '{http://owncloud.org/ns}id'; public const DISPLAYNAME_PROPERTYNAME = '{http://owncloud.org/ns}display-name'; public const USERVISIBLE_PROPERTYNAME = '{http://owncloud.org/ns}user-visible'; @@ -45,7 +46,8 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { public const CANASSIGN_PROPERTYNAME = '{http://owncloud.org/ns}can-assign'; public const SYSTEM_TAGS_PROPERTYNAME = '{http://nextcloud.org/ns}system-tags'; public const NUM_FILES_PROPERTYNAME = '{http://nextcloud.org/ns}files-assigned'; - public const FILEID_PROPERTYNAME = '{http://nextcloud.org/ns}reference-fileid'; + public const REFERENCE_FILEID_PROPERTYNAME = '{http://nextcloud.org/ns}reference-fileid'; + public const OBJECTIDS_PROPERTYNAME = '{http://nextcloud.org/ns}object-ids'; /** * @var \Sabre\DAV\Server $server @@ -202,7 +204,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { return; } - if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagMappingNode)) { + if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagMappingNode) && !($node instanceof SystemTagObjectType)) { return; } @@ -251,9 +253,25 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { return $node->getNumberOfFiles(); }); - $propFind->handle(self::FILEID_PROPERTYNAME, function () use ($node): int { + $propFind->handle(self::REFERENCE_FILEID_PROPERTYNAME, function () use ($node): int { return $node->getReferenceFileId(); }); + + $propFind->handle(self::OBJECTIDS_PROPERTYNAME, function () use ($node): SystemTagsObjectList { + $objectTypes = $this->tagMapper->getAvailableObjectTypes(); + $objects = []; + foreach ($objectTypes as $type) { + $systemTagObjectType = new SystemTagObjectType($node->getSystemTag(), $type, $this->tagManager, $this->tagMapper); + $objects = array_merge($objects, array_fill_keys($systemTagObjectType->getObjectsIds(), $type)); + } + return new SystemTagsObjectList($objects); + }); + } + + if ($node instanceof SystemTagObjectType) { + $propFind->handle(self::OBJECTIDS_PROPERTYNAME, function () use ($node): SystemTagsObjectList { + return new SystemTagsObjectList(array_fill_keys($node->getObjectsIds(), $node->getName())); + }); } } @@ -351,7 +369,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { self::USERASSIGNABLE_PROPERTYNAME, self::GROUPS_PROPERTYNAME, self::NUM_FILES_PROPERTYNAME, - self::FILEID_PROPERTYNAME, + self::REFERENCE_FILEID_PROPERTYNAME, ], function ($props) use ($node) { $tag = $node->getSystemTag(); $name = $tag->getName(); @@ -388,7 +406,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { $this->tagManager->setTagGroups($tag, $groupIds); } - if (isset($props[self::NUM_FILES_PROPERTYNAME]) || isset($props[self::FILEID_PROPERTYNAME])) { + if (isset($props[self::NUM_FILES_PROPERTYNAME]) || isset($props[self::REFERENCE_FILEID_PROPERTYNAME])) { // read-only properties throw new Forbidden(); } diff --git a/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php b/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php index cf889985d1b..b854db7b94d 100644 --- a/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php +++ b/apps/dav/lib/SystemTag/SystemTagsByIdCollection.php @@ -11,6 +11,7 @@ use OCP\IGroupManager; use OCP\IUserSession; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\Exception\Forbidden; @@ -30,6 +31,7 @@ class SystemTagsByIdCollection implements ICollection { private ISystemTagManager $tagManager, private IUserSession $userSession, private IGroupManager $groupManager, + protected ISystemTagObjectMapper $tagMapper, ) { } @@ -162,6 +164,6 @@ class SystemTagsByIdCollection implements ICollection { * @return SystemTagNode */ private function makeNode(ISystemTag $tag) { - return new SystemTagNode($tag, $this->userSession->getUser(), $this->isAdmin(), $this->tagManager); + return new SystemTagNode($tag, $this->userSession->getUser(), $this->isAdmin(), $this->tagManager, $this->tagMapper); } } diff --git a/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php index 6a3dd0c2155..c27926ec410 100644 --- a/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php +++ b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php @@ -16,6 +16,7 @@ use OCP\Files\IRootFolder; use OCP\Files\NotPermittedException; use OCP\IUserSession; use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\SimpleCollection; @@ -28,6 +29,7 @@ class SystemTagsInUseCollection extends SimpleCollection { protected IUserSession $userSession, protected IRootFolder $rootFolder, protected ISystemTagManager $systemTagManager, + protected ISystemTagObjectMapper $tagMapper, SystemTagsInFilesDetector $systemTagsInFilesDetector, protected string $mediaType = '', ) { @@ -46,7 +48,7 @@ class SystemTagsInUseCollection extends SimpleCollection { if ($this->mediaType !== '') { throw new NotFound('Invalid media type'); } - return new self($this->userSession, $this->rootFolder, $this->systemTagManager, $this->systemTagsInFilesDetector, $name); + return new self($this->userSession, $this->rootFolder, $this->systemTagManager, $this->tagMapper, $this->systemTagsInFilesDetector, $name); } /** @@ -73,7 +75,7 @@ class SystemTagsInUseCollection extends SimpleCollection { foreach ($result as $tagData) { $tag = new SystemTag((string)$tagData['id'], $tagData['name'], (bool)$tagData['visibility'], (bool)$tagData['editable']); // read only, so we can submit the isAdmin parameter as false generally - $node = new SystemTagNode($tag, $user, false, $this->systemTagManager); + $node = new SystemTagNode($tag, $user, false, $this->systemTagManager, $this->tagMapper); $node->setNumberOfFiles((int)$tagData['number_files']); $node->setReferenceFileId((int)$tagData['ref_file_id']); $children[] = $node; diff --git a/apps/dav/lib/SystemTag/SystemTagsObjectList.php b/apps/dav/lib/SystemTag/SystemTagsObjectList.php new file mode 100644 index 00000000000..e25f1c804ee --- /dev/null +++ b/apps/dav/lib/SystemTag/SystemTagsObjectList.php @@ -0,0 +1,40 @@ +<?php +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\DAV\SystemTag; + +use Sabre\Xml\Writer; +use Sabre\Xml\XmlSerializable; + +/** + * This property contains multiple "object-id" elements. + */ +class SystemTagsObjectList implements XmlSerializable { + public const NS_NEXTCLOUD = 'http://nextcloud.org/ns'; + + /** + * @param array<string, string> $objects An array of object ids and their types + */ + public function __construct( + private array $objects, + ) { } + + /** + * The xmlSerialize method is called during xml writing. + * + * @param Writer $writer + * @return void + */ + public function xmlSerialize(Writer $writer) { + foreach ($this->objects as $objectsId => $type) { + $writer->startElement('{' . self::NS_NEXTCLOUD . '}object-id'); + $writer->writeElement('{' . self::NS_NEXTCLOUD . '}id', $objectsId); + $writer->writeElement('{' . self::NS_NEXTCLOUD . '}type', $type); + $writer->endElement(); + } + } +} |