]> source.dussan.org Git - nextcloud-server.git/commitdiff
Dispatch events when tags are added/updated/deleted
authorJoas Schilling <nickvergessen@owncloud.com>
Mon, 1 Feb 2016 11:19:48 +0000 (12:19 +0100)
committerJoas Schilling <nickvergessen@owncloud.com>
Tue, 2 Feb 2016 08:57:42 +0000 (09:57 +0100)
lib/private/systemtag/managerfactory.php
lib/private/systemtag/systemtagmanager.php
lib/public/systemtag/managerevent.php [new file with mode: 0644]
tests/lib/systemtag/systemtagmanagertest.php

index 2939caacde8ee2a63908803e2c6dcb4fe62ad5f4..7ad4f922600e26ede6ab441b1497e018608b1911 100644 (file)
@@ -57,7 +57,8 @@ class ManagerFactory implements ISystemTagManagerFactory {
         */
        public function getManager() {
                return new SystemTagManager(
-                       $this->serverContainer->getDatabaseConnection()
+                       $this->serverContainer->getDatabaseConnection(),
+                       $this->serverContainer->getEventDispatcher()
                );
        }
 
index af912a74936f049fded76e9e0edee670aff7f6e3..76a60a91328276384d71a91bab90967e59711380 100644 (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()
diff --git a/lib/public/systemtag/managerevent.php b/lib/public/systemtag/managerevent.php
new file mode 100644 (file)
index 0000000..a0429fc
--- /dev/null
@@ -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;
+       }
+}
index f8d711774797f2964912754e0acc62a5f6ca4c8d..64220205ade928d9268db1245beeddbf5e1be29d 100644 (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();
        }