Skip to content

Commit

Permalink
Merge pull request #16 from mirko-bukilic/master
Browse files Browse the repository at this point in the history
Added Mailgun REST API functionality
  • Loading branch information
ppavlovic committed Jun 10, 2022
2 parents 7adc7a2 + 5deaab8 commit 685d90d
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/Client/MailgunCurlHttpClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace G4\Mailer\Client;

class MailgunCurlHttpClient
{
const API = 'api:';

/**
* @var resource
*/
private $curl;

/**
* Send POST curl http request to provided url with provided params and headers
*
* @param array $params
* @param array $headers
* @param string $url
* @param string $token
*
* @return array
*
* @throws \RuntimeException
*/
public function post(array $params, $url, $token)
{
$this->init();

curl_setopt_array($this->curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $params,
CURLOPT_USERPWD => self::API . $token,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_HEADER => false
]);

$result = $this->execute();
$error = $this->error();
$this->close();

if ($error) {
throw new \RuntimeException(sprintf("cURL Error #: %s\n", $error));
}

$response = json_decode($result, true);

if (!$response) {
throw new \RuntimeException(sprintf('Empty response from %s', $url));
}

return $response;
}

/**
* @return resource
*/
private function init()
{
$this->curl = curl_init();
}

/**
* @return void
*/
private function close()
{
if ($this->curl) {
curl_close($this->curl);
}
}

/**
* @return bool|string
*/
private function execute()
{
return curl_exec($this->curl);
}

/**
* @return string
*/
private function error()
{
return curl_error($this->curl);
}
}
11 changes: 11 additions & 0 deletions src/Exception/MailgunMailNotSentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace G4\Mailer\Exception;

class MailgunMailNotSentException extends EmailNotSentException
{
public function __construct($message, $code = 0, \Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
2 changes: 2 additions & 0 deletions src/Mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace G4\Mailer;

use G4\Mailer\Transport\Amazon\AmazonSes;
use G4\Mailer\Transport\Mailgun\Rest\Mailgun;
use G4\Mailer\Transport\Smtp\Smtp;
use G4\Mailer\Transport\MailerQ\Rest\MailerQ;
use G4\Mailer\Transport\TransportInterface;
Expand Down Expand Up @@ -34,6 +35,7 @@ public static function factory($options)
case 'smtp'; $transport = new Smtp($options); break;
case 'amazon_ses'; $transport = new AmazonSes($options); break;
case 'mailerq_rest'; $transport = new MailerQ($options); break;
case 'mailgun_rest'; $transport = new Mailgun($options); break;
default:
throw new \Exception("Mail delivery not defined");
}
Expand Down
59 changes: 59 additions & 0 deletions src/Message/Mailgun/Rest/Message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace G4\Mailer\Message\Mailgun\Rest;

class Message
{
/**
* @var array
*/
private $body;

/**
* @var string
*/
private $url;

/**
* @var string
*/
private $token;

/**
* Message constructor.
*
* @param array $body
* @param string $url
* @param string $token
*/
public function __construct(array $body, $url, $token)
{
$this->body = $body;
$this->url = $url;
$this->token = $token;
}

/**
* @return array
*/
public function getBody()
{
return $this->body;
}

/**
* @return string
*/
public function getUrl()
{
return $this->url;
}

/**
* @return string
*/
public function getToken()
{
return $this->token;
}
}
26 changes: 26 additions & 0 deletions src/Message/Mailgun/Rest/MessageFacade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace G4\Mailer\Message\Mailgun\Rest;

class MessageFacade
{
/**
* @param \G4\Mailer\Message $message
* @param array $options
* @return Message
*/
public static function convert(\G4\Mailer\Message $message, array $options)
{
$body = [
'from' => $message->getFrom(),
'to' => is_array($message->getTo()) ? $message->getTo()[0] : $message->getTo(),
'subject' => $message->getSubject(),
'text' => $message->getTextBody()
];

$url = $options['url'];
$token = $options['token'];

return new Message($body, $url, $token);
}
}
48 changes: 48 additions & 0 deletions src/Transport/Mailgun/Rest/Mailgun.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace G4\Mailer\Transport\Mailgun\Rest;

use G4\Mailer\Client\MailgunCurlHttpClient;
use G4\Mailer\Exception\MailgunMailNotSentException;
use G4\Mailer\Message\Mailgun\Rest\MessageFacade;
use G4\Mailer\Transport\TransportInterface;

class Mailgun implements TransportInterface
{
private $options;

public function __construct($options)
{
$this->setOptions($options);
}

public function send(\G4\Mailer\Message $message)
{
try {
$mailgunMessage = MessageFacade::convert($message, $this->options);

(new MailgunCurlHttpClient())->post(
$mailgunMessage->getBody(),
$mailgunMessage->getUrl(),
$mailgunMessage->getToken()
);
} catch (\Exception $exception) {
if ($exception->getMessage() !== sprintf('Empty response from %s', $this->options['url'])) {
throw new MailgunMailNotSentException(sprintf('Email not sent. Reason: %s', $exception->getMessage()), $exception->getCode());
}
}
}

private function setOptions($options)
{
if (!isset($options['url'])) {
throw new \InvalidArgumentException('url not defined');
}

if (!isset($options['token'])) {
throw new \InvalidArgumentException('token not defined');
}

$this->options = $options;
}
}

0 comments on commit 685d90d

Please sign in to comment.