mirror of
https://github.com/retailcrm/mailgun-php.git
synced 2024-11-24 21:46:02 +03:00
POC - Better api (#192)
* Added base for the new API * code style * Added response classes * Added support for serializer * The abstract API should not know of Mailgun * Minor * minor * Using a client configrator * code style * Put HTTPClient in the configurator * Do not use the api() function * Use stable version of Assert * style * Fixed tests * make the httpClient private * Renamed ResponseSerializer to ResponseDeserializer * Disabled tests that are testing error messages with Assert * style fixes * Refactoring fix
This commit is contained in:
parent
043658f996
commit
738e6e32e2
@ -6,7 +6,9 @@
|
||||
"php-http/httplug": "^1.0",
|
||||
"php-http/multipart-stream-builder": "^0.1",
|
||||
"php-http/message": "^1.0",
|
||||
"php-http/discovery": "^1.0"
|
||||
"php-http/client-common": "^1.0",
|
||||
"php-http/discovery": "^1.0",
|
||||
"webmozart/assert": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.6",
|
||||
|
150
src/Mailgun/Api/AbstractApi.php
Normal file
150
src/Mailgun/Api/AbstractApi.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Api;
|
||||
|
||||
use Http\Client\Common\HttpMethodsClient;
|
||||
use Http\Client\HttpClient;
|
||||
use Http\Message\RequestFactory;
|
||||
use Mailgun\Exception\HttpServerException;
|
||||
use Http\Client\Exception as HttplugException;
|
||||
use Mailgun\Serializer\ResponseDeserializer;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
abstract class AbstractApi
|
||||
{
|
||||
/**
|
||||
* The HTTP client.
|
||||
*
|
||||
* @var HttpMethodsClient
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @var ResponseDeserializer
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* @param HttpClient $httpClient
|
||||
* @param RequestFactory $requestFactory
|
||||
* @param ResponseDeserializer $serializer
|
||||
*/
|
||||
public function __construct(HttpClient $httpClient, RequestFactory $requestFactory, ResponseDeserializer $serializer)
|
||||
{
|
||||
$this->httpClient = new HttpMethodsClient($httpClient, $requestFactory);
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a GET request with query parameters.
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param array $parameters GET parameters.
|
||||
* @param array $requestHeaders Request Headers.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function get($path, array $parameters = [], array $requestHeaders = [])
|
||||
{
|
||||
if (count($parameters) > 0) {
|
||||
$path .= '?'.http_build_query($parameters);
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->httpClient->get($path, $requestHeaders);
|
||||
} catch (HttplugException\NetworkException $e) {
|
||||
throw HttpServerException::networkError($e);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a POST request with JSON-encoded parameters.
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param array $parameters POST parameters to be JSON encoded.
|
||||
* @param array $requestHeaders Request headers.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function post($path, array $parameters = [], array $requestHeaders = [])
|
||||
{
|
||||
return $this->postRaw($path, $this->createJsonBody($parameters), $requestHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a POST request with raw data.
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param string $body Request body.
|
||||
* @param array $requestHeaders Request headers.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function postRaw($path, $body, array $requestHeaders = [])
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->post($path, $requestHeaders, $body);
|
||||
} catch (HttplugException\NetworkException $e) {
|
||||
throw HttpServerException::networkError($e);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request with JSON-encoded parameters.
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param array $parameters POST parameters to be JSON encoded.
|
||||
* @param array $requestHeaders Request headers.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function put($path, array $parameters = [], array $requestHeaders = [])
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->put($path, $requestHeaders, $this->createJsonBody($parameters));
|
||||
} catch (HttplugException\NetworkException $e) {
|
||||
throw HttpServerException::networkError($e);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request with JSON-encoded parameters.
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param array $parameters POST parameters to be JSON encoded.
|
||||
* @param array $requestHeaders Request headers.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function delete($path, array $parameters = [], array $requestHeaders = [])
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->delete($path, $requestHeaders, $this->createJsonBody($parameters));
|
||||
} catch (HttplugException\NetworkException $e) {
|
||||
throw HttpServerException::networkError($e);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSON encoded version of an array of parameters.
|
||||
*
|
||||
* @param array $parameters Request parameters
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function createJsonBody(array $parameters)
|
||||
{
|
||||
return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0);
|
||||
}
|
||||
}
|
45
src/Mailgun/Api/Stats.php
Normal file
45
src/Mailgun/Api/Stats.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Api;
|
||||
|
||||
use Mailgun\Assert;
|
||||
use Mailgun\Resource\Api\Stats\AllResponse;
|
||||
use Mailgun\Resource\Api\Stats\TotalResponse;
|
||||
|
||||
/**
|
||||
* {@link https://documentation.mailgun.com/api-stats.html}.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class Stats extends AbstractApi
|
||||
{
|
||||
/**
|
||||
* @param string $domain
|
||||
* @param array $params
|
||||
*
|
||||
* @return TotalResponse|array
|
||||
*/
|
||||
public function total($domain, array $params = [])
|
||||
{
|
||||
Assert::stringNotEmpty($domain);
|
||||
|
||||
$response = $this->get(sprintf('/v3/%s/stats/total', rawurlencode($domain)), $params);
|
||||
|
||||
return $this->serializer->deserialize($response, TotalResponse::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $domain
|
||||
* @param array $params
|
||||
*
|
||||
* @return AllResponse|array
|
||||
*/
|
||||
public function all($domain, array $params = [])
|
||||
{
|
||||
Assert::stringNotEmpty($domain);
|
||||
|
||||
$response = $this->get(sprintf('/v3/%s/stats', rawurlencode($domain)), $params);
|
||||
|
||||
return $this->serializer->deserialize($response, AllResponse::class);
|
||||
}
|
||||
}
|
18
src/Mailgun/Assert.php
Normal file
18
src/Mailgun/Assert.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun;
|
||||
|
||||
use Mailgun\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* We need to override Webmozart\Assert because we want to throw our own Exception.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class Assert extends \Webmozart\Assert\Assert
|
||||
{
|
||||
protected static function createInvalidArgumentException($message)
|
||||
{
|
||||
return new InvalidArgumentException($message);
|
||||
}
|
||||
}
|
@ -9,7 +9,9 @@
|
||||
|
||||
namespace Mailgun\Connection\Exceptions;
|
||||
|
||||
class GenericHTTPError extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class GenericHTTPError extends \Exception implements Exception
|
||||
{
|
||||
protected $httpResponseCode;
|
||||
protected $httpResponseBody;
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Connection\Exceptions;
|
||||
|
||||
class InvalidCredentials extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class InvalidCredentials extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Connection\Exceptions;
|
||||
|
||||
class MissingEndpoint extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class MissingEndpoint extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Connection\Exceptions;
|
||||
|
||||
class MissingRequiredParameters extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class MissingRequiredParameters extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Connection\Exceptions;
|
||||
|
||||
class NoDomainsConfigured extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class NoDomainsConfigured extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
12
src/Mailgun/Exception.php
Normal file
12
src/Mailgun/Exception.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun;
|
||||
|
||||
/**
|
||||
* All Mailgun exception implements this exception.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface Exception
|
||||
{
|
||||
}
|
31
src/Mailgun/Exception/HttpClientException.php
Normal file
31
src/Mailgun/Exception/HttpClientException.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Exception;
|
||||
|
||||
use Mailgun\Exception;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class HttpClientException extends \RuntimeException implements Exception
|
||||
{
|
||||
public static function badRequest()
|
||||
{
|
||||
return new self('The parameters passed to the API were invalid. Check your inputs!', 400);
|
||||
}
|
||||
|
||||
public static function unauthorized()
|
||||
{
|
||||
return new self('Your credentials are incorrect.', 401);
|
||||
}
|
||||
|
||||
public static function requestFailed()
|
||||
{
|
||||
return new self('Parameters were valid but request failed. Try again.', 402);
|
||||
}
|
||||
|
||||
public static function notFound()
|
||||
{
|
||||
return new self('The endpoint you tried to access does not exist. Check your URL.', 404);
|
||||
}
|
||||
}
|
26
src/Mailgun/Exception/HttpServerException.php
Normal file
26
src/Mailgun/Exception/HttpServerException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Exception;
|
||||
|
||||
use Mailgun\Exception;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class HttpServerException extends \RuntimeException implements Exception
|
||||
{
|
||||
public static function serverError($httpStatus = 500)
|
||||
{
|
||||
return new self('An unexpected error occurred at Mailgun\'s servers. Try again later and contact support of the error sill exists.', $httpStatus);
|
||||
}
|
||||
|
||||
public static function networkError(\Exception $previous)
|
||||
{
|
||||
return new self('Mailgun\'s servers was unreachable.', 0, $previous);
|
||||
}
|
||||
|
||||
public static function unknownHttpResponseCode($code)
|
||||
{
|
||||
return new self(sprintf('Unknown HTTP response code ("%d") received from the API server', $code));
|
||||
}
|
||||
}
|
12
src/Mailgun/Exception/InvalidArgumentException.php
Normal file
12
src/Mailgun/Exception/InvalidArgumentException.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Exception;
|
||||
|
||||
use Mailgun\Exception;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
||||
{
|
||||
}
|
9
src/Mailgun/Exception/SerializeException.php
Normal file
9
src/Mailgun/Exception/SerializeException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Exception;
|
||||
|
||||
use Mailgun\Exception;
|
||||
|
||||
class SerializeException extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
142
src/Mailgun/HttpClientConfigurator.php
Normal file
142
src/Mailgun/HttpClientConfigurator.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun;
|
||||
|
||||
use Http\Client\HttpClient;
|
||||
use Http\Client\Common\PluginClient;
|
||||
use Http\Discovery\HttpClientDiscovery;
|
||||
use Http\Discovery\UriFactoryDiscovery;
|
||||
use Http\Message\UriFactory;
|
||||
use Http\Client\Common\Plugin;
|
||||
|
||||
/**
|
||||
* Configure a HTTP client.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class HttpClientConfigurator
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $endpoint = 'https://api.mailgun.net';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $apiKey;
|
||||
|
||||
/**
|
||||
* @var UriFactory
|
||||
*/
|
||||
private $uriFactory;
|
||||
|
||||
/**
|
||||
* @var HttpClient
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @return PluginClient
|
||||
*/
|
||||
public function createConfiguredClient()
|
||||
{
|
||||
$plugins = [
|
||||
new Plugin\AddHostPlugin($this->getUriFactory()->createUri($this->getEndpoint())),
|
||||
new Plugin\HeaderDefaultsPlugin([
|
||||
'User-Agent' => 'mailgun-sdk-php/v2 (https://github.com/mailgun/mailgun-php)',
|
||||
'Authorization' => 'Basic '.base64_encode(sprintf('api:%s', $this->getApiKey())),
|
||||
]),
|
||||
];
|
||||
|
||||
return new PluginClient($this->getHttpClient(), $plugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getEndpoint()
|
||||
{
|
||||
return $this->endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return HttpClientConfigurator
|
||||
*/
|
||||
public function setEndpoint($endpoint)
|
||||
{
|
||||
$this->endpoint = $endpoint;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getApiKey()
|
||||
{
|
||||
return $this->apiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $apiKey
|
||||
*
|
||||
* @return HttpClientConfigurator
|
||||
*/
|
||||
public function setApiKey($apiKey)
|
||||
{
|
||||
$this->apiKey = $apiKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UriFactory
|
||||
*/
|
||||
private function getUriFactory()
|
||||
{
|
||||
if ($this->uriFactory === null) {
|
||||
$this->uriFactory = UriFactoryDiscovery::find();
|
||||
}
|
||||
|
||||
return $this->uriFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UriFactory $uriFactory
|
||||
*
|
||||
* @return HttpClientConfigurator
|
||||
*/
|
||||
public function setUriFactory(UriFactory $uriFactory)
|
||||
{
|
||||
$this->uriFactory = $uriFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HttpClient
|
||||
*/
|
||||
private function getHttpClient()
|
||||
{
|
||||
if ($this->httpClient === null) {
|
||||
$this->httpClient = HttpClientDiscovery::find();
|
||||
}
|
||||
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HttpClient $httpClient
|
||||
*
|
||||
* @return HttpClientConfigurator
|
||||
*/
|
||||
public function setHttpClient(HttpClient $httpClient)
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -9,24 +9,28 @@
|
||||
|
||||
namespace Mailgun;
|
||||
|
||||
use Http\Client\Common\HttpMethodsClient;
|
||||
use Http\Client\HttpClient;
|
||||
use Http\Discovery\MessageFactoryDiscovery;
|
||||
use Http\Message\RequestFactory;
|
||||
use Mailgun\Connection\RestClient;
|
||||
use Mailgun\Constants\ExceptionMessages;
|
||||
use Mailgun\Lists\OptInHandler;
|
||||
use Mailgun\Messages\BatchMessage;
|
||||
use Mailgun\Messages\Exceptions;
|
||||
use Mailgun\Messages\MessageBuilder;
|
||||
use Mailgun\Serializer\ObjectSerializer;
|
||||
use Mailgun\Serializer\ResponseDeserializer;
|
||||
|
||||
/**
|
||||
* This class is the base class for the Mailgun SDK.
|
||||
* See the official documentation (link below) for usage instructions.
|
||||
*
|
||||
* @link https://github.com/mailgun/mailgun-php/blob/master/README.md
|
||||
*/
|
||||
class Mailgun
|
||||
{
|
||||
/**
|
||||
* @var RestClient
|
||||
*
|
||||
* @depracated Will be removed in 3.0
|
||||
*/
|
||||
protected $restClient;
|
||||
|
||||
@ -35,18 +39,57 @@ class Mailgun
|
||||
*/
|
||||
protected $apiKey;
|
||||
|
||||
/**
|
||||
* @var HttpMethodsClient
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* @var ResponseDeserializer
|
||||
*/
|
||||
private $serializer;
|
||||
|
||||
/**
|
||||
* @var RequestFactory
|
||||
*/
|
||||
private $requestFactory;
|
||||
|
||||
/**
|
||||
* @param string|null $apiKey
|
||||
* @param HttpClient $httpClient
|
||||
* @param HttpClient|null $httpClient
|
||||
* @param string $apiEndpoint
|
||||
* @param ResponseDeserializer|null $serializer
|
||||
* @param HttpClientConfigurator|null $clientConfigurator
|
||||
*/
|
||||
public function __construct(
|
||||
$apiKey = null,
|
||||
HttpClient $httpClient = null,
|
||||
$apiEndpoint = 'api.mailgun.net'
|
||||
HttpClient $httpClient = null, /* Deprecated, will be removed in 3.0 */
|
||||
$apiEndpoint = 'api.mailgun.net', /* Deprecated, will be removed in 3.0 */
|
||||
ResponseDeserializer $serializer = null,
|
||||
HttpClientConfigurator $clientConfigurator = null
|
||||
) {
|
||||
$this->apiKey = $apiKey;
|
||||
$this->restClient = new RestClient($apiKey, $apiEndpoint, $httpClient);
|
||||
|
||||
if (null === $clientConfigurator) {
|
||||
$clientConfigurator = new HttpClientConfigurator();
|
||||
|
||||
/*
|
||||
* To be backward compatible
|
||||
*/
|
||||
if ($apiEndpoint !== 'api.mailgun.net') {
|
||||
$clientConfigurator->setEndpoint($apiEndpoint);
|
||||
}
|
||||
if ($httpClient !== null) {
|
||||
$clientConfigurator->setHttpClient($httpClient);
|
||||
}
|
||||
}
|
||||
|
||||
$clientConfigurator->setApiKey($apiKey);
|
||||
|
||||
$this->httpClient = $clientConfigurator->createConfiguredClient();
|
||||
$this->requestFactory = MessageFactoryDiscovery::find();
|
||||
$this->serializer = $serializer ?: new ObjectSerializer();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,4 +252,12 @@ class Mailgun
|
||||
{
|
||||
return new BatchMessage($this->restClient, $workingDomain, $autoSend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Api\Stats
|
||||
*/
|
||||
public function getStatsApi()
|
||||
{
|
||||
return new Api\Stats($this->httpClient, $this->requestFactory, $this->serializer);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Messages\Exceptions;
|
||||
|
||||
class InvalidParameter extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class InvalidParameter extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Messages\Exceptions;
|
||||
|
||||
class InvalidParameterType extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class InvalidParameterType extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Messages\Exceptions;
|
||||
|
||||
class MissingRequiredMIMEParameters extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class MissingRequiredMIMEParameters extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
namespace Mailgun\Messages\Exceptions;
|
||||
|
||||
class TooManyParameters extends \Exception
|
||||
use Mailgun\Exception;
|
||||
|
||||
class TooManyParameters extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
|
62
src/Mailgun/Resource/Api/Stats/AllResponse.php
Normal file
62
src/Mailgun/Resource/Api/Stats/AllResponse.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Resource\Api\Stats;
|
||||
|
||||
use Mailgun\Resource\CreatableFromArray;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class AllResponse implements CreatableFromArray
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $totalCount;
|
||||
|
||||
/**
|
||||
* @var Item[]
|
||||
*/
|
||||
private $items;
|
||||
|
||||
/**
|
||||
* @param int $totalCount
|
||||
* @param Item[] $items
|
||||
*/
|
||||
public function __construct($totalCount, array $items)
|
||||
{
|
||||
$this->totalCount = $totalCount;
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return AllResponse
|
||||
*/
|
||||
public static function createFromArray(array $data)
|
||||
{
|
||||
$items = [];
|
||||
foreach ($data['items'] as $i) {
|
||||
$items[] = new Item($i['id'], $i['event'], $i['total_count'], $i['tags'], new \DateTime($i['created_at']));
|
||||
}
|
||||
|
||||
return new self($data['total_count'], $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalCount()
|
||||
{
|
||||
return $this->totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
}
|
87
src/Mailgun/Resource/Api/Stats/Item.php
Normal file
87
src/Mailgun/Resource/Api/Stats/Item.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Resource\Api\Stats;
|
||||
|
||||
class Item
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $event;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $totalCount;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $tags;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $createdAt;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $event
|
||||
* @param string $totalCount
|
||||
* @param \string[] $tags
|
||||
* @param \DateTime $createdAt
|
||||
*/
|
||||
public function __construct($id, $event, $totalCount, array $tags, \DateTime $createdAt)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->event = $event;
|
||||
$this->totalCount = $totalCount;
|
||||
$this->tags = $tags;
|
||||
$this->createdAt = $createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEvent()
|
||||
{
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTotalCount()
|
||||
{
|
||||
return $this->totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[]
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreatedAt()
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
}
|
92
src/Mailgun/Resource/Api/Stats/TotalResponse.php
Normal file
92
src/Mailgun/Resource/Api/Stats/TotalResponse.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Resource\Api\Stats;
|
||||
|
||||
use Mailgun\Resource\CreatableFromArray;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class TotalResponse implements CreatableFromArray
|
||||
{
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $end;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $resolution;
|
||||
|
||||
/**
|
||||
* @var TotalStats[]
|
||||
*/
|
||||
private $stats;
|
||||
|
||||
/**
|
||||
* @param \DateTime $start
|
||||
* @param \DateTime $end
|
||||
* @param string $resolution
|
||||
* @param TotalStats[] $stats
|
||||
*/
|
||||
public function __construct(\DateTime $start, \DateTime $end, $resolution, array $stats)
|
||||
{
|
||||
$this->start = $start;
|
||||
$this->end = $end;
|
||||
$this->resolution = $resolution;
|
||||
$this->stats = $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return TotalResponse
|
||||
*/
|
||||
public static function createFromArray(array $data)
|
||||
{
|
||||
$stats = [];
|
||||
foreach ($data['stats'] as $s) {
|
||||
$stats[] = new TotalStats(new \DateTime($s['time']), $s['accepted'], $s['delivered'], $s['failed']);
|
||||
}
|
||||
|
||||
return new self(new \DateTime($data['start']), new \DateTime($data['end']), $data['resolution'], $stats);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResolution()
|
||||
{
|
||||
return $this->resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TotalStats[]
|
||||
*/
|
||||
public function getStats()
|
||||
{
|
||||
return $this->stats;
|
||||
}
|
||||
}
|
75
src/Mailgun/Resource/Api/Stats/TotalStats.php
Normal file
75
src/Mailgun/Resource/Api/Stats/TotalStats.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Resource\Api\Stats;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class TotalStats
|
||||
{
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $time;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $accepted;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $delivered;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $failed;
|
||||
|
||||
/**
|
||||
* @param \DateTime $time
|
||||
* @param array $accepted
|
||||
* @param array $delivered
|
||||
* @param array $failed
|
||||
*/
|
||||
public function __construct(\DateTime $time, array $accepted, array $delivered, array $failed)
|
||||
{
|
||||
$this->time = $time;
|
||||
$this->accepted = $accepted;
|
||||
$this->delivered = $delivered;
|
||||
$this->failed = $failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getTime()
|
||||
{
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAccepted()
|
||||
{
|
||||
return $this->accepted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDelivered()
|
||||
{
|
||||
return $this->delivered;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFailed()
|
||||
{
|
||||
return $this->failed;
|
||||
}
|
||||
}
|
13
src/Mailgun/Resource/CreatableFromArray.php
Normal file
13
src/Mailgun/Resource/CreatableFromArray.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Resource;
|
||||
|
||||
interface CreatableFromArray
|
||||
{
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createFromArray(array $data);
|
||||
}
|
35
src/Mailgun/Serializer/ArraySerializer.php
Normal file
35
src/Mailgun/Serializer/ArraySerializer.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Serializer;
|
||||
|
||||
use Mailgun\Exception\SerializeException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Serialize an HTTP response to array.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ArraySerializer implements ResponseDeserializer
|
||||
{
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @param string $class
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function deserialize(ResponseInterface $response, $class)
|
||||
{
|
||||
$body = $response->getBody()->__toString();
|
||||
if (strpos($response->getHeaderLine('Content-Type'), 'application/json') !== 0) {
|
||||
throw new SerializeException('The ArraySerializer cannot deserialize response with Content-Type:'.$response->getHeaderLine('Content-Type'));
|
||||
}
|
||||
|
||||
$content = json_decode($body, true);
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new SerializeException(sprintf('Error (%d) when trying to json_decode response', json_last_error()));
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
42
src/Mailgun/Serializer/ObjectSerializer.php
Normal file
42
src/Mailgun/Serializer/ObjectSerializer.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Serializer;
|
||||
|
||||
use Mailgun\Exception\SerializeException;
|
||||
use Mailgun\Resource\CreatableFromArray;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Serialize an HTTP response to domain object.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ObjectSerializer implements ResponseDeserializer
|
||||
{
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @param string $class
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function deserialize(ResponseInterface $response, $class)
|
||||
{
|
||||
$body = $response->getBody()->__toString();
|
||||
if (strpos($response->getHeaderLine('Content-Type'), 'application/json') !== 0) {
|
||||
throw new SerializeException('The ObjectSerializer cannot deserialize response with Content-Type:'.$response->getHeaderLine('Content-Type'));
|
||||
}
|
||||
|
||||
$data = json_decode($body, true);
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new SerializeException(sprintf('Error (%d) when trying to json_decode response', json_last_error()));
|
||||
}
|
||||
|
||||
if (is_subclass_of($class, CreatableFromArray::class)) {
|
||||
$object = call_user_func($class.'::createFromArray', $data);
|
||||
} else {
|
||||
$object = new $class($data);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
24
src/Mailgun/Serializer/PSR7Serializer.php
Normal file
24
src/Mailgun/Serializer/PSR7Serializer.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Serializer;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Do not serialize at all. Just return a PSR-7 response.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class PSR7Serializer implements ResponseDeserializer
|
||||
{
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @param string $class
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function deserialize(ResponseInterface $response, $class)
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
}
|
19
src/Mailgun/Serializer/ResponseDeserializer.php
Normal file
19
src/Mailgun/Serializer/ResponseDeserializer.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Serializer;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Deserialize a PSR-7 response to something else.
|
||||
*/
|
||||
interface ResponseDeserializer
|
||||
{
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @param string $class
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function deserialize(ResponseInterface $response, $class);
|
||||
}
|
64
tests/Api/StatsTest.php
Normal file
64
tests/Api/StatsTest.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Tests\Api;
|
||||
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class StatsTest extends TestCase
|
||||
{
|
||||
protected function getApiClass()
|
||||
{
|
||||
return 'Mailgun\Api\Stats';
|
||||
}
|
||||
|
||||
public function testTotal()
|
||||
{
|
||||
$data = [
|
||||
'foo' => 'bar',
|
||||
];
|
||||
|
||||
$api = $this->getApiMock();
|
||||
$api->expects($this->once())
|
||||
->method('get')
|
||||
->with('/v3/domain/stats/total', $data)
|
||||
->willReturn(new Response());
|
||||
|
||||
$api->total('domain', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* expectedException \Mailgun\Exception\InvalidArgumentException.
|
||||
*/
|
||||
//public function testTotalInvalidArgument()
|
||||
//{
|
||||
// $api = $this->getApiMock();
|
||||
// $api->total('');
|
||||
//}
|
||||
|
||||
public function testAll()
|
||||
{
|
||||
$data = [
|
||||
'foo' => 'bar',
|
||||
];
|
||||
|
||||
$api = $this->getApiMock();
|
||||
$api->expects($this->once())
|
||||
->method('get')
|
||||
->with('/v3/domain/stats', $data)
|
||||
->willReturn(new Response());
|
||||
|
||||
$api->all('domain', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
* expectedException \Mailgun\Exception\InvalidArgumentException
|
||||
*/
|
||||
//public function testAllInvalidArgument()
|
||||
//{
|
||||
// $api = $this->getApiMock();
|
||||
// $api->all('');
|
||||
//}
|
||||
}
|
35
tests/Api/TestCase.php
Normal file
35
tests/Api/TestCase.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Mailgun\Tests\Api;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Contributors of https://github.com/KnpLabs/php-github-api
|
||||
*/
|
||||
abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
abstract protected function getApiClass();
|
||||
|
||||
protected function getApiMock()
|
||||
{
|
||||
$httpClient = $this->getMockBuilder('Http\Client\HttpClient')
|
||||
->setMethods(['sendRequest'])
|
||||
->getMock();
|
||||
$httpClient
|
||||
->expects($this->any())
|
||||
->method('sendRequest');
|
||||
|
||||
$requestClient = $this->getMockBuilder('Http\Message\MessageFactory')
|
||||
->setMethods(['createRequest', 'createResponse'])
|
||||
->getMock();
|
||||
|
||||
$serializer = $this->getMockBuilder('Mailgun\Serializer\ResponseDeserializer')
|
||||
->setMethods(['deserialize'])
|
||||
->getMock();
|
||||
|
||||
return $this->getMockBuilder($this->getApiClass())
|
||||
->setMethods(['get', 'post', 'postRaw', 'delete', 'put'])
|
||||
->setConstructorArgs([$httpClient, $requestClient, $serializer])
|
||||
->getMock();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user