resolve displayname via manager and registerable resolvers
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
parent
fea3e20a80
commit
5d98ab83e9
6 changed files with 198 additions and 4 deletions
|
@ -71,3 +71,14 @@ $commentsManager->registerEventHandler(function () {
|
||||||
$handler = $application->getContainer()->query(\OCA\Comments\EventHandler::class);
|
$handler = $application->getContainer()->query(\OCA\Comments\EventHandler::class);
|
||||||
return $handler;
|
return $handler;
|
||||||
});
|
});
|
||||||
|
$commentsManager->registerDisplayNameResolver('user', function($id) {
|
||||||
|
$manager = \OC::$server->getUserManager();
|
||||||
|
$user = $manager->get($id);
|
||||||
|
if(is_null($user)) {
|
||||||
|
$l = \OC::$server->getL10N('comments');
|
||||||
|
$displayName = $l->t('Unknown user');
|
||||||
|
} else {
|
||||||
|
$displayName = $user->getDisplayName();
|
||||||
|
}
|
||||||
|
return $displayName;
|
||||||
|
});
|
||||||
|
|
|
@ -45,6 +45,7 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
||||||
const PROPERTY_NAME_MENTION = '{http://owncloud.org/ns}mention';
|
const PROPERTY_NAME_MENTION = '{http://owncloud.org/ns}mention';
|
||||||
const PROPERTY_NAME_MENTION_TYPE = '{http://owncloud.org/ns}mentionType';
|
const PROPERTY_NAME_MENTION_TYPE = '{http://owncloud.org/ns}mentionType';
|
||||||
const PROPERTY_NAME_MENTION_ID = '{http://owncloud.org/ns}mentionId';
|
const PROPERTY_NAME_MENTION_ID = '{http://owncloud.org/ns}mentionId';
|
||||||
|
const PROPERTY_NAME_MENTION_DISPLAYNAME = '{http://owncloud.org/ns}mentionDisplayName';
|
||||||
|
|
||||||
/** @var IComment */
|
/** @var IComment */
|
||||||
public $comment;
|
public $comment;
|
||||||
|
@ -125,6 +126,7 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
||||||
self::PROPERTY_NAME_MENTION,
|
self::PROPERTY_NAME_MENTION,
|
||||||
self::PROPERTY_NAME_MENTION_TYPE,
|
self::PROPERTY_NAME_MENTION_TYPE,
|
||||||
self::PROPERTY_NAME_MENTION_ID,
|
self::PROPERTY_NAME_MENTION_ID,
|
||||||
|
self::PROPERTY_NAME_MENTION_DISPLAYNAME,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,10 +285,19 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
||||||
*/
|
*/
|
||||||
protected function composeMentionsPropertyValue() {
|
protected function composeMentionsPropertyValue() {
|
||||||
return array_map(function($mention) {
|
return array_map(function($mention) {
|
||||||
|
try {
|
||||||
|
$displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']);
|
||||||
|
} catch (\OutOfBoundsException $e) {
|
||||||
|
$this->logger->logException($e);
|
||||||
|
// No displayname, upon client's discretion what to display.
|
||||||
|
$displayName = '';
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
self::PROPERTY_NAME_MENTION => [
|
self::PROPERTY_NAME_MENTION => [
|
||||||
self::PROPERTY_NAME_MENTION_TYPE => $mention['type'],
|
self::PROPERTY_NAME_MENTION_TYPE => $mention['type'],
|
||||||
self::PROPERTY_NAME_MENTION_ID => $mention['id'],
|
self::PROPERTY_NAME_MENTION_ID => $mention['id'],
|
||||||
|
self::PROPERTY_NAME_MENTION_DISPLAYNAME => $displayName,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}, $this->comment->getMentions());
|
}, $this->comment->getMentions());
|
||||||
|
|
|
@ -27,11 +27,14 @@ namespace OCA\DAV\Tests\unit\Comments;
|
||||||
|
|
||||||
use OCA\DAV\Comments\CommentNode;
|
use OCA\DAV\Comments\CommentNode;
|
||||||
use OCP\Comments\IComment;
|
use OCP\Comments\IComment;
|
||||||
|
use OCP\Comments\ICommentsManager;
|
||||||
use OCP\Comments\MessageTooLongException;
|
use OCP\Comments\MessageTooLongException;
|
||||||
|
|
||||||
class CommentsNodeTest extends \Test\TestCase {
|
class CommentsNodeTest extends \Test\TestCase {
|
||||||
|
|
||||||
|
/** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
protected $commentsManager;
|
protected $commentsManager;
|
||||||
|
|
||||||
protected $comment;
|
protected $comment;
|
||||||
protected $node;
|
protected $node;
|
||||||
protected $userManager;
|
protected $userManager;
|
||||||
|
@ -374,8 +377,16 @@ class CommentsNodeTest extends \Test\TestCase {
|
||||||
$ns . 'childrenCount' => 3,
|
$ns . 'childrenCount' => 3,
|
||||||
$ns . 'message' => 'such a nice file you have…',
|
$ns . 'message' => 'such a nice file you have…',
|
||||||
$ns . 'mentions' => [
|
$ns . 'mentions' => [
|
||||||
[ $ns . 'mention' => [ $ns . 'mentionType' => 'user', $ns . 'mentionId' => 'alice'] ],
|
[ $ns . 'mention' => [
|
||||||
[ $ns . 'mention' => [ $ns . 'mentionType' => 'user', $ns . 'mentionId' => 'bob'] ],
|
$ns . 'mentionType' => 'user',
|
||||||
|
$ns . 'mentionId' => 'alice',
|
||||||
|
$ns . 'mentionDisplayName' => 'Alice Al-Isson',
|
||||||
|
] ],
|
||||||
|
[ $ns . 'mention' => [
|
||||||
|
$ns . 'mentionType' => 'user',
|
||||||
|
$ns . 'mentionId' => 'bob',
|
||||||
|
$ns . 'mentionDisplayName' => 'Unknown user',
|
||||||
|
] ],
|
||||||
],
|
],
|
||||||
$ns . 'verb' => 'comment',
|
$ns . 'verb' => 'comment',
|
||||||
$ns . 'actorType' => 'users',
|
$ns . 'actorType' => 'users',
|
||||||
|
@ -388,6 +399,14 @@ class CommentsNodeTest extends \Test\TestCase {
|
||||||
$ns . 'isUnread' => null,
|
$ns . 'isUnread' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$this->commentsManager->expects($this->exactly(2))
|
||||||
|
->method('resolveDisplayName')
|
||||||
|
->withConsecutive(
|
||||||
|
[$this->equalTo('user'), $this->equalTo('alice')],
|
||||||
|
[$this->equalTo('user'), $this->equalTo('bob')]
|
||||||
|
)
|
||||||
|
->willReturnOnConsecutiveCalls('Alice Al-Isson', 'Unknown user');
|
||||||
|
|
||||||
$this->comment->expects($this->once())
|
$this->comment->expects($this->once())
|
||||||
->method('getId')
|
->method('getId')
|
||||||
->will($this->returnValue($expected[$ns . 'id']));
|
->will($this->returnValue($expected[$ns . 'id']));
|
||||||
|
|
|
@ -55,6 +55,9 @@ class Manager implements ICommentsManager {
|
||||||
/** @var ICommentsEventHandler[] */
|
/** @var ICommentsEventHandler[] */
|
||||||
protected $eventHandlers = [];
|
protected $eventHandlers = [];
|
||||||
|
|
||||||
|
/** @var \Closure[] */
|
||||||
|
protected $displayNameResolvers = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager constructor.
|
* Manager constructor.
|
||||||
*
|
*
|
||||||
|
@ -759,6 +762,50 @@ class Manager implements ICommentsManager {
|
||||||
$this->eventHandlers = [];
|
$this->eventHandlers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers a method that resolves an ID to a display name for a given type
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param \Closure $closure
|
||||||
|
* @throws \OutOfBoundsException
|
||||||
|
* @since 9.2.0
|
||||||
|
*
|
||||||
|
* Only one resolver shall be registered per type. Otherwise a
|
||||||
|
* \OutOfBoundsException has to thrown.
|
||||||
|
*/
|
||||||
|
public function registerDisplayNameResolver($type, \Closure $closure) {
|
||||||
|
if(!is_string($type)) {
|
||||||
|
throw new \InvalidArgumentException('String expected.');
|
||||||
|
}
|
||||||
|
if(isset($this->displayNameResolvers[$type])) {
|
||||||
|
throw new \OutOfBoundsException('Displayname resolver for this type already registered');
|
||||||
|
}
|
||||||
|
$this->displayNameResolvers[$type] = $closure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resolves a given ID of a given Type to a display name.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $id
|
||||||
|
* @return string
|
||||||
|
* @throws \OutOfBoundsException
|
||||||
|
* @since 9.2.0
|
||||||
|
*
|
||||||
|
* If a provided type was not registered, an \OutOfBoundsException shall
|
||||||
|
* be thrown. It is upon the resolver discretion what to return of the
|
||||||
|
* provided ID is unknown. It must be ensured that a string is returned.
|
||||||
|
*/
|
||||||
|
public function resolveDisplayName($type, $id) {
|
||||||
|
if(!is_string($type)) {
|
||||||
|
throw new \InvalidArgumentException('String expected.');
|
||||||
|
}
|
||||||
|
if(!isset($this->displayNameResolvers[$type])) {
|
||||||
|
throw new \OutOfBoundsException('No Displayname resolver for this type registered');
|
||||||
|
}
|
||||||
|
return (string)$this->displayNameResolvers[$type]($id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns valid, registered entities
|
* returns valid, registered entities
|
||||||
*
|
*
|
||||||
|
|
|
@ -246,4 +246,32 @@ interface ICommentsManager {
|
||||||
*/
|
*/
|
||||||
public function registerEventHandler(\Closure $closure);
|
public function registerEventHandler(\Closure $closure);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers a method that resolves an ID to a display name for a given type
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param \Closure $closure
|
||||||
|
* @throws \OutOfBoundsException
|
||||||
|
* @since 9.2.0
|
||||||
|
*
|
||||||
|
* Only one resolver shall be registered per type. Otherwise a
|
||||||
|
* \OutOfBoundsException has to thrown.
|
||||||
|
*/
|
||||||
|
public function registerDisplayNameResolver($type, \Closure $closure);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resolves a given ID of a given Type to a display name.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $id
|
||||||
|
* @return string
|
||||||
|
* @throws \OutOfBoundsException
|
||||||
|
* @since 9.2.0
|
||||||
|
*
|
||||||
|
* If a provided type was not registered, an \OutOfBoundsException shall
|
||||||
|
* be thrown. It is upon the resolver discretion what to return of the
|
||||||
|
* provided ID is unknown. It must be ensured that a string is returned.
|
||||||
|
*/
|
||||||
|
public function resolveDisplayName($type, $id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,4 +664,82 @@ class ManagerTest extends TestCase {
|
||||||
$manager->delete($comment->getId());
|
$manager->delete($comment->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testResolveDisplayName() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
};
|
||||||
|
|
||||||
|
$galaxyClosure = function($name) {
|
||||||
|
return strtoupper($name);
|
||||||
|
};
|
||||||
|
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
$manager->registerDisplayNameResolver('galaxy', $galaxyClosure);
|
||||||
|
|
||||||
|
$this->assertSame('Neptune', $manager->resolveDisplayName('planet', 'neptune'));
|
||||||
|
$this->assertSame('SOMBRERO', $manager->resolveDisplayName('galaxy', 'sombrero'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \OutOfBoundsException
|
||||||
|
*/
|
||||||
|
public function testRegisterResolverDuplicate() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
};
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testRegisterResolverInvalidType() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
};
|
||||||
|
$manager->registerDisplayNameResolver(1337, $planetClosure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \OutOfBoundsException
|
||||||
|
*/
|
||||||
|
public function testResolveDisplayNameUnregisteredType() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
};
|
||||||
|
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
$manager->resolveDisplayName('galaxy', 'sombrero');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testResolveDisplayNameDirtyResolver() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function() { return null; };
|
||||||
|
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
$this->assertTrue(is_string($manager->resolveDisplayName('planet', 'neptune')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testResolveDisplayNameInvalidType() {
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$planetClosure = function() { return null; };
|
||||||
|
|
||||||
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
$this->assertTrue(is_string($manager->resolveDisplayName(1337, 'neptune')));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue