/** * {@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; }