830 lines
21 KiB
PHP
830 lines
21 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2021 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
|
|
namespace OCA\Circles\Service;
|
|
|
|
use OCA\Circles\AppInfo\Application;
|
|
use OCA\Circles\Db\CircleRequest;
|
|
use OCA\Circles\Db\MemberRequest;
|
|
use OCA\Circles\Exceptions\CircleNameTooShortException;
|
|
use OCA\Circles\Exceptions\CircleNotFoundException;
|
|
use OCA\Circles\Exceptions\FederatedEventException;
|
|
use OCA\Circles\Exceptions\FederatedItemException;
|
|
use OCA\Circles\Exceptions\InitiatorNotConfirmedException;
|
|
use OCA\Circles\Exceptions\InitiatorNotFoundException;
|
|
use OCA\Circles\Exceptions\MembersLimitException;
|
|
use OCA\Circles\Exceptions\OwnerNotFoundException;
|
|
use OCA\Circles\Exceptions\RemoteInstanceException;
|
|
use OCA\Circles\Exceptions\RemoteNotFoundException;
|
|
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
|
|
use OCA\Circles\Exceptions\RequestBuilderException;
|
|
use OCA\Circles\Exceptions\UnknownRemoteException;
|
|
use OCA\Circles\FederatedItems\CircleConfig;
|
|
use OCA\Circles\FederatedItems\CircleCreate;
|
|
use OCA\Circles\FederatedItems\CircleDestroy;
|
|
use OCA\Circles\FederatedItems\CircleEdit;
|
|
use OCA\Circles\FederatedItems\CircleJoin;
|
|
use OCA\Circles\FederatedItems\CircleLeave;
|
|
use OCA\Circles\FederatedItems\CircleSetting;
|
|
use OCA\Circles\IEntity;
|
|
use OCA\Circles\IFederatedUser;
|
|
use OCA\Circles\Model\Circle;
|
|
use OCA\Circles\Model\Federated\FederatedEvent;
|
|
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;
|
|
use OCA\Circles\Tools\Model\SimpleDataStore;
|
|
use OCA\Circles\Tools\Traits\TArrayTools;
|
|
use OCA\Circles\Tools\Traits\TDeserialize;
|
|
use OCA\Circles\Tools\Traits\TNCLogger;
|
|
use OCA\Circles\Tools\Traits\TStringTools;
|
|
use OCP\ICache;
|
|
use OCP\ICacheFactory;
|
|
use OCP\IL10N;
|
|
use OCP\Security\IHasher;
|
|
|
|
class CircleService {
|
|
use TArrayTools;
|
|
use TStringTools;
|
|
use TNCLogger;
|
|
use TDeserialize;
|
|
|
|
public const CACHE_GET_CIRCLES = 'circles/getCircles';
|
|
public const CACHE_GET_CIRCLES_TTL = 300;
|
|
|
|
|
|
/** @var IL10N */
|
|
private $l10n;
|
|
|
|
/** @var IHasher */
|
|
private $hasher;
|
|
|
|
/** @var ICache $cache */
|
|
private $cache;
|
|
|
|
/** @var CircleRequest */
|
|
private $circleRequest;
|
|
|
|
/** @var MemberRequest */
|
|
private $memberRequest;
|
|
|
|
/** @var RemoteStreamService */
|
|
private $remoteStreamService;
|
|
|
|
/** @var FederatedUserService */
|
|
private $federatedUserService;
|
|
|
|
/** @var FederatedEventService */
|
|
private $federatedEventService;
|
|
|
|
/** @var MemberService */
|
|
private $memberService;
|
|
|
|
/** @var PermissionService */
|
|
private $permissionService;
|
|
|
|
/** @var ConfigService */
|
|
private $configService;
|
|
|
|
|
|
/**
|
|
* @param IL10N $l10n
|
|
* @param IHasher $hasher
|
|
* @param CircleRequest $circleRequest
|
|
* @param MemberRequest $memberRequest
|
|
* @param RemoteStreamService $remoteStreamService
|
|
* @param FederatedUserService $federatedUserService
|
|
* @param FederatedEventService $federatedEventService
|
|
* @param MemberService $memberService
|
|
* @param PermissionService $permissionService
|
|
* @param ConfigService $configService
|
|
*/
|
|
public function __construct(
|
|
IL10N $l10n,
|
|
IHasher $hasher,
|
|
ICacheFactory $cacheFactory,
|
|
CircleRequest $circleRequest,
|
|
MemberRequest $memberRequest,
|
|
RemoteStreamService $remoteStreamService,
|
|
FederatedUserService $federatedUserService,
|
|
FederatedEventService $federatedEventService,
|
|
MemberService $memberService,
|
|
PermissionService $permissionService,
|
|
ConfigService $configService,
|
|
) {
|
|
$this->l10n = $l10n;
|
|
$this->hasher = $hasher;
|
|
$this->cache = $cacheFactory->createDistributed(self::CACHE_GET_CIRCLES);
|
|
$this->circleRequest = $circleRequest;
|
|
$this->memberRequest = $memberRequest;
|
|
$this->remoteStreamService = $remoteStreamService;
|
|
$this->federatedUserService = $federatedUserService;
|
|
$this->federatedEventService = $federatedEventService;
|
|
$this->memberService = $memberService;
|
|
$this->permissionService = $permissionService;
|
|
$this->configService = $configService;
|
|
|
|
$this->setup('app', Application::APP_ID);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param FederatedUser|null $owner
|
|
* @param bool $personal
|
|
* @param bool $local
|
|
*
|
|
* @return array
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws UnknownRemoteException
|
|
* @throws RequestBuilderException
|
|
* @throws CircleNameTooShortException
|
|
*/
|
|
public function create(
|
|
string $name,
|
|
?FederatedUser $owner = null,
|
|
bool $personal = false,
|
|
bool $local = false,
|
|
): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
if (is_null($owner)) {
|
|
$owner = $this->federatedUserService->getCurrentUser();
|
|
}
|
|
|
|
if (is_null($owner)) {
|
|
$owner = $this->federatedUserService->getCurrentApp();
|
|
}
|
|
|
|
if (is_null($owner)) {
|
|
throw new OwnerNotFoundException('owner not defined');
|
|
}
|
|
|
|
$circle = new Circle();
|
|
$circle->setName($this->cleanCircleName($name))
|
|
->setSingleId($this->token(ManagedModel::ID_LENGTH))
|
|
->setSource(Member::TYPE_CIRCLE);
|
|
|
|
if (strlen($circle->getName()) < 3) {
|
|
throw new CircleNameTooShortException('Circle name is too short');
|
|
}
|
|
|
|
if ($personal) {
|
|
$circle->setConfig(Circle::CFG_PERSONAL);
|
|
}
|
|
|
|
if ($local) {
|
|
$circle->addConfig(Circle::CFG_LOCAL);
|
|
}
|
|
|
|
$this->confirmName($circle);
|
|
$this->permissionService->confirmAllowedCircleTypes($circle);
|
|
|
|
$member = new Member();
|
|
$member->importFromIFederatedUser($owner);
|
|
$member->setId($this->token(ManagedModel::ID_LENGTH))
|
|
->setCircleId($circle->getSingleId())
|
|
->setLevel(Member::LEVEL_OWNER)
|
|
->setStatus(Member::STATUS_MEMBER);
|
|
|
|
$this->federatedUserService->setMemberPatron($member);
|
|
|
|
$circle->setOwner($member)
|
|
->setInitiator($member);
|
|
|
|
$event = new FederatedEvent(CircleCreate::class);
|
|
$event->setCircle($circle);
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param bool $forceSync
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function destroy(string $circleId, bool $forceSync = false): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
$event = new FederatedEvent(CircleDestroy::class);
|
|
$event->setCircle($circle);
|
|
$event->forceSync($forceSync);
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param int $config
|
|
* @param bool $superSession
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function updateConfig(string $circleId, int $config): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
$event = new FederatedEvent(CircleConfig::class);
|
|
$event->setCircle($circle);
|
|
$event->setParams(
|
|
new SimpleDataStore(
|
|
[
|
|
'config' => $config,
|
|
'superSession' => $this->federatedUserService->canBypassCurrentUserCondition()
|
|
]
|
|
)
|
|
);
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* if $value is null, setting is unset
|
|
*
|
|
* @param string $circleId
|
|
* @param string $setting
|
|
* @param string|null $value
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function updateSetting(string $circleId, string $setting, ?string $value): array {
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
if (strtolower($setting) === 'password_single' && !is_null($value)) {
|
|
$value = $this->hasher->hash($value);
|
|
}
|
|
|
|
$event = new FederatedEvent(CircleSetting::class);
|
|
$event->setCircle($circle);
|
|
$event->setParams(
|
|
new SimpleDataStore(
|
|
[
|
|
'setting' => $setting,
|
|
'value' => $value,
|
|
'unset' => is_null($value)
|
|
]
|
|
)
|
|
);
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param string $name
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function updateName(string $circleId, string $name): array {
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
$event = new FederatedEvent(CircleEdit::class);
|
|
$event->setCircle($circle);
|
|
$event->setParams(new SimpleDataStore(['name' => $name]));
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
public function updateDisplayName(string $circleId, string $displayName): array {
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
$event = new FederatedEvent(CircleEdit::class);
|
|
$event->setCircle($circle);
|
|
$event->setParams(new SimpleDataStore(['displayName' => $displayName]));
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param string $description
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function updateDescription(string $circleId, string $description): array {
|
|
$circle = $this->getCircle($circleId);
|
|
|
|
$event = new FederatedEvent(CircleEdit::class);
|
|
$event->setCircle($circle);
|
|
$event->setParams(new SimpleDataStore(['description' => $description]));
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws UnknownRemoteException
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function circleJoin(string $circleId): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
|
|
$probe = new CircleProbe();
|
|
$probe->includeNonVisibleCircles()
|
|
->emulateVisitor();
|
|
|
|
$circle = $this->circleRequest->getCircle(
|
|
$circleId,
|
|
$this->federatedUserService->getCurrentUser(),
|
|
$probe
|
|
);
|
|
|
|
if (!$circle->getInitiator()->hasInvitedBy()) {
|
|
$this->federatedUserService->setMemberPatron($circle->getInitiator());
|
|
}
|
|
|
|
$event = new FederatedEvent(CircleJoin::class);
|
|
$event->setCircle($circle);
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param bool $force
|
|
*
|
|
* @return array
|
|
* @throws CircleNotFoundException
|
|
* @throws FederatedEventException
|
|
* @throws FederatedItemException
|
|
* @throws InitiatorNotConfirmedException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws OwnerNotFoundException
|
|
* @throws RemoteInstanceException
|
|
* @throws RemoteNotFoundException
|
|
* @throws RemoteResourceNotFoundException
|
|
* @throws RequestBuilderException
|
|
* @throws UnknownRemoteException
|
|
*/
|
|
public function circleLeave(string $circleId, bool $force = false): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
|
|
$probe = new CircleProbe();
|
|
$probe->includeNonVisibleCircles()
|
|
->emulateVisitor();
|
|
|
|
$circle = $this->circleRequest->getCircle(
|
|
$circleId,
|
|
$this->federatedUserService->getCurrentUser(),
|
|
$probe
|
|
);
|
|
|
|
$event = new FederatedEvent(CircleLeave::class);
|
|
$event->setCircle($circle);
|
|
$event->getParams()->sBool('force', $force);
|
|
|
|
$this->federatedEventService->newEvent($event);
|
|
|
|
return $event->getOutcome();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $circleId
|
|
* @param CircleProbe|null $probe
|
|
*
|
|
* @return Circle
|
|
* @throws CircleNotFoundException
|
|
* @throws InitiatorNotFoundException
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function getCircle(
|
|
string $circleId,
|
|
?CircleProbe $probe = null,
|
|
): Circle {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
|
|
return $this->circleRequest->getCircle(
|
|
$circleId,
|
|
$this->federatedUserService->getCurrentEntity(),
|
|
$probe
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return Circle[]
|
|
* @throws InitiatorNotFoundException
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function getCircles(CircleProbe $probe, bool $caching = false): array {
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
|
|
// This is a quick solution before implementation of DataProbe
|
|
if ($caching && !is_null($this->federatedUserService->getCurrentUser())) {
|
|
$key = $this->generateGetCirclesCacheKey(
|
|
$this->federatedUserService->getCurrentUser(),
|
|
$probe->getChecksum()
|
|
);
|
|
|
|
$cachedData = $this->cache->get($key);
|
|
try {
|
|
if (!is_string($cachedData)) {
|
|
throw new InvalidItemException();
|
|
}
|
|
|
|
return $this->deserializeList($cachedData, Circle::class);
|
|
} catch (InvalidItemException $e) {
|
|
}
|
|
}
|
|
|
|
$circles = $this->circleRequest->getCircles(
|
|
$this->federatedUserService->getCurrentUser(),
|
|
$probe
|
|
);
|
|
|
|
if ($caching && !is_null($this->federatedUserService->getCurrentUser())) {
|
|
$this->cache->set($key, json_encode($circles), self::CACHE_GET_CIRCLES_TTL);
|
|
}
|
|
|
|
return $circles;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function confirmName(Circle $circle): void {
|
|
if ($circle->isConfig(Circle::CFG_SYSTEM)
|
|
|| $circle->isConfig(Circle::CFG_SINGLE)) {
|
|
return;
|
|
}
|
|
|
|
$this->confirmDisplayName($circle);
|
|
$this->generateSanitizedName($circle);
|
|
}
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @throws RequestBuilderException
|
|
*/
|
|
private function confirmDisplayName(Circle $circle) {
|
|
$baseDisplayName = $circle->getName();
|
|
|
|
$i = 1;
|
|
while (true) {
|
|
$testDisplayName = $baseDisplayName . (($i > 1) ? ' (' . $i . ')' : '');
|
|
$test = new Circle();
|
|
$test->setDisplayName($testDisplayName);
|
|
|
|
try {
|
|
$stored = $this->circleRequest->searchCircle($test);
|
|
if ($stored->getSingleId() === $circle->getSingleId()) {
|
|
throw new CircleNotFoundException();
|
|
}
|
|
} catch (CircleNotFoundException $e) {
|
|
$circle->setDisplayName($testDisplayName);
|
|
|
|
return;
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function generateSanitizedName(Circle $circle) {
|
|
$baseSanitizedName = $this->sanitizeName($circle->getName());
|
|
if ($baseSanitizedName === '') {
|
|
$baseSanitizedName = substr($circle->getSingleId(), 0, 3);
|
|
}
|
|
|
|
$i = 1;
|
|
while (true) {
|
|
$testSanitizedName = $baseSanitizedName . (($i > 1) ? ' (' . $i . ')' : '');
|
|
|
|
$test = new Circle();
|
|
$test->setSanitizedName($testSanitizedName);
|
|
|
|
try {
|
|
$stored = $this->circleRequest->searchCircle($test);
|
|
if ($stored->getSingleId() === $circle->getSingleId()) {
|
|
throw new CircleNotFoundException();
|
|
}
|
|
} catch (CircleNotFoundException $e) {
|
|
$circle->setSanitizedName($testSanitizedName);
|
|
|
|
return;
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $name
|
|
*
|
|
* @return string
|
|
*/
|
|
public function sanitizeName(string $name): string {
|
|
// replace '/' with '-' to prevent directory traversal
|
|
// replacing instead of stripping seems the better tradeoff here
|
|
$sanitized = str_replace('/', '-', $name);
|
|
|
|
// remove characters which are illegal on Windows (includes illegal characters on Unix/Linux)
|
|
// see also \OC\Files\Storage\Common::verifyPosixPath(...)
|
|
/** @noinspection CascadeStringReplacementInspection */
|
|
$sanitized = str_replace(['*', '|', '\\', ':', '"', '<', '>', '?'], '', $sanitized);
|
|
|
|
// remove leading+trailing spaces and dots to prevent hidden files
|
|
return trim($sanitized, ' .');
|
|
}
|
|
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @throws MembersLimitException
|
|
*/
|
|
public function confirmCircleNotFull(Circle $circle): void {
|
|
if ($this->isCircleFull($circle)) {
|
|
throw new MembersLimitException(StatusCode::$MEMBER_ADD[121], 121);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @return bool
|
|
* @throws RequestBuilderException
|
|
*/
|
|
public function isCircleFull(Circle $circle): bool {
|
|
$filterMember = new Member();
|
|
$filterMember->setLevel(Member::LEVEL_MEMBER);
|
|
$probe = new MemberProbe();
|
|
$probe->setFilterMember($filterMember);
|
|
|
|
$members = $this->memberRequest->getMembers($circle->getSingleId(), null, $probe);
|
|
|
|
$limit = $this->getInt('members_limit', $circle->getSettings());
|
|
if ($limit === 0) {
|
|
$limit = $this->configService->getAppValueInt(ConfigService::MEMBERS_LIMIT);
|
|
}
|
|
if ($limit === -1) {
|
|
return false;
|
|
}
|
|
|
|
return (sizeof($members) >= $limit);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $name
|
|
*
|
|
* @return string
|
|
*/
|
|
public function cleanCircleName(string $name): string {
|
|
$name = preg_replace('/\s+/', ' ', $name);
|
|
|
|
return trim($name);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param IEntity $entity
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDefinition(IEntity $entity): string {
|
|
if ($entity instanceof Circle) {
|
|
return $this->getDefinitionCircle($entity);
|
|
}
|
|
if ($entity instanceof IFederatedUser) {
|
|
return $this->getDefinitionUser($entity);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @param Circle $circle
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDefinitionCircle(Circle $circle): string {
|
|
$source = Circle::$DEF_SOURCE[$circle->getSource()];
|
|
if ($circle->isConfig(Circle::CFG_NO_OWNER)
|
|
|| $circle->isConfig(Circle::CFG_SINGLE)) {
|
|
return $this->l10n->t('%s', [$source]);
|
|
}
|
|
|
|
if ($circle->isConfig(Circle::CFG_PERSONAL)) {
|
|
return $this->l10n->t('Personal team');
|
|
}
|
|
|
|
if ($circle->hasOwner()) {
|
|
return $this->l10n->t(
|
|
'%s owned by %s',
|
|
[
|
|
$source,
|
|
$this->configService->displayFederatedUser($circle->getOwner(), true)
|
|
]
|
|
);
|
|
}
|
|
|
|
return $source;
|
|
}
|
|
|
|
/**
|
|
* @param IFederatedUser $federatedUser
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDefinitionUser(IFederatedUser $federatedUser): string {
|
|
return $this->l10n->t('%s', [Circle::$DEF_SOURCE[$federatedUser->getUserType()]]);
|
|
}
|
|
|
|
|
|
private function generateGetCirclesCacheKey(FederatedUser $federatedUser, string $probeSum): string {
|
|
return $federatedUser->getSingleId() . '#' . $probeSum;
|
|
}
|
|
|
|
|
|
/**
|
|
* @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
|
|
*
|
|
* @return Circle[]
|
|
* @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
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return Circle[]
|
|
*/
|
|
public function probeCirclesByIds(array $ids, ?DataProbe $dataProbe = null): array {
|
|
if (empty($ids)) {
|
|
return [];
|
|
}
|
|
$this->federatedUserService->mustHaveCurrentUser();
|
|
return $this->circleRequest->probeCirclesByIds(
|
|
$this->federatedUserService->getCurrentUser(),
|
|
$ids,
|
|
$dataProbe ?? new DataProbe()
|
|
);
|
|
}
|
|
}
|