class JsonBlueprintDenormalizer in Subrequests 8
Same name and namespace in other branches
- 8.2 src/Normalizer/JsonBlueprintDenormalizer.php \Drupal\subrequests\Normalizer\JsonBlueprintDenormalizer
- 3.x src/Normalizer/JsonBlueprintDenormalizer.php \Drupal\subrequests\Normalizer\JsonBlueprintDenormalizer
Hierarchy
- class \Drupal\subrequests\Normalizer\JsonBlueprintDenormalizer implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface, \Symfony\Component\Serializer\SerializerAwareInterface
Expanded class hierarchy of JsonBlueprintDenormalizer
1 string reference to 'JsonBlueprintDenormalizer'
1 service uses JsonBlueprintDenormalizer
File
- src/
Normalizer/ JsonBlueprintDenormalizer.php, line 13
Namespace
Drupal\subrequests\NormalizerView source
class JsonBlueprintDenormalizer implements DenormalizerInterface, SerializerAwareInterface {
/**
* @var \Symfony\Component\Serializer\Serializer
*/
protected $serializer;
/**
* {@inheritdoc}
*/
public function setSerializer(SerializerInterface $serializer) {
if (!is_a($serializer, Serializer::class)) {
throw new \ErrorException('Serializer is unable to normalize or denormalize.');
}
$this->serializer = $serializer;
}
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = NULL, array $context = []) {
// The top level is an array of normalized requests.
$requests = array_map(function ($item) use ($format, $context) {
return $this->serializer
->denormalize($item, Request::class, $format, $context);
}, $data);
// We want to create one tree per parent, but for that we need to identify
// the parents first.
$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;
}, []);
// Now get all the requests for the root parent to create the root tree.
$root_tree = new RequestTree($requests_per_parent[RequestTree::ROOT_TREE_ID]);
unset($requests_per_parent[RequestTree::ROOT_TREE_ID]);
// Iterate through all the parents to find them in the tree. The attach the
// sub-tree to the root.
// TODO: If a tree hangs from a parent that is not attached to the root, then this process may fail.
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;
}
/**
* {@inheritdoc}
*/
public function supportsDenormalization($data, $type, $format = NULL) {
return $format === 'json' && $type === RequestTree::class && is_array($data) && !static::arrayIsKeyed($data);
}
/**
* Check if an array is keyed.
*
* @param array $input
* The input array to check.
*
* @return bool
* True if the array is keyed.
*/
public static function arrayIsKeyed(array $input) {
$keys = array_keys($input);
// If the array does not start at 0, it is not numeric.
if ($keys[0] !== 0) {
return TRUE;
}
// If there is a non-numeric key, the array is not numeric.
$numeric_keys = array_filter($keys, 'is_numeric');
if (count($keys) != count($numeric_keys)) {
return TRUE;
}
// If the keys are not following the natural numbers sequence, then it is
// not numeric.
for ($index = 1; $index < count($keys); $index++) {
if ($keys[$index] - $keys[$index - 1] !== 1) {
return TRUE;
}
}
return FALSE;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
JsonBlueprintDenormalizer:: |
protected | property | ||
JsonBlueprintDenormalizer:: |
public static | function | Check if an array is keyed. | |
JsonBlueprintDenormalizer:: |
public | function | Denormalizes data back into an object of the given class. | |
JsonBlueprintDenormalizer:: |
public | function | Sets the owning Serializer object. | |
JsonBlueprintDenormalizer:: |
public | function | Checks whether the given class is supported for denormalization by this normalizer. |