Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Hooks
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 5
156
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
 onUserMailerChangeReturnPath
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
12
 generateVerp
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 onBeforeCreateEchoEvent
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 onEchoGetDefaultNotifiedUsers
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2namespace MediaWiki\Extension\BounceHandler;
3
4use InvalidArgumentException;
5use MailAddress;
6use MediaWiki\Config\Config;
7use MediaWiki\Extension\Notifications\Model\Event;
8use MediaWiki\Hook\UserMailerChangeReturnPathHook;
9use MediaWiki\MainConfigNames;
10use MediaWiki\User\User;
11use MediaWiki\User\UserFactory;
12
13/**
14 * Hooks used by BounceHandler
15 *
16 * @file
17 * @ingroup Hooks
18 * @author Tony Thomas, Kunal Mehta, Jeff Green
19 * @license GPL-2.0-or-later
20 */
21class Hooks implements UserMailerChangeReturnPathHook {
22    private Config $config;
23    private UserFactory $userFactory;
24
25    public function __construct(
26        Config $config,
27        UserFactory $userFactory
28    ) {
29        $this->config = $config;
30        $this->userFactory = $userFactory;
31    }
32
33    /**
34     * This function generates the VERP address on UserMailer::send()
35     * Generating VERP address for a batch of send emails is complex. This feature is hence disabled
36     *
37     * @param MailAddress[] $recip Recipient's email array
38     * @param string &$returnPath return-path address
39     * @throws InvalidArgumentException
40     */
41    public function onUserMailerChangeReturnPath( $recip, &$returnPath ) {
42        if ( $this->config->get( 'GenerateVERP' ) && count( $recip ) === 1 ) {
43            $this->generateVerp( $recip[0], $returnPath );
44        }
45    }
46
47    /**
48     * Process a given $to address and return its VERP return path
49     *
50     * @param MailAddress $to
51     * @param string &$returnPath return-path address
52     * @return bool true
53     */
54    protected function generateVerp( MailAddress $to, &$returnPath ) {
55        $user = $this->userFactory->newFromName( $to->name );
56        if ( !$user ) {
57            return true;
58        }
59        $email = $to->address;
60        if ( $user->getEmail() === $email && $user->isEmailConfirmed() ) {
61            $uid = $user->getId();
62        } else {
63            return true;
64        }
65        $domainPart = $this->config->get( 'VERPdomainPart' ) ??
66            $this->config->get( MainConfigNames::ServerName );
67        $verpAddress = new VerpAddressGenerator(
68            $this->config->get( 'VERPprefix' ),
69            $this->config->get( 'VERPalgorithm' ),
70            $this->config->get( 'VERPsecret' ),
71            $domainPart
72        );
73        $returnPath = $verpAddress->generateVERP( $uid );
74
75        return true;
76    }
77
78    /**
79     * Add BounceHandler events to Echo
80     *
81     * @param array &$notifications Echo notifications
82     * @return bool
83     */
84    public static function onBeforeCreateEchoEvent( array &$notifications ) {
85        $notifications['unsubscribe-bouncehandler'] = [
86            'presentation-model' => EchoBounceHandlerPresentationModel::class,
87            'primary-link' => [
88                'message' => 'notification-link-text-change-email',
89                'destination' => 'change-email'
90            ],
91            // We cannot have additional Echo emails being sent after a user is un-subscribed
92            'category' => 'system-noemail',
93            'section' => 'alert',
94
95            'title-message' => 'notification-bouncehandler',
96            'title-params' => [ 'user' ],
97            'flyout-message' => 'notification-bouncehandler-flyout',
98            'flyout-params' => [ 'failed-email', 'user' ],
99        ];
100
101        return true;
102    }
103
104    /**
105     * Add user to be notified on echo event
106     *
107     * @param Event $event
108     * @param User[] &$users
109     * @return bool
110     */
111    public static function onEchoGetDefaultNotifiedUsers( Event $event, array &$users ) {
112        if ( $event->getExtraParam( 'failed-user-id' ) === null ) {
113            return true;
114        }
115        $extra = $event->getExtra();
116        $eventType = $event->getType();
117        if ( $eventType === 'unsubscribe-bouncehandler' ) {
118            $recipientId = $extra['failed-user-id'];
119            $recipient = User::newFromId( $recipientId );
120            $users[$recipientId] = $recipient;
121        }
122
123        return true;
124    }
125
126}