Skip to content

Commit

Permalink
Fix stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
teohhanhui authored and soyuka committed Mar 18, 2019
1 parent c5f6428 commit 186b8e9
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 153 deletions.
4 changes: 2 additions & 2 deletions features/main/content_negotiation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ Feature: Content Negotiation support
"jsonData": [],
"arrayData": [],
"name_converted": null,
"relatedOwnedDummy": null,
"relatedOwningDummy": null,
"relatedOwnedDummy": null,
"relatedOwningDummy": null,
"id": 1,
"name": "XML!",
"alias": null,
Expand Down
7 changes: 3 additions & 4 deletions src/GraphQl/Resolver/ResourceFieldResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ public function __construct(IriConverterInterface $iriConverter, ResourceClassRe
public function __invoke($source, $args, $context, ResolveInfo $info)
{
$property = null;
if ('id' === $info->fieldName && isset($source[ItemNormalizer::ITEM_KEY])) {
if ('id' === $info->fieldName && !isset($source['_id']) && isset($source[ItemNormalizer::ITEM_KEY])) {
$object = unserialize($source[ItemNormalizer::ITEM_KEY]);
if ($this->resourceClassResolver->isResourceClass($this->getObjectClass($object))) {
return $this->iriConverter->getIriFromItem($object);
}
}

if ('_id' === $info->fieldName && isset($source['id'])) {
// if we set _id in the normalizer we take it
$property = $source['_id'] ?? $source['id'];
if ('_id' === $info->fieldName && !isset($source['_id']) && isset($source['id'])) {
$property = $source['id'];
} elseif (\is_array($source) && isset($source[$info->fieldName])) {
$property = $source[$info->fieldName];
} elseif (isset($source->{$info->fieldName})) {
Expand Down
25 changes: 8 additions & 17 deletions src/GraphQl/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
use ApiPlatform\Core\Serializer\ItemNormalizer as BaseItemNormalizer;
use ApiPlatform\Core\Util\ClassInfoTrait;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* GraphQL normalizer.
Expand Down Expand Up @@ -47,28 +45,21 @@ public function supportsNormalization($data, $format = null, array $context = []
*/
public function normalize($object, $format = null, array $context = [])
{
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
if (!$this->serializer instanceof NormalizerInterface) {
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
}

$context['api_normalize'] = true;
$context['resource_class'] = $this->getObjectClass($transformed);
$context['origin_resource'] = $object;

return $this->serializer->normalize($transformed, $format, $context);
if (!$this->handleNonResource && null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
return parent::normalize($object, $format, $context);
}

$data = parent::normalize($object, $format, $context);
if (!\is_array($data)) {
throw new UnexpectedValueException('Expected data to be an array');
}

// we're handling the case where we have an Output class, we need the IRI from the origin resource
if (($context['origin_resource'] ?? false) && isset($data['id'])) {
$data['_id'] = $data['id'];
$data['id'] = $this->iriConverter->getIriFromItem($context['origin_resource']);
unset($context['origin_resource']);
if ($this->handleNonResource) {
// when using an output class, get the IRI from the resource
if (isset($context['api_resource']) && isset($data['id'])) {
$data['_id'] = $data['id'];
$data['id'] = $this->iriConverter->getIriFromItem($context['api_resource']);
}
}

$data[self::ITEM_KEY] = serialize($object); // calling serialize prevent weird normalization process done by Webonyx's GraphQL PHP
Expand Down
28 changes: 4 additions & 24 deletions src/Hal/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@

namespace ApiPlatform\Core\Hal\Serializer;

use ApiPlatform\Core\Exception\RuntimeException;
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
use ApiPlatform\Core\Serializer\ContextTrait;
use ApiPlatform\Core\Util\ClassInfoTrait;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* Converts between objects and array including HAL metadata.
Expand Down Expand Up @@ -50,26 +48,8 @@ public function supportsNormalization($data, $format = null, array $context = []
*/
public function normalize($object, $format = null, array $context = [])
{
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
if (!$this->serializer instanceof NormalizerInterface) {
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
}

$context['api_normalize'] = true;
$context['resource_class'] = $this->getObjectClass($transformed);

return $this->serializer->normalize($transformed, $format, $context);
}

if ($this->handleNonResource && $context['api_normalize'] ?? false) {
$object = $this->transformOutput($object, $context);
$data = $this->initContext($this->getObjectClass($object), $context);
$rawData = parent::normalize($object, $format, $context);
if (!\is_array($rawData)) {
return $rawData;
}

return $data + $rawData;
if ($this->handleNonResource || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
return parent::normalize($object, $format, $context);
}

if (!isset($context['cache_key'])) {
Expand Down Expand Up @@ -105,11 +85,11 @@ public function supportsDenormalization($data, $type, $format = null, array $con
/**
* {@inheritdoc}
*
* @throws RuntimeException
* @throws LogicException
*/
public function denormalize($data, $class, $format = null, array $context = [])
{
throw new RuntimeException(sprintf('%s is a read-only format.', self::FORMAT));
throw new LogicException(sprintf('%s is a read-only format.', self::FORMAT));
}

/**
Expand Down
45 changes: 19 additions & 26 deletions src/JsonApi/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use ApiPlatform\Core\Api\IriConverterInterface;
use ApiPlatform\Core\Api\OperationType;
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
use ApiPlatform\Core\Exception\InvalidArgumentException;
use ApiPlatform\Core\Exception\ItemNotFoundException;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
Expand All @@ -25,7 +24,9 @@
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
use ApiPlatform\Core\Util\ClassInfoTrait;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
Expand Down Expand Up @@ -63,22 +64,7 @@ public function supportsNormalization($data, $format = null, array $context = []
*/
public function normalize($object, $format = null, array $context = [])
{
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
if (!$this->serializer instanceof NormalizerInterface) {
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
}

$context['api_normalize'] = true;
$context['resource_class'] = $this->getObjectClass($transformed);

return $this->serializer->normalize($transformed, $format, $context);
}

if ($this->handleNonResource && $context['api_normalize'] ?? false) {
$object = $this->transformOutput($object, $context);
$context['api_normalize'] = true;
$context['resource_class'] = $this->getObjectClass($object);

if ($this->handleNonResource || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
return parent::normalize($object, $format, $context);
}

Expand Down Expand Up @@ -135,13 +121,15 @@ public function supportsDenormalization($data, $type, $format = null, array $con

/**
* {@inheritdoc}
*
* @throws NotNormalizableValueException
*/
public function denormalize($data, $class, $format = null, array $context = [])
{
// Avoid issues with proxies if we populated the object
if (!isset($context[self::OBJECT_TO_POPULATE]) && isset($data['data']['id'])) {
if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) {
throw new InvalidArgumentException('Update is not allowed for this operation.');
throw new NotNormalizableValueException('Update is not allowed for this operation.');
}

$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri(
Expand Down Expand Up @@ -184,6 +172,9 @@ protected function setAttributeValue($object, $attribute, $value, $format = null
* {@inheritdoc}
*
* @see http://jsonapi.org/format/#document-resource-object-linkage
*
* @throws RuntimeException
* @throws NotNormalizableValueException
*/
protected function denormalizeRelation(string $attributeName, PropertyMetadata $propertyMetadata, string $className, $value, string $format = null, array $context)
{
Expand All @@ -194,24 +185,26 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $
if ($this->serializer instanceof DenormalizerInterface) {
return $this->serializer->denormalize($value, $className, $format, $context);
}
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', DenormalizerInterface::class));
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', DenormalizerInterface::class));
}

if (!\is_array($value) || !isset($value['id'], $value['type'])) {
throw new InvalidArgumentException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
throw new NotNormalizableValueException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
}

try {
return $this->iriConverter->getItemFromIri($value['id'], $context + ['fetch_data' => true]);
} catch (ItemNotFoundException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}
}

/**
* {@inheritdoc}
*
* @see http://jsonapi.org/format/#document-resource-object-linkage
*
* @throws RuntimeException
*/
protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relatedObject, string $resourceClass, string $format = null, array $context)
{
Expand All @@ -224,7 +217,7 @@ protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relate
if ($this->serializer instanceof NormalizerInterface) {
return $this->serializer->normalize($relatedObject, $format, $context);
}
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
}
} else {
$iri = $this->iriConverter->getIriFromItem($relatedObject);
Expand All @@ -236,7 +229,7 @@ protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relate
$context['api_sub_level'] = true;

if (!$this->serializer instanceof NormalizerInterface) {
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
}
$data = $this->serializer->normalize($relatedObject, $format, $context);
unset($context['api_sub_level']);
Expand Down Expand Up @@ -328,7 +321,7 @@ private function getComponents($object, string $format = null, array $context)
*
* @param object $object
*
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
private function getPopulatedRelations($object, string $format = null, array $context, array $relationships): array
{
Expand Down Expand Up @@ -367,7 +360,7 @@ private function getPopulatedRelations($object, string $format = null, array $co
// Many to many relationship
foreach ($attributeValue as $attributeValueElement) {
if (!isset($attributeValueElement['data'])) {
throw new InvalidArgumentException(sprintf('The JSON API attribute \'%s\' must contain a "data" key.', $relationshipName));
throw new UnexpectedValueException(sprintf('The JSON API attribute \'%s\' must contain a "data" key.', $relationshipName));
}
unset($attributeValueElement['data']['attributes']);
$data[$relationshipName]['data'][] = $attributeValueElement['data'];
Expand Down
31 changes: 14 additions & 17 deletions src/JsonLd/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

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;
Expand All @@ -25,9 +24,9 @@
use ApiPlatform\Core\Util\ClassInfoTrait;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* Converts between objects and array including JSON-LD and Hydra metadata.
Expand Down Expand Up @@ -61,24 +60,22 @@ public function supportsNormalization($data, $format = null, array $context = []

/**
* {@inheritdoc}
*
* @throws LogicException
*/
public function normalize($object, $format = null, array $context = [])
{
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
if (!$this->serializer instanceof NormalizerInterface) {
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
}

$context['api_normalize'] = true;
$context['resource_class'] = $this->getObjectClass($transformed);
$context['origin_resource'] = $object;

return $this->serializer->normalize($transformed, $format, $context);
if (!$this->handleNonResource && null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
return parent::normalize($object, $format, $context);
}

if ($this->handleNonResource && $context['api_normalize'] ?? false) {
if (($context['origin_resource'] ?? false)) {
$context['output']['iri'] = $this->iriConverter->getIriFromItem($context['origin_resource']);
if ($this->handleNonResource) {
if (!($context['api_normalize'] ?? false)) {
throw new LogicException('"api_normalize" must be set to true in context to normalize non-resource');
}

if (isset($context['api_resource'])) {
$context['output']['iri'] = $this->iriConverter->getIriFromItem($context['api_resource']);
}

$context['api_normalize'] = true;
Expand Down Expand Up @@ -127,14 +124,14 @@ public function supportsDenormalization($data, $type, $format = null, array $con
/**
* {@inheritdoc}
*
* @throws InvalidArgumentException
* @throws NotNormalizableValueException
*/
public function denormalize($data, $class, $format = null, array $context = [])
{
// Avoid issues with proxies if we populated the object
if (isset($data['@id']) && !isset($context[self::OBJECT_TO_POPULATE])) {
if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) {
throw new InvalidArgumentException('Update is not allowed for this operation.');
throw new NotNormalizableValueException('Update is not allowed for this operation.');
}

$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri($data['@id'], $context + ['fetch_data' => true]);
Expand Down
Loading

0 comments on commit 186b8e9

Please sign in to comment.