Dispatch events when tags are added/updated/deleted

This commit is contained in:
Joas Schilling 2016-02-01 12:19:48 +01:00
parent 591613fce2
commit d5126b1ad4
4 changed files with 161 additions and 14 deletions

View File

@ -57,7 +57,8 @@ class ManagerFactory implements ISystemTagManagerFactory {
*/
public function getManager() {
return new SystemTagManager(
$this->serverContainer->getDatabaseConnection()
$this->serverContainer->getDatabaseConnection(),
$this->serverContainer->getEventDispatcher()
);
}

View File

@ -26,17 +26,20 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ManagerEvent;
use OCP\SystemTag\TagAlreadyExistsException;
use OCP\SystemTag\TagNotFoundException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class SystemTagManager implements ISystemTagManager {
const TAG_TABLE = 'systemtag';
/**
* @var IDBConnection
*/
private $connection;
/** @var IDBConnection */
protected $connection;
/** @var EventDispatcherInterface */
protected $dispatcher;
/**
* Prepared query for selecting tags directly
@ -46,12 +49,14 @@ class SystemTagManager implements ISystemTagManager {
private $selectTagQuery;
/**
* Constructor.
*
* @param IDBConnection $connection database connection
*/
public function __construct(IDBConnection $connection) {
* Constructor.
*
* @param IDBConnection $connection database connection
* @param EventDispatcherInterface $dispatcher
*/
public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) {
$this->connection = $connection;
$this->dispatcher = $dispatcher;
$query = $this->connection->getQueryBuilder();
$this->selectTagQuery = $query->select('*')
@ -190,14 +195,20 @@ class SystemTagManager implements ISystemTagManager {
);
}
$tagId = $this->connection->lastInsertId('*PREFIX*' . self::TAG_TABLE);
$tagId = $query->getLastInsertId();
return new SystemTag(
$tag = new SystemTag(
(int)$tagId,
$tagName,
(bool)$userVisible,
(bool)$userAssignable
);
$this->dispatcher->dispatch(ManagerEvent::EVENT_CREATE, new ManagerEvent(
ManagerEvent::EVENT_CREATE, $tag
));
return $tag;
}
/**
@ -207,6 +218,22 @@ class SystemTagManager implements ISystemTagManager {
$userVisible = (int)$userVisible;
$userAssignable = (int)$userAssignable;
try {
$tags = $this->getTagsByIds($tagId);
} catch (TagNotFoundException $e) {
throw new TagNotFoundException(
'Tag does not exist', 0, null, [$tagId]
);
}
$beforeUpdate = array_shift($tags);
$afterUpdate = new SystemTag(
(int) $tagId,
$tagName,
(bool) $userVisible,
(bool) $userAssignable
);
$query = $this->connection->getQueryBuilder();
$query->update(self::TAG_TABLE)
->set('name', $query->createParameter('name'))
@ -231,6 +258,10 @@ class SystemTagManager implements ISystemTagManager {
$e
);
}
$this->dispatcher->dispatch(ManagerEvent::EVENT_UPDATE, new ManagerEvent(
ManagerEvent::EVENT_UPDATE, $afterUpdate, $beforeUpdate
));
}
/**
@ -242,10 +273,21 @@ class SystemTagManager implements ISystemTagManager {
}
$tagNotFoundException = null;
$tags = [];
try {
$this->getTagsByIds($tagIds);
$tags = $this->getTagsByIds($tagIds);
} catch (TagNotFoundException $e) {
$tagNotFoundException = $e;
// Get existing tag objects for the hooks later
$existingTags = array_diff($tagIds, $tagNotFoundException->getMissingTags());
if (!empty($existingTags)) {
try {
$tags = $this->getTagsByIds($existingTags);
} catch (TagNotFoundException $e) {
// Ignore further errors...
}
}
}
// delete relationships first
@ -261,6 +303,12 @@ class SystemTagManager implements ISystemTagManager {
->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
->execute();
foreach ($tags as $tag) {
$this->dispatcher->dispatch(ManagerEvent::EVENT_DELETE, new ManagerEvent(
ManagerEvent::EVENT_DELETE, $tag
));
}
if ($tagNotFoundException !== null) {
throw new TagNotFoundException(
'Tag id(s) not found', 0, $tagNotFoundException, $tagNotFoundException->getMissingTags()

View File

@ -0,0 +1,85 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @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/>
*
*/
namespace OCP\SystemTag;
use Symfony\Component\EventDispatcher\Event;
/**
* Class ManagerEvent
*
* @package OCP\SystemTag
* @since 9.0.0
*/
class ManagerEvent extends Event {
const EVENT_CREATE = 'OCP\SystemTag\ISystemTagManager::createTag';
const EVENT_UPDATE = 'OCP\SystemTag\ISystemTagManager::updateTag';
const EVENT_DELETE = 'OCP\SystemTag\ISystemTagManager::deleteTag';
/** @var string */
protected $event;
/** @var ISystemTag */
protected $tag;
/** @var ISystemTag */
protected $beforeTag;
/**
* DispatcherEvent constructor.
*
* @param string $event
* @param ISystemTag $tag
* @param ISystemTag $beforeTag
* @since 9.0.0
*/
public function __construct($event, ISystemTag $tag, ISystemTag $beforeTag = null) {
$this->event = $event;
$this->tag = $tag;
$this->beforeTag = $beforeTag;
}
/**
* @return string
* @since 9.0.0
*/
public function getEvent() {
return $this->event;
}
/**
* @return ISystemTag
* @since 9.0.0
*/
public function getTag() {
return $this->tag;
}
/**
* @return ISystemTag
* @since 9.0.0
*/
public function getTagBefore() {
if ($this->event !== self::EVENT_UPDATE) {
throw new \BadMethodCallException('getTagBefore is only available on the update Event');
}
return $this->beforeTag;
}
}

View File

@ -15,6 +15,7 @@ use OC\SystemTag\SystemTagObjectMapper;
use OCP\IDBConnection;
use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
/**
@ -35,11 +36,23 @@ class SystemTagManagerTest extends TestCase {
*/
private $connection;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function setUp() {
parent::setUp();
$this->connection = \OC::$server->getDatabaseConnection();
$this->tagManager = new SystemTagManager($this->connection);
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')
->getMock();
$this->tagManager = new SystemTagManager(
$this->connection,
$this->dispatcher
);
$this->pruneTagsTables();
}