diff --git a/src/JsonApiSerializer.php b/src/JsonApiSerializer.php index 63a2420..f08693b 100644 --- a/src/JsonApiSerializer.php +++ b/src/JsonApiSerializer.php @@ -52,11 +52,9 @@ public function serialize($value) $this->filterOutResourceFields($request); $this->filterOutIncludedResources($request); - return parent::serialize($value); } - /** * @param Request $request */ diff --git a/src/Server/Data/DataAssertions.php b/src/Server/Data/DataAssertions.php index a819449..f711d07 100644 --- a/src/Server/Data/DataAssertions.php +++ b/src/Server/Data/DataAssertions.php @@ -11,6 +11,7 @@ namespace NilPortugues\Api\JsonApi\Server\Data; use NilPortugues\Api\JsonApi\JsonApiSerializer; +use NilPortugues\Api\JsonApi\JsonApiTransformer; use NilPortugues\Api\JsonApi\Server\Errors\ErrorBag; use NilPortugues\Api\JsonApi\Server\Errors\InvalidAttributeError; use NilPortugues\Api\JsonApi\Server\Errors\InvalidTypeError; @@ -60,7 +61,7 @@ private static function assertItIsArray($data, ErrorBag $errorBag) */ private static function assertItHasTypeMember(array $data, ErrorBag $errorBag) { - if (empty($data['type']) || !is_string($data['type'])) { + if (empty($data[JsonApiTransformer::TYPE_KEY]) || !is_string($data[JsonApiTransformer::TYPE_KEY])) { $errorBag[] = new MissingTypeError(); throw new DataException(); } @@ -80,10 +81,10 @@ private static function assertItTypeMemberIsExpectedValue( $className, ErrorBag $errorBag ) { - $mapping = $serializer->getTransformer()->getMappingByAlias($data['type']); + $mapping = $serializer->getTransformer()->getMappingByAlias($data[JsonApiTransformer::TYPE_KEY]); if (null === $mapping || $mapping->getClassName() !== $className) { - $errorBag[] = new InvalidTypeError($data['type']); + $errorBag[] = new InvalidTypeError($data[JsonApiTransformer::TYPE_KEY]); throw new DataException(); } } @@ -96,7 +97,7 @@ private static function assertItTypeMemberIsExpectedValue( */ private static function assertItHasAttributeMember($data, ErrorBag $errorBag) { - if (empty($data['attributes']) || !is_array($data['attributes'])) { + if (empty($data[JsonApiTransformer::ATTRIBUTES_KEY]) || !is_array($data[JsonApiTransformer::ATTRIBUTES_KEY])) { $errorBag[] = new MissingAttributesError(); throw new DataException(); } @@ -111,9 +112,9 @@ private static function assertItHasAttributeMember($data, ErrorBag $errorBag) */ private static function assertAttributesExists(array $data, JsonApiSerializer $serializer, ErrorBag $errorBag) { - $inputAttributes = array_keys($data['attributes']); + $inputAttributes = array_keys($data[JsonApiTransformer::ATTRIBUTES_KEY]); - $mapping = $serializer->getTransformer()->getMappingByAlias($data['type']); + $mapping = $serializer->getTransformer()->getMappingByAlias($data[JsonApiTransformer::TYPE_KEY]); $properties = str_replace( array_keys($mapping->getAliasedProperties()), @@ -121,13 +122,13 @@ private static function assertAttributesExists(array $data, JsonApiSerializer $s $mapping->getProperties() ); $properties = array_diff($properties, $mapping->getIdProperties()); - $properties = array_diff($properties, $mapping->getHiddenProperties()); + $properties = array_merge($properties, $mapping->getHiddenProperties()); $hasErrors = false; foreach ($inputAttributes as $property) { if (false === in_array($property, $properties)) { $hasErrors = true; - $errorBag[] = new InvalidAttributeError($property, $data['type']); + $errorBag[] = new InvalidAttributeError($property, $data[JsonApiTransformer::TYPE_KEY]); } } diff --git a/src/Server/Data/DataObject.php b/src/Server/Data/DataObject.php index dfbd4d3..b4e367a 100644 --- a/src/Server/Data/DataObject.php +++ b/src/Server/Data/DataObject.php @@ -11,14 +11,30 @@ namespace NilPortugues\Api\JsonApi\Server\Data; use NilPortugues\Api\JsonApi\JsonApiSerializer; +use NilPortugues\Api\JsonApi\JsonApiTransformer; use NilPortugues\Api\JsonApi\Server\Errors\ErrorBag; +use NilPortugues\Api\JsonApi\Server\Errors\InvalidAttributeError; +use NilPortugues\Api\JsonApi\Server\Errors\InvalidTypeError; use NilPortugues\Api\JsonApi\Server\Errors\MissingAttributeError; +use NilPortugues\Api\JsonApi\Server\Errors\MissingDataError; +use NilPortugues\Api\JsonApi\Server\Errors\MissingTypeError; /** * Class DataObject. */ class DataObject { + /** + * @param array $data + * @param JsonApiSerializer $serializer + * @param string $className + * @param ErrorBag $errorBag + */ + public static function assertPatch($data, JsonApiSerializer $serializer, $className, ErrorBag $errorBag) + { + DataAssertions::assert($data, $serializer, $className, $errorBag); + } + /** * @param array $data * @param JsonApiSerializer $serializer @@ -34,12 +50,16 @@ public static function assertPost($data, JsonApiSerializer $serializer, $classNa } catch (DataException $e) { } + try { + self::assertRelationshipData($data, $serializer, $errorBag); + } catch (DataException $e) { + } + $missing = self::missingCreationAttributes($data, $serializer); if (false === empty($missing)) { foreach ($missing as $attribute) { $errorBag[] = new MissingAttributeError($attribute); } - throw new DataException(); } } @@ -56,28 +76,17 @@ public static function assertPut($data, JsonApiSerializer $serializer, $classNam self::assertPost($data, $serializer, $className, $errorBag); } - /** - * @param array $data - * @param JsonApiSerializer $serializer - * @param string $className - * @param ErrorBag $errorBag - */ - public static function assertPatch($data, JsonApiSerializer $serializer, $className, ErrorBag $errorBag) - { - DataAssertions::assert($data, $serializer, $className, $errorBag); - } - /** * @param array $data * @param JsonApiSerializer $serializer * * @return array */ - private static function missingCreationAttributes(array $data, JsonApiSerializer $serializer) + private static function missingCreationAttributes(array $data, $serializer) { - $inputAttributes = array_keys($data['attributes']); + $inputAttributes = array_keys($data[JsonApiTransformer::ATTRIBUTES_KEY]); - $mapping = $serializer->getTransformer()->getMappingByAlias($data['type']); + $mapping = $serializer->getTransformer()->getMappingByAlias($data[JsonApiTransformer::TYPE_KEY]); $properties = str_replace( array_keys($mapping->getAliasedProperties()), @@ -99,10 +108,93 @@ private static function missingCreationAttributes(array $data, JsonApiSerializer */ public static function getAttributes(array $data, JsonApiSerializer $serializer) { - $mapping = $serializer->getTransformer()->getMappingByAlias($data['type']); + $mapping = $serializer->getTransformer()->getMappingByAlias($data[JsonApiTransformer::TYPE_KEY]); $aliases = $mapping->getAliasedProperties(); - $keys = str_replace(array_values($aliases), array_keys($aliases), array_keys($data['attributes'])); + $keys = str_replace( + array_values($aliases), + array_keys($aliases), + array_keys($data[JsonApiTransformer::ATTRIBUTES_KEY]) + ); + + return array_combine($keys, array_values($data[JsonApiTransformer::ATTRIBUTES_KEY])); + } - return array_combine($keys, array_values($data['attributes'])); + /** + * @param array $data + * @param JsonApiSerializer $serializer + * @param ErrorBag $errorBag + * + * @throws DataException + */ + private static function assertRelationshipData(array $data, JsonApiSerializer $serializer, ErrorBag $errorBag) + { + if (!empty($data[JsonApiTransformer::RELATIONSHIPS_KEY])) { + foreach ($data[JsonApiTransformer::RELATIONSHIPS_KEY] as $relationshipData) { + if (empty($relationshipData[JsonApiTransformer::DATA_KEY]) || !is_array( + $relationshipData[JsonApiTransformer::DATA_KEY] + ) + ) { + $errorBag[] = new MissingDataError(); + break; + } + + $firstKey = key($relationshipData[JsonApiTransformer::DATA_KEY]); + if (is_numeric($firstKey)) { + foreach ($relationshipData[JsonApiTransformer::DATA_KEY] as $inArrayRelationshipData) { + self::relationshipDataAssert($inArrayRelationshipData, $serializer, $errorBag); + } + break; + } + + self::relationshipDataAssert($relationshipData[JsonApiTransformer::DATA_KEY], $serializer, $errorBag); + } + } + } + + /** + * @param array $relationshipData + * @param JsonApiSerializer $serializer + * @param ErrorBag $errorBag + */ + private static function relationshipDataAssert($relationshipData, JsonApiSerializer $serializer, ErrorBag $errorBag) + { + //Has type member. + if (empty($relationshipData[JsonApiTransformer::TYPE_KEY]) || !is_string( + $relationshipData[JsonApiTransformer::TYPE_KEY] + ) + ) { + $errorBag[] = new MissingTypeError(); + + return; + } + + //Provided type value is supported. + if (null === $serializer->getTransformer()->getMappingByAlias( + $relationshipData[JsonApiTransformer::TYPE_KEY] + ) + ) { + $errorBag[] = new InvalidTypeError($relationshipData[JsonApiTransformer::TYPE_KEY]); + + return; + } + + //Validate if attributes passed in make sense. + if (!empty($relationshipData[JsonApiTransformer::ATTRIBUTES_KEY])) { + $mapping = $serializer->getTransformer()->getMappingByAlias( + $relationshipData[JsonApiTransformer::TYPE_KEY] + ); + + $properties = str_replace( + array_keys($mapping->getAliasedProperties()), + array_values($mapping->getAliasedProperties()), + $mapping->getProperties() + ); + + foreach (array_keys($relationshipData[JsonApiTransformer::ATTRIBUTES_KEY]) as $property) { + if (false === in_array($property, $properties, true)) { + $errorBag[] = new InvalidAttributeError($property, $relationshipData[JsonApiTransformer::TYPE_KEY]); + } + } + } } }