summaryrefslogtreecommitdiffstats
path: root/lib/Client.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Client.php')
-rw-r--r--lib/Client.php174
1 files changed, 174 insertions, 0 deletions
diff --git a/lib/Client.php b/lib/Client.php
new file mode 100644
index 0000000..c14344a
--- /dev/null
+++ b/lib/Client.php
@@ -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);
+ }
+}