Send_Email::sendQCDesicionEmail()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
nc 1
nop 8
dl 0
loc 11
c 0
b 0
f 0
cc 1
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 Copyright (C) 2018-2020 KANOUN Salim
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the Affero GNU General Public v.3 License as published by
6
 the Free Software Foundation;
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
 Affero GNU General Public Public for more details.
11
 You should have received a copy of the Affero GNU General Public Public along
12
 with this program; if not, write to the Free Software Foundation, Inc.,
13
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
/**
17
 * Email sending services for user's email notifications
18
 */
19
20
use PHPMailer\PHPMailer\PHPMailer;
0 ignored issues
show
Bug introduced by
The type PHPMailer\PHPMailer\PHPMailer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
Class Send_Email {
23
    
24
	private $message;
25
	private $linkpdo;
26
	private $smtp_config;
27
	public $platformName;
28
	public $adminEmail;
29
	public $corporation;
30
	public $webAddress;
31
	public $emailsDestinators;
32
	public $subject;
33
34
	public $replyTo;
35
    
36
	public function __construct(PDO $linkpdo) {
37
		$this->linkpdo=$linkpdo;
38
       
39
		$this->smtp_config=array(
40
			'useSMTP'=> GAELO_USE_SMTP,
41
			'host'=> GAELO_SMTP_HOST,
42
			'port'=> GAELO_SMTP_PORT,
43
			'user'=> GAELO_SMTP_USER,
44
			'password' => GAELO_SMTP_PASSWORD,
45
			'SMTPSecure' => GAELO_SMTP_SECURE
46
		);
47
        
48
		$this->platformName=GAELO_PLATEFORM_NAME;
49
		$this->adminEmail=GAELO_ADMIN_EMAIL;
50
		$this->corporation=GAELO_CORPORATION;
51
		$this->webAddress=GAELO_WEB_ADDRESS;
52
		$this->replyTo=GAELO_REPLY_TO;
53
		$this->emailsDestinators=[];
54
		$this->subject='GaelO Notification';
55
	}
56
57
	/**
58
	 * Set the message to send (will be included in the HTML template)
59
	 */
60
	public function setMessage(string $message) {
61
		$this->message=$message;
62
	}
63
64
	public function setSubject(String $subject) {
65
		$this->subject=$subject;
66
	}
67
68
	/**
69
	 * Send email prepared in this class
70
	 * Sender is the the admin email in the preferece database
71
	 * @param array $emails
72
	 * @param string $subject
73
	 * @param string $replyTo , optional, to allow a direct response to the user sending email
74
	 * @return string
75
	 */
76
	public function sendEmail() {
77
78
		$mail=new PHPMailer(true); // Passing `true` enables exceptions
79
		$mail->CharSet='UTF-8';
80
81
		//Recipients
82
		if ($this->smtp_config['useSMTP']) {
83
			$mail->IsSMTP(); // Set mailer to use SMTP
84
			$mail->Host=$this->smtp_config['host']; // Specify main and backup server
85
			$mail->Port=$this->smtp_config['port']; // Set the SMTP port
86
			$mail->SMTPAuth=true; // Enable SMTP authentication
87
			$mail->Username=$this->smtp_config['user']; // SMTP username
88
			$mail->Password=$this->smtp_config['password']; // SMTP password
89
			$mail->SMTPSecure=$this->smtp_config['SMTPSecure'];
90
		}else {
91
			//Add DKIM private key if exist
92
			if (file_exists($_SERVER['DOCUMENT_ROOT'].'/data/_config/dkim.private')) {
93
				$mail->DKIM_domain=GAELO_WEB_ADDRESS;
94
				$mail->DKIM_private=$_SERVER['DOCUMENT_ROOT'].'/data/_config/dkim.private';
95
				$mail->DKIM_selector='mail';
96
				$mail->DKIM_passphrase='';
97
				$mail->DKIM_identity=$mail->From;
98
			}
99
		}
100
101
		//Add Sender Name
102
		$mail->setFrom($this->adminEmail, $this->corporation, true);
103
        
104
		//Add Reply To
105
		try {
106
			$mail->addReplyTo($this->replyTo); 
107
		}catch (Exception $e) {
108
			error_log("Reply to email problem".$e->getMessage());
109
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
110
		}
111
        
112
		//Add destinators
113
		if (sizeof($this->emailsDestinators) > 1) {
114
			foreach ($this->emailsDestinators as $value) {
115
				try {
116
					$mail->addBCC($value);
117
				}catch (Exception $e) {
118
					error_log('error adding email'.$e->getMessage());
119
				}
120
			 }
121
			//Add message to mail object
122
			$this->buildMessage($mail); 
123
		}else if (sizeof($this->emailsDestinators) == 1) {
124
			//If only one add regular adress
125
			try {
126
				$mail->addAddress($this->emailsDestinators[0]);
127
				$userObject=User::getUserByEmail($this->emailsDestinators[0], $this->linkpdo);
128
				$this->buildMessage($mail, $userObject->lastName, $userObject->firstName);
129
			}catch (Exception $e) {
130
				error_log('error adding email'.$e->getMessage());
131
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
132
			}
133
134
           
135
		}
136
137
		//Content
138
		$mail->isHTML(true); // Set email format to HTML
139
		$mail->Subject=$this->corporation.' Imaging Platform -'.$this->subject;
140
		try {
141
			$answer=$mail->send();
142
			return $answer;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $answer returns the type boolean which is incompatible with the documented return type string.
Loading history...
143
		}catch (Exception $e) {
144
			error_log("Message could not be sent. Mailer Error: {$mail->ErrorInfo}");
145
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
146
		}
147
        
148
        
149
	}
150
    
151
	private function buildMessage(PHPMailer $mail, $lastName=null, $firstName=null) {
152
        
153
		if ($lastName == null && $firstName == null) {
154
			$nameString="user";
155
		}else {
156
			$nameString=$firstName.' '.$lastName;
157
		}
158
                    
159
		$messageToSend=
160
		'<!doctype html> <html lang="en">
161
            <head>
162
                <meta charset="utf-8">
163
                <title> '.$this->platformName.'</title>
164
                <style>
165
                    h1   {color: brown ; text-align: center}
166
                    a:link { color: brown; }
167
                    header { text-align: center;}
168
                    #footer-link {
169
                        width: 100%;
170
                        background-color: beige;
171
                        color: black;
172
                        text-align: center;
173
                    }
174
                    
175
                    #automatic {
176
                        font-style: italic;
177
                    }
