Skip to content

Commit c304b11

Browse files
authored
Merge pull request #1913 from antograssiot/dataprovider-bc-layer
Add a BC layer on data providers and deprecation errors
2 parents 2aaeabb + 32dea18 commit c304b11

File tree

5 files changed

+95
-8
lines changed

5 files changed

+95
-8
lines changed

src/Bridge/Doctrine/Orm/ItemDataProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultItemExtensionInterface;
1818
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\IdentifierManagerTrait;
1919
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
20-
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
20+
use ApiPlatform\Core\DataProvider\DenormalizedIdentifiersAwareItemDataProviderInterface;
2121
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
2222
use ApiPlatform\Core\Exception\RuntimeException;
2323
use ApiPlatform\Core\Identifier\Normalizer\ChainIdentifierDenormalizer;
@@ -35,7 +35,7 @@
3535
* @author Samuel ROZE <[email protected]>
3636
* @final
3737
*/
38-
class ItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
38+
class ItemDataProvider implements DenormalizedIdentifiersAwareItemDataProviderInterface, RestrictedDataProviderInterface
3939
{
4040
use IdentifierManagerTrait;
4141

src/DataProvider/ChainItemDataProvider.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,17 @@ public function getItem(string $resourceClass, $id, string $operationName = null
4444
continue;
4545
}
4646

47-
return $dataProvider->getItem($resourceClass, $id, $operationName, $context);
47+
$identifier = $id;
48+
if (!$dataProvider instanceof DenormalizedIdentifiersAwareItemDataProviderInterface && $identifier && \is_array($identifier)) {
49+
if (\count($identifier) > 1) {
50+
@trigger_error(sprintf('Receiving "$id" as non-array in an item data provider is deprecated in 2.3 in favor of implementing "%s".', DenormalizedIdentifiersAwareItemDataProviderInterface::class), E_USER_DEPRECATED);
51+
$identifier = http_build_query($identifier, '', ';');
52+
} else {
53+
$identifier = current($identifier);
54+
}
55+
}
56+
57+
return $dataProvider->getItem($resourceClass, $identifier, $operationName, $context);
4858
} catch (ResourceClassNotSupportedException $e) {
4959
@trigger_error(sprintf('Throwing a "%s" is deprecated in favor of implementing "%s"', \get_class($e), RestrictedDataProviderInterface::class), E_USER_DEPRECATED);
5060
continue;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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\DataProvider;
15+
16+
/**
17+
* Marks data providers able to deal with complex identifiers denormalized as an array.
18+
*
19+
* @author Anthony GRASSIOT <[email protected]>
20+
*/
21+
interface DenormalizedIdentifiersAwareItemDataProviderInterface extends ItemDataProviderInterface
22+
{
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
public function getItem(string $resourceClass, /* array */ $id, string $operationName = null, array $context = []);
27+
}

tests/DataProvider/ChainItemDataProviderTest.php

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
namespace ApiPlatform\Core\Tests\DataProvider;
1515

1616
use ApiPlatform\Core\DataProvider\ChainItemDataProvider;
17+
use ApiPlatform\Core\DataProvider\DenormalizedIdentifiersAwareItemDataProviderInterface;
1718
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
1819
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
1920
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
21+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositePrimitiveItem;
2022
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
2123
use PHPUnit\Framework\TestCase;
2224

@@ -32,14 +34,42 @@ public function testGetItem()
3234
$dummy = new Dummy();
3335
$dummy->setName('Lucie');
3436

37+
$firstDataProvider = $this->prophesize(DenormalizedIdentifiersAwareItemDataProviderInterface::class);
38+
$firstDataProvider->willImplement(RestrictedDataProviderInterface::class);
39+
$firstDataProvider->supports(Dummy::class, null, [])->willReturn(false);
40+
41+
$secondDataProvider = $this->prophesize(DenormalizedIdentifiersAwareItemDataProviderInterface::class);
42+
$secondDataProvider->willImplement(RestrictedDataProviderInterface::class);
43+
$secondDataProvider->supports(Dummy::class, null, [])->willReturn(true);
44+
$secondDataProvider->getItem(Dummy::class, ['id' => 1], null, [])->willReturn($dummy);
45+
46+
$thirdDataProvider = $this->prophesize(DenormalizedIdentifiersAwareItemDataProviderInterface::class);
47+
$thirdDataProvider->willImplement(RestrictedDataProviderInterface::class);
48+
$thirdDataProvider->supports(Dummy::class, null, [])->willReturn(true);
49+
$thirdDataProvider->getItem(Dummy::class, ['id' => 1], null, [])->willReturn(new \stdClass());
50+
51+
$chainItemDataProvider = new ChainItemDataProvider([
52+
$firstDataProvider->reveal(),
53+
$secondDataProvider->reveal(),
54+
$thirdDataProvider->reveal(),
55+
]);
56+
57+
$this->assertEquals($dummy, $chainItemDataProvider->getItem(Dummy::class, ['id' => 1]));
58+
}
59+
60+
public function testGetItemWithoutDenormalizedIdentifiers()
61+
{
62+
$dummy = new Dummy();
63+
$dummy->setName('Lucie');
64+
3565
$firstDataProvider = $this->prophesize(ItemDataProviderInterface::class);
3666
$firstDataProvider->willImplement(RestrictedDataProviderInterface::class);
3767
$firstDataProvider->supports(Dummy::class, null, [])->willReturn(false);
3868

3969
$secondDataProvider = $this->prophesize(ItemDataProviderInterface::class);
4070
$secondDataProvider->willImplement(RestrictedDataProviderInterface::class);
4171
$secondDataProvider->supports(Dummy::class, null, [])->willReturn(true);
42-
$secondDataProvider->getItem(Dummy::class, 1, null, [])->willReturn($dummy);
72+
$secondDataProvider->getItem(Dummy::class, '1', null, [])->willReturn($dummy);
4373

4474
$thirdDataProvider = $this->prophesize(ItemDataProviderInterface::class);
4575
$thirdDataProvider->willImplement(RestrictedDataProviderInterface::class);
@@ -52,7 +82,7 @@ public function testGetItem()
5282
$thirdDataProvider->reveal(),
5383
]);
5484

