diff --git a/features/bootstrap/DoctrineContext.php b/features/bootstrap/DoctrineContext.php index 5f6c1b168f0..e9d5b43f050 100644 --- a/features/bootstrap/DoctrineContext.php +++ b/features/bootstrap/DoctrineContext.php @@ -78,6 +78,8 @@ use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedRelated; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedString; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Customer; +use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DisableItemOperation; +use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DisableItemOperation as DisableItemOperationDocument; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyAggregateOffer; use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCar; @@ -1484,6 +1486,17 @@ public function thereAreConvertedOwnerObjects(int $nb) $this->manager->flush(); } + /** + * @Given there is 1 DisableItemOperation + */ + public function thereIsOneDisableItemOperation() + { + $item = $this->buildDisableItemOperation(); + $item->name = 'Test'; + $this->manager->persist($item); + $this->manager->flush(); + } + private function isOrm(): bool { return null !== $this->schemaTool; @@ -1853,4 +1866,12 @@ private function buildConvertedRelated() { return $this->isOrm() ? new ConvertedRelated() : new ConvertedRelatedDocument(); } + + /** + * @return DisableItemOperation|DisableItemOperationDocument + */ + private function buildDisableItemOperation() + { + return $this->isOrm() ? new DisableItemOperation() : new DisableItemOperationDocument(); + } } diff --git a/features/main/operation.feature b/features/main/operation.feature index b81805498ea..b4c71a0520e 100644 --- a/features/main/operation.feature +++ b/features/main/operation.feature @@ -55,3 +55,9 @@ Feature: Operation support } } """ + + @createSchema + Scenario: Get a resource that doesn't have a defined item operation + Given there is 1 DisableItemOperation + When I send a "GET" request to "/disable_item_operations" + Then the response status code should be 200 diff --git a/src/JsonLd/Serializer/ItemNormalizer.php b/src/JsonLd/Serializer/ItemNormalizer.php index aca10e346d7..2d2efbba6d8 100644 --- a/src/JsonLd/Serializer/ItemNormalizer.php +++ b/src/JsonLd/Serializer/ItemNormalizer.php @@ -15,6 +15,7 @@ use ApiPlatform\Core\Api\IriConverterInterface; use ApiPlatform\Core\Api\ResourceClassResolverInterface; +use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\JsonLd\ContextBuilderInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; @@ -71,7 +72,13 @@ public function normalize($object, $format = null, array $context = []) $resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null); $context = $this->initContext($resourceClass, $context); - $iri = $this->iriConverter->getIriFromItem($object); + + try { + $iri = $this->iriConverter->getIriFromItem($object); + } catch (InvalidArgumentException $e) { + $iri = '_:'.(\function_exists('spl_object_id') ? spl_object_id($object) : spl_object_hash($object)); + } + $context['iri'] = $iri; $context['api_normalize'] = true; diff --git a/tests/Fixtures/TestBundle/Document/DisableItemOperation.php b/tests/Fixtures/TestBundle/Document/DisableItemOperation.php new file mode 100644 index 00000000000..51af135ba06 --- /dev/null +++ b/tests/Fixtures/TestBundle/Document/DisableItemOperation.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Document; + +use ApiPlatform\Core\Annotation\ApiResource; +use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; + +/** + * DisableItemOperation. + * + * @author Antoine Bluchet + * + * @ApiResource(itemOperations={}, collectionOperations={"get"}) + * @ODM\Document + */ +class DisableItemOperation +{ + /** + * @ODM\Id(strategy="INCREMENT", type="integer") + */ + private $id; + + /** + * @var string The dummy name + * + * @ODM\Field + */ + public $name; + + public function getId() { + return $this->id; + } +} diff --git a/tests/Fixtures/TestBundle/Entity/DisableItemOperation.php b/tests/Fixtures/TestBundle/Entity/DisableItemOperation.php new file mode 100644 index 00000000000..7d53109234d --- /dev/null +++ b/tests/Fixtures/TestBundle/Entity/DisableItemOperation.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity; + +use ApiPlatform\Core\Annotation\ApiResource; +use Doctrine\ORM\Mapping as ORM; + +/** + * DisableItemOperation. + * + * @author Antoine Bluchet + * + * @ApiResource(itemOperations={}, collectionOperations={"get", "post"}) + * @ORM\Entity + */ +class DisableItemOperation +{ + /** + * @var int The id + * + * @ORM\Column(type="integer", nullable=true) + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string The dummy name + * + * @ORM\Column + */ + public $name; + + public function getId() { + return $this->id; + } +}