* introduce a Controller for requests * introduce result sorting mechanism * extend Comments to retrieve commentors (actors) in a tree * add commenters sorter * add share recipients sorter Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>pull/6779/head
parent
2b31b82891
commit
fd6daf8d19
@ -0,0 +1,93 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\Comments\Collaboration; |
||||
|
||||
|
||||
use OCP\Collaboration\AutoComplete\ISorter; |
||||
use OCP\Comments\ICommentsManager; |
||||
|
||||
class CommentersSorter implements ISorter { |
||||
|
||||
/** @var ICommentsManager */ |
||||
private $commentsManager; |
||||
|
||||
public function __construct(ICommentsManager $commentsManager) { |
||||
$this->commentsManager = $commentsManager; |
||||
} |
||||
|
||||
public function getId() { |
||||
return 'commenters'; |
||||
} |
||||
|
||||
/** |
||||
* Sorts people who commented on the given item atop (descelating) of the |
||||
* others |
||||
* |
||||
* @param array $sortArray |
||||
* @param array $context |
||||
*/ |
||||
public function sort(array &$sortArray, array $context) { |
||||
$commenters = $this->retrieveCommentsInformation($context['itemType'], $context['itemId']); |
||||
if(count($commenters) === 0) { |
||||
return; |
||||
} |
||||
|
||||
foreach ($sortArray as $type => &$byType) { |
||||
if(!isset($commenters[$type])) { |
||||
continue; |
||||
} |
||||
|
||||
usort($byType, function ($a, $b) use ($commenters, $type) { |
||||
$r = $this->compare($a, $b, $commenters[$type]); |
||||
return $r; |
||||
}); |
||||
|
||||
$s = ''; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param $type |
||||
* @param $id |
||||
* @return array |
||||
*/ |
||||
protected function retrieveCommentsInformation($type, $id) { |
||||
$comments = $this->commentsManager->getForObject($type, $id, 1); |
||||
if(count($comments) === 0) { |
||||
return []; |
||||
} |
||||
|
||||
return $this->commentsManager->getActorsInTree($comments[0]->getTopmostParentId()); |
||||
} |
||||
|
||||
protected function compare(array $a, array $b, array $commenters) { |
||||
$a = $a['value']['shareWith']; |
||||
$b = $b['value']['shareWith']; |
||||
|
||||
$valueA = isset($commenters[$a]) ? $commenters[$a] : 0; |
||||
$valueB = isset($commenters[$b]) ? $commenters[$b] : 0; |
||||
|
||||
return $valueB - $valueA; |
||||
} |
||||
} |
@ -0,0 +1,147 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\Comments\Tests\Unit\Collaboration; |
||||
|
||||
|
||||
use OCA\Comments\Collaboration\CommentersSorter; |
||||
use OCP\Comments\IComment; |
||||
use OCP\Comments\ICommentsManager; |
||||
use Test\TestCase; |
||||
|
||||
class CommentersSorterTest extends TestCase { |
||||
/** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ |
||||
protected $commentsManager; |
||||
/** @var CommentersSorter */ |
||||
protected $sorter; |
||||
|
||||
public function setUp() { |
||||
parent::setUp(); |
||||
|
||||
$this->commentsManager = $this->createMock(ICommentsManager::class); |
||||
|
||||
$this->sorter = new CommentersSorter($this->commentsManager); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider sortDataProvider |
||||
* @param $data |
||||
*/ |
||||
public function testSort($data) { |
||||
$this->commentsManager->expects($this->once()) |
||||
->method('getForObject') |
||||
->willReturn([$this->createMock(IComment::class)]); |
||||
|
||||
$this->commentsManager->expects($this->once()) |
||||
->method('getActorsInTree') |
||||
->willReturn($data['actors']); |
||||
|
||||
$workArray = $data['input']; |
||||
$this->sorter->sort($workArray, ['itemType' => 'files', 'itemId' => '24']); |
||||
|
||||
$this->assertSame($data['expected'], $workArray); |
||||
} |
||||
|
||||
public function sortDataProvider() { |
||||
return [[ |
||||
[ |
||||
#1 – sort properly and otherwise keep existing order |
||||
'actors' => ['users' => ['celia' => 3, 'darius' => 7, 'faruk' => 5, 'gail' => 5], 'bots' => ['r2-d2' => 8]], |
||||
'input' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
'expected' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
] |
||||
], |
||||
], |
||||
[ |
||||
#2 – no commentors, input equals output |
||||
'actors' => [], |
||||
'input' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
'expected' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
], |
||||
[ |
||||
#3 – no nothing |
||||
'actors' => [], |
||||
'input' => [], |
||||
'expected' => [], |
||||
], |
||||
]]; |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\Files_Sharing\Collaboration; |
||||
|
||||
|
||||
use OCP\Collaboration\AutoComplete\ISorter; |
||||
use OCP\Files\Folder; |
||||
use OCP\Files\Node; |
||||
use OCP\Share\IManager; |
||||
|
||||
class ShareRecipientSorter implements ISorter { |
||||
|
||||
/** @var IManager */ |
||||
private $shareManager; |
||||
/** @var Folder */ |
||||
private $userFolder; |
||||
|
||||
public function __construct(IManager $shareManager, Folder $userFolder) { |
||||
$this->shareManager = $shareManager; |
||||
$this->userFolder = $userFolder; |
||||
} |
||||
|
||||
public function getId() { |
||||
return 'share-recipients'; |
||||
} |
||||
|
||||
public function sort(array &$sortArray, array $context) { |
||||
// let's be tolerant. Comments uses "files" by default, other usages are often singular |
||||
if($context['itemType'] !== 'files' && $context['itemType'] !== 'file') { |
||||
return; |
||||
} |
||||
/** @var Node[] $nodes */ |
||||
$nodes = $this->userFolder->getById((int)$context['itemId']); |
||||
if(count($nodes) === 0) { |
||||
return; |
||||
} |
||||
$al = $this->shareManager->getAccessList($nodes[0]); |
||||
|
||||
foreach ($sortArray as $type => &$byType) { |
||||
if(!isset($al[$type]) || !is_array($al[$type])) { |
||||
continue; |
||||
} |
||||
usort($byType, function ($a, $b) use ($al, $type) { |
||||
return $this->compare($a, $b, $al[$type]); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param array $a |
||||
* @param array $b |
||||
* @param array $al |
||||
* @return int |
||||
*/ |
||||
protected function compare(array $a, array $b, array $al) { |
||||
$a = $a['value']['shareWith']; |
||||
$b = $b['value']['shareWith']; |
||||
|
||||
$valueA = (int)in_array($a, $al, true); |
||||
$valueB = (int)in_array($b, $al, true); |
||||
|
||||
return $valueB - $valueA; |
||||
} |
||||
} |
@ -0,0 +1,220 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\Files_Sharing\Tests\Collaboration; |
||||
|
||||
|
||||
use OCA\Files_Sharing\Collaboration\ShareRecipientSorter; |
||||
use OCP\Files\Folder; |
||||
use OCP\Files\Node; |
||||
use OCP\Share\IManager; |
||||
use Test\TestCase; |
||||
|
||||
class ShareRecipientSorterTest extends TestCase { |
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ |
||||
protected $shareManager; |
||||
/** @var Folder|\PHPUnit_Framework_MockObject_MockObject */ |
||||
protected $userFolder; |
||||
/** @var ShareRecipientSorter */ |
||||
protected $sorter; |
||||
|
||||
public function setUp() { |
||||
parent::setUp(); |
||||
|
||||
$this->shareManager = $this->createMock(IManager::class); |
||||
$this->userFolder = $this->createMock(Folder::class); |
||||
|
||||
$this->sorter = new ShareRecipientSorter($this->shareManager, $this->userFolder); |
||||
} |
||||
|
||||
/** |
||||
* @dataProvider sortDataProvider |
||||
* @param $data |
||||
*/ |
||||
public function testSort($data) { |
||||
$node = $this->createMock(Node::class); |
||||
|
||||
if ($data['context']['itemType'] === 'files') { |
||||
$this->userFolder->expects($this->once()) |
||||
->method('getById') |
||||
->with($data['context']['itemId']) |
||||
->willReturn([$node]); |
||||
|
||||
$this->shareManager->expects($this->once()) |
||||
->method('getAccessList') |
||||
->with($node) |
||||
->willReturn($data['accessList']); |
||||
} else { |
||||
$this->userFolder->expects($this->never()) |
||||
->method('getById'); |
||||
$this->shareManager->expects($this->never()) |
||||
->method('getAccessList'); |
||||
} |
||||
|
||||
$workArray = $data['input']; |
||||
$this->sorter->sort($workArray, $data['context']); |
||||
|
||||
$this->assertSame($data['expected'], $workArray); |
||||
} |
||||
|
||||
public function testSortNoNodes() { |
||||
$this->userFolder->expects($this->once()) |
||||
->method('getById') |
||||
->willReturn([]); |
||||
|
||||
$this->shareManager->expects($this->never()) |
||||
->method('getAccessList'); |
||||
|
||||
$originalArray = ['users' => [ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
]]; |
||||
$workArray = $originalArray; |
||||
$this->sorter->sort($workArray, ['itemType' => 'files', 'itemId' => 404]); |
||||
|
||||
$this->assertEquals($originalArray, $workArray); |
||||
} |
||||
|
||||
public function sortDataProvider() { |
||||
return [[ |
||||
[ |
||||
#1 – sort properly and otherwise keep existing order |
||||
'context' => ['itemType' => 'files', 'itemId' => 42], |
||||
'accessList' => ['users' => ['celia', 'darius', 'faruk', 'gail'], 'bots' => ['r2-d2']], |
||||
'input' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
'expected' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
] |
||||
], |
||||
], |
||||
[ |
||||
# 2 – no recipients |
||||
'context' => ['itemType' => 'files', 'itemId' => 42], |
||||
'accessList' => ['users' => false], |
||||
'input' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
'expected' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
], |
||||
[ |
||||
#3 – unsupported item type |
||||
'context' => ['itemType' => 'announcements', 'itemId' => 42], |
||||
'accessList' => null, // not needed |
||||
'input' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
'expected' => [ |
||||
'users' => |
||||
[ |
||||
['value' => ['shareWith' => 'alice']], |
||||
['value' => ['shareWith' => 'bob']], |
||||
['value' => ['shareWith' => 'celia']], |
||||
['value' => ['shareWith' => 'darius']], |
||||
['value' => ['shareWith' => 'elena']], |
||||
['value' => ['shareWith' => 'faruk']], |
||||
['value' => ['shareWith' => 'gail']], |
||||
], |
||||
'bots' => [ |
||||
['value' => ['shareWith' => 'c-3po']], |
||||
['value' => ['shareWith' => 'r2-d2']], |
||||
] |
||||
], |
||||
], |
||||
[ |
||||
#4 – no nothing |
||||
'context' => ['itemType' => 'files', 'itemId' => 42], |
||||
'accessList' => [], |
||||
'input' => [], |
||||
'expected' => [], |
||||
], |
||||
]]; |
||||
} |
||||
} |
@ -0,0 +1,89 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OC\Core\Controller; |
||||
|
||||
use OCP\AppFramework\Controller; |
||||
use OCP\AppFramework\Http\DataResponse; |
||||
use OCP\Collaboration\AutoComplete\IManager; |
||||
use OCP\Collaboration\Collaborators\ISearch; |
||||
use OCP\IRequest; |
||||
use OCP\Share; |
||||
|
||||
class AutoCompleteController extends Controller { |
||||
/** @var ISearch */ |
||||
private $collaboratorSearch; |
||||
/** @var IManager */ |
||||
private $autoCompleteManager; |
||||
|
||||
public function __construct($appName, IRequest $request, ISearch $collaboratorSearch, IManager $autoCompleteManager) { |
||||
parent::__construct($appName, $request); |
||||
|
||||
$this->collaboratorSearch = $collaboratorSearch; |
||||
$this->autoCompleteManager = $autoCompleteManager; |
||||
} |
||||
|
||||
/** |
||||
* @NoAdminRequired |
||||
* |
||||
* @param string $itemType |
||||
* @param string $itemId |
||||
* @param string|null $sorter can be piped, top prio first, e.g.: "commenters|share-recipients" |
||||
* @param array $shareTypes |
||||
* @return DataResponse |
||||
*/ |
||||
public function get($itemType, $itemId, $sorter = null, $shareTypes = [Share::SHARE_TYPE_USER]) { |
||||
// if enumeration/user listings are disabled, we'll receive an empty |
||||
// result from search() – thus nothing else to do here. |
||||
list($results,) = $this->collaboratorSearch->search('', $shareTypes, false, 20, 0); |
||||
|
||||
// there won't be exact matches without a search string |
||||
unset($results['exact']); |
||||
|
||||
$sorters = array_reverse(explode('|', $sorter)); |
||||
$this->autoCompleteManager->runSorters($sorters, $results, [ |
||||
'itemType' => $itemType, |
||||
'itemId' => $itemId, |
||||
]); |
||||
|
||||
// transform to expected format |
||||
$results = $this->prepareResultArray($results); |
||||
|
||||
return new DataResponse($results); |
||||
} |
||||
|
||||
|
||||
protected function prepareResultArray(array $results) { |
||||
$output = []; |
||||
foreach ($results as $type => $subResult) { |
||||
foreach ($subResult as $result) { |
||||
$output[] = [ |
||||
'id' => $result['value']['shareWith'], |
||||
'label' => $result['label'], |
||||
'source' => $type, |
||||
]; |
||||
} |
||||
} |
||||
return $output; |
||||
} |
||||
} |
@ -0,0 +1,81 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OC\Collaboration\AutoComplete; |
||||
|
||||
use OCP\Collaboration\AutoComplete\IManager; |
||||
use OCP\Collaboration\AutoComplete\ISorter; |
||||
use OCP\IServerContainer; |
||||
|
||||
class Manager implements IManager { |
||||
/** @var string[] */ |
||||
protected $sorters =[]; |
||||
|
||||
/** @var ISorter[] */ |
||||
protected $sorterInstances = []; |
||||
/** @var IServerContainer */ |
||||
private $c; |
||||
|
||||
public function __construct(IServerContainer $container) { |
||||
$this->c = $container; |
||||
} |
||||
|
||||
public function runSorters(array $sorters, array &$sortArray, array $context) { |
||||
$sorterInstances = $this->getSorters(); |
||||
while($sorter = array_shift($sorters)) { |
||||
if(isset($sorterInstances[$sorter])) { |
||||
$sorterInstances[$sorter]->sort($sortArray, $context); |
||||
} else { |
||||
$this->c->getLogger()->warning('No sorter for ID "{id}", skipping', [ |
||||
'app' => 'core', 'id' => $sorter |
||||
]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public function registerSorter($className) { |
||||
$sorters[] = $className; |
||||
} |
||||
|
||||
protected function getSorters() { |
||||
if(count($this->sorterInstances) === 0) { |
||||
foreach ($this->sorters as $sorter) { |
||||
/** @var ISorter $instance */ |
||||
$instance = $this->c->resolve($sorter); |
||||
if(!$instance instanceof ISorter) { |
||||
$this->c->getLogger()->notice('Skipping sorter which is not an instance of ISorter. Class name: {class}', |
||||
['app' => 'core', 'class' => $sorter]); |
||||
continue; |
||||
} |
||||
$sorterId = trim($instance->getId()); |
||||
if(trim($sorterId) === '') { |
||||
$this->c->getLogger()->notice('Skipping sorter with empty ID. Class name: {class}', |
||||
['app' => 'core', 'class' => $sorter]); |
||||
continue; |
||||
} |
||||
$this->sorterInstances[$sorterId] = $instance; |
||||
} |
||||
} |
||||
return $this->sorterInstances; |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCP\Collaboration\AutoComplete; |
||||
|
||||
/** |
||||
* Interface IManager |
||||
* |
||||
* @package OCP\Collaboration\AutoComplete |
||||
* @since 13.0.0 |
||||
*/ |
||||
interface IManager { |
||||
/** |
||||
* @param string $className – class name of the ISorter implementation |
||||
* @since 13.0.0 |
||||
*/ |
||||
public function registerSorter($className); |
||||
|
||||
/** |
||||
* @param array $sorters list of sorter IDs, seperated by "|" |
||||
* @param array $sortArray array representation of OCP\Collaboration\Collaborators\ISearchResult |
||||
* @param array $context context info of the search, keys: itemType, itemId |
||||
* @since 13.0.0 |
||||
*/ |
||||
public function runSorters(array $sorters, array &$sortArray, array $context); |
||||
} |
@ -0,0 +1,50 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCP\Collaboration\AutoComplete; |
||||
|
||||
/** |
||||
* Interface ISorter |
||||
* |
||||
* Sorts the list of .e.g users for auto completion |
||||
* |
||||
* @package OCP\Collaboration\AutoComplete |
||||
* @since 13.0.0 |
||||
*/ |
||||
interface ISorter { |
||||
|
||||
/** |
||||
* @return string The ID of the sorter, e.g. commenters |
||||
* @since 13.0.0 |
||||
*/ |
||||
public function getId(); |
||||
|
||||
/** |
||||
* executes the sort action |
||||
* |
||||
* @param array $sortArray the array to be sorted, provided as reference |
||||
* @param array $context carries key 'itemType' and 'itemId' of the source object (e.g. a file) |
||||
* @since 13.0.0 |
||||
*/ |
||||
public function sort(array &$sortArray, array $context); |
||||
} |
@ -0,0 +1,84 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* 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 |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace Tests\Core\Controller; |
||||
|
||||
|
||||
use OC\Core\Controller\AutoCompleteController; |
||||
use OCP\Collaboration\AutoComplete\IManager; |
||||
use OCP\Collaboration\Collaborators\ISearch; |
||||
use OCP\IRequest; |
||||
use Test\TestCase; |
||||
|
||||
class AutoCompleteControllerTest extends TestCase { |
||||
/** @var ISearch|\PHPUnit_Framework_MockObject_MockObject */ |
||||
protected $collaboratorSearch; |
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ |
||||
protected $autoCompleteManager; |
||||
/** @var AutoCompleteController */ |
||||
protected $controller; |
||||
|
||||
protected function setUp() { |
||||
parent::setUp(); |
||||
|
||||
/** @var IRequest $request */ |
||||
$request = $this->createMock(IRequest::class); |
||||
$this->collaboratorSearch = $this->createMock(ISearch::class); |
||||
$this->autoCompleteManager = $this->createMock(IManager::class); |
||||
|
||||
$this->controller = new AutoCompleteController( |
||||
'core', |
||||
$request, |
||||
$this->collaboratorSearch, |
||||
$this->autoCompleteManager |
||||
); |
||||
} |
||||
|
||||
public function testGet() { |
||||
$searchResults = [ |
||||
'exact' => [ |
||||
'users' => [], |
||||
'robots' => [], |
||||
], |
||||
'users' => [ |
||||
['label' => 'Alice A.', 'value' => ['shareWith' => 'alice']], |
||||
['label' => 'Bob Y.', 'value' => ['shareWith' => 'bob']], |
||||
], |
||||
]; |
||||
|
||||
$expected = [ |
||||
[ 'id' => 'alice', 'label' => 'Alice A.', 'source' => 'users'], |
||||
[ 'id' => 'bob', 'label' => 'Bob Y.', 'source' => 'users'], |
||||
]; |
||||
|
||||
$this->collaboratorSearch->expects($this->once()) |
||||
->method('search') |
||||
->willReturn([$searchResults, false]); |
||||
|
||||
$response = $this->controller->get('files', '42', null); |
||||
|
||||
$list = $response->getData(); |
||||
$this->assertEquals($expected, $list); // has better error output… |
||||
$this->assertSame($expected, $list); |
||||
} |
||||
} |
Loading…
Reference in new issue