Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/circles.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2022-11-10 15:46:06 +0300
committerMaxence Lange <maxence@artificial-owl.com>2022-11-10 15:51:56 +0300
commitbfe262eba01ecd27a6999a09ee8360fa78fd5c3d (patch)
treea890927af3ec7709d475da9714fc4311177fd1e3
parent5dc232a9a4ede25e8cbdf64f14a3a84cc3aaca32 (diff)
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r--lib/Collaboration/v2/CollaboratorSearchPlugin.php21
-rw-r--r--lib/Db/CircleRequest.php87
-rw-r--r--lib/Db/CoreQueryBuilder.php74
-rw-r--r--lib/Model/Probes/CircleProbe.php14
-rw-r--r--lib/Model/Probes/MemberProbe.php18
-rw-r--r--lib/Service/CircleService.php52
-rw-r--r--lib/ShareByCircleProvider.php24
7 files changed, 208 insertions, 82 deletions
diff --git a/lib/Collaboration/v2/CollaboratorSearchPlugin.php b/lib/Collaboration/v2/CollaboratorSearchPlugin.php
index cce2c517..4e734e1b 100644
--- a/lib/Collaboration/v2/CollaboratorSearchPlugin.php
+++ b/lib/Collaboration/v2/CollaboratorSearchPlugin.php
@@ -31,13 +31,14 @@ declare(strict_types=1);
namespace OCA\Circles\Collaboration\v2;
-use OCA\Circles\Tools\Traits\TNCLogger;
use Exception;
use OCA\Circles\AppInfo\Application;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\DataProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\FederatedUserService;
+use OCA\Circles\Tools\Traits\TNCLogger;
use OCP\Collaboration\Collaborators\ISearchPlugin;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Collaboration\Collaborators\SearchResultType;
@@ -114,11 +115,21 @@ class CollaboratorSearchPlugin implements ISearchPlugin {
->filterSystemCircles()
->setItemsLimit($limit)
->setItemsOffset($offset)
- ->setFilterCircle($filterCircle)
- ->mustBeMember(!$fromFrontEnd)
- ->filterConfig(Circle::CFG_ROOT, $fromFrontEnd);
+ ->setFilterCircle($filterCircle);
+
+ // If from the OCS API, we use getCircles(), to get more complex result at the price of huge resource,
+ // if not (ie. share popup) we only need probeCircles()
+ if ($fromFrontEnd) {
+ $probe->mustBeMember(false)
+ ->filterConfig(Circle::CFG_ROOT, true);
- $circles = $this->circleService->getCircles($probe);
+ $circles = $this->circleService->getCircles($probe);
+ } else {
+ $dataProbe = new DataProbe();
+ $dataProbe->add(DataProbe::OWNER);
+
+ $circles = $this->circleService->probeCircles($probe, $dataProbe);
+ }
} catch (Exception $e) {
return false;
}
diff --git a/lib/Db/CircleRequest.php b/lib/Db/CircleRequest.php
index 0610e5ff..0896603f 100644
--- a/lib/Db/CircleRequest.php
+++ b/lib/Db/CircleRequest.php
@@ -191,7 +191,7 @@ class CircleRequest extends CircleRequestBuilder {
$qb->limitToDirectMembership(CoreQueryBuilder::CIRCLE, $probe->getFilterMember());
}
if ($probe->hasFilterCircle()) {
- $qb->filterCircle($probe->getFilterCircle());
+ $qb->filterCircleDetails($probe->getFilterCircle());
}
if ($probe->hasFilterRemoteInstance()) {
$qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $probe->getFilterRemoteInstance(), false);
@@ -204,6 +204,33 @@ class CircleRequest extends CircleRequestBuilder {
/**
+ * get data about single Circle.
+ *
+ * - CircleProbe is used to confirm the visibility of the targeted circle,
+ * - DataProbe is used to define the complexity of the data to be returned for each entry of the list
+ *
+ * @param string $singleId
+ * @param IFederatedUser|null $initiator
+ * @param CircleProbe $circleProbe
+ * @param DataProbe $dataProbe
+ *
+ * @return Circle
+ * @throws CircleNotFoundException
+ * @throws RequestBuilderException
+ */
+ public function probeCircle(
+ string $singleId,
+ ?IFederatedUser $initiator,
+ CircleProbe $circleProbe,
+ DataProbe $dataProbe
+ ): Circle {
+ $qb = $this->buildProbeCircle($initiator, $circleProbe, $dataProbe);
+ $qb->limit('unique_id', $singleId);
+
+ return $this->getItemFromRequest($qb);
+ }
+
+ /**
* get data about multiple Circles.
*
* - CircleProbe is used to define the list of circles to be returned by the method,
@@ -221,30 +248,66 @@ class CircleRequest extends CircleRequestBuilder {
CircleProbe $circleProbe,
DataProbe $dataProbe
): array {
+ $qb = $this->buildProbeCircle($initiator, $circleProbe, $dataProbe);
+
+ $qb->chunk($circleProbe->getItemsOffset(), $circleProbe->getItemsLimit());
+
+ return $this->getItemsFromRequest($qb);
+ }
+
+ /**
+ * @param IFederatedUser|null $initiator
+ * @param CircleProbe $circleProbe
+ * @param DataProbe $dataProbe
+ *
+ * @return CoreQueryBuilder
+ * @throws RequestBuilderException
+ */
+ private function buildProbeCircle(
+ ?IFederatedUser $initiator,
+ CircleProbe $circleProbe,
+ DataProbe $dataProbe
+ ): CoreQueryBuilder {
$qb = $this->getCircleSelectSql();
- if (!$dataProbe->has(CoreQueryBuilder::MEMBERSHIPS)) {
- $dataProbe->add(CoreQueryBuilder::MEMBERSHIPS);
+ if (!$dataProbe->has(DataProbe::MEMBERSHIPS)) {
+ $dataProbe->add(DataProbe::MEMBERSHIPS);
}
$qb->setSqlPath(CoreQueryBuilder::CIRCLE, $dataProbe->getPath())
- ->setOptions([CoreQueryBuilder::CIRCLE], $circleProbe->getAsOptions());
+ ->setOptions([CoreQueryBuilder::CIRCLE], $circleProbe->getAsOptions())
+ ->filterCircles(CoreQueryBuilder::CIRCLE, $circleProbe);
+
+ if ($circleProbe->hasFilterCircle()) {
+ $qb->filterCircleDetails($circleProbe->getFilterCircle());
+ }
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
+ $qb->innerJoinMembership($circleProbe, CoreQueryBuilder::CIRCLE);
- $qb->innerJoinMembership(CoreQueryBuilder::CIRCLE);
+ $aliasMembership = $qb->generateAlias(CoreQueryBuilder::CIRCLE, CoreQueryBuilder::MEMBERSHIPS);
- if (!is_null($initiator)) {
- $qb->limitToSingleId(
- $initiator->getSingleId(), $qb->generateAlias(
- CoreQueryBuilder::CIRCLE,
- CoreQueryBuilder::MEMBERSHIPS
- )
+ $limit = $qb->expr()->orX();
+ if (is_null($initiator)) {
+ // to get unique result, enforce a limit on level=owner
+ $limit->add($qb->exprLimitInt('level', Member::LEVEL_OWNER, $aliasMembership));
+ } else {
+ $limit->add(
+ $qb->exprLimit(
+ 'single_id',
+ $initiator->getSingleId(),
+ $aliasMembership
+ )
);
+ $qb->completeProbeWithInitiator(CoreQueryBuilder::CIRCLE, 'single_id', $aliasMembership);
}
- return $this->getItemsFromRequest($qb);
+ $qb->andWhere($limit);
+ $qb->resetSqlPath();
+
+ return $qb;
}
+
/**
* @param array $circleIds
*
diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php
index a09bba62..9fbea8eb 100644
--- a/lib/Db/CoreQueryBuilder.php
+++ b/lib/Db/CoreQueryBuilder.php
@@ -382,9 +382,11 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
/**
+ * filter result on details (ie. displayName, Description, ...)
+ *
* @param Circle $circle
*/
- public function filterCircle(Circle $circle): void {
+ public function filterCircleDetails(Circle $circle): void {
if ($this->getType() !== QueryBuilder::SELECT) {
return;
}
@@ -885,12 +887,15 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
/**
+ * @param CircleProbe $probe
* @param string $alias
* @param string $field
- *
- * @throws RequestBuilderException
*/
- public function innerJoinMembership(string $alias, string $field = 'unique_id'): void {
+ public function innerJoinMembership(
+ CircleProbe $probe,
+ string $alias,
+ string $field = 'unique_id'
+ ): void {
if ($this->getType() !== QueryBuilder::SELECT) {
return;
}
@@ -902,22 +907,17 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
}
$expr = $this->expr();
- $this->generateMembershipSelectAlias($aliasMembership)
- ->innerJoin(
- $alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership,
- $expr->andX(
- $expr->eq($aliasMembership . '.circle_id', $alias . '.' . $field),
- $expr->eq(
- $aliasMembership . '.level',
- $this->createNamedParameter(
- Member::LEVEL_MEMBER,
- self::PARAM_INT
- )
- )
- )
- );
-// $this->leftJoinBasedOn($aliasMember);
+ $on = $expr->andX($expr->eq($aliasMembership . '.circle_id', $alias . '.' . $field));
+
+ // limit on membership level if requested
+ $minLevel = $probe->getMinimumLevel();
+ if ($minLevel > Member::LEVEL_MEMBER) {
+ $on->add($this->exprGt('level', $minLevel, true, $aliasMembership));
+ }
+
+ $this->generateMembershipSelectAlias($aliasMembership)
+ ->innerJoin($alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership, $on);
}
@@ -1319,6 +1319,36 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
}
+ public function completeProbeWithInitiator(
+ string $alias,
+ string $field = 'single_id',
+ string $helperAlias = ''
+ ): void {
+ if ($this->getType() !== QueryBuilder::SELECT) {
+ return;
+ }
+
+ try {
+ $aliasInitiator = $this->generateAlias($alias, self::INITIATOR);
+ } catch (RequestBuilderException $e) {
+ return;
+ }
+
+ $helperAlias = ($helperAlias === '') ? $alias : $helperAlias;
+
+ $expr = $this->expr();
+ $this->generateMemberSelectAlias($aliasInitiator)
+ ->leftJoin(
+ $alias, CoreRequestBuilder::TABLE_MEMBER, $aliasInitiator,
+ $expr->andX(
+ $expr->eq($aliasInitiator . '.circle_id', $helperAlias . '.' . $field),
+ $this->exprLimitInt('level', Member::LEVEL_OWNER, $aliasInitiator)
+ )
+ );
+//
+// $this->leftJoinBasedOn($aliasInitiator);
+ }
+
/**
* @param string $alias
*
@@ -1768,4 +1798,10 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
return $this;
}
+
+ public function resetSqlPath(): self {
+ $this->sqlPath = [];
+
+ return $this;
+ }
}
diff --git a/lib/Model/Probes/CircleProbe.php b/lib/Model/Probes/CircleProbe.php
index 11006792..7aadd424 100644
--- a/lib/Model/Probes/CircleProbe.php
+++ b/lib/Model/Probes/CircleProbe.php
@@ -41,16 +41,10 @@ use OCA\Circles\Model\Circle;
class CircleProbe extends MemberProbe {
- /** @var int */
- private $include = 0;
-
- /** @var int */
- private $filter = Circle::CFG_SINGLE;
-
- /** @var bool */
- private $includeNonVisible = false;
- /** @var bool */
- private $visitSingleCircles = false;
+ private int $include = 0;
+ private int $filter = Circle::CFG_SINGLE;
+ private bool $includeNonVisible = false;
+ private bool $visitSingleCircles = false;
/**
diff --git a/lib/Model/Probes/MemberProbe.php b/lib/Model/Probes/MemberProbe.php
index e2cdb1bb..f391f604 100644
--- a/lib/Model/Probes/MemberProbe.php
+++ b/lib/Model/Probes/MemberProbe.php
@@ -39,20 +39,10 @@ use OCA\Circles\Model\Member;
* @package OCA\Circles\Model\Probes
*/
class MemberProbe extends BasicProbe {
-
-
- /** @var int */
- private $minimumLevel = Member::LEVEL_NONE;
-
- /** @var bool */
- private $emulateVisitor = false;
-
- /** @var bool */
- private $requestingMembership = false;
-
- /** @var bool */
- private $initiatorDirectMember = false;
-
+ private int $minimumLevel = Member::LEVEL_NONE;
+ private bool $emulateVisitor = false;
+ private bool $requestingMembership = false;
+ private bool $initiatorDirectMember = false;
/**
* allow the initiator as a requesting member
diff --git a/lib/Service/CircleService.php b/lib/Service/CircleService.php
index 7d0a241b..b4e023e8 100644
--- a/lib/Service/CircleService.php
+++ b/lib/Service/CircleService.php
@@ -735,13 +735,17 @@ class CircleService {
return $this->l10n->t('Personal Circle');
}
- return $this->l10n->t(
- '%s owned by %s',
- [
- $source,
- $this->configService->displayFederatedUser($circle->getOwner(), true)
- ]
- );
+ if ($circle->hasOwner()) {
+ return $this->l10n->t(
+ '%s owned by %s',
+ [
+ $source,
+ $this->configService->displayFederatedUser($circle->getOwner(), true)
+ ]
+ );
+ }
+
+ return $source;
}
/**
@@ -760,6 +764,40 @@ class CircleService {
/**
+ * @param string $circleId
+ * @param CircleProbe $circleProbe
+ * @param DataProbe|null $dataProbe
+ *
+ * @return Circle
+ * @throws InitiatorNotFoundException
+ * @throws RequestBuilderException
+ * @throws CircleNotFoundException
+ */
+ public function probeCircle(
+ string $circleId,
+ ?CircleProbe $circleProbe = null,
+ ?DataProbe $dataProbe = null
+ ): Circle {
+ $this->federatedUserService->mustHaveCurrentUser();
+
+ if (is_null($circleProbe)) {
+ $circleProbe = new CircleProbe();
+ $circleProbe->includeSystemCircles();
+ }
+
+ if (is_null($dataProbe)) {
+ $dataProbe = new DataProbe();
+ }
+
+ return $this->circleRequest->probeCircle(
+ $circleId,
+ $this->federatedUserService->getCurrentUser(),
+ $circleProbe,
+ $dataProbe
+ );
+ }
+
+ /**
* @param CircleProbe $circleProbe
* @param DataProbe|null $dataProbe
*
diff --git a/lib/ShareByCircleProvider.php b/lib/ShareByCircleProvider.php
index 844fdc7b..d3582580 100644
--- a/lib/ShareByCircleProvider.php
+++ b/lib/ShareByCircleProvider.php
@@ -58,8 +58,8 @@ use OCA\Circles\Exceptions\UnknownRemoteException;
use OCA\Circles\FederatedItems\Files\FileShare;
use OCA\Circles\FederatedItems\Files\FileUnshare;
use OCA\Circles\Model\Federated\FederatedEvent;
-use OCA\Circles\Model\Helpers\MemberHelper;
use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\DataProbe;
use OCA\Circles\Model\ShareWrapper;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\EventService;
@@ -217,21 +217,18 @@ class ShareByCircleProvider implements IShareProvider {
}
$this->federatedUserService->initCurrentUser();
- $circle = $this->circleService->getCircle($share->getSharedWith());
- $owner = $circle->getInitiator();
-
- $initiatorHelper = new MemberHelper($owner);
- $initiatorHelper->mustBeMember();
+ $circleProbe = new CircleProbe();
+ $dataProbe = new DataProbe();
+ $dataProbe->add(DataProbe::OWNER)
+ ->add(DataProbe::INITIATOR, [DataProbe::BASED_ON]);
+ $circle = $this->circleService->probeCircle($share->getSharedWith(), $circleProbe, $dataProbe);
$share->setToken($this->token(15));
+ $owner = $circle->getInitiator();
$this->shareWrapperService->save($share);
try {
- $wrappedShare = $this->shareWrapperService->getShareById(
- (int)$share->getId(),
- $this->federatedUserService->getCurrentUser()
- );
-
+ $wrappedShare = $this->shareWrapperService->getShareById((int)$share->getId());
$wrappedShare->setOwner($owner);
} catch (ShareWrapperNotFoundException $e) {
throw new ShareNotFound();
@@ -291,10 +288,7 @@ class ShareByCircleProvider implements IShareProvider {
$this->federatedUserService->initCurrentUser();
try {
- $wrappedShare = $this->shareWrapperService->getShareById(
- (int)$share->getId(),
- $this->federatedUserService->getCurrentUser()
- );
+ $wrappedShare = $this->shareWrapperService->getShareById((int)$share->getId());
} catch (ShareWrapperNotFoundException $e) {
return;
}