From 0f07fd5ab1ca7d18ad35bbd46b20e847ca115bdc Mon Sep 17 00:00:00 2001 From: Charly Goblet Date: Mon, 20 Feb 2023 13:36:07 +0100 Subject: [PATCH] [Notifier] Add Pushover bridge --- .../FrameworkExtension.php | 2 + .../Resources/config/notifier_transports.php | 5 + .../Notifier/Bridge/Pushover/.gitattributes | 4 + .../Notifier/Bridge/Pushover/.gitignore | 3 + .../Notifier/Bridge/Pushover/CHANGELOG.md | 7 + .../Notifier/Bridge/Pushover/LICENSE | 19 ++ .../Bridge/Pushover/PushoverOptions.php | 188 ++++++++++++++++++ .../Bridge/Pushover/PushoverTransport.php | 89 +++++++++ .../Pushover/PushoverTransportFactory.php | 42 ++++ .../Notifier/Bridge/Pushover/README.md | 24 +++ .../Tests/PushoverTransportFactoryTest.php | 39 ++++ .../Pushover/Tests/PushoverTransportTest.php | 123 ++++++++++++ .../Notifier/Bridge/Pushover/composer.json | 36 ++++ .../Notifier/Bridge/Pushover/phpunit.xml.dist | 31 +++ .../Exception/UnsupportedSchemeException.php | 4 + src/Symfony/Component/Notifier/Transport.php | 2 + 16 files changed, 618 insertions(+) create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/.gitattributes create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/.gitignore create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/CHANGELOG.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/LICENSE create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/PushoverOptions.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransport.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransportFactory.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/README.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportFactoryTest.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportTest.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/composer.json create mode 100644 src/Symfony/Component/Notifier/Bridge/Pushover/phpunit.xml.dist diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 842eb8eab4425..694b89fcdb546 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -166,6 +166,7 @@ use Symfony\Component\Notifier\Bridge\OvhCloud\OvhCloudTransportFactory; use Symfony\Component\Notifier\Bridge\PagerDuty\PagerDutyTransportFactory; use Symfony\Component\Notifier\Bridge\Plivo\PlivoTransportFactory; +use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransportFactory; use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralTransportFactory; use Symfony\Component\Notifier\Bridge\RocketChat\RocketChatTransportFactory; use Symfony\Component\Notifier\Bridge\Sendberry\SendberryTransportFactory; @@ -2606,6 +2607,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ OvhCloudTransportFactory::class => 'notifier.transport_factory.ovh-cloud', PagerDutyTransportFactory::class => 'notifier.transport_factory.pager-duty', PlivoTransportFactory::class => 'notifier.transport_factory.plivo', + PushoverTransportFactory::class => 'notifier.transport_factory.pushover', RingCentralTransportFactory::class => 'notifier.transport_factory.ring-central', RocketChatTransportFactory::class => 'notifier.transport_factory.rocket-chat', SendberryTransportFactory::class => 'notifier.transport_factory.sendberry', diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php index c5e0371d933ba..41471838cf309 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php @@ -50,6 +50,7 @@ use Symfony\Component\Notifier\Bridge\OvhCloud\OvhCloudTransportFactory; use Symfony\Component\Notifier\Bridge\PagerDuty\PagerDutyTransportFactory; use Symfony\Component\Notifier\Bridge\Plivo\PlivoTransportFactory; +use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransportFactory; use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralTransportFactory; use Symfony\Component\Notifier\Bridge\RocketChat\RocketChatTransportFactory; use Symfony\Component\Notifier\Bridge\Sendberry\SendberryTransportFactory; @@ -331,5 +332,9 @@ ->set('notifier.transport_factory.pager-duty', PagerDutyTransportFactory::class) ->parent('notifier.transport_factory.abstract') ->tag('chatter.transport_factory') + + ->set('notifier.transport_factory.pushover', PushoverTransportFactory::class) + ->parent('notifier.transport_factory.abstract') + ->tag('texter.transport_factory') ; }; diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/.gitattributes b/src/Symfony/Component/Notifier/Bridge/Pushover/.gitattributes new file mode 100644 index 0000000000000..84c7add058fb5 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/.gitattributes @@ -0,0 +1,4 @@ +/Tests export-ignore +/phpunit.xml.dist export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/.gitignore b/src/Symfony/Component/Notifier/Bridge/Pushover/.gitignore new file mode 100644 index 0000000000000..c49a5d8df5c65 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/CHANGELOG.md b/src/Symfony/Component/Notifier/Bridge/Pushover/CHANGELOG.md new file mode 100644 index 0000000000000..1f2c8f86cde72 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +6.3 +--- + + * Add the bridge diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/LICENSE b/src/Symfony/Component/Notifier/Bridge/Pushover/LICENSE new file mode 100644 index 0000000000000..3ed9f412ce53d --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverOptions.php b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverOptions.php new file mode 100644 index 0000000000000..36b12150a0a1e --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverOptions.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Pushover; + +use Symfony\Component\Notifier\Exception\InvalidArgumentException; +use Symfony\Component\Notifier\Message\MessageOptionsInterface; +use Symfony\Component\Notifier\Notification\Notification; + +/** + * @author mocodo + * + * @see https://pushover.net/api + */ +final class PushoverOptions implements MessageOptionsInterface +{ + private const PRIORITIES = [-2, -1, 0, 1, 2]; + + private const SOUNDS = [ + 'pushover', + 'bike', + 'bugle', + 'cashregister', + 'classical', + 'cosmic', + 'falling', + 'gamelan', + 'incoming', + 'intermission', + 'magic', + 'mechanical', + 'pianobar', + 'siren', + 'spacealarm', + 'tugboat', + 'alien', + 'climb', + 'persistent', + 'echo', + 'vibrate', + 'none', + ]; + + private array $options; + + public function __construct(array $options = []) + { + $this->options = $options; + } + + public static function fromNotification(Notification $notification): self + { + $options = new self(); + $options->title($notification->getSubject()); + $priority = match ($notification->getImportance()) { + Notification::IMPORTANCE_URGENT => 2, + Notification::IMPORTANCE_HIGH => 1, + Notification::IMPORTANCE_MEDIUM => 0, + Notification::IMPORTANCE_LOW => -1 + }; + $options->priority($priority); + + return $options; + } + + public function toArray(): array + { + $options = $this->options; + unset($options['attachment']); + + return $options; + } + + public function getRecipientId(): ?string + { + return $this->options['device'] ?? null; + } + + /** + * @see https://pushover.net/api#identifiers + * + * @return $this + */ + public function device(string $device): static + { + $this->options['device'] = $device; + + return $this; + } + + /** + * @see https://pushover.net/api#html + * + * @return $this + */ + public function asHtml(bool $bool): static + { + $this->options['html'] = $bool ? 1 : 0; + + return $this; + } + + /** + * @see https://pushover.net/api#priority + * + * @return $this + */ + public function priority(int $priority): static + { + if (!\in_array($priority, self::PRIORITIES, true)) { + throw new InvalidArgumentException(sprintf('Pushover notification priority must be one of "%s".', implode(', ', self::PRIORITIES))); + } + + $this->options['priority'] = $priority; + + return $this; + } + + /** + * @see https://pushover.net/api#sounds + * + * @return $this + */ + public function sound(string $sound): static + { + if (!\in_array($sound, self::SOUNDS, true)) { + throw new InvalidArgumentException(sprintf('Pushover notification sound must be one of "%s".', implode(', ', self::SOUNDS))); + } + + $this->options['sound'] = $sound; + + return $this; + } + + /** + * @see https://pushover.net/api#timestamp + * + * @return $this + */ + public function timestamp(int $timestamp): static + { + $this->options['timestamp'] = $timestamp; + + return $this; + } + + /** + * @return $this + */ + public function title(string $title): static + { + $this->options['title'] = $title; + + return $this; + } + + /** + * @see https://pushover.net/api#urls + * + * @return $this + */ + public function url(string $url): static + { + $this->options['url'] = $url; + + return $this; + } + + /** + * @see https://pushover.net/api#urls + * + * @return $this + */ + public function urlTitle(string $urlTitle): static + { + $this->options['url_title'] = $urlTitle; + + return $this; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransport.php b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransport.php new file mode 100644 index 0000000000000..be7e6f75dbed0 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransport.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Pushover; + +use Symfony\Component\Notifier\Exception\TransportException; +use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Message\PushMessage; +use Symfony\Component\Notifier\Message\SentMessage; +use Symfony\Component\Notifier\Transport\AbstractTransport; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author mocodo + */ +final class PushoverTransport extends AbstractTransport +{ + protected const HOST = 'api.pushover.net'; + + public function __construct( + #[\SensitiveParameter] private readonly string $userKey, + #[\SensitiveParameter] private readonly string $appToken, + HttpClientInterface $client = null, + EventDispatcherInterface $dispatcher = null, + ) { + parent::__construct($client, $dispatcher); + } + + public function supports(MessageInterface $message): bool + { + return $message instanceof PushMessage; + } + + public function __toString(): string + { + return sprintf('pushover://%s', $this->getEndpoint()); + } + + protected function doSend(MessageInterface $message): SentMessage + { + if (!$message instanceof PushMessage) { + throw new UnsupportedMessageTypeException(__CLASS__, PushMessage::class, $message); + } + + $opts = $message->getOptions(); + $options = $opts ? $opts->toArray() : []; + $options['message'] = $message->getContent(); + $options['title'] = $message->getSubject(); + $options['token'] = $this->appToken; + $options['user'] = $this->userKey; + + $endpoint = sprintf('https://%s/1/messages.json', self::HOST); + $response = $this->client->request('POST', $endpoint, [ + 'body' => $options, + ]); + + try { + $statusCode = $response->getStatusCode(); + } catch (TransportExceptionInterface $e) { + throw new TransportException('Could not reach the remote Pushover server.', $response, 0, $e); + } + + if (200 !== $statusCode) { + throw new TransportException(sprintf('Unable to send the Pushover push notification: "%s".', $response->getContent(false)), $response); + } + + $result = $response->toArray(false); + + if (!isset($result['request'])) { + throw new TransportException(sprintf('Unable to send the Pushover push notification: "%s".', $result->getContent(false)), $response); + } + + $sentMessage = new SentMessage($message, (string) $this); + $sentMessage->setMessageId($result['request']); + + return $sentMessage; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransportFactory.php new file mode 100644 index 0000000000000..1e55e361bdf36 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/PushoverTransportFactory.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Pushover; + +use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; +use Symfony\Component\Notifier\Transport\AbstractTransportFactory; +use Symfony\Component\Notifier\Transport\Dsn; +use Symfony\Component\Notifier\Transport\TransportInterface; + +/** + * @author mocodo + */ +final class PushoverTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if ('pushover' !== $dsn->getScheme()) { + throw new UnsupportedSchemeException($dsn, 'pushover', $this->getSupportedSchemes()); + } + + $userKey = $dsn->getUser(); + $appToken = $dsn->getPassword(); + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); + + return (new PushoverTransport($userKey, $appToken, $this->client, $this->dispatcher))->setHost($host)->setPort($port); + } + + protected function getSupportedSchemes(): array + { + return ['pushover']; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/README.md b/src/Symfony/Component/Notifier/Bridge/Pushover/README.md new file mode 100644 index 0000000000000..f46c98345eddb --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/README.md @@ -0,0 +1,24 @@ +Pushover Notifier +================= + +Provides [Pushover](https://pushover.net) integration for Symfony Notifier. + +DSN example +----------- + +``` +PUSHOVER_DSN=pushover://USER_KEY:APP_TOKEN@default +``` + +where: + +- `USER_KEY` is your user/group key (or that of your target user), viewable when logged into your Pushover's dashboard +- `APP_TOKEN` is your application's API token + +Resources +--------- + +* [Contributing](https://symfony.com/doc/current/contributing/index.html) +* [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportFactoryTest.php new file mode 100644 index 0000000000000..a22389dafda0d --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportFactoryTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Pushover\Tests; + +use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransportFactory; +use Symfony\Component\Notifier\Test\TransportFactoryTestCase; + +final class PushoverTransportFactoryTest extends TransportFactoryTestCase +{ + public function createFactory(): PushoverTransportFactory + { + return new PushoverTransportFactory(); + } + + public static function createProvider(): iterable + { + yield ['pushover://api.pushover.net', 'pushover://userKey:appToken@api.pushover.net']; + } + + public static function supportsProvider(): iterable + { + yield [true, 'pushover://userKey@appToken']; + yield [false, 'somethingElse://userKey@appToken']; + } + + public static function unsupportedSchemeProvider(): iterable + { + yield ['somethingElse://userKey@appToken']; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportTest.php b/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportTest.php new file mode 100644 index 0000000000000..9b2af410122c8 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/Tests/PushoverTransportTest.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Pushover\Tests; + +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransport; +use Symfony\Component\Notifier\Message\ChatMessage; +use Symfony\Component\Notifier\Message\PushMessage; +use Symfony\Component\Notifier\Notification\Notification; +use Symfony\Component\Notifier\Test\TransportTestCase; +use Symfony\Component\Notifier\Tests\Transport\DummyMessage; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +final class PushoverTransportTest extends TransportTestCase +{ + public static function createTransport(HttpClientInterface $client = null): PushoverTransport + { + return new PushoverTransport('userKey', 'appToken', $client ?? new MockHttpClient()); + } + + public static function toStringProvider(): iterable + { + yield ['pushover://api.pushover.net', self::createTransport()]; + } + + public static function supportedMessagesProvider(): iterable + { + yield [new PushMessage('Hello!', 'World')]; + } + + public static function unsupportedMessagesProvider(): iterable + { + yield [new ChatMessage('Hello!')]; + yield [new DummyMessage()]; + } + + public function testSendWithOptions() + { + $messageSubject = 'testMessageSubject'; + $messageContent = 'testMessageContent'; + + $response = $this->createMock(ResponseInterface::class); + + $response->expects($this->exactly(2)) + ->method('getStatusCode') + ->willReturn(200); + + $response->expects($this->once()) + ->method('getContent') + ->willReturn(json_encode(['status' => 1, 'request' => 'uuid'])); + + $expectedBody = http_build_query([ + 'message' => 'testMessageContent', + 'title' => 'testMessageSubject', + 'token' => 'appToken', + 'user' => 'userKey', + ]); + + $client = new MockHttpClient(function (string $method, string $url, array $options = []) use ( + $response, + $expectedBody + ): ResponseInterface { + $this->assertSame($expectedBody, $options['body']); + + return $response; + }); + $transport = self::createTransport($client); + + $sentMessage = $transport->send(new PushMessage($messageSubject, $messageContent)); + + $this->assertSame('uuid', $sentMessage->getMessageId()); + } + + public function testSendWithNotification() + { + $messageSubject = 'testMessageSubject'; + $messageContent = 'testMessageContent'; + + $response = $this->createMock(ResponseInterface::class); + + $response->expects($this->exactly(2)) + ->method('getStatusCode') + ->willReturn(200); + + $response->expects($this->once()) + ->method('getContent') + ->willReturn(json_encode(['status' => 1, 'request' => 'uuid'])); + + $notification = (new Notification($messageSubject))->content($messageContent); + $pushMessage = PushMessage::fromNotification($notification); + + $expectedBody = http_build_query([ + 'message' => 'testMessageContent', + 'title' => 'testMessageSubject', + 'token' => 'appToken', + 'user' => 'userKey', + ]); + + $client = new MockHttpClient(function (string $method, string $url, array $options = []) use ( + $response, + $expectedBody + ): ResponseInterface { + $this->assertSame($expectedBody, $options['body']); + + return $response; + }); + $transport = self::createTransport($client); + + $sentMessage = $transport->send($pushMessage); + + $this->assertSame('uuid', $sentMessage->getMessageId()); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/composer.json b/src/Symfony/Component/Notifier/Bridge/Pushover/composer.json new file mode 100644 index 0000000000000..faa5a061a3bca --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/composer.json @@ -0,0 +1,36 @@ +{ + "name": "symfony/pushover-notifier", + "type": "symfony-notifier-bridge", + "description": "Symfony Pushover Notifier Bridge", + "keywords": [ + "pushover", + "notifier" + ], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "mocodo", + "homepage": "https://github.com/mocodo" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony/http-client": "^5.4|^6.0", + "symfony/notifier": "^6.3" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0" + }, + "autoload": { + "psr-4": {"Symfony\\Component\\Notifier\\Bridge\\Pushover\\": ""}, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/src/Symfony/Component/Notifier/Bridge/Pushover/phpunit.xml.dist b/src/Symfony/Component/Notifier/Bridge/Pushover/phpunit.xml.dist new file mode 100644 index 0000000000000..89349c102ebde --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Pushover/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php index 86aa5f3930634..f0312937fa587 100644 --- a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php @@ -164,6 +164,10 @@ class UnsupportedSchemeException extends LogicException 'class' => Bridge\Plivo\PlivoTransportFactory::class, 'package' => 'symfony/plivo-notifier', ], + 'pushover' => [ + 'class' => Bridge\Pushover\PushoverTransportFactory::class, + 'package' => 'symfony/pushover-notifier', + ], 'ringcentral' => [ 'class' => Bridge\RingCentral\RingCentralTransportFactory::class, 'package' => 'symfony/ring-central-notifier', diff --git a/src/Symfony/Component/Notifier/Transport.php b/src/Symfony/Component/Notifier/Transport.php index 260c57cb349b7..9dcf3348cc68a 100644 --- a/src/Symfony/Component/Notifier/Transport.php +++ b/src/Symfony/Component/Notifier/Transport.php @@ -42,6 +42,7 @@ use Symfony\Component\Notifier\Bridge\OvhCloud\OvhCloudTransportFactory; use Symfony\Component\Notifier\Bridge\PagerDuty\PagerDutyTransportFactory; use Symfony\Component\Notifier\Bridge\Plivo\PlivoTransportFactory; +use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransportFactory; use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralTransportFactory; use Symfony\Component\Notifier\Bridge\RocketChat\RocketChatTransportFactory; use Symfony\Component\Notifier\Bridge\Sendberry\SendberryTransportFactory; @@ -111,6 +112,7 @@ final class Transport OvhCloudTransportFactory::class, PagerDutyTransportFactory::class, PlivoTransportFactory::class, + PushoverTransportFactory::class, RingCentralTransportFactory::class, RocketChatTransportFactory::class, SendberryTransportFactory::class,