diff options
author | Joas Schilling <coding@schilljs.com> | 2021-06-02 10:21:32 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2021-08-24 17:55:33 +0300 |
commit | af402b95c85c762a92e2ea1e5f7630a6f0729fc0 (patch) | |
tree | 06013156366731dd8d0ceb403f48a9be50c28e32 /lib | |
parent | 7accfeef9853fff1f73d69df1925bf111278d69f (diff) |
Handle the AddingCircleMemberEvent and add new members to the rooms
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AppInfo/Application.php | 7 | ||||
-rw-r--r-- | lib/Listener/CircleMembershipListener.php | 144 |
2 files changed, 151 insertions, 0 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index e062e11b2..43fb3fbef 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -23,8 +23,13 @@ declare(strict_types=1); namespace OCA\Talk\AppInfo; +use OCA\Circles\Events\AddingCircleMemberEvent; use OCA\Circles\Events\CircleDestroyedEvent; use OCA\Circles\Events\CircleMemberAddedEvent; +use OCA\Circles\Events\CircleMemberRemovedEvent; +use OCA\Circles\Events\MembershipsCreatedEvent; +use OCA\Circles\Events\MembershipsRemovedEvent; +use OCA\Circles\Events\RemovingCircleMemberEvent; use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; use OCA\Talk\Activity\Listener as ActivityListener; use OCA\Talk\Capabilities; @@ -120,6 +125,8 @@ class Application extends App implements IBootstrap { $context->registerEventListener(AttendeesRemovedEvent::class, SystemMessageListener::class); $context->registerEventListener(CircleDestroyedEvent::class, CircleDeletedListener::class); + $context->registerEventListener(AddingCircleMemberEvent::class, CircleMembershipListener::class); + $context->registerEventListener(RemovingCircleMemberEvent::class, CircleMembershipListener::class); $context->registerSearchProvider(ConversationSearch::class); $context->registerSearchProvider(CurrentMessageSearch::class); diff --git a/lib/Listener/CircleMembershipListener.php b/lib/Listener/CircleMembershipListener.php new file mode 100644 index 000000000..71a96bae4 --- /dev/null +++ b/lib/Listener/CircleMembershipListener.php @@ -0,0 +1,144 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> + * + * @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\Talk\Listener; + +use OCA\Circles\Events\AddingCircleMemberEvent; +use OCA\Circles\Events\CircleGenericEvent; +use OCA\Circles\Events\CircleMemberAddedEvent; +use OCA\Circles\Events\CircleMemberRemovedEvent; +use OCA\Circles\Events\MembershipsCreatedEvent; +use OCA\Circles\Events\MembershipsRemovedEvent; +use OCA\Circles\Events\RemovingCircleMemberEvent; +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\Member; +use OCA\Talk\Exceptions\ParticipantNotFoundException; +use OCA\Talk\Manager; +use OCA\Talk\Model\Attendee; +use OCA\Talk\Participant; +use OCA\Talk\Service\ParticipantService; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserManager; + +class CircleMembershipListener implements IEventListener { + + /** @var IUserManager */ + private $userManager; + /** @var IGroupManager */ + private $groupManager; + /** @var Manager */ + private $manager; + /** @var ParticipantService */ + private $participantService; + + public function __construct(IUserManager $userManager, + IGroupManager $groupManager, + Manager $manager, + ParticipantService $participantService) { + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->manager = $manager; + $this->participantService = $participantService; + } + + public function handle(Event $event): void { + if ($event instanceof AddingCircleMemberEvent) { + $this->addingCircleMemberEvent($event); + } + + if ($event instanceof RemovingCircleMemberEvent) { + $this->removeFormerMemberFromRooms($event->getCircle(), $event->getMember()); + } + } + + protected function addingCircleMemberEvent(AddingCircleMemberEvent $event): void { + $roomsForTargetCircle = $this->manager->getRoomsForActor(Attendee::ACTOR_CIRCLES, $event->getCircle()->getSingleId()); + + if (empty($roomsForTargetCircle)) { + // The circle is not in any room => bye! + return; + } + + // These members are "memberships" in circles which link to entities such as users, groups or circles + if ($event->getType() === CircleGenericEvent::MULTIPLE) { + $newMembers = $event->getMembers(); + } else { + $newMembers = [$event->getMember()]; + } + + foreach ($newMembers as $newMember) { + // Get the base circle of the membership + $basedOnCircle = $newMember->getBasedOn(); + // Get all (nested) memberships in the added $newMember as a flat list + $userMembers = $basedOnCircle->getInheritedMembers(); + + foreach ($userMembers as $userMember) { + $this->addNewMemberToRooms($roomsForTargetCircle, $userMember); + } + } + } + + protected function addNewMemberToRooms(array $rooms, Member $member): void { + if ($member->getUserType() !== Member::TYPE_USER || $member->getUserId() === '') { + // Not a user? + return; + } + + $user = $this->userManager->get($member->getUserId()); + if (!$user instanceof IUser) { + return; + } + + foreach ($rooms as $room) { + try { + $participant = $room->getParticipant($member->getUserId()); + if ($participant->getAttendee()->getParticipantType() === Participant::USER_SELF_JOINED) { + $this->participantService->updateParticipantType($room, $participant, Participant::USER); + } + } catch (ParticipantNotFoundException $e) { + $this->participantService->addUsers($room, [[ + 'actorType' => Attendee::ACTOR_USERS, + 'actorId' => $member->getUserId(), + 'displayName' => $user->getDisplayName(), + ]]); + } + } + } + + protected function removeFormerMemberFromRooms(Circle $circle, Member $member): void { + if ($member->getUserType() !== Member::TYPE_USER || $member->getUserId() === '') { + // Not a user? + return; + } + + $rooms = $this->manager->getRoomsForActor(Attendee::ACTOR_CIRCLES, $circle->getSingleId()); + if (empty($rooms)) { + return; + } + + // FIXME we now need to check user groups and circles? + } +} |