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-08-30 19:28:06 +0300
committerMaxence Lange <maxence@artificial-owl.com>2022-10-22 15:32:12 +0300
commit6be7c4df14c781fb3eb81d7e7ea9a9f9b799a609 (patch)
treeb3aea9e0ea2381b51106f49f38fd05788da87eb4
parent886dfd88e167e9581954243332b99528264c767c (diff)
+DataProbe
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r--lib/CirclesManager.php35
-rw-r--r--lib/Db/CircleRequest.php43
-rw-r--r--lib/Db/CoreQueryBuilder.php81
-rw-r--r--lib/Model/Probes/DataProbe.php111
-rw-r--r--lib/Service/CircleService.php24
5 files changed, 287 insertions, 7 deletions
diff --git a/lib/CirclesManager.php b/lib/CirclesManager.php
index 6acbd69d..3959d843 100644
--- a/lib/CirclesManager.php
+++ b/lib/CirclesManager.php
@@ -57,6 +57,7 @@ use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Membership;
use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\DataProbe;
use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
@@ -316,7 +317,14 @@ class CirclesManager {
/**
- * returns Circles available, based on current session
+ * WARNING: This method is not using Cached Memberships meaning that the request can be heavy and should
+ * only be used if probeCircles() does not fit your need.
+ *
+ * Always prefer probeCircles();
+ *
+ * returns available Circles to the current session.
+ *
+ * @see probeCircles()
*
* @return Circle[]
* @throws InitiatorNotFoundException
@@ -510,6 +518,31 @@ class CirclesManager {
/**
+ * Returns data about Circles based on cached Memberships.
+ * Meaning that only Circles the current user is a member will be returned.
+ *
+ * CircleProbe is used to filter Circles to be returned by the method.
+ * DataProbe is used to add details to returned Circles.
+ *
+ * @param CircleProbe|null $circleProbe
+ * @param DataProbe|null $dataProbe
+ *
+ * @return array
+ * @throws InitiatorNotFoundException
+ * @throws RequestBuilderException
+ */
+ public function probeCircles(?CircleProbe $circleProbe = null, ?DataProbe $dataProbe = null): array {
+ if (is_null($circleProbe)) {
+ $circleProbe = new CircleProbe();
+ $circleProbe->filterHiddenCircles()
+ ->filterBackendCircles();
+ }
+
+ return $this->circleService->probeCircles($circleProbe, $dataProbe);
+ }
+
+
+ /**
* WIP
*
* @param string $circleId
diff --git a/lib/Db/CircleRequest.php b/lib/Db/CircleRequest.php
index 1303f480..afb9f160 100644
--- a/lib/Db/CircleRequest.php
+++ b/lib/Db/CircleRequest.php
@@ -42,6 +42,7 @@ use OCA\Circles\Model\Circle;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\DataProbe;
/**
* Class CircleRequest
@@ -203,6 +204,48 @@ class CircleRequest extends CircleRequestBuilder {
/**
+ * get data about multiple Circles.
+ *
+ * - CircleProbe is used to define the list of circles to be returned by the method,
+ * - DataProbe is used to define the complexity of the data to be returned for each entry of the list
+ *
+ * @param IFederatedUser|null $initiator
+ * @param CircleProbe $circleProbe
+ * @param DataProbe $dataProbe
+ *
+ * @return array
+ * @throws RequestBuilderException
+ */
+ public function probeCircles(
+ ?IFederatedUser $initiator,
+ CircleProbe $circleProbe,
+ DataProbe $dataProbe
+ ): array {
+ $qb = $this->getCircleSelectSql();
+ if (!$dataProbe->has(CoreQueryBuilder::MEMBERSHIPS)) {
+ $dataProbe->add(CoreQueryBuilder::MEMBERSHIPS);
+ }
+
+ $qb->setAlternateSqlPath(CoreQueryBuilder::CIRCLE, $dataProbe->getPath())
+ ->setOptions([CoreQueryBuilder::CIRCLE], $circleProbe->getAsOptions());
+
+ $qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
+
+ $qb->innerJoinMembership(CoreQueryBuilder::CIRCLE);
+
+ if (!is_null($initiator)) {
+ $qb->limitToSingleId(
+ $initiator->getSingleId(), $qb->generateAlias(
+ CoreQueryBuilder::CIRCLE,
+ CoreQueryBuilder::MEMBERSHIPS
+ )
+ );
+ }
+
+ return $this->getItemsFromRequest($qb);
+ }
+
+ /**
* @param array $circleIds
*
* @return array
diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php
index 01268ea0..fffad9d3 100644
--- a/lib/Db/CoreQueryBuilder.php
+++ b/lib/Db/CoreQueryBuilder.php
@@ -238,6 +238,7 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
/** @var array */
private $options = [];
+ private array $alternateSqlPath = [];
/**
* CoreQueryBuilder constructor.
@@ -315,8 +316,8 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
/**
* @param string $singleId
*/
- public function limitToSingleId(string $singleId): void {
- $this->limit('single_id', $singleId, '', true);
+ public function limitToSingleId(string $singleId, string $alias = ''): void {
+ $this->limit('single_id', $singleId, $alias, true);
}
@@ -888,6 +889,43 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
/**
* @param string $alias
+ * @param string $field
+ *
+ * @throws RequestBuilderException
+ */
+ public function innerJoinMembership(string $alias, string $field = 'unique_id'): void {
+ if ($this->getType() !== QueryBuilder::SELECT) {
+ return;
+ }
+
+ try {
+ $aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS);
+ } catch (RequestBuilderException $e) {
+ return;
+ }
+
+ $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);
+ }
+
+
+ /**
+ * @param string $alias
* @param string $fieldCircleId
* @param string $fieldSingleId
*
@@ -1658,8 +1696,8 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
public function generateAlias(string $base, string $extension, ?array &$options = []): string {
$search = str_replace('_', '.', $base);
$path = $search . '.' . $extension;
- if (!$this->validKey($path, self::$SQL_PATH)
- && !in_array($extension, $this->getArray($search, self::$SQL_PATH))) {
+ if (!$this->validKey($path, $this->getSqlPath())
+ && !in_array($extension, $this->getArray($search, $this->getSqlPath()))) {
throw new RequestBuilderException($extension . ' not found in ' . $search);
}
@@ -1672,7 +1710,7 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
$optionPath = trim($optionPath . '.' . $p, '.');
$options = array_merge(
$options,
- $this->getArray($optionPath . '.' . self::OPTIONS, self::$SQL_PATH),
+ $this->getArray($optionPath . '.' . self::OPTIONS, $this->getSqlPath()),
$this->getArray($optionPath . '.' . self::OPTIONS, $this->options)
);
}
@@ -1691,7 +1729,7 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
$search = str_replace('_', '.', $prefix);
$path = [];
- foreach ($this->getArray($search, self::$SQL_PATH) as $arr => $item) {
+ foreach ($this->getArray($search, $this->getSqlPath()) as $arr => $item) {
if (is_numeric($arr)) {
$k = $item;
} else {
@@ -1702,4 +1740,35 @@ class CoreQueryBuilder extends ExtendedQueryBuilder {
return $path;
}
+
+
+ /**
+ * @return array
+ */
+ public function getSqlPath(): array {
+ if (empty($this->alternateSqlPath)) {
+ return self::$SQL_PATH;
+ }
+
+ return $this->alternateSqlPath;
+ }
+
+
+ /**
+ * DataProbe uses this to set which data need to be extracted, based on self::$SQL_PATH.
+ *
+ * @param string $key
+ * @param array $path
+ *
+ * @return $this
+ */
+ public function setAlternateSqlPath(string $key, array $path = []): self {
+ if (empty($this->alternateSqlPath)) {
+ $this->alternateSqlPath = self::$SQL_PATH;
+ }
+
+ $this->alternateSqlPath[$key] = $path;
+
+ return $this;
+ }
}
diff --git a/lib/Model/Probes/DataProbe.php b/lib/Model/Probes/DataProbe.php
new file mode 100644
index 00000000..cb6b6461
--- /dev/null
+++ b/lib/Model/Probes/DataProbe.php
@@ -0,0 +1,111 @@
+<?php
+
+declare(strict_types=1);
+
+
+/**
+ * Circles - Bring cloud-users closer together.
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2022
+ * @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\Circles\Model\Probes;
+
+use OCA\Circles\Db\CoreQueryBuilder;
+
+/**
+ * Class CircleProbe
+ *
+ * @package OCA\Circles\Model\Probes
+ */
+class DataProbe extends BasicProbe {
+ public const OWNER = CoreQueryBuilder::OWNER;
+ public const MEMBER = CoreQueryBuilder::MEMBER;
+ public const BASED_ON = CoreQueryBuilder::BASED_ON;
+ public const MEMBERSHIPS = CoreQueryBuilder::MEMBERSHIPS;
+ public const CONFIG = CoreQueryBuilder::CONFIG;
+ public const INITIATOR = CoreQueryBuilder::INITIATOR;
+ public const INHERITED_BY = CoreQueryBuilder::INHERITED_BY;
+
+
+ private array $path = [];
+
+
+ public function __construct() {
+ }
+
+
+ /**
+ * @param string $key
+ * @param array $path
+ *
+ * @return $this
+ */
+ public function add(string $key, array $path = []): self {
+ $this->path[$key] = $path;
+
+ return $this;
+ }
+
+
+ /**
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function has(string $key): bool {
+ return (array_key_exists($key, $this->path));
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getPath(): array {
+ return $this->path;
+ }
+
+
+ /**
+ * Return an array with includes as options
+ *
+ * @return array
+ */
+ public function getAsOptions(): array {
+ return array_merge(
+ [
+ 'path' => $this->getPath()
+ ],
+ parent::getAsOptions()
+ );
+ }
+
+ /**
+ * Return a JSON object with includes as options
+ *
+ * @return array
+ */
+ public function JsonSerialize(): array {
+ return $this->getAsOptions();
+ }
+}
diff --git a/lib/Service/CircleService.php b/lib/Service/CircleService.php
index 8b865ae2..7d0a241b 100644
--- a/lib/Service/CircleService.php
+++ b/lib/Service/CircleService.php
@@ -62,6 +62,7 @@ use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\ManagedModel;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Probes\CircleProbe;
+use OCA\Circles\Model\Probes\DataProbe;
use OCA\Circles\Model\Probes\MemberProbe;
use OCA\Circles\StatusCode;
use OCA\Circles\Tools\Exceptions\InvalidItemException;
@@ -756,4 +757,27 @@ class CircleService {
private function generateGetCirclesCacheKey(FederatedUser $federatedUser, string $probeSum): string {
return $federatedUser->getSingleId() . '#' . $probeSum;
}
+
+
+ /**
+ * @param CircleProbe $circleProbe
+ * @param DataProbe|null $dataProbe
+ *
+ * @return array
+ * @throws InitiatorNotFoundException
+ * @throws RequestBuilderException
+ */
+ public function probeCircles(CircleProbe $circleProbe, ?DataProbe $dataProbe = null): array {
+ $this->federatedUserService->mustHaveCurrentUser();
+
+ if (is_null($dataProbe)) {
+ $dataProbe = new DataProbe();
+ }
+
+ return $this->circleRequest->probeCircles(
+ $this->federatedUserService->getCurrentUser(),
+ $circleProbe,
+ $dataProbe
+ );
+ }
}