1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
<?php
namespace SparkPost;
use Http\Client\HttpClient;
use Http\Client\HttpAsyncClient;
use GuzzleHttp\Psr7\Request as Request;
class SparkPost
{
/**
* Library version, used for setting User-Agent.
*/
private $version = '2.0.0';
/**
* HttpClient used to make requests.
*/
public $httpClient;
/**
* Options for requests.
*/
private $options;
/**
* Default options for requests that can be overridden with the setOptions function.
*/
private static $defaultOptions = [
'host' => 'api.sparkpost.com',
'protocol' => 'https',
'port' => 443,
'key' => '',
'version' => 'v1',
'async' => true,
];
/**
* Instance of Transmission class.
*/
public $transmissions;
/**
* Sets up the SparkPost instance.
*
* @param HttpClient $httpClient - An httplug client or adapter
* @param array $options - An array to overide default options or a string to be used as an API key
*/
public function __construct(HttpClient $httpClient, $options)
{
$this->setOptions($options);
$this->setHttpClient($httpClient);
$this->setupEndpoints();
}
/**
* Sends either sync or async request based on async option.
*
* @param string $method
* @param string $uri
* @param array $payload - either used as the request body or url query params
* @param array $headers
*
* @return SparkPostPromise or SparkPostResponse depending on sync or async request
*/
public function request($method = 'GET', $uri = '', $payload = [], $headers = [])
{
if ($this->options['async'] === true) {
return $this->asyncRequest($method, $uri, $payload, $headers);
} else {
return $this->syncRequest($method, $uri, $payload, $headers);
}
}
/**
* Sends sync request to SparkPost API.
*
* @param string $method
* @param string $uri
* @param array $payload
* @param array $headers
*
* @return SparkPostResponse
*
* @throws SparkPostException
*/
public function syncRequest($method = 'GET', $uri = '', $payload = [], $headers = [])
{
$request = $this->buildRequest($method, $uri, $payload, $headers);
try {
return new SparkPostResponse($this->httpClient->sendRequest($request));
} catch (\Exception $exception) {
throw new SparkPostException($exception);
}
}
/**
* Sends async request to SparkPost API.
*
* @param string $method
* @param string $uri
* @param array $payload
* @param array $headers
*
* @return SparkPostPromise
*/
public function asyncRequest($method = 'GET', $uri = '', $payload = [], $headers = [])
{
if ($this->httpClient instanceof HttpAsyncClient) {
$request = $this->buildRequest($method, $uri, $payload, $headers);
return new SparkPostPromise($this->httpClient->sendAsyncRequest($request));
} else {
throw new \Exception('Your http client does not support asynchronous requests. Please use a different client or use synchronous requests.');
}
}
/**
* Builds request from given params.
*
* @param string $method
* @param string $uri
* @param array $payload
* @param array $headers
*
* @return GuzzleHttp\Psr7\Request - A Psr7 compliant request
*/
public function buildRequest($method, $uri, $payload, $headers)
{
$method = trim(strtoupper($method));
if ($method === 'GET') {
$params = $payload;
$body = [];
} else {
$params = [];
$body = $payload;
}
$url = $this->getUrl($uri, $params);
$headers = $this->getHttpHeaders($headers);
return new Request($method, $url, $headers, json_encode($body));
}
/**
* Returns an array for the request headers.
*
* @param array $headers - any custom headers for the request
*
* @return array $headers - headers for the request
*/
public function getHttpHeaders($headers = [])
{
$constantHeaders = [
'Authorization' => $this->options['key'],
'Content-Type' => 'application/json',
'User-Agent' => 'php-sparkpost/'.$this->version,
];
foreach ($constantHeaders as $key => $value) {
$headers[$key] = $value;
}
return $headers;
}
/**
* Builds the request url from the options and given params.
*
* @param string $path - the path in the url to hit
* @param array $params - query parameters to be encoded into the url
*
* @return string $url - the url to send the desired request to
*/
public function getUrl($path, $params = [])
{
$options = $this->options;
$paramsArray = [];
foreach ($params as $key => $value) {
if (is_array($value)) {
$value = implode(',', $value);
}
array_push($paramsArray, $key.'='.$value);
}
$paramsString = implode('&', $paramsArray);
return $options['protocol'].'://'.$options['host'].($options['port'] ? ':'.$options['port'] : '').'/api/'.$options['version'].'/'.$path.($paramsString ? '?'.$paramsString : '');
}
/**
* Sets $httpClient to be used for request.
*
* @param Http\Client\HttpClient $httpClient - the client to be used for request
*/
public function setHttpClient(HttpClient $httpClient)
{
$this->httpClient = $httpClient;
}
/**
* Sets the options from the param and defaults for the SparkPost object.
*
* @param array $options - either an string API key or an array of options
*/
public function setOptions($options)
{
// if the options map is a string we should assume that its an api key
if (is_string($options)) {
$options = ['key' => $options];
}
// Validate API key because its required
if (!isset($this->options['key']) && (!isset($options['key']) || !preg_match('/\S/', $options['key']))) {
throw new \Exception('You must provide an API key');
}
$this->options = isset($this->options) ? $this->options : self::$defaultOptions;
// set options, overriding defaults
foreach ($options as $option => $value) {
if (key_exists($option, $this->options)) {
$this->options[$option] = $value;
}
}
}
/**
* Sets up any endpoints to custom classes e.g. $this->transmissions.
*/
private function setupEndpoints()
{
$this->transmissions = new Transmission($this);
}
}
|