From f09647ec37cdca7a3638e15659f47659edc8155f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Thu, 12 Apr 2018 11:11:56 +0200 Subject: [PATCH 1/3] On invalid iri error with plain identifiers, use the data provider If a resource property is writable, we can't use plain identifiers, and end up with a iri error, while we explicit allowed plain identifiers. --- src/Serializer/AbstractItemNormalizer.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index e6693532a27..59f9057cc4e 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -304,7 +304,17 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $ $context['resource_class'] = $className; $context['api_allow_update'] = true; - return $this->serializer->denormalize($value, $className, $format, $context); + try { + return $this->serializer->denormalize($value, $className, $format, $context); + } catch (InvalidArgumentException $e) { + if ('Invalid value provided (invalid IRI?).' !== $e->getMessage()) { + throw $e; + } + + if (!$this->allowPlainIdentifiers || null === $this->itemDataProvider) { + throw $e; + } + } } if (!\is_array($value)) { From 28a8259a39e94ae8de4bc54432dac0c2be0b35c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Thu, 12 Apr 2018 12:43:33 +0200 Subject: [PATCH 2/3] Make an appropriare exception for invalid value on item normalizer --- src/Exception/InvalidValueException.php | 18 ++++++++++++++++++ src/Serializer/AbstractItemNormalizer.php | 9 +++------ 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 src/Exception/InvalidValueException.php diff --git a/src/Exception/InvalidValueException.php b/src/Exception/InvalidValueException.php new file mode 100644 index 00000000000..5d3b8d458ab --- /dev/null +++ b/src/Exception/InvalidValueException.php @@ -0,0 +1,18 @@ + + * + * 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\Exception; + +class InvalidValueException extends InvalidArgumentException +{ +} diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index 59f9057cc4e..4d3cf52d355 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -18,6 +18,7 @@ use ApiPlatform\Core\Api\ResourceClassResolverInterface; use ApiPlatform\Core\DataProvider\ItemDataProviderInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; +use ApiPlatform\Core\Exception\InvalidValueException; use ApiPlatform\Core\Exception\ItemNotFoundException; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; @@ -157,7 +158,7 @@ protected function getAllowedAttributes($classOrObject, array $context, $attribu protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = []) { if (!\is_string($attribute)) { - throw new InvalidArgumentException('Invalid value provided (invalid IRI?).'); + throw new InvalidValueException('Invalid value provided (invalid IRI?).'); } $propertyMetadata = $this->propertyMetadataFactory->create($context['resource_class'], $attribute, $this->getFactoryOptions($context)); @@ -306,11 +307,7 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $ try { return $this->serializer->denormalize($value, $className, $format, $context); - } catch (InvalidArgumentException $e) { - if ('Invalid value provided (invalid IRI?).' !== $e->getMessage()) { - throw $e; - } - + } catch (InvalidValueException $e) { if (!$this->allowPlainIdentifiers || null === $this->itemDataProvider) { throw $e; } From cd0dd88331c3d2eb98c793dab79d4835762ee75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Thu, 12 Apr 2018 18:38:35 +0200 Subject: [PATCH 3/3] Add a behat test for plain id relations --- features/main/relation.feature | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/features/main/relation.feature b/features/main/relation.feature index 5dea0791074..bc9fa83b253 100644 --- a/features/main/relation.feature +++ b/features/main/relation.feature @@ -512,13 +512,50 @@ Feature: Relations support } """ + Scenario: Passing a (valid) plain identifier on a relation + When I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/dummies" with body: + """ + { + "relatedDummy": "1", + "relatedDummies": ["1"], + "name": "Dummy with plain relations" + } + """ + Then the response status code should be 201 + And the response should be in JSON + And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8" + And the JSON should be equal to: + """ + { + "@context":"/contexts/Dummy", + "@id":"/dummies/2", + "@type":"Dummy", + "description":null, + "dummy":null, + "dummyBoolean":null, + "dummyDate":null, + "dummyFloat":null, + "dummyPrice":null, + "relatedDummy":"/related_dummies/1", + "relatedDummies":["/related_dummies/1"], + "jsonData":[], + "arrayData":[], + "name_converted":null, + "id":2, + "name":"Dummy with plain relations", + "alias":null, + "foo":null + } + """ + @dropSchema Scenario: Passing an invalid IRI to a relation When I add "Content-Type" header equal to "application/ld+json" And I send a "POST" request to "/relation_embedders" with body: """ { - "related": "certainly not an iri" + "related": "certainly not an iri and not a plain identifier" } """ Then the response status code should be 400