/**
  * {@inheritdoc}
  */
 public function preprocess($value)
 {
     if (!$value) {
         // If value is empty, return NULL, so no new entity will be created.
         return NULL;
     }
     $cardinality = $this->getCardinality();
     if ($cardinality != 1 && !is_array($value)) {
         // If the field is entity reference type and its cardinality larger than
         // 1 set value to an array.
         $value = explode(',', $value);
     }
     if ($cardinality != 1 && ResourceFieldBase::isArrayNumeric($value)) {
         // Set the cardinality to 1 to process each value as a single value item.
         $this->setCardinality(1);
         // For multiple value items, pre-process them separately.
         $values = array();
         foreach ($value as $item) {
             $values[] = $this->preprocess($item);
         }
         $this->setCardinality($cardinality);
         return $values;
     }
     // If the provided value is the ID to the referenced entity, then do not do
     // a sub-request.
     if (!is_array($value) || empty($value['body'])) {
         // Allow to pass an array with the ID instead of the ID directly.
         return !empty($value['id']) && array_keys($value) == array('id') ? $value['id'] : $value;
     }
     /* @var ResourceFieldCollectionInterface $merged_value */
     $merged_value = $this->mergeEntityFromReference($value);
     return $merged_value->getInterpreter()->getWrapper()->getIdentifier();
 }
 /**
  * Process callback, Remove Drupal specific items from the image array.
  *
  * @param array $value
  *   The image array.
  *
  * @return array
  *   A cleaned image array.
  */
 public function imageProcess($value)
 {
     if (ResourceFieldBase::isArrayNumeric($value)) {
         $output = array();
         foreach ($value as $item) {
             $output[] = $this->imageProcess($item);
         }
         return $output;
     }
     return array('id' => $value['fid'], 'self' => file_create_url($value['uri']), 'filemime' => $value['filemime'], 'filesize' => $value['filesize'], 'width' => $value['width'], 'height' => $value['height'], 'styles' => $value['image_styles']);
 }
 /**
  * Return the files ID from the multiple files array.
  *
  * Since by default Entity API does not allow to get the file ID, we extract
  * it ourself in this preprocess callback.
  *
  * @param array $value
  *   Array of files array as retrieved by the wrapper.
  *
  * @return int
  *   Array with file IDs.
  */
 public function getFilesId(array $value)
 {
     if (ResourceFieldBase::isArrayNumeric($value)) {
         $return = array();
         foreach ($value as $file_array) {
             $return[] = $this->getFilesId($file_array);
         }
         return $return;
     }
     return empty($value['fid']) ? NULL : $value['fid'];
 }
 /**
  * {@inheritdoc}
  */
 public function prepare(array $data)
 {
     // If we're returning an error then set the content type to
     // 'application/problem+json; charset=utf-8'.
     if (!empty($data['status']) && floor($data['status'] / 100) != 2) {
         $this->contentType = 'application/problem+json; charset=utf-8';
         return $data;
     }
     $extracted = $this->extractFieldValues($data);
     $output = $this->limitFields($extracted);
     // Force returning a single item.
     $output = ResourceFieldBase::isArrayNumeric($output) ? reset($output) : $output;
     return $output ?: array();
 }
 /**
  * {@inheritdoc}
  */
 public function autoDiscovery()
 {
     if (method_exists($this->decorated, 'autoDiscovery')) {
         return $this->decorated->autoDiscovery();
     }
     return ResourceFieldBase::emptyDiscoveryInfo($this->getPublicName());
 }
 /**
  * Returns only the allowed fields by filtering out the other ones.
  *
  * @param mixed $output
  *   The data structure to filter.
  * @param bool|string[] $allowed_fields
  *   FALSE to allow all fields. An array of allowed values otherwise.
  *
  * @return mixed
  *   The filtered output.
  */
 protected function limitFields($output, $allowed_fields = NULL)
 {
     if (!isset($allowed_fields)) {
         $request = ($resource = $this->getResource()) ? $resource->getRequest() : restful()->getRequest();
         $input = $request->getParsedInput();
         // Set the field limits to false if there are no limits.
         $allowed_fields = empty($input['fields']) ? FALSE : explode(',', $input['fields']);
     }
     if (!is_array($output)) {
         // $output is a simple value.
         return $output;
     }
     $result = array();
     if (ResourceFieldBase::isArrayNumeric($output)) {
         foreach ($output as $item) {
             $result[] = $this->limitFields($item, $allowed_fields);
         }
         return $result;
     }
     foreach ($output as $field_name => $field_contents) {
         if ($allowed_fields !== FALSE && !in_array($field_name, $allowed_fields)) {
             continue;
         }
         $result[$field_name] = $this->limitFields($field_contents, $this->unprefixInputOptions($allowed_fields, $field_name));
     }
     return $result;
 }
 /**
  * Helper method to determine if an array is numeric.
  *
  * @param array $input
  *   The input array.
  *
  * @return bool
  *   TRUE if the array is numeric, false otherwise.
  */
 public static function isArrayNumeric(array $input)
 {
     return ResourceFieldBase::isArrayNumeric($input);
 }
 /**
  * Take a JSON API item and makes it hierarchical object, like simple JSON.
  *
  * @param array $item
  *   The JSON API item.
  * @param array $included
  *   The included pool of elements.
  *
  * @return array
  *   The hierarchical object.
  *
  * @throws \Drupal\restful\Exception\BadRequestException
  */
 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;
 }