%PDF- %PDF-
Direktori : /www/varak.net/nextcloud.varak.net/apps_old/apps/circles/lib/Service/ |
Current File : //www/varak.net/nextcloud.varak.net/apps_old/apps/circles/lib/Service/ActivityService.php |
<?php declare(strict_types=1); /** * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Circles\Service; use OCA\Circles\AppInfo\Application; use OCA\Circles\Db\MemberRequest; use OCA\Circles\Events\CircleGenericEvent; use OCA\Circles\IFederatedUser; use OCA\Circles\Model\Circle; use OCA\Circles\Model\Federated\FederatedEvent; use OCA\Circles\Model\Member; use OCP\Activity\IEvent; use OCP\Activity\IManager as IActivityManager; use OCP\IUser; use OCP\IUserManager; use UnhandledMatchError; class ActivityService { public function __construct( private IActivityManager $activityManager, private IUserManager $userManager, private MemberRequest $memberRequest, private ConfigService $configService ) { } /** * @param Circle $circle */ public function onCircleCreation(Circle $circle): void { if ($circle->isConfig(Circle::CFG_PERSONAL) || !$this->configService->getAppValueBool(ConfigService::ACTIVITY_ON_NEW_CIRCLE)) { return; } $event = $this->generateEvent('circles_as_non_member'); $event->setSubject('circle_create', ['circle' => json_encode($circle)]); $this->userManager->callForSeenUsers( function ($user) use ($event) { /** @var IUser $user */ $this->publishEvent($event, [$user]); } ); } /** * @param Circle $circle */ public function onCircleDestruction(Circle $circle): void { if ($circle->isConfig(Circle::CFG_PERSONAL)) { return; } $event = $this->generateEvent('circles_as_member'); $event->setSubject('circle_delete', ['circle' => json_encode($circle)]); $this->publishEvent( $event, $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MEMBER) ); } /** * @param Circle $circle * @param Member $member * @param int $eventType */ public function onMemberNew( Circle $circle, Member $member, int $eventType ): void { if ($circle->isConfig(Circle::CFG_PERSONAL)) { return; } if ($member->getLevel() === Member::LEVEL_NONE) { $this->onMemberAlmost($circle, $member, $eventType); return; } switch ($member->getUserType()) { case Member::TYPE_USER: case Member::TYPE_MAIL: case Member::TYPE_CONTACT: $this->onMemberNewAccount($circle, $member, $eventType); break; case Member::TYPE_CIRCLE: $this->onMemberNewCircle( $circle, $member, $eventType ); break; } } /** * @param Circle $circle * @param Member $member * @param int $eventType */ private function onMemberNewAccount( Circle $circle, Member $member, int $eventType ): void { $event = $this->generateEvent('circles_as_member'); try { $event->setSubject( match ($eventType) { CircleGenericEvent::ADDED => 'member_added', CircleGenericEvent::JOINED => 'member_join' }, [ 'circle' => json_encode($circle), 'member' => json_encode($member) ] ); } catch (UnhandledMatchError $e) { return; } $this->publishEvent( $event, array_merge( [$member], $this->memberRequest->getInheritedMembers( $circle->getSingleId(), false, Member::LEVEL_MODERATOR ) ) ); } /** * @param Circle $circle * @param Member $member * @param int $eventType */ private function onMemberNewCircle( Circle $circle, Member $member, int $eventType = CircleGenericEvent::JOINED ): void { $event = $this->generateEvent('circles_as_member'); try { $event->setSubject( match ($eventType) { CircleGenericEvent::ADDED => 'member_circle_added', CircleGenericEvent::JOINED => 'member_circle_joined' }, [ 'circle' => json_encode($circle), 'member' => json_encode($member) ] ); } catch (UnhandledMatchError $e) { return; } $this->publishEvent( $event, array_merge( $this->memberRequest->getInheritedMembers($member->getSingleId(), false, Member::LEVEL_MEMBER), $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MODERATOR) ) ); } /** * @param Circle $circle * @param Member $member * @param int $eventType */ private function onMemberAlmost( Circle $circle, Member $member, int $eventType ): void { if ($member->getUserType() !== Member::TYPE_USER) { return; // only if almost-member is a local account } $event = $this->generateEvent('circles_as_moderator'); try { $event->setSubject( match ($eventType) { CircleGenericEvent::INVITED => 'member_invited', CircleGenericEvent::REQUESTED => 'member_request_invitation' }, [ 'circle' => json_encode($circle), 'member' => json_encode($member) ] ); } catch (UnhandledMatchError $e) { return; } $this->publishEvent( $event, array_merge( [$member], $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MODERATOR) ) ); } /** * @param Circle $circle * @param Member $member * @param int $eventType */ public function onMemberRemove(Circle $circle, Member $member, int $eventType): void { if ($circle->isConfig(Circle::CFG_PERSONAL)) { return; } switch ($member->getUserType()) { case Member::TYPE_USER: case Member::TYPE_MAIL: case Member::TYPE_CONTACT: $this->onMemberRemoveAccount($circle, $member, $eventType); break; case Member::TYPE_CIRCLE: $this->onMemberRemoveCircle( $circle, $member, $eventType ); break; } } private function onMemberRemoveAccount( Circle $circle, Member $member, int $eventType ): void { $event = $this->generateEvent('circles_as_member'); try { $event->setSubject( match ($eventType) { CircleGenericEvent::LEFT => 'member_left', CircleGenericEvent::REMOVED => 'member_remove' }, [ 'circle' => json_encode($circle), 'member' => json_encode($member) ] ); } catch (UnhandledMatchError $e) { return; } $this->publishEvent( $event, array_merge( [$member], $this->memberRequest->getInheritedMembers( $circle->getSingleId(), false, Member::LEVEL_MODERATOR ) ) ); } private function onMemberRemoveCircle( Circle $circle, Member $member, int $eventType = CircleGenericEvent::JOINED ): void { $event = $this->generateEvent('circles_as_member'); try { $event->setSubject( match ($eventType) { CircleGenericEvent::LEFT => 'member_circle_left', CircleGenericEvent::REMOVED => 'member_circle_removed' }, [ 'circle' => json_encode($circle), 'member' => json_encode($member) ] ); } catch (UnhandledMatchError $e) { return; } $this->publishEvent( $event, array_merge( $this->memberRequest->getInheritedMembers($member->getSingleId(), false, Member::LEVEL_MEMBER), $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MODERATOR) ) ); } /** * @param Circle $circle * @param Member $member * @param int $level */ public function onMemberLevel( Circle $circle, Member $member, int $level ): void { if ($member->getLevel() === Member::LEVEL_OWNER) { $this->onMemberOwner($circle, $member); return; } $event = $this->generateEvent('circles_as_moderator'); $event->setSubject( 'member_level', ['circle' => json_encode($circle), 'member' => json_encode($member), 'level' => $level] ); $this->publishEvent( $event, array_merge( [$member], $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MODERATOR)) ); } /** * @param Circle $circle * @param Member $member */ public function onMemberOwner(Circle $circle, Member $member): void { $event = $this->generateEvent('circles_as_moderator'); $event->setSubject( 'member_owner', ['circle' => json_encode($circle), 'member' => json_encode($member)] ); $this->publishEvent( $event, $this->memberRequest->getInheritedMembers($circle->getSingleId(), false, Member::LEVEL_MEMBER) ); } public function onShareNew(Circle $getCircle, FederatedEvent $federatedEvent): void { } /** * generateEvent() * Create an Activity Event with the basic settings for the app. * * @param string $type * * @return IEvent */ private function generateEvent(string $type): IEvent { $event = $this->activityManager->generateEvent(); $event->setApp(Application::APP_ID) ->setType($type); return $event; } /** * Publish the event to the users. * - if user is IUser, we get userId, * - if user is Member, we ignore non-local account and returns local userId, * - others models are ignored * - avoid duplicate activity in case of inheritance as an account can be inherited memberships throw different path * * @param IEvent $event * @param array<IUser|IFederatedUser> $users */ private function publishEvent(IEvent $event, array $users): void { $knownSingleIds = []; foreach ($users as $user) { if ($user instanceof IUser) { $userId = $user->getUID(); } elseif ($user instanceof IFederatedUser) { $singleId = $user->getSingleId(); if ($user->getUserType() !== Member::TYPE_USER || in_array($singleId, $knownSingleIds)) { continue; // we ignore non-local account and already known single ids } $knownSingleIds[] = $singleId; $userId = $user->getUserId(); } else { continue; } $event->setAffectedUser($userId); $this->activityManager->publish($event); } } }