summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/SendGridCompatibility/Email.php450
-rw-r--r--lib/SendGridCompatibility/SendGrid.php31
-rw-r--r--lib/SparkPost/APIResource.php462
-rw-r--r--lib/SparkPost/APIResponseException.php107
-rw-r--r--lib/SparkPost/MessageEvents.php98
-rw-r--r--lib/SparkPost/SparkPost.php258
-rw-r--r--lib/SparkPost/Transmission.php238
7 files changed, 882 insertions, 762 deletions
diff --git a/lib/SendGridCompatibility/Email.php b/lib/SendGridCompatibility/Email.php
index 5065e1f..3ca2466 100644
--- a/lib/SendGridCompatibility/Email.php
+++ b/lib/SendGridCompatibility/Email.php
@@ -1,199 +1,259 @@
<?php
+
namespace SparkPost\SendGridCompatibility;
-class Email {
- public $model;
-
- /**
- * Sets up the model for saving the configuration
- */
- public function __construct() {
- $this->model = array();
- }
-
- /**
- * adds addresses as recipients
- * @param string $address
- * @param string $name optional
- * @return $this
- */
- public function addTo($address, $name = null) {
- if (!isset($this->model['recipients'])) {
- $this->model['recipients'] = array();
- }
-
- if(isset($name)) {
- $address = array('address'=>array('email'=>$address, 'name'=>$name));
- } else {
- $address = array('address'=>array('email'=>$address));
- }
-
- array_push($this->model['recipients'], $address);
- return $this;
- }
-
- /**
- * explicitly sets a list of addresses
- * @param array $addresses
- * @return $this
- */
- public function setTos(array $addresses) {
- $this->model['recipients'] = $addresses;
- return $this;
- }
-
- /**
- * sets the from address
- * @param string $address
- * @return $this
- */
- public function setFrom($address) {
- $this->model['from'] = array('email' => $address);
- return $this;
- }
-
- /**
- * Sets the name for the from address
- * @param string $name
- * @return $this
- * @throws \Exception
- */
- public function setFromName($name) {
- if(!isset($this->model['from'])){
- throw new \Exception('Must set \'From\' prior to setting \'From Name\'.');
- }
- $this->model['from']['name'] = $name;
- return $this;
- }
-
- /**
- * sets the reply to field
- * @param string $address
- * @return $this
- */
- public function setReplyTo ($address) {
- $this->model['replyTo'] = $address;
- return $this;
- }
-
- /**
- * throws an error because bcc fields are not yet implemented.
- * @throws \Exception
- * @param string $address
- * @return $this
- */
- public function addBcc($address) {
- throw new \Exception('Adding bcc recipients is not yet supported, try adding them as a \'to\' address');
- }
-
- /**
- * sets the subject header
- * @param string $subject
- * @return $this
- */
- public function setSubject($subject) {
- $this->model['subject'] = $subject;
- return $this;
- }
-
- /**
- * sets the text body
- * @param string $text
- * @return $this
- */
- public function setText($text) {
- $this->model['text'] = $text;
- return $this;
- }
-
- /**
- * sets the html body
- * @param string $html
- * @return $this
- */
- public function setHtml($html) {
- $this->model['html'] = $html;
- return $this;
- }
-
- /**
- * Throws an exception since adding categories is not yet supported
- * @param string $category
- * @throws \Exception
- */
- public function addCategory($category) {
- throw new \Exception('Adding categories is not yet supported');
- }
-
- /**
- * Throws an exception since adding attachments is not yet supported
- * @throws \Exception
- * @param mixed $attachment
- */
- public function addAttachment($attachment) {
- throw new \Exception('Adding attachments is not yet supported');
- }
-
- /**
- * Adds transmission level substitution data
- * @param string $name
- * @param mixed $values
- * @return $this
- */
- public function addSubstitution($name, $values) {
- if (!isset($this->model['substitutionData'])) {
- $this->model['substitutionData'] = array();
- }
- $this->model['substitutionData'][$name] = $values;
-
- return $this;
- }
-
- /**
- * Adds transmission level substitution data
- * @param string $name
- * @param mixed $values
- */
- public function addSection($name, $values) {
- $this->addSubstitution($name, $values);
- }
-
- /**
- * Throws an exception because arguments for third party systems is not supported
- * @throws \Exception
- * @param mixed $value
- */
- public function addUniqueArg($key, $value) {
- throw new \Exception('Adding Unique Arguments is not yet supported');
- }
-
- /**
- * Throws an exception because arguments for third party systems is not supported
- * @throws \Exception
- * @param mixed $values
- */
- public function setUniqueArgs(array $values) {
- throw new \Exception('Setting Unique Arguments is not yet supported');
- }
-
- /**
- * Adds custom headers to the email header
- * @param string $name
- * @param string $value
- */
- public function addHeader($name, $value) {
- if (!isset($this->model['customHeaders'])) {
- $this->model['customHeaders'] = array();
- }
- $this->model['customHeaders'][$name] = $value;
- }
-
- /**
- * converts this object to a configuration for a SparkPost transmission
- * @return array
- */
- public function toSparkPostTransmission() {
- return $this->model;
- }
+class Email
+{
+ public $model;
+
+ /**
+ * Sets up the model for saving the configuration.
+ */
+ public function __construct()
+ {
+ $this->model = array();
+ }
+
+ /**
+ * adds addresses as recipients.
+ *
+ * @param string $address
+ * @param string $name optional
+ *
+ * @return $this
+ */
+ public function addTo($address, $name = null)
+ {
+ if (!isset($this->model['recipients'])) {
+ $this->model['recipients'] = array();
+ }
+
+ if (isset($name)) {
+ $address = array('address' => array('email' => $address, 'name' => $name));
+ } else {
+ $address = array('address' => array('email' => $address));
+ }
+
+ array_push($this->model['recipients'], $address);
+
+ return $this;
+ }
+
+ /**
+ * explicitly sets a list of addresses.
+ *
+ * @param array $addresses
+ *
+ * @return $this
+ */
+ public function setTos(array $addresses)
+ {
+ $this->model['recipients'] = $addresses;
+
+ return $this;
+ }
+
+ /**
+ * sets the from address.
+ *
+ * @param string $address
+ *
+ * @return $this
+ */
+ public function setFrom($address)
+ {
+ $this->model['from'] = array('email' => $address);
+
+ return $this;
+ }
+
+ /**
+ * Sets the name for the from address.
+ *
+ * @param string $name
+ *
+ * @return $this
+ *
+ * @throws \Exception
+ */
+ public function setFromName($name)
+ {
+ if (!isset($this->model['from'])) {
+ throw new \Exception('Must set \'From\' prior to setting \'From Name\'.');
+ }
+ $this->model['from']['name'] = $name;
+
+ return $this;
+ }
+
+ /**
+ * sets the reply to field.
+ *
+ * @param string $address
+ *
+ * @return $this
+ */
+ public function setReplyTo($address)
+ {
+ $this->model['replyTo'] = $address;
+
+ return $this;
+ }
+
+ /**
+ * throws an error because bcc fields are not yet implemented.
+ *
+ * @throws \Exception
+ *
+ * @param string $address
+ *
+ * @return $this
+ */
+ public function addBcc($address)
+ {
+ throw new \Exception('Adding bcc recipients is not yet supported, try adding them as a \'to\' address');
+ }
+
+ /**
+ * sets the subject header.
+ *
+ * @param string $subject
+ *
+ * @return $this
+ */
+ public function setSubject($subject)
+ {
+ $this->model['subject'] = $subject;
+
+ return $this;
+ }
+
+ /**
+ * sets the text body.
+ *
+ * @param string $text
+ *
+ * @return $this
+ */
+ public function setText($text)
+ {
+ $this->model['text'] = $text;
+
+ return $this;
+ }
+
+ /**
+ * sets the html body.
+ *
+ * @param string $html
+ *
+ * @return $this
+ */
+ public function setHtml($html)
+ {
+ $this->model['html'] = $html;
+
+ return $this;
+ }
+
+ /**
+ * Throws an exception since adding categories is not yet supported.
+ *
+ * @param string $category
+ *
+ * @throws \Exception
+ */
+ public function addCategory($category)
+ {
+ throw new \Exception('Adding categories is not yet supported');
+ }
+
+ /**
+ * Throws an exception since adding attachments is not yet supported.
+ *
+ * @throws \Exception
+ *
+ * @param mixed $attachment
+ */
+ public function addAttachment($attachment)
+ {
+ throw new \Exception('Adding attachments is not yet supported');
+ }
+
+ /**
+ * Adds transmission level substitution data.
+ *
+ * @param string $name
+ * @param mixed $values
+ *
+ * @return $this
+ */
+ public function addSubstitution($name, $values)
+ {
+ if (!isset($this->model['substitutionData'])) {
+ $this->model['substitutionData'] = array();
+ }
+ $this->model['substitutionData'][$name] = $values;
+
+ return $this;
+ }
+
+ /**
+ * Adds transmission level substitution data.
+ *
+ * @param string $name
+ * @param mixed $values
+ */
+ public function addSection($name, $values)
+ {
+ $this->addSubstitution($name, $values);
+ }
+
+ /**
+ * Throws an exception because arguments for third party systems is not supported.
+ *
+ * @throws \Exception
+ *
+ * @param mixed $value
+ */
+ public function addUniqueArg($key, $value)
+ {
+ throw new \Exception('Adding Unique Arguments is not yet supported');
+ }
+
+ /**
+ * Throws an exception because arguments for third party systems is not supported.
+ *
+ * @throws \Exception
+ *
+ * @param mixed $values
+ */
+ public function setUniqueArgs(array $values)
+ {
+ throw new \Exception('Setting Unique Arguments is not yet supported');
+ }
+
+ /**
+ * Adds custom headers to the email header.
+ *
+ * @param string $name
+ * @param string $value
+ */
+ public function addHeader($name, $value)
+ {
+ if (!isset($this->model['customHeaders'])) {
+ $this->model['customHeaders'] = array();
+ }
+ $this->model['customHeaders'][$name] = $value;
+ }
+
+ /**
+ * converts this object to a configuration for a SparkPost transmission.
+ *
+ * @return array
+ */
+ public function toSparkPostTransmission()
+ {
+ return $this->model;
+ }
}
-?>
diff --git a/lib/SendGridCompatibility/SendGrid.php b/lib/SendGridCompatibility/SendGrid.php
index 1671e6b..c5e84c1 100644
--- a/lib/SendGridCompatibility/SendGrid.php
+++ b/lib/SendGridCompatibility/SendGrid.php
@@ -1,23 +1,26 @@
<?php
+
namespace SparkPost\SendGridCompatibility;
use SparkPost\SparkPost;
-class SendGrid{
- private $sparky;
+class SendGrid
+{
+ private $sparky;
- public function __construct($username, $password, $options = null, $httpAdapter) {
- //username isn't used in our system
- $opts = array('key'=>$password);
- if (!is_null($options)) {
- $opts = array_merge($opts, $options);
- }
+ public function __construct($username, $password, $options = null, $httpAdapter)
+ {
+ //username isn't used in our system
+ $opts = array('key' => $password);
+ if (!is_null($options)) {
+ $opts = array_merge($opts, $options);
+ }
- $this->sparky = new SparkPost($httpAdapter, $opts);
- }
+ $this->sparky = new SparkPost($httpAdapter, $opts);
+ }
- public function send(Email $email) {
- $this->sparky->transmission->send($email->toSparkPostTransmission());
- }
+ public function send(Email $email)
+ {
+ $this->sparky->transmission->send($email->toSparkPostTransmission());
+ }
}
-?>
diff --git a/lib/SparkPost/APIResource.php b/lib/SparkPost/APIResource.php
index f593038..36b03a8 100644
--- a/lib/SparkPost/APIResource.php
+++ b/lib/SparkPost/APIResource.php
@@ -1,241 +1,265 @@
<?php
+
namespace SparkPost;
/**
- * SDK interface for managing SparkPost API endpoints
+ * 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;
+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;
}
- $path = explode('.', $mapPath);
- $temp = &$model;
- foreach( $path as $key ) {
- if( !isset($temp[$key]) ){
- $temp[$key] = null;
- }
- $temp = &$temp[$key];
+ /**
+ * 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;
}
- $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);
+
+ /**
+ * 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;
}
- 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;
+
+ /**
+ * 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]);
}
- 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);
- }
- }
+ /**
+ * 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]);
+ }
- $queryString = http_build_query($options['query']);
- $url .= '?'.$queryString;
+ /**
+ * 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]);
}
- 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);
+ /**
+ * 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]);
}
- 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'] : ""
- );
- }
+
+ /**
+ * 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;
}
- /*
- * Configuration Errors, and a catch all for other errors
+ /**
+ * 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
*/
- catch (\Exception $exception) {
- if($exception instanceof APIResponseException) {
- throw $exception;
- }
+ private function buildBody($options)
+ {
+ $body = null;
+ if (!empty($options['body'])) {
+ $model = static::$structure;
+ $requestModel = $this->buildRequestModel($options['body'], $model);
+ $body = json_encode($requestModel);
+ }
- throw new APIResponseException('Unable to contact ' . ucfirst($this->endpoint) . ' API: '. $exception->getMessage(), $exception->getCode());
+ 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
index bc0e782..a491b3c 100644
--- a/lib/SparkPost/APIResponseException.php
+++ b/lib/SparkPost/APIResponseException.php
@@ -2,54 +2,61 @@
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;
- }
-
+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
index 788b752..d44a30f 100644
--- a/lib/SparkPost/MessageEvents.php
+++ b/lib/SparkPost/MessageEvents.php
@@ -1,60 +1,64 @@
<?php
+
namespace SparkPost;
/**
- * SDK class for querying the Message Events API
+ * 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';
+ /**
+ * @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);
- }
- }
+ /**
+ * 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);
- }
+ 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 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]);
- }
-} \ No newline at end of file
+ /**
+ * 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/SparkPost.php b/lib/SparkPost/SparkPost.php
index ffc84f0..92ad867 100644
--- a/lib/SparkPost/SparkPost.php
+++ b/lib/SparkPost/SparkPost.php
@@ -1,136 +1,150 @@
<?php
+
namespace SparkPost;
+
use Ivory\HttpAdapter\Configuration;
use Ivory\HttpAdapter\HttpAdapterInterface;
-class SparkPost {
-
- public $transmission;
- public $messageEvents;
-
- /**
- * Library version, used for setting User-Agent.
- */
- private $version = '1.1.0';
-
- /**
- * Connection config for making requests.
- */
- private $config;
-
- /**
- * @var \Ivory\HttpAdapter\HttpAdapterInterface to make requests through.
- */
- public $httpAdapter;
-
- /**
- * Default config values. Passed in values will override these.
- */
- private static $apiDefaults = [
- 'host'=>'api.sparkpost.com',
- 'protocol'=>'https',
- 'port'=>443,
- 'strictSSL'=>true,
- 'key'=>'',
- 'version'=>'v1'
- ];
-
- /**
- * Sets up httpAdapter and config
- *
- * Sets up instances of sub libraries.
- *
- * @param \Ivory\HttpAdapter\HttpAdapterInterface $httpAdapter - An adapter for making http requests
- * @param String | array $settingsConfig - Hashmap that contains config values
- * for the SDK to connect to SparkPost. If its a string we assume that
- * its just they API Key.
- */
- public function __construct($httpAdapter, $settingsConfig) {
- //config needs to be setup before adapter because of default adapter settings
- $this->setConfig($settingsConfig);
- $this->setHttpAdapter($httpAdapter);
-
- $this->transmission = new Transmission($this);
- $this->messageEvents = new MessageEvents($this);
- }
-
- /**
- * Creates an unwrapped api interface for endpoints that aren't yet supported.
- * The new resource is attached to this object as well as returned
- * @param string $endpoint
- * @return APIResource - the unwrapped resource
- */
- public function setupUnwrapped ($endpoint) {
- $this->{$endpoint} = new APIResource($this);
- $this->{$endpoint}->endpoint = $endpoint;
-
- return $this->{$endpoint};
- }
-
- /**
- * Merges passed in headers with default headers for http requests
- */
- public function getHttpHeaders() {
- $defaultOptions = [
- 'Authorization' => $this->config['key'],
- 'Content-Type' => 'application/json',
+class SparkPost
+{
+ public $transmission;
+ public $messageEvents;
+
+ /**
+ * Library version, used for setting User-Agent.
+ */
+ private $version = '1.1.0';
+
+ /**
+ * Connection config for making requests.
+ */
+ private $config;
+
+ /**
+ * @var \Ivory\HttpAdapter\HttpAdapterInterface to make requests through.
+ */
+ public $httpAdapter;
+
+ /**
+ * Default config values. Passed in values will override these.
+ */
+ private static $apiDefaults = [
+ 'host' => 'api.sparkpost.com',
+ 'protocol' => 'https',
+ 'port' => 443,
+ 'strictSSL' => true,
+ 'key' => '',
+ 'version' => 'v1',
];
- return $defaultOptions;
- }
-
- /**
- * Helper function for getting the configuration for http requests
- * @param array $config
- * @return Configuration
- */
- private function getHttpConfig($config) {
- // create Configuration for http adapter
- $httpConfig = new Configuration();
- $baseUrl = $config['protocol'] . '://' . $config['host'] . ($config['port'] ? ':' . $config['port'] : '') . '/api/' . $config['version'];
- $httpConfig->setBaseUri($baseUrl);
- $httpConfig->setUserAgent('php-sparkpost/' . $this->version);
- return $httpConfig;
- }
-
-
- /**
- * Validates and sets up the httpAdapter
- * @param $httpAdapter \Ivory\HttpAdapter\HttpAdapterInterface to make requests through.
- * @throws \Exception
- */
- public function setHttpAdapter(HttpAdapterInterface $httpAdapter) {
- $this->httpAdapter = $httpAdapter;
- $this->httpAdapter->setConfiguration($this->getHttpConfig($this->config));
- }
-
- /**
- * Allows the user to pass in values to override the defaults and set their API key
- * @param String | array $settingsConfig - Hashmap that contains config values
- * for the SDK to connect to SparkPost. If its a string we assume that
- * its just they API Key.
- * @throws \Exception
- */
- public function setConfig($settingsConfig) {
- // if the config map is a string we should assume that its an api key
- if (is_string($settingsConfig)) {
- $settingsConfig = ['key'=>$settingsConfig];
+ /**
+ * Sets up httpAdapter and config.
+ *
+ * Sets up instances of sub libraries.
+ *
+ * @param \Ivory\HttpAdapter\HttpAdapterInterface $httpAdapter - An adapter for making http requests
+ * @param string | array $settingsConfig - Hashmap that contains config values
+ * for the SDK to connect to SparkPost. If its a string we assume that
+ * its just they API Key.
+ */
+ public function __construct($httpAdapter, $settingsConfig)
+ {
+ //config needs to be setup before adapter because of default adapter settings
+ $this->setConfig($settingsConfig);
+ $this->setHttpAdapter($httpAdapter);
+
+ $this->transmission = new Transmission($this);
+ $this->messageEvents = new MessageEvents($this);
}
- // Validate API key because its required
- if (!isset($settingsConfig['key']) || !preg_match('/\S/', $settingsConfig['key'])){
- throw new \Exception('You must provide an API key');
+ /**
+ * Creates an unwrapped api interface for endpoints that aren't yet supported.
+ * The new resource is attached to this object as well as returned.
+ *
+ * @param string $endpoint
+ *
+ * @return APIResource - the unwrapped resource
+ */
+ public function setupUnwrapped($endpoint)
+ {
+ $this->{$endpoint} = new APIResource($this);
+ $this->{$endpoint}->endpoint = $endpoint;
+
+ return $this->{$endpoint};
}
- $this->config = self::$apiDefaults;
+ /**
+ * Merges passed in headers with default headers for http requests.
+ */
+ public function getHttpHeaders()
+ {
+ $defaultOptions = [
+ 'Authorization' => $this->config['key'],
+ 'Content-Type' => 'application/json',
+ ];
+
+ return $defaultOptions;
+ }
- // set config, overriding defaults
- foreach ($settingsConfig as $configOption => $configValue) {
- if(key_exists($configOption, $this->config)) {
- $this->config[$configOption] = $configValue;
- }
+ /**
+ * Helper function for getting the configuration for http requests.
+ *
+ * @param array $config
+ *
+ * @return Configuration
+ */
+ private function getHttpConfig($config)
+ {
+ // create Configuration for http adapter
+ $httpConfig = new Configuration();
+ $baseUrl = $config['protocol'].'://'.$config['host'].($config['port'] ? ':'.$config['port'] : '').'/api/'.$config['version'];
+ $httpConfig->setBaseUri($baseUrl);
+ $httpConfig->setUserAgent('php-sparkpost/'.$this->version);
+
+ return $httpConfig;
}
- }
-}
-?>
+ /**
+ * Validates and sets up the httpAdapter.
+ *
+ * @param $httpAdapter \Ivory\HttpAdapter\HttpAdapterInterface to make requests through.
+ *
+ * @throws \Exception
+ */
+ public function setHttpAdapter(HttpAdapterInterface $httpAdapter)
+ {
+ $this->httpAdapter = $httpAdapter;
+ $this->httpAdapter->setConfiguration($this->getHttpConfig($this->config));
+ }
+
+ /**
+ * Allows the user to pass in values to override the defaults and set their API key.
+ *
+ * @param string | array $settingsConfig - Hashmap that contains config values
+ * for the SDK to connect to SparkPost. If its a string we assume that
+ * its just they API Key.
+ *
+ * @throws \Exception
+ */
+ public function setConfig($settingsConfig)
+ {
+ // if the config map is a string we should assume that its an api key
+ if (is_string($settingsConfig)) {
+ $settingsConfig = ['key' => $settingsConfig];
+ }
+
+ // Validate API key because its required
+ if (!isset($settingsConfig['key']) || !preg_match('/\S/', $settingsConfig['key'])) {
+ throw new \Exception('You must provide an API key');
+ }
+
+ $this->config = self::$apiDefaults;
+
+ // set config, overriding defaults
+ foreach ($settingsConfig as $configOption => $configValue) {
+ if (key_exists($configOption, $this->config)) {
+ $this->config[$configOption] = $configValue;
+ }
+ }
+ }
+}
diff --git a/lib/SparkPost/Transmission.php b/lib/SparkPost/Transmission.php
index ae5d071..ff63722 100644
--- a/lib/SparkPost/Transmission.php
+++ b/lib/SparkPost/Transmission.php
@@ -1,128 +1,136 @@
<?php
+
namespace SparkPost;
-use Guzzle\Http\Client;
-use Guzzle\Http\Exception\ClientErrorResponseException;
/**
- * SDK interface for managing transmissions
+ * SDK interface for managing transmissions.
*/
-class Transmission extends APIResource {
-
- public $endpoint = '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'
- ];
+ /**
+ * 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
- ];
+ /**
+ * 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);
- }
+ /**
+ * 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 );
- }
+ 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;
+ /**
+ * 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 );
- }
+ 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);
- }
+ /**
+ * 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);
+ }
}
-
-?>