Skip to content

Commit 029c6bd

Browse files
committed
Provides an integration with the Symfony Messenger component
1 parent f8693d1 commit 029c6bd

File tree

10 files changed

+223
-1
lines changed

10 files changed

+223
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"symfony/framework-bundle": "^3.3 || ^4.0",
6161
"symfony/mercure": "*",
6262
"symfony/mercure-bundle": "*",
63-
"symfony/messenger": "^4.1",
63+
"symfony/messenger": "^4.2",
6464
"symfony/phpunit-bridge": "^3.3 || ^4.0",
6565
"symfony/routing": "^3.3 || ^4.0",
6666
"symfony/security": "^3.0 || ^4.0",

src/Annotation/ApiResource.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
* @Attribute("itemOperations", type="array"),
4343
* @Attribute("maximumItemsPerPage", type="int"),
4444
* @Attribute("mercure", type="mixed"),
45+
* @Attribute("messenger", type="bool"),
4546
* @Attribute("normalizationContext", type="array"),
4647
* @Attribute("order", type="array"),
4748
* @Attribute("outputClass", type="mixed"),
@@ -183,6 +184,13 @@ final class ApiResource
183184
*/
184185
private $mercure;
185186

187+
/**
188+
* @see https://github.com/Haehnchen/idea-php-annotation-plugin/issues/112
189+
*
190+
* @var bool
191+
*/
192+
private $messenger;
193+
186194
/**
187195
* @see https://github.com/Haehnchen/idea-php-annotation-plugin/issues/112
188196
*

src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
3838
use Symfony\Component\Finder\Finder;
3939
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
40+
use Symfony\Component\Messenger\MessageBusInterface;
4041
use Symfony\Component\Validator\Validator\ValidatorInterface;
4142
use Symfony\Component\Yaml\Yaml;
4243

@@ -145,6 +146,10 @@ public function load(array $configs, ContainerBuilder $container)
145146
$this->registerValidatorConfiguration($container, $config);
146147
$this->registerDataCollectorConfiguration($container, $config, $loader);
147148
$this->registerMercureConfiguration($container, $config, $loader, $useDoctrine);
149+
150+
if (interface_exists(MessageBusInterface::class)) {
151+
$loader->load('messenger.xml');
152+
}
148153
}
149154

150155
/**
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<service id="api_platform.message_bus" alias="message_bus" />
9+
10+
<service id="api_platform.messenger.data_persister" class="ApiPlatform\Core\DataPersister\MessengerDataPersister" public="false">
11+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
12+
<argument type="service" id="api_platform.message_bus" />
13+
14+
<tag name="api_platform.data_persister" priority="-900" />
15+
</service>
16+
</services>
17+
18+
</container>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\DataPersister;
15+
16+
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
17+
use ApiPlatform\Core\Util\ClassInfoTrait;
18+
use Symfony\Component\Messenger\Envelope;
19+
use Symfony\Component\Messenger\MessageBusInterface;
20+
21+
/**
22+
* Dispatches the given resource using the message bus of Symfony Messenger.
23+
*
24+
* @experimental
25+
*
26+
* @author Kévin Dunglas <[email protected]>
27+
*/
28+
final class MessengerDataPersister implements DataPersisterInterface
29+
{
30+
use ClassInfoTrait;
31+
32+
private $resourceMetadataFactory;
33+
private $messageBus;
34+
35+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, MessageBusInterface $messageBus)
36+
{
37+
$this->resourceMetadataFactory = $resourceMetadataFactory;
38+
$this->messageBus = $messageBus;
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function supports($data): bool
45+
{
46+
return true === $this->resourceMetadataFactory->create($this->getObjectClass($data))->getAttribute('messenger');
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
public function persist($data)
53+
{
54+
$this->messageBus->dispatch($data);
55+
56+
return $data;
57+
}
58+
59+
/**
60+
* {@inheritdoc}
61+
*/
62+
public function remove($data)
63+
{
64+
$this->messageBus->dispatch(new Envelope($data, new RemoveStamp()));
65+
}
66+
}

src/DataPersister/RemoveStamp.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\DataPersister;
15+
16+
use Symfony\Component\Messenger\Stamp\StampInterface;
17+
18+
/**
19+
* Hints that the resource in the enveloppe must be removed.
20+
*
21+
* @author Kévin Dunglas <[email protected]>
22+
*/
23+
final class RemoveStamp implements StampInterface
24+
{
25+
}

tests/Annotation/ApiResourceTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@ public function testConstruct()
3838
'formats' => ['foo', 'bar' => ['application/bar']],
3939
'filters' => ['foo', 'bar'],
4040
'graphql' => ['query' => ['normalization_context' => ['groups' => ['foo', 'bar']]]],
41+
'inputClass' => 'Foo',
4142
'iri' => 'http://example.com/res',
4243
'itemOperations' => ['foo' => ['bar']],
4344
'maximumItemsPerPage' => 42,
4445
'mercure' => '[\'foo\', object.owner]',
46+
'messenger' => true,
4547
'normalizationContext' => ['groups' => ['bar']],
4648
'order' => ['foo', 'bar' => 'ASC'],
49+
'outputClass' => 'Bar',
4750
'paginationClientEnabled' => true,
4851
'paginationClientItemsPerPage' => true,
4952
'paginationClientPartial' => true,
@@ -74,10 +77,13 @@ public function testConstruct()
7477
'force_eager' => false,
7578
'formats' => ['foo', 'bar' => ['application/bar']],
7679
'filters' => ['foo', 'bar'],
80+
'input_class' => 'Foo',
7781
'maximum_items_per_page' => 42,
7882
'mercure' => '[\'foo\', object.owner]',
83+
'messenger' => true,
7984
'normalization_context' => ['groups' => ['bar']],
8085
'order' => ['foo', 'bar' => 'ASC'],
86+
'output_class' => 'Bar',
8187
'pagination_client_enabled' => true,
8288
'pagination_client_items_per_page' => true,
8389
'pagination_client_partial' => true,

tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ private function getBaseContainerBuilderProphecy()
767767
'api_platform.validator',
768768
'api_platform.mercure.listener.response.add_link_header',
769769
'api_platform.doctrine.listener.mercure.publish',
770+
'api_platform.messenger.data_persister',
770771
];
771772

772773
foreach ($definitions as $definition) {
@@ -775,6 +776,7 @@ private function getBaseContainerBuilderProphecy()
775776

776777
$aliases = [
777778
'api_platform.http_cache.purger' => 'api_platform.http_cache.purger.varnish',
779+
'api_platform.message_bus' => 'message_bus',
778780
EagerLoadingExtension::class => 'api_platform.doctrine.orm.query_extension.eager_loading',
779781
FilterExtension::class => 'api_platform.doctrine.orm.query_extension.filter',
780782
FilterEagerLoadingExtension::class => 'api_platform.doctrine.orm.query_extension.filter_eager_loading',
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Tests\DataPersister;
15+
16+
use ApiPlatform\Core\DataPersister\MessengerDataPersister;
17+
use ApiPlatform\Core\DataPersister\RemoveStamp;
18+
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
19+
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
20+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
21+
use PHPUnit\Framework\TestCase;
22+
use Prophecy\Argument;
23+
use Symfony\Component\Messenger\Envelope;
24+
use Symfony\Component\Messenger\MessageBusInterface;
25+
26+
/**
27+
* @author Kévin Dunglas <[email protected]>
28+
*/
29+
class MessengerDataPersisterTest extends TestCase
30+
{
31+
public function testSupport()
32+
{
33+
$metadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
34+
$metadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata(null, null, null, null, null, ['messenger' => true]));
35+
36+
$dataPersister = new MessengerDataPersister($metadataFactoryProphecy->reveal(), $this->prophesize(MessageBusInterface::class)->reveal());
37+
$this->assertTrue($dataPersister->supports(new Dummy()));
38+
}
39+
40+
public function testPersist()
41+
{
42+
$dummy = new Dummy();
43+
44+
$messageBus = $this->prophesize(MessageBusInterface::class);
45+
$messageBus->dispatch($dummy)->willReturn(new Envelope(new \stdClass()))->shouldBeCalled();
46+
47+
$dataPersister = new MessengerDataPersister($this->prophesize(ResourceMetadataFactoryInterface::class)->reveal(), $messageBus->reveal());
48+
$this->assertSame($dummy, $dataPersister->persist($dummy));
49+
}
50+
51+
public function testRemove()
52+
{
53+
$dummy = new Dummy();
54+
55+
$messageBus = $this->prophesize(MessageBusInterface::class);
56+
$messageBus->dispatch(Argument::that(function (Envelope $envelope) {
57+
return null !== $envelope->last(RemoveStamp::class);
58+
}))->willReturn(new Envelope(new \stdClass()))->shouldBeCalled();
59+
60+
$dataPersister = new MessengerDataPersister($this->prophesize(ResourceMetadataFactoryInterface::class)->reveal(), $messageBus->reveal());
61+
$dataPersister->remove($dummy);
62+
}
63+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Tests\DataPersister;
15+
16+
use ApiPlatform\Core\DataPersister\RemoveStamp;
17+
use PHPUnit\Framework\TestCase;
18+
use Symfony\Component\Messenger\Stamp\StampInterface;
19+
20+
/**
21+
* @author Kévin Dunglas <[email protected]>
22+
*/
23+
class RemoveStampTest extends TestCase
24+
{
25+
public function testConstruct()
26+
{
27+
$this->assertInstanceOf(StampInterface::class, new RemoveStamp());
28+
}
29+
}

0 commit comments

Comments
 (0)