Skip to content

Commit

Permalink
Merge pull request #6 from misantron/refactoring
Browse files Browse the repository at this point in the history
Library refactoring around PSR-2 / PSR-4 code standards
  • Loading branch information
thinkingserious authored Sep 13, 2016
2 parents 2319345 + e5de48e commit 55ffd69
Show file tree
Hide file tree
Showing 10 changed files with 380 additions and 321 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.lock
vendor/
*.old
.idea/
15 changes: 10 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"version": "3.1.0",
"require-dev": {
"phpunit/phpunit": "~4.4",
"squizlabs/php_codesniffer": "2.*"
"squizlabs/php_codesniffer": "~2.0"
},
"homepage": "http://github.com/sendgrid/php-http-client",
"keywords": ["SendGrid", "HTTP", "REST", "API", "Fluent"],
"license": "MIT",
"authors": [
{
"name": "Matt Bernier",
"email": "dx@sendgrid.com"
"name": "Matt Bernier",
"email": "dx@sendgrid.com"
},
{
"name": "Elmer Thomas",
Expand All @@ -24,8 +24,13 @@
"php": ">=5.6"
},
"autoload": {
"psr-0": {
"SendGrid": "lib/"
"psr-4": {
"SendGrid\\": "lib/"
}
},
"autoload-dev": {
"psr-4": {
"SendGrid\\Test\\": "test/unit/"
}
}
}
51 changes: 25 additions & 26 deletions examples/example.php
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
<?php

// If running this outside of this context, use the following include and
// comment out the two includes below
// require __DIR__ . '/vendor/autoload.php';
include(dirname(__DIR__).'/lib/SendGrid/client.php');
include(dirname(__DIR__) . '/lib/Client.php');
// This gets the parent directory, for your current directory use getcwd()
$path_to_config = dirname(__DIR__);
$api_key = getenv('SENDGRID_API_KEY');
$headers = array('Authorization: Bearer '.$api_key);
$client = new SendGrid\Client('https://api.sendgrid.com', $headers, '/v3', null);
$apiKey = getenv('SENDGRID_API_KEY');
$headers = ['Authorization: Bearer ' . $apiKey];
$client = new SendGrid\Client('https://api.sendgrid.com', $headers, '/v3');

// GET Collection
$query_params = array('limit' => 100, 'offset' => 0);
$request_headers = array('X-Mock: 200');
$query_params = ['limit' => 100, 'offset' => 0];
$request_headers = ['X-Mock: 200'];
$response = $client->api_keys()->get(null, $query_params, $request_headers);
echo $response->statusCode();
echo $response->body();
echo $response->headers();

// POST
$request_body = array(
'name' => 'My PHP API Key',
'scopes' => array(
'mail.send',
'alerts.create',
'alerts.read'
)
);
$request_body = [
'name' => 'My PHP API Key',
'scopes' => [
'mail.send',
'alerts.create',
'alerts.read'
]
];
$response = $client->api_keys()->post($request_body);
echo $response->statusCode();
echo $response->body();
Expand All @@ -40,22 +41,22 @@
echo $response->headers();

// PATCH
$request_body = array(
'name' => 'A New Hope'
);
$request_body = [
'name' => 'A New Hope'
];
$response = $client->api_keys()->_($api_key_id)->patch($request_body);
echo $response->statusCode();
echo $response->body();
echo $response->headers();

// PUT
$request_body = array(
'name' => 'A New Hope',
'scopes' => array(
'user.profile.read',
'user.profile.update'
)
);
$request_body = [
'name' => 'A New Hope',
'scopes' => [
'user.profile.read',
'user.profile.update'
]
];
$response = $client->api_keys()->_($api_key_id)->put($request_body);
echo $response->statusCode();
echo $response->body();
Expand All @@ -66,5 +67,3 @@
echo $response->statusCode();
echo $response->body();
echo $response->headers();

?>
174 changes: 174 additions & 0 deletions lib/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php

/**
* HTTP Client library
*
* PHP version 5.4
*
* @author Matt Bernier <dx@sendgrid.com>
* @author Elmer Thomas <dx@sendgrid.com>
* @copyright 2016 SendGrid
* @license https://opensource.org/licenses/MIT The MIT License
* @version GIT: <git_id>
* @link http://packagist.org/packages/sendgrid/php-http-client
*/

namespace SendGrid;

/**
* Quickly and easily access any REST or REST-like API.
*/
class Client
{
/** @var string */
protected $host;
/** @var array */
protected $headers;
/** @var string */
protected $version;
/** @var array */
protected $path;
/** @var array */
private $methods;

/**
* Initialize the client
*
* @param string $host the base url (e.g. https://api.sendgrid.com)
* @param array $headers global request headers
* @param string $version api version (configurable)
* @param array $path holds the segments of the url path
*/
public function __construct($host, $headers = null, $version = null, $path = null)
{
$this->host = $host;
$this->headers = $headers ?: [];
$this->version = $version;
$this->path = $path ?: [];
// These are the supported HTTP verbs
$this->methods = ['delete', 'get', 'patch', 'post', 'put'];
}

/**
* Make a new Client object
*
* @param string $name name of the url segment
*
* @return Client object
*/
private function buildClient($name = null)
{
if (isset($name)) {
$this->path[] = $name;
}
$client = new Client($this->host, $this->headers, $this->version, $this->path);
$this->path = [];
return $client;
}

/**
* Build the final URL to be passed
*
* @param array $queryParams an array of all the query parameters
*
* @return string
*/
private function buildUrl($queryParams = null)
{
$path = '/' . implode('/', $this->path);
if (isset($queryParams)) {
$path .= '?' . http_build_query($queryParams);
}
return sprintf('%s%s%s', $this->host, $this->version ?: '', $path);
}

/**
* Make the API call and return the response. This is separated into
* it's own function, so we can mock it easily for testing.
*
* @param string $method the HTTP verb
* @param string $url the final url to call
* @param array $body request body
* @param array $headers any additional request headers
*
* @return Response object
*/
public function makeRequest($method, $url, $body = null, $headers = null)
{
$curl = curl_init($url);

curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => 1,
CURLOPT_CUSTOMREQUEST => strtoupper($method),
CURLOPT_SSL_VERIFYPEER => false,
]);

if (isset($headers)) {
$this->headers = array_merge($this->headers, $headers);
}
if (isset($body)) {
$encodedBody = json_encode($body);
curl_setopt($curl, CURLOPT_POSTFIELDS, $encodedBody);
$this->headers = array_merge($this->headers, ['Content-Type: application/json']);
}
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->headers);

