diff --git a/src/lib/Output/Generator/AbstractFieldTypeHashGenerator.php b/src/lib/Output/Generator/AbstractFieldTypeHashGenerator.php new file mode 100644 index 00000000..ceffc72b --- /dev/null +++ b/src/lib/Output/Generator/AbstractFieldTypeHashGenerator.php @@ -0,0 +1,142 @@ +normalizer = $normalizer; + $this->logger = $logger ?? new NullLogger(); + $this->strictMode = $strictMode; + } + + /** + * Generates the field type value $hashValue as a child of the given Object + * using $hashElementName as the property name. + */ + public function generateHashValue( + JsonObject|ArrayObject|ArrayList $parent, + string $hashElementName, + mixed $hashValue + ): void { + $parent->$hashElementName = $this->generateValue($parent, $hashValue); + } + + /** + * Generates and returns a JSON structure (array or object) depending on $value type + * with $parent. + * + * If $type only contains numeric keys, the resulting structure will be an + * JSON array, otherwise a JSON object + * + * @param array $value + */ + protected function generateArrayValue( + JsonObject|ArrayObject|ArrayList $parent, + array $value, + ): JsonObject|ArrayObject|ArrayList { + if ($this->isNumericArray($value)) { + return $this->generateListArray($parent, $value); + } else { + return $this->generateHashArray($parent, $value); + } + } + + /** + * Generates and returns a value based on $hashValue type, with $parent ( + * if the type of $hashValue supports it). + */ + abstract protected function generateValue(JsonObject|ArrayObject|ArrayList $parent, mixed $value): mixed; + + /** + * Checks if the given $value is a purely numeric array. + * + * @param array $value + */ + protected function isNumericArray(array $value): bool + { + foreach (array_keys($value) as $key) { + if (is_string($key)) { + return false; + } + } + + return true; + } + + protected function generateObjectValue(JsonObject|ArrayObject|ArrayList $parent, object $value): mixed + { + try { + $value = $this->normalizer->normalize($value, 'json', ['parent' => $parent]); + } catch (ExceptionInterface $e) { + if ($this->strictMode) { + throw $e; + } + $message = sprintf( + 'Unable to normalize value for type "%s". %s. ' + . 'Ensure that a normalizer is registered with tag: "%s".', + get_class($value), + $e->getMessage(), + 'ibexa.rest.serializer.normalizer', + ); + + assert($this->logger instanceof LoggerInterface); + $this->logger->error($message, [ + 'exception' => $e, + ]); + + $value = null; + } + + if (is_array($value)) { + return $this->generateArrayValue($parent, $value); + } + + return $value; + } + + /** + * Generates a JSON array from the given $hashArray with $parent. + * + * @param array $listArray + */ + abstract protected function generateListArray( + JsonObject|ArrayObject|ArrayList $parent, + array $listArray, + ): JsonObject|ArrayObject|ArrayList; + + /** + * Generates a JSON object from the given $hashArray with $parent. + * + * @param array $hashArray + */ + abstract protected function generateHashArray( + JsonObject|ArrayObject|ArrayList $parent, + array $hashArray, + ): JsonObject|ArrayObject|ArrayList; +} diff --git a/src/lib/Output/Generator/Json/FieldTypeHashGenerator.php b/src/lib/Output/Generator/Json/FieldTypeHashGenerator.php index 31b369ee..69456be4 100644 --- a/src/lib/Output/Generator/Json/FieldTypeHashGenerator.php +++ b/src/lib/Output/Generator/Json/FieldTypeHashGenerator.php @@ -4,57 +4,16 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Rest\Output\Generator\Json; -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; -use Symfony\Component\Serializer\Exception\ExceptionInterface; -use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use Ibexa\Rest\Output\Generator\AbstractFieldTypeHashGenerator; +use Ibexa\Rest\Output\Generator\Data\ArrayList; -class FieldTypeHashGenerator implements LoggerAwareInterface +class FieldTypeHashGenerator extends AbstractFieldTypeHashGenerator { - use LoggerAwareTrait; - - private NormalizerInterface $normalizer; - - private bool $strictMode; - - public function __construct( - NormalizerInterface $normalizer, - ?LoggerInterface $logger = null, - bool $strictMode = false - ) { - $this->normalizer = $normalizer; - $this->logger = $logger ?? new NullLogger(); - $this->strictMode = $strictMode; - } - - /** - * Generates the field type value $hashValue as a child of the given Object - * using $hashElementName as the property name. - * - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject|\Ibexa\Rest\Output\Generator\Data\ArrayList $parent - * @param string $hashElementName - * @param mixed $hashValue - */ - public function generateHashValue($parent, $hashElementName, $hashValue) - { - $parent->$hashElementName = $this->generateValue($parent, $hashValue); - } - - /** - * Generates and returns a value based on $hashValue type, with $parent ( - * if the type of $hashValue supports it). - * - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject $parent - * @param mixed $value - * - * @return mixed - */ - protected function generateValue($parent, $value) + protected function generateValue(JsonObject|ArrayObject|ArrayList $parent, mixed $value): mixed { if ($value === null || is_scalar($value)) { // Will be handled accordingly on serialization @@ -72,37 +31,10 @@ protected function generateValue($parent, $value) throw new \Exception('Invalid type in Field value hash: ' . get_debug_type($value)); } - /** - * Generates and returns a JSON structure (array or object) depending on $value type - * with $parent. - * - * If $type only contains numeric keys, the resulting structure will be an - * JSON array, otherwise a JSON object - * - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject $parent - * @param array $value - * - * @return \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject - */ - protected function generateArrayValue($parent, array $value) - { - if ($this->isNumericArray($value)) { - return $this->generateListArray($parent, $value); - } else { - return $this->generateHashArray($parent, $value); - } - } - - /** - * Generates a JSON array from the given $hashArray with $parent. - * - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject|\Ibexa\Rest\Output\Generator\Data\ArrayList $parent - * @param array $listArray - * - * @return \Ibexa\Rest\Output\Generator\Json\ArrayObject|JsonObject - */ - protected function generateListArray($parent, array $listArray) - { + protected function generateListArray( + JsonObject|ArrayObject|ArrayList $parent, + array $listArray, + ): JsonObject|ArrayObject|ArrayList { $arrayObject = new ArrayObject($parent); foreach ($listArray as $listItem) { $arrayObject->append($this->generateValue($arrayObject, $listItem)); @@ -111,16 +43,10 @@ protected function generateListArray($parent, array $listArray) return $arrayObject; } - /** - * Generates a JSON object from the given $hashArray with $parent. - * - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject $parent - * @param array $hashArray - * - * @return \Ibexa\Rest\Output\Generator\Json\JsonObject - */ - protected function generateHashArray($parent, array $hashArray) - { + protected function generateHashArray( + JsonObject|ArrayObject|ArrayList $parent, + array $hashArray, + ): JsonObject|ArrayObject|ArrayList { $object = new JsonObject($parent); foreach ($hashArray as $hashKey => $hashItem) { $object->$hashKey = $this->generateValue($object, $hashItem); @@ -128,56 +54,4 @@ protected function generateHashArray($parent, array $hashArray) return $object; } - - /** - * Checks if the given $value is a purely numeric array. - * - * @param array $value - * - * @return bool - */ - protected function isNumericArray(array $value) - { - foreach (array_keys($value) as $key) { - if (is_string($key)) { - return false; - } - } - - return true; - } - - /** - * @param \Ibexa\Rest\Output\Generator\Json\ArrayObject|\Ibexa\Rest\Output\Generator\Json\JsonObject $parent - * - * @return mixed - */ - protected function generateObjectValue($parent, object $value) - { - try { - $value = $this->normalizer->normalize($value, 'json', ['parent' => $parent]); - } catch (ExceptionInterface $e) { - if ($this->strictMode) { - throw $e; - } - $message = sprintf( - 'Unable to normalize value for type "%s". %s. ' - . 'Ensure that a normalizer is registered with tag: "%s".', - get_class($value), - $e->getMessage(), - 'ibexa.rest.serializer.normalizer', - ); - $this->logger->error($message, [ - 'exception' => $e, - ]); - - $value = null; - } - - if (is_array($value)) { - return $this->generateArrayValue($parent, $value); - } - - return $value; - } } diff --git a/src/lib/Output/Generator/Xml/FieldTypeHashGenerator.php b/src/lib/Output/Generator/Xml/FieldTypeHashGenerator.php index d8f107c3..9c12dc01 100644 --- a/src/lib/Output/Generator/Xml/FieldTypeHashGenerator.php +++ b/src/lib/Output/Generator/Xml/FieldTypeHashGenerator.php @@ -8,12 +8,14 @@ namespace Ibexa\Rest\Output\Generator\Xml; -use Ibexa\Rest\Output\Generator\Json\FieldTypeHashGenerator as JsonFieldTypeHashGenerator; +use Ibexa\Rest\Output\Generator\AbstractFieldTypeHashGenerator; +use Ibexa\Rest\Output\Generator\Data\ArrayList; +use Ibexa\Rest\Output\Generator\Json\ArrayObject; use Ibexa\Rest\Output\Generator\Json\JsonObject; -final class FieldTypeHashGenerator extends JsonFieldTypeHashGenerator +final class FieldTypeHashGenerator extends AbstractFieldTypeHashGenerator { - protected function generateValue($parent, $value): mixed + protected function generateValue(JsonObject|ArrayObject|ArrayList $parent, mixed $value): mixed { if ($value === null) { return null; @@ -30,17 +32,10 @@ protected function generateValue($parent, $value): mixed } } - protected function generateArrayValue($parent, $value): JsonObject - { - if ($this->isNumericArray($value)) { - return $this->generateListArray($parent, $value); - } else { - return $this->generateHashArray($parent, $value); - } - } - - protected function generateListArray($parent, array $listArray): JsonObject - { + protected function generateListArray( + JsonObject|ArrayObject|ArrayList $parent, + array $listArray, + ): JsonObject|ArrayObject|ArrayList { $object = new JsonObject($parent); $object->value = []; @@ -53,8 +48,10 @@ protected function generateListArray($parent, array $listArray): JsonObject return $object; } - protected function generateHashArray($parent, array $hashArray): JsonObject - { + protected function generateHashArray( + JsonObject|ArrayObject|ArrayList $parent, + array $hashArray, + ): JsonObject|ArrayObject|ArrayList { $object = new JsonObject($parent); $object->value = [];