diff options
author | Avi Goldman <avrahamymgoldman@gmail.com> | 2016-06-10 10:15:49 -0400 |
---|---|---|
committer | Avi Goldman <avrahamymgoldman@gmail.com> | 2016-06-10 10:15:49 -0400 |
commit | 425bc01d8b2915f114032777e03046cdd5884453 (patch) | |
tree | a0b96315484e112272c4d53b9805b438a5685e9d /lib/SparkPost | |
parent | 45657aeff2eabb9974676471f2924eeed1b4fb29 (diff) | |
download | php-sparkpost-425bc01d8b2915f114032777e03046cdd5884453.zip php-sparkpost-425bc01d8b2915f114032777e03046cdd5884453.tar.gz php-sparkpost-425bc01d8b2915f114032777e03046cdd5884453.tar.bz2 |
FAD-3148 added custom promise class and custom response class. Did good things to SparkPost class
Diffstat (limited to 'lib/SparkPost')
-rw-r--r-- | lib/SparkPost/APIResource.php | 265 | ||||
-rw-r--r-- | lib/SparkPost/APIResponseException.php | 62 | ||||
-rw-r--r-- | lib/SparkPost/MessageEvents.php | 64 | ||||
-rw-r--r-- | lib/SparkPost/Promise.php | 45 | ||||
-rw-r--r-- | lib/SparkPost/Response.php | 55 | ||||
-rw-r--r-- | lib/SparkPost/SparkPost.php | 27 | ||||
-rw-r--r-- | lib/SparkPost/Transmission.php | 136 |
7 files changed, 118 insertions, 536 deletions
diff --git a/lib/SparkPost/APIResource.php b/lib/SparkPost/APIResource.php deleted file mode 100644 index 36b03a8..0000000 --- a/lib/SparkPost/APIResource.php +++ /dev/null @@ -1,265 +0,0 @@ -<?php - -namespace SparkPost; - -/** - * SDK interface for managing SparkPost API endpoints. - */ -class APIResource -{ - /** - * name of the API endpoint, mainly used for URL construction. - * This is public to provide an interface. - * - * @var string - */ - public $endpoint; - - /** - * Mapping for values passed into the send method to the values needed for the respective API. - * - * @var array - */ - protected static $parameterMappings = []; - - /** - * Sets up default structure and default values for the model that is acceptable by the API. - * - * @var array - */ - protected static $structure = []; - - /** - * SparkPost reference for httpAdapters and configs. - */ - protected $sparkpost; - - /** - * Initializes config and httpAdapter for use later. - * - * @param $sparkpost \SparkPost\SparkPost provides api configuration information - */ - public function __construct(SparkPost $sparkpost) - { - $this->sparkpost = $sparkpost; - } - - /** - * Private Method helper to reference parameter mappings and set the right value for the right parameter. - * - * @param array $model (pass by reference) the set of values to map - * @param string $mapKey a dot syntax path determining which value to set - * @param mixed $value value for the given path - */ - protected function setMappedValue(&$model, $mapKey, $value) - { - //get mapping - if (empty(static::$parameterMappings)) { - // if parameterMappings is empty we can assume that no wrapper is defined - // for the current endpoint and we will use the mapKey to define the mappings directly - $mapPath = $mapKey; - } elseif (array_key_exists($mapKey, static::$parameterMappings)) { - // use only defined parameter mappings to construct $model - $mapPath = static::$parameterMappings[$mapKey]; - } else { - return; - } - - $path = explode('.', $mapPath); - $temp = &$model; - foreach ($path as $key) { - if (!isset($temp[$key])) { - $temp[$key] = null; - } - $temp = &$temp[$key]; - } - $temp = $value; - } - - /** - * maps values from the passed in model to those needed for the request. - * - * @param array $requestConfig the passed in model - * @param array $model the set of defaults - * - * @return array A model ready for the body of a request - */ - protected function buildRequestModel(array $requestConfig, array $model = []) - { - foreach ($requestConfig as $key => $value) { - $this->setMappedValue($model, $key, $value); - } - - return $model; - } - - /** - * posts to the api with a supplied body. - * - * @param array $body post body for the request - * - * @return array Result of the request - */ - public function create(array $body = []) - { - return $this->callResource('post', null, ['body' => $body]); - } - - /** - * Makes a put request to the api with a supplied body. - * - * @param $resourcePath - * @param array $body Put body for the request - * - * @return array Result of the request - * - * @throws APIResponseException - */ - public function update($resourcePath, array $body = []) - { - return $this->callResource('put', $resourcePath, ['body' => $body]); - } - - /** - * Wrapper method for issuing GET request to current API endpoint. - * - * @param string $resourcePath (optional) string resource path of specific resource - * @param array $query (optional) query string parameters - * - * @return array Result of the request - */ - public function get($resourcePath = null, array $query = []) - { - return $this->callResource('get', $resourcePath, ['query' => $query]); - } - - /** - * Wrapper method for issuing DELETE request to current API endpoint. - * - * @param string $resourcePath (optional) string resource path of specific resource - * @param array $query (optional) query string parameters - * - * @return array Result of the request - */ - public function delete($resourcePath = null, array $query = []) - { - return $this->callResource('delete', $resourcePath, ['query' => $query]); - } - - /** - * assembles a URL for a request. - * - * @param string $resourcePath path after the initial endpoint - * @param array $options array with an optional value of query with values to build a querystring from. Any - * query elements that are themselves arrays will be imploded into a comma separated list. - * - * @return string the assembled URL - */ - private function buildUrl($resourcePath, $options) - { - $url = "/{$this->endpoint}/"; - if (!is_null($resourcePath)) { - $url .= $resourcePath; - } - - if (!empty($options['query'])) { - // check each query element - if it's an array, implode it to match the API-accepted format - foreach ($options['query'] as &$element) { - if (is_array($element)) { - $element = implode(',', $element); - } - } - - $queryString = http_build_query($options['query']); - $url .= '?'.$queryString; - } - - return $url; - } - - /** - * Prepares a body for put and post requests. - * - * @param array $options array with an optional value of body with values to build a request body from. - * - * @return string|null A json encoded string or null if no body was provided - */ - private function buildBody($options) - { - $body = null; - if (!empty($options['body'])) { - $model = static::$structure; - $requestModel = $this->buildRequestModel($options['body'], $model); - $body = json_encode($requestModel); - } - - return $body; - } - - /** - * Private Method for issuing GET and DELETE request to current API endpoint. - * - * This method is responsible for getting the collection _and_ - * a specific entity from the API endpoint - * - * If resourcePath parameter is omitted, then we fetch the collection - * - * @param string $action HTTP method type - * @param string $resourcePath (optional) string resource path of specific resource - * @param array $options (optional) query string parameters - * - * @return array Result set of action performed on resource - * - * @throws APIResponseException - */ - private function callResource($action, $resourcePath = null, $options = []) - { - $action = strtoupper($action); // normalize - - $url = $this->buildUrl($resourcePath, $options); - $body = $this->buildBody($options); - - //make request - try { - $response = $this->sparkpost->httpAdapter->send($url, $action, $this->sparkpost->getHttpHeaders(), $body); - - $statusCode = $response->getStatusCode(); - - // Handle 4XX responses, 5XX responses will throw an HttpAdapterException - if ($statusCode < 400) { - return json_decode($response->getBody()->getContents(), true); - } elseif ($statusCode === 403) { - $response = json_decode($response->getBody(), true); - throw new APIResponseException( - 'Request forbidden', - $statusCode, - isset($response['errors'][0]['message']) ? $response['errors'][0]['message'] : 'Request forbidden', - isset($response['errors'][0]['code']) ? $response['errors'][0]['code'] : 1100, - isset($response['errors'][0]['description']) ? $response['errors'][0]['description'] : 'Does this API Key have the correct permissions?' - ); - } elseif ($statusCode === 404) { - throw new APIResponseException('The specified resource does not exist', 404); - } else { - $response = json_decode($response->getBody(), true); - throw new APIResponseException( - 'Received bad response from '.ucfirst($this->endpoint), - $statusCode, - isset($response['errors'][0]['message']) ? $response['errors'][0]['message'] : '', - isset($response['errors'][0]['code']) ? $response['errors'][0]['code'] : 0, - isset($response['errors'][0]['description']) ? $response['errors'][0]['description'] : '' - ); - } - } - - /* - * Configuration Errors, and a catch all for other errors - */ - catch (\Exception $exception) { - if ($exception instanceof APIResponseException) { - throw $exception; - } - - throw new APIResponseException('Unable to contact '.ucfirst($this->endpoint).' API: '.$exception->getMessage(), $exception->getCode()); - } - } -} diff --git a/lib/SparkPost/APIResponseException.php b/lib/SparkPost/APIResponseException.php deleted file mode 100644 index a491b3c..0000000 --- a/lib/SparkPost/APIResponseException.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php - -namespace SparkPost; - -class APIResponseException extends \Exception -{ - /** - * @var string - */ - protected $apiMessage; - - /** - * @var int - */ - protected $apiCode; - - /** - * @var string - */ - protected $apiDescription; - - /** - * Construct the exception. - */ - public function __construct($message = '', $code = 0, $apiMessage = '', $apiCode = 0, $apiDescription = '') - { - $this->apiMessage = $apiMessage; - $this->apiCode = $apiCode; - $this->apiDescription = $apiDescription; - parent::__construct($message, $code); - } - - /** - * Gets the Exception message. - * - * @return string the Exception message as a string. - */ - public function getAPIMessage() - { - return $this->apiMessage; - } - - /** - * Gets the API Exception code. - * - * @return int the exception code as integer. - */ - public function getAPICode() - { - return $this->apiCode; - } - - /** - * Gets the Exception description. - * - * @return string the Exception description as a string. - */ - public function getAPIDescription() - { - return $this->apiDescription; - } -} diff --git a/lib/SparkPost/MessageEvents.php b/lib/SparkPost/MessageEvents.php deleted file mode 100644 index d44a30f..0000000 --- a/lib/SparkPost/MessageEvents.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php - -namespace SparkPost; - -/** - * SDK class for querying the Message Events API. - * - * @see https://developers.sparkpost.com/api/#/reference/message-events - */ -class MessageEvents extends APIResource -{ - /** - * @var string - */ - public $endpoint = 'message-events'; - - /** - * Method for issuing search requests to the Message Events API. - * - * The method passes-through all of the query parameters - the valid ones are listed at - * - * @link https://developers.sparkpost.com/api/#/reference/message-events/events-documentation/search-for-message-events - * - * @param array $queryParams The query parameters. Note that a query parameter containing an array - * is collapsed into a comma-separated list. - * - * @return array The result of the query. - */ - public function search(array $queryParams) - { - // check for DateTime objects & replace them with the formatted string equivalent - foreach (['from', 'to'] as $dateTimeParam) { - if (isset($queryParams[$dateTimeParam]) && $queryParams[$dateTimeParam] instanceof \DateTime) { - // the message events API doesn't allow the seconds or GMT offset, so strip them - $queryParams[$dateTimeParam] = substr($queryParams[$dateTimeParam]->format(\DateTime::ATOM), 0, 16); - } - } - - return $this->get(null, $queryParams); - } - - /** - * List descriptions of the event fields that could be included in a response from the MessageEvent::search() method. - * - * @return array The event field descriptions. - */ - public function documentation() - { - return $this->get('events/documentation'); - } - - /** - * List examples of the event data that will be included in a response from the MessageEvent::search() method. - * - * @param array $events (optional) Event types for which to get a sample payload. If not provided, samples - * for all events will be returned. - * - * @return array Sample events. - */ - public function samples(array $events = []) - { - return $this->get('events/samples', ['events' => $events]); - } -} diff --git a/lib/SparkPost/Promise.php b/lib/SparkPost/Promise.php new file mode 100644 index 0000000..c419597 --- /dev/null +++ b/lib/SparkPost/Promise.php @@ -0,0 +1,45 @@ +<?php + +namespace SparkPost; + +use Http\Promise\Promise as HttpPromise; +use SparkPost\Response as SparkPostResponse; +use SparkPost\Exception as SparkPostException; + +class Promise implements HttpPromise +{ + private $promise; + + public function __construct(HttpPromise $promise) { + $this->promise = $promise; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null) { + $this->promise->then( + function($response) { + $onFulfilled(new SparkPostResponse($response)); + }, + function(Exception $exception) { + $onRejected(new SparkPostException($exception)); + }); + } + + public function getState() { + return $this->promise->getState(); + } + + + public function wait($unwrap = true) { + try + { + $response = $this->promise->wait($unwrap); + return new SparkPostResponse($response); + } + catch (Exception $exception) + { + throw new SparkPostException($exception); + } + } +} + +?>
\ No newline at end of file diff --git a/lib/SparkPost/Response.php b/lib/SparkPost/Response.php new file mode 100644 index 0000000..c2751b6 --- /dev/null +++ b/lib/SparkPost/Response.php @@ -0,0 +1,55 @@ +<?php + +namespace SparkPost; + +use Psr\Http\Message\ResponseInterface as ResponseInterface; +use GuzzleHttp\Psr7\Response as HttpResponse; +use GuzzleHttp\Psr7\MessageTrait; + +class Response implements ResponseInterface { + + use MessageTrait; + + private $response; + + public function __construct(HttpResponse $response) { + $this->response = $response; + } + + public function getBody() + { + $body = $this->response->getBody(); + $body_string = $body->__toString(); + + if (is_string($body_string)) { + $json = json_decode($body_string, true); + + if (json_last_error() == JSON_ERROR_NONE) { + return $json; + } + else { + return $body; + } + } + + return $body; + } + + public function getStatusCode() + { + return $this->response->getStatusCode(); + } + + public function withStatus($code, $reasonPhrase = '') + { + return $this->response->withStatus($code, $reasonPhrase); + } + + public function getReasonPhrase() + { + $this->response->getReasonPhrase(); + } + +} + +?>
\ No newline at end of file diff --git a/lib/SparkPost/SparkPost.php b/lib/SparkPost/SparkPost.php index 8ba9bf9..b37351e 100644 --- a/lib/SparkPost/SparkPost.php +++ b/lib/SparkPost/SparkPost.php @@ -2,8 +2,9 @@ namespace SparkPost; -use GuzzleHttp\Psr7\Request as Request; use Http\Client\HttpClient; +use GuzzleHttp\Psr7\Request as Request; +use SparkPost\Promise as SparkPostPromise; class SparkPost { @@ -12,6 +13,8 @@ class SparkPost public $httpClient; private $options; + public $transmissions; + private static $defaultOptions = [ 'host' => 'api.sparkpost.com', 'protocol' => 'https', @@ -26,31 +29,34 @@ class SparkPost { $this->setOptions($options); $this->setHttpClient($httpClient); + $this->setupEndpoints(); } - public function request($method, $uri, $payload = []) + public function request($method = '', $uri = '', $payload = [], $headers = []) { $method = trim(strtoupper($method)); if ($method === 'GET') { $params = $payload; - $body = null; + $body = []; } else { - $params = null; + $params = []; $body = $payload; } $url = $this->getUrl($uri, $params); - $headers = $this->getHttpHeaders(); + $headers = $this->getHttpHeaders($headers); - $request = new Request($method, $url, $headers, $body); + $request = new Request($method, $url, $headers, json_encode($body)); - return $httpClient->sendAsyncRequest($request); + $promise = $this->httpClient->sendAsyncRequest($request); + + return new SparkPostPromise($promise); } - public function getHttpHeaders() + public function getHttpHeaders($headers) { return [ 'Authorization' => $this->options['key'], @@ -87,7 +93,7 @@ class SparkPost throw new \Exception('You must provide an API key'); } - $this->options = $this->options || self::$defaultOptions; + $this->options = isset($this->options) ? $this->options : self::$defaultOptions; // set options, overriding defaults foreach ($options as $option => $value) { @@ -96,4 +102,7 @@ class SparkPost } } } + + private function setupEndpoints() { + } } diff --git a/lib/SparkPost/Transmission.php b/lib/SparkPost/Transmission.php deleted file mode 100644 index ff63722..0000000 --- a/lib/SparkPost/Transmission.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php - -namespace SparkPost; - -/** - * SDK interface for managing transmissions. - */ -class Transmission extends APIResource -{ - public $endpoint = 'transmissions'; - - /** - * Mapping for values passed into the send method to the values needed for the Transmission API. - * - * @var array - */ - protected static $parameterMappings = [ - 'attachments' => 'content.attachments', - 'campaign' => 'campaign_id', - 'customHeaders' => 'content.headers', - 'description' => 'description', - 'from' => 'content.from', - 'html' => 'content.html', - 'inlineCss' => 'options.inline_css', - 'inlineImages' => 'content.inline_images', - 'metadata' => 'metadata', - 'recipientList' => 'recipients.list_id', - 'recipients' => 'recipients', - 'replyTo' => 'content.reply_to', - 'returnPath' => 'return_path', - 'rfc822' => 'content.email_rfc822', - 'sandbox' => 'options.sandbox', - 'startTime' => 'options.start_time', - 'subject' => 'content.subject', - 'substitutionData' => 'substitution_data', - 'template' => 'content.template_id', - 'text' => 'content.text', - 'trackClicks' => 'options.click_tracking', - 'trackOpens' => 'options.open_tracking', - 'transactional' => 'options.transactional', - 'useDraftTemplate' => 'use_draft_template', - ]; - - /** - * Sets up default structure and default values for the model that is acceptable by the API. - * - * @var array - */ - protected static $structure = [ - 'return_path' => 'default@sparkpostmail.com', - 'content' => [ - 'html' => null, - 'text' => null, - 'email_rfc822' => null, - ], - 'use_draft_template' => false, - ]; - - /** - * Method for issuing POST request to the Transmissions API. - * - * This method assumes that all the appropriate fields have - * been populated by the user through configuration. Acceptable - * configuration values are: - * 'attachments': array, - * 'campaign': string, - * 'customHeaders': array, - * 'description': string, - * 'from': string, - * 'html': string, - * 'inlineCss': boolean, - * 'inlineImages': array, - * 'metadata': array, - * 'recipientList': string, - * 'recipients': array, - * 'replyTo': string, - * 'rfc822': string, - * 'sandbox': boolean, - * 'startTime': string | \DateTime, - * 'subject': string, - * 'substitutionData': array, - * 'template': string, - * 'text': string, - * 'trackClicks': boolean, - * 'trackOpens': boolean, - * 'transactional': boolean, - * 'useDraftTemplate': boolean - * - * @param array $transmissionConfig - * - * @return array API repsonse represented as key-value pairs - */ - public function send($transmissionConfig) - { - if (isset($transmissionConfig['startTime']) && $transmissionConfig['startTime'] instanceof \DateTime) { - $transmissionConfig['startTime'] = $transmissionConfig['startTime']->format(\DateTime::ATOM); - } - - return $this->create($transmissionConfig); - } - - /** - * Method for retrieving information about all transmissions - * Wrapper method for a cleaner interface. - * - * @param null|string $campaignID - * @param null|string $templateID - * - * @return array result Set of transmissions - */ - public function all($campaignID = null, $templateID = null) - { - $options = []; - if ($campaignID !== null) { - $options['campaign_id'] = $campaignID; - } - if ($templateID !== null) { - $options['template_id'] = $templateID; - } - - return $this->get(null, $options); - } - - /** - * Method for retrieving information about a single transmission - * Wrapper method for a cleaner interface. - * - * @param string $transmissionID Identifier of the transmission to be found - * - * @return array result Single transmission represented in key-value pairs - */ - public function find($transmissionID) - { - return $this->get($transmissionID); - } -} |