Bez popisu

AuthorizedEmailsController.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. namespace MailPoet\Services;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Entities\NewsletterEntity;
  5. use MailPoet\Mailer\Mailer;
  6. use MailPoet\Mailer\MailerError;
  7. use MailPoet\Mailer\MailerLog;
  8. use MailPoet\Models\Newsletter;
  9. use MailPoet\Newsletter\NewslettersRepository;
  10. use MailPoet\Settings\SettingsController;
  11. class AuthorizedEmailsController {
  12. const AUTHORIZED_EMAIL_ADDRESSES_ERROR_SETTING = 'authorized_emails_addresses_check';
  13. /** @var Bridge */
  14. private $bridge;
  15. /** @var SettingsController */
  16. private $settings;
  17. /** @var NewslettersRepository */
  18. private $newslettersRepository;
  19. private $automaticEmailTypes = [
  20. Newsletter::TYPE_WELCOME,
  21. Newsletter::TYPE_NOTIFICATION,
  22. Newsletter::TYPE_AUTOMATIC,
  23. ];
  24. public function __construct(
  25. SettingsController $settingsController,
  26. Bridge $bridge,
  27. NewslettersRepository $newslettersRepository
  28. ) {
  29. $this->settings = $settingsController;
  30. $this->bridge = $bridge;
  31. $this->newslettersRepository = $newslettersRepository;
  32. }
  33. public function setFromEmailAddress(string $address) {
  34. $authorizedEmails = array_map('strtolower', $this->bridge->getAuthorizedEmailAddresses() ?: []);
  35. $isAuthorized = $this->validateAuthorizedEmail($authorizedEmails, $address);
  36. if (!$isAuthorized) {
  37. throw new \InvalidArgumentException("Email address '$address' is not authorized");
  38. }
  39. // update FROM address in settings & all scheduled and active emails
  40. $this->settings->set('sender.address', $address);
  41. $result = $this->validateAddressesInScheduledAndAutomaticEmails($authorizedEmails);
  42. foreach ($result['invalid_senders_in_newsletters'] ?? [] as $item) {
  43. $newsletter = $this->newslettersRepository->findOneById((int)$item['newsletter_id']);
  44. if ($newsletter) {
  45. $newsletter->setSenderAddress($address);
  46. }
  47. }
  48. $this->newslettersRepository->flush();
  49. $this->settings->set(self::AUTHORIZED_EMAIL_ADDRESSES_ERROR_SETTING, null);
  50. }
  51. public function checkAuthorizedEmailAddresses() {
  52. if (!Bridge::isMPSendingServiceEnabled()) {
  53. $this->settings->set(self::AUTHORIZED_EMAIL_ADDRESSES_ERROR_SETTING, null);
  54. $this->updateMailerLog();
  55. return;
  56. }
  57. $authorizedEmails = $this->bridge->getAuthorizedEmailAddresses();
  58. // Keep previous check result for an invalid response from API
  59. if ($authorizedEmails === false) {
  60. return;
  61. }
  62. $authorizedEmails = array_map('strtolower', $authorizedEmails);
  63. $result = [];
  64. $result = $this->validateAddressesInSettings($authorizedEmails, $result);
  65. $result = $this->validateAddressesInScheduledAndAutomaticEmails($authorizedEmails, $result);
  66. $this->settings->set(self::AUTHORIZED_EMAIL_ADDRESSES_ERROR_SETTING, $result ?: null);
  67. $this->updateMailerLog($result);
  68. }
  69. public function onSettingsSave($settings) {
  70. $senderAddressSet = !empty($settings['sender']['address']);
  71. $mailpoetSendingMethodSet = ($settings[Mailer::MAILER_CONFIG_SETTING_NAME]['method'] ?? null) === Mailer::METHOD_MAILPOET;
  72. if ($senderAddressSet || $mailpoetSendingMethodSet) {
  73. $this->checkAuthorizedEmailAddresses();
  74. }
  75. }
  76. public function onNewsletterSenderAddressUpdate(NewsletterEntity $newsletter, string $oldSenderAddress = null) {
  77. if ($newsletter->getSenderAddress() === $oldSenderAddress) {
  78. return;
  79. }
  80. if ($newsletter->getType() === NewsletterEntity::TYPE_STANDARD && $newsletter->getStatus() === NewsletterEntity::STATUS_SCHEDULED) {
  81. $this->checkAuthorizedEmailAddresses();
  82. }
  83. if (in_array($newsletter->getType(), $this->automaticEmailTypes, true) && $newsletter->getStatus() === Newsletter::STATUS_ACTIVE) {
  84. $this->checkAuthorizedEmailAddresses();
  85. }
  86. }
  87. private function validateAddressesInSettings($authorizedEmails, $result = []) {
  88. $defaultSenderAddress = $this->settings->get('sender.address');
  89. if (!$this->validateAuthorizedEmail($authorizedEmails, $defaultSenderAddress)) {
  90. $result['invalid_sender_address'] = $defaultSenderAddress;
  91. }
  92. return $result;
  93. }
  94. private function validateAddressesInScheduledAndAutomaticEmails($authorizedEmails, $result = []) {
  95. $condittion = sprintf(
  96. "(`type` = '%s' AND `status` = '%s') OR (`type` IN ('%s') AND `status` = '%s')",
  97. Newsletter::TYPE_STANDARD,
  98. Newsletter::STATUS_SCHEDULED,
  99. implode("', '", $this->automaticEmailTypes),
  100. Newsletter::STATUS_ACTIVE
  101. );
  102. $newsletters = Newsletter::whereRaw($condittion)->findMany();
  103. $invalidSendersInNewsletters = [];
  104. foreach ($newsletters as $newsletter) {
  105. if ($this->validateAuthorizedEmail($authorizedEmails, $newsletter->senderAddress)) {
  106. continue;
  107. }
  108. $invalidSendersInNewsletters[] = [
  109. 'newsletter_id' => $newsletter->id,
  110. 'subject' => $newsletter->subject,
  111. 'sender_address' => $newsletter->senderAddress,
  112. ];
  113. }
  114. if (!count($invalidSendersInNewsletters)) {
  115. return $result;
  116. }
  117. $result['invalid_senders_in_newsletters'] = $invalidSendersInNewsletters;
  118. return $result;
  119. }
  120. /**
  121. * @param array|null $error
  122. */
  123. private function updateMailerLog(array $error = null) {
  124. if ($error) {
  125. return;
  126. }
  127. $mailerLogError = MailerLog::getError();
  128. if ($mailerLogError && $mailerLogError['operation'] === MailerError::OPERATION_AUTHORIZATION) {
  129. MailerLog::resumeSending();
  130. }
  131. }
  132. private function validateAuthorizedEmail($authorizedEmails, $email) {
  133. return in_array(strtolower($email), $authorizedEmails, true);
  134. }
  135. }