Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
MessageGroupSubscriptionHookHandler
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 4
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 registerHooks
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 onBeforeCreateEchoEvent
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
20
 onEchoGetBundleRules
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
6use MediaWiki\Extension\Notifications\AttributeManager;
7use MediaWiki\Extension\Notifications\Hooks\BeforeCreateEchoEventHook;
8use MediaWiki\Extension\Notifications\Hooks\EchoGetBundleRulesHook;
9use MediaWiki\Extension\Notifications\Model\Event;
10use MediaWiki\Extension\Translate\Services;
11use MediaWiki\User\UserFactory;
12
13/**
14 * Hook handler to handle user subscriptions to message groups
15 * @since 2024.04
16 * @license GPL-2.0-or-later
17 * @author Abijeet Patro
18 */
19class MessageGroupSubscriptionHookHandler implements BeforeCreateEchoEventHook, EchoGetBundleRulesHook {
20    private MessageGroupSubscription $messageGroupSubscription;
21    private UserFactory $userFactory;
22    private const SUPPORTED_NOTIFICATION_TYPES = [ 'translate-mgs-message-added' ];
23
24    public function __construct(
25        MessageGroupSubscription $messageGroupSubscription,
26        UserFactory $userFactory
27    ) {
28        $this->messageGroupSubscription = $messageGroupSubscription;
29        $this->userFactory = $userFactory;
30    }
31
32    public static function registerHooks( array &$hooks ): void {
33        $hooks['BeforeCreateEchoEvent'][] = static function (
34            array &$notifications,
35            array &$notificationCategories,
36            array &$notificationIcons
37        ) {
38            Services::getInstance()->getMessageGroupSubscriptionHookHandler()->onBeforeCreateEchoEvent(
39                $notifications,
40                $notificationCategories,
41                $notificationIcons
42            );
43        };
44
45        $hooks['EchoGetBundleRules'][] = static function ( Event $event, string &$bundleKey ) {
46            Services::getInstance()->getMessageGroupSubscriptionHookHandler()->onEchoGetBundleRules(
47                $event,
48                $bundleKey
49            );
50        };
51    }
52
53    public function onBeforeCreateEchoEvent(
54        array &$notifications,
55        array &$notificationCategories,
56        array &$notificationIcons
57    ) {
58        $messageGroupSubscription = $this->messageGroupSubscription;
59        $userFactory = $this->userFactory;
60        $notificationCategories[ 'translate-message-group-subscription' ] = [
61            'tooltip' => 'echo-pref-tooltip-translate-message-group-subscription'
62        ];
63
64        $notifications[ 'translate-mgs-message-added' ] = [
65            'category' => 'translate-message-group-subscription',
66            'group' => 'neutral',
67            'section' => 'message',
68            'presentation-model' => MessageGroupSubscriptionPresentationModel::class,
69            'bundle' => [
70                'web' => true,
71                'expandable' => true,
72            ],
73            AttributeManager::ATTR_LOCATORS => static function ( Event $event ) use (
74                $messageGroupSubscription,
75                $userFactory
76            ) {
77                $extra = $event->getExtra();
78                $sourceGroupIds = $extra['sourceGroupIds'] ?? [];
79
80                $commonUserIds = [];
81                if ( $sourceGroupIds ) {
82                    // Find the list of users who will receive more specific notification about updates
83                    // and remove them from this group notification.
84                    // If an aggregate group has *two* source message group, remove users who
85                    // have to be subscribed to both those two source message groups.
86                    $commonUserIds = $messageGroupSubscription->getGroupSubscriberUnion( $sourceGroupIds );
87                }
88
89                $iterator = $messageGroupSubscription->getGroupSubscribers( $extra['groupId'] );
90                $usersToNotify = [];
91                foreach ( $iterator as $userIdentityValue ) {
92                    if ( in_array( $userIdentityValue->getId(), $commonUserIds ) ) {
93                        continue;
94                    }
95                    $usersToNotify[] = $userFactory->newFromUserIdentity( $userIdentityValue );
96                }
97
98                return $usersToNotify;
99            }
100        ];
101
102        $notificationIcons[ 'translate-mgs-icon' ] = [
103            'path' => 'Translate/resources/images/bell.svg'
104        ];
105    }
106
107    /** Notifications for subscriptions are bundled by message group */
108    public function onEchoGetBundleRules( Event $event, string &$bundleKey ) {
109        if ( in_array( $event->getType(), self::SUPPORTED_NOTIFICATION_TYPES ) ) {
110            $bundleKey = $event->getExtraParam( 'groupId' );
111        }
112    }
113}