Skip to content

Commit 55ffd69

Browse files
Merge pull request #6 from misantron/refactoring
Library refactoring around PSR-2 / PSR-4 code standards
2 parents 2319345 + e5de48e commit 55ffd69

File tree

10 files changed

+380
-321
lines changed

10 files changed

+380
-321
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.lock
33
vendor/
44
*.old
5+
.idea/

Diff for: composer.json

+10-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
"version": "3.1.0",
66
"require-dev": {
77
"phpunit/phpunit": "~4.4",
8-
"squizlabs/php_codesniffer": "2.*"
8+
"squizlabs/php_codesniffer": "~2.0"
99
},
1010
"homepage": "http://github.com/sendgrid/php-http-client",
1111
"keywords": ["SendGrid", "HTTP", "REST", "API", "Fluent"],
1212
"license": "MIT",
1313
"authors": [
1414
{
15-
"name": "Matt Bernier",
16-
"email": "dx@sendgrid.com"
15+
"name": "Matt Bernier",
16+
"email": "dx@sendgrid.com"
1717
},
1818
{
1919
"name": "Elmer Thomas",
@@ -24,8 +24,13 @@
2424
"php": ">=5.6"
2525
},
2626
"autoload": {
27-
"psr-0": {
28-
"SendGrid": "lib/"
27+
"psr-4": {
28+
"SendGrid\\": "lib/"
29+
}
30+
},
31+
"autoload-dev": {
32+
"psr-4": {
33+
"SendGrid\\Test\\": "test/unit/"
2934
}
3035
}
3136
}

Diff for: examples/example.php

+25-26
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
<?php
2+
23
// If running this outside of this context, use the following include and
34
// comment out the two includes below
45
// require __DIR__ . '/vendor/autoload.php';
5-
include(dirname(__DIR__).'/lib/SendGrid/client.php');
6+
include(dirname(__DIR__) . '/lib/Client.php');
67
// This gets the parent directory, for your current directory use getcwd()
78
$path_to_config = dirname(__DIR__);
8-
$api_key = getenv('SENDGRID_API_KEY');
9-
$headers = array('Authorization: Bearer '.$api_key);
10-
$client = new SendGrid\Client('https://api.sendgrid.com', $headers, '/v3', null);
9+
$apiKey = getenv('SENDGRID_API_KEY');
10+
$headers = ['Authorization: Bearer ' . $apiKey];
11+
$client = new SendGrid\Client('https://api.sendgrid.com', $headers, '/v3');
1112

1213
// GET Collection
13-
$query_params = array('limit' => 100, 'offset' => 0);
14-
$request_headers = array('X-Mock: 200');
14+
$query_params = ['limit' => 100, 'offset' => 0];
15+
$request_headers = ['X-Mock: 200'];
1516
$response = $client->api_keys()->get(null, $query_params, $request_headers);
1617
echo $response->statusCode();
1718
echo $response->body();
1819
echo $response->headers();
1920

2021
// POST
21-
$request_body = array(
22-
'name' => 'My PHP API Key',
23-
'scopes' => array(
24-
'mail.send',
25-
'alerts.create',
26-
'alerts.read'
27-
)
28-
);
22+
$request_body = [
23+
'name' => 'My PHP API Key',
24+
'scopes' => [
25+
'mail.send',
26+
'alerts.create',
27+
'alerts.read'
28+
]
29+
];
2930
$response = $client->api_keys()->post($request_body);
3031
echo $response->statusCode();
3132
echo $response->body();
@@ -40,22 +41,22 @@
4041
echo $response->headers();
4142

4243
// PATCH
43-
$request_body = array(
44-
'name' => 'A New Hope'
45-
);
44+
$request_body = [
45+
'name' => 'A New Hope'
46+
];
4647
$response = $client->api_keys()->_($api_key_id)->patch($request_body);
4748
echo $response->statusCode();
4849
echo $response->body();
4950
echo $response->headers();
5051

5152
// PUT
52-
$request_body = array(
53-
'name' => 'A New Hope',
54-
'scopes' => array(
55-
'user.profile.read',
56-
'user.profile.update'
57-
)
58-
);
53+
$request_body = [
54+
'name' => 'A New Hope',
55+
'scopes' => [
56+
'user.profile.read',
57+
'user.profile.update'
58+
]
59+
];
5960
$response = $client->api_keys()->_($api_key_id)->put($request_body);
6061
echo $response->statusCode();
6162
echo $response->body();
@@ -66,5 +67,3 @@
6667
echo $response->statusCode();
6768
echo $response->body();
6869
echo $response->headers();
69-
70-
?>

Diff for: lib/Client.php

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
3+
/**
4+
* HTTP Client library
5+
*
6+
* PHP version 5.4
7+
*
8+
* @author Matt Bernier <dx@sendgrid.com>
9+
* @author Elmer Thomas <dx@sendgrid.com>
10+
* @copyright 2016 SendGrid
11+
* @license https://opensource.org/licenses/MIT The MIT License
12+
* @version GIT: <git_id>
13+
* @link http://packagist.org/packages/sendgrid/php-http-client
14+
*/
15+
16+
namespace SendGrid;
17+
18+
/**
19+
* Quickly and easily access any REST or REST-like API.
20+
*/
21+
class Client
22+
{
23+
/** @var string */
24+
protected $host;
25+
/** @var array */
26+
protected $headers;
27+
/** @var string */
28+
protected $version;
29+
/** @var array */
30+
protected $path;
31+
/** @var array */
32+
private $methods;
33+
34+
/**
35+
* Initialize the client
36+
*
37+
* @param string $host the base url (e.g. https://api.sendgrid.com)
38+
* @param array $headers global request headers
39+
* @param string $version api version (configurable)
40+
* @param array $path holds the segments of the url path
41+
*/
42+
public function __construct($host, $headers = null, $version = null, $path = null)
43+
{
44+
$this->host = $host;
45+
$this->headers = $headers ?: [];
46+
$this->version = $version;
47+
$this->path = $path ?: [];
48+
// These are the supported HTTP verbs
49+
$this->methods = ['delete', 'get', 'patch', 'post', 'put'];
50+
}
51+
52+
/**
53+
* Make a new Client object
54+
*
55+
* @param string $name name of the url segment
56+
*
57+
* @return Client object
58+
*/
59+
private function buildClient($name = null)
60+
{
61+
if (isset($name)) {
62+
$this->path[] = $name;
63+
}
64+
$client = new Client($this->host, $this->headers, $this->version, $this->path);
65+
$this->path = [];
66+
return $client;
67+
}
68+
69+
/**
70+
* Build the final URL to be passed
71+
*
72+
* @param array $queryParams an array of all the query parameters
73+
*
74+
* @return string
75+
*/
76+
private function buildUrl($queryParams = null)
77+
{
78+
$path = '/' . implode('/', $this->path);
79+
if (isset($queryParams)) {
80+
$path .= '?' . http_build_query($queryParams);
81+
}
82+
return sprintf('%s%s%s', $this->host, $this->version ?: '', $path);
83+
}
84+
85+
/**
86+
* Make the API call and return the response. This is separated into
87+
* it's own function, so we can mock it easily for testing.
88+
*
89+
* @param string $method the HTTP verb
90+
* @param string $url the final url to call
91+
* @param array $body request body
92+
* @param array $headers any additional request headers
93+
*
94+
* @return Response object
95+
*/
96+
public function makeRequest($method, $url, $body = null, $headers = null)
97+
{
98+
$curl = curl_init($url);
99+
100+
curl_setopt_array($curl, [
101+
CURLOPT_RETURNTRANSFER => true,
102+
CURLOPT_HEADER => 1,
103+
CURLOPT_CUSTOMREQUEST => strtoupper($method),
104+
CURLOPT_SSL_VERIFYPEER => false,
105+
]);
106+
107+
if (isset($headers)) {
108+
$this->headers = array_merge($this->headers, $headers);
109+
}
110+
if (isset($body)) {
111+
$encodedBody = json_encode($body);
112+
curl_setopt($curl, CURLOPT_POSTFIELDS, $encodedBody);
113+
$this->headers = array_merge($this->headers, ['Content-Type: application/json']);
114+
}
115+
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->headers);
116+
117+
$response = curl_exec($curl);
118+
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
119+
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
120+
121+
$responseBody = substr($response, $headerSize);
122+
$responseHeaders = substr($response, 0, $headerSize);
123+
124+
$responseHeaders = explode("\n", $responseHeaders);
125+
126+
curl_close($curl);
127+
128+
return new Response($statusCode, $responseBody, $responseHeaders);
129+
}
130+
131+
/**
132+
* Add variable values to the url.
133+
* (e.g. /your/api/{variable_value}/call)
134+
* Another example: if you have a PHP reserved word, such as and,
135+
* in your url, you must use this method.
136+
*
137+
* @param string $name name of the url segment
138+
*
139+
* @return Client object
140+
*/
141+
public function _($name = null)
142+
{
143+
return $this->buildClient($name);
144+
}
145+
146+
/**
147+
* Dynamically add method calls to the url, then call a method.
148+
* (e.g. client.name.name.method())
149+
*
150+
* @param string $name name of the dynamic method call or HTTP verb
151+
* @param array $args parameters passed with the method call
152+
*
153+
* @return Client or Response object
154+
*/
155+
public function __call($name, $args)
156+
{
157+
$name = strtolower($name);
158+
159+
if ($name === 'version') {
160+
$this->version = $args[0];
161+
return $this->_();
162+
}
163+
164+
if (in_array($name, $this->methods, true)) {
165+
$body = isset($args[0]) ? $args[0] : null;
166+
$queryParams = isset($args[1]) ? $args[1] : null;
167+
$url = $this->buildUrl($queryParams);
168+
$headers = isset($args[2]) ? $args[2] : null;
169+
return $this->makeRequest($name, $url, $body, $headers);
170+
}
171+
172+
return $this->_($name);
173+
}
174+
}

