Browse Source

Merge pull request #54810 from nextcloud/feat/typed-tag-events

feat(SystemTag): Add typed events for tag mapper events
pull/54870/head
Marcel Klehr 2 months ago
committed by GitHub
parent
commit
7bd0b5704d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      lib/composer/composer/autoload_classmap.php
  2. 2
      lib/composer/composer/autoload_static.php
  3. 10
      lib/private/SystemTag/SystemTagObjectMapper.php
  4. 73
      lib/public/SystemTag/TagAssignedEvent.php
  5. 73
      lib/public/SystemTag/TagUnassignedEvent.php
  6. 33
      tests/lib/SystemTag/SystemTagObjectMapperTest.php

2
lib/composer/composer/autoload_classmap.php

@ -850,8 +850,10 @@ return array(
'OCP\\SystemTag\\MapperEvent' => $baseDir . '/lib/public/SystemTag/MapperEvent.php',
'OCP\\SystemTag\\SystemTagsEntityEvent' => $baseDir . '/lib/public/SystemTag/SystemTagsEntityEvent.php',
'OCP\\SystemTag\\TagAlreadyExistsException' => $baseDir . '/lib/public/SystemTag/TagAlreadyExistsException.php',
'OCP\\SystemTag\\TagAssignedEvent' => $baseDir . '/lib/public/SystemTag/TagAssignedEvent.php',
'OCP\\SystemTag\\TagCreationForbiddenException' => $baseDir . '/lib/public/SystemTag/TagCreationForbiddenException.php',
'OCP\\SystemTag\\TagNotFoundException' => $baseDir . '/lib/public/SystemTag/TagNotFoundException.php',
'OCP\\SystemTag\\TagUnassignedEvent' => $baseDir . '/lib/public/SystemTag/TagUnassignedEvent.php',
'OCP\\SystemTag\\TagUpdateForbiddenException' => $baseDir . '/lib/public/SystemTag/TagUpdateForbiddenException.php',
'OCP\\Talk\\Exceptions\\NoBackendException' => $baseDir . '/lib/public/Talk/Exceptions/NoBackendException.php',
'OCP\\Talk\\IBroker' => $baseDir . '/lib/public/Talk/IBroker.php',

2
lib/composer/composer/autoload_static.php

@ -891,8 +891,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\SystemTag\\MapperEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/MapperEvent.php',
'OCP\\SystemTag\\SystemTagsEntityEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/SystemTagsEntityEvent.php',
'OCP\\SystemTag\\TagAlreadyExistsException' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagAlreadyExistsException.php',
'OCP\\SystemTag\\TagAssignedEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagAssignedEvent.php',
'OCP\\SystemTag\\TagCreationForbiddenException' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagCreationForbiddenException.php',
'OCP\\SystemTag\\TagNotFoundException' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagNotFoundException.php',
'OCP\\SystemTag\\TagUnassignedEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagUnassignedEvent.php',
'OCP\\SystemTag\\TagUpdateForbiddenException' => __DIR__ . '/../../..' . '/lib/public/SystemTag/TagUpdateForbiddenException.php',
'OCP\\Talk\\Exceptions\\NoBackendException' => __DIR__ . '/../../..' . '/lib/public/Talk/Exceptions/NoBackendException.php',
'OCP\\Talk\\IBroker' => __DIR__ . '/../../..' . '/lib/public/Talk/IBroker.php',

10
lib/private/SystemTag/SystemTagObjectMapper.php

@ -17,7 +17,9 @@ use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\MapperEvent;
use OCP\SystemTag\TagAssignedEvent;
use OCP\SystemTag\TagNotFoundException;
use OCP\SystemTag\TagUnassignedEvent;
class SystemTagObjectMapper implements ISystemTagObjectMapper {
public const RELATION_TABLE = 'systemtag_object_mapping';
@ -172,6 +174,7 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
$objId,
$tagsAssigned
));
$this->dispatcher->dispatchTyped(new TagAssignedEvent($objectType, [$objId], $tagsAssigned));
}
/**
@ -202,6 +205,7 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
$objId,
$tagIds
));
$this->dispatcher->dispatchTyped(new TagUnassignedEvent($objectType, [$objId], $tagIds));
}
/**
@ -307,6 +311,9 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
[(int)$tagId]
));
}
if (!empty($removedObjectIds)) {
$this->dispatcher->dispatchTyped(new TagUnassignedEvent($objectType, array_map(fn ($objectId) => (string)$objectId, $removedObjectIds), [(int)$tagId]));
}
if (empty($objectIds)) {
return;
@ -338,6 +345,9 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
[(int)$tagId]
));
}
if (!empty($addedObjectIds)) {
$this->dispatcher->dispatchTyped(new TagAssignedEvent($objectType, array_map(fn ($objectId) => (string)$objectId, $addedObjectIds), [(int)$tagId]));
}
// Dispatch unassign events for removed object ids
foreach ($removedObjectIds as $objectId) {

73
lib/public/SystemTag/TagAssignedEvent.php

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\SystemTag;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IWebhookCompatibleEvent;
/**
* Event class for when a system tag is assigned to an object
*
* @since 32.0.0
*/
class TagAssignedEvent extends Event implements IWebhookCompatibleEvent {
protected string $objectType;
/** @var list<string> */
protected array $objectIds;
/** @var list<int> */
protected array $tags;
/**
* constructor
*
* @param list<string> $objectIds
* @param list<int> $tags
* @since 32.0.0
*/
public function __construct(string $objectType, array $objectIds, array $tags) {
parent::__construct();
$this->objectType = $objectType;
$this->objectIds = $objectIds;
$this->tags = $tags;
}
/**
* @since 32.0.0
*/
public function getObjectType(): string {
return $this->objectType;
}
/**
* @return list<string>
* @since 32.0.0
*/
public function getObjectIds(): array {
return $this->objectIds;
}
/**
* @return list<int>
* @since 32.0.0
*/
public function getTags(): array {
return $this->tags;
}
/**
* @return array{objectType: string, objectIds: list<string>, tagIds: list<int>}
* @since 32.0.0
*/
public function getWebhookSerializable(): array {
return [
'objectType' => $this->getObjectType(),
'objectIds' => $this->getObjectIds(),
'tagIds' => $this->getTags(),
];
}
}