178
179
                    #logo-gaelo {
180
                        max-height: 180px;
181
                        width: auto;
182
                    }
183
                    
184
                    #footer-contact{ color: black ; background: white ; text-align: left}
185
                    
186
                    #message { text-align: left; }
187
                </style>       
188
            </head>
189
            <body>
190
                <header class="main-header" id ="header">
191
                    <img id="logo-gaelo" src=cid:logo_gaelo alt="Banner Image"/>
192
                </header>
193
                <h1><a href="http://'.$this->webAddress.'">'.$this->platformName.'</a></h1>
194
                <div id="message"><b>Dear '.$nameString.',</b><br>'.$this->message.'</div>
195
                <div class="footer">
196
                    <p id ="footer-contact">Please contact the Imaging Department of '.$this->corporation.' for any questions (<a HREF="mailto:'.$this->adminEmail.'">'.$this->adminEmail.'</a>) <br>
197
                                Kind regards, <br>
198
                                The Imaging Department of '.$this->corporation.'. <br>
199
                    </p>
200
                    <p id="automatic">This is an automatic e-mail. Please do not reply. <br></p>
201
                    <p id="footer-link"><a href="http://'.$this->webAddress.'">'.$this->webAddress.'</a></p>
202
                </div>
203
            </body>
204
        </html>';
