Skip to content

Library refactoring around PSR-2 / PSR-4 code standards #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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