Skip to content

Commit 808a453

Browse files
authored
Merge pull request #2072 from dunglas/persist-attr
New "_api_persist" request attribute to skip the WriteListener
2 parents fb58dda + bb8f3f4 commit 808a453

File tree

8 files changed

+63
-14
lines changed

8 files changed

+63
-14
lines changed

src/EventListener/WriteListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function __construct(DataPersisterInterface $dataPersister)
3737
public function onKernelView(GetResponseForControllerResultEvent $event)
3838
{
3939
$request = $event->getRequest();
40-
if ($request->isMethodSafe(false) || !$request->attributes->has('_api_resource_class')) {
40+
if ($request->isMethodSafe(false) || !$request->attributes->has('_api_resource_class') || !$request->attributes->getBoolean('_api_persist', true)) {
4141
return;
4242
}
4343

src/Util/AttributesExtractor.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,10 @@ public static function extractAttributes(array $attributes): array
5858
return [];
5959
}
6060

61-
if (null === $apiRequest = $attributes['_api_receive'] ?? null) {
62-
$result['receive'] = true;
63-
} else {
64-
$result['receive'] = (bool) $apiRequest;
65-
}
61+
$result += [
62+
'receive' => (bool) ($attributes['_api_receive'] ?? true),
63+
'persist' => (bool) ($attributes['_api_persist'] ?? true),
64+
];
6665

6766
return $result;
6867
}

tests/Bridge/Symfony/Bundle/DataCollector/RequestDataCollectorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function testWithResource()
107107
$this->response
108108
);
109109

110-
$this->assertSame(['resource_class' => DummyEntity::class, 'item_operation_name' => 'get', 'receive' => true], $dataCollector->getRequestAttributes());
110+
$this->assertSame(['resource_class' => DummyEntity::class, 'item_operation_name' => 'get', 'receive' => true, 'persist' => true], $dataCollector->getRequestAttributes());
111111
$this->assertSame(['foo', 'bar'], $dataCollector->getAcceptableContentTypes());
112112
$this->assertSame(DummyEntity::class, $dataCollector->getResourceClass());
113113
$this->assertSame(['foo' => null, 'a_filter' => \stdClass::class], $dataCollector->getFilters());

tests/EventListener/AddFormatListenerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public function testResourceClassSupportedRequestFormat()
224224
$event = $eventProphecy->reveal();
225225

226226
$formatsProviderProphecy = $this->prophesize(FormatsProviderInterface::class);
227-
$formatsProviderProphecy->getFormatsFromAttributes(['resource_class' => 'Foo', 'collection_operation_name' => 'get', 'receive' => true])->willReturn(['csv' => ['text/csv']])->shouldBeCalled();
227+
$formatsProviderProphecy->getFormatsFromAttributes(['resource_class' => 'Foo', 'collection_operation_name' => 'get', 'receive' => true, 'persist' => true])->willReturn(['csv' => ['text/csv']])->shouldBeCalled();
228228

229229
$listener = new AddFormatListener(new Negotiator(), $formatsProviderProphecy->reveal());
230230
$listener->onKernelRequest($event);

tests/EventListener/DeserializeListenerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public function testDeserializeResourceClassSupportedFormat(string $method, bool
172172
$serializerContextBuilderProphecy->createFromRequest(Argument::type(Request::class), false, Argument::type('array'))->willReturn([])->shouldBeCalled();
173173

174174
$formatsProviderProphecy = $this->prophesize(FormatsProviderInterface::class);
175-
$formatsProviderProphecy->getFormatsFromAttributes(['resource_class' => 'Foo', 'collection_operation_name' => 'post', 'receive' => true])->willReturn(self::FORMATS)->shouldBeCalled();
175+
$formatsProviderProphecy->getFormatsFromAttributes(['resource_class' => 'Foo', 'collection_operation_name' => 'post', 'receive' => true, 'persist' => true])->willReturn(self::FORMATS)->shouldBeCalled();
176176

177177
$listener = new DeserializeListener($serializerProphecy->reveal(), $serializerContextBuilderProphecy->reveal(), $formatsProviderProphecy->reveal());
178178

tests/EventListener/WriteListenerTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,31 @@ public function testOnKernelViewWithSafeMethod()
170170
(new WriteListener($dataPersisterProphecy->reveal()))->onKernelView($event);
171171
}
172172

173+
public function testOnKernelViewWithPersistFlagOff()
174+
{
175+
$dummy = new Dummy();
176+
$dummy->setName('Dummyrino');
177+
178+
$dataPersisterProphecy = $this->prophesize(DataPersisterInterface::class);
179+
$dataPersisterProphecy->supports($dummy)->shouldNotBeCalled();
180+
$dataPersisterProphecy->persist($dummy)->shouldNotBeCalled();
181+
$dataPersisterProphecy->remove($dummy)->shouldNotBeCalled();
182+
183+
$request = new Request();
184+
$request->setMethod('HEAD');
185+
$request->attributes->set('_api_resource_class', Dummy::class);
186+
$request->attributes->set('_api_persist', false);
187+
188+
$event = new GetResponseForControllerResultEvent(
189+
$this->prophesize(HttpKernelInterface::class)->reveal(),
190+
$request,
191+
HttpKernelInterface::MASTER_REQUEST,
192+
$dummy
193+
);
194+
195+
(new WriteListener($dataPersisterProphecy->reveal()))->onKernelView($event);
196+
}
197+
173198
public function testOnKernelViewWithNoResourceClass()
174199
{
175200
$dummy = new Dummy();

tests/Serializer/SerializerFilterContextBuilderTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public function testCreateFromRequestWithoutAttributes()
154154
'resource_class' => DummyGroup::class,
155155
'collection_operation_name' => 'get',
156156
'receive' => true,
157+
'persist' => true,
157158
];
158159

159160
$resourceMetadata = new ResourceMetadata(

tests/Util/RequestAttributesExtractorTest.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function testExtractCollectionAttributes()
2727
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_collection_operation_name' => 'post']);
2828

2929
$this->assertEquals(
30-
['resource_class' => 'Foo', 'collection_operation_name' => 'post', 'receive' => true],
30+
['resource_class' => 'Foo', 'collection_operation_name' => 'post', 'receive' => true, 'persist' => true],
3131
RequestAttributesExtractor::extractAttributes($request)
3232
);
3333
}
@@ -37,7 +37,7 @@ public function testExtractItemAttributes()
3737
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get']);
3838

3939
$this->assertEquals(
40-
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true],
40+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => true],
4141
RequestAttributesExtractor::extractAttributes($request)
4242
);
4343
}
@@ -47,21 +47,45 @@ public function testExtractReceive()
4747
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get', '_api_receive' => '0']);
4848

4949
$this->assertEquals(
50-
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => false],
50+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => false, 'persist' => true],
5151
RequestAttributesExtractor::extractAttributes($request)
5252
);
5353

5454
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get', '_api_receive' => '1']);
5555

5656
$this->assertEquals(
57-
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true],
57+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => true],
5858
RequestAttributesExtractor::extractAttributes($request)
5959
);
6060

6161
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get']);
6262

6363
$this->assertEquals(
64-
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true],
64+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => true],
65+
RequestAttributesExtractor::extractAttributes($request)
66+
);
67+
}
68+
69+
public function testExtractPersist()
70+
{
71+
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get', '_api_persist' => '0']);
72+
73+
$this->assertEquals(
74+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => false],
75+
RequestAttributesExtractor::extractAttributes($request)
76+
);
77+
78+
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get', '_api_persist' => '1']);
79+
80+
$this->assertEquals(
81+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => true],
82+
RequestAttributesExtractor::extractAttributes($request)
83+
);
84+
85+
$request = new Request([], [], ['_api_resource_class' => 'Foo', '_api_item_operation_name' => 'get']);
86+
87+
$this->assertEquals(
88+
['resource_class' => 'Foo', 'item_operation_name' => 'get', 'receive' => true, 'persist' => true],
6589
RequestAttributesExtractor::extractAttributes($request)
6690
);
6791
}

0 commit comments

Comments
 (0)