205
        
206
		$messageToSend=trim(preg_replace('/\t+/', '', $messageToSend));
207
		$messageToSend=str_replace(array("\r", "\n"), '', $messageToSend);
208
        
209
		//Prepare Html2PlainText for email validity (both version to enhance spam validation)
210
		$htmlMessageObject=new \Html2Text\Html2Text($messageToSend);
0 ignored issues
show
Bug introduced by
The type Html2Text\Html2Text was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
211
		$mail->Body=$messageToSend;
212
		$mail->AltBody=$htmlMessageObject->getText();
213
		$mail->AddEmbeddedImage($_SERVER['DOCUMENT_ROOT'].'/assets/images/gaelo-logo-square.png', 'logo_gaelo');
214
        
215
        
216
	}
217
    
218
	/**
219
	 * Retrieve all emails of Admins users
220
	 */
221
	public function getAdminsEmails() {
222
		$connecter=$this->linkpdo->prepare('SELECT email FROM users WHERE is_administrator=1 AND status!="Deactivated"');
223
		$connecter->execute();
224
		$adminResult=$connecter->fetchAll(PDO::FETCH_COLUMN);
225
       
226
		return $adminResult;
227
	}
228
    
229
	/**
230
	 * Get email of a given user
231
	 * @param string $username
232
	 * @return string email
233
	 */
234
	public function getUserEmails(string $username) {
235
		$userObject=new User($username, $this->linkpdo);
236
		return $userObject->userEmail;
237
	}
238
    
239
	/**
240
	 * Method to get email by role in a study
241
	 * Do not return deactivated account
242
	 * @param string $role
243
	 * @param string $study
244
	 * @return array mails
245
	 */
246
	public function getRolesEmails(string $study, string $role) {
247
		$connecter=$this->linkpdo->prepare('SELECT users.email FROM roles, users 
248
                                                     WHERE roles.study=:study 
249
                                                        AND roles.username=users.username 
250
                                                        AND roles.name=:role
251
                                                        AND users.status!="Deactivated"');
252
		$connecter->execute(array(
253
				'study'=>$study,
254
				'role'=>$role));
255
    	
256
		$results=$connecter->fetchAll(PDO::FETCH_COLUMN);
257
		return $results;
258
	}
259
260
	/**
261
	 * Return all users having a specific center in main of affiliated centers
262
	 * @param PDO $linkpdo
263
	 * @param $center
264
	 * @return User[]
265
	 */
266
	private function getUsersAffiliatedToCenter(int $center) {
267
		
268
		//Select All users that has a matching center
269
		$queryUsersEmail=$this->linkpdo->prepare('
270
								    SELECT users.username
271
									FROM users
272
									WHERE (center=:center)
273
									UNION
274
									SELECT affiliated_centers.username
275
									FROM affiliated_centers,
276
									     users
277
									WHERE (affiliated_centers.center=:center
278
									       AND affiliated_centers.username=users.username)');
279
		
280
		$queryUsersEmail->execute(array('center'=>$center));
281
		$users=$queryUsersEmail->fetchAll(PDO::FETCH_COLUMN);
282
		
283
		$usersObjects=[];
284
		foreach ($users as $user) {
285
			$usersObjects[]=new User($user, $this->linkpdo);	
286
		}
287
		
288
		return $usersObjects;
289
290
	}
291
    
292
	/**
293
	 * Add investigators emails having a particular center center in main or affiliated center
294
	 */
295
	public function selectInvestigatorsEmailsWithSameCenter(String $study, int $center, ?array $job=null) : Send_Email {
296
		//Select All users that has a matching center
297
		$users=$this->getUsersAffiliatedToCenter($center);
298
		//For each user check that we match role requirement (array if investigator), string if monitor or supervisor
299
		foreach ($users as $user) {
300
            
301
			if (is_array($job) && !in_array($user->userJob, $job)) {
302
				continue;
303
			}
304
        
305
			if ($user->isRoleAllowed($study, User::INVESTIGATOR)) {
306
				$this->addEmail($user->userEmail);
307
			}
308
            
309
		}
310
        
311
		return $this;
312
	}
313
314
	public function addAminEmails() : Send_Email {
315
316
		$emails=$this->getAdminsEmails();
317
		$this->addEmails($emails);
318
		return $this;
319
320
	}
321
322
	public function addEmails(Array $emails) : Send_Email{
323
324
		foreach ($emails as $email) {
325
			if (!in_array($email, $this->emailsDestinators))
326
			{
327
				$this->emailsDestinators[]=$email; 
328
			}
329
330
		}
331
		return $this;
332
333
	}
334
335
	public function addGroupEmails(String $study, String $role) : Send_Email {
336
337
		$emails=$this->getRolesEmails($study, $role);
338
		$this->addEmails($emails);
339
		return $this;
340
341
	}
342
343
	public function addEmailsReviewerWithNoReview(string $study, int $idVisit) {
344
		$connecter=$this->linkpdo->prepare('SELECT users.email FROM roles, users 
345
												WHERE roles.study=:study 
346
												AND roles.username=users.username 
347
												AND roles.name=:role
348
												AND users.status!="Deactivated"
349
												AND (SELECT COUNT(*) FROM reviews WHERE id_visit=:idVisit AND username=roles.username AND deleted=0 AND validated=1 AND is_local=0) = 0
350
												');
351
		$connecter->execute(array(
352
				'study'=>$study,
353
				'role'=>User::REVIEWER,
354
				'idVisit' => $idVisit));
355
    	
356
		$emails=$connecter->fetchAll(PDO::FETCH_COLUMN);
357
		$this->addEmails($emails);
358
		return $this;
359
	}
360
361
	public function addEmail(String $email) : Send_Email {
362
363
		if (!in_array($email, $this->emailsDestinators))
364
			{
365
				$this->emailsDestinators[]=$email; 
366
			}
367
        
368
		return $this;
369
	}
370
371
	public function sendModifyUserMessage($username, $newPassword) {
372
373
		$message="Your account password is reset. Please log in at: ".$this->webAddress."<br>
374
        Username : $username<br>
375
        Temporary password : $newPassword<br>
376
        You will be asked to change this password at your first log in attempt<br>
377
        on the platform.<br>";
378
        
379
		$this->setMessage($message);
380
		$this->subject='Reactivation';
381
		$this->sendEmail();
382
383
	}
384
385
	public function sendNewAccountMessage($username, $password) {
386
387
		$message="Your account is created for the upload platform used to exchange
388
                imaging data. Please log in at: " . $this->webAddress." <br>
389
                Username : $username<br>
390
                Temporary password : $password<br>
391
                You will be asked to change this password at your first log in attempt
392
                on the platform.<br><br>";
393
394
		$this->setMessage($message);
395
		$this->subject='New account';
396
		$this->sendEmail();
397
	}
398
399
	public function sendNewPasswordEmail($username, $password) {
400
401
		$message="This automatic e-mail contains your new temporary password for your
402
          user account.<br>
403
          Username : ".$username." <br>
404
          Temporary password : ".$password." <br>
405
          You will be asked to change this password at your first connection.<br>";
406
        
407
		$this->setMessage($message);
408
		$this->subject='New Password';
409
		$this->sendEmail();
410
411
	}
412
413
	public function sendQCDesicionEmail(String $controlDecision, String $study, String $patientCode, String $visitType, $formDecision, $formComment, $imageDecision, $imageComment) {
414
		$message="Quality Control of the following visit has been set to : ".$controlDecision."<br>
415
                Study : ".$study."<br>
416
                Patient Number : ".$patientCode."<br>
417
                Visit : ".$visitType."<br>
418
                Investigation Form : ".$formDecision." Comment :".$formComment."<br>
419
                Image Series : ".$imageDecision." Comment :".$imageComment." <br>";
420
421
		$this->setMessage($message);
422
		$this->subject = $study.' - Quality Control Patient '.$patientCode;
423
		$this->sendEmail();
424
	}
425
426
	public function sendBlockedAccountNoPasswordChangeEmail($username, $linkedStudy) {
427
428
		$message="The password change request cannot be done because the account is Deactivated<br>
429
          Username : ".$username."<br>
430
          The account is linked to the following studies:".implode(',', $linkedStudy)."<br>
431
          Please contact the ".$this->corporation." to activate your account:<br>
432
          ".$this->adminEmail."<br>";
433
434
		$this->setMessage($message);
435
		$this->subject='Blocked account';
436
		$this->sendEmail();
437
438
	}
439
440
	public function sendAdminLoggedAlertEmail($username, $remoteAddress) {
441
		$message='the Admin user '.$username.' logged in from '.$remoteAddress.'
442
        <br> Please review this activity';
443
		$this->setMessage($message);
444
		$this->subject="Admin Logged In";
445
		$this->sendEmail();
446
        
447
	}
448
449
	public function sendUnlockRequestMessage(String $role, String $username, String $visitType, $patientNum, String $study, String $request) {
450
		$message="An Unlock ".$role." form Request was emitted by ".$username. 
451
		" for the ".$visitType. 
452
		" visit of patient ".$patientNum. 
453
		" in Study ".$study."<br>
454
        Reason for request: " . $request." <br>";
455
		$this->setMessage($message);
456
		$this->subject='Ask Unlock';
457
		$this->sendEmail();
458
        
459
	}
460
461
	public function sendReviewReadyMessage(String $study, int $patientCode, String $visitType) {
462
		$message = "The following visit is ready for review in the platform: <br>
463
        Study : ".$study."<br>
464
        Patient Number : ".$patientCode."<br>
465
        Visit : ".$visitType."<br>";
466
		$this->setMessage($message);
467
		$this->subject=$study." - Awaiting Review Patient ".$patientCode;
468
		$this->sendEmail();
469
	}
470
471
	public function sendCorrectiveActionDoneMessage(bool $done, String $study, int $patientCode, String $visitType) {
472
473
		if (!$done) {
474
			$message="No corrective action could be applied on the following visit: <br>
475
                        Study : " . $study."<br>
476
			            Patient Number : " . $patientCode."<br>
477
			            Uploaded visit : " . $visitType."<br>";
478
		} 
479
		else {
480
			$message="A corrective action was applied on the following visit: <br>
481
                        Study : " . $study."<br>
482
		          		Patient Number : " . $patientCode."<br>
483
		          		Uploaded visit : " . $visitType."<br>";
484
			
485
		}
486
		$this->setMessage($message);
487
		$this->subject= $study." - Corrective Action Patient ".$patientCode;
488
		$this->sendEmail();
489
490
	}
491
492
	public function sendRequestMessage(String $name, String $email, String $center, String $request) {
493
		$message="The following request was sent and will be processed as soon as possible:<br>
494
		Name : ".$name."<br>
495
		E-mail : ".$email."<br>
496
		Investigational center : ".$center."<br>
497
        Request : ".$request."<br>";
498
        
499
		$this->setMessage($message);
500
		$this->subject="Request";
501
		$this->sendEmail();
502
	}
503
504
	public function sendAwaitingAdjudicationMessage(String $study, int $patientCode, String $visitType) {
505
		$message="Review of the following visit is awaiting adjudication <br>
506
        Study : ".$study."<br>
507
        Patient Number : ".$patientCode."<br>
508
        Visit : ".$visitType."<br>
509
        The visit is awaiting for your adjudication review";
510
511
		$this->setMessage($message);
512
		$this->subject= $study." - Awaiting Adjudication Patient ".$patientCode ;
513
		$this->sendEmail();
514
	}
515
516
	public function sendVisitConcludedMessage(String $study, int $patientCode, String $visitType, $conclusionValue) {
517
		$message="Review of the following visit is concluded <br>
518
                Study : ".$study."<br>
519
                Patient Number : ".$patientCode."<br>
520
				Visit : ".$visitType."<br>
521
                Conclusion Value : ".$conclusionValue;
522
523
		$this->setMessage($message);
524
		$this->subject=$study." - Visit Concluded Patient ".$patientCode;
525
		$this->sendEmail();
526
	}
527
528
	public function sendBlockedAccountNotification($username, $studies) {
529
		$message='The following user account is blocked after too many bad password
530
                attempts.<br>
531
                Username : '.$username.'<br>
532
                The account is linked to the following studies:<br>
533
                '. implode('<br>', $studies).' </br>';
534
535
		$this->setMessage($message);
536
		$this->subject="Account Blocked";
537
		$this->sendEmail();
538
	}
539
540
	public function sendUploadedVisitMessage($study, $patientCode, $visitType) {
541
		$message="The following visit has been uploaded on the platform: <br>
542
        Study : ".$study."<br>
543
        Patient Number : ".$patientCode."<br>
544
        Uploaded visit : ".$visitType."<br>";
545
546
		$this->setMessage($message);
547
		$this->subject= $study." - New upload Patient ".$patientCode;
548
		$this->sendEmail();
549
550
	}
551
552
	public function sendDeletedFormMessage(String $study, String $patientCode, String $visitType) {
553
		$message="Your form sent for study : ".$study."<br>
554
        Patient : ".$patientCode."<br>
555
        Visit  : ".$visitType." <br>
556
        Have been deleted. <br>
557
        You can now resend a new version of this form <br>";
558
559
		$this->setMessage($message);
560
		$this->subject= $study." - Form Deleted Patient ".$patientCode;
561
		$this->sendEmail();
562
563
	}
564
565
	public function sendUnlockedFormMessage(String $study, String $patientCode, String $visitType) {
566
		$message="Your form sent for study : ".$study."<br>
567
        Patient : ".$patientCode."<br>
568
        Visit  : ".$visitType." <br>
569
        Have been Unlocked. <br>
570
        You can now resend a new version of this form <br>";
571
572
		$this->setMessage($message);
573
		$this->subject= $study." - Form Unlocked Patient ".$patientCode;
574
		$this->sendEmail();
575
576
	}
577
578
	public function sendUploadValidationFailure($idVisit, $patientCode, String $visitType, String $study, String $zipPath, String $username, String $errorMessage) {
579
		$message="An Import Error occured during validation of upload <br>
580
            Visit ID : ".$idVisit."<br>
581
            Patient Code : ".$patientCode."<br>
582
            Visit Type : ".$visitType."<br>
583
            Study : ".$study."<br>
584
            zipPath : ".$zipPath."<br>
585
            username: ".$username."<br>
586
            error  : ".$errorMessage."<br>";
587
588
		$this->setMessage($message);
589
		$this->subject=$study." - Error During Import Patient ".$patientCode;
590
		$this->sendEmail();
591
	}
592
593
	public function sendCreatedNotDoneVisitNotification($patientCode, $study, $visitType, $creatorUser) {
594
		$message="A Not Done visit has been created <br>
595
        Patient Number : ".$patientCode."<br>
596
        Study : ".$study."<br> 
597
        Visit Type : ".$visitType."<br>
598
        Creating Username : ".$creatorUser."<br>";
599
600
		$this->setMessage($message);
601
		$this->subject=$study." - Visit Not Done Patient ".$patientCode;
602
		$this->sendEmail();
603
	}
604
605
    
606
}
607