Skip to content

Commit 5006f78

Browse files
authored
Merge pull request #2275 from nextcloud/feature/54562/implement-ipartialshareprovider
feature: implement IPartialShareProvider support
2 parents da8abf1 + 389efbb commit 5006f78

File tree

5 files changed

+128
-5
lines changed

5 files changed

+128
-5
lines changed

lib/Db/CoreQueryBuilder.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,20 @@ public function limitToFileSource(int $nodeId): void {
345345
$this->limitInt('file_source', $nodeId);
346346
}
347347

348+
public function limitToFileTarget(string $target, string $alias): void {
349+
$this->orWhere(
350+
$this->exprLimit('file_target', $target),
351+
$this->exprLimit('file_target', $target, $alias),
352+
);
353+
}
354+
355+
public function limitToFileTargetLike(string $target, string $alias): void {
356+
$this->orWhere(
357+
$this->exprLike('file_target', $target),
358+
$this->exprLike('file_target', $target, $alias),
359+
);
360+
}
361+
348362
/**
349363
* @param array $files
350364
*/
@@ -1465,9 +1479,11 @@ public function leftJoinFileCache(string $aliasShare) {
14651479
* @param string $aliasShare
14661480
* @param string $aliasShareMemberships
14671481
*
1482+
* @return string the alias generated for the join
1483+
*
14681484
* @throws RequestBuilderException
14691485
*/
1470-
public function leftJoinShareChild(string $aliasShare, string $aliasShareMemberships = '') {
1486+
public function leftJoinShareChild(string $aliasShare, string $aliasShareMemberships = ''): string {
14711487
$expr = $this->expr();
14721488

14731489
$aliasShareChild = $this->generateAlias($aliasShare, self::SHARE);
@@ -1491,6 +1507,7 @@ public function leftJoinShareChild(string $aliasShare, string $aliasShareMembers
14911507
);
14921508

14931509
// $this->selectAlias($aliasShareParent . '.permissions', 'parent_perms');
1510+
return $aliasShareChild;
14941511
}
14951512

14961513

lib/Db/ShareWrapperRequest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,40 @@ public function getSharedWith(
359359
return $this->getItemsFromRequest($qb);
360360
}
361361

362+
public function getSharedWithByPath(
363+
FederatedUser $federatedUser,
364+
string $path,
365+
bool $forChildren,
366+
CircleProbe $probe,
367+
): array {
368+
$qb = $this->getShareSelectSql();
369+
$qb->setOptions(
370+
[CoreQueryBuilder::SHARE],
371+
array_merge(
372+
$probe->getAsOptions(),
373+
['getData' => true]
374+
)
375+
);
376+
377+
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
378+
379+
$aliasCircle = $qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::CIRCLE);
380+
$qb->limitToFederatedUserMemberships(CoreQueryBuilder::SHARE, $aliasCircle, $federatedUser);
381+
382+
$qb->leftJoinFileCache(CoreQueryBuilder::SHARE);
383+
$qb->limitNull('parent', false);
384+
$childAlias = $qb->leftJoinShareChild(CoreQueryBuilder::SHARE);
385+
386+
if ($forChildren) {
387+
$qb->limitToFileTargetLike($path . '_%', $childAlias);
388+
} else {
389+
$qb->limitToFileTarget($path, $childAlias);
390+
}
391+
392+
$qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
393+
394+
return $this->getItemsFromRequest($qb);
395+
}
362396

363397
/**
364398
* @param FederatedUser $federatedUser

lib/Service/ShareWrapperService.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,29 @@ public function getSharedWith(
239239
return $shares;
240240
}
241241

242+
public function getSharedWithByPath(
243+
FederatedUser $federatedUser,
244+
string $path,
245+
bool $forChildren,
246+
?CircleProbe $probe,
247+
): array {
248+
$key = $this->generateSharedWithByPathCacheKey($federatedUser, $path, $forChildren, $probe?->getChecksum());
249+
250+
$cachedData = $this->cache->get($key);
251+
try {
252+
if (!is_string($cachedData)) {
253+
throw new InvalidItemException();
254+
}
255+
256+
return $this->deserializeList($cachedData, ShareWrapper::class);
257+
} catch (InvalidItemException $e) {
258+
}
259+
260+
$shares = $this->shareWrapperRequest->getSharedWithByPath($federatedUser, $path, $forChildren, $probe);
261+
$this->cache->set($key, json_encode($shares), self::CACHE_SHARED_WITH_TTL);
262+
263+
return $shares;
264+
}
242265

243266
/**
244267
* @param FederatedUser $federatedUser
@@ -322,6 +345,18 @@ private function createChild(IShare $share, FederatedUser $federatedUser): Share
322345
return $this->getShareById($childId, $federatedUser);
323346
}
324347

348+
private function generateSharedWithByPathCacheKey(
349+
FederatedUser $federatedUser,
350+
string $path,
351+
bool $forChildren,
352+
?string $probeSum,
353+
): string {
354+
$pathHash = \md5($path);
355+
return $federatedUser->getSingleId() . '#'
356+
. $pathHash . '#'
357+
. $forChildren . '#'
358+
. $probeSum;
359+
}
325360

326361
/**
327362
* @param FederatedUser $federatedUser

lib/ShareByCircleProvider.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
use OCP\Share\Exceptions\AlreadySharedException;
5757
use OCP\Share\Exceptions\IllegalIDChangeException;
5858
use OCP\Share\Exceptions\ShareNotFound;
59+
use OCP\Share\IPartialShareProvider;
5960
use OCP\Share\IShare;
6061
use OCP\Share\IShareProvider;
6162
use Psr\Log\LoggerInterface;
@@ -65,7 +66,7 @@
6566
*
6667
* @package OCA\Circles
6768
*/
68-
class ShareByCircleProvider implements IShareProvider {
69+
class ShareByCircleProvider implements IShareProvider, IPartialShareProvider {
6970
use TArrayTools;
7071
use TStringTools;
7172
use TNCLogger;
@@ -522,6 +523,44 @@ function (ShareWrapper $wrapper) {
522523
);
523524
}
524525

526+
public function getSharedWithByPath(
527+
string $userId,
528+
int $shareType,
529+
string $path,
530+
bool $forChildren,
531+
int $limit,
532+
int $offset,
533+
): iterable {
534+
if ($shareType !== IShare::TYPE_CIRCLE) {
535+
return [];
536+
}
537+
538+
$federatedUser = $this->federatedUserService->getLocalFederatedUser($userId);
539+
$probe = new CircleProbe();
540+
$probe->includePersonalCircles()
541+
->includeSystemCircles()
542+
->mustBeMember()
543+
->setItemsLimit($limit)
544+
->setItemsOffset($offset);
545+
546+
$wrappedShares = $this->shareWrapperService->getSharedWithByPath(
547+
$federatedUser,
548+
$path,
549+
$forChildren,
550+
$probe,
551+
);
552+
553+
/** @var array<string, IShare> */
554+
return array_filter(
555+
array_map(
556+
function (ShareWrapper $wrapper) {
557+
return $wrapper->getShare(
558+
$this->rootFolder, $this->userManager, $this->urlGenerator, true
559+
);
560+
}, $wrappedShares
561+
)
562+
);
563+
}
525564

526565
/**
527566
* @param string $token

tests/psalm-baseline.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,6 @@
374374
</UndefinedDocblockClass>
375375
</file>
376376
<file src="lib/ShareByCircleProvider.php">
377-
<ImplementedParamTypeMismatch>
378-
<code><![CDATA[$shareId]]></code>
379-
</ImplementedParamTypeMismatch>
380377
<InvalidNullableReturnType>
381378
<code><![CDATA[IShare]]></code>
382379
<code><![CDATA[IShare]]></code>
@@ -386,6 +383,7 @@
386383
</InvalidNullableReturnType>
387384
<LessSpecificImplementedReturnType>
388385
<code><![CDATA[array]]></code>
386+
<code><![CDATA[iterable]]></code>
389387
</LessSpecificImplementedReturnType>
390388
<NullableReturnStatement>
391389
<code><![CDATA[$wrappedShare->getShare($this->rootFolder, $this->userManager, $this->urlGenerator)]]></code>

0 commit comments

Comments
 (0)