You are here

protected static function FormatterJsonApi::restructureItem in RESTful 7.2

Take a JSON API item and makes it hierarchical object, like simple JSON.

Parameters

array $item: The JSON API item.

array $included: The included pool of elements.

Return value

array The hierarchical object.

Throws

\Drupal\restful\Exception\BadRequestException

File

src/Plugin/formatter/FormatterJsonApi.php, line 659
Contains \Drupal\restful\Plugin\formatter\FormatterJsonApi.

Class

FormatterJsonApi
Class FormatterJsonApi @package Drupal\restful\Plugin\formatter

Namespace

Drupal\restful\Plugin\formatter

Code

protected static function restructureItem(array $item, array $included) {
  if (empty($item['meta']['subrequest']) && empty($item['attributes']) && empty($item['relationship'])) {
    throw new BadRequestException('Invalid JSON provided: both attributes and relationship are empty.');
  }

  // Make sure that the attributes and relationships are accessible.
  $element = empty($item['attributes']) ? array() : $item['attributes'];
  $relationships = empty($item['relationships']) ? array() : $item['relationships'];

  // For every relationship we need to see if it was included.
  foreach ($relationships as $field_name => $relationship) {
    if (empty($relationship['data'])) {
      throw new BadRequestException('Invalid JSON provided: relationship without data.');
    }
    $data = $relationship['data'];

    // It's always weird to deal with lists of items vs a single item.
    $single_item = !ResourceFieldBase::isArrayNumeric($data);

    // Make sure we're always dealing with a list of items.
    $data = $single_item ? array(
      $data,
    ) : $data;
    $element[$field_name] = array();
    foreach ($data as $info_pair) {

      // Validate the JSON API structure for a relationship.
      if (empty($info_pair['type'])) {
        throw new BadRequestException('Invalid JSON provided: relationship item without type.');
      }
      if (empty($info_pair['id'])) {
        throw new BadRequestException('Invalid JSON provided: relationship item without id.');
      }

      // Initialize the object if empty.
      if (!empty($info_pair['meta']['subrequest']) && ($included_item = static::retrieveIncludedItem($info_pair['type'], $info_pair['id'], $included))) {

        // If the relationship was included, restructure it and embed it.
        $value = array(
          'body' => static::restructureItem($included_item, $included),
          'id' => $info_pair['id'],
          'request' => $info_pair['meta']['subrequest'],
        );
        if (!empty($value['request']['method']) && $value['request']['method'] == RequestInterface::METHOD_POST) {

          // If the value is a POST remove the ID, since we already
          // retrieved the included item.
          unset($value['id']);
        }
        $element[$field_name][] = $value;
      }
      else {

        // If the include could not be retrieved, use the ID instead.
        $element[$field_name][] = array(
          'id' => $info_pair['id'],
        );
      }
    }

    // Make the single relationships to be a single item or a single ID.
    $element[$field_name] = $single_item ? reset($element[$field_name]) : $element[$field_name];
  }
  return $element;
}