/**
  * {@inheritdoc}
  */
 protected static function checkPropertyAccess(ResourceFieldInterface $resource_field, $op, DataInterpreterInterface $interpreter)
 {
     $term = $interpreter->getWrapper()->value();
     if ($resource_field->getProperty() == 'name' && empty($term->tid) && $op == 'edit') {
         return TRUE;
     }
     return parent::checkPropertyAccess($resource_field, $op, $interpreter);
 }
 /**
  * {@inheritdoc}
  */
 public function autoDiscovery()
 {
     if (method_exists($this->decorated, 'autoDiscovery')) {
         return $this->decorated->autoDiscovery();
     }
     return ResourceFieldBase::emptyDiscoveryInfo($this->getPublicName());
 }
 /**
  * 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);
 }
 /**
  * {@inheritdoc}
  */
 public function methodAccess(ResourceFieldInterface $resource_field)
 {
     return in_array($this->getRequest()->getMethod(), $resource_field->getMethods());
 }
 /**
  * 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);
 }