/**
  * 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);
 }
 /**
  * Get value from a field rendered by Drupal field API's formatter.
  *
  * @param \EntityMetadataWrapper $property_wrapper
  *   The property wrapper. Either \EntityDrupalWrapper or \EntityListWrapper.
  * @param \EntityDrupalWrapper $wrapper
  *   The entity wrapper.
  *
  * @return mixed
  *   A single or multiple values.
  *
  * @throws \Drupal\restful\Exception\ServerConfigurationException
  */
 protected function formatterValue(\EntityMetadataWrapper $property_wrapper, \EntityDrupalWrapper $wrapper)
 {
     $value = NULL;
     if (!ResourceFieldEntity::propertyIsField($this->getProperty())) {
         // Property is not a field.
         throw new ServerConfigurationException(format_string('@property is not a configurable field, so it cannot be processed using field API formatter', array('@property' => $this->getProperty())));
     }
     // Get values from the formatter.
     $output = field_view_field($this->getEntityType(), $wrapper->value(), $this->getProperty(), $this->getFormatter());
     // Unset the theme, as we just want to get the value from the formatter,
     // without the wrapping HTML.
     unset($output['#theme']);
     if ($property_wrapper instanceof \EntityListWrapper) {
         // Multiple values.
         foreach (element_children($output) as $delta) {
             $value[] = drupal_render($output[$delta]);
         }
     } else {
         // Single value.
         $value = drupal_render($output);
     }
     return $value;
 }
 /**
  * {@inheritdoc}
  */
 public function value(DataInterpreterInterface $interpreter)
 {
     $value = $this->decorated->value($interpreter);
     if (isset($value)) {
         // Let the decorated resolve callbacks.
         return $value;
     }
     // Check user has access to the property.
     if (!$this->access('view', $interpreter)) {
         return NULL;
     }
     $resource = $this->getResource();
     // If the field definition does not contain a resource, or it is set
     // explicitly to fullView FALSE, then return only the entity ID.
     if ($resource || !empty($resource) && $resource['fullView'] !== FALSE || $this->getFormatter()) {
         // Let the resource embedding to the parent class.
         return parent::value($interpreter);
     }
     // Since this is a reference field (a field that points to other entities,
     // we can know for sure that the property wrappers are instances of
     // \EntityDrupalWrapper or lists of them.
     $property_wrapper = $this->propertyWrapper($interpreter);
     if (!$property_wrapper->value()) {
         // If there is no referenced entity, return.
         return NULL;
     }
     // If this is a multivalue field, then call recursively on the items.
     if ($property_wrapper instanceof \EntityListWrapper) {
         $values = array();
         foreach ($property_wrapper->getIterator() as $item_wrapper) {
             $values[] = $this->referencedId($item_wrapper);
         }
         return $values;
     }
     /* @var $property_wrapper \EntityDrupalWrapper */
     return $this->referencedId($property_wrapper);
 }
 /**
  * Get the public fields with the default values applied to them.
  *
  * @param array $field_definitions
  *   The field definitions to process.
  *
  * @throws \Drupal\restful\Exception\ServerConfigurationException
  *   For resources without ID field.
  *
  * @return array
  *   The field definition array.
  */
 protected function processPublicFields(array $field_definitions)
 {
     // The fields that only contain a property need to be set to be
     // ResourceFieldEntity. Otherwise they will be considered regular
     // ResourceField.
     return array_map(function ($field_definition) {
         $field_entity_class = '\\Drupal\\restful\\Plugin\\resource\\Field\\ResourceFieldEntity';
         $class_name = ResourceFieldEntity::fieldClassName($field_definition);
         if (!$class_name || is_subclass_of($class_name, $field_entity_class)) {
             $class_name = $field_entity_class;
         }
         return $field_definition + array('class' => $class_name, 'entityType' => $this->getEntityType());
     }, $field_definitions);
 }