diff --git a/lib/Mailer/ElasticEmail.php b/lib/Mailer/ElasticEmail.php new file mode 100644 index 0000000000..f6206f6644 --- /dev/null +++ b/lib/Mailer/ElasticEmail.php @@ -0,0 +1,63 @@ +url = 'https://api.elasticemail.com/mailer/send'; + $this->api_key = $api_key; + $this->newsletter = $newsletter; + $this->subscribers = $subscribers; + $this->from_name = $from_name; + $this->from_email = $from_email; + } + + function send() { + $result = wp_remote_post( + $this->url, + $this->request() + ); + return preg_match('/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/', $result['body']); + } + + function getSubscribers() { + $subscribers = array_map(function ($subscriber) { + if(!isset($subscriber['email'])) return; + $first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : ''; + $last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : ''; + $subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']); + $subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber)); + return $subscriber; + }, $this->subscribers); + return implode(';', array_filter($subscribers)); + } + + function getBody() { + $parameters = array( + 'api_key' => $this->api_key, + 'from' => $this->from_email, + 'from_name' => $this->from_name, + 'to' => $this->getSubscribers(), + 'subject' => $this->newsletter['subject'], + 'body_html' => $this->newsletter['body'] + ); + + $body = array_map(function ($parameter, $value) { + return $parameter . '=' . urlencode($value); + }, array_keys($parameters), $parameters); + return implode('&', $body); + } + + function request() { + return array( + 'timeout' => 10, + 'httpversion' => '1.0', + 'method' => 'POST', + 'headers' => array( + 'Content-Type' => 'application/x-www-form-urlencoded' + ), + 'body' => $this->getBody() + ); + } +} \ No newline at end of file diff --git a/lib/Mailer/SendGrid.php b/lib/Mailer/SendGrid.php new file mode 100644 index 0000000000..3f1125284a --- /dev/null +++ b/lib/Mailer/SendGrid.php @@ -0,0 +1,64 @@ +url = 'https://api.sendgrid.com/api/mail.send.json'; + $this->api_key = $api_key; + $this->newsletter = $newsletter; + $this->subscribers = $subscribers; + $this->from_name = $from_name; + $this->from_email = $from_email; + } + + function send() { + if (!count($this->getSubscribers())) return false; + $result = wp_remote_post( + $this->url, + $this->request() + ); + $result = json_decode($result['body'], true); + return (isset($result['errors']) === false); + } + + function getSubscribers() { + $subscribers = array_map(function ($subscriber) { + if(!isset($subscriber['email'])) return; + $first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : ''; + $last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : ''; + $subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']); + $subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber)); + return $subscriber; + }, $this->subscribers); + return array_filter($subscribers); + } + + function getBody() { + $parameters = array( + 'from' => sprintf('%s <%s>', $this->from_name, $this->from_email), + 'x-smtpapi' => json_encode(array('to' => $this->getSubscribers())), + 'to' => $this->from_email, + 'subject' => $this->newsletter['subject'], + 'html' => $this->newsletter['body'] + ); + $body = array_map(function ($parameter, $value) { + return $parameter . '=' . urlencode($value); + }, array_keys($parameters), $parameters); + return implode('&', array_filter($body)); + } + + function request() { + return array( + 'timeout' => 10, + 'httpversion' => '1.1', + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $this->api_key, + 'Content-Type' => 'application/x-www-form-urlencoded' + ), + 'body' => $this->getBody() + ); + } +} \ No newline at end of file diff --git a/tests/unit/Mailer/ElasticEmailCest.php b/tests/unit/Mailer/ElasticEmailCest.php new file mode 100644 index 0000000000..eea41f6609 --- /dev/null +++ b/tests/unit/Mailer/ElasticEmailCest.php @@ -0,0 +1,115 @@ +data = array( + 'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa', + 'from_email' => 'vlad@mailpoet.com', + 'from_name' => 'Vlad', + 'newsletter' => array( + 'subject' => 'hi there!', + 'body' => 'this is a test message....' + ), + 'subscribers' => array( + array( + 'email' => 'johndoe@mailpoet.com', + 'last_name' => 'Smith' + ), + array( + 'email' => 'janesmith@mailpoet.com', + 'first_name' => 'Jane', + 'last_name' => 'Smith' + ), + array( + 'email' => 'someone@mailpoet.com', + ), + array() + ) + ); + + $this->mailer = new ElasticEmail( + $this->data['api_key'], + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + $this->data['subscribers']); + } + + function itCanGenerateSubscribers() { + $subscribers = explode(';', $this->mailer->getSubscribers()); + expect(count($subscribers))->equals(3); + + // test proper handling of spaces between first/last name + expect($subscribers[0])->equals( + $this->data['subscribers'][0]['last_name'] . ' <' . $this->data['subscribers'][0]['email'] . '>' + ); + expect($subscribers[1])->equals( + $this->data['subscribers'][1]['first_name'] . ' ' . + $this->data['subscribers'][1]['last_name'] . + ' <' . $this->data['subscribers'][1]['email'] . '>' + ); + } + + function itCanGenerateBody() { + $urlEncodedBody = $this->mailer->getBody(); + expect($urlEncodedBody) + ->contains(urlencode($this->data['newsletter']['subject'])); + + $body = explode('&', urldecode($urlEncodedBody)); + expect($body[0]) + ->equals("api_key=" . $this->data['api_key']); + expect($body[1]) + ->equals("from=" . $this->data['from_email']); + expect($body[2]) + ->equals("from_name=" . $this->data['from_name']); + expect($body[3]) + ->contains($this->data['subscribers'][0]['email']); + expect($body[4]) + ->equals("subject=" . $this->data['newsletter']['subject']); + expect($body[5]) + ->equals("body_html=" . $this->data['newsletter']['body']); + } + + function itCanCreateRequest() { + $request = $this->mailer->request(); + expect($request['timeout']) + ->equals(10); + expect($request['httpversion']) + ->equals('1.0'); + expect($request['method']) + ->equals('POST'); + expect($request['headers']['Content-Type']) + ->equals('application/x-www-form-urlencoded'); + expect($request['body']) + ->equals($this->mailer->getBody()); + } + + function itCannotSendWithoutSubscribers() { + $mailer = new ElasticEmail( + $this->data['api_key'], + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + array() + ); + expect($mailer->send())->equals(false); + } + + function itCannotSendWithoutProperAPIKey() { + $mailer = new ElasticEmail( + 'someapikey', + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + $this->data['subscribers'] + ); + expect($mailer->send())->equals(false); + } + + function itCanSend() { + $result = $this->mailer->send(); + expect($result)->equals(true); + } +} diff --git a/tests/unit/Mailer/SendGridCest.php b/tests/unit/Mailer/SendGridCest.php new file mode 100644 index 0000000000..c54b68119b --- /dev/null +++ b/tests/unit/Mailer/SendGridCest.php @@ -0,0 +1,112 @@ +data = array( + 'api_key' => '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', + 'from_email' => 'vlad@mailpoet.com', + 'from_name' => 'Vlad', + 'newsletter' => array( + 'subject' => 'hi there!', + 'body' => 'this is a test message....' + ), + 'subscribers' => array( + array( + 'email' => 'johndoe@mailpoet.com', + 'last_name' => 'Smith' + ), + array( + 'email' => 'janesmith@mailpoet.com', + 'first_name' => 'Jane', + 'last_name' => 'Smith' + ), + array( + 'email' => 'someone@mailpoet.com', + ), + array() + ) + ); + + $this->mailer = new SendGrid( + $this->data['api_key'], + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + $this->data['subscribers']); + } + + function itCanGenerateSubscribers() { + $subscribers = $this->mailer->getSubscribers(); + expect(count($subscribers))->equals(3); + // test proper handling of spaces between first/last name + expect($subscribers[0])->equals( + $this->data['subscribers'][0]['last_name'] . ' <' . $this->data['subscribers'][0]['email'] . '>' + ); + expect($subscribers[1])->equals( + $this->data['subscribers'][1]['first_name'] . ' ' . + $this->data['subscribers'][1]['last_name'] . + ' <' . $this->data['subscribers'][1]['email'] . '>' + ); + } + + function itCanGenerateBody() { + $urlEncodedBody = $this->mailer->getBody(); + expect($urlEncodedBody) + ->contains(urlencode($this->data['newsletter']['subject'])); + + $body = explode('&', urldecode($urlEncodedBody)); + expect($body[0]) + ->equals("from=" . sprintf('%s <%s>', $this->data['from_name'], $this->data['from_email'])); + expect($body[1]) + ->contains($this->data['subscribers'][0]['email']); + expect($body[2]) + ->equals("to=" . $this->data['from_email']); + expect($body[3]) + ->equals("subject=" . $this->data['newsletter']['subject']); + expect($body[4]) + ->equals("html=" . $this->data['newsletter']['body']); + } + + function itCanCreateRequest() { + $request = $this->mailer->request(); + expect($request['timeout']) + ->equals(10); + expect($request['httpversion']) + ->equals('1.1'); + expect($request['method']) + ->equals('POST'); + expect($request['headers']['Content-Type']) + ->equals('application/x-www-form-urlencoded'); + expect($request['body']) + ->equals($this->mailer->getBody()); + } + + function itCannotSendWithoutSubscribers() { + $mailer = new SendGrid( + $this->data['api_key'], + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + array() + ); + expect($mailer->send())->equals(false); + } + + function itCannotSendWithoutProperAPIKey() { + $mailer = new SendGrid( + 'someapikey', + $this->data['from_email'], + $this->data['from_name'], + $this->data['newsletter'], + $this->data['subscribers'] + ); + expect($mailer->send())->equals(false); + } + + function itCanSend() { + $result = $this->mailer->send(); + expect($result)->equals(true); + } +}