diff --git a/composer.json b/composer.json index a174c7f..b221f9d 100644 --- a/composer.json +++ b/composer.json @@ -17,12 +17,13 @@ ], "require": { "php": "^8.4", - "spatie/laravel-package-tools": "^1.16", - "illuminate/contracts": "^10.0||^11.0||^12.0", "ext-curl": "*", "ext-json": "*", + "guzzlehttp/guzzle": "7.x", + "illuminate/contracts": "^10.0||^11.0||^12.0", "league/oauth2-client": "^2", - "guzzlehttp/guzzle": "7.x" + "spatie/laravel-data": "^4.15", + "spatie/laravel-package-tools": "^1.16" }, "require-dev": { "laravel/pint": "^1.14", diff --git a/src/DTOs/CompaignDTO.php b/src/DTOs/CompaignDTO.php index 67fd6e9..fc56d23 100644 --- a/src/DTOs/CompaignDTO.php +++ b/src/DTOs/CompaignDTO.php @@ -2,7 +2,9 @@ namespace Coderflex\LaravelSendy\DTOs; -class CompaignDTO +use Spatie\LaravelData\Data; + +class CompaignDTO extends Data { public function __construct( // diff --git a/src/DTOs/SubscribersDTO.php b/src/DTOs/SubscribersDTO.php index 23d8e8d..8aed236 100644 --- a/src/DTOs/SubscribersDTO.php +++ b/src/DTOs/SubscribersDTO.php @@ -2,7 +2,9 @@ namespace Coderflex\LaravelSendy\DTOs; -class SubscribersDTO +use Spatie\LaravelData\Data; + +class SubscribersDTO extends Data { public function __construct( // diff --git a/src/LaravelSendy.php b/src/LaravelSendy.php index f018533..d75fa91 100644 --- a/src/LaravelSendy.php +++ b/src/LaravelSendy.php @@ -6,9 +6,30 @@ use Coderflex\LaravelSendy\Resources\Resources\Campaigns; use Coderflex\LaravelSendy\Resources\Resources\Lists; use Coderflex\LaravelSendy\Resources\Resources\Subscribers; +use Exception; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; class LaravelSendy { + protected string $apiKey; + + protected string $apiUrl; + + public function __construct() + { + if (blank(config('laravel-sendy.api_key'))) { + throw new Exception('API Key is not set in the config file.'); + } + + if (blank(config('laravel-sendy.api_url'))) { + throw new Exception('API URL is not set in the config file.'); + } + + $this->apiKey = config('laravel-sendy.api_key'); + $this->apiUrl = config('laravel-sendy.api_url'); + } + public function subscribers(): Subscribers { return new Subscribers; @@ -28,4 +49,65 @@ public function campaigns(): Campaigns { return new Campaigns; } + + public function __call(string $function, array $args) + { + $options = ['get', 'post', 'put', 'delete', 'patch']; + $path = (isset($args[0])) ? $args[0] : null; + $data = (isset($args[1])) ? $args[1] : []; + $headers = (isset($args[2])) ? $args[2] : []; + + if (! in_array($function, $options)) { + throw new Exception("Method {$function} not found."); + } + + return self::guzzle( + type: $function, + request: $path, + data: $data, + headers: $headers + ); + } + + /** + * @throws \Exception + */ + protected function guzzle(string $type, string $request, array $data = [], array $headers = []): mixed + { + try { + $client = new Client; + + $mainHeaders = [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.$this->apiKey, + ]; + + $headers = is_array($headers) && count($headers) > 0 + ? array_merge($mainHeaders, $headers) + : $mainHeaders; + + $response = $client->$type($this->apiUrl.$request, [ + 'headers' => $headers, + 'body' => json_encode($data), + ]); + + $responseObject = $response->getBody()->getContents(); + + return $this->isJson($responseObject) + ? json_decode($responseObject, true) + : $responseObject; + + } catch (ClientException $th) { + throw new Exception('Error: '.$th->getMessage()); + } catch (Exception $th) { + throw new Exception('Error: '.$th->getMessage()); + } + } + + protected function isJson(string $string): bool + { + return is_array(json_decode($string)) && + (json_last_error() === JSON_ERROR_NONE); + } } diff --git a/src/Resources/Brands.php b/src/Resources/Brands.php index c7f9d2b..03da1af 100644 --- a/src/Resources/Brands.php +++ b/src/Resources/Brands.php @@ -2,10 +2,12 @@ namespace Coderflex\LaravelSendy\Resources\Resources; +use Coderflex\LaravelSendy\Facades\LaravelSendy; + class Brands { public function get() { - // + return LaravelSendy::get('/api/brands/get-brands.php'); } } diff --git a/src/Resources/Campaigns.php b/src/Resources/Campaigns.php index ecf3957..6338fb0 100644 --- a/src/Resources/Campaigns.php +++ b/src/Resources/Campaigns.php @@ -2,10 +2,18 @@ namespace Coderflex\LaravelSendy\Resources\Resources; +use Coderflex\LaravelSendy\DTOs\CompaignDTO; +use Coderflex\LaravelSendy\Facades\LaravelSendy; + class Campaigns { public function create(array $data) { - // + $data = CompaignDTO::from($data)->toArray(); + + // validate the data + // $this->validate($data); + + return LaravelSendy::post('/api/campaigns/create.php', $data); } } diff --git a/src/Resources/Lists.php b/src/Resources/Lists.php index ad5c261..82a5f78 100644 --- a/src/Resources/Lists.php +++ b/src/Resources/Lists.php @@ -2,10 +2,22 @@ namespace Coderflex\LaravelSendy\Resources\Resources; +use Coderflex\LaravelSendy\Facades\LaravelSendy; + class Lists { + /** + * Get all lists for a specific brand. + * + * @return array + */ public function get(int $brandId, bool $includeHidden = false) { - // Implementation to get lists + $params = http_build_query([ + 'brand_id' => $brandId, + 'include_hidden' => $includeHidden, + ]); + + return LaravelSendy::get('/api/lists/get-lists.php', $params); } } diff --git a/src/Resources/Subscribers.php b/src/Resources/Subscribers.php index 53248af..382b322 100644 --- a/src/Resources/Subscribers.php +++ b/src/Resources/Subscribers.php @@ -2,25 +2,57 @@ namespace Coderflex\LaravelSendy\Resources\Resources; +use Coderflex\LaravelSendy\DTOs\SubscribersDTO; +use Coderflex\LaravelSendy\Facades\LaravelSendy; + class Subscribers { public function subscribe(array $data) { - // + $data = SubscribersDTO::from($data)->toArray(); + + // validate the data + + return LaravelSendy::post('subscribe', $data); } - public function unsubscribe(int $listId, string $email) + public function unsubscribe(int $listId, string $email, bool $plainTextResponse) { - // + $data = http_build_query([ + 'list' => $listId, + 'email' => $email, + 'boolean' => $plainTextResponse, + ]); + + return LaravelSendy::post('/api/subscribers/unsubscribe.php', $data); } public function delete(int $listId, string $email) { - // + $data = http_build_query([ + 'list_id' => $listId, + 'email' => $email, + ]); + + return LaravelSendy::post('/api/subscribers/delete.php', $data); + } + + public function status(int $listId, string $email) + { + $data = http_build_query([ + 'list_id' => $listId, + 'email' => $email, + ]); + + return LaravelSendy::post('/api/subscribers/subscription-status.php', $data); } public function count(int $listId) { - // + $data = http_build_query([ + 'list_id' => $listId, + ]); + + return LaravelSendy::post('/api/subscribers/active-subscriber-count.php', $data); } }