73
lib/public/SystemTag/TagUnassignedEvent.php

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\SystemTag;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IWebhookCompatibleEvent;
/**
* Event class for when a system tag is unassigned from an object
*
* @since 32.0.0
*/
class TagUnassignedEvent extends Event implements IWebhookCompatibleEvent {
protected string $objectType;
/** @var list<string> */
protected array $objectIds;
/** @var list<int> */
protected array $tags;
/**
* constructor
*
* @param list<string> $objectIds
* @param list<int> $tags
* @since 32.0.0
*/
public function __construct(string $objectType, array $objectIds, array $tags) {
parent::__construct();
$this->objectType = $objectType;
$this->objectIds = $objectIds;
$this->tags = $tags;
}
/**
* @since 32.0.0
*/
public function getObjectType(): string {
return $this->objectType;
}
/**
* @return list<string>
* @since 32.0.0
*/
public function getObjectIds(): array {
return $this->objectIds;
}
/**
* @return list<int>
* @since 32.0.0
*/
public function getTags(): array {
return $this->tags;
}
/**
* @return array{objectType: string, objectIds: list<string>, tagIds: list<int>}
* @since 32.0.0
*/
public function getWebhookSerializable(): array {
return [
'objectType' => $this->getObjectType(),
'objectIds' => $this->getObjectIds(),
'tagIds' => $this->getTags(),
];
}
}

33
tests/lib/SystemTag/SystemTagObjectMapperTest.php

@ -11,13 +11,16 @@ namespace Test\SystemTag;
use OC\SystemTag\SystemTag;
use OC\SystemTag\SystemTagManager;
use OC\SystemTag\SystemTagObjectMapper;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IDBConnection;
use OCP\Server;
use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagAssignedEvent;
use OCP\SystemTag\TagNotFoundException;
use OCP\SystemTag\TagUnassignedEvent;
use Test\TestCase;
/**
@ -208,16 +211,46 @@ class SystemTagObjectMapperTest extends TestCase {
}
public function testAssignUnassignTags(): void {
$event = null;
$this->dispatcher->expects($this->any())->method('dispatchTyped')->willReturnCallback(function (Event $e) use (&$event) {
$event = $e;
});
$this->tagMapper->unassignTags('1', 'testtype', [$this->tag1->getId()]);
$this->assertNotNull($event);
$this->assertEquals(TagUnassignedEvent::class, $event::class);
$this->assertEquals('testtype', $event->getObjectType());
$this->assertCount(1, $event->getObjectIds());
$this->assertEquals('1', current($event->getObjectIds()));
$this->assertCount(1, $event->getTags());
$this->assertEquals($this->tag1->getId(), current($event->getTags()));
$tagIdMapping = $this->tagMapper->getTagIdsForObjects('1', 'testtype');
$this->assertEquals([
1 => [$this->tag2->getId()],
], $tagIdMapping);
$this->tagMapper->assignTags('1', 'testtype', [$this->tag1->getId()]);
$this->assertNotNull($event);
$this->assertEquals(TagAssignedEvent::class, $event::class);
$this->assertEquals('testtype', $event->getObjectType());
$this->assertCount(1, $event->getObjectIds());
$this->assertEquals('1', current($event->getObjectIds()));
$this->assertCount(1, $event->getTags());
$this->assertEquals($this->tag1->getId(), current($event->getTags()));
$this->tagMapper->assignTags('1', 'testtype', $this->tag3->getId());
$this->assertNotNull($event);
$this->assertEquals(TagAssignedEvent::class, $event::class);
$this->assertEquals('testtype', $event->getObjectType());
$this->assertCount(1, $event->getObjectIds());
$this->assertEquals('1', current($event->getObjectIds()));
$this->assertCount(1, $event->getTags());
$this->assertEquals($this->tag3->getId(), current($event->getTags()));
$tagIdMapping = $this->tagMapper->getTagIdsForObjects('1', 'testtype');
$this->assertEquals([

Loading…
Cancel
Save