Initial release with Customer and Domain
This commit is contained in:
commit
379f20590e
22
composer.json
Normal file
22
composer.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "leenooks/dreamscape",
|
||||
"description": "Dreamscape API",
|
||||
"keywords": ["laravel","leenooks","dreamscape"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Deon George",
|
||||
"email": "deon@leenooks.net"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"jenssegers/model": "^1.5"
|
||||
},
|
||||
"require-dev": {
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dreamscape\\": "src"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
224
src/API.php
Normal file
224
src/API.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
namespace Dreamscape;
|
||||
|
||||
use Dreamscape\Response\Base;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use Dreamscape\Response\Generic;
|
||||
|
||||
final class API
|
||||
{
|
||||
private const LOGKEY = 'API';
|
||||
private const CACHE_TIME = 60*60*12;
|
||||
private const MAX_LIMIT = 100;
|
||||
|
||||
// Our reseller details
|
||||
private string $key;
|
||||
private string $url;
|
||||
|
||||
public function __construct(string $id,string $key,bool $tryprod=FALSE)
|
||||
{
|
||||
$this->url = (config('app.env') == 'local' && ! $tryprod) ? 'https://reseller-api.sandbox.ds.network' : 'https://reseller-api.ds.network';
|
||||
$this->key = $key;
|
||||
|
||||
Log::debug(sprintf('%s:Dreamscape API for id [%s]',static::LOGKEY,$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the API
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @return object|array
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function execute(string $path,array $parameters=[])
|
||||
{
|
||||
$url = sprintf('%s/%s',$this->url,$path);
|
||||
$request_id = md5(uniqid().microtime(true));
|
||||
$signature = md5($request_id.$this->key);
|
||||
$method = Arr::get($parameters,'method','GET');
|
||||
|
||||
if ($parameters)
|
||||
Arr::forget($parameters,'method');
|
||||
|
||||
// If we are passed an array, we'll do a normal post.
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$request = $this->prepareRequest(
|
||||
$url,
|
||||
$parameters,
|
||||
[
|
||||
'accept: application/json',
|
||||
'Api-Request-Id: '.$request_id,
|
||||
'Api-Signature: '.$signature,
|
||||
]
|
||||
);
|
||||
break;
|
||||
|
||||
case 'POST':
|
||||
$request = $this->prepareRequestPost(
|
||||
$url,
|
||||
$parameters,
|
||||
[
|
||||
'accept: application/json',
|
||||
'Api-Request-Id: '.$request_id,
|
||||
'Api-Signature: '.$signature,
|
||||
]
|
||||
);
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
$request = $this->prepareRequestPut(
|
||||
$url,
|
||||
$parameters,
|
||||
[
|
||||
'accept: application/json',
|
||||
'Api-Request-Id: '.$request_id,
|
||||
'Api-Signature: '.$signature,
|
||||
]
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception(sprintf('Unknown method: %s',$method));
|
||||
}
|
||||
|
||||
$key = md5($path.serialize($parameters));
|
||||
|
||||
//Cache::forget($key);
|
||||
$result = Cache::remember($key,self::CACHE_TIME,function() use ($request,$url) {
|
||||
try {
|
||||
$response = curl_exec($request);
|
||||
|
||||
switch($x=curl_getinfo($request,CURLINFO_HTTP_CODE)) {
|
||||
case 400:
|
||||
case 404:
|
||||
dump([$xx=curl_getinfo($request),'response'=>$response]);
|
||||
|
||||
throw new \Exception(sprintf('CURL exec returned %d: %s (%s)',$x,curl_error($request),serialize($xx)));
|
||||
}
|
||||
|
||||
curl_close($request);
|
||||
return json_decode($response);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
dump(['error'=>$e->getMessage()]);
|
||||
Log::error(sprintf('%s:Got an error while posting to [%s] (%s)',static::LOGKEY,$url,$e->getMessage()),['m'=>__METHOD__]);
|
||||
|
||||
curl_close($request);
|
||||
throw new \Exception($e->getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of our clients
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return Generic
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getCustomers(array $parameters=[]): Generic
|
||||
{
|
||||
Log::debug(sprintf('%s:Get a list of customers',static::LOGKEY));
|
||||
$key = 'customers';
|
||||
|
||||
$fetchall = FALSE;
|
||||
if (Arr::get($parameters,'fetchall')) {
|
||||
Arr::forget($parameters,['fetchall']);
|
||||
$parameters['limit'] = self::MAX_LIMIT;
|
||||
$parameters['page'] = 1;
|
||||
|
||||
$fetchall = TRUE;
|
||||
}
|
||||
|
||||
$o = new Generic($this->execute($key,$parameters),$key);
|
||||
|
||||
return $fetchall ? $this->fetchall($o,$key,$parameters) : $o;
|
||||
}
|
||||
|
||||
private function fetchall(Base $o,string $path,array $parameters): Base
|
||||
{
|
||||
while ($o->hasMore()) {
|
||||
$parameters['page']++;
|
||||
|
||||
$o->merge($this->execute($path,$parameters));
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of our clients domains
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return Generic
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getDomains(array $parameters=[]): Generic
|
||||
{
|
||||
Log::debug(sprintf('%s:Get a list of domains',static::LOGKEY));
|
||||
|
||||
return new Generic($this->execute('domains',$parameters),'domains');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of our available product types
|
||||
*
|
||||
* @return Generic
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getProductTypes(): Generic
|
||||
{
|
||||
Log::debug(sprintf('%s:Get a list of product types',static::LOGKEY));
|
||||
|
||||
return new Generic($this->execute('products/types'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the API call
|
||||
*
|
||||
* @param $url
|
||||
* @param array $parameters
|
||||
* @param array $headers
|
||||
* @return resource
|
||||
*/
|
||||
private function prepareRequest($url,array $parameters=[],array $headers=[])
|
||||
{
|
||||
$request = curl_init();
|
||||
|
||||
curl_setopt($request,CURLOPT_URL,$url.($parameters ? '?'.http_build_query($parameters) : ''));
|
||||
curl_setopt($request,CURLOPT_RETURNTRANSFER,TRUE);
|
||||
if ($headers)
|
||||
curl_setopt($request,CURLOPT_HTTPHEADER,$headers);
|
||||
curl_setopt($request,CURLINFO_HEADER_OUT,TRUE);
|
||||
curl_setopt($request,CURLOPT_SSL_VERIFYPEER,FALSE);
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function prepareRequestPost($url,$parameters='',$headers=[])
|
||||
{
|
||||
$request = $this->prepareRequest($url,[],$headers);
|
||||
curl_setopt($request,CURLOPT_POST,TRUE);
|
||||
curl_setopt($request,CURLOPT_POSTFIELDS,json_encode($parameters));
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function prepareRequestPut($url,$parameters='',$headers=[])
|
||||
{
|
||||
$request = $this->prepareRequest($url,[],$headers);
|
||||
//curl_setopt($request,CURLOPT_PUT,TRUE);
|
||||
curl_setopt($request,CURLOPT_CUSTOMREQUEST,'PUT');
|
||||
curl_setopt($request,CURLOPT_POSTFIELDS,json_encode($parameters));
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
32
src/Models/Customer.php
Normal file
32
src/Models/Customer.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Dreamscape\Models;
|
||||
|
||||
use Jenssegers\Model\Model;
|
||||
|
||||
/*
|
||||
"id" => 5249071
|
||||
"status_id" => 1
|
||||
"username" => "graytech"
|
||||
"first_name" => "Deon"
|
||||
"last_name" => "George"
|
||||
"address" => "48B Celia Street"
|
||||
"city" => "Bentleigh East"
|
||||
"country" => "AU"
|
||||
"state" => "VIC"
|
||||
"post_code" => "3165"
|
||||
"country_code" => 61
|
||||
"phone" => "354101135"
|
||||
"mobile" => null
|
||||
"email" => "deon..@..t.au"
|
||||
"currency" => "AUD"
|
||||
"account_type" => "business"
|
||||
"business_name" => "Graytech Hosting Pty Ltd"
|
||||
"business_number_type" => "ABN"
|
||||
"business_number" => "49106229476"
|
||||
"date_added" => "2013-05-21T19:43:06+00:00"
|
||||
*/
|
||||
|
||||
final class Customer extends Model
|
||||
{
|
||||
}
|
65
src/Models/Domain.php
Normal file
65
src/Models/Domain.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Dreamscape\Models;
|
||||
|
||||
use Jenssegers\Model\Model;
|
||||
|
||||
/*
|
||||
"id" => 20756501
|
||||
"domain_name" => "graytech.net.au"
|
||||
"auth_key" => ""
|
||||
"status_id" => 2
|
||||
"period" => 24
|
||||
"start_date" => "2021-07-19T06:18:38+00:00"
|
||||
"expiry_date" => "2023-09-22T00:00:00+00:00"
|
||||
"customer_id" => 5249071
|
||||
"registrant_id" => 22203773
|
||||
"admin_contact_id" => 5249071
|
||||
"billing_contact_id" => 5249071
|
||||
"tech_contact_id" => 5249071
|
||||
"name_servers" => array:2 [
|
||||
0 => {#1109
|
||||
+"host": "arch.ns.cloudflare.com"
|
||||
+"ip": "173.245.59.68,2803:f800:50::6ca2:c144"
|
||||
}
|
||||
1 => {#1110
|
||||
+"host": "brianna.ns.cloudflare.com"
|
||||
+"ip": "173.245.58.245,2a06:98c1:50::ac40:20f5"
|
||||
}
|
||||
]
|
||||
"is_locked" => false
|
||||
"privacy" => false
|
||||
"eligibility_data" => array:7 [
|
||||
0 => {#1111
|
||||
+"name": "business_type"
|
||||
+"value": "Company"
|
||||
}
|
||||
1 => {#1112
|
||||
+"name": "business_name"
|
||||
+"value": null
|
||||
}
|
||||
2 => {#1113
|
||||
+"name": "business_number_type"
|
||||
+"value": "ACN"
|
||||
}
|
||||
3 => {#1114
|
||||
+"name": "business_number"
|
||||
+"value": "106 229 476"
|
||||
}
|
||||
4 => {#1115
|
||||
+"name": "trading_name"
|
||||
+"value": "Graytech Hosting Pty Ltd"
|
||||
}
|
||||
5 => {#1116
|
||||
+"name": "trading_number_type"
|
||||
+"value": "ACN"
|
||||
}
|
||||
6 => {#1117
|
||||
+"name": "trading_number"
|
||||
+"value": "106 229 476"
|
||||
}
|
||||
*/
|
||||
|
||||
final class Domain extends Model
|
||||
{
|
||||
}
|
214
src/Response/Base.php
Normal file
214
src/Response/Base.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace Dreamscape\Response;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use Dreamscape\Models\{Customer,Domain};
|
||||
|
||||
/**
|
||||
* This parent class handles responses received from Trello
|
||||
*
|
||||
* @note: This class is used for events not specifically created.
|
||||
*/
|
||||
abstract class Base implements \JsonSerializable, \Countable, \ArrayAccess, \Iterator
|
||||
{
|
||||
protected const LOGKEY = 'RB-';
|
||||
|
||||
protected Collection $_data;
|
||||
protected bool $_status;
|
||||
protected object $_pagination;
|
||||
protected ?string $_type;
|
||||
|
||||
private ?int $counter = NULL;
|
||||
protected const TYPES = [
|
||||
'customers',
|
||||
'domains',
|
||||
];
|
||||
|
||||
/**
|
||||
* Default Constructor Setup
|
||||
*
|
||||
* @param object $response
|
||||
* @param string $type
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(object $response,string $type)
|
||||
{
|
||||
if (! in_array($type,self::TYPES))
|
||||
throw new \Exception('Unknown data type: '.$type);
|
||||
|
||||
$this->_data = $this->data($response,$type);
|
||||
$this->_status = $response->status;
|
||||
$this->_pagination = $response->pagination;
|
||||
$this->_type = $type;
|
||||
|
||||
// This is only for child classes
|
||||
if (get_class($this) == Base::class) {
|
||||
Log::debug(sprintf('%s:Dreamscape RESPONSE Initialised [%s]',static::LOGKEY,get_class($this)),['m'=>__METHOD__]);
|
||||
|
||||
if (App::environment() == 'dev')
|
||||
file_put_contents('/tmp/response',print_r($this,TRUE),FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/* ABSTRACT */
|
||||
|
||||
/**
|
||||
* When we json_encode this object, this is the data that will be returned
|
||||
*/
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->_data ?: new \stdClass;
|
||||
}
|
||||
|
||||
public function current(): mixed
|
||||
{
|
||||
return $this->_data[$this->counter];
|
||||
}
|
||||
|
||||
public function next(): void
|
||||
{
|
||||
$this->counter++;
|
||||
}
|
||||
|
||||
public function key(): mixed
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
public function valid(): bool
|
||||
{
|
||||
return isset($this->_data[$this->counter]);
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->counter = 0;
|
||||
}
|
||||
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return $this->has($offset);
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->_data->get($offset);
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
throw new \Exception('Method not implemented: '.__METHOD__);
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
$this->_data->forget($offset);
|
||||
|
||||
// Rekey the collection
|
||||
$this->_data = $this->_data->values();
|
||||
|
||||
// Reset the counter if we have deleted a value before it
|
||||
if ($offset < $this->counter)
|
||||
$this->counter--;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->_data);
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
* Convert our response into a collection of the appropriate model
|
||||
*
|
||||
* @param object $response
|
||||
* @param string $type
|
||||
* @return Collection
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function data(object $response,string $type): Collection
|
||||
{
|
||||
switch ($type) {
|
||||
case 'customers':
|
||||
$data = collect(Customer::hydrate($response->data));
|
||||
break;
|
||||
|
||||
case 'domains':
|
||||
$data = collect(Domain::hydrate($response->data));
|
||||
break;
|
||||
|
||||
default: throw new \Exception('Unknown object type: '.$this->_type);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if there are more values to obtain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMore(): bool
|
||||
{
|
||||
return $this->_status && ($this->count() < $this->totalItems());
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge more values to the result
|
||||
*
|
||||
* @param object $response
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function merge(object $response): void
|
||||
{
|
||||
$this->_data = $this->_data->merge($this->data($response,$this->_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current resultset page number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function page(): int
|
||||
{
|
||||
return $this->_pagination->current_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for an item in the result
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function search(string $key, mixed $value): mixed
|
||||
{
|
||||
return $this->_data->search(function($item) use ($key,$value) { return $item->{$key} == $value; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result status
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function status(): bool
|
||||
{
|
||||
return $this->_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total items available
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function totalItems(): int
|
||||
{
|
||||
return $this->_pagination->total_items;
|
||||
}
|
||||
}
|
11
src/Response/Generic.php
Normal file
11
src/Response/Generic.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Dreamscape\Response;
|
||||
|
||||
/**
|
||||
* This is a Generic Dreamscape Response to API calls
|
||||
*/
|
||||
class Generic extends Base
|
||||
{
|
||||
protected const LOGKEY = 'RGD';
|
||||
}
|
Loading…
Reference in New Issue
Block a user