/** * {@inheritdoc} */ public function getResource() { return $this->decorated->getResource(); }
/** * Get the (reference) field information for a single item. * * @param ResourceFieldInterface $resource_field * The resource field. * * @throws \Drupal\restful\Exception\BadRequestException * * @return array * An array containing the following keys: * - 'name': Drupal's internal field name. Ex: field_article_related * - 'type': Either a field or a property. * - 'entity_type': The entity type this field points to. Not populated if * the field is not a reference (for instance the destination field used * in the where clause). * - 'bundles': The allowed bundles for this field. Not populated if the * field is not a reference (for instance the destination field used in * the where clause). */ protected function getFieldsFromPublicNameItem(ResourceFieldInterface $resource_field) { $property = $resource_field->getProperty(); $resource = $resource_field->getResource(); $item = array('name' => $property, 'type' => ResourceFieldEntity::propertyIsField($property) ? RelationalFilterInterface::TYPE_FIELD : RelationalFilterInterface::TYPE_PROPERTY, 'entity_type' => NULL, 'bundles' => array()); $item['column'] = $item['type'] == RelationalFilterInterface::TYPE_FIELD ? $resource_field->getColumn() : NULL; $instance_id = sprintf('%s:%d.%d', $resource['name'], $resource['majorVersion'], $resource['minorVersion']); /* @var ResourceEntity $resource */ $resource = restful()->getResourceManager()->getPluginCopy($instance_id, Request::create('', array(), RequestInterface::METHOD_GET)); // Variables for the next iteration. $definitions = $resource->getFieldDefinitions(); $item['entity_type'] = $resource->getEntityType(); $item['bundles'] = $resource->getBundles(); return array($item, $definitions); }
/** * Embeds the final contents of a field. * * If the field is a relationship to another resource, it embeds the resource. * * @param ResourceFieldInterface $resource_field * The resource field being processed. If it is a related resource, this is * used to extract the contents of the resource. If not, it's used to * extract the simple value. * @param string $parent_id * ID in the parent resource where this is being embedded. * @param DataInterpreterInterface $interpreter * The context for the $resource_field. * @param array $parents * Tracks the parents of the field to construct the dot notation for the * field name. * @param string[] $parent_hashes * An array that holds the name of the parent cache hashes that lead to the * current data structure. * * @return array * The contents for the JSON API attribute or relationship. */ protected function embedField(ResourceFieldInterface $resource_field, $parent_id, DataInterpreterInterface $interpreter, array &$parents, array &$parent_hashes) { // If the field points to a resource that can be included, include it // right away. if (!$resource_field instanceof ResourceFieldResourceInterface) { return $resource_field->render($interpreter); } // Check if the resource needs to be included. If not then set 'full_view' // to false. $cardinality = $resource_field->getCardinality(); $output = array(); $public_field_name = $resource_field->getPublicName(); if (!($ids = $resource_field->compoundDocumentId($interpreter))) { return NULL; } $ids = $cardinality == 1 ? $ids = array($ids) : $ids; $resource_info = $resource_field->getResource(); $empty_value = array('#fields' => array(), '#embedded' => TRUE, '#resource_plugin' => sprintf('%s:%d.%d', $resource_info['name'], $resource_info['majorVersion'], $resource_info['minorVersion']), '#cache_placeholder' => array('parents' => array_merge($parents, array($public_field_name)), 'parent_hashes' => $parent_hashes)); $value = array_map(function ($id) use($empty_value) { return $empty_value + array('#resource_id' => $id); }, $ids); if ($this->needsIncluding($resource_field, $parents)) { $value = $resource_field->render($interpreter); if (empty($value) || !static::isIterable($value)) { return $value; } $new_parents = $parents; $new_parents[] = $public_field_name; $value = $this->extractFieldValues($value, $new_parents, $parent_hashes); $value = $cardinality == 1 ? array($value) : $value; } // At this point we are dealing with an embed. $value = array_filter($value); // Set the resource for the reference. $resource_plugin = $resource_field->getResourcePlugin(); foreach ($value as $value_item) { $id = $value_item['#resource_id']; $basic_info = array('type' => $resource_field->getResourceMachineName(), 'id' => (string) $id); // We want to be able to include only the images in articles.images, // but not articles.related.images. That's why we need the path // including the parents. $item = array('#resource_name' => $basic_info['type'], '#resource_plugin' => $resource_plugin->getPluginId(), '#resource_id' => $basic_info['id'], '#include_links' => array('self' => $resource_plugin->versionedUrl($basic_info['id'])), '#relationship_info' => array('type' => $basic_info['type'], 'id' => $basic_info['id'])) + $value_item; $output[] = $item; } // If there is a resource plugin for the parent, set the related // links. $links = array(); if ($resource = $this->getResource()) { $links['related'] = $resource->versionedUrl('', array('absolute' => TRUE, 'query' => array('filter' => array($public_field_name => reset($ids))))); $links['self'] = $resource_plugin->versionedUrl($parent_id . '/relationships/' . $public_field_name); } return $output + array('#embedded' => TRUE, '#cardinality' => $cardinality, '#relationship_links' => $links); }