Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc6100bc

Browse files
committed
feature#39342 [Notifier] Add mercure bridge (mtarld)
This PR was merged into the 5.3-dev branch.Discussion----------[Notifier] Add mercure bridge| Q | A| ------------- | ---| Branch? | 5.x| Bug fix? | no| New feature? | yes| Deprecations? | no| Tickets |Fix#36481| License | MIT| Doc PR |symfony/symfony-docs#14840Add a Notifier bridge for Mercure.In this PR, Mercure is considered as a chatter (I'm still wondering if it's the most appropriate type).The first approach for the DSN is `mercure://jwtToken@host:port/hubPath?topic=/foo/1&secure=false` with:- `topic` optional (defaults to `null`)- `secure` optional (defaults to `true`)I'm not sure about the current way to deal with http/https. Maybe we can just replace the `mercure` scheme by `http|https`?The notification representation is following [Activity Streams](https://www.w3.org/TR/activitystreams-core/#jsonld)#SymfonyHackdayCommits-------19c6544 [Notifier] Add mercure bridge
2 parentsd91278a +19c6544 commitc6100bc

File tree

16 files changed

+677
-0
lines changed

16 files changed

+677
-0
lines changed

‎composer.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
"psr/http-client":"^1.0",
131131
"psr/simple-cache":"^1.0",
132132
"egulias/email-validator":"^2.1.10",
133+
"symfony/mercure-bundle":"^0.2",
133134
"symfony/phpunit-bridge":"^5.2",
134135
"symfony/security-acl":"~2.8|~3.0",
135136
"phpdocumentor/reflection-docblock":"^3.0|^4.0|^5.0",

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
useSymfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
2626
useSymfony\Bundle\FrameworkBundle\Routing\RouteLoaderInterface;
2727
useSymfony\Bundle\FullStack;
28+
useSymfony\Bundle\MercureBundle\MercureBundle;
2829
useSymfony\Component\Asset\PackageInterface;
2930
useSymfony\Component\BrowserKit\AbstractBrowser;
3031
useSymfony\Component\Cache\Adapter\AdapterInterface;
@@ -43,6 +44,8 @@
4344
useSymfony\Component\Console\Command\Command;
4445
useSymfony\Component\DependencyInjection\Alias;
4546
useSymfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
47+
useSymfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
48+
useSymfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
4649
useSymfony\Component\DependencyInjection\ChildDefinition;
4750
useSymfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
4851
useSymfony\Component\DependencyInjection\ContainerBuilder;
@@ -112,6 +115,7 @@
112115
useSymfony\Component\Notifier\Bridge\Iqsms\IqsmsTransportFactory;
113116
useSymfony\Component\Notifier\Bridge\LinkedIn\LinkedInTransportFactory;
114117
useSymfony\Component\Notifier\Bridge\Mattermost\MattermostTransportFactory;
118+
useSymfony\Component\Notifier\Bridge\Mercure\MercureTransportFactory;
115119
useSymfony\Component\Notifier\Bridge\Mobyt\MobytTransportFactory;
116120
useSymfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory;
117121
useSymfony\Component\Notifier\Bridge\Octopush\OctopushTransportFactory;
@@ -2242,6 +2246,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
22422246
LinkedInTransportFactory::class =>'notifier.transport_factory.linkedin',
22432247
GatewayApiTransportFactory::class =>'notifier.transport_factory.gatewayapi',
22442248
OctopushTransportFactory::class =>'notifier.transport_factory.octopush',
2249+
MercureTransportFactory::class =>'notifier.transport_factory.mercure',
22452250
];
22462251

22472252
foreach ($classToServicesas$class =>$service) {
@@ -2250,6 +2255,15 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
22502255
}
22512256
}
22522257

