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:
<?php
/**
* Erply Books API PHP client
*
* @author Rene Korss <rene@koren.ee>
* @copyright Copyright (c) 2020 Rene Korss (https://koren.ee)
*/
namespace Koren\ErplyBooks;
use Http\Adapter\Guzzle6\Client as GuzzleClient;
use Http\Client\HttpClient;
use InvalidArgumentException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Erply Books API PHP client Client class
*
* @author Rene Korss <rene@koren.ee>
* @copyright Copyright (c) 2020 Rene Korss (https://koren.ee)
* @license MIT
*/
class Client
{
/**
* API base URL
* @var string
*/
const BASE_URL = 'https://accounting.erply.com/api';
/**
* API token
* @var String
*/
protected $token;
/**
* Http Client
* @var HttpClient
*/
protected $httpClient;
/**
* Additional query params
* @var array
*/
protected $query = [];
/**
* API client constructor
*
* @param string $token API token
* @param \Http\Client\HttpClient $client HTTP Client used for requests
*/
public function __construct($token, HttpClient $client = null)
{
// Fallback to Guzzle
if (is_null($client)) {
$client = new GuzzleClient();
}
$this->token = $token;
$this->setHttpClient($client);
}
/**
* Get API token
*/
public function getApiToken() : string
{
return $this->token;
}
/**
* Set the Http Client used for API requests
*
* This allows the default http client to be swapped out for a HTTPlug compatible
* replacement.
*
* @param \Http\Client\HttpClient $client
*
* @return \Resolve\Api\Client
*/
public function setHttpClient(HttpClient $client) : self
{
$this->httpClient = $client;
return $this;
}
/**
* Get the Http Client used for API requests
*
* @return \Http\Client\HttpClient
*/
public function getHttpClient() : HttpClient
{
return $this->httpClient;
}
/**
* Adds token to request
*
* @param \Psr\Http\Message\RequestInterface $request Request being sent
*
* @return \Psr\Http\Message\RequestInterface
*/
public function authenticate(RequestInterface $request) : RequestInterface
{
$credentials = ['token' => $this->token];
$request = $request->withHeader('Content-Type', 'application/json');
$body = $request->getBody();
$body->rewind();
$content = $body->getContents();
$params = json_decode($content, true);
$params = array_merge((array)$params, $credentials);
$body->rewind();
$body->write(json_encode($params));
$request = $request->withHeader('Accept', 'application/json');
return $request;
}
/**
* Add query param
*
* @param array $param Key and value array of param
*
* @return \Resolve\Api\Client
*/
public function withQuery(array $param) : self
{
$this->query = array_merge($this->query, $param);
return $this;
}
/**
* Add query param
*
* @param \Psr\Http\Message\RequestInterface $request Request being sent
*
* @return \Psr\Http\Message\RequestInterface
*/
protected function withQueryParams(RequestInterface $request) : RequestInterface
{
if (count($this->query) > 0) {
$query = [];
parse_str($request->getUri()->getQuery(), $query);
$query = array_merge($query, $this->query);
$request = $request->withUri($request->getUri()->withQuery(http_build_query($query)));
}
return $request;
}
/**
* Send request
*
* @param \Psr\Http\Message\RequestInterface $request Request being sent
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function sendRequest(RequestInterface $request) : ResponseInterface
{
// Add apiKey to request
$request = $this->authenticate($request);
// Add query params if any
$request = $this->withQueryParams($request);
$response = $this->getHttpClient()->sendRequest($request);
return $response;
}
/**
* Magic method to get resource object
*
* @return mixed Resource
*
* @throws \InvalidArgumentException if resource is not found
* @ignore
* @SuppressWarnings(PHPMD.MissingImport)
*/
public function __call($name, $args)
{
$className = 'Koren\ErplyBooks\Resource\\'.$name;
if (!class_exists($className)) {
throw new InvalidArgumentException('Resource '.$name.' not found.');
}
$resource = new $className;
$resource->setClient($this);
return $resource;
}
}