JsonBlueprintDenormalizer.php in Subrequests 8
File
src/Normalizer/JsonBlueprintDenormalizer.php
View source
<?php
namespace Drupal\subrequests\Normalizer;
use Drupal\subrequests\Blueprint\RequestTree;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Serializer;
class JsonBlueprintDenormalizer implements DenormalizerInterface, SerializerAwareInterface {
protected $serializer;
public function setSerializer(SerializerInterface $serializer) {
if (!is_a($serializer, Serializer::class)) {
throw new \ErrorException('Serializer is unable to normalize or denormalize.');
}
$this->serializer = $serializer;
}
public function denormalize($data, $class, $format = NULL, array $context = []) {
$requests = array_map(function ($item) use ($format, $context) {
return $this->serializer
->denormalize($item, Request::class, $format, $context);
}, $data);
$requests_per_parent = array_reduce($requests, function (array $carry, Request $request) {
$parent_id = $request->attributes
->get(RequestTree::SUBREQUEST_PARENT_ID, RequestTree::ROOT_TREE_ID);
if (empty($carry[$parent_id])) {
$carry[$parent_id] = [];
}
$carry[$parent_id][] = $request;
return $carry;
}, []);
$root_tree = new RequestTree($requests_per_parent[RequestTree::ROOT_TREE_ID]);
unset($requests_per_parent[RequestTree::ROOT_TREE_ID]);
foreach ($requests_per_parent as $parent_id => $children_requests) {
$parent_requests = array_filter($requests, function (Request $request) use ($parent_id) {
return $request->attributes
->get(RequestTree::SUBREQUEST_ID) == $parent_id;
});
$parent_request = reset($parent_requests);
$parent_request->attributes
->set(RequestTree::SUBREQUEST_TREE, new RequestTree($children_requests, $parent_id));
}
return $root_tree;
}
public function supportsDenormalization($data, $type, $format = NULL) {
return $format === 'json' && $type === RequestTree::class && is_array($data) && !static::arrayIsKeyed($data);
}
public static function arrayIsKeyed(array $input) {
$keys = array_keys($input);
if ($keys[0] !== 0) {
return TRUE;
}
$numeric_keys = array_filter($keys, 'is_numeric');
if (count($keys) != count($numeric_keys)) {
return TRUE;
}
for ($index = 1; $index < count($keys); $index++) {
if ($keys[$index] - $keys[$index - 1] !== 1) {
return TRUE;
}
}
return FALSE;
}
}