diff --git a/Example/CompleteNotificationExample.php b/Example/CompleteNotificationExample.php index e62d6ca..0334460 100644 --- a/Example/CompleteNotificationExample.php +++ b/Example/CompleteNotificationExample.php @@ -12,6 +12,7 @@ namespace Serhiy\Pushover\Example; use Serhiy\Pushover\Api\Message\Attachment; +use Serhiy\Pushover\Api\Message\CustomSound; use Serhiy\Pushover\Api\Message\Message; use Serhiy\Pushover\Api\Message\Notification; use Serhiy\Pushover\Api\Message\Priority; @@ -48,8 +49,10 @@ public function completeNotification() // create notification $notification = new Notification($application, $recipient, $message); - // set notification sound + // set notification built-in sound $notification->setSound(new Sound(Sound::PUSHOVER)); + // or set notification custom sound + $notification->setCustomSound(new CustomSound("door_open")); // add attachment $notification->setAttachment(new Attachment("/path/to/file.jpg", Attachment::MIME_TYPE_JPEG)); diff --git a/README.md b/README.md index 8f2ef17..35876b5 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Light, simple and fast, yet comprehensive wrapper for the [Pushover](https://pus - HTML messages - Supplementary URL and its title - Notification priority - - Notification sound + - Notification sound (including custom sound) - Message time - User/Group Validation API ([Example](Example/UserGroupValidationExample.php)) - Validation by user or group key diff --git a/src/Api/Message/CustomSound.php b/src/Api/Message/CustomSound.php new file mode 100644 index 0000000..5393ac9 --- /dev/null +++ b/src/Api/Message/CustomSound.php @@ -0,0 +1,60 @@ + + * + * 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; + +/** + * @author Serhiy Lunak + */ +class CustomSound +{ + /** + * Custom Sound Notification + * Admins can now upload custom sounds through Pushover website and have them played on devices + * without having to copy sound files to each device. Can only contain letters, numbers, underscores, and dashes, + * and is limited to 20 characters, such as "warning", "door_open", or "long_siren2". It cannot match the name + * of any built-in sound and will be specified as the sound parameter through our API when requesting this sound. + * + * @var string + */ + private $customSound; + + public function __construct(string $customSound) + { + $this->setCustomSound($customSound); + } + + /** + * @return string + */ + public function getCustomSound(): string + { + return $this->customSound; + } + + /** + * @param string $customSound + */ + public function setCustomSound(string $customSound): void + { + if (in_array($customSound, Sound::getAvailableSounds())) { + throw new InvalidArgumentException(sprintf('Sound "%s" is not a valid custom sound because it matches the name of a built-in sound.', $customSound)); + } + + if (1 !== preg_match("/^[a-zA-Z0-9_-]{1,20}$/", $customSound)) { + throw new InvalidArgumentException(sprintf('Sound "%s" is not a valid custom sound. Custom sound name can only contain letters, numbers, underscores, and dashes, and is limited to 20 characters, such as "warning", "door_open", or "long_siren2".', $customSound)); + } + + $this->customSound = $customSound; + } +} diff --git a/src/Api/Message/Notification.php b/src/Api/Message/Notification.php index 3a63fa2..555f4fb 100644 --- a/src/Api/Message/Notification.php +++ b/src/Api/Message/Notification.php @@ -47,6 +47,11 @@ class Notification */ private $sound; + /** + * @var CustomSound|null + */ + private $customSound; + /** * @var Attachment|null */ @@ -123,6 +128,22 @@ public function setSound(?Sound $sound): void $this->sound = $sound; } + /** + * @return CustomSound|null + */ + public function getCustomSound(): ?CustomSound + { + return $this->customSound; + } + + /** + * @param CustomSound|null $customSound + */ + public function setCustomSound(?CustomSound $customSound): void + { + $this->customSound = $customSound; + } + /** * @return Attachment|null */ diff --git a/src/Client/MessageClient.php b/src/Client/MessageClient.php index f9972f7..13a9d26 100644 --- a/src/Client/MessageClient.php +++ b/src/Client/MessageClient.php @@ -92,6 +92,10 @@ public function buildCurlPostFields(Notification $notification): array $curlPostFields['sound'] = $notification->getSound()->getSound(); } + if (null !== $notification->getCustomSound()) { + $curlPostFields['sound'] = $notification->getCustomSound()->getCustomSound(); + } + 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())); diff --git a/tests/Api/Message/CustomSoundTest.php b/tests/Api/Message/CustomSoundTest.php new file mode 100644 index 0000000..5c8ae02 --- /dev/null +++ b/tests/Api/Message/CustomSoundTest.php @@ -0,0 +1,90 @@ + + * + * 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\CustomSound; +use Serhiy\Pushover\Exception\InvalidArgumentException; + +/** + * @author Serhiy Lunak + */ +class CustomSoundTest extends TestCase +{ + public function testCanBeCreated() + { + $this->assertInstanceOf(CustomSound::class, $customSound = new CustomSound("door_open")); + + return $customSound; + } + + /** + * @depends testCanBeCreated + * @param CustomSound $customSound + */ + public function testGetCustomSound(CustomSound $customSound) + { + $this->assertEquals('door_open', $customSound->getCustomSound()); + } + + /** + * @depends testCanBeCreated + * @param CustomSound $customSound + */ + public function testSetCustomSound(CustomSound $customSound) + { + $customSound->setCustomSound("warning"); + + $this->assertEquals('warning', $customSound->getCustomSound()); + + $customSound->setCustomSound("door_open"); + + $this->assertEquals('door_open', $customSound->getCustomSound()); + + $customSound->setCustomSound("bell-sound"); + + $this->assertEquals('bell-sound', $customSound->getCustomSound()); + } + + /** + * @depends testCanBeCreated + * @param CustomSound $customSound + */ + public function testSetExistingCustomSound(CustomSound $customSound) + { + $this->expectException(InvalidArgumentException::class); + + $customSound->setCustomSound("echo"); + } + + /** + * @depends testCanBeCreated + * @param CustomSound $customSound + */ + public function testSetInvalidCustomSound(CustomSound $customSound) + { + $this->expectException(InvalidArgumentException::class); + + $customSound->setCustomSound("warning+door_open"); + } + + /** + * @depends testCanBeCreated + * @param CustomSound $customSound + */ + public function testSetLongCustomSound(CustomSound $customSound) + { + $this->expectException(InvalidArgumentException::class); + + $customSound->setCustomSound("warning_door_open_warning_door_open"); + } +} diff --git a/tests/Api/Message/NotificationTest.php b/tests/Api/Message/NotificationTest.php index 57bdc25..5876422 100644 --- a/tests/Api/Message/NotificationTest.php +++ b/tests/Api/Message/NotificationTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Serhiy\Pushover\Api\Message\Attachment; +use Serhiy\Pushover\Api\Message\CustomSound; use Serhiy\Pushover\Api\Message\Message; use Serhiy\Pushover\Api\Message\Notification; use Serhiy\Pushover\Api\Message\Sound; @@ -61,6 +62,28 @@ public function testSetSoundNull(Notification $notification) $this->assertNull($notification->getSound()); } + /** + * @depends testCanBeCreated + * @param Notification $notification + */ + public function testSetCustomSound(Notification $notification) + { + $notification->setCustomSound(new CustomSound("door_open")); + + $this->assertEquals('door_open', $notification->getCustomSound()->getCustomSound()); + } + + /** + * @depends testCanBeCreated + * @param Notification $notification + */ + public function testSetCustomSoundNull(Notification $notification) + { + $notification->setCustomSound(null); + + $this->assertNull($notification->getCustomSound()); + } + /** * @depends testCanBeCreated * @param Notification $notification