|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace Canvas\Api\Controllers; |
|
6
|
|
|
|
|
7
|
|
|
use Canvas\Models\Users; |
|
8
|
|
|
use Canvas\Models\Sources; |
|
9
|
|
|
use Canvas\Models\UserLinkedSources; |
|
10
|
|
|
use Canvas\Exception\ServerErrorHttpException; |
|
11
|
|
|
use Canvas\Exception\ModelException; |
|
12
|
|
|
use Baka\Auth\Models\Users as BakaUsers; |
|
13
|
|
|
use Canvas\Traits\AuthTrait; |
|
14
|
|
|
use Canvas\Traits\SocialLoginTrait; |
|
15
|
|
|
use Exception; |
|
16
|
|
|
use Phalcon\Http\Response; |
|
17
|
|
|
use Phalcon\Validation\Validator\Confirmation; |
|
18
|
|
|
use Phalcon\Validation\Validator\Email as EmailValidator; |
|
19
|
|
|
use Phalcon\Validation\Validator\PresenceOf; |
|
20
|
|
|
use Phalcon\Validation\Validator\StringLength; |
|
21
|
|
|
use Baka\Auth\Models\Sessions; |
|
22
|
|
|
use Canvas\Auth\Factory; |
|
23
|
|
|
use Canvas\Validation as CanvasValidation; |
|
24
|
|
|
use Canvas\Notifications\ResetPassword; |
|
25
|
|
|
use Canvas\Notifications\PasswordUpdate; |
|
26
|
|
|
use Canvas\Validations\PasswordValidation; |
|
27
|
|
|
use Canvas\Traits\TokenTrait; |
|
28
|
|
|
use Lcobucci\JWT\Builder; |
|
29
|
|
|
use Lcobucci\JWT\Signer\Hmac\Sha512; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* Class AuthController. |
|
33
|
|
|
* |
|
34
|
|
|
* @package Canvas\Api\Controllers |
|
35
|
|
|
* |
|
36
|
|
|
* @property Users $userData |
|
37
|
|
|
* @property Request $request |
|
38
|
|
|
* @property Config $config |
|
39
|
|
|
* @property \Baka\Mail\Message $mail |
|
40
|
|
|
* @property Apps $app |
|
41
|
|
|
*/ |
|
42
|
|
|
class AuthController extends \Baka\Auth\AuthController |
|
43
|
|
|
{ |
|
44
|
|
|
/** |
|
45
|
|
|
* Auth Trait. |
|
46
|
|
|
*/ |
|
47
|
|
|
use AuthTrait; |
|
48
|
|
|
use TokenTrait; |
|
49
|
|
|
use SocialLoginTrait; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Setup for this controller. |
|
53
|
|
|
* |
|
54
|
|
|
* @return void |
|
55
|
|
|
*/ |
|
56
|
|
|
public function onConstruct() |
|
57
|
|
|
{ |
|
58
|
|
|
$this->userLinkedSourcesModel = new UserLinkedSources(); |
|
59
|
|
|
$this->userModel = new Users(); |
|
60
|
|
|
|
|
61
|
|
|
if (!isset($this->config->jwt)) { |
|
62
|
|
|
throw new ServerErrorHttpException('You need to configure your app JWT'); |
|
|
|
|
|
|
63
|
|
|
} |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* User Login. |
|
68
|
|
|
* @method POST |
|
69
|
|
|
* @url /v1/auth |
|
70
|
|
|
* |
|
71
|
|
|
* @return Response |
|
72
|
|
|
*/ |
|
73
|
|
|
public function login() : Response |
|
74
|
|
|
{ |
|
75
|
|
|
$request = $this->request->getPostData(); |
|
76
|
|
|
|
|
77
|
|
|
$userIp = !defined('API_TESTS') ? $this->request->getClientAddress() : '127.0.0.1'; //help getting the client ip on scrutinizer :( |
|
78
|
|
|
$admin = 0; |
|
79
|
|
|
$remember = 1; |
|
80
|
|
|
|
|
81
|
|
|
//Ok let validate user password |
|
82
|
|
|
$validation = new CanvasValidation(); |
|
83
|
|
|
$validation->add('email', new EmailValidator(['message' => _('The email is not valid')])); |
|
84
|
|
|
$validation->add('password', new PresenceOf(['message' => _('The password is required.')])); |
|
85
|
|
|
|
|
86
|
|
|
$validation->setFilters('name', 'trim'); |
|
87
|
|
|
$validation->setFilters('password', 'trim'); |
|
88
|
|
|
|
|
89
|
|
|
//validate this form for password |
|
90
|
|
|
$validation->validate($request); |
|
91
|
|
|
|
|
92
|
|
|
$email = $validation->getValue('email'); |
|
93
|
|
|
$password = $validation->getValue('password'); |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* Login the user via ecosystem or app. |
|
97
|
|
|
*/ |
|
98
|
|
|
$auth = Factory::create($this->app->ecosystemAuth()); |
|
99
|
|
|
$userData = $auth::login($email, $password, $remember, $admin, $userIp); |
|
100
|
|
|
$token = $userData->getToken(); |
|
101
|
|
|
|
|
102
|
|
|
//start session |
|
103
|
|
|
$session = new Sessions(); |
|
104
|
|
|
$session->start($userData, $token['sessionId'], $token['token'], $userIp, 1); |
|
105
|
|
|
|
|
106
|
|
|
return $this->response([ |
|
107
|
|
|
'token' => $token['token'], |
|
108
|
|
|
'refresh_token' => $token['refresh_token'], |
|
109
|
|
|
'time' => date('Y-m-d H:i:s'), |
|
110
|
|
|
'expires' => date('Y-m-d H:i:s', time() + $this->config->jwt->payload->exp), |
|
111
|
|
|
'refresh_token_expires' => date('Y-m-d H:i:s', time() + 31536000), |
|
112
|
|
|
'id' => $userData->getId() |
|
113
|
|
|
]); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* User Signup. |
|
118
|
|
|
* |
|
119
|
|
|
* @method POST |
|
120
|
|
|
* @url /v1/users |
|
121
|
|
|
* |
|
122
|
|
|
* @return Response |
|
123
|
|
|
*/ |
|
124
|
|
|
public function signup() : Response |
|
125
|
|
|
{ |
|
126
|
|
|
$user = $this->userModel; |
|
127
|
|
|
|
|
128
|
|
|
$request = $this->request->getPostData(); |
|
129
|
|
|
|
|
130
|
|
|
//Ok let validate user password |
|
131
|
|
|
$validation = new CanvasValidation(); |
|
132
|
|
|
$validation->add('password', new PresenceOf(['message' => _('The password is required.')])); |
|
133
|
|
|
$validation->add('firstname', new PresenceOf(['message' => _('The firstname is required.')])); |
|
134
|
|
|
$validation->add('lastname', new PresenceOf(['message' => _('The lastname is required.')])); |
|
135
|
|
|
$validation->add('email', new EmailValidator(['message' => _('The email is not valid.')])); |
|
136
|
|
|
|
|
137
|
|
|
$validation->add( |
|
138
|
|
|
'password', |
|
139
|
|
|
new StringLength([ |
|
140
|
|
|
'min' => 8, |
|
141
|
|
|
'messageMinimum' => _('Password is too short. Minimum 8 characters.'), |
|
142
|
|
|
]) |
|
143
|
|
|
); |
|
144
|
|
|
|
|
145
|
|
|
$validation->add('password', new Confirmation([ |
|
146
|
|
|
'message' => _('Password and confirmation do not match.'), |
|
147
|
|
|
'with' => 'verify_password', |
|
148
|
|
|
])); |
|
149
|
|
|
|
|
150
|
|
|
$validation->setFilters('password', 'trim'); |
|
151
|
|
|
$validation->setFilters('displayname', 'trim'); |
|
152
|
|
|
$validation->setFilters('default_company', 'trim'); |
|
153
|
|
|
|
|
154
|
|
|
//validate this form for password |
|
155
|
|
|
$validation->validate($request); |
|
156
|
|
|
|
|
157
|
|
|
$user->email = $validation->getValue('email'); |
|
158
|
|
|
$user->firstname = $validation->getValue('firstname'); |
|
159
|
|
|
$user->lastname = $validation->getValue('lastname'); |
|
160
|
|
|
$user->password = $validation->getValue('password'); |
|
161
|
|
|
$userIp = !defined('API_TESTS') ? $this->request->getClientAddress() : '127.0.0.1'; //help getting the client ip on scrutinizer :( |
|
162
|
|
|
$user->displayname = $validation->getValue('displayname'); |
|
163
|
|
|
$user->defaultCompanyName = $validation->getValue('default_company'); |
|
164
|
|
|
|
|
165
|
|
|
//user registration |
|
166
|
|
|
try { |
|
167
|
|
|
$this->db->begin(); |
|
168
|
|
|
|
|
169
|
|
|
$user->signUp(); |
|
170
|
|
|
|
|
171
|
|
|
$this->db->commit(); |
|
172
|
|
|
} catch (Exception $e) { |
|
173
|
|
|
$this->db->rollback(); |
|
174
|
|
|
|
|
175
|
|
|
throw new Exception($e->getMessage()); |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
$token = $user->getToken(); |
|
179
|
|
|
|
|
180
|
|
|
//start session |
|
181
|
|
|
$session = new Sessions(); |
|
182
|
|
|
$session->start($user, $token['sessionId'], $token['token'], $userIp, 1); |
|
183
|
|
|
|
|
184
|
|
|
$authSession = [ |
|
185
|
|
|
'token' => $token['token'], |
|
186
|
|
|
'time' => date('Y-m-d H:i:s'), |
|
187
|
|
|
'expires' => date('Y-m-d H:i:s', time() + $this->config->jwt->payload->exp), |
|
188
|
|
|
'id' => $user->getId(), |
|
189
|
|
|
]; |
|
190
|
|
|
|
|
191
|
|
|
$user->password = null; |
|
192
|
|
|
$this->sendEmail($user, 'signup'); |
|
193
|
|
|
|
|
194
|
|
|
return $this->response([ |
|
195
|
|
|
'user' => $user, |
|
196
|
|
|
'session' => $authSession |
|
197
|
|
|
]); |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
/** |
|
201
|
|
|
* Refresh user auth. |
|
202
|
|
|
* |
|
203
|
|
|
* @return Response |
|
204
|
|
|
* @todo Validate acces_token and refresh token, session's user email and relogin |
|
205
|
|
|
*/ |
|
206
|
|
|
public function refresh(): Response |
|
207
|
|
|
{ |
|
208
|
|
|
$request = $this->request->getPostData(); |
|
209
|
|
|
$accessToken = $this->getToken($request['access_token']); |
|
210
|
|
|
$refreshToken = $this->getToken($request['refresh_token']); |
|
211
|
|
|
|
|
212
|
|
|
// if (time() != $accessToken->getClaim('exp')) { |
|
213
|
|
|
// throw new ServerErrorHttpException('Issued Access Token has not expired'); |
|
214
|
|
|
// } |
|
215
|
|
|
|
|
216
|
|
|
//Check if both tokens relate to the same user's email |
|
217
|
|
|
if ($accessToken->getClaim('sessionId') == $refreshToken->getClaim('sessionId')) { |
|
218
|
|
|
$user = Users::getByEmail($accessToken->getClaim('email')); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
$token = $this->checkSessionStatus($user, $refreshToken->getClaim('sessionId'), (string)$this->request->getClientAddress()); |
|
|
|
|
|
|
222
|
|
|
|
|
223
|
|
|
return $this->response([ |
|
224
|
|
|
'token' => $token['token'], |
|
225
|
|
|
'time' => date('Y-m-d H:i:s'), |
|
226
|
|
|
'expires' => date('Y-m-d H:i:s', time() + $this->config->jwt->payload->exp), |
|
227
|
|
|
'id' => $user->getId(), |
|
228
|
|
|
]); |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
/** |
|
232
|
|
|
* Check auth session status and create a new one if there is none. |
|
233
|
|
|
* |
|
234
|
|
|
* @param Users $user |
|
235
|
|
|
* @param string $sessionId |
|
236
|
|
|
* @param string $clientAddress |
|
237
|
|
|
* @return array |
|
238
|
|
|
*/ |
|
239
|
|
|
private function checkSessionStatus(Users $user, string $sessionId, string $clientAddress): array |
|
240
|
|
|
{ |
|
241
|
|
|
$session = new Sessions(); |
|
242
|
|
|
$session->check($user, $sessionId, $clientAddress, 1); |
|
243
|
|
|
$token = $this->newAuthSession($sessionId, $user->email); |
|
244
|
|
|
$session->start($user, $token['sessionId'], $token['token'], $clientAddress, 1); |
|
245
|
|
|
return $token; |
|
246
|
|
|
} |
|
247
|
|
|
|
|
248
|
|
|
/** |
|
249
|
|
|
* Create a new session based off the refresh token session id. |
|
250
|
|
|
* |
|
251
|
|
|
* @param string $sessionId |
|
252
|
|
|
* @param string $email |
|
253
|
|
|
* @return void |
|
|
|
|
|
|
254
|
|
|
*/ |
|
255
|
|
|
private function newAuthSession(string $sessionId, string $email) |
|
256
|
|
|
{ |
|
257
|
|
|
$signer = new Sha512(); |
|
258
|
|
|
$builder = new Builder(); |
|
259
|
|
|
$token = $builder |
|
|
|
|
|
|
260
|
|
|
->setIssuer(getenv('TOKEN_AUDIENCE')) |
|
261
|
|
|
->setAudience(getenv('TOKEN_AUDIENCE')) |
|
262
|
|
|
->setId($sessionId, true) |
|
263
|
|
|
->setIssuedAt(time()) |
|
264
|
|
|
->setNotBefore(time() + 500) |
|
265
|
|
|
->setExpiration(time() + $this->di->getConfig()->jwt->payload->exp) |
|
266
|
|
|
->set('sessionId', $sessionId) |
|
267
|
|
|
->set('email', $email) |
|
268
|
|
|
->sign($signer, getenv('TOKEN_PASSWORD')) |
|
269
|
|
|
->getToken(); |
|
270
|
|
|
|
|
271
|
|
|
return [ |
|
272
|
|
|
'sessionId' => $sessionId, |
|
273
|
|
|
'token' => $token->__toString() |
|
274
|
|
|
]; |
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
/** |
|
278
|
|
|
* Send email to change current email for user. |
|
279
|
|
|
* @param int $id |
|
280
|
|
|
* @return Response |
|
281
|
|
|
*/ |
|
282
|
|
|
public function sendEmailChange(int $id): Response |
|
283
|
|
|
{ |
|
284
|
|
|
//Search for user |
|
285
|
|
|
$user = Users::getById($id); |
|
286
|
|
|
|
|
287
|
|
|
if (!is_object($user)) { |
|
288
|
|
|
throw new NotFoundHttpException(_('User not found')); |
|
289
|
|
|
} |
|
290
|
|
|
|
|
291
|
|
|
//Send email |
|
292
|
|
|
$this->sendEmail($user, 'email-change'); |
|
293
|
|
|
|
|
294
|
|
|
return $this->response($user); |
|
295
|
|
|
} |
|
296
|
|
|
|
|
297
|
|
|
/** |
|
298
|
|
|
* Change user's email. |
|
299
|
|
|
* @param string $hash |
|
300
|
|
|
* @return Response |
|
301
|
|
|
*/ |
|
302
|
|
|
public function changeUserEmail(string $hash): Response |
|
303
|
|
|
{ |
|
304
|
|
|
$request = $this->request->getPostData(); |
|
305
|
|
|
|
|
306
|
|
|
//Ok let validate user password |
|
307
|
|
|
$validation = new CanvasValidation(); |
|
308
|
|
|
$validation->add('password', new PresenceOf(['message' => _('The password is required.')])); |
|
309
|
|
|
$validation->add('new_email', new EmailValidator(['message' => _('The email is not valid.')])); |
|
310
|
|
|
|
|
311
|
|
|
$validation->add( |
|
312
|
|
|
'password', |
|
313
|
|
|
new StringLength([ |
|
314
|
|
|
'min' => 8, |
|
315
|
|
|
'messageMinimum' => _('Password is too short. Minimum 8 characters.'), |
|
316
|
|
|
]) |
|
317
|
|
|
); |
|
318
|
|
|
|
|
319
|
|
|
//validate this form for password |
|
320
|
|
|
$validation->setFilters('password', 'trim'); |
|
321
|
|
|
$validation->setFilters('default_company', 'trim'); |
|
322
|
|
|
$validation->validate($request); |
|
323
|
|
|
|
|
324
|
|
|
$newEmail = $validation->getValue('new_email'); |
|
325
|
|
|
$password = $validation->getValue('password'); |
|
326
|
|
|
|
|
327
|
|
|
//Search user by key |
|
328
|
|
|
$user = Users::getByUserActivationEmail($hash); |
|
329
|
|
|
|
|
330
|
|
|
if (!is_object($user)) { |
|
331
|
|
|
throw new NotFoundHttpException(_('User not found')); |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
|
|
$this->db->begin(); |
|
335
|
|
|
|
|
336
|
|
|
$user->email = $newEmail; |
|
337
|
|
|
|
|
338
|
|
|
if (!$user->update()) { |
|
339
|
|
|
throw new ModelException((string)current($user->getMessages())); |
|
|
|
|
|
|
340
|
|
|
} |
|
341
|
|
|
|
|
342
|
|
|
if (!$userData = $this->loginUsers($user->email, $password)) { |
|
343
|
|
|
$this->db->rollback(); |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
$this->db->commit(); |
|
347
|
|
|
|
|
348
|
|
|
return $this->response($userData); |
|
349
|
|
|
} |
|
350
|
|
|
|
|
351
|
|
|
/** |
|
352
|
|
|
* Login user using Access Token. |
|
353
|
|
|
* @return Response |
|
354
|
|
|
*/ |
|
355
|
|
|
public function loginBySocial(): Response |
|
356
|
|
|
{ |
|
357
|
|
|
$request = $this->request->getPostData(); |
|
358
|
|
|
|
|
359
|
|
|
$source = Sources::findFirstOrFail([ |
|
360
|
|
|
'title = ?0 and is_deleted = 0', |
|
361
|
|
|
'bind' => [$request['provider']] |
|
362
|
|
|
]); |
|
363
|
|
|
|
|
364
|
|
|
return $this->response($this->providerLogin($source, $request['social_id'], $request)); |
|
365
|
|
|
} |
|
366
|
|
|
|
|
367
|
|
|
/** |
|
368
|
|
|
* Send the user how filled out the form to the specify email |
|
369
|
|
|
* a link to reset his password. |
|
370
|
|
|
* |
|
371
|
|
|
* @return Response |
|
372
|
|
|
*/ |
|
373
|
|
|
public function recover(): Response |
|
374
|
|
|
{ |
|
375
|
|
|
$request = $this->request->getPostData(); |
|
376
|
|
|
|
|
377
|
|
|
$validation = new CanvasValidation(); |
|
378
|
|
|
$validation->add('email', new EmailValidator(['message' => _('The email is not valid.')])); |
|
379
|
|
|
|
|
380
|
|
|
$validation->validate($request); |
|
381
|
|
|
|
|
382
|
|
|
$email = $validation->getValue('email'); |
|
383
|
|
|
|
|
384
|
|
|
$recoverUser = Users::getByEmail($email); |
|
385
|
|
|
$recoverUser->generateForgotHash(); |
|
386
|
|
|
|
|
387
|
|
|
$recoverUser->notify(new ResetPassword($recoverUser)); |
|
388
|
|
|
|
|
389
|
|
|
return $this->response(_('Check your email to recover your password')); |
|
390
|
|
|
} |
|
391
|
|
|
|
|
392
|
|
|
/** |
|
393
|
|
|
* Reset the user password. |
|
394
|
|
|
* @method PUT |
|
395
|
|
|
* @url /v1/reset |
|
396
|
|
|
* |
|
397
|
|
|
* @return Response |
|
398
|
|
|
*/ |
|
399
|
|
|
public function reset(string $key) : Response |
|
400
|
|
|
{ |
|
401
|
|
|
//is the key empty or does it existe? |
|
402
|
|
|
if (empty($key) || !$userData = Users::findFirst(['user_activation_forgot = :key:', 'bind' => ['key' => $key]])) { |
|
403
|
|
|
throw new Exception(_('This Key to reset password doesn\'t exist')); |
|
404
|
|
|
} |
|
405
|
|
|
|
|
406
|
|
|
$request = $this->request->getPostData(); |
|
407
|
|
|
|
|
408
|
|
|
// Get the new password and the verify |
|
409
|
|
|
$newPassword = trim($request['new_password']); |
|
410
|
|
|
$verifyPassword = trim($request['verify_password']); |
|
411
|
|
|
|
|
412
|
|
|
//Ok let validate user password |
|
413
|
|
|
PasswordValidation::validate($newPassword, $verifyPassword); |
|
414
|
|
|
|
|
415
|
|
|
// Has the password and set it |
|
416
|
|
|
$userData->resetPassword($newPassword); |
|
417
|
|
|
$userData->user_activation_forgot = ''; |
|
418
|
|
|
$userData->updateOrFail(); |
|
419
|
|
|
|
|
420
|
|
|
//log the user out of the site from all devices |
|
421
|
|
|
$session = new Sessions(); |
|
422
|
|
|
$session->end($userData); |
|
423
|
|
|
|
|
424
|
|
|
$userData->notify(new PasswordUpdate($userData)); |
|
425
|
|
|
|
|
426
|
|
|
return $this->response(_('Password Updated')); |
|
427
|
|
|
} |
|
428
|
|
|
|
|
429
|
|
|
/** |
|
430
|
|
|
* Set the email config array we are going to be sending. |
|
431
|
|
|
* |
|
432
|
|
|
* @todo deprecated move to notifications |
|
433
|
|
|
* @param String $emailAction |
|
|
|
|
|
|
434
|
|
|
* @param Users $user |
|
|
|
|
|
|
435
|
|
|
* @return void |
|
436
|
|
|
*/ |
|
437
|
|
|
protected function sendEmail(BakaUsers $user, string $type): void |
|
438
|
|
|
{ |
|
439
|
|
|
$send = true; |
|
440
|
|
|
$subject = null; |
|
441
|
|
|
$body = null; |
|
442
|
|
|
switch ($type) { |
|
443
|
|
|
case 'recover': |
|
444
|
|
|
$recoveryLink = $this->config->app->frontEndUrl . '/users/reset-password/' . $user->user_activation_forgot; |
|
445
|
|
|
$subject = _('Password Recovery'); |
|
446
|
|
|
$body = sprintf(_('Click %shere%s to set a new password for your account.'), '<a href="' . $recoveryLink . '" target="_blank">', '</a>'); |
|
447
|
|
|
// send email to recover password |
|
448
|
|
|
break; |
|
449
|
|
|
case 'reset': |
|
450
|
|
|
$activationUrl = $this->config->app->frontEndUrl . '/user/activate/' . $user->user_activation_key; |
|
451
|
|
|
$subject = _('Password Updated!'); |
|
452
|
|
|
$body = sprintf(_('Your password was update please, use this link to activate your account: %sActivate account%s'), '<a href="' . $activationUrl . '">', '</a>'); |
|
453
|
|
|
// send email that password was update |
|
454
|
|
|
break; |
|
455
|
|
|
case 'email-change': |
|
456
|
|
|
$emailChangeUrl = $this->config->app->frontEndUrl . '/user/' . $user->user_activation_email . '/email'; |
|
457
|
|
|
$subject = _('Email Change Request'); |
|
458
|
|
|
$body = sprintf(_('Click %shere%s to set a new email for your account.'), '<a href="' . $emailChangeUrl . '">', '</a>'); |
|
459
|
|
|
break; |
|
460
|
|
|
default: |
|
461
|
|
|
$send = false; |
|
462
|
|
|
break; |
|
463
|
|
|
} |
|
464
|
|
|
|
|
465
|
|
|
if ($send) { |
|
466
|
|
|
$this->mail |
|
467
|
|
|
->to($user->email) |
|
468
|
|
|
->subject($subject) |
|
469
|
|
|
->content($body) |
|
470
|
|
|
->sendNow(); |
|
471
|
|
|
} |
|
472
|
|
|
} |
|
473
|
|
|
} |
|
474
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.