From c0780736ca9303a80163b5dab03074ba3366d7cf Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 21 Apr 2017 01:41:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D0=B5=20=D1=87=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D0=B8,=20=D0=BE=D1=82=D0=B2=D0=B5=D1=87=D0=B0=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B7=D0=B0=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BA=D1=83=20E-mail=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/emails/EmailHelper.php | 56 +++++++++++++ api/emails/Template.php | 79 +++++++++++++++++++ api/emails/TemplateWithRenderer.php | 66 ++++++++++++++++ .../exceptions/CannotSendEmailException.php | 8 ++ .../ChangeEmailConfirmCurrentEmail.php | 35 ++++++++ .../templates/ChangeEmailConfirmNewEmail.php | 39 +++++++++ api/emails/templates/ForgotPasswordEmail.php | 34 ++++++++ api/emails/templates/ForgotPasswordParams.php | 30 +++++++ api/emails/templates/RegistrationEmail.php | 34 ++++++++ .../templates/RegistrationEmailParams.php | 30 +++++++ api/mails/new-email-confirmation-html.php | 4 +- api/mails/new-email-confirmation-text.php | 4 +- .../authentication/ForgotPasswordForm.php | 35 +------- .../authentication/RegistrationForm.php | 36 +-------- .../RepeatAccountActivationForm.php | 4 +- .../profile/ChangeEmail/InitStateForm.php | 28 +------ .../profile/ChangeEmail/NewEmailForm.php | 31 +------- 17 files changed, 427 insertions(+), 126 deletions(-) create mode 100644 api/emails/EmailHelper.php create mode 100644 api/emails/Template.php create mode 100644 api/emails/TemplateWithRenderer.php create mode 100644 api/emails/exceptions/CannotSendEmailException.php create mode 100644 api/emails/templates/ChangeEmailConfirmCurrentEmail.php create mode 100644 api/emails/templates/ChangeEmailConfirmNewEmail.php create mode 100644 api/emails/templates/ForgotPasswordEmail.php create mode 100644 api/emails/templates/ForgotPasswordParams.php create mode 100644 api/emails/templates/RegistrationEmail.php create mode 100644 api/emails/templates/RegistrationEmailParams.php diff --git a/api/emails/EmailHelper.php b/api/emails/EmailHelper.php new file mode 100644 index 0000000..17bb67b --- /dev/null +++ b/api/emails/EmailHelper.php @@ -0,0 +1,56 @@ +account; + $locale = $account->lang; + $params = new RegistrationEmailParams( + $account->username, + $emailActivation->key, + Yii::$app->request->getHostInfo() . '/activation/' . $emailActivation->key + ); + + (new RegistrationEmail(self::buildTo($account), $locale, $params))->send(); + } + + public static function forgotPassword(ForgotPassword $emailActivation): void { + $account = $emailActivation->account; + $locale = $account->lang; + $params = new ForgotPasswordParams( + $account->username, + $emailActivation->key, + Yii::$app->request->getHostInfo() . '/recover-password/' . $emailActivation->key + ); + + (new ForgotPasswordEmail(self::buildTo($account), $locale, $params))->send(); + } + + public static function changeEmailConfirmCurrent(CurrentEmailConfirmation $emailActivation): void { + (new ChangeEmailConfirmCurrentEmail(self::buildTo($emailActivation->account), $emailActivation->key))->send(); + } + + public static function changeEmailConfirmNew(NewEmailConfirmation $emailActivation): void { + $account = $emailActivation->account; + (new ChangeEmailConfirmNewEmail(self::buildTo($account), $account->username, $emailActivation->key))->send(); + } + + public static function buildTo(Account $account): array { + return [$account->email => $account->username]; + } + +} diff --git a/api/emails/Template.php b/api/emails/Template.php new file mode 100644 index 0000000..c4aa1e9 --- /dev/null +++ b/api/emails/Template.php @@ -0,0 +1,79 @@ + name] + */ + public function __construct($to) { + $this->mailer = Yii::$app->mailer; + $this->to = $to; + } + + /** + * @return array|string + */ + public function getTo() { + return $this->to; + } + + abstract public function getSubject(): string; + + /** + * @return array|string + * @throws InvalidConfigException + */ + public function getFrom() { + $fromEmail = Yii::$app->params['fromEmail']; + if (!$fromEmail) { + throw new InvalidConfigException('Please specify fromEmail app in app params'); + } + + return [$fromEmail => 'Ely.by Accounts']; + } + + public function getParams(): array { + return []; + } + + public function getMailer(): MailerInterface { + return $this->mailer; + } + + public function send(): void { + if (!$this->createMessage()->send()) { + throw new CannotSendEmailException('Unable send email.'); + } + } + + /** + * @return string|array + */ + abstract protected function getView(); + + protected function createMessage(): MessageInterface { + return $this->getMailer() + ->compose($this->getView(), $this->getParams()) + ->setTo($this->getTo()) + ->setFrom($this->getFrom()) + ->setSubject($this->getSubject()); + } + +} diff --git a/api/emails/TemplateWithRenderer.php b/api/emails/TemplateWithRenderer.php new file mode 100644 index 0000000..c3e3a57 --- /dev/null +++ b/api/emails/TemplateWithRenderer.php @@ -0,0 +1,66 @@ +emailRenderer = Yii::$app->emailRenderer; + $this->locale = $locale; + } + + public function getLocale(): string { + return $this->locale; + } + + public function getEmailRenderer(): EmailRenderer { + return $this->emailRenderer; + } + + /** + * Метод должен возвращать имя шаблона, который должен быть использован. + * Имена можно взять в репозитории elyby/email-renderer + * + * @return string + */ + abstract protected function getTemplateName(): string; + + protected final function getView() { + return $this->getTemplateName(); + } + + protected function createMessage(): MessageInterface { + return $this->getMailer() + ->compose() + ->setHtmlBody($this->render()) + ->setTo($this->getTo()) + ->setFrom($this->getFrom()) + ->setSubject($this->getSubject()); + } + + private function render(): string { + return $this->getEmailRenderer() + ->getTemplate($this->getTemplateName()) + ->setLocale($this->getLocale()) + ->setParams($this->getParams()) + ->render(); + } + +} diff --git a/api/emails/exceptions/CannotSendEmailException.php b/api/emails/exceptions/CannotSendEmailException.php new file mode 100644 index 0000000..0e9c37f --- /dev/null +++ b/api/emails/exceptions/CannotSendEmailException.php @@ -0,0 +1,8 @@ +key = $key; + } + + public function getSubject(): string { + return 'Ely.by Account change E-mail confirmation'; + } + + /** + * @return string|array + */ + protected function getView() { + return [ + 'html' => '@app/mails/current-email-confirmation-html', + 'text' => '@app/mails/current-email-confirmation-text', + ]; + } + + public function getParams(): array { + return [ + 'key' => $this->key, + ]; + } + +} diff --git a/api/emails/templates/ChangeEmailConfirmNewEmail.php b/api/emails/templates/ChangeEmailConfirmNewEmail.php new file mode 100644 index 0000000..02ee338 --- /dev/null +++ b/api/emails/templates/ChangeEmailConfirmNewEmail.php @@ -0,0 +1,39 @@ +username = $username; + $this->key = $key; + } + + public function getSubject(): string { + return 'Ely.by Account new E-mail confirmation'; + } + + /** + * @return string|array + */ + protected function getView() { + return [ + 'html' => '@app/mails/new-email-confirmation-html', + 'text' => '@app/mails/new-email-confirmation-text', + ]; + } + + public function getParams(): array { + return [ + 'key' => $this->key, + 'username' => $this->username, + ]; + } + +} diff --git a/api/emails/templates/ForgotPasswordEmail.php b/api/emails/templates/ForgotPasswordEmail.php new file mode 100644 index 0000000..1af0505 --- /dev/null +++ b/api/emails/templates/ForgotPasswordEmail.php @@ -0,0 +1,34 @@ +params = $params; + } + + public function getSubject(): string { + return 'Ely.by Account forgot password'; + } + + protected function getTemplateName(): string { + return 'forgotPassword'; + } + + public function getParams(): array { + return [ + 'username' => $this->params->getUsername(), + 'code' => $this->params->getCode(), + 'link' => $this->params->getLink(), + ]; + } + +} diff --git a/api/emails/templates/ForgotPasswordParams.php b/api/emails/templates/ForgotPasswordParams.php new file mode 100644 index 0000000..c060fdf --- /dev/null +++ b/api/emails/templates/ForgotPasswordParams.php @@ -0,0 +1,30 @@ +username = $username; + $this->code = $code; + $this->link = $code; + } + + public function getUsername(): string { + return $this->username; + } + + public function getCode(): string { + return $this->code; + } + + public function getLink(): string { + return $this->link; + } + +} diff --git a/api/emails/templates/RegistrationEmail.php b/api/emails/templates/RegistrationEmail.php new file mode 100644 index 0000000..1e065f2 --- /dev/null +++ b/api/emails/templates/RegistrationEmail.php @@ -0,0 +1,34 @@ +params = $params; + } + + public function getSubject(): string { + return 'Ely.by Account registration'; + } + + protected function getTemplateName(): string { + return 'register'; + } + + public function getParams(): array { + return [ + 'username' => $this->params->getUsername(), + 'code' => $this->params->getCode(), + 'link' => $this->params->getLink(), + ]; + } + +} diff --git a/api/emails/templates/RegistrationEmailParams.php b/api/emails/templates/RegistrationEmailParams.php new file mode 100644 index 0000000..c64f3e9 --- /dev/null +++ b/api/emails/templates/RegistrationEmailParams.php @@ -0,0 +1,30 @@ +username = $username; + $this->code = $code; + $this->link = $code; + } + + public function getUsername(): string { + return $this->username; + } + + public function getCode(): string { + return $this->code; + } + + public function getLink(): string { + return $this->link; + } + +} diff --git a/api/mails/new-email-confirmation-html.php b/api/mails/new-email-confirmation-html.php index 33b9a04..e1adab5 100644 --- a/api/mails/new-email-confirmation-html.php +++ b/api/mails/new-email-confirmation-html.php @@ -1,12 +1,12 @@

- This E-mail was specified as new for account username ?>. To confirm this E-mail, pass code + This E-mail was specified as new for account . To confirm this E-mail, pass code below into form on site.

Code:

diff --git a/api/mails/new-email-confirmation-text.php b/api/mails/new-email-confirmation-text.php index f516746..100dd49 100644 --- a/api/mails/new-email-confirmation-text.php +++ b/api/mails/new-email-confirmation-text.php @@ -1,11 +1,11 @@ -This E-mail was specified as new for account username ?>. To confirm this E-mail, pass code below into form on site. +This E-mail was specified as new for account . To confirm this E-mail, pass code below into form on site. Code: diff --git a/api/models/authentication/ForgotPasswordForm.php b/api/models/authentication/ForgotPasswordForm.php index 051decb..407d5fc 100644 --- a/api/models/authentication/ForgotPasswordForm.php +++ b/api/models/authentication/ForgotPasswordForm.php @@ -1,6 +1,7 @@ sendMail($emailActivation); + EmailHelper::forgotPassword($emailActivation); return true; } - public function sendMail(EmailActivation $emailActivation) { - /** @var \yii\swiftmailer\Mailer $mailer */ - $mailer = Yii::$app->mailer; - $fromEmail = Yii::$app->params['fromEmail']; - if (!$fromEmail) { - throw new InvalidConfigException('Please specify fromEmail app in app params'); - } - - $account = $emailActivation->account; - $htmlBody = Yii::$app->emailRenderer->getTemplate('forgotPassword') - ->setLocale($account->lang) - ->setParams([ - 'username' => $account->username, - 'code' => $emailActivation->key, - 'link' => Yii::$app->request->getHostInfo() . '/recover-password/' . $emailActivation->key, - ]) - ->render(); - - /** @var \yii\swiftmailer\Message $message */ - $message = $mailer->compose() - ->setHtmlBody($htmlBody) - ->setTo([$account->email => $account->username]) - ->setFrom([$fromEmail => 'Ely.by Accounts']) - ->setSubject('Ely.by Account forgot password'); - - if (!$message->send()) { - throw new ErrorException('Unable send email with activation code.'); - } - } - public function getLogin() { return $this->login; } diff --git a/api/models/authentication/RegistrationForm.php b/api/models/authentication/RegistrationForm.php index c39a249..95db013 100644 --- a/api/models/authentication/RegistrationForm.php +++ b/api/models/authentication/RegistrationForm.php @@ -2,12 +2,12 @@ namespace api\models\authentication; use api\components\ReCaptcha\Validator as ReCaptchaValidator; +use api\emails\EmailHelper; use api\models\base\ApiForm; use common\helpers\Error as E; use common\components\UserFriendlyRandomKey; use common\models\Account; use common\models\confirmations\RegistrationConfirmation; -use common\models\EmailActivation; use common\models\UsernameHistory; use common\validators\EmailValidator; use common\validators\LanguageValidator; @@ -17,7 +17,6 @@ use Exception; use Ramsey\Uuid\Uuid; use Yii; use yii\base\ErrorException; -use yii\base\InvalidConfigException; use yii\helpers\ArrayHelper; use const common\LATEST_RULES_VERSION; @@ -103,7 +102,7 @@ class RegistrationForm extends ApiForm { throw new ErrorException('Cannot save username history record'); } - $this->sendMail($emailActivation, $account); + EmailHelper::registration($emailActivation); $transaction->commit(); } catch (Exception $e) { @@ -114,37 +113,6 @@ class RegistrationForm extends ApiForm { return $account; } - // TODO: подумать, чтобы вынести этот метод в какую-то отдельную конструкцию, т.к. используется и внутри NewAccountActivationForm - public function sendMail(EmailActivation $emailActivation, Account $account) { - /** @var \yii\swiftmailer\Mailer $mailer */ - $mailer = Yii::$app->mailer; - $fromEmail = Yii::$app->params['fromEmail']; - - if (!$fromEmail) { - throw new InvalidConfigException('Please specify fromEmail app in app params'); - } - - $htmlBody = Yii::$app->emailRenderer->getTemplate('register') - ->setLocale($account->lang) - ->setParams([ - 'username' => $account->username, - 'code' => $emailActivation->key, - 'link' => Yii::$app->request->getHostInfo() . '/activation/' . $emailActivation->key, - ]) - ->render(); - - /** @var \yii\swiftmailer\Message $message */ - $message = $mailer->compose() - ->setHtmlBody($htmlBody) - ->setTo([$account->email => $account->username]) - ->setFrom([$fromEmail => 'Ely.by Accounts']) - ->setSubject('Ely.by Account registration'); - - if (!$message->send()) { - throw new ErrorException('Unable send email with activation code.'); - } - } - /** * Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается, * что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь diff --git a/api/models/authentication/RepeatAccountActivationForm.php b/api/models/authentication/RepeatAccountActivationForm.php index 6041f33..9a7e525 100644 --- a/api/models/authentication/RepeatAccountActivationForm.php +++ b/api/models/authentication/RepeatAccountActivationForm.php @@ -2,6 +2,7 @@ namespace api\models\authentication; use api\components\ReCaptcha\Validator as ReCaptchaValidator; +use api\emails\EmailHelper; use api\models\base\ApiForm; use common\helpers\Error as E; use common\components\UserFriendlyRandomKey; @@ -72,8 +73,7 @@ class RepeatAccountActivationForm extends ApiForm { throw new ErrorException('Unable save email-activation model.'); } - $regForm = new RegistrationForm(); - $regForm->sendMail($activation, $account); + EmailHelper::registration($activation); $transaction->commit(); } catch (ErrorException $e) { diff --git a/api/models/profile/ChangeEmail/InitStateForm.php b/api/models/profile/ChangeEmail/InitStateForm.php index fd14bba..680d45c 100644 --- a/api/models/profile/ChangeEmail/InitStateForm.php +++ b/api/models/profile/ChangeEmail/InitStateForm.php @@ -1,6 +1,7 @@ removeOldCode(); $activation = $this->createCode(); - $this->sendCode($activation); + + EmailHelper::changeEmailConfirmCurrent($activation); $transaction->commit(); } catch (Exception $e) { @@ -93,29 +94,6 @@ class InitStateForm extends ApiForm { $emailActivation->delete(); } - public function sendCode(EmailActivation $code) { - $mailer = Yii::$app->mailer; - $fromEmail = Yii::$app->params['fromEmail']; - if (!$fromEmail) { - throw new InvalidConfigException('Please specify fromEmail app in app params'); - } - - $acceptor = $code->account; - $message = $mailer->compose([ - 'html' => '@app/mails/current-email-confirmation-html', - 'text' => '@app/mails/current-email-confirmation-text', - ], [ - 'key' => $code->key, - ]) - ->setTo([$acceptor->email => $acceptor->username]) - ->setFrom([$fromEmail => 'Ely.by Accounts']) - ->setSubject('Ely.by Account change E-mail confirmation'); - - if (!$message->send()) { - throw new ErrorException('Unable send email with activation code.'); - } - } - /** * Возвращает E-mail активацию, которая использовалась внутри процесса для перехода на следующий шаг. * Метод предназначен для проверки, не слишком ли часто отправляются письма о смене E-mail. diff --git a/api/models/profile/ChangeEmail/NewEmailForm.php b/api/models/profile/ChangeEmail/NewEmailForm.php index 9f05948..907ac3c 100644 --- a/api/models/profile/ChangeEmail/NewEmailForm.php +++ b/api/models/profile/ChangeEmail/NewEmailForm.php @@ -1,6 +1,7 @@ delete(); $activation = $this->createCode(); - $this->sendCode($activation); + + EmailHelper::changeEmailConfirmNew($activation); $transaction->commit(); @@ -67,32 +68,6 @@ class NewEmailForm extends ApiForm { return $emailActivation; } - public function sendCode(EmailActivation $code) { - /** @var \yii\swiftmailer\Mailer $mailer */ - $mailer = Yii::$app->mailer; - $fromEmail = Yii::$app->params['fromEmail']; - if (!$fromEmail) { - throw new InvalidConfigException('Please specify fromEmail app in app params'); - } - - $acceptor = $code->account; - /** @var \yii\swiftmailer\Message $message */ - $message = $mailer->compose([ - 'html' => '@app/mails/new-email-confirmation-html', - 'text' => '@app/mails/new-email-confirmation-text', - ], [ - 'key' => $code->key, - 'account' => $acceptor, - ]) - ->setTo([$this->email => $acceptor->username]) - ->setFrom([$fromEmail => 'Ely.by Accounts']) - ->setSubject('Ely.by Account new E-mail confirmation'); - - if (!$message->send()) { - throw new ErrorException('Unable send email with activation code.'); - } - } - public function __construct(Account $account, array $config = []) { $this->account = $account; parent::__construct($config);