55-
$this->assertEquals($dummy, $chainItemDataProvider->getItem(Dummy::class, 1));
85+
$this->assertEquals($dummy, $chainItemDataProvider->getItem(Dummy::class, ['id' => 1]));
5686
}
5787

5888
public function testGetItemExceptions()
@@ -86,7 +116,27 @@ public function testLegacyGetItem()
86116

87117
$chainItemDataProvider = new ChainItemDataProvider([$firstDataProvider->reveal(), $secondDataProvider->reveal(), $thirdDataProvider->reveal()]);
88118

89-
$this->assertEquals($dummy, $chainItemDataProvider->getItem(Dummy::class, 1));
119+
$chainItemDataProvider->getItem(Dummy::class, 1);
120+
}
121+
122+
/**
123+
* @group legacy
124+
* @expectedDeprecation Receiving "$id" as non-array in an item data provider is deprecated in 2.3 in favor of implementing "ApiPlatform\Core\DataProvider\DenormalizedIdentifiersAwareItemDataProviderInterface".
125+
*/
126+
public function testLegacyGetItemWithoutDenormalizedIdentifiersAndCompositeIdentifier()
127+
{
128+
$dummy = new CompositePrimitiveItem('Lucie', 1984);
129+
130+
$dataProvider = $this->prophesize(ItemDataProviderInterface::class);
131+
$dataProvider->willImplement(RestrictedDataProviderInterface::class);
132+
$dataProvider->supports(CompositePrimitiveItem::class, null, [])->willReturn(true);
133+
$dataProvider->getItem(CompositePrimitiveItem::class, 'name=Lucie;year=1984', null, [])->willReturn($dummy);
134+
135+
$chainItemDataProvider = new ChainItemDataProvider([
136+
$dataProvider->reveal(),
137+
]);
138+
139+
$this->assertEquals($dummy, $chainItemDataProvider->getItem(CompositePrimitiveItem::class, ['name' => 'Lucie', 'year' => 1984]));
90140
}
91141

92142
/**

tests/Fixtures/TestBundle/DataProvider/ContainNonResourceItemDataProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ public function getItem(string $resourceClass, $id, string $operationName = null
3535
{
3636
// Retrieve the blog post item from somewhere
3737
$cnr = new ContainNonResource();
38-
$cnr->id = $id['id'];
38+
$cnr->id = $id;
3939
$cnr->notAResource = new NotAResource('f1', 'b1');
4040
$cnr->nested = new ContainNonResource();
41-
$cnr->nested->id = "{$id['id']}-nested";
41+
$cnr->nested->id = "$id-nested";
4242
$cnr->nested->notAResource = new NotAResource('f2', 'b2');
4343

4444
return $cnr;

0 commit comments

Comments
 (0)