Merge pull request #22049 from owncloud/issue-22041-activities-for-systemtags
Issue 22041 activities for systemtags
This commit is contained in:
commit
2d1d89ee29
13 changed files with 875 additions and 42 deletions
300
apps/systemtags/activity/extension.php
Normal file
300
apps/systemtags/activity/extension.php
Normal file
|
@ -0,0 +1,300 @@
|
|||
<?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 OCA\SystemTags\Activity;
|
||||
|
||||
use OCP\Activity\IExtension;
|
||||
use OCP\Activity\IManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
|
||||
/**
|
||||
* Class Extension
|
||||
*
|
||||
* @package OCA\SystemTags\Activity
|
||||
*/
|
||||
class Extension implements IExtension {
|
||||
const APP_NAME = 'systemtags';
|
||||
|
||||
const CREATE_TAG = 'create_tag';
|
||||
const UPDATE_TAG = 'update_tag';
|
||||
const DELETE_TAG = 'delete_tag';
|
||||
|
||||
const ASSIGN_TAG = 'assign_tag';
|
||||
const UNASSIGN_TAG = 'unassign_tag';
|
||||
|
||||
/** @var IFactory */
|
||||
protected $languageFactory;
|
||||
|
||||
/** @var IManager */
|
||||
protected $activityManager;
|
||||
|
||||
/**
|
||||
* @param IFactory $languageFactory
|
||||
* @param IManager $activityManager
|
||||
*/
|
||||
public function __construct(IFactory $languageFactory, IManager $activityManager) {
|
||||
$this->languageFactory = $languageFactory;
|
||||
$this->activityManager = $activityManager;
|
||||
}
|
||||
|
||||
protected function getL10N($languageCode = null) {
|
||||
return $this->languageFactory->get(self::APP_NAME, $languageCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can return an array of additional notification types.
|
||||
* If no additional types are to be added false is to be returned
|
||||
*
|
||||
* @param string $languageCode
|
||||
* @return array|false
|
||||
*/
|
||||
public function getNotificationTypes($languageCode) {
|
||||
$l = $this->getL10N($languageCode);
|
||||
|
||||
return array(
|
||||
self::APP_NAME => (string) $l->t('<strong>System tags</strong> for a file have been modified'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given method additional types to be displayed in the settings can be returned.
|
||||
* In case no additional types are to be added false is to be returned.
|
||||
*
|
||||
* @param string $method
|
||||
* @return array|false
|
||||
*/
|
||||
public function getDefaultTypes($method) {
|
||||
return [self::APP_NAME];
|
||||
}
|
||||
|
||||
/**
|
||||
* A string naming the css class for the icon to be used can be returned.
|
||||
* If no icon is known for the given type false is to be returned.
|
||||
*
|
||||
* @param string $type
|
||||
* @return string|false
|
||||
*/
|
||||
public function getTypeIcon($type) {
|
||||
switch ($type) {
|
||||
case self::APP_NAME:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can translate a given message to the requested languages.
|
||||
* If no translation is available false is to be returned.
|
||||
*
|
||||
* @param string $app
|
||||
* @param string $text
|
||||
* @param array $params
|
||||
* @param boolean $stripPath
|
||||
* @param boolean $highlightParams
|
||||
* @param string $languageCode
|
||||
* @return string|false
|
||||
*/
|
||||
public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
|
||||
if ($app !== self::APP_NAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$l = $this->getL10N($languageCode);
|
||||
|
||||
if ($this->activityManager->isFormattingFilteredObject()) {
|
||||
$translation = $this->translateShort($text, $l, $params);
|
||||
if ($translation !== false) {
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->translateLong($text, $l, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param IL10N $l
|
||||
* @param array $params
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function translateShort($text, IL10N $l, array $params) {
|
||||
|
||||
switch ($text) {
|
||||
case self::ASSIGN_TAG:
|
||||
$params[2] = $this->convertParameterToTag($params[2], $l);
|
||||
return (string) $l->t('%1$s assigned system tag %3$s', $params);
|
||||
case self::UNASSIGN_TAG:
|
||||
$params[2] = $this->convertParameterToTag($params[2], $l);
|
||||
return (string) $l->t('%1$s unassigned system tag %3$s', $params);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param IL10N $l
|
||||
* @param array $params
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function translateLong($text, IL10N $l, array $params) {
|
||||
|
||||
switch ($text) {
|
||||
case self::CREATE_TAG:
|
||||
$params[1] = $this->convertParameterToTag($params[1], $l);
|
||||
return (string) $l->t('%1$s created system tag %2$s', $params);
|
||||
case self::DELETE_TAG:
|
||||
$params[1] = $this->convertParameterToTag($params[1], $l);
|
||||
return (string) $l->t('%1$s deleted system tag %2$s', $params);
|
||||
case self::UPDATE_TAG:
|
||||
$params[1] = $this->convertParameterToTag($params[1], $l);
|
||||
$params[2] = $this->convertParameterToTag($params[2], $l);
|
||||
return (string) $l->t('%1$s updated system tag %3$s to %2$s', $params);
|
||||
case self::ASSIGN_TAG:
|
||||
$params[2] = $this->convertParameterToTag($params[2], $l);
|
||||
return (string) $l->t('%1$s assigned system tag %3$s to %2$s', $params);
|
||||
case self::UNASSIGN_TAG:
|
||||
$params[2] = $this->convertParameterToTag($params[2], $l);
|
||||
return (string) $l->t('%1$s unassigned system tag %3$s from %2$s', $params);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define the type of parameters for translation
|
||||
*
|
||||
* Currently known types are:
|
||||
* * file => will strip away the path of the file and add a tooltip with it
|
||||
* * username => will add the avatar of the user
|
||||
*
|
||||
* @param string $app
|
||||
* @param string $text
|
||||
* @return array|false
|
||||
*/
|
||||
public function getSpecialParameterList($app, $text) {
|
||||
if ($app === self::APP_NAME) {
|
||||
switch ($text) {
|
||||
case self::CREATE_TAG:
|
||||
case self::DELETE_TAG:
|
||||
return array(
|
||||
0 => 'username',
|
||||
//1 => 'systemtag description',
|
||||
);
|
||||
case self::UPDATE_TAG:
|
||||
return array(
|
||||
0 => 'username',
|
||||
//1 => 'systemtag description',
|
||||
//2 => 'systemtag description',
|
||||
);
|
||||
|
||||
case self::ASSIGN_TAG:
|
||||
case self::UNASSIGN_TAG:
|
||||
return array(
|
||||
0 => 'username',
|
||||
1 => 'file',
|
||||
//2 => 'systemtag description',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define the parameter grouping by returning the index as integer.
|
||||
* In case no grouping is required false is to be returned.
|
||||
*
|
||||
* @param array $activity
|
||||
* @return integer|false
|
||||
*/
|
||||
public function getGroupParameter($activity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can define additional navigation entries. The array returned has to contain two keys 'top'
|
||||
* and 'apps' which hold arrays with the relevant entries.
|
||||
* If no further entries are to be added false is no be returned.
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function getNavigation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can check if a custom filter (given by a query string like filter=abc) is valid or not.
|
||||
*
|
||||
* @param string $filterValue
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFilterValid($filterValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension can filter the types based on the filter if required.
|
||||
* In case no filter is to be applied false is to be returned unchanged.
|
||||
*
|
||||
* @param array $types
|
||||
* @param string $filter
|
||||
* @return array|false
|
||||
*/
|
||||
public function filterNotificationTypes($types, $filter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given filter the extension can specify the sql query conditions including parameters for that query.
|
||||
* In case the extension does not know the filter false is to be returned.
|
||||
* The query condition and the parameters are to be returned as array with two elements.
|
||||
* E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%'));
|
||||
*
|
||||
* @param string $filter
|
||||
* @return array|false
|
||||
*/
|
||||
public function getQueryForFilter($filter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $parameter
|
||||
* @param IL10N $l
|
||||
* @return string
|
||||
*/
|
||||
protected function convertParameterToTag($parameter, IL10N $l) {
|
||||
if (preg_match('/^\<parameter\>\{\{\{(.*)\|\|\|(.*)\}\}\}\<\/parameter\>$/', $parameter, $matches)) {
|
||||
switch ($matches[2]) {
|
||||
case 'assignable':
|
||||
return '<parameter>' . $matches[1] . '</parameter>';
|
||||
case 'not-assignable':
|
||||
return '<parameter>' . $l->t('%s (not-assignable)', $matches[1]) . '</parameter>';
|
||||
case 'invisible':
|
||||
return '<parameter>' . $l->t('%s (invisible)', $matches[1]) . '</parameter>';
|
||||
}
|
||||
}
|
||||
|
||||
return $parameter;
|
||||
}
|
||||
}
|
223
apps/systemtags/activity/listener.php
Normal file
223
apps/systemtags/activity/listener.php
Normal file
|
@ -0,0 +1,223 @@
|
|||
<?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 OCA\SystemTags\Activity;
|
||||
|
||||
use OCP\Activity\IManager;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Files\Config\IMountProviderCollection;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Share;
|
||||
use OCP\SystemTag\ISystemTag;
|
||||
use OCP\SystemTag\ISystemTagManager;
|
||||
use OCP\SystemTag\ManagerEvent;
|
||||
use OCP\SystemTag\MapperEvent;
|
||||
use OCP\SystemTag\TagNotFoundException;
|
||||
|
||||
class Listener {
|
||||
/** @var IGroupManager */
|
||||
protected $groupManager;
|
||||
/** @var IManager */
|
||||
protected $activityManager;
|
||||
/** @var IUserSession */
|
||||
protected $session;
|
||||
/** @var \OCP\SystemTag\ISystemTagManager */
|
||||
protected $tagManager;
|
||||
/** @var \OCP\App\IAppManager */
|
||||
protected $appManager;
|
||||
/** @var \OCP\Files\Config\IMountProviderCollection */
|
||||
protected $mountCollection;
|
||||
/** @var \OCP\Files\IRootFolder */
|
||||
protected $rootFolder;
|
||||
|
||||
/**
|
||||
* Listener constructor.
|
||||
*
|
||||
* @param IGroupManager $groupManager
|
||||
* @param IManager $activityManager
|
||||
* @param IUserSession $session
|
||||
* @param ISystemTagManager $tagManager
|
||||
* @param IAppManager $appManager
|
||||
* @param IMountProviderCollection $mountCollection
|
||||
* @param IRootFolder $rootFolder
|
||||
*/
|
||||
public function __construct(IGroupManager $groupManager,
|
||||
IManager $activityManager,
|
||||
IUserSession $session,
|
||||
ISystemTagManager $tagManager,
|
||||
IAppManager $appManager,
|
||||
IMountProviderCollection $mountCollection,
|
||||
IRootFolder $rootFolder) {
|
||||
$this->groupManager = $groupManager;
|
||||
$this->activityManager = $activityManager;
|
||||
$this->session = $session;
|
||||
$this->tagManager = $tagManager;
|
||||
$this->appManager = $appManager;
|
||||
$this->mountCollection = $mountCollection;
|
||||
$this->rootFolder = $rootFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ManagerEvent $event
|
||||
*/
|
||||
public function event(ManagerEvent $event) {
|
||||
$actor = $this->session->getUser();
|
||||
if ($actor instanceof IUser) {
|
||||
$actor = $actor->getUID();
|
||||
} else {
|
||||
$actor = '';
|
||||
}
|
||||
|
||||
$activity = $this->activityManager->generateEvent();
|
||||
$activity->setApp(Extension::APP_NAME)
|
||||
->setType(Extension::APP_NAME)
|
||||
->setAuthor($actor);
|
||||
if ($event->getEvent() === ManagerEvent::EVENT_CREATE) {
|
||||
$activity->setSubject(Extension::CREATE_TAG, [
|
||||
$actor,
|
||||
$this->prepareTagAsParameter($event->getTag()),
|
||||
]);
|
||||
} else if ($event->getEvent() === ManagerEvent::EVENT_UPDATE) {
|
||||
$activity->setSubject(Extension::UPDATE_TAG, [
|
||||
$actor,
|
||||
$this->prepareTagAsParameter($event->getTag()),
|
||||
$this->prepareTagAsParameter($event->getTagBefore()),
|
||||
]);
|
||||
} else if ($event->getEvent() === ManagerEvent::EVENT_DELETE) {
|
||||
$activity->setSubject(Extension::DELETE_TAG, [
|
||||
$actor,
|
||||
$this->prepareTagAsParameter($event->getTag()),
|
||||
]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$group = $this->groupManager->get('admin');
|
||||
if ($group instanceof IGroup) {
|
||||
foreach ($group->getUsers() as $user) {
|
||||
$activity->setAffectedUser($user->getUID());
|
||||
$this->activityManager->publish($activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MapperEvent $event
|
||||
*/
|
||||
public function mapperEvent(MapperEvent $event) {
|
||||
$tagIds = $event->getTags();
|
||||
if ($event->getObjectType() !== 'files' ||empty($tagIds)
|
||||
|| !in_array($event->getEvent(), [MapperEvent::EVENT_ASSIGN, MapperEvent::EVENT_UNASSIGN])
|
||||
|| !$this->appManager->isInstalled('activity')) {
|
||||
// System tags not for files, no tags, not (un-)assigning or no activity-app enabled (save the energy)
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$tags = $this->tagManager->getTagsByIds($tagIds);
|
||||
} catch (TagNotFoundException $e) {
|
||||
// User assigned/unassigned a non-existing tag, ignore...
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($tags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all mount point owners
|
||||
$cache = $this->mountCollection->getMountCache();
|
||||
$mounts = $cache->getMountsForFileId($event->getObjectId());
|
||||
if (empty($mounts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$users = [];
|
||||
foreach ($mounts as $mount) {
|
||||
$owner = $mount->getUser()->getUID();
|
||||
$ownerFolder = $this->rootFolder->getUserFolder($owner);
|
||||
$nodes = $ownerFolder->getById($event->getObjectId());
|
||||
if (!empty($nodes)) {
|
||||
/** @var Node $node */
|
||||
$node = array_shift($nodes);
|
||||
$path = $node->getPath();
|
||||
if (strpos($path, '/' . $owner . '/files/') === 0) {
|
||||
$path = substr($path, strlen('/' . $owner . '/files'));
|
||||
}
|
||||
// Get all users that have access to the mount point
|
||||
$users = array_merge($users, Share::getUsersSharingFile($path, $owner, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
$actor = $this->session->getUser();
|
||||
if ($actor instanceof IUser) {
|
||||
$actor = $actor->getUID();
|
||||
} else {
|
||||
$actor = '';
|
||||
}
|
||||
|
||||
$activity = $this->activityManager->generateEvent();
|
||||
$activity->setApp(Extension::APP_NAME)
|
||||
->setType(Extension::APP_NAME)
|
||||
->setAuthor($actor)
|
||||
->setObject($event->getObjectType(), $event->getObjectId());
|
||||
|
||||
foreach ($users as $user => $path) {
|
||||
$activity->setAffectedUser($user);
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if ($event->getEvent() === MapperEvent::EVENT_ASSIGN) {
|
||||
$activity->setSubject(Extension::ASSIGN_TAG, [
|
||||
$actor,
|
||||
$path,
|
||||
$this->prepareTagAsParameter($tag),
|
||||
]);
|
||||
} else if ($event->getEvent() === MapperEvent::EVENT_UNASSIGN) {
|
||||
$activity->setSubject(Extension::UNASSIGN_TAG, [
|
||||
$actor,
|
||||
$path,
|
||||
$this->prepareTagAsParameter($tag),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->activityManager->publish($activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ISystemTag $tag
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareTagAsParameter(ISystemTag $tag) {
|
||||
if (!$tag->isUserVisible()) {
|
||||
return '{{{' . $tag->getName() . '|||invisible}}}';
|
||||
} else if (!$tag->isUserAssignable()) {
|
||||
return '{{{' . $tag->getName() . '|||not-assignable}}}';
|
||||
} else {
|
||||
return '{{{' . $tag->getName() . '|||assignable}}}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use OCA\SystemTags\Activity\Extension;
|
||||
use OCA\SystemTags\Activity\Listener;
|
||||
use OCP\SystemTag\ManagerEvent;
|
||||
use OCP\SystemTag\MapperEvent;
|
||||
|
||||
$eventDispatcher = \OC::$server->getEventDispatcher();
|
||||
$eventDispatcher->addListener(
|
||||
'OCA\Files::loadAdditionalScripts',
|
||||
|
@ -39,3 +44,32 @@ $eventDispatcher->addListener(
|
|||
\OCP\Util::addStyle('systemtags');
|
||||
}
|
||||
);
|
||||
|
||||
$activityManager = \OC::$server->getActivityManager();
|
||||
$activityManager->registerExtension(function() {
|
||||
$application = new \OCP\AppFramework\App('systemtags');
|
||||
/** @var \OCA\SystemTags\Activity\Extension $extension */
|
||||
$extension = $application->getContainer()->query('OCA\SystemTags\Activity\Extension');
|
||||
return $extension;
|
||||
});
|
||||
|
||||
$managerListener = function(ManagerEvent $event) use ($activityManager) {
|
||||
$application = new \OCP\AppFramework\App('systemtags');
|
||||
/** @var \OCA\SystemTags\Activity\Listener $listener */
|
||||
$listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener');
|
||||
$listener->event($event);
|
||||
};
|
||||
|
||||
$eventDispatcher->addListener(ManagerEvent::EVENT_CREATE, $managerListener);
|
||||
$eventDispatcher->addListener(ManagerEvent::EVENT_DELETE, $managerListener);
|
||||
$eventDispatcher->addListener(ManagerEvent::EVENT_UPDATE, $managerListener);
|
||||
|
||||
$mapperListener = function(MapperEvent $event) use ($activityManager) {
|
||||
$application = new \OCP\AppFramework\App('systemtags');
|
||||
/** @var \OCA\SystemTags\Activity\Listener $listener */
|
||||
$listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener');
|
||||
$listener->mapperEvent($event);
|
||||
};
|
||||
|
||||
$eventDispatcher->addListener(MapperEvent::EVENT_ASSIGN, $mapperListener);
|
||||
$eventDispatcher->addListener(MapperEvent::EVENT_UNASSIGN, $mapperListener);
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
<licence>AGPL</licence>
|
||||
<author>Vincent Petry</author>
|
||||
<default_enable/>
|
||||
<version>0.1</version>
|
||||
<version>0.2</version>
|
||||
<dependencies>
|
||||
<owncloud min-version="9.0" max-version="9.0" />
|
||||
</dependencies>
|
||||
<documentation>
|
||||
<user>user-systemtags</user>
|
||||
</documentation>
|
||||
<types>
|
||||
<logging/>
|
||||
</types>
|
||||
</info>
|
||||
|
|
|
@ -310,20 +310,19 @@ class ActivityManager implements IManager {
|
|||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $id
|
||||
* @param string $id
|
||||
*/
|
||||
public function setFormattingObject($type, $id) {
|
||||
$this->formattingObjectType = $type;
|
||||
$this->formattingObjectId = $id;
|
||||
$this->formattingObjectId = (string) $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFormattingFilteredObject() {
|
||||
return 'filter' === $this->request->getParam('filter')
|
||||
&& $this->formattingObjectType === $this->request->getParam('objecttype')
|
||||
&& $this->formattingObjectId === $this->request->getParam('objectid');
|
||||
return $this->formattingObjectType === $this->request->getParam('object_type')
|
||||
&& $this->formattingObjectId === $this->request->getParam('object_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -152,6 +152,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
|||
return $this->getServer()->getL10N($c->query('AppName'));
|
||||
});
|
||||
|
||||
$this->registerService('OCP\\L10N\\IFactory', function($c) {
|
||||
return $this->getServer()->getL10NFactory();
|
||||
});
|
||||
|
||||
$this->registerService('OCP\\ILogger', function($c) {
|
||||
return $this->getServer()->getLogger();
|
||||
});
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
*/
|
||||
namespace OC\SystemTag;
|
||||
|
||||
use OCP\SystemTag\ISystemTagManagerFactory;
|
||||
use OCP\SystemTag\ISystemTagManager;
|
||||
use OC\SystemTag\SystemTagManager;
|
||||
use OC\SystemTag\SystemTagObjectMapper;
|
||||
use OCP\IServerContainer;
|
||||
use OCP\SystemTag\ISystemTagManager;
|
||||
use OCP\SystemTag\ISystemTagManagerFactory;
|
||||
use OCP\SystemTag\ISystemTagObjectMapper;
|
||||
|
||||
/**
|
||||
* Default factory class for system tag managers
|
||||
|
@ -58,7 +57,8 @@ class ManagerFactory implements ISystemTagManagerFactory {
|
|||
*/
|
||||
public function getManager() {
|
||||
return new SystemTagManager(
|
||||
$this->serverContainer->getDatabaseConnection()
|
||||
$this->serverContainer->getDatabaseConnection(),
|
||||
$this->serverContainer->getEventDispatcher()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,8 @@ class ManagerFactory implements ISystemTagManagerFactory {
|
|||
public function getObjectMapper() {
|
||||
return new SystemTagObjectMapper(
|
||||
$this->serverContainer->getDatabaseConnection(),
|
||||
$this->getManager()
|
||||
$this->getManager(),
|
||||
$this->serverContainer->getEventDispatcher()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -28,31 +28,34 @@ use OCP\IDBConnection;
|
|||
use OCP\SystemTag\ISystemTag;
|
||||
use OCP\SystemTag\ISystemTagManager;
|
||||
use OCP\SystemTag\ISystemTagObjectMapper;
|
||||
use OCP\SystemTag\MapperEvent;
|
||||
use OCP\SystemTag\TagNotFoundException;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class SystemTagObjectMapper implements ISystemTagObjectMapper {
|
||||
|
||||
const RELATION_TABLE = 'systemtag_object_mapping';
|
||||
|
||||
/**
|
||||
* @var ISystemTagManager
|
||||
*/
|
||||
private $tagManager;
|
||||
/** @var ISystemTagManager */
|
||||
protected $tagManager;
|
||||
|
||||
/**
|
||||
* @var IDBConnection
|
||||
*/
|
||||
private $connection;
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var EventDispatcherInterface */
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param IDBConnection $connection database connection
|
||||
* @param ISystemTagManager $tagManager system tag manager
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(IDBConnection $connection, ISystemTagManager $tagManager) {
|
||||
public function __construct(IDBConnection $connection, ISystemTagManager $tagManager, EventDispatcherInterface $dispatcher) {
|
||||
$this->connection = $connection;
|
||||
$this->tagManager = $tagManager;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,6 +146,13 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
|
|||
// ignore existing relations
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(MapperEvent::EVENT_ASSIGN, new MapperEvent(
|
||||
MapperEvent::EVENT_ASSIGN,
|
||||
$objectType,
|
||||
$objId,
|
||||
$tagIds
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,6 +174,13 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
|
|||
->setParameter('objecttype', $objectType)
|
||||
->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
|
||||
->execute();
|
||||
|
||||
$this->dispatcher->dispatch(MapperEvent::EVENT_UNASSIGN, new MapperEvent(
|
||||
MapperEvent::EVENT_UNASSIGN,
|
||||
$objectType,
|
||||
$objId,
|
||||
$tagIds
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
85
lib/public/systemtag/managerevent.php
Normal file
85
lib/public/systemtag/managerevent.php
Normal 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;
|
||||
}
|
||||
}
|
93
lib/public/systemtag/mapperevent.php
Normal file
93
lib/public/systemtag/mapperevent.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?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 MapperEvent
|
||||
*
|
||||
* @package OCP\SystemTag
|
||||
* @since 9.0.0
|
||||
*/
|
||||
class MapperEvent extends Event {
|
||||
|
||||
const EVENT_ASSIGN = 'OCP\SystemTag\ISystemTagObjectMapper::assignTags';
|
||||
const EVENT_UNASSIGN = 'OCP\SystemTag\ISystemTagObjectMapper::unassignTags';
|
||||
|
||||
/** @var string */
|
||||
protected $event;
|
||||
/** @var string */
|
||||
protected $objectType;
|
||||
/** @var string */
|
||||
protected $objectId;
|
||||
/** @var int[] */
|
||||
protected $tags;
|
||||
|
||||
/**
|
||||
* DispatcherEvent constructor.
|
||||
*
|
||||
* @param string $event
|
||||
* @param string $objectType
|
||||
* @param string $objectId
|
||||
* @param int[] $tags
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function __construct($event, $objectType, $objectId, array $tags) {
|
||||
$this->event = $event;
|
||||
$this->objectType = $objectType;
|
||||
$this->objectId = $objectId;
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getEvent() {
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getObjectType() {
|
||||
return $this->objectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getObjectId() {
|
||||
return $this->objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getTags() {
|
||||
return $this->tags;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -378,7 +391,7 @@ class SystemTagManagerTest extends TestCase {
|
|||
$tag1 = $this->tagManager->createTag('one', true, false);
|
||||
$tag2 = $this->tagManager->createTag('two', true, true);
|
||||
|
||||
$tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager);
|
||||
$tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager, $this->dispatcher);
|
||||
|
||||
$tagMapper->assignTags(1, 'testtype', $tag1->getId());
|
||||
$tagMapper->assignTags(1, 'testtype', $tag2->getId());
|
||||
|
|
|
@ -10,14 +10,15 @@
|
|||
|
||||
namespace Test\SystemTag;
|
||||
|
||||
use OC\SystemTag\SystemTag;
|
||||
use OC\SystemTag\SystemTagManager;
|
||||
use OC\SystemTag\SystemTagObjectMapper;
|
||||
use \OCP\SystemTag\ISystemTag;
|
||||
use \OCP\SystemTag\ISystemTagManager;
|
||||
use \OCP\SystemTag\ISystemTagObjectMapper;
|
||||
use \OCP\SystemTag\TagNotFoundException;
|
||||
use \OCP\IDBConnection;
|
||||
use \OC\SystemTag\SystemTag;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\SystemTag\ISystemTag;
|
||||
use OCP\SystemTag\ISystemTagManager;
|
||||
use OCP\SystemTag\ISystemTagObjectMapper;
|
||||
use OCP\SystemTag\TagNotFoundException;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
|
@ -43,6 +44,11 @@ class SystemTagObjectMapperTest extends TestCase {
|
|||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
private $dispatcher;
|
||||
|
||||
/**
|
||||
* @var ISystemTag
|
||||
*/
|
||||
|
@ -67,7 +73,14 @@ class SystemTagObjectMapperTest extends TestCase {
|
|||
$this->tagManager = $this->getMockBuilder('OCP\SystemTag\ISystemTagManager')
|
||||
->getMock();
|
||||
|
||||
$this->tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager);
|
||||
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')
|
||||
->getMock();
|
||||
|
||||
$this->tagMapper = new SystemTagObjectMapper(
|
||||
$this->connection,
|
||||
$this->tagManager,
|
||||
$this->dispatcher
|
||||
);
|
||||
|
||||
$this->tag1 = new SystemTag(1, 'testtag1', false, false);
|
||||
$this->tag2 = new SystemTag(2, 'testtag2', true, false);
|
||||
|
|
Loading…
Reference in a new issue