2258+
if (class_exists(MercureTransportFactory::class)) {
2259+
if (!class_exists(MercureBundle::class)) {
2260+
thrownew \LogicException('The MercureBundle is not registered in your application. Try running "composer require symfony/mercure-bundle".');
2261+
}
2262+
2263+
$container->getDefinition($classToServices[MercureTransportFactory::class])
2264+
->replaceArgument('$publisherLocator',newServiceLocatorArgument(newTaggedIteratorArgument('mercure.publisher',null,null,true)));
2265+
}
2266+
22532267
if (isset($config['admin_recipients'])) {
22542268
$notifier =$container->getDefinition('notifier');
22552269
foreach ($config['admin_recipients']as$i =>$recipient) {

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
useSymfony\Component\Notifier\Bridge\Iqsms\IqsmsTransportFactory;
2323
useSymfony\Component\Notifier\Bridge\LinkedIn\LinkedInTransportFactory;
2424
useSymfony\Component\Notifier\Bridge\Mattermost\MattermostTransportFactory;
25+
useSymfony\Component\Notifier\Bridge\Mercure\MercureTransportFactory;
2526
useSymfony\Component\Notifier\Bridge\Mobyt\MobytTransportFactory;
2627
useSymfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory;
2728
useSymfony\Component\Notifier\Bridge\Octopush\OctopushTransportFactory;
@@ -135,6 +136,10 @@
135136
->parent('notifier.transport_factory.abstract')
136137
->tag('texter.transport_factory')
137138

139+
->set('notifier.transport_factory.mercure', MercureTransportFactory::class)
140+
->parent('notifier.transport_factory.abstract')
141+
->tag('chatter.transport_factory')
142+
138143
->set('notifier.transport_factory.null', NullTransportFactory::class)
139144
->parent('notifier.transport_factory.abstract')
140145
->tag('chatter.transport_factory')
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/Testsexport-ignore
2+
/phpunit.xml.distexport-ignore
3+
/.gitattributesexport-ignore
4+
/.gitignoreexport-ignore
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CHANGELOG
2+
=========
3+
4+
5.3
5+
---
6+
7+
* Add the bridge
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2021 Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Notifier\Bridge\Mercure;
13+
14+
useSymfony\Component\Notifier\Message\MessageOptionsInterface;
15+
16+
/**
17+
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
18+
*/
19+
finalclass MercureOptionsimplements MessageOptionsInterface
20+
{
21+
private$topics;
22+
private$private;
23+
private$id;
24+
private$type;
25+
private$retry;
26+
27+
/**
28+
* @param string|string[]|null $topics
29+
*/
30+
publicfunction__construct($topics =null,bool$private =false, ?string$id =null, ?string$type =null, ?int$retry =null)
31+
{
32+
if (null !==$topics && !\is_array($topics) && !\is_string($topics)) {
33+
thrownew \TypeError(sprintf('"%s()" expects parameter 1 to be an array of strings, a string or null, "%s" given.',__METHOD__,get_debug_type($topics)));
34+
}
35+
36+
$this->topics =null !==$topics ? (array)$topics :null;
37+
$this->private =$private;
38+
$this->id =$id;
39+
$this->type =$type;
40+
$this->retry =$retry;
41+
}
42+
43+
/**
44+
* @return string[]|null
45+
*/
46+
publicfunctiongetTopics(): ?array
47+
{
48+
return$this->topics;
49+
}
50+
51+
publicfunctionisPrivate():bool
52+
{
53+
return$this->private;
54+
}
55+
56+
publicfunctiongetId(): ?string
57+
{
58+
return$this->id;
59+
}
60+
61+
publicfunctiongetType(): ?string
62+
{
63+
return$this->type;
64+
}
65+
66+
publicfunctiongetRetry(): ?int
67+
{
68+
return$this->retry;
69+
}
70+
71+
publicfunctiontoArray():array
72+
{
73+
return [
74+
'topics' =>$this->topics,
75+
'private' =>$this->private,
76+
'id' =>$this->id,
77+
'type' =>$this->type,
78+
'retry' =>$this->retry,
79+
];
80+
}
81+
82+
publicfunctiongetRecipientId(): ?string
83+
{
84+
returnnull;
85+
}
86+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Notifier\Bridge\Mercure;
13+
14+
useSymfony\Component\Mercure\PublisherInterface;
15+
useSymfony\Component\Mercure\Update;
16+
useSymfony\Component\Notifier\Exception\InvalidArgumentException;
17+
useSymfony\Component\Notifier\Exception\LogicException;
18+
useSymfony\Component\Notifier\Exception\TransportException;
19+
useSymfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
20+
useSymfony\Component\Notifier\Message\ChatMessage;
21+
useSymfony\Component\Notifier\Message\MessageInterface;
22+
useSymfony\Component\Notifier\Message\SentMessage;
23+
useSymfony\Component\Notifier\Transport\AbstractTransport;
24+
useSymfony\Contracts\EventDispatcher\EventDispatcherInterface;
25+
useSymfony\Contracts\HttpClient\Exception\ExceptionInterface;
26+
useSymfony\Contracts\HttpClient\HttpClientInterface;
27+
28+
/**
29+
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
30+
*/
31+
finalclass MercureTransportextends AbstractTransport
32+
{
33+
private$publisher;
34+
private$publisherId;
35+
private$topics;
36+
37+
/**
38+
* @param string|string[]|null $topics
39+
*/
40+
publicfunction__construct(PublisherInterface$publisher,string$publisherId,$topics =null, ?HttpClientInterface$client =null, ?EventDispatcherInterface$dispatcher =null)
41+
{
42+
if (null !==$topics && !\is_array($topics) && !\is_string($topics)) {
43+
thrownew \TypeError(sprintf('"%s()" expects parameter 3 to be an array of strings, a string or null, "%s" given.',__METHOD__,get_debug_type($topics)));
44+
}
45+
46+
$this->publisher =$publisher;
47+
$this->publisherId =$publisherId;
48+
$this->topics =$topics ??'https://symfony.com/notifier';
49+
50+
parent::__construct($client,$dispatcher);
51+
}
52+
53+
publicfunction__toString():string
54+
{
55+
returnsprintf('mercure://%s?%s',$this->publisherId,http_build_query(['topic' =>$this->topics]));
56+
}
57+
58+
publicfunctionsupports(MessageInterface$message):bool
59+
{
60+
return$messageinstanceof ChatMessage && (null ===$message->getOptions() ||$message->getOptions()instanceof MercureOptions);
61+
}
62+
63+
/**
64+
* @see https://symfony.com/doc/current/mercure.html#publishing
65+
*/
66+
protectedfunctiondoSend(MessageInterface$message):SentMessage
67+
{
68+
if (!$messageinstanceof ChatMessage) {
69+
thrownewUnsupportedMessageTypeException(__CLASS__, ChatMessage::class,$message);
70+
}
71+
72+
if (($options =$message->getOptions()) && !$optionsinstanceof MercureOptions) {
73+
thrownewLogicException(sprintf('The "%s" transport only supports instances of "%s" for options.',__CLASS__, MercureOptions::class));
74+
}
75+
76+
if (null ===$options) {
77+
$options =newMercureOptions($this->topics);
78+
}
79+
80+
// @see https://www.w3.org/TR/activitystreams-core/#jsonld
81+
$update =newUpdate($options->getTopics() ??$this->topics,json_encode([
82+
'@context' =>'https://www.w3.org/ns/activitystreams',
83+
'type' =>'Announce',
84+
'summary' =>$message->getSubject(),
85+
]),$options->isPrivate(),$options->getId(),$options->getType(),$options->getRetry());
86+
87+
try {
88+
$messageId = ($this->publisher)($update);
89+
90+
$sentMessage =newSentMessage($message, (string)$this);
91+
$sentMessage->setMessageId($messageId);
92+
93+
return$sentMessage;
94+
}catch (ExceptionInterface$e) {
95+
thrownewTransportException(sprintf('Unable to post the Mercure message: "%s".',$e->getResponse()->getContent(false)),$e->getResponse(),$e->getCode(),$e);
96+
}catch (\InvalidArgumentException$e) {
97+
thrownewInvalidArgumentException(sprintf('Unable to post the Mercure message: "%s".',$e->getMessage()),$e->getCode(),$e);
98+
}
99+
}
100+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Notifier\Bridge\Mercure;
13+
14+
useSymfony\Component\Mercure\PublisherInterface;
15+
useSymfony\Component\Notifier\Exception\LogicException;
16+
useSymfony\Component\Notifier\Exception\UnsupportedSchemeException;
17+
useSymfony\Component\Notifier\Transport\AbstractTransportFactory;
18+
useSymfony\Component\Notifier\Transport\Dsn;
19+
useSymfony\Component\Notifier\Transport\TransportInterface;
20+
useSymfony\Contracts\Service\ServiceProviderInterface;
21+
22+
/**
23+
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
24+
*/
25+
finalclass MercureTransportFactoryextends AbstractTransportFactory
26+
{
27+
private$publisherLocator;
28+
29+
/**
30+
* @param ServiceProviderInterface $publisherLocator A container that holds {@see PublisherInterface} instances
31+
*/
32+
publicfunction__construct(ServiceProviderInterface$publisherLocator)
33+
{
34+
parent::__construct();
35+
36+
$this->publisherLocator =$publisherLocator;
37+
}
38+
39+
/**
40+
* @return MercureTransport
41+
*/
42+
publicfunctioncreate(Dsn$dsn):TransportInterface
43+
{
44+
if ('mercure' !==$dsn->getScheme()) {
45+
thrownewUnsupportedSchemeException($dsn,'mercure',$this->getSupportedSchemes());
46+
}
47+
48+
$publisherId =$dsn->getHost();
49+
if (!$this->publisherLocator->has($publisherId)) {
50+
thrownewLogicException(sprintf('"%s" not found. Did you mean one of: %s?',$publisherId,implode(',',array_keys($this->publisherLocator->getProvidedServices()))));
51+
}
52+
53+
$topic =$dsn->getOption('topic');
54+
55+
returnnewMercureTransport($this->publisherLocator->get($publisherId),$publisherId,$topic);
56+
}
57+
58+
protectedfunctiongetSupportedSchemes():array
59+
{
60+
return ['mercure'];
61+
}
62+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Mercure Notifier
2+
================
3+
4+
Provides[Mercure](https://github.com/symfony/mercure) integration for Symfony Notifier.
5+
6+
DSN example
7+
-----------
8+
9+
```
10+
MERCURE_DSN=mercure://PUBLISHER_SERVICE_ID?topic=TOPIC
11+
```
12+
13+
where:
14+
-`PUBLISHER_SERVICE_ID` is the Mercure publisher service id
15+
-`TOPIC` is the topic IRI (optional, default:`https://symfony.com/notifier`. Could be either a single topic:`topic=https://foo` or multiple topics:`topic[]=/foo/1&topic[]=https://bar`)
16+
17+
Resources
18+
---------
19+
20+
*[Contributing](https://symfony.com/doc/current/contributing/index.html)
21+
*[Report issues](https://github.com/symfony/symfony/issues) and
22+
[send Pull Requests](https://github.com/symfony/symfony/pulls)
23+
in the[main Symfony repository](https://github.com/symfony/symfony)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp