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 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslationNotificationsEmailJob
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 7
182
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
 run
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
6
 addressFromUser
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 buildAddress
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getMailAddress
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 validateParams
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 validateEmail
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\TranslationNotifications\Jobs;
5
6use InvalidArgumentException;
7use MailAddress;
8use MediaWiki\Context\RequestContext;
9use MediaWiki\MediaWikiServices;
10use MediaWiki\Title\Title;
11use MediaWiki\User\User;
12use UserMailer;
13
14/**
15 * Uses UserMailer to send out emails.
16 *
17 * @ingroup JobQueue
18 * @license GPL-2.0-or-later
19 */
20class TranslationNotificationsEmailJob extends GenericTranslationNotificationsJob {
21    public function __construct( Title $title, array $params ) {
22        parent::__construct( 'TranslationNotificationsEmailJob', $title, $params );
23        $this->validateParams( $params );
24    }
25
26    /** Execute the job */
27    public function run(): bool {
28        $this->logDebug( 'Starting execution...' );
29        $to = $this->getMailAddress( $this->params['to'] );
30        $from = $this->getMailAddress( $this->params['from'] );
31        $replyTo = $this->getMailAddress( $this->params['replyTo'] );
32        $subject = $this->params['subject'];
33
34        $status = UserMailer::send(
35            $to,
36            $from,
37            $subject,
38            $this->params['body'] ?? '',
39            [ 'replyTo' => $replyTo ]
40        );
41
42        if ( !$status->isOK() ) {
43            $formatterFactory = MediaWikiServices::getInstance()->getFormatterFactory();
44            $errorMsg = $formatterFactory
45                ->getStatusFormatter( RequestContext::getMain() )
46                ->getMessage( $status )
47                ->text();
48            $this->logError( $errorMsg );
49            $this->setLastError( $errorMsg );
50            return false;
51        }
52
53        $this->logInfo( 'Sent email to user regarding: ' . $subject );
54        return true;
55    }
56
57    public static function addressFromUser( User $user ): array {
58        return [
59            'email' => $user->getEmail(),
60            'name' => $user->getName(),
61            'fullName' => $user->getRealName()
62        ];
63    }
64
65    public static function buildAddress( string $email, string $name, ?string $fullName ): array {
66        return [
67            'email' => $email,
68            'name' => $name,
69            'fullName' => $fullName ?? ''
70        ];
71    }
72
73    private function getMailAddress( array $address ): MailAddress {
74        return new MailAddress(
75            $address['email'],
76            $address['name'],
77            $address['fullName']
78        );
79    }
80
81    private function validateParams( array $params ): void {
82        $from = $params[ 'from' ] ?? [];
83        $to = $params[ 'to' ] ?? [];
84        $replyTo = $params['replyTo'] ?? [];
85        $subject = $params['subject'] ?? false;
86
87        $this->validateEmail( $from, 'from' );
88        $this->validateEmail( $to, 'to' );
89        $this->validateEmail( $replyTo, 'replyTo' );
90
91        if ( !is_string( $subject ) || strlen( $subject ) === 0 ) {
92            throw new InvalidArgumentException( 'Parameter "subject" must be a non-empty string.' );
93        }
94    }
95
96    private function validateEmail( array $address, string $propName ): void {
97        $requiredProps = [ 'email', 'name' ];
98        foreach ( $requiredProps as $prop ) {
99            $propVal = $address[ $prop ] ?? false;
100            if ( !is_string( $propVal ) || strlen( $propVal ) === 0 ) {
101                throw new InvalidArgumentException(
102                    "Parameter: $propName must contain " . implode( ', ', $requiredProps )
103                );
104            }
105        }
106    }
107}