diff --git a/Example/ResponseExample.php b/Example/ResponseExample.php index 7156ac9..22ad568 100644 --- a/Example/ResponseExample.php +++ b/Example/ResponseExample.php @@ -16,6 +16,7 @@ use Serhiy\Pushover\Api\Message\Message; use Serhiy\Pushover\Api\Message\Notification; use Serhiy\Pushover\Api\Message\Recipient; +use Serhiy\Pushover\Api\Message\Request; use Serhiy\Pushover\Api\Message\Response; /** @@ -46,13 +47,21 @@ public function responseExample() */ $response = $client->push($notification); + /** + * True if request was successful, false otherwise. Reflects $requestStatus property. + * + * @var bool + */ + $response->isSuccessful(); + /** * Status returned by Pushover API. * Either 1 if successful or something other than 1 if unsuccessful. + * Reflects $isSuccessful property. * * @var int */ - $response->getStatus(); + $response->getRequestStatus(); /** * Request returned by Pushover API. @@ -60,7 +69,7 @@ public function responseExample() * * @var string */ - $response->getRequest(); + $response->getRequestToken(); /** * Receipt. @@ -87,5 +96,20 @@ public function responseExample() * @var mixed */ $response->getCurlResponse(); + + /** + * Object Containing request. + * It contains notification object, which in turn contains application, recipient and message objects. + * It also contains array for CURLOPT_POSTFIELDS curl argument and API URL. + * + * @var Request + */ + $request = $response->getRequest(); + $request->getNotification(); // Notification object + $request->getNotification()->getApplication(); + $request->getNotification()->getRecipient(); + $request->getNotification()->getMessage(); + $request->getCurlPostFields(); // array, array for CURLOPT_POSTFIELDS curl argument + $request->getFullUrl(); // string, API URL } } diff --git a/README.md b/README.md index cb4ff6c..8d10d27 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ composer require "serhiy/pushover" Instantiate the client, application and recipient of the notification: ```php +use Serhiy\Pushover\Api\Message\Client; +use Serhiy\Pushover\Api\Message\Application; +use Serhiy\Pushover\Api\Message\Recipient; + $client = new Client(); $application = new Application("replace_with_pushover_application_api_token"); $recipient = new Recipient("replace_with_pushover_user_key"); @@ -47,26 +51,73 @@ Or use Dependency Injection to inject them into the services of your app. Compose a message: ```php +use Serhiy\Pushover\Api\Message\Message; + $message = new Message("This is a test message", "This is a title of the message"); ``` Create notification: ```php +use Serhiy\Pushover\Api\Message\Notification; + $notification = new Notification($application, $recipient, $message); ``` -And push it: +Push it: ```php -/** @var Response $response */ +/** @var \Serhiy\Pushover\Api\Message\Response $response */ $response = $client->push($notification); ``` -Client returns Response object which contains the status, request ID, receipt if any and errors array. +## Working with response + +*Note: For complete example refer to [ResponseExample.php](Example/ResponseExample.php)* + +Client returns Response object. Checking if the message was accepted is easy: + +```php +if ($response->isSuccessful()) { + // ... +} +``` + +One can get status and token returned by Pushover: + +```php +$response->getRequestStatus(); +$response->getRequestToken(); +``` + +Or even unmodified json response from the API (json_decode into an array if needed): + +```php +$response->getCurlResponse(); +``` +Response also contains original Request object: + +```php +/** @var \Serhiy\Pushover\Api\Message\Request $request */ +$request = $response->getRequest(); +``` + +Request contains original notification object, which in turn contains application, recipient and message objects. + +```php +/** @var \Serhiy\Pushover\Api\Message\Notification $notification */ +$notification = $request->getNotification(); // Notification object +$notification->getApplication(); +$notification->getRecipient(); +$notification->getMessage(); +``` + +As well as an array for CURLOPT_POSTFIELDS curl argument and full API URL. + ```php -var_dump($response); +$request->getCurlPostFields(); +$request->getFullUrl(); ``` For more code examples, see `Example` folder in the root of the project. You may also generate and see code documentation. diff --git a/src/Api/Message/Client.php b/src/Api/Message/Client.php index 01e7882..1886cf6 100644 --- a/src/Api/Message/Client.php +++ b/src/Api/Message/Client.php @@ -26,8 +26,20 @@ class Client extends ApiClient */ const API_PATH = 'messages.json'; + /** + * @var Request + */ + private $request; + + /** + * @var Response + */ + private $response; + public function __construct() { + $this->request = new Request(self::API_BASE_URL, self::API_VERSION, self::API_PATH); + $this->response = new Response(); } /** @@ -37,10 +49,27 @@ public function __construct() * @return Response */ public function push(Notification $notification) + { + $this->request->setCurlPostFields($notification); + $this->request->setNotification($notification); + + $curlResponse = $this->doCurl(); + + $this->processCurlResponse($curlResponse); + + $this->response->setRequest($this->request); + + return $this->response; + } + + /** + * @return mixed + */ + private function doCurl() { curl_setopt_array($ch = curl_init(), array( - CURLOPT_URL => self::API_BASE_URL.'/'.self::API_VERSION.'/'.self::API_PATH, - CURLOPT_POSTFIELDS => $this->buildCurlPostFields($notification), + CURLOPT_URL => $this->request->getFullUrl(), + CURLOPT_POSTFIELDS => $this->request->getCurlPostFields(), CURLOPT_SAFE_UPLOAD => true, CURLOPT_RETURNTRANSFER => true, )); @@ -56,82 +85,36 @@ public function push(Notification $notification) throw new LogicException('Curl should return json encoded string because CURLOPT_RETURNTRANSFER is set, "true" returned instead.'); } - return $this->processResponse($curlResponse); - } - - /** - * Builds array for CURLOPT_POSTFIELDS curl argument. - * - * @param Notification $notification - * @return array - */ - private function buildCurlPostFields(Notification $notification) - { - $curlPostFields = array( - "token" => $notification->getApplication()->getToken(), - "user" => $notification->getRecipient()->getUserKey(), - "message" => $notification->getMessage()->getMessage(), - "timestamp" => $notification->getMessage()->getTimestamp(), - ); - - if (null !== $notification->getRecipient()->getDevice()) { - $curlPostFields['device'] = $notification->getRecipient()->getDeviceListCommaSeparated(); - } - - if (null !== $notification->getMessage()->getTitle()) { - $curlPostFields['title'] = $notification->getMessage()->getTitle(); - } - - if (null !== $notification->getMessage()->getUrl()) { - $curlPostFields['url'] = $notification->getMessage()->getUrl(); - } - - if (null !== $notification->getMessage()->getUrlTitle()) { - $curlPostFields['url_title'] = $notification->getMessage()->getUrlTitle(); - } - - if (null !== $notification->getMessage()->getPriority()) { - $curlPostFields['priority'] = $notification->getMessage()->getPriority()->getPriority(); - - if (Priority::EMERGENCY == $notification->getMessage()->getPriority()->getPriority()) { - $curlPostFields['retry'] = $notification->getMessage()->getPriority()->getRetry(); - $curlPostFields['expire'] = $notification->getMessage()->getPriority()->getExpire(); - } - } - - if (true === $notification->getMessage()->getIsHtml()) { - $curlPostFields['html'] = 1; - } - - if (null !== $notification->getSound()) { - $curlPostFields['sound'] = $notification->getSound()->getSound(); - } - - return $curlPostFields; + return $curlResponse; } /** * Processes curl response and returns Response object. * * @param mixed $curlResponse - * @return Response + * @return void */ - private function processResponse($curlResponse) + private function processCurlResponse($curlResponse) { $decodedCurlResponse = json_decode($curlResponse); - $response = new Response($decodedCurlResponse->status, $decodedCurlResponse->request); + $this->response->setRequestStatus($decodedCurlResponse->status); + $this->response->setRequestToken($decodedCurlResponse->request); + $this->response->setCurlResponse($curlResponse); - $response->setCurlResponse($curlResponse); + if ($this->response->getRequestStatus() == 1) { + $this->response->setIsSuccessful(true); + } - if ($response->getStatus() != 1) { - $response->setErrors($decodedCurlResponse->errors); + if ($this->response->getRequestStatus() != 1) { + $this->response->setErrors($decodedCurlResponse->errors); + $this->response->setIsSuccessful(false); } if (isset($decodedCurlResponse->receipt)) { - $response->setReceipt($curlResponse->receipt); + $this->response->setReceipt($curlResponse->receipt); } - return $response; + return; } } diff --git a/src/Api/Message/Request.php b/src/Api/Message/Request.php new file mode 100644 index 0000000..dc6cb6a --- /dev/null +++ b/src/Api/Message/Request.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Serhiy\Pushover\Api\Message; + +/** + * Request object. + * + * Holds curl and other request data. + * + * @author Serhiy Lunak + */ +class Request +{ + /** + * @var string + */ + private $api_base_url; + /** + * @var string + */ + private $api_version; + /** + * @var string + */ + private $api_path; + + /** + * CURLOPT_POSTFIELDS. + * + * Array for CURLOPT_POSTFIELDS curl argument. + * + * @var array + */ + private $curlPostFields; + + /** + * Object that contains notification. + * + * @var Notification + */ + private $notification; + + public function __construct(string $api_base_url, string $api_version, string $api_path) + { + $this->api_base_url = $api_base_url; + $this->api_version = $api_version; + $this->api_path = $api_path; + } + + /** + * Builds API URL + * + * @return string + */ + public function getFullUrl() + { + return $this->api_base_url.'/'.$this->api_version.'/'.$this->api_path; + } + + /** + * @return array + */ + public function getCurlPostFields(): array + { + return $this->curlPostFields; + } + + /** + * @param Notification $notification + */ + public function setCurlPostFields(Notification $notification): void + { + $this->curlPostFields = $this->buildCurlPostFields($notification); + } + + /** + * @return Notification + */ + public function getNotification(): Notification + { + return $this->notification; + } + + /** + * @param Notification $notification + */ + public function setNotification(Notification $notification): void + { + $this->notification = $notification; + } + + /** + * Builds array for CURLOPT_POSTFIELDS curl argument. + * + * @param Notification $notification + * @return array + */ + private function buildCurlPostFields(Notification $notification) + { + $curlPostFields = array( + "token" => $notification->getApplication()->getToken(), + "user" => $notification->getRecipient()->getUserKey(), + "message" => $notification->getMessage()->getMessage(), + "timestamp" => $notification->getMessage()->getTimestamp(), + ); + + if (null !== $notification->getRecipient()->getDevice()) { + $curlPostFields['device'] = $notification->getRecipient()->getDeviceListCommaSeparated(); + } + + if (null !== $notification->getMessage()->getTitle()) { + $curlPostFields['title'] = $notification->getMessage()->getTitle(); + } + + if (null !== $notification->getMessage()->getUrl()) { + $curlPostFields['url'] = $notification->getMessage()->getUrl(); + } + + if (null !== $notification->getMessage()->getUrlTitle()) { + $curlPostFields['url_title'] = $notification->getMessage()->getUrlTitle(); + } + + if (null !== $notification->getMessage()->getPriority()) { + $curlPostFields['priority'] = $notification->getMessage()->getPriority()->getPriority(); + + if (Priority::EMERGENCY == $notification->getMessage()->getPriority()->getPriority()) { + $curlPostFields['retry'] = $notification->getMessage()->getPriority()->getRetry(); + $curlPostFields['expire'] = $notification->getMessage()->getPriority()->getExpire(); + } + } + + if (true === $notification->getMessage()->getIsHtml()) { + $curlPostFields['html'] = 1; + } + + if (null !== $notification->getSound()) { + $curlPostFields['sound'] = $notification->getSound()->getSound(); + } + + return $curlPostFields; + } +} diff --git a/src/Api/Message/Response.php b/src/Api/Message/Response.php index 0e951f2..13111bf 100644 --- a/src/Api/Message/Response.php +++ b/src/Api/Message/Response.php @@ -16,22 +16,31 @@ * If your POST request to our API was valid, you will receive an HTTP 200 (OK) status, * with a JSON object containing a status code of 1. If any input was invalid, you will receive an HTTP 4xx status, * with a JSON object containing a status code of something other than 1, and an errors array detailing which parameters were invalid. + * + * @author Serhiy Lunak */ class Response { /** - * Either 1 if successful or something other than 1 if unsuccessful. + * True if request was successful, false otherwise. Reflects $requestStatus property. + * + * @var bool + */ + private $isSuccessful; + + /** + * Either 1 if successful or something other than 1 if unsuccessful. Reflects $isSuccessful property. * * @var int */ - private $status; + private $requestStatus; /** * Randomly-generated unique token that we have associated with your request. * * @var string */ - private $request; + private $requestToken; /** * Receipt. @@ -44,7 +53,7 @@ class Response private $receipt; /** - * Original curl response. + * Original curl response in json format. * Original, unmodified response from curl request. * * @var mixed @@ -58,27 +67,64 @@ class Response */ private $errors; - public function __construct(int $status, string $request) + /** + * Object that contains original request. + * + * @var Request + */ + private $request; + + public function __construct() { - $this->status = $status; - $this->request = $request; $this->errors = array(); } + /** + * @return bool + */ + public function isSuccessful(): bool + { + return $this->isSuccessful; + } + + /** + * @param bool $isSuccessful + */ + public function setIsSuccessful(bool $isSuccessful): void + { + $this->isSuccessful = $isSuccessful; + } + /** * @return int */ - public function getStatus(): int + public function getRequestStatus(): int { - return $this->status; + return $this->requestStatus; + } + + /** + * @param int $requestStatus + */ + public function setRequestStatus(int $requestStatus): void + { + $this->requestStatus = $requestStatus; } /** * @return string */ - public function getRequest(): string + public function getRequestToken(): string { - return $this->request; + return $this->requestToken; + } + + /** + * @param string $requestToken + */ + public function setRequestToken(string $requestToken): void + { + $this->requestToken = $requestToken; } /** @@ -128,4 +174,20 @@ public function setCurlResponse($curlResponse): void { $this->curlResponse = $curlResponse; } + + /** + * @return Request + */ + public function getRequest(): Request + { + return $this->request; + } + + /** + * @param Request $request + */ + public function setRequest(Request $request): void + { + $this->request = $request; + } } diff --git a/tests/Api/Message/RequestTest.php b/tests/Api/Message/RequestTest.php new file mode 100644 index 0000000..db513c3 --- /dev/null +++ b/tests/Api/Message/RequestTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Api\Message; + +use PHPUnit\Framework\TestCase; +use Serhiy\Pushover\Api\Message\Application; +use Serhiy\Pushover\Api\Message\Client; +use Serhiy\Pushover\Api\Message\Message; +use Serhiy\Pushover\Api\Message\Notification; +use Serhiy\Pushover\Api\Message\Recipient; +use Serhiy\Pushover\Api\Message\Request; + +/** + * @author Serhiy Lunak + */ +class RequestTest extends TestCase +{ + /** + * @return Request + */ + public function testCanBeCrated() + { + $request = new Request(Client::API_BASE_URL, Client::API_VERSION, Client::API_PATH); + + $this->assertInstanceOf(Request::class, $request); + + return $request; + } + + /** + * @depends testCanBeCrated + * @param Request $request + */ + public function testGetFullUrl(Request $request) + { + $this->assertEquals(Client::API_BASE_URL.'/'.Client::API_VERSION.'/'.Client::API_PATH, $request->getFullUrl()); + } + + /** + * @depends testCanBeCrated + * @param Request $request + * @return Request + */ + public function testNotification(Request $request) + { + $application = new Application("azGDORePK8gMaC0QOYAMyEEuzJnyUi"); // using dummy token + $recipient = new Recipient("uQiRzpo4DXghDmr9QzzfQu27cmVRsG"); // using dummy user key + $message = new Message("This is a test message", "This is a title of the message"); + $notification = new Notification($application, $recipient, $message); + + $request->setNotification($notification); + + $this->assertInstanceOf(Notification::class, $request->getNotification()); + $this->assertEquals("azGDORePK8gMaC0QOYAMyEEuzJnyUi", $request->getNotification()->getApplication()->getToken()); + $this->assertEquals("uQiRzpo4DXghDmr9QzzfQu27cmVRsG", $request->getNotification()->getRecipient()->getUserKey()); + $this->assertEquals("This is a test message", $request->getNotification()->getMessage()->getMessage()); + $this->assertEquals("This is a title of the message", $request->getNotification()->getMessage()->getTitle()); + + return $request; + } + + /** + * @depends testNotification + * @param Request $request + */ + public function testBuildCurlPostFields(Request $request) + { + $request->setCurlPostFields($request->getNotification()); + $curlPostFields = $request->getCurlPostFields(); + + $this->assertIsArray($curlPostFields); + $this->assertEquals("azGDORePK8gMaC0QOYAMyEEuzJnyUi", $curlPostFields["token"]); + $this->assertEquals("uQiRzpo4DXghDmr9QzzfQu27cmVRsG", $curlPostFields["user"]); + $this->assertEquals("This is a test message", $curlPostFields["message"]); + $this->assertEquals("This is a title of the message", $curlPostFields["title"]); + } +} diff --git a/tests/Api/Message/ResponseTest.php b/tests/Api/Message/ResponseTest.php index 5b738e2..28756a6 100644 --- a/tests/Api/Message/ResponseTest.php +++ b/tests/Api/Message/ResponseTest.php @@ -26,7 +26,7 @@ class ResponseTest extends TestCase { public function testCanBeCrated() { - $response = new Response(1, '11111111-aaaa-2222-bbbb-333333cccccc'); + $response = new Response(); $this->assertInstanceOf(Response::class, $response); } @@ -42,7 +42,8 @@ public function testRealResponseForInvalidRequest() $response = $client->push($notification); $this->assertInstanceOf(Response::class, $response); - $this->assertEquals(0, $response->getStatus()); + $this->assertEquals(false, $response->isSuccessful()); + $this->assertEquals(0, $response->getRequestStatus()); $this->assertEquals("invalid", json_decode($response->getCurlResponse())->token); } }