Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/files_sharing/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
'url' => '/api/v1/sharees',
'verb' => 'GET',
],
[
'name' => 'ShareesAPI#findRecommended',
'url' => '/api/v1/sharees_recommended',
'verb' => 'GET',
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this in the docs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/*
* Remote Shares
*/
Expand Down
158 changes: 157 additions & 1 deletion apps/files_sharing/lib/Controller/ShareesAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,29 @@
*/
namespace OCA\Files_Sharing\Controller;

use function array_filter;
use function array_slice;
use function array_values;
use Generator;
use OC\Collaboration\Collaborators\SearchResult;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCSController;
use OCP\Collaboration\Collaborators\ISearch;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Collaboration\Collaborators\SearchResultType;
use OCP\IRequest;
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\Share;
use OCP\Share\IManager;
use function usort;

class ShareesAPIController extends OCSController {

/** @var userId */
protected $userId;

/** @var IConfig */
protected $config;

Expand Down Expand Up @@ -87,6 +99,7 @@ class ShareesAPIController extends OCSController {
private $collaboratorSearch;

/**
* @param string $UserId
* @param string $appName
* @param IRequest $request
* @param IConfig $config
Expand All @@ -95,6 +108,7 @@ class ShareesAPIController extends OCSController {
* @param ISearch $collaboratorSearch
*/
public function __construct(
$UserId,
string $appName,
IRequest $request,
IConfig $config,
Expand All @@ -103,7 +117,7 @@ public function __construct(
ISearch $collaboratorSearch
) {
parent::__construct($appName, $request);

$this->userId = $UserId;
$this->config = $config;
$this->urlGenerator = $urlGenerator;
$this->shareManager = $shareManager;
Expand Down Expand Up @@ -212,6 +226,148 @@ public function search(string $search = '', string $itemType = null, int $page =
return $response;
}

/**
* @param string $user
* @param int $shareType
*
* @return Generator<array<string>>
*/
private function getAllShareesByType(string $user, int $shareType): Generator {
$offset = 0;
$pageSize = 50;

while (count($page = $this->shareManager->getSharesBy(
$user,
$shareType,
null,
false,
$pageSize,
$offset
))) {
foreach ($page as $share) {
yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()];
}

$offset += $pageSize;
}
}

private function sortShareesByFrequency(array $sharees): array {
usort($sharees, function(array $s1, array $s2) {
return $s2['count'] - $s1['count'];
});
return $sharees;
}

private $searchResultTypeMap = [
Share::SHARE_TYPE_USER => 'users',
Share::SHARE_TYPE_GROUP => 'groups',
Share::SHARE_TYPE_REMOTE => 'remotes',
Share::SHARE_TYPE_REMOTE_GROUP => 'remote_groups',
Share::SHARE_TYPE_EMAIL => 'emails',
];

private function getAllSharees(string $user, array $shareTypes): ISearchResult {
$result = [];
foreach ($shareTypes as $shareType) {
$sharees = $this->getAllShareesByType($user, $shareType);
$shareTypeResults = [];
foreach ($sharees as list($sharee, $displayname)) {
if (!isset($this->searchResultTypeMap[$shareType])) {
continue;
}

if (!isset($shareTypeResults[$sharee])) {
$shareTypeResults[$sharee] = [
'count' => 1,
'label' => $displayname,
'value' => [
'shareType' => $shareType,
'shareWith' => $sharee,
],
];
} else {
$shareTypeResults[$sharee]['count']++;
}
}
$result = array_merge($result, array_values($shareTypeResults));
}

$top5 = array_slice(
$this->sortShareesByFrequency($result),
0,
5
);

$searchResult = new SearchResult();
foreach ($this->searchResultTypeMap as $int => $str) {
$searchResult->addResultSet(new SearchResultType($str), [], []);
foreach ($top5 as $x) {
if ($x['value']['shareType'] === $int) {
$searchResult->addResultSet(new SearchResultType($str), [], [$x]);
}
}
}
return $searchResult;
}

/**
* @NoAdminRequired
*
* @param string $itemType
* @return DataResponse
* @throws OCSBadRequestException
*/
public function findRecommended(string $itemType = null, $shareType = null): DataResponse {
$shareTypes = [
Share::SHARE_TYPE_USER,
];

if ($itemType === null) {
throw new OCSBadRequestException('Missing itemType');
} elseif ($itemType === 'file' || $itemType === 'folder') {
if ($this->shareManager->allowGroupSharing()) {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
}

if ($this->isRemoteSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE;
}

if ($this->isRemoteGroupSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE_GROUP;
}

if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}

if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_ROOM)) {
$shareTypes[] = Share::SHARE_TYPE_ROOM;
}
} else {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}

// FIXME: DI
if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
}

if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
sort($shareTypes);
} else if (is_numeric($shareType)) {
$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
sort($shareTypes);
}

return new DataResponse(
$this->getAllSharees($this->userId, $shareTypes)->asArray()
);
}

/**
* Method to get out the static call for better testing
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class ShareesAPIControllerTest extends TestCase {
/** @var ShareesAPIController */
protected $sharees;

/** @var string */
protected $uid;

/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
protected $request;

Expand All @@ -62,6 +65,7 @@ class ShareesAPIControllerTest extends TestCase {
protected function setUp() {
parent::setUp();

$this->uid = 'test123';
$this->request = $this->createMock(IRequest::class);
$this->shareManager = $this->createMock(IManager::class);

Expand All @@ -74,6 +78,7 @@ protected function setUp() {
$this->collaboratorSearch = $this->createMock(ISearch::class);

$this->sharees = new ShareesAPIController(
$this->uid,
'files_sharing',
$this->request,
$configMock,
Expand Down Expand Up @@ -243,6 +248,8 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn
->method('allowGroupSharing')
->willReturn($allowGroupSharing);

/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
Expand All @@ -251,6 +258,7 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,
Expand Down Expand Up @@ -335,6 +343,8 @@ public function testSearchInvalid($getData, $message) {
$config->expects($this->never())
->method('getAppValue');

/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
Expand All @@ -343,6 +353,7 @@ public function testSearchInvalid($getData, $message) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,
Expand Down
2 changes: 1 addition & 1 deletion core/js/dist/share_backend.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/js/dist/share_backend.js.map

Large diffs are not rendered by default.

Loading