Diff for: lib/Response.php

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/**
4+
* HTTP Client library
5+
*
6+
* PHP version 5.4
7+
*
8+
* @author Matt Bernier <dx@sendgrid.com>
9+
* @author Elmer Thomas <dx@sendgrid.com>
10+
* @copyright 2016 SendGrid
11+
* @license https://opensource.org/licenses/MIT The MIT License
12+
* @version GIT: <git_id>
13+
* @link http://packagist.org/packages/sendgrid/php-http-client
14+
*/
15+
16+
namespace SendGrid;
17+
18+
/**
19+
* Holds the response from an API call.
20+
*/
21+
class Response
22+
{
23+
/** @var int */
24+
protected $statusCode;
25+
/** @var string */
26+
protected $body;
27+
/** @var array */
28+
protected $headers;
29+
30+
/**
31+
* Setup the response data
32+
*
33+
* @param int $statusCode the status code.
34+
* @param string $body the response body.
35+
* @param array $headers an array of response headers.
36+
*/
37+
public function __construct($statusCode = null, $body = null, $headers = null)
38+
{
39+
$this->statusCode = $statusCode;
40+
$this->body = $body;
41+
$this->headers = $headers;
42+
}
43+
44+
/**
45+
* The status code
46+
*
47+
* @return int
48+
*/
49+
public function statusCode()
50+
{
51+
return $this->statusCode;
52+
}
53+
54+
/**
55+
* The response body
56+
*
57+
* @return string
58+
*/
59+
public function body()
60+
{
61+
return $this->body;
62+
}
63+
64+
/**
65+
* The response headers
66+
*
67+
* @return array
68+
*/
69+
public function headers()
70+
{
71+
return $this->headers;
72+
}
73+
}

0 commit comments

Comments
 (0)