<?php namespace MailPoet\Mailer\Methods; if (!defined('ABSPATH')) exit; use MailPoet\Config\ServicesChecker; use MailPoet\Mailer\Mailer; use MailPoet\Mailer\MailerError; use MailPoet\Mailer\Methods\Common\BlacklistCheck; use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper; use MailPoet\Services\AuthorizedEmailsController; use MailPoet\Services\Bridge; use MailPoet\Services\Bridge\API; class MailPoet implements MailerMethod { public $api; public $sender; public $replyTo; public $servicesChecker; /** @var AuthorizedEmailsController */ private $authorizedEmailsController; /** @var MailPoetMapper */ private $errorMapper; /** @var BlacklistCheck */ private $blacklist; public function __construct( $apiKey, $sender, $replyTo, MailPoetMapper $errorMapper, AuthorizedEmailsController $authorizedEmailsController ) { $this->api = new API($apiKey); $this->sender = $sender; $this->replyTo = $replyTo; $this->servicesChecker = new ServicesChecker(); $this->errorMapper = $errorMapper; $this->authorizedEmailsController = $authorizedEmailsController; $this->blacklist = new BlacklistCheck(); } public function send($newsletter, $subscriber, $extraParams = []): array { if ($this->servicesChecker->isMailPoetAPIKeyValid() === false) { return Mailer::formatMailerErrorResult($this->errorMapper->getInvalidApiKeyError()); } $subscribersForBlacklistCheck = is_array($subscriber) ? $subscriber : [$subscriber]; foreach ($subscribersForBlacklistCheck as $sub) { if ($this->blacklist->isBlacklisted($sub)) { $error = $this->errorMapper->getBlacklistError($sub); return Mailer::formatMailerErrorResult($error); } } $messageBody = $this->getBody($newsletter, $subscriber, $extraParams); $result = $this->api->sendMessages($messageBody); switch ($result['status']) { case API::SENDING_STATUS_CONNECTION_ERROR: $error = $this->errorMapper->getConnectionError($result['message']); return Mailer::formatMailerErrorResult($error); case API::SENDING_STATUS_SEND_ERROR: $error = $this->processSendError($result, $subscriber, $newsletter); return Mailer::formatMailerErrorResult($error); case API::SENDING_STATUS_OK: default: return Mailer::formatMailerSendSuccessResult(); } } public function processSendError($result, $subscriber, $newsletter) { if (!empty($result['code']) && $result['code'] === API::RESPONSE_CODE_KEY_INVALID) { Bridge::invalidateKey(); } elseif ( !empty($result['code']) && $result['code'] === API::RESPONSE_CODE_CAN_NOT_SEND && $result['message'] === MailerError::MESSAGE_EMAIL_NOT_AUTHORIZED ) { $this->authorizedEmailsController->checkAuthorizedEmailAddresses(); } return $this->errorMapper->getErrorForResult($result, $subscriber, $this->sender, $newsletter); } public function processSubscriber($subscriber) { preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData); if (!isset($subscriberData['email'])) { $subscriberData = [ 'email' => $subscriber, ]; } return [ 'email' => $subscriberData['email'], 'name' => (isset($subscriberData['name'])) ? $subscriberData['name'] : '', ]; } public function getBody($newsletter, $subscriber, $extraParams = []) { if (is_array($newsletter) && is_array($subscriber)) { $body = []; for ($record = 0; $record < count($newsletter); $record++) { $body[] = $this->composeBody( $newsletter[$record], $this->processSubscriber($subscriber[$record]), (!empty($extraParams['unsubscribe_url'][$record])) ? $extraParams['unsubscribe_url'][$record] : false, (!empty($extraParams['meta'][$record])) ? $extraParams['meta'][$record] : false ); } } else { $body[] = $this->composeBody( $newsletter, $this->processSubscriber($subscriber), (!empty($extraParams['unsubscribe_url'])) ? $extraParams['unsubscribe_url'] : false, (!empty($extraParams['meta'])) ? $extraParams['meta'] : false ); } return $body; } private function composeBody($newsletter, $subscriber, $unsubscribeUrl, $meta): array { $body = [ 'to' => ([ 'address' => $subscriber['email'], 'name' => $subscriber['name'], ]), 'from' => ([ 'address' => $this->sender['from_email'], 'name' => $this->sender['from_name'], ]), 'reply_to' => ([ 'address' => $this->replyTo['reply_to_email'], ]), 'subject' => $newsletter['subject'], ]; if (!empty($this->replyTo['reply_to_name'])) { $body['reply_to']['name'] = $this->replyTo['reply_to_name']; } if (!empty($newsletter['body']['html'])) { $body['html'] = $newsletter['body']['html']; } if (!empty($newsletter['body']['text'])) { $body['text'] = $newsletter['body']['text']; } if ($unsubscribeUrl) { $body['list_unsubscribe'] = $unsubscribeUrl; } if ($meta) { $body['meta'] = $meta; } return $body; } }