$response = curl_exec($curl);
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

$responseBody = substr($response, $headerSize);
$responseHeaders = substr($response, 0, $headerSize);

$responseHeaders = explode("\n", $responseHeaders);

curl_close($curl);

return new Response($statusCode, $responseBody, $responseHeaders);
}

/**
* Add variable values to the url.
* (e.g. /your/api/{variable_value}/call)
* Another example: if you have a PHP reserved word, such as and,
* in your url, you must use this method.
*
* @param string $name name of the url segment
*
* @return Client object
*/
public function _($name = null)
{
return $this->buildClient($name);
}

/**
* Dynamically add method calls to the url, then call a method.
* (e.g. client.name.name.method())
*
* @param string $name name of the dynamic method call or HTTP verb
* @param array $args parameters passed with the method call
*
* @return Client or Response object
*/
public function __call($name, $args)
{
$name = strtolower($name);

if ($name === 'version') {
$this->version = $args[0];
return $this->_();
}

if (in_array($name, $this->methods, true)) {
$body = isset($args[0]) ? $args[0] : null;
$queryParams = isset($args[1]) ? $args[1] : null;
$url = $this->buildUrl($queryParams);
$headers = isset($args[2]) ? $args[2] : null;
return $this->makeRequest($name, $url, $body, $headers);
}

return $this->_($name);
}
}
73 changes: 73 additions & 0 deletions lib/Response.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* HTTP Client library
*
* PHP version 5.4
*
* @author Matt Bernier <dx@sendgrid.com>
* @author Elmer Thomas <dx@sendgrid.com>
* @copyright 2016 SendGrid
* @license https://opensource.org/licenses/MIT The MIT License
* @version GIT: <git_id>
* @link http://packagist.org/packages/sendgrid/php-http-client
*/

namespace SendGrid;

/**
* Holds the response from an API call.
*/
class Response
{
/** @var int */
protected $statusCode;
/** @var string */
protected $body;
/** @var array */
protected $headers;

/**
* Setup the response data
*
* @param int $statusCode the status code.
* @param string $body the response body.
* @param array $headers an array of response headers.
*/
public function __construct($statusCode = null, $body = null, $headers = null)
{
$this->statusCode = $statusCode;
$this->body = $body;
$this->headers = $headers;
}

/**
* The status code
*
* @return int
*/
public function statusCode()
{
return $this->statusCode;
}

/**
* The response body
*
* @return string
*/
public function body()
{
return $this->body;
}

/**
* The response headers
*
* @return array
*/
public function headers()
{
return $this->headers;
}
}
Loading

0 comments on commit 55ffd69

Please sign in to comment.