diff options
author | Vinicius Cubas Brand <viniciuscb@gmail.com> | 2017-10-25 18:38:13 +0300 |
---|---|---|
committer | Vinicius Cubas Brand <viniciuscb@gmail.com> | 2017-10-25 18:38:13 +0300 |
commit | a7458c3e73f468198a6725d0b29683ea40e908d4 (patch) | |
tree | c761ac7fcd15139efccfc297e80ed2ff3014b608 /lib | |
parent | 200422b2ffe2bd5b6014f42c5296ce808c9a96f5 (diff) | |
parent | 6e34dea0c8fe0b2e9cd9f07ec85923b7c8097db4 (diff) |
Merge branch 'master' into circles-files-panel
Diffstat (limited to 'lib')
33 files changed, 1324 insertions, 320 deletions
diff --git a/lib/Activity/Provider.php b/lib/Activity/Provider.php index 178a3447..44f6b134 100644 --- a/lib/Activity/Provider.php +++ b/lib/Activity/Provider.php @@ -39,6 +39,7 @@ use OCA\Circles\Service\MiscService; use OCP\Activity\IEvent; use OCP\Activity\IManager; use OCP\Activity\IProvider; +use OpenCloud\Common\Exceptions\InvalidArgumentError; class Provider implements IProvider { @@ -78,17 +79,14 @@ class Provider implements IProvider { /** - * @param string $lang - * @param IEvent $event - * @param IEvent|null $previousEvent - * - * @return IEvent + * {@inheritdoc} */ public function parse($lang, IEvent $event, IEvent $previousEvent = null) { try { $params = $event->getSubjectParameters(); $this->initActivityParser($event, $params); + $circle = Circle::fromJSON($params['circle']); $this->setIcon($event, $circle); @@ -101,7 +99,7 @@ class Provider implements IProvider { return $event; } - throw new InvalidArgumentException(); + return $event; } @@ -157,7 +155,7 @@ class Provider implements IProvider { * @param Circle $circle * @param array $params * - * @throws InvalidArgumentError + * @throws FakeException */ private function parseAsMember(IEvent &$event, Circle $circle, $params) { if ($event->getType() !== 'circles_as_member') { @@ -167,8 +165,6 @@ class Provider implements IProvider { $this->parserCircle->parseSubjectCircleCreate($event, $circle); $this->parserCircle->parseSubjectCircleDelete($event, $circle); $this->parseMemberAsMember($event, $circle, $params); - - throw new InvalidArgumentError(); } @@ -187,8 +183,6 @@ class Provider implements IProvider { $this->parseMemberAsModerator($event, $circle, $params); $this->parseGroupAsModerator($event, $circle, $params); $this->parseLinkAsModerator($event, $circle, $params); - - throw new InvalidArgumentError(); } @@ -211,8 +205,6 @@ class Provider implements IProvider { $this->parserMember->parseSubjectMemberAdd($event, $circle, $member); $this->parserMember->parseSubjectMemberLeft($event, $circle, $member); $this->parserMember->parseSubjectMemberRemove($event, $circle, $member); - - throw new InvalidArgumentError(); } @@ -231,8 +223,6 @@ class Provider implements IProvider { $this->parserGroup->parseGroupLink($event, $circle, $group); $this->parserGroup->parseGroupUnlink($event, $circle, $group); $this->parserGroup->parseGroupLevel($event, $circle, $group); - - throw new InvalidArgumentException(); } @@ -252,8 +242,6 @@ class Provider implements IProvider { $this->parserMember->parseMemberLevel($event, $circle, $member); $this->parserMember->parseMemberRequestInvitation($event, $circle, $member); $this->parserMember->parseMemberOwner($event, $circle, $member); - - throw new InvalidArgumentException(); } @@ -281,8 +269,6 @@ class Provider implements IProvider { $this->parserLink->parseLinkUp($event, $circle, $remote); $this->parserLink->parseLinkDown($event, $circle, $remote); $this->parserLink->parseLinkRemove($event, $circle, $remote); - - throw new InvalidArgumentException(); } diff --git a/lib/Activity/ProviderSubjectMember.php b/lib/Activity/ProviderSubjectMember.php index 5ca24ad3..065b7afd 100644 --- a/lib/Activity/ProviderSubjectMember.php +++ b/lib/Activity/ProviderSubjectMember.php @@ -46,7 +46,7 @@ class ProviderSubjectMember extends ProviderParser { * @throws FakeException */ public function parseSubjectMemberJoin(IEvent &$event, Circle $circle, Member $member) { - if ($event->getSubject() !== 'member_request_invitation') { + if ($event->getSubject() !== 'member_join') { return; } diff --git a/lib/Api/Sharees.php b/lib/Api/Sharees.php index e6e68e0b..2755f93c 100644 --- a/lib/Api/Sharees.php +++ b/lib/Api/Sharees.php @@ -34,6 +34,14 @@ use OCA\Circles\Service\MiscService; use OCP\Share; +/** + * ############### WARNING ################# + * ### + * ### This file is needed and used by Nextcloud 12 and lower. + * ### + * + * @package OCA\Circles\Api + */ class Sharees { @@ -53,9 +61,12 @@ class Sharees { // public static function search($search, $limit, $offset) { public static function search($search) { $c = self::getContainer(); + $userId = \OC::$server->getUserSession() + ->getUser() + ->getUID(); $data = $c->query(CirclesService::class) - ->listCircles(Circle::CIRCLES_ALL, $search, Member::LEVEL_MEMBER); + ->listCircles($userId, Circle::CIRCLES_ALL, $search, Member::LEVEL_MEMBER); $result = array( 'exact' => ['circles'], 'circles' => [] diff --git a/lib/Api/v1/Circles.php b/lib/Api/v1/Circles.php index bbb08d9e..104af315 100644 --- a/lib/Api/v1/Circles.php +++ b/lib/Api/v1/Circles.php @@ -167,14 +167,21 @@ class Circles { * @param mixed $type * @param string $name * @param int $level + * @param string $userId * * @return Circle[] */ - public static function listCircles($type, $name = '', $level = 0) { + public static function listCircles($type, $name = '', $level = 0, $userId = '') { $c = self::getContainer(); + if ($userId === '') { + $userId = \OC::$server->getUserSession() + ->getUser() + ->getUID(); + } + return $c->query(CirclesService::class) - ->listCircles($type, $name, $level); + ->listCircles($userId, $type, $name, $level); } @@ -183,10 +190,32 @@ class Circles { * * Return all the circle the current user is a member. * + * @param string $userId + * * @return Circle[] */ - public static function joinedCircles() { - return self::listCircles(Circle::CIRCLES_ALL, '', Member::LEVEL_MEMBER); + public static function joinedCircles($userId = '') { + return self::listCircles(Circle::CIRCLES_ALL, '', Member::LEVEL_MEMBER, $userId); + } + + + /** + * Circles::joinedCircleIds(); + * + * Return all the circleIds the user is a member, if empty user, using current user. + * + * @param $userId + * + * @return array + */ + public static function joinedCircleIds($userId = '') { + $circleIds = []; + $circles = self::listCircles(Circle::CIRCLES_ALL, '', Member::LEVEL_MEMBER, $userId); + foreach ($circles as $circle) { + $circleIds[] = $circle->getUniqueId(); + } + + return $circleIds; } @@ -358,6 +387,24 @@ class Circles { /** + * Circles::getSharesFromCircle(); + * + * This function will returns all item (array) shared to a specific circle identified by its Id, + * source and type. Limited to current user session. + * + * @param string $circleUniqueId + * + * @return mixed + */ + public static function getSharesFromCircle($circleUniqueId) { + $c = self::getContainer(); + + return $c->query(SharingFrameService::class) + ->getFrameFromCircle($circleUniqueId); + } + + + /** * Circles::linkCircle(); * * Initiate a link procedure. Current user must be at least Admin of the circle. diff --git a/lib/Api/v1/ShotgunCircles.php b/lib/Api/v1/ShotgunCircles.php new file mode 100644 index 00000000..7ea575bc --- /dev/null +++ b/lib/Api/v1/ShotgunCircles.php @@ -0,0 +1,79 @@ +<?php +/** + * 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 2017 + * @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\Api\v1; + + +use OCA\Circles\AppInfo\Application; +use OCA\Circles\Exceptions\ApiVersionIncompatibleException; +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\FederatedLink; +use OCA\Circles\Model\Member; +use OCA\Circles\Model\SharingFrame; +use OCA\Circles\Service\CirclesService; +use OCA\Circles\Service\FederatedLinkService; +use OCA\Circles\Service\MembersService; +use OCA\Circles\Service\MiscService; +use OCA\Circles\Service\SharingFrameService; +use OCP\Util; + +/** + * Better use the other one. + * + * This is a shotgun class; don't blow your foot. + */ +class ShotgunCircles { + + protected static function getContainer() { + $app = new Application(); + + return $app->getContainer(); + } + + + /** + * ShotgunCircles::getSharesFromCircle(); + * + * This function will returns all item (array) shared to a specific circle identified by its Id, + * source and type. + * + * Warning - please use Circles::getSharesFromCircle for any interaction with the current user + * session. + * + * @param string $circleUniqueId + * @param string $userId + * + * @return SharingFrame[] + */ + public static function getSharesFromCircle($circleUniqueId, $userId = '') { + $c = self::getContainer(); + + return $c->query(SharingFrameService::class) + ->forceGetFrameFromCircle($circleUniqueId, $userId); + } + + +}
\ No newline at end of file diff --git a/lib/Circles/FileSharingBroadcaster.php b/lib/Circles/FileSharingBroadcaster.php index d60d4ace..e945052d 100644 --- a/lib/Circles/FileSharingBroadcaster.php +++ b/lib/Circles/FileSharingBroadcaster.php @@ -204,9 +204,6 @@ class FileSharingBroadcaster implements IBroadcaster { * @param string $author * @param $circleName * @param string $email - * - * @internal param string $filename - * @internal param string $circle */ protected function sendMail($fileName, $link, $author, $circleName, $email) { $message = $this->mailer->createMessage(); diff --git a/lib/Collaboration/v1/CollaboratorSearchPlugin.php b/lib/Collaboration/v1/CollaboratorSearchPlugin.php new file mode 100644 index 00000000..0195266e --- /dev/null +++ b/lib/Collaboration/v1/CollaboratorSearchPlugin.php @@ -0,0 +1,82 @@ +<?php +/** + * 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 Arthur Schiwon <blizzz@arthur-schiwon.de> + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2017 + * @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\Collaboration\v1; + +use OCA\Circles\Api\v1\Circles; +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\Member; +use OCA\Circles\Service\MiscService; +use OCP\Collaboration\Collaborators\ISearchPlugin; +use OCP\Collaboration\Collaborators\ISearchResult; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\Share; + +class CollaboratorSearchPlugin implements ISearchPlugin { + + /** + * {@inheritdoc} + */ + public function search($search, $limit, $offset, ISearchResult $searchResult) { + $wide = $exact = []; + + $circles = Circles::listCircles(Circle::CIRCLES_ALL, $search, Member::LEVEL_MEMBER); + foreach ($circles as $circle) { + $entry = $this->addResultEntry($circle); + if (strtolower($circle->getName()) === strtolower($search)) { + $exact[] = $entry; + } else { + $wide[] = $entry; + } + } + + $type = new SearchResultType('circles'); + $searchResult->addResultSet($type, $wide, $exact); + } + + + /** + * @param Circle $circle + * + * @return array + */ + private function addResultEntry(Circle $circle) { + + return [ + 'label' => $circle->getName(), + 'value' => [ + 'shareType' => Share::SHARE_TYPE_CIRCLE, + 'shareWith' => $circle->getUniqueId(), + 'circleInfo' => $circle->getInfo(), + 'circleOwner' => MiscService::getDisplay( + $circle->getOwner() + ->getUserId(), Member::TYPE_USER + ) + ], + ]; + } +}
\ No newline at end of file diff --git a/lib/Command/Clean.php b/lib/Command/Clean.php new file mode 100644 index 00000000..2f55faab --- /dev/null +++ b/lib/Command/Clean.php @@ -0,0 +1,132 @@ +<?php +/** + * 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 2017 + * @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\Command; + +use Exception; +use OC\Core\Command\Base; +use OCA\Circles\Db\CirclesRequest; +use OCA\Circles\Db\CoreRequestBuilder; +use OCA\Circles\Db\MembersRequest; +use OCA\Circles\Exceptions\CircleDoesNotExistException; +use OCP\IDBConnection; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + + +class Clean extends Base { + + /** @var IDBConnection */ + private $dbConnection; + + /** @var CirclesRequest */ + private $circlesRequest; + + /** @var MembersRequest */ + private $membersRequest; + + + /** + * Clean constructor. + * + * @param IDBConnection $connection + * @param CirclesRequest $circlesRequest + * @param MembersRequest $membersRequest + */ + public function __construct( + IDBConnection $connection, CirclesRequest $circlesRequest, MembersRequest $membersRequest + ) { + parent::__construct(); + $this->dbConnection = $connection; + $this->circlesRequest = $circlesRequest; + $this->membersRequest = $membersRequest; + + } + + protected function configure() { + parent::configure(); + $this->setName('circles:clean') + ->setDescription('remove all extra data from database'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + + try { + $this->fixUserType(); + $this->removeCirclesWithNoOwner(); + $this->removeMembersWithNoCircles(); + + $output->writeln('done'); + } catch (Exception $e) { + $output->writeln($e->getMessage()); + } + } + + + private function fixUserType() { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update(CoreRequestBuilder::TABLE_MEMBERS) + ->set('user_type', $qb->createNamedParameter(1)) + ->where( + $qb->expr() + ->eq('user_type', $qb->createNamedParameter(0)) + ); + + return $qb->execute(); + } + + + private function removeCirclesWithNoOwner() { + + $circles = $this->circlesRequest->forceGetCircles(); + + foreach ($circles as $circle) { + if ($circle->getOwner() + ->getUserId() === null) { + $this->circlesRequest->destroyCircle($circle->getUniqueId()); + } + } + } + + + private function removeMembersWithNoCircles() { + + $members = $this->membersRequest->forceGetAllMembers(); + + foreach ($members as $member) { + try { + $this->circlesRequest->forceGetCircle($member->getCircleId()); + + } catch (CircleDoesNotExistException $e) { + $this->membersRequest->removeMember($member); + } + } + + } +} + + + diff --git a/lib/Command/FixUniqueId.php b/lib/Command/FixUniqueId.php new file mode 100644 index 00000000..bb7ac131 --- /dev/null +++ b/lib/Command/FixUniqueId.php @@ -0,0 +1,148 @@ +<?php +/** + * 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 2017 + * @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\Command; + +use Exception; +use OC\Core\Command\Base; +use OC\Share\Share; +use OCA\Circles\Db\CirclesRequest; +use OCA\Circles\Db\CoreRequestBuilder; +use OCA\Circles\Model\Circle; +use OCP\IDBConnection; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + + +class FixUniqueId extends Base { + + /** @var IDBConnection */ + protected $connection; + + /** @var CirclesRequest */ + private $circlesRequest; + + public function __construct(CirclesRequest $circlesRequest, IDBConnection $connection) { + parent::__construct(); + $this->circlesRequest = $circlesRequest; + $this->connection = $connection; + } + + protected function configure() { + parent::configure(); + $this->setName('circles:fixuniqueid') + ->setDescription('fix Unique Id issue.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + + try { + $this->swapToShortenUniqueId(); + + $output->writeln('done'); + } catch (Exception $e) { + $output->writeln($e->getMessage()); + } + } + + + private function swapToShortenUniqueId() { + + $qb = $this->connection->getQueryBuilder(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->select('id', 'unique_id') + ->from(CoreRequestBuilder::TABLE_CIRCLES); + + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $circleId = $data['id']; + + $shortenUniqueId = substr($data['unique_id'], 0, Circle::SHORT_UNIQUE_ID_LENGTH); + + $this->swapToShortenUniqueIdInTable( + $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_GROUPS + ); + $this->swapToShortenUniqueIdInTable( + $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS + ); +// +// $this->cleanBuggyDuplicateEntries( +// $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS, 'user_id' +// ); + + $this->swapToShortenUniqueIdInTable( + $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS + ); + + $this->swapToShortenUniqueIdInTable( + $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS + ); + + $this->swapToShortenUniqueIdInShares($circleId, $shortenUniqueId); + } + $cursor->closeCursor(); + } + + + private function swapToShortenUniqueIdInTable($circleId, $shortenUniqueId, $table) { + + $qb = $this->connection->getQueryBuilder(); + $qb->update($table) + ->where( + $qb->expr() + ->eq('circle_id', $qb->createNamedParameter($circleId)) + ); + + $qb->set('circle_id', $qb->createNamedParameter($shortenUniqueId)); + $qb->execute(); + } + + + private function swapToShortenUniqueIdInShares($circleId, $shortenUniqueId) { + $qb = $this->connection->getQueryBuilder(); + $expr = $qb->expr(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->update('share') + ->where( + $expr->andX( + $expr->eq( + 'share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE) + ), + $expr->eq('share_with', $qb->createNamedParameter($circleId)) + ) + ); + + $qb->set('share_with', $qb->createNamedParameter($shortenUniqueId)); + $qb->execute(); + } + + +} + + + diff --git a/lib/Command/Groups.php b/lib/Command/Groups.php new file mode 100644 index 00000000..fe6505d3 --- /dev/null +++ b/lib/Command/Groups.php @@ -0,0 +1,153 @@ +<?php +/** + * 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 2017 + * @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\Command; + +use Exception; +use OC\Core\Command\Base; +use OCA\Circles\Db\CirclesRequest; +use OCA\Circles\Exceptions\CommandMissingArgumentException; +use OCA\Circles\Exceptions\FakeException; +use OCP\IL10N; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class Groups extends Base { + + /** @var IL10N */ + private $l10n; + + /** @var CirclesRequest */ + private $circlesRequest; + + /** + * Groups constructor. + * + * @param IL10N $l10n + * @param CirclesRequest $circlesRequest + */ + public function __construct(IL10N $l10n, CirclesRequest $circlesRequest) { + parent::__construct(); + $this->l10n = $l10n; + $this->circlesRequest = $circlesRequest; + } + + + protected function configure() { + parent::configure(); + $this->setName('circles:groups') + ->setDescription('manage the linked groups') + ->addOption('list', 'l', InputOption::VALUE_NONE, 'list all linked group') + ->addOption('link', 'a', InputOption::VALUE_NONE, 'link a group to a circle') + ->addOption('unlink', 'd', InputOption::VALUE_NONE, 'unlink a group from a circle') + ->addArgument('circle_id', InputArgument::OPTIONAL, 'id of the circle') + ->addArgument('group', InputArgument::OPTIONAL, 'name of the group'); + } + + + protected function execute(InputInterface $input, OutputInterface $output) { + + try { + $this->listLinkedGroups($input, $output); + $this->addLinkedGroups($input, $output); + $this->delLinkedGroups($input, $output); + + } catch (FakeException $e) { + $output->writeln('done'); + } catch (Exception $e) { + $output->writeln($e->getMessage()); + } + } + + + /** + * @param InputInterface $input + * @param OutputInterface $output + * + * @throws FakeException + */ + private function listLinkedGroups(InputInterface $input, OutputInterface $output) { + if ($input->getOption('list') !== true) { + return; + } + + throw new FakeException(); + } + + + /** + * @param InputInterface $input + * @param OutputInterface $output + * + * @throws FakeException + */ + private function addLinkedGroups(InputInterface $input, OutputInterface $output) { + if ($input->getOption('link') !== true) { + return; + } + + list($circleId, $group) = $this->getCircleIdAndGroupFromArguments($input); + + throw new FakeException(); + } + + + /** + * @param InputInterface $input + * @param OutputInterface $output + * + * @throws FakeException + */ + private function delLinkedGroups(InputInterface $input, OutputInterface $output) { + if ($input->getOption('unlink') !== true) { + return; + } + + list($circleId, $group) = $this->getCircleIdAndGroupFromArguments($input); + + throw new FakeException(); + } + + + private function getCircleIdAndGroupFromArguments(InputInterface $input) { + if ($input->getArgument('circle_id') === null + || $input->getArgument('group') === null) { + throw new CommandMissingArgumentException( + + ); +// $this->l10n->t( +// 'Missing argument: {cmd} circle_id group', ['cmd' => './occ circles:link'] +// ) + } + + return [$input->getArgument('circle_id'), $input->getArgument('group')]; + } + +} + diff --git a/lib/Controller/CirclesController.php b/lib/Controller/CirclesController.php index 3fda607c..1ea2e3d2 100644 --- a/lib/Controller/CirclesController.php +++ b/lib/Controller/CirclesController.php @@ -73,7 +73,7 @@ class CirclesController extends BaseController { public function listing($type, $name = '', $level = 0) { try { - $data = $this->circlesService->listCircles($type, $name, $level); + $data = $this->circlesService->listCircles($this->userId, $type, $name, $level); return $this->success(['type' => $type, 'data' => $data]); } catch (CircleTypeDisabledException $e) { diff --git a/lib/Controller/NavigationController.php b/lib/Controller/NavigationController.php index 95fa9f0b..b1ca633a 100644 --- a/lib/Controller/NavigationController.php +++ b/lib/Controller/NavigationController.php @@ -26,8 +26,10 @@ namespace OCA\Circles\Controller; +use OCA\Circles\Api\v1\Circles; +use OCA\Circles\Api\v1\ShotgunCircles; use OCA\Circles\AppInfo\Application; -use \OCA\Circles\Model\Circle; +use OCA\Circles\Model\Circle; use OCA\Circles\Service\ConfigService; use OCA\Testing\Config; use OCP\AppFramework\Http; @@ -45,6 +47,7 @@ class NavigationController extends BaseController { * @return TemplateResponse */ public function navigate() { + $data = [ 'allowed_circles' => array( Circle::CIRCLES_PERSONAL => $this->configService->isCircleAllowed( diff --git a/lib/Db/CircleProviderRequestBuilder.php b/lib/Db/CircleProviderRequestBuilder.php index 2fb98ad9..c12e0e9e 100644 --- a/lib/Db/CircleProviderRequestBuilder.php +++ b/lib/Db/CircleProviderRequestBuilder.php @@ -154,8 +154,6 @@ class CircleProviderRequestBuilder extends CoreRequestBuilder { * * @param IQueryBuilder $qb * @param $files - * - * @internal param $fileId */ protected function limitToFiles(IQueryBuilder &$qb, $files) { diff --git a/lib/Db/CirclesRequest.php b/lib/Db/CirclesRequest.php index f51423d5..d2ae5ef4 100644 --- a/lib/Db/CirclesRequest.php +++ b/lib/Db/CirclesRequest.php @@ -30,12 +30,8 @@ namespace OCA\Circles\Db; use OCA\Circles\Exceptions\CircleAlreadyExistsException; use OCA\Circles\Exceptions\CircleDoesNotExistException; -use OCA\Circles\Exceptions\FederatedLinkDoesNotExistException; -use OCA\Circles\Exceptions\SharingFrameDoesNotExistException; use OCA\Circles\Model\Circle; -use OCA\Circles\Model\FederatedLink; use OCA\Circles\Model\Member; -use OCA\Circles\Model\SharingFrame; class CirclesRequest extends CirclesRequestBuilder { @@ -73,6 +69,32 @@ class CirclesRequest extends CirclesRequestBuilder { /** + * forceGetCircles(); + * + * returns data of a all circles. + * + * WARNING: This function does not filters data regarding the current user/viewer. + * In case of interaction with users, Please use getCircles() instead. + * + * @return Circle[] + */ + public function forceGetCircles() { + + $qb = $this->getCirclesSelectSql(); + $this->leftJoinOwner($qb); + + $circles = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $circles[] = $this->parseCirclesSelectSql($data); + } + $cursor->closeCursor(); + + return $circles; + } + + + /** * forceGetCircleByName(); * * returns data of a circle from its Name. @@ -111,7 +133,7 @@ class CirclesRequest extends CirclesRequestBuilder { * @param string $name * @param int $level * - * @return array + * @return Circle[] */ public function getCircles($userId, $type = 0, $name = '', $level = 0) { if ($type === 0) { @@ -128,16 +150,16 @@ class CirclesRequest extends CirclesRequestBuilder { } $this->limitRegardingCircleType($qb, $userId, -1, $type, $name); - $result = []; + $circles = []; $cursor = $qb->execute(); while ($data = $cursor->fetch()) { if ($name === '' || stripos(strtolower($data['name']), strtolower($name)) !== false) { - $result[] = $this->parseCirclesSelectSql($data); + $circles[] = $this->parseCirclesSelectSql($data); } } $cursor->closeCursor(); - return $result; + return $circles; } @@ -281,43 +303,6 @@ class CirclesRequest extends CirclesRequestBuilder { } - /** - * saveFrame() - * - * Insert a new entry in the database to save the SharingFrame. - * - * @param SharingFrame $frame - */ - public function saveFrame(SharingFrame $frame) { - $qb = $this->getSharesInsertSql(); - $circle = $frame->getCircle(); - $qb->setValue('circle_id', $qb->createNamedParameter($circle->getUniqueId())) - ->setValue('source', $qb->createNamedParameter($frame->getSource())) - ->setValue('type', $qb->createNamedParameter($frame->getType())) - ->setValue('headers', $qb->createNamedParameter($frame->getHeaders(true))) - ->setValue('author', $qb->createNamedParameter($frame->getAuthor())) - ->setValue('cloud_id', $qb->createNamedParameter($frame->getCloudId())) - ->setValue('unique_id', $qb->createNamedParameter($frame->getUniqueId())) - ->setValue('payload', $qb->createNamedParameter($frame->getPayload(true))); - - $qb->execute(); - } - - - public function updateFrame(SharingFrame $frame) { - $qb = $this->getSharesUpdateSql($frame->getUniqueId()); - $circle = $frame->getCircle(); - $qb->set('circle_id', $qb->createNamedParameter($circle->getUniqueId())) - ->set('source', $qb->createNamedParameter($frame->getSource())) - ->set('type', $qb->createNamedParameter($frame->getType())) - ->set('headers', $qb->createNamedParameter($frame->getHeaders(true))) - ->set('author', $qb->createNamedParameter($frame->getAuthor())) - ->set('cloud_id', $qb->createNamedParameter($frame->getCloudId())) - ->set('unique_id', $qb->createNamedParameter($frame->getUniqueId())) - ->set('payload', $qb->createNamedParameter($frame->getPayload(true))); - - $qb->execute(); - } public function updateCircle(Circle $circle) { @@ -354,31 +339,6 @@ class CirclesRequest extends CirclesRequestBuilder { } - /** - * @param string $circleUniqueId - * @param string $frameUniqueId - * - * @return SharingFrame - * @throws SharingFrameDoesNotExistException - */ - public function getFrame($circleUniqueId, $frameUniqueId) { - $qb = $this->getSharesSelectSql(); - $this->limitToUniqueId($qb, $frameUniqueId); - $this->limitToCircleId($qb, $circleUniqueId); - $this->leftJoinCircle($qb); - - $cursor = $qb->execute(); - $data = $cursor->fetch(); - $cursor->closeCursor(); - - if ($data === false) { - throw new SharingFrameDoesNotExistException($this->l10n->t('Sharing Frame does not exist')); - } - - $entry = $this->parseSharesSelectSql($data); - - return $entry; - } }
\ No newline at end of file diff --git a/lib/Db/CirclesRequestBuilder.php b/lib/Db/CirclesRequestBuilder.php index aad08c36..5cfbfd77 100644 --- a/lib/Db/CirclesRequestBuilder.php +++ b/lib/Db/CirclesRequestBuilder.php @@ -245,7 +245,7 @@ class CirclesRequestBuilder extends CoreRequestBuilder { * @param IQueryBuilder $qb * @param string $userId */ - protected function leftJoinUserIdAsViewer(IQueryBuilder &$qb, $userId) { + public function leftJoinUserIdAsViewer(IQueryBuilder &$qb, $userId) { if ($qb->getType() !== QueryBuilder::SELECT) { return; @@ -274,12 +274,13 @@ class CirclesRequestBuilder extends CoreRequestBuilder { ); } + /** * Left Join members table to get the owner of the circle. * * @param IQueryBuilder $qb */ - protected function leftJoinOwner(IQueryBuilder &$qb) { + public function leftJoinOwner(IQueryBuilder &$qb) { if ($qb->getType() !== QueryBuilder::SELECT) { return; @@ -309,88 +310,6 @@ class CirclesRequestBuilder extends CoreRequestBuilder { } - /** - * Left Join circle table to get more information about the circle. - * - * @param IQueryBuilder $qb - */ - protected function leftJoinCircle(IQueryBuilder &$qb) { - - if ($qb->getType() !== QueryBuilder::SELECT) { - return; - } - - $expr = $qb->expr(); - $pf = $this->default_select_alias . '.'; - - /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->selectAlias('lc.type', 'circle_type') - ->selectAlias('lc.name', 'circle_name') - ->leftJoin( - $this->default_select_alias, CoreRequestBuilder::TABLE_CIRCLES, 'lc', - $expr->eq( - $pf . 'circle_id', - $qb->createFunction( - 'SUBSTR(`lc`.`unique_id`, 1, ' . Circle::SHORT_UNIQUE_ID_LENGTH . ')' - ) - ) - ); - } - - - /** - * Base of the Sql Select request for Shares - * - * @return IQueryBuilder - */ - protected function getSharesSelectSql() { - $qb = $this->dbConnection->getQueryBuilder(); - - /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select( - 's.circle_id', 's.source', 's.type', 's.author', 's.cloud_id', 's.payload', - 's.creation', 's.headers', 's.unique_id' - ) - ->from(self::TABLE_SHARES, 's'); - - $this->default_select_alias = 's'; - - return $qb; - } - - - /** - * Base of the Sql Insert request for Shares - * - * @return IQueryBuilder - */ - protected function getSharesInsertSql() { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->insert(self::TABLE_SHARES) - ->setValue('creation', $qb->createFunction('NOW()')); - - return $qb; - } - - - /** - * Base of the Sql Update request for Shares - * - * @param string $uniqueId - * - * @return IQueryBuilder - */ - protected function getSharesUpdateSql($uniqueId) { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->update(self::TABLE_SHARES) - ->where( - $qb->expr() - ->eq('unique_id', $qb->createNamedParameter((string)$uniqueId)) - ); - - return $qb; - } - /** * Base of the Sql Insert request for Shares @@ -502,32 +421,4 @@ class CirclesRequestBuilder extends CoreRequestBuilder { } - /** - * @param array $data - * - * @return SharingFrame - */ - protected function parseSharesSelectSql($data) { - $frame = new SharingFrame($data['source'], $data['type']); - - $circle = new Circle(); - $circle->setUniqueId($data['circle_id']); - if (key_exists('circle_type', $data)) { - $circle->setType($data['circle_type']); - $circle->setName($data['circle_name']); - } - - $frame->setCircle($circle); - - $frame->setAuthor($data['author']); - $frame->setCloudId($data['cloud_id']); - $frame->setPayload(json_decode($data['payload'], true)); - $frame->setCreation($data['creation']); - $frame->setHeaders(json_decode($data['headers'], true)); - $frame->setUniqueId($data['unique_id']); - - return $frame; - } - - }
\ No newline at end of file diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 2e569590..307dfdb2 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -103,8 +103,6 @@ class CoreRequestBuilder { * * @param IQueryBuilder $qb * @param $userId - * - * @internal param int $circleId */ protected function limitToUserId(IQueryBuilder &$qb, $userId) { $this->limitToDBField($qb, 'user_id', $userId); @@ -116,8 +114,6 @@ class CoreRequestBuilder { * * @param IQueryBuilder $qb * @param int $type - * - * @internal param int $circleId */ protected function limitToUserType(IQueryBuilder &$qb, $type) { $this->limitToDBField($qb, 'user_type', $type); @@ -329,6 +325,37 @@ class CoreRequestBuilder { } + + /** + * Left Join circle table to get more information about the circle. + * + * @param IQueryBuilder $qb + */ + protected function leftJoinCircle(IQueryBuilder &$qb) { + + if ($qb->getType() !== QueryBuilder::SELECT) { + return; + } + + $expr = $qb->expr(); + $pf = $this->default_select_alias . '.'; + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->selectAlias('lc.type', 'circle_type') + ->selectAlias('lc.name', 'circle_name') + ->leftJoin( + $this->default_select_alias, CoreRequestBuilder::TABLE_CIRCLES, 'lc', + $expr->eq( + $pf . 'circle_id', + $qb->createFunction( + 'SUBSTR(`lc`.`unique_id`, 1, ' . Circle::SHORT_UNIQUE_ID_LENGTH . ')' + ) + ) + ); + } + + + /** * link to the groupId/UserId of the NC DB. * diff --git a/lib/Db/MembersRequest.php b/lib/Db/MembersRequest.php index 5de7d142..55a52627 100644 --- a/lib/Db/MembersRequest.php +++ b/lib/Db/MembersRequest.php @@ -88,6 +88,7 @@ class MembersRequest extends MembersRequestBuilder { $qb = $this->getMembersSelectSql(); $this->limitToMembersAndAlmost($qb); $this->limitToLevel($qb, $level); + $this->limitToCircleId($qb, $circleUniqueId); $members = []; @@ -106,6 +107,30 @@ class MembersRequest extends MembersRequestBuilder { /** + * Returns all members. + * + * WARNING: This function does not filters data regarding the current user/viewer. + * In case of interaction with users, Please use getMembers() instead. + * + * + * @return Member[] + */ + public function forceGetAllMembers() { + + $qb = $this->getMembersSelectSql(); + + $members = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $members[] = $this->parseMembersSelectSql($data); + } + $cursor->closeCursor(); + + return $members; + } + + + /** * @param string $circleUniqueId * @param Member $viewer * @@ -452,29 +477,56 @@ class MembersRequest extends MembersRequestBuilder { * @param string $uniqueCircleId */ public function removeAllFromCircle($uniqueCircleId) { - $qb = $this->getMembersDeleteSql($uniqueCircleId); + $qb = $this->getMembersDeleteSql(); + $expr = $qb->expr(); + + $qb->where($expr->eq('circle_id', $qb->createNamedParameter($uniqueCircleId))); $qb->execute(); } /** - * removeAllFromUser(); + * removeAllMembershipsFromUser(); * * remove All membership from a User. Used when removing a User from the Cloud. * - * @param $userId + * @param string $userId */ - public function removeAllFromUser($userId) { + public function removeAllMembershipsFromUser($userId) { if ($userId === '') { return; } - $qb = $this->getMembersDeleteSql('', Member::TYPE_USER, $userId); + $qb = $this->getMembersDeleteSql(); + $expr = $qb->expr(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->where( + $expr->andX( + $expr->eq('user_id', $qb->createNamedParameter($userId)), + $expr->eq('user_type', $qb->createNamedParameter(Member::TYPE_USER)) + ) + ); + $qb->execute(); } /** + * remove member, identified by its id, type and circleId + * + * @param Member $member + */ + public function removeMember(Member $member) { + $qb = $this->getMembersDeleteSql(); + $this->limitToCircleId($qb, $member->getCircleId()); + $this->limitToUserId($qb, $member->getUserId()); + $this->limitToUserType($qb, $member->getType()); + + $qb->execute(); + } + + /** * update database entry for a specific Group. * * @param Member $member diff --git a/lib/Db/MembersRequestBuilder.php b/lib/Db/MembersRequestBuilder.php index 0279a624..5d6530d5 100644 --- a/lib/Db/MembersRequestBuilder.php +++ b/lib/Db/MembersRequestBuilder.php @@ -81,7 +81,8 @@ class MembersRequestBuilder extends CoreRequestBuilder { $qb->select( 'm.user_id', 'm.user_type', 'm.circle_id', 'm.level', 'm.status', 'm.note', 'm.joined' ) - ->from(self::TABLE_MEMBERS, 'm'); + ->from(self::TABLE_MEMBERS, 'm') + ->orderBy('m.joined'); $this->default_select_alias = 'm'; @@ -188,27 +189,11 @@ class MembersRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Delete request for Members * - * @param string $uniqueCircleId - * @param string $userId - * @param int $type - * * @return IQueryBuilder */ - protected function getMembersDeleteSql($uniqueCircleId, $type = 0, $userId = '') { + protected function getMembersDeleteSql() { $qb = $this->dbConnection->getQueryBuilder(); - $expr = $qb->expr(); - - $and = $expr->andX(); - if ($uniqueCircleId !== '') { - $and->add($expr->eq('circle_id', $qb->createNamedParameter($uniqueCircleId))); - } - if ($type > 0) { - $and->add($expr->eq('user_id', $qb->createNamedParameter($userId))); - $and->add($expr->eq('user_type', $qb->createNamedParameter($type))); - } - - $qb->delete(CoreRequestBuilder::TABLE_MEMBERS) - ->where($and); + $qb->delete(CoreRequestBuilder::TABLE_MEMBERS); return $qb; } diff --git a/lib/Db/SharingFrameRequest.php b/lib/Db/SharingFrameRequest.php new file mode 100644 index 00000000..7882bd46 --- /dev/null +++ b/lib/Db/SharingFrameRequest.php @@ -0,0 +1,129 @@ +<?php +/** + * 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 2017 + * @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\Db; + + +use OCA\Circles\Exceptions\CircleAlreadyExistsException; +use OCA\Circles\Exceptions\CircleDoesNotExistException; +use OCA\Circles\Exceptions\FederatedLinkDoesNotExistException; +use OCA\Circles\Exceptions\SharingFrameDoesNotExistException; +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\FederatedLink; +use OCA\Circles\Model\Member; +use OCA\Circles\Model\SharingFrame; + +class SharingFrameRequest extends SharingFrameRequestBuilder { + + + /** + * @param string $circleUniqueId + * @param string $frameUniqueId + * + * @return SharingFrame + * @throws SharingFrameDoesNotExistException + */ + public function getSharingFrame($circleUniqueId, $frameUniqueId) { + $qb = $this->getSharesSelectSql(); + $this->limitToUniqueId($qb, $frameUniqueId); + $this->limitToCircleId($qb, $circleUniqueId); + $this->leftJoinCircle($qb); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new SharingFrameDoesNotExistException($this->l10n->t('Sharing Frame does not exist')); + } + + $entry = $this->parseSharesSelectSql($data); + + return $entry; + } + + + /** + * @param string $circleUniqueId + * + * @return SharingFrame[] + */ + public function getSharingFramesFromCircle($circleUniqueId) { + $qb = $this->getSharesSelectSql(); + $this->limitToCircleId($qb, $circleUniqueId); + + $frames = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $frames[] = $this->parseSharesSelectSql($data); + } + $cursor->closeCursor(); + + return $frames; + } + + + /** + * saveFrame() + * + * Insert a new entry in the database to save the SharingFrame. + * + * @param SharingFrame $frame + */ + public function saveSharingFrame(SharingFrame $frame) { + $qb = $this->getSharesInsertSql(); + $circle = $frame->getCircle(); + $qb->setValue('circle_id', $qb->createNamedParameter($circle->getUniqueId())) + ->setValue('source', $qb->createNamedParameter($frame->getSource())) + ->setValue('type', $qb->createNamedParameter($frame->getType())) + ->setValue('headers', $qb->createNamedParameter($frame->getHeaders(true))) + ->setValue('author', $qb->createNamedParameter($frame->getAuthor())) + ->setValue('cloud_id', $qb->createNamedParameter($frame->getCloudId())) + ->setValue('unique_id', $qb->createNamedParameter($frame->getUniqueId())) + ->setValue('payload', $qb->createNamedParameter($frame->getPayload(true))); + + $qb->execute(); + } + + + public function updateSharingFrame(SharingFrame $frame) { + $qb = $this->getSharesUpdateSql($frame->getUniqueId()); + $circle = $frame->getCircle(); + $qb->set('circle_id', $qb->createNamedParameter($circle->getUniqueId())) + ->set('source', $qb->createNamedParameter($frame->getSource())) + ->set('type', $qb->createNamedParameter($frame->getType())) + ->set('headers', $qb->createNamedParameter($frame->getHeaders(true))) + ->set('author', $qb->createNamedParameter($frame->getAuthor())) + ->set('cloud_id', $qb->createNamedParameter($frame->getCloudId())) + ->set('unique_id', $qb->createNamedParameter($frame->getUniqueId())) + ->set('payload', $qb->createNamedParameter($frame->getPayload(true))); + + $qb->execute(); + } + + +}
\ No newline at end of file diff --git a/lib/Db/SharingFrameRequestBuilder.php b/lib/Db/SharingFrameRequestBuilder.php new file mode 100644 index 00000000..82d002cb --- /dev/null +++ b/lib/Db/SharingFrameRequestBuilder.php @@ -0,0 +1,145 @@ +<?php + +/** + * 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 2017 + * @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\Db; + + +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\SharingFrame; +use OCA\Circles\Service\ConfigService; +use OCA\Circles\Service\MiscService; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\IL10N; + +class SharingFrameRequestBuilder extends CoreRequestBuilder { + + /** @var CirclesRequest */ + protected $circlesRequest; + + /** @var MembersRequest */ + protected $membersRequest; + + /** + * CirclesRequestBuilder constructor. + * + * {@inheritdoc} + * @param MembersRequest $membersRequest + */ + public function __construct( + IL10N $l10n, IDBConnection $connection, CirclesRequest $circlesRequest, + MembersRequest $membersRequest, ConfigService $configService, MiscService $miscService + ) { + parent::__construct($l10n, $connection, $configService, $miscService); + $this->circlesRequest = $circlesRequest; + $this->membersRequest = $membersRequest; + } + + + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function getSharesSelectSql() { + $qb = $this->dbConnection->getQueryBuilder(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->select( + 's.circle_id', 's.source', 's.type', 's.author', 's.cloud_id', 's.payload', + 's.creation', 's.headers', 's.unique_id' + ) + ->from(self::TABLE_SHARES, 's'); + + $this->default_select_alias = 's'; + + return $qb; + } + + + /** + * Base of the Sql Insert request for Shares + * + * @return IQueryBuilder + */ + protected function getSharesInsertSql() { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert(self::TABLE_SHARES) + ->setValue('creation', $qb->createFunction('NOW()')); + + return $qb; + } + + + /** + * Base of the Sql Update request for Shares + * + * @param string $uniqueId + * + * @return IQueryBuilder + */ + protected function getSharesUpdateSql($uniqueId) { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update(self::TABLE_SHARES) + ->where( + $qb->expr() + ->eq('unique_id', $qb->createNamedParameter((string)$uniqueId)) + ); + + return $qb; + } + + + /** + * @param array $data + * + * @return SharingFrame + */ + protected function parseSharesSelectSql($data) { + $frame = new SharingFrame($data['source'], $data['type']); + + $circle = new Circle(); + $circle->setUniqueId($data['circle_id']); + if (key_exists('circle_type', $data)) { + $circle->setType($data['circle_type']); + $circle->setName($data['circle_name']); + } + + $frame->setCircle($circle); + + $frame->setAuthor($data['author']); + $frame->setCloudId($data['cloud_id']); + $frame->setPayload(json_decode($data['payload'], true)); + $frame->setCreation($data['creation']); + $frame->setHeaders(json_decode($data['headers'], true)); + $frame->setUniqueId($data['unique_id']); + + return $frame; + } + + +}
\ No newline at end of file diff --git a/lib/Events/UserEvents.php b/lib/Events/UserEvents.php index f9041e18..8b8986a9 100644 --- a/lib/Events/UserEvents.php +++ b/lib/Events/UserEvents.php @@ -4,12 +4,16 @@ namespace OCA\Circles\Events; +use OCA\Circles\Service\CirclesService; use OCA\Circles\Service\GroupsService; use OCA\Circles\Service\MembersService; use OCA\Circles\Service\MiscService; class UserEvents { + /** @var CirclesService */ + private $circlesService; + /** @var MembersService */ private $membersService; @@ -19,9 +23,19 @@ class UserEvents { /** @var MiscService */ private $miscService; + /** + * UserEvents constructor. + * + * @param CirclesService $circlesService + * @param MembersService $membersService + * @param GroupsService $groupsService + * @param MiscService $miscService + */ public function __construct( - MembersService $membersService, GroupsService $groupsService, MiscService $miscService + CirclesService $circlesService, MembersService $membersService, GroupsService $groupsService, + MiscService $miscService ) { + $this->circlesService = $circlesService; $this->membersService = $membersService; $this->groupsService = $groupsService; $this->miscService = $miscService; @@ -33,6 +47,7 @@ class UserEvents { */ public function onUserDeleted(array $params) { $userId = $params['uid']; + $this->circlesService->onUserRemoved($userId); $this->membersService->onUserRemoved($userId); } diff --git a/lib/Exceptions/CommandMissingArgumentException.php b/lib/Exceptions/CommandMissingArgumentException.php new file mode 100644 index 00000000..5f5a6c75 --- /dev/null +++ b/lib/Exceptions/CommandMissingArgumentException.php @@ -0,0 +1,34 @@ +<?php +/** + * 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 2017 + * @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\Exceptions; + + +class CommandMissingArgumentException extends \Exception { + +} + + diff --git a/lib/Migration/SetMemberTypeToDefault.php b/lib/Migration/SetMemberTypeToDefault.php new file mode 100644 index 00000000..982b27b2 --- /dev/null +++ b/lib/Migration/SetMemberTypeToDefault.php @@ -0,0 +1,52 @@ +<?php +/** + * 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 2017 + * @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\Migration; + +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +/** + * @package OCA\Circles\Migration + */ +class SetMemberTypeToDefault implements IRepairStep { + + + public function __construct() { + } + + public function getName() { + return ''; + } + + /** + * @param IOutput $output + */ + public function run(IOutput $output) { + } + + +} diff --git a/lib/Migration/UpdateShareTimeToTimestamp.php b/lib/Migration/UpdateShareTimeToTimestamp.php index dc93f129..8156f613 100644 --- a/lib/Migration/UpdateShareTimeToTimestamp.php +++ b/lib/Migration/UpdateShareTimeToTimestamp.php @@ -86,7 +86,7 @@ class UpdateShareTimeToTimestamp implements IRepairStep { $select = $this->connection->getQueryBuilder(); $select->select('*') ->from('share') - ->where($select->expr()->eq('share_type', $select->createNamedParameter(Share::SHARE_TYPE_CIRCLE))); + ->where($select->expr()->eq('share_type', $select->createNamedParameter(7))); $update = $this->connection->getQueryBuilder(); $update->update('share') diff --git a/lib/Migration/UsingShortenUniqueIdInsteadOfCircleId.php b/lib/Migration/UsingShortenUniqueIdInsteadOfCircleId.php index 3dac45d2..fb806b98 100644 --- a/lib/Migration/UsingShortenUniqueIdInsteadOfCircleId.php +++ b/lib/Migration/UsingShortenUniqueIdInsteadOfCircleId.php @@ -27,7 +27,6 @@ namespace OCA\Circles\Migration; use OC\Share\Share; -use OCA\Circles\AppInfo\Application; use OCA\Circles\Db\CoreRequestBuilder; use OCA\Circles\Model\Circle; use OCP\IConfig; @@ -69,7 +68,7 @@ class UsingShortenUniqueIdInsteadOfCircleId implements IRepairStep { public function run(IOutput $output) { $oldVersion = explode( '.', \OC::$server->getConfig() - ->getAppValue(Application::APP_NAME, 'installed_version', '') + ->getAppValue('circles', 'installed_version', '') ); if ((int)$oldVersion[0] === 0 @@ -90,24 +89,24 @@ class UsingShortenUniqueIdInsteadOfCircleId implements IRepairStep { $cursor = $qb->execute(); while ($data = $cursor->fetch()) { $circleId = $data['id']; - $shortenUniqueId = substr($data['unique_id'], 0, Circle::SHORT_UNIQUE_ID_LENGTH); + $shortenUniqueId = substr($data['unique_id'], 0, 14); $this->swapToShortenUniqueIdInTable( - $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_GROUPS + $circleId, $shortenUniqueId, 'circles_groups' ); $this->swapToShortenUniqueIdInTable( - $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS + $circleId, $shortenUniqueId, 'circles_links' ); // $this->cleanBuggyDuplicateEntries( // $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS, 'user_id' // ); $this->swapToShortenUniqueIdInTable( - $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS + $circleId, $shortenUniqueId, 'circles_members' ); $this->swapToShortenUniqueIdInTable( - $circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS + $circleId, $shortenUniqueId, 'circles_links' ); $this->swapToShortenUniqueIdInShares($circleId, $shortenUniqueId); } @@ -138,7 +137,7 @@ class UsingShortenUniqueIdInsteadOfCircleId implements IRepairStep { ->where( $expr->andX( $expr->eq( - 'share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE) + 'share_type', $qb->createNamedParameter(7) ), $expr->eq('share_with', $qb->createNamedParameter($circleId)) ) diff --git a/lib/Model/SharingFrame.php b/lib/Model/SharingFrame.php index 33a14f79..988897e4 100644 --- a/lib/Model/SharingFrame.php +++ b/lib/Model/SharingFrame.php @@ -327,10 +327,6 @@ class SharingFrame implements \JsonSerializable { private static function getCircleFromArray($arr) { $circle = Circle::fromArray(MiscService::get($arr, 'circle', null)); - $circle->setType(MiscService::get($arr, 'circle_type')); - $circle->setName(MiscService::get($arr, 'circle_name')); - $circle->setId(MiscService::get($arr, 'circle_id')); - return $circle; } } diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index ecf0097d..29016ff3 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -30,6 +30,7 @@ namespace OCA\Circles\Service; +use Exception; use OCA\Circles\AppInfo\Application; use OCA\Circles\Db\CircleProviderRequest; use OCA\Circles\Db\CirclesRequest; @@ -121,7 +122,7 @@ class CirclesService { * @throws \Exception */ public function createCircle($type, $name) { - self::convertTypeStringToBitValue($type); + $type = $this->convertTypeStringToBitValue($type); $type = (int)$type; if ($type === '') { @@ -154,15 +155,21 @@ class CirclesService { /** * list Circles depends on type (or all) and name (parts) and minimum level. * + * @param string $userId * @param mixed $type * @param string $name * @param int $level * * @return Circle[] * @throws CircleTypeDisabledException + * @throws Exception */ - public function listCircles($type, $name = '', $level = 0) { - self::convertTypeStringToBitValue($type); + public function listCircles($userId, $type, $name = '', $level = 0) { + $type = $this->convertTypeStringToBitValue($type); + + if ($userId === '') { + throw new Exception('UserID cannot be null'); + } if (!$this->configService->isCircleAllowed((int)$type)) { throw new CircleTypeDisabledException( @@ -171,7 +178,7 @@ class CirclesService { } $data = []; - $result = $this->circlesRequest->getCircles($this->userId, $type, $name, $level); + $result = $this->circlesRequest->getCircles($userId, $type, $name, $level); foreach ($result as $item) { $data[] = $item; } @@ -383,27 +390,73 @@ class CirclesService { return $this->circlesRequest->forceGetCircleByName($circleName); } + /** - * Convert a Type in String to its Bit Value + * When a user is removed. + * Before deleting a user from the cloud, we assign a new owner to his Circles. + * Remove the Circle if it has no admin. * - * @param string $type + * @param string $userId */ - public static function convertTypeStringToBitValue(&$type) { - if (strtolower($type) === 'personal') { - $type = Circle::CIRCLES_PERSONAL; - } - if (strtolower($type) === 'secret') { - $type = Circle::CIRCLES_SECRET; - } - if (strtolower($type) === 'closed') { - $type = Circle::CIRCLES_CLOSED; + public function onUserRemoved($userId) { + $circles = $this->circlesRequest->getCircles($userId, 0, '', Member::LEVEL_OWNER); + + foreach ($circles as $circle) { + + $members = + $this->membersRequest->forceGetMembers($circle->getUniqueId(), Member::LEVEL_ADMIN); + + if (sizeof($members) === 1) { + $this->circlesRequest->destroyCircle($circle->getUniqueId()); + continue; + } + + $this->switchOlderAdminToOwner($circle, $members); } - if (strtolower($type) === 'public') { - $type = Circle::CIRCLES_PUBLIC; + } + + + /** + * switchOlderAdminToOwner(); + * + * @param Member[] $members + */ + private function switchOlderAdminToOwner($circle, $members) { + + foreach ($members as $member) { + if ($member->getLevel() === Member::LEVEL_ADMIN) { + $member->setLevel(Member::LEVEL_OWNER); + $this->membersRequest->updateMember($member); + $this->eventsService->onMemberOwner($circle, $member); + + return; + } } - if (strtolower($type) === 'all') { - $type = Circle::CIRCLES_ALL; + + } + + + /** + * Convert a Type in String to its Bit Value + * + * @param string $type + * + * @return int|mixed + */ + public function convertTypeStringToBitValue($type) { + $strings = [ + 'personal' => Circle::CIRCLES_PERSONAL, + 'secret' => Circle::CIRCLES_SECRET, + 'closed' => Circle::CIRCLES_CLOSED, + 'public' => Circle::CIRCLES_PUBLIC, + 'all' => Circle::CIRCLES_ALL + ]; + + if (!key_exists(strtolower($type), $strings)) { + return $type; } + + return $strings[strtolower($type)]; } diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 6e3f36c0..347b745e 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -47,6 +47,7 @@ class ConfigService { private $defaults = [ self::CIRCLES_ALLOW_CIRCLES => Circle::CIRCLES_ALL, + self::CIRCLES_TEST_ASYNC_INIT => '0', self::CIRCLES_SWAP_TO_TEAMS => '0', self::CIRCLES_ALLOW_LINKED_GROUPS => '0', self::CIRCLES_ALLOW_FEDERATED_CIRCLES => '0', @@ -219,10 +220,7 @@ class ConfigService { * * @return void */ - public - function setAppValue( - $key, $value - ) { + public function setAppValue($key, $value) { $this->config->setAppValue($this->appName, $key, $value); } @@ -233,10 +231,7 @@ class ConfigService { * * @return string */ - public - function deleteAppValue( - $key - ) { + public function deleteAppValue($key) { return $this->config->deleteAppValue($this->appName, $key); } @@ -247,10 +242,7 @@ class ConfigService { * * @return string */ - public - function getUserValue( - $key - ) { + public function getUserValue($key) { return $this->config->getUserValue($this->userId, $this->appName, $key); } @@ -262,10 +254,7 @@ class ConfigService { * * @return string */ - public - function setUserValue( - $key, $value - ) { + public function setUserValue($key, $value) { return $this->config->setUserValue($this->userId, $this->appName, $key, $value); } @@ -277,10 +266,7 @@ class ConfigService { * * @return string */ - public - function getValueForUser( - $userId, $key - ) { + public function getValueForUser($userId, $key) { return $this->config->getUserValue($userId, $this->appName, $key); } @@ -293,10 +279,7 @@ class ConfigService { * * @return string */ - public - function setValueForUser( - $userId, $key, $value - ) { + public function setValueForUser($userId, $key, $value) { return $this->config->setUserValue($userId, $this->appName, $key, $value); } @@ -308,10 +291,7 @@ class ConfigService { * * @return string|integer */ - public - function getCloudVersion( - $complete = false - ) { + public function getCloudVersion($complete = false) { $ver = Util::getVersion(); if ($complete) { diff --git a/lib/Service/EventsService.php b/lib/Service/EventsService.php index 001e3e5b..4e491769 100644 --- a/lib/Service/EventsService.php +++ b/lib/Service/EventsService.php @@ -115,6 +115,7 @@ class EventsService { $this->publishEvent($event, [$user]); } ); + $this->dispatch('\OCA\Circles::onCircleCreation', ['circle' => $circle]); } @@ -351,7 +352,7 @@ class EventsService { * @param Circle $circle * @param Member $member */ - private function onMemberOwner(Circle $circle, Member $member) { + public function onMemberOwner(Circle $circle, Member $member) { $event = $this->generateEvent('circles_as_moderator'); $event->setSubject( 'member_owner', @@ -728,9 +729,9 @@ class EventsService { $event->setApp(Application::APP_NAME) ->setType($type); - if ($this->userId === null) { + // if ($this->userId === null) { // $event->setAuthor($this->userId); - } + // } return $event; } @@ -756,7 +757,11 @@ class EventsService { $this->activityManager->publish($event); } } - + + /** + * @param string $context + * @param array $arguments + */ private function dispatch($context, $arguments) { $this->eventDispatcher->dispatch($context, new GenericEvent(null,$arguments)); } diff --git a/lib/Service/MembersService.php b/lib/Service/MembersService.php index cfedb2b2..4f9a10e8 100644 --- a/lib/Service/MembersService.php +++ b/lib/Service/MembersService.php @@ -506,7 +506,7 @@ class MembersService { * @param $userId */ public function onUserRemoved($userId) { - $this->membersRequest->removeAllFromUser($userId); + $this->membersRequest->removeAllMembershipsFromUser($userId); } diff --git a/lib/Service/MiscService.php b/lib/Service/MiscService.php index aba3e9d8..27765c1b 100644 --- a/lib/Service/MiscService.php +++ b/lib/Service/MiscService.php @@ -53,7 +53,7 @@ class MiscService { $this->userManager = $userManager; } - public function log($message, $level = 2) { + public function log($message, $level = 4) { $data = array( 'app' => $this->appName, 'level' => $level diff --git a/lib/Service/SharingFrameService.php b/lib/Service/SharingFrameService.php index 4aa17e7a..c633f04e 100644 --- a/lib/Service/SharingFrameService.php +++ b/lib/Service/SharingFrameService.php @@ -32,6 +32,7 @@ use OCA\Circles\Api\v1\Circles; use OCA\Circles\AppInfo\Application; use OCA\Circles\Db\CirclesRequest; use OCA\Circles\Db\FederatedLinksRequest; +use OCA\Circles\Db\SharingFrameRequest; use OCA\Circles\Exceptions\CircleDoesNotExistException; use OCA\Circles\Exceptions\MemberDoesNotExistException; use OCA\Circles\Exceptions\PayloadDeliveryException; @@ -52,6 +53,9 @@ class SharingFrameService { /** @var ConfigService */ private $configService; + /** @var SharingFrameRequest */ + private $sharingFrameRequest; + /** @var CirclesRequest */ private $circlesRequest; @@ -76,6 +80,7 @@ class SharingFrameService { * * @param string $userId * @param ConfigService $configService + * @param SharingFrameRequest $sharingFrameRequest * @param CirclesRequest $circlesRequest * @param FederatedLinksRequest $federatedLinksRequest * @param BroadcastService $broadcastService @@ -86,6 +91,7 @@ class SharingFrameService { public function __construct( $userId, ConfigService $configService, + SharingFrameRequest $sharingFrameRequest, CirclesRequest $circlesRequest, FederatedLinksRequest $federatedLinksRequest, BroadcastService $broadcastService, @@ -95,6 +101,7 @@ class SharingFrameService { ) { $this->userId = $userId; $this->configService = $configService; + $this->sharingFrameRequest = $sharingFrameRequest; $this->circlesRequest = $circlesRequest; $this->federatedLinksRequest = $federatedLinksRequest; $this->broadcastService = $broadcastService; @@ -128,7 +135,7 @@ class SharingFrameService { $frame->setCircle($circle); $this->generateHeaders($frame, $circle, $broadcast); - $this->circlesRequest->saveFrame($frame); + $this->sharingFrameRequest->saveSharingFrame($frame); $this->initiateShare($circle->getUniqueId(), $frame->getUniqueId()); } catch (Exception $e) { @@ -162,6 +169,42 @@ class SharingFrameService { } } + + /** + * return all SharingFrame from a circle regarding a userId. + * + * @param string $circleUniqueId + * + * @return SharingFrame[] + */ + public function getFrameFromCircle($circleUniqueId) { + return $this->forceGetFrameFromCircle($circleUniqueId, $this->userId); + } + + + /** + * return all SharingFrame from a circle. + * + * Warning, result won't be filtered regarding current user session. + * Please use getFrameFromCircle(); + * + * @param string $circleUniqueId + * @param $viewerId + * + * @return SharingFrame[] + */ + public function forceGetFrameFromCircle($circleUniqueId, $viewerId) { + + if ($viewerId !== '') { + $circle = $this->circlesRequest->getCircle($circleUniqueId, $viewerId); + $circle->getViewer() + ->hasToBeMember(); + } + + return $this->sharingFrameRequest->getSharingFramesFromCircle($circleUniqueId); + } + + /** * @param string $circleUniqueId * @param string $frameUniqueId @@ -176,7 +219,7 @@ class SharingFrameService { } try { - $frame = $this->circlesRequest->getFrame($circleUniqueId, $frameUniqueId); + $frame = $this->sharingFrameRequest->getSharingFrame($circleUniqueId, $frameUniqueId); if ($frame->getCloudId() !== null) { throw new SharingFrameAlreadyDeliveredException('share_already_delivered'); } @@ -207,13 +250,13 @@ class SharingFrameService { } try { - $this->circlesRequest->getFrame($link->getCircleId(), $frame->getUniqueId()); + $this->sharingFrameRequest->getSharingFrame($link->getCircleId(), $frame->getUniqueId()); throw new SharingFrameAlreadyExistException('shares_is_already_known'); } catch (SharingFrameDoesNotExistException $e) { } $frame->setCircle($circle); - $this->circlesRequest->saveFrame($frame); + $this->sharingFrameRequest->saveSharingFrame($frame); return true; } @@ -235,11 +278,13 @@ class SharingFrameService { $client = $this->clientService->newClient(); try { $client->post( - $this->generatePayloadDeliveryURL($this->configService->getLocalAddress()), [ - 'body' => $args, - 'timeout' => Application::CLIENT_TIMEOUT, - 'connect_timeout' => Application::CLIENT_TIMEOUT, - ] + $this->generatePayloadDeliveryURL( + $this->configService->getLocalAddress() . \OC::$WEBROOT + ), [ + 'body' => $args, + 'timeout' => Application::CLIENT_TIMEOUT, + 'connect_timeout' => Application::CLIENT_TIMEOUT, + ] ); return true; @@ -340,7 +385,7 @@ class SharingFrameService { */ public function updateFrameWithCloudId(SharingFrame $frame) { $frame->setCloudId($this->configService->getLocalAddress()); - $this->circlesRequest->updateFrame($frame); + $this->sharingFrameRequest->updateSharingFrame($frame); } diff --git a/lib/ShareByCircleProvider.php b/lib/ShareByCircleProvider.php index 4a4e710b..b2025502 100644 --- a/lib/ShareByCircleProvider.php +++ b/lib/ShareByCircleProvider.php @@ -657,7 +657,7 @@ class ShareByCircleProvider extends CircleProviderRequest implements IShareProvi $message = 'Sharing %s failed, this item is already shared with this circle'; $message_t = $this->l10n->t($message, array($share_src)); $this->logger->debug( - sprintf($message, $share_src, $share->getSharedWith()), ['app' => Application::APP_NAME] + sprintf($message, $share_src, $share->getSharedWith()), ['app' => 'circles'] ); return new \Exception($message_t); |