@@ -159,20 +159,26 @@ service, including controllers::
159
159
namespace App\Controller;
160
160
161
161
use Symfony\Component\HttpFoundation\Response;
162
- use Symfony\Component\Mercure\PublisherInterface ;
162
+ use Symfony\Component\Mercure\HubInterface ;
163
163
use Symfony\Component\Mercure\Update;
164
164
165
165
class PublishController
166
166
{
167
- public function __invoke(PublisherInterface $publisher): Response
167
+ private $hub;
168
+
169
+ public function __construct(HubInterface $hub)
170
+ {
171
+ $this->hub = $hub;
172
+ }
173
+
174
+ public function __invoke(): Response
168
175
{
169
176
$update = new Update(
170
177
'http://example.com/books/1',
171
178
json_encode(['status' => 'OutOfStock'])
172
179
);
173
180
174
- // The Publisher service is an invokable object
175
- $publisher($update);
181
+ $this->hub->publish($update);
176
182
177
183
return new Response('published!');
178
184
}
@@ -294,22 +300,25 @@ by using the ``AbstractController::addLink`` helper method::
294
300
// src/Controller/DiscoverController.php
295
301
namespace App\Controller;
296
302
297
- use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
298
303
use Symfony\Component\HttpFoundation\JsonResponse;
299
304
use Symfony\Component\HttpFoundation\Request;
300
- use Symfony\Component\WebLink\Link ;
305
+ use Symfony\Component\Mercure\Discovery ;
301
306
302
- class DiscoverController extends AbstractController
307
+ class DiscoverController
303
308
{
304
- public function __invoke(Request $request): JsonResponse
309
+ private $discovery;
310
+
311
+ public function __construct(Discovery $discovery)
305
312
{
306
- // This parameter is automatically created by the MercureBundle
307
- $hubUrl = $this->getParameter('mercure.default_hub');
313
+ $this->discovery = $discovery;
314
+ }
308
315
316
+ public function __invoke(Request $request): JsonResponse
317
+ {
309
318
// Link: <http://localhost:3000/.well-known/mercure>; rel="mercure"
310
- $this->addLink($request, new Link('mercure', $hubUrl) );
319
+ $this->discovery-> addLink($request);
311
320
<
10000
td data-grid-cell-id="diff-d5dd97c607d1cb5cfb01adaaa4cdefddd2ea8a3e8671c777c5d44e2c21eaf092-311-320-2" data-line-anchor="diff-d5dd97c607d1cb5cfb01adaaa4cdefddd2ea8a3e8671c777c5d44e2c21eaf092R320" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell right-side-diff-cell left-side">
312
- return $this->json ([
321
+ return new JsonResponse ([
313
322
'@id' => '/books/1',
314
323
'availability' => 'https://schema.org/InStock',
315
324
]);
@@ -347,12 +356,18 @@ of the ``Update`` constructor to ``true``::
347
356
namespace App\Controller;
348
357
349
358
use Symfony\Component\HttpFoundation\Response;
350
- use Symfony\Component\Mercure\PublisherInterface;
351
359
use Symfony\Component\Mercure\Update;
352
360
353
361
class PublishController
354
362
{
355
- public function __invoke(PublisherInterface $publisher): Response
363
+ private $hub;
364
+
365
+ public function __construct(HubInterface $hub)
366
+ {
367
+ $this->hub = $hub;
368
+ }
369
+
370
+ public function __invoke(): Response
356
371
{
357
372
$update = new Update(
358
373
'http://example.com/books/1',
@@ -362,7 +377,7 @@ of the ``Update`` constructor to ``true``::
362
377
363
378
// Publisher's JWT must contain this topic, a URI template it matches or * in mercure.publish or you'll get a 401
364
379
// Subscriber's JWT must contain this topic, a URI template it matches or * in mercure.subscribe to receive the update
365
- $publisher ($update);
380
+ $this->hub->publish ($update);
366
381
367
382
return new Response('private update published!');
368
383
}
@@ -417,39 +432,34 @@ And here is the controller::
417
432
// src/Controller/DiscoverController.php
418
433
namespace App\Controller;
419
434
420
- use Lcobucci\JWT\Configuration;
421
- use Lcobucci\JWT\Signer\Hmac\Sha256;
422
- use Lcobucci\JWT\Signer\Key;
423
- use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
424
- use Symfony\Component\HttpFoundation\Cookie;
425
435
use Symfony\Component\HttpFoundation\Request;
426
436
use Symfony\Component\HttpFoundation\Response;
427
- use Symfony\Component\WebLink\Link;
437
+ use Symfony\Component\Mercure\Authorization;
438
+ use Symfony\Component\Mercure\Discovery;
428
439
429
- class DiscoverController extends AbstractController
440
+ class DiscoverController
430
441
{
442
+ private $discovery;
443
+ private $authorization;
444
+
445
+ public function __construct(Discovery $discovery, Authorization $authorization)
446
+ {
447
+ $this->discovery = $discovery;
448
+ $this->authorization = $authorization;
449
+ }
450
+
431
451
public function __invoke(Request $request): Response
432
452
{
433
- $hubUrl = $this->getParameter('mercure.default_hub');
434
- $this->addLink($request, new Link('mercure', $hubUrl));
435
-
436
- $key = Key\InMemory::plainText('mercure_secret_key'); // don't forget to set this parameter! Test value: !ChangeMe!
437
- $configuration = Configuration::forSymmetricSigner(new Sha256(), $key);
438
-
439
- $token = $configuration->builder()
440
- ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or *
441
- ->getToken($configuration->signer(), $configuration->signingKey())
442
- ->toString();
443
-
444
- $response = $this->json(['@id' => '/demo/books/1', 'availability' => 'https://schema.org/InStock']);
445
- $cookie = Cookie::create('mercureAuthorization')
446
- ->withValue($token)
447
- ->withPath('/.well-known/mercure')
448
- ->withSecure(true)
449
- ->withHttpOnly(true)
450
- ->withSameSite('strict')
451
- ;
452
- $response->headers->setCookie($cookie);
453
+ $this->discovery->addLink($request);
454
+
455
+ $response = new JsonResponse([
456
+ '@id' => '/demo/books/1',
457
+ 'availability' => 'https://schema.org/InStock'
458
+ ]);
459
+
460
+ $response->headers->setCookie(
461
+ $this->authorization->createCookie($request, ["http://example.com/books/1"])
462
+ );
453
463
454
464
return $response;
455
465
}
@@ -464,15 +474,17 @@ Programmatically Generating The JWT Used to Publish
464
474
---------------------------------------------------
465
475
466
476
Instead of directly storing a JWT in the configuration,
467
- you can create a service that will return the token used by
468
- the ``Publisher `` object::
477
+ you can create a token provider that will return the token used by
478
+ the ``HubInterface `` object::
469
479
470
- // src/Mercure/MyJwtProvider .php
480
+ // src/Mercure/MyTokenProvider .php
471
481
namespace App\Mercure;
472
482
473
- final class MyJwtProvider
483
+ use Symfony\Component\Mercure\JWT\TokenProviderInterface;
484
+
485
+ final class MyTokenProvider implements TokenProviderInterface
474
486
{
475
- public function __invoke (): string
487
+ public function getToken (): string
476
488
{
477
489
return 'the-JWT';
478
490
}
@@ -489,7 +501,8 @@ Then, reference this service in the bundle configuration:
489
501
hubs :
490
502
default :
491
503
url : https://mercure-hub.example.com/.well-known/mercure
492
- jwt_provider : App\Mercure\MyJwtProvider
504
+ jwt :
505
+ provider : App\Mercure\MyTokenProvider
493
506
494
507
.. code-block :: xml
495
508
@@ -499,8 +512,9 @@ Then, reference this service in the bundle configuration:
499
512
<hub
500
513
name =" default"
501
514
url =" https://mercure-hub.example.com/.well-known/mercure"
502
- jwt-provider =" App\Mercure\MyJwtProvider"
503
- />
515
+ >
516
+ <jwt provider =" App\Mercure\MyTokenProvider" />
517
+ </hub >
504
518
</config >
505
519
506
520
.. code-block :: php
@@ -512,7 +526,9 @@ Then, reference this service in the bundle configuration:
512
526
'hubs' => [
513
527
'default' => [
514
528
'url' => 'https://mercure-hub.example.com/.well-known/mercure',
515
- 'jwt_provider' => MyJwtProvider::class,
529
+ 'jwt' => [
530
+ 'provider' => MyJwtProvider::class,
531
+ ]
516
532
],
517
533
],
518
534
]);
0 commit comments