xero-8.x-2.x-dev/src/Normalizer/XeroListNormalizer.php
src/Normalizer/XeroListNormalizer.php
<?php
namespace Drupal\xero\Normalizer;
use Drupal\Core\TypedData\Plugin\DataType\ItemList;
use Drupal\serialization\Normalizer\TypedDataNormalizer;
use Drupal\xero\Plugin\DataType\XeroComplexItemBase;
use Drupal\xero\Plugin\DataType\XeroItemBase;
use Drupal\xero\Plugin\DataType\XeroItemList;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
/**
* Implements normalization of Xero data types wrapped in XeroListitem.
*
* Drupal's ListNormalizer is explicitly for field data and does not pass in
* the plugin identifier as the context.
*/
class XeroListNormalizer extends TypedDataNormalizer implements NormalizerInterface {
/**
* Old-style check for interface or class support.
*
* @var string
*/
protected $supportedInterfaceOrClass = 'Drupal\xero\Plugin\DataType\XeroItemList';
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, ?string $format = NULL, array $context = []): bool {
return $data instanceof XeroItemList;
}
/**
* {@inheritdoc}
*/
public function getSupportedTypes(?string $format): array {
return [
ItemList::class => FALSE,
XeroItemList::class => TRUE,
XeroComplexItemBase::class => TRUE,
XeroItemBase::class => TRUE,
];
}
/**
* {@inheritdoc}
*/
public function normalize($object, $format = NULL, array $context = []): \ArrayObject|array|string|int|float|bool|null {
$items = [];
// Derive the Xero type from the item list item definition.
$item_class = $object->getItemDefinition()->getClass();
if (in_array('Drupal\xero\TypedData\XeroItemInterface', class_implements($item_class))) {
$plural_name = $item_class::getXeroProperty('plural_name');
$name = $item_class::getXeroProperty('xero_name');
}
else {
throw new \InvalidArgumentException('Invalid xero type used in object.');
}
/** @var \Drupal\xero\TypedData\XeroItemInterface $item */
foreach ($object as $n => $item) {
$plugin_id = $item->getDataDefinition()->getDataType();
$normalizedItem = $this->serializer->normalize($item, $format, ['plugin_id' => $plugin_id]);
$items[] = $normalizedItem;
}
$item_count = count($items);
$top = $context['top'] ?? TRUE;
// JSON serialization expects an array of objects without extra nesting
// unless it's the top element.
if ($top) {
if ($item_count === 1) {
$ret = $items[0];
}
else {
$ret = [$plural_name => $items];
}
}
else {
$ret = $items;
}
return $ret;
}
/**
* Remove null values from normalized items.
*
* @param mixed $value
* The value to reduce.
*
* @return mixed
* Either FALSE or the value.
*/
protected function reduceEmpty($value) {
if (is_array($value)) {
foreach ($value as $n => $item) {
$item = $this->reduceEmpty($item);
if ($item) {
$value[$n] = $item;
}
else {
unset($value[$n]);
}
}
}
elseif (empty($value)) {
return FALSE;
}
return $value;
}
}
