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