diff --git a/mailpoet/lib/DI/ContainerConfigurator.php b/mailpoet/lib/DI/ContainerConfigurator.php index e716ff6b0f..fd9b0975c2 100644 --- a/mailpoet/lib/DI/ContainerConfigurator.php +++ b/mailpoet/lib/DI/ContainerConfigurator.php @@ -278,6 +278,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\Mailer\WordPress\WordpressMailerReplacer::class); $container->autowire(\MailPoet\Mailer\Methods\Common\BlacklistCheck::class); $container->autowire(\MailPoet\Mailer\MetaInfo::class); + $container->autowire(\MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper::class)->setPublic(true); // Subscribers $container->autowire(\MailPoet\Subscribers\NewSubscriberNotificationMailer::class)->setPublic(true); $container->autowire(\MailPoet\Subscribers\ConfirmationEmailMailer::class)->setPublic(true); diff --git a/mailpoet/lib/Mailer/Mailer.php b/mailpoet/lib/Mailer/Mailer.php index 24ff8f2e81..c4191bc07a 100644 --- a/mailpoet/lib/Mailer/Mailer.php +++ b/mailpoet/lib/Mailer/Mailer.php @@ -92,7 +92,7 @@ class Mailer { $this->mailerConfig['mailpoet_api_key'], $this->sender, $this->replyTo, - new MailPoetMapper(), + ContainerWrapper::getInstance()->get(MailPoetMapper::class), ContainerWrapper::getInstance()->get(AuthorizedEmailsController::class) ); break; diff --git a/mailpoet/lib/Mailer/MailerError.php b/mailpoet/lib/Mailer/MailerError.php index 9345a6f5bb..6a64109763 100644 --- a/mailpoet/lib/Mailer/MailerError.php +++ b/mailpoet/lib/Mailer/MailerError.php @@ -9,6 +9,7 @@ class MailerError { const OPERATION_SEND = 'send'; const OPERATION_AUTHORIZATION = 'authorization'; const OPERATION_INSUFFICIENT_PRIVILEGES = 'insufficient_privileges'; + const OPERATION_EMAIL_LIMIT_REACHED = 'email_limit_reached'; const LEVEL_HARD = 'hard'; const LEVEL_SOFT = 'soft'; @@ -16,6 +17,7 @@ class MailerError { const MESSAGE_EMAIL_FORBIDDEN_ACTION = 'Key is valid, but the action is forbidden'; const MESSAGE_EMAIL_INSUFFICIENT_PRIVILEGES = 'Insufficient privileges'; const MESSAGE_EMAIL_NOT_AUTHORIZED = 'The email address is not authorized'; + const MESSAGE_EMAIL_VOLUME_LIMIT_REACHED = 'Email volume limit reached'; /** @var string */ private $operation; diff --git a/mailpoet/lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php b/mailpoet/lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php index 5e10b4073c..615ba66c81 100644 --- a/mailpoet/lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php +++ b/mailpoet/lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php @@ -3,13 +3,16 @@ namespace MailPoet\Mailer\Methods\ErrorMappers; use InvalidArgumentException; +use MailPoet\Config\ServicesChecker; use MailPoet\Mailer\Mailer; use MailPoet\Mailer\MailerError; use MailPoet\Mailer\SubscriberError; use MailPoet\Services\Bridge\API; use MailPoet\Util\Helpers; +use MailPoet\Util\License\Features\Subscribers as SubscribersFeature; use MailPoet\Util\Notices\UnauthorizedEmailNotice; use MailPoet\WP\Functions as WPFunctions; +use MailPoetVendor\Carbon\Carbon; class MailPoetMapper { use BlacklistErrorMapperTrait; @@ -19,6 +22,25 @@ class MailPoetMapper { const TEMPORARY_UNAVAILABLE_RETRY_INTERVAL = 300; // seconds + /** @var ServicesChecker */ + private $servicesChecker; + + /** @var SubscribersFeature */ + private $subscribersFeature; + + /** @var WPFunctions */ + private $wp; + + public function __construct( + ServicesChecker $servicesChecker, + SubscribersFeature $subscribers, + WPFunctions $wp + ) { + $this->servicesChecker = $servicesChecker; + $this->subscribersFeature = $subscribers; + $this->wp = $wp; + } + public function getInvalidApiKeyError() { return new MailerError( MailerError::OPERATION_SEND, @@ -60,6 +82,9 @@ class MailPoetMapper { if ($result['message'] === MailerError::MESSAGE_EMAIL_INSUFFICIENT_PRIVILEGES) { $operation = MailerError::OPERATION_INSUFFICIENT_PRIVILEGES; $message = $this->getInsufficientPrivilegesMessage(); + } elseif ($result['message'] === MailerError::MESSAGE_EMAIL_VOLUME_LIMIT_REACHED) { + $operation = MailerError::OPERATION_EMAIL_LIMIT_REACHED; + $message = $this->getEmailVolumeLimitReachedMessage(); } elseif ($result['message'] === MailerError::MESSAGE_EMAIL_NOT_AUTHORIZED) { $operation = MailerError::OPERATION_AUTHORIZATION; $message = $this->getUnauthorizedEmailMessage($sender); @@ -96,7 +121,7 @@ class MailPoetMapper { private function getUnauthorizedEmailMessage($sender) { $email = $sender ? $sender['from_email'] : __('Unknown address', 'mailpoet'); $validationError = ['invalid_sender_address' => $email]; - $notice = new UnauthorizedEmailNotice(WPFunctions::get(), null); + $notice = new UnauthorizedEmailNotice($this->wp, null); $message = $notice->getMessage($validationError); return $message; } @@ -148,4 +173,25 @@ class MailPoetMapper { return "{$message}
"; } + + private function getEmailVolumeLimitReachedMessage(): string { + $partialApiKey = $this->servicesChecker->generatePartialApiKey(); + $emailVolumeLimit = $this->subscribersFeature->getEmailVolumeLimit(); + $date = Carbon::now()->startOfMonth()->addMonth(); + $message = sprintf( + __('You have sent more emails this month than your MailPoet plan includes (%s), and sending has been temporarily paused. To continue sending with MailPoet Sending Service please [link]upgrade your plan[/link], or wait until sending is automatically resumed on %s.', 'mailpoet'), + $emailVolumeLimit, + $this->wp->dateI18n(get_option('date_format'), $date->getTimestamp()) + ); + $message = Helpers::replaceLinkTags( + $message, + "https://account.mailpoet.com/orders/upgrade/{$partialApiKey}", + [ + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ] + ); + + return "{$message}
"; + } } diff --git a/mailpoet/lib/Util/License/Features/Subscribers.php b/mailpoet/lib/Util/License/Features/Subscribers.php index 5c8137c497..2213bdee0d 100644 --- a/mailpoet/lib/Util/License/Features/Subscribers.php +++ b/mailpoet/lib/Util/License/Features/Subscribers.php @@ -15,6 +15,7 @@ class Subscribers { const MSS_SUPPORT_SETTING_KEY = 'mta.mailpoet_api_key_state.data.support_tier'; const PREMIUM_KEY_STATE = 'premium.premium_key_state.state'; const PREMIUM_SUBSCRIBERS_LIMIT_SETTING_KEY = 'premium.premium_key_state.data.site_active_subscriber_limit'; + const PREMIUM_EMAIL_VOLUME_LIMIT_SETTING_KEY = 'premium.premium_key_state.data.email_volume_limit'; const PREMIUM_SUPPORT_SETTING_KEY = 'premium.premium_key_state.data.support_tier'; /** @var SettingsController */ @@ -62,6 +63,10 @@ class Subscribers { return false; } + public function getEmailVolumeLimit(): int { + return (int)$this->settings->get(self::PREMIUM_EMAIL_VOLUME_LIMIT_SETTING_KEY); + } + private function hasValidMssKey() { $state = $this->settings->get(self::MSS_KEY_STATE); return $state === Bridge::KEY_VALID || $state === Bridge::KEY_EXPIRING;