aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib')
-rw-r--r--apps/dav/lib/SystemTag/SystemTagNode.php9
-rw-r--r--apps/dav/lib/SystemTag/SystemTagObjectType.php36
-rw-r--r--apps/dav/lib/SystemTag/SystemTagPlugin.php43
-rw-r--r--apps/dav/lib/SystemTag/SystemTagsInUseCollection.php2
-rw-r--r--apps/dav/lib/SystemTag/SystemTagsObjectList.php50
5 files changed, 125 insertions, 15 deletions
diff --git a/apps/dav/lib/SystemTag/SystemTagNode.php b/apps/dav/lib/SystemTag/SystemTagNode.php
index 154bfa493f2..ed4eb44cbbd 100644
--- a/apps/dav/lib/SystemTag/SystemTagNode.php
+++ b/apps/dav/lib/SystemTag/SystemTagNode.php
@@ -184,7 +184,12 @@ class SystemTagNode implements \Sabre\DAV\ICollection {
}
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)];
+ $objectTypes = $this->tagMapper->getAvailableObjectTypes();
+ return array_map(
+ function ($objectType) {
+ return new SystemTagObjectType($this->tag, $objectType, $this->tagManager, $this->tagMapper);
+ },
+ $objectTypes
+ );
}
}
diff --git a/apps/dav/lib/SystemTag/SystemTagObjectType.php b/apps/dav/lib/SystemTag/SystemTagObjectType.php
index 0279e4411d8..0e1368854cd 100644
--- a/apps/dav/lib/SystemTag/SystemTagObjectType.php
+++ b/apps/dav/lib/SystemTag/SystemTagObjectType.php
@@ -14,7 +14,7 @@ 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 {
+class SystemTagObjectType implements \Sabre\DAV\IFile {
public const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
/** @var string[] */
@@ -39,19 +39,43 @@ class SystemTagObjectType implements \Sabre\DAV\INode {
return $this->objectsIds;
}
- public function delete() {
- throw new MethodNotAllowed();
+ /**
+ * Returns the system tag represented by this node
+ *
+ * @return ISystemTag system tag
+ */
+ public function getSystemTag() {
+ return $this->tag;
}
public function getName() {
return $this->type;
}
+ public function getLastModified() {
+ return null;
+ }
+
+ public function getETag() {
+ return '"' . $this->tag->getETag() . '"';
+ }
+
public function setName($name) {
throw new MethodNotAllowed();
}
-
- public function getLastModified() {
- return null;
+ public function put($data) {
+ throw new MethodNotAllowed();
+ }
+ public function get() {
+ throw new MethodNotAllowed();
+ }
+ public function delete() {
+ throw new MethodNotAllowed();
+ }
+ public function getContentType() {
+ throw new MethodNotAllowed();
+ }
+ public function getSize() {
+ throw new MethodNotAllowed();
}
}
diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php
index 687b47284eb..c88a69f1154 100644
--- a/apps/dav/lib/SystemTag/SystemTagPlugin.php
+++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php
@@ -8,6 +8,7 @@
namespace OCA\DAV\SystemTag;
use OCA\DAV\Connector\Sabre\Directory;
+use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\Node;
use OCP\IGroupManager;
use OCP\IUser;
@@ -20,6 +21,7 @@ use OCP\Util;
use Sabre\DAV\Exception\BadRequest;
use Sabre\DAV\Exception\Conflict;
use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\PreconditionFailed;
use Sabre\DAV\Exception\UnsupportedMediaType;
use Sabre\DAV\PropFind;
use Sabre\DAV\PropPatch;
@@ -80,6 +82,9 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
*/
public function initialize(\Sabre\DAV\Server $server) {
$server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
+ $server->xml->namespaceMap[self::NS_NEXTCLOUD] = 'nc';
+
+ $server->xml->elementMap[self::OBJECTIDS_PROPERTYNAME] = SystemTagsObjectList::class;
$server->protectedProperties[] = self::ID_PROPERTYNAME;
@@ -213,6 +218,10 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
$propFind->setPath(str_replace('systemtags-assigned/', 'systemtags/', $propFind->getPath()));
}
+ $propFind->handle(FilesPlugin::GETETAG_PROPERTYNAME, function () use ($node): string|null {
+ return $node->getSystemTag()->getETag();
+ });
+
$propFind->handle(self::ID_PROPERTYNAME, function () use ($node) {
return $node->getSystemTag()->getId();
});
@@ -359,9 +368,37 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
*/
public function handleUpdateProperties($path, PropPatch $propPatch) {
$node = $this->server->tree->getNodeForPath($path);
- if (!($node instanceof SystemTagNode)) {
+ if (!($node instanceof SystemTagNode) && !($node instanceof SystemTagObjectType)) {
return;
}
+
+ $propPatch->handle([self::OBJECTIDS_PROPERTYNAME], function ($props) use ($node) {
+ if (!($node instanceof SystemTagObjectType)) {
+ return false;
+ }
+
+ if (isset($props[self::OBJECTIDS_PROPERTYNAME])) {
+ $propValue = $props[self::OBJECTIDS_PROPERTYNAME];
+ if (!($propValue instanceof SystemTagsObjectList) || count($propValue?->getObjects() ?: []) === 0) {
+ throw new BadRequest('Invalid object-ids property');
+ }
+
+ $objects = $propValue->getObjects();
+ $objectTypes = array_unique(array_values($objects));
+
+ if (count($objectTypes) !== 1 || $objectTypes[0] !== $node->getName()) {
+ throw new BadRequest('Invalid object-ids property. All object types must be of the same type: ' . $node->getName());
+ }
+
+ $this->tagMapper->setObjectIdsForTag($node->getSystemTag()->getId(), $node->getName(), array_keys($objects));
+ }
+
+ if ($props[self::OBJECTIDS_PROPERTYNAME] === null) {
+ $this->tagMapper->setObjectIdsForTag($node->getSystemTag()->getId(), $node->getName(), []);
+ }
+
+ return true;
+ });
$propPatch->handle([
self::DISPLAYNAME_PROPERTYNAME,
@@ -371,6 +408,10 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
self::NUM_FILES_PROPERTYNAME,
self::REFERENCE_FILEID_PROPERTYNAME,
], function ($props) use ($node) {
+ if (!($node instanceof SystemTagNode)) {
+ return false;
+ }
+
$tag = $node->getSystemTag();
$name = $tag->getName();
$userVisible = $tag->isUserVisible();
diff --git a/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php
index c27926ec410..9b02a5be42c 100644
--- a/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php
+++ b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php
@@ -73,7 +73,7 @@ class SystemTagsInUseCollection extends SimpleCollection {
$result = $this->systemTagsInFilesDetector->detectAssignedSystemTagsIn($userFolder, $this->mediaType);
$children = [];
foreach ($result as $tagData) {
- $tag = new SystemTag((string)$tagData['id'], $tagData['name'], (bool)$tagData['visibility'], (bool)$tagData['editable']);
+ $tag = new SystemTag((string)$tagData['id'], $tagData['name'], (bool)$tagData['visibility'], (bool)$tagData['editable'], $tagData['etag']);
// read only, so we can submit the isAdmin parameter as false generally
$node = new SystemTagNode($tag, $user, false, $this->systemTagManager, $this->tagMapper);
$node->setNumberOfFiles((int)$tagData['number_files']);
diff --git a/apps/dav/lib/SystemTag/SystemTagsObjectList.php b/apps/dav/lib/SystemTag/SystemTagsObjectList.php
index e25f1c804ee..0743b8d8130 100644
--- a/apps/dav/lib/SystemTag/SystemTagsObjectList.php
+++ b/apps/dav/lib/SystemTag/SystemTagsObjectList.php
@@ -1,4 +1,5 @@
<?php
+
declare(strict_types=1);
/**
@@ -7,21 +8,60 @@ declare(strict_types=1);
*/
namespace OCA\DAV\SystemTag;
+use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
+use Sabre\Xml\XmlDeserializable;
use Sabre\Xml\XmlSerializable;
/**
* This property contains multiple "object-id" elements.
*/
-class SystemTagsObjectList implements XmlSerializable {
+class SystemTagsObjectList implements XmlSerializable, XmlDeserializable {
+
public const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
+ public const OBJECTID_ROOT_PROPERTYNAME = '{http://nextcloud.org/ns}object-id';
+ public const OBJECTID_PROPERTYNAME = '{http://nextcloud.org/ns}id';
+ public const OBJECTTYPE_PROPERTYNAME = '{http://nextcloud.org/ns}type';
/**
* @param array<string, string> $objects An array of object ids and their types
*/
public function __construct(
private array $objects,
- ) { }
+ ) {
+ }
+
+ public function getObjects(): array {
+ return $this->objects;
+ }
+
+ public static function xmlDeserialize(Reader $reader) {
+ $tree = $reader->parseInnerTree();
+ if ($tree === null) {
+ return null;
+ }
+
+ $objects = [];
+ foreach ($tree as $elem) {
+ if ($elem['name'] === self::OBJECTID_ROOT_PROPERTYNAME) {
+ $value = $elem['value'];
+ $id = '';
+ $type = '';
+ foreach ($value as $subElem) {
+ if ($subElem['name'] === self::OBJECTID_PROPERTYNAME) {
+ $id = $subElem['value'];
+ } elseif ($subElem['name'] === self::OBJECTTYPE_PROPERTYNAME) {
+ $type = $subElem['value'];
+ }
+ }
+ if ($id !== '' && $type !== '') {
+ $objects[$id] = $type;
+ }
+ }
+ }
+
+ return new self($objects);
+ }
/**
* The xmlSerialize method is called during xml writing.
@@ -31,9 +71,9 @@ class SystemTagsObjectList implements XmlSerializable {
*/
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->startElement(SystemTagPlugin::OBJECTIDS_PROPERTYNAME);
+ $writer->writeElement(self::OBJECTID_PROPERTYNAME, $objectsId);
+ $writer->writeElement(self::OBJECTTYPE_PROPERTYNAME, $type);
$writer->endElement();
}
}