Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/slunak/pushover-php
Browse files Browse the repository at this point in the history
  • Loading branch information
slunak committed Jun 21, 2020
2 parents 8d23645 + 4c0d023 commit 1acab5f
Show file tree
Hide file tree
Showing 7 changed files with 348 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Example/CompleteNotificationExample.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Serhiy\Pushover\Example;

use Serhiy\Pushover\Api\Message\Application;
use Serhiy\Pushover\Api\Message\Attachment;
use Serhiy\Pushover\Api\Message\Client;
use Serhiy\Pushover\Api\Message\Message;
use Serhiy\Pushover\Api\Message\Notification;
Expand Down Expand Up @@ -51,6 +52,8 @@ public function completeNotification()
$notification = new Notification($application, $recipient, $message);
// set notification sound
$notification->setSound(new Sound(Sound::PUSHOVER));
// add attachment
$notification->setAttachment(new Attachment("/path/to/file.jpg", Attachment::MIME_TYPE_JPEG));

// push notification
/** @var Response $response */
Expand Down
154 changes: 154 additions & 0 deletions src/Api/Message/Attachment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php

/*
* This file is part of the Pushover package.
*
* (c) Serhiy Lunak <https://github.com/slunak>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Serhiy\Pushover\Api\Message;

use Serhiy\Pushover\Exception\InvalidArgumentException;

/**
* Pushover messages can include an image attachment.
* When received by a device, it will attempt to download the image and display it with the notification.
* If this fails or takes too long, the notification will be displayed without it and the image download can be retried inside the Pushover app.
* Note that, like messages, once attachments are downloaded by the device, they are deleted from our servers and only stored on the device going forward.
* Attachments uploaded for devices that are not running at least version 3.0 of our apps will be discarded as they cannot be displayed by those devices.
*
* @author Serhiy Lunak
*/
class Attachment
{
/**
* Windows OS/2 Bitmap Graphics.
*/
const MIME_TYPE_JPEG = 'image/jpeg';

/**
* Portable Network Graphics.
*/
const MIME_TYPE_PNG = 'image/png';

/**
* Graphics Interchange Format (GIF).
*/
const MIME_TYPE_GIF = 'image/gif';

/**
* Windows OS/2 Bitmap Graphics
*/
const MIME_TYPE_BMP = 'image/bmp';

/**
* Icon format
*/
const MIME_TYPE_ICO = 'image/vnd.microsoft.icon';

/**
* Scalable Vector Graphics (SVG)
*/
const MIME_TYPE_SVG = 'image/svg+xml';

/**
* Tagged Image File Format (TIFF)
*/
const MIME_TYPE_TIFF = 'image/tiff';

/**
* WEBP image
*/
const MIME_TYPE_WEBP = 'image/webp';

/**
* MIME type.
* A media type (also known as a Multipurpose Internet Mail Extensions or MIME type) is a standard
* that indicates the nature and format of a document, file, or assortment of bytes.
* In case of Pushover attachment only image MIME type is accepted.
*
* @var string
*/
private $mimeType;

/**
* Path to the file.
* Path and filename of the image file to be sent with notification.
*
* @var string
*/
private $filename;

public function __construct(string $filename, string $mimeType)
{
$this->setMimeType($mimeType);
$this->setFilename($filename);
}

/**
* Generates array with all supported attachment types. Attachment types are taken from the constants of this class.
*
* @return array
*/
public function getSupportedAttachmentTypes(): array
{
$oClass = new \ReflectionClass(__CLASS__);
return $oClass->getConstants();
}

/**
* Supported extensions.
* Returns array of supported extensions.
*
* @return array
*/
public function getSupportedAttachmentExtensions(): array
{
return array(
'bmp', 'gif', 'ico', 'jpeg', 'jpg', 'png', 'svg', 'tif', 'tiff', 'webp'
);
}

/**
* @return string
*/
public function getMimeType(): string
{
return $this->mimeType;
}

/**
* @param string $mimeType
*/
public function setMimeType(string $mimeType): void
{
if (!in_array($mimeType, $this->getSupportedAttachmentTypes())) {
throw new InvalidArgumentException(sprintf('Attachment type "%s" is not supported.', $mimeType));
}

$this->mimeType = $mimeType;
}

/**
* @return string
*/
public function getFilename(): string
{
return $this->filename;
}

/**
* @param string $filename
*/
public function setFilename(string $filename): void
{
if (!in_array(pathinfo($filename, PATHINFO_EXTENSION), $this->getSupportedAttachmentExtensions())) {
throw new InvalidArgumentException(sprintf('Attachment extension "%s" is not supported.', pathinfo($filename, PATHINFO_EXTENSION)));
}

$this->filename = $filename;
}
}
21 changes: 21 additions & 0 deletions src/Api/Message/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ class Notification
*/
private $sound;

/**
* @var Attachment
*/
private $attachment;

public function __construct(Application $application, Recipient $recipient, Message $message)
{
$this->application = $application;
Expand Down Expand Up @@ -110,4 +115,20 @@ public function setSound(?Sound $sound): void
{
$this->sound = $sound;
}

/**
* @return Attachment|null
*/
public function getAttachment(): ?Attachment
{
return $this->attachment;
}

/**
* @param Attachment|null $attachment
*/
public function setAttachment(?Attachment $attachment): void
{
$this->attachment = $attachment;
}
}
17 changes: 17 additions & 0 deletions src/Api/Message/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Serhiy\Pushover\Api\Message;

use Serhiy\Pushover\Exception\LogicException;

/**
* Request object.
*
Expand Down Expand Up @@ -146,6 +148,21 @@ private function buildCurlPostFields(Notification $notification)
$curlPostFields['sound'] = $notification->getSound()->getSound();
}

if (null !== $notification->getAttachment()) {
if (! is_readable($notification->getAttachment()->getFilename())) {
throw new LogicException(sprintf('File "%s" does not exist or is not readable.', $notification->getAttachment()->getFilename()));
}

if (2621440 < filesize($notification->getAttachment()->getFilename())) {
throw new LogicException(sprintf('Attachments are currently limited to 2621440 bytes (2.5 megabytes). %s bytes attachment provided.', filesize($notification->getAttachment()->getFilename())));
}

$curlPostFields['attachment'] = curl_file_create(
$notification->getAttachment()->getFilename(),
$notification->getAttachment()->getMimeType()
);
}

return $curlPostFields;
}
}
112 changes: 112 additions & 0 deletions tests/Api/Message/AttachmentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

/*
* This file is part of the Pushover package.
*
* (c) Serhiy Lunak <https://github.com/slunak>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Api\Message;

use Serhiy\Pushover\Api\Message\Attachment;
use PHPUnit\Framework\TestCase;
use Serhiy\Pushover\Exception\InvalidArgumentException;

/**
* @author Serhiy Lunak
*/
class AttachmentTest extends TestCase
{
public function testCanBeCreated()
{
$attachment = new Attachment('/images/test.jpeg', Attachment::MIME_TYPE_JPEG);
$this->assertInstanceOf(Attachment::class, $attachment);

return $attachment;
}

public function testCannotBeCreatedWithInvalidMimeType()
{
$this->expectException(InvalidArgumentException::class);

new Attachment('/images/test.jpeg', 'image/invalid');
}

public function testCannotBeCreatedWithInvalidExtension()
{
$this->expectException(InvalidArgumentException::class);

new Attachment('/images/test.invalid', Attachment::MIME_TYPE_JPEG);
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testGetMimeType(Attachment $attachment)
{
$this->assertEquals(Attachment::MIME_TYPE_JPEG, $attachment->getMimeType());
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testGetFilename(Attachment $attachment)
{
$this->assertEquals('/images/test.jpeg', $attachment->getFilename());
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testSetMimeType(Attachment $attachment)
{
$attachment->setMimeType(Attachment::MIME_TYPE_JPEG);
$this->assertEquals(Attachment::MIME_TYPE_JPEG, $attachment->getMimeType());

$this->expectException(InvalidArgumentException::class);
$attachment->setMimeType('image/invalid');
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testSetFilename(Attachment $attachment)
{
$attachment->setMimeType(Attachment::MIME_TYPE_JPEG);
$this->assertEquals(Attachment::MIME_TYPE_JPEG, $attachment->getMimeType());

$this->expectException(InvalidArgumentException::class);
$attachment->setMimeType('image/invalid');
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testSupportedAttachmentTypes(Attachment $attachment)
{
$supportedAttachmentsTypes = new \ReflectionClass(Attachment::class);

$this->assertEquals($supportedAttachmentsTypes->getConstants(), $attachment->getSupportedAttachmentTypes());
}

/**
* @depends testCanBeCreated
* @param Attachment $attachment
*/
public function testSupportedAttachmentExtensions(Attachment $attachment)
{
$supportedAttachmentExtensions = array(
'bmp', 'gif', 'ico', 'jpeg', 'jpg', 'png', 'svg', 'tif', 'tiff', 'webp'
);

$this->assertEquals($supportedAttachmentExtensions, $attachment->getSupportedAttachmentExtensions());
}
}
24 changes: 24 additions & 0 deletions tests/Api/Message/NotificationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\TestCase;
use Serhiy\Pushover\Api\Message\Application;
use Serhiy\Pushover\Api\Message\Attachment;
use Serhiy\Pushover\Api\Message\Message;
use Serhiy\Pushover\Api\Message\Notification;
use Serhiy\Pushover\Api\Message\Recipient;
Expand Down Expand Up @@ -58,4 +59,27 @@ public function testNoSound(Notification $notification)

$this->assertNull($notification->getSound());
}

/**
* @depends testCanBeCreated
* @param Notification $notification
*/
public function testNotificationAttachment(Notification $notification)
{
$notification->setAttachment(new Attachment("/path/to/file.jpg", Attachment::MIME_TYPE_JPEG));

$this->assertEquals('/path/to/file.jpg', $notification->getAttachment()->getFilename());
$this->assertEquals('image/jpeg', $notification->getAttachment()->getMimeType());
}

/**
* @depends testCanBeCreated
* @param Notification $notification
*/
public function testNoAttachment(Notification $notification)
{
$notification->setAttachment(null);

$this->assertNull($notification->getAttachment());
}
}
Loading

0 comments on commit 1acab5f

Please sign in to comment.