ResourceTypeRepository.php in JSON:API 8
File
src/ResourceType/ResourceTypeRepository.php
View source
<?php
namespace Drupal\jsonapi\ResourceType;
use Drupal\Core\Entity\ContentEntityNullStorage;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\TypedData\DataReferenceTargetDefinition;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
class ResourceTypeRepository implements ResourceTypeRepositoryInterface {
protected $entityTypeManager;
protected $entityTypeBundleInfo;
protected $entityFieldManager;
protected $all = [];
const RESOURCE_TYPE_CLASS = ResourceType::class;
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_bundle_info, EntityFieldManagerInterface $entity_field_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfo = $entity_bundle_info;
$this->entityFieldManager = $entity_field_manager;
}
public function clearCachedDefinitions() {
$this->all = [];
}
public function all() {
if (!$this->all) {
$entity_type_ids = array_keys($this->entityTypeManager
->getDefinitions());
foreach ($entity_type_ids as $entity_type_id) {
$resource_type_class = static::RESOURCE_TYPE_CLASS;
$this->all = array_merge($this->all, array_map(function ($bundle) use ($entity_type_id, $resource_type_class) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
return new $resource_type_class($entity_type_id, $bundle, $entity_type
->getClass(), static::shouldBeInternalResourceType($entity_type), static::isLocatableResourceType($entity_type));
}, array_keys($this->entityTypeBundleInfo
->getBundleInfo($entity_type_id))));
}
foreach ($this->all as $resource_type) {
$relatable_resource_types = $this
->calculateRelatableResourceTypes($resource_type);
$resource_type
->setRelatableResourceTypes($relatable_resource_types);
}
}
return $this->all;
}
public function get($entity_type_id, $bundle) {
if (empty($entity_type_id)) {
throw new PreconditionFailedHttpException('Server error. The current route is malformed.');
}
foreach ($this
->all() as $resource) {
if ($resource
->getEntityTypeId() == $entity_type_id && $resource
->getBundle() == $bundle) {
return $resource;
}
}
return NULL;
}
public function getByTypeName($type_name) {
foreach ($this
->all() as $resource) {
if ($resource
->getTypeName() == $type_name) {
return $resource;
}
}
return NULL;
}
protected static function shouldBeInternalResourceType(EntityTypeInterface $entity_type) {
if (method_exists(EntityTypeInterface::class, 'isInternal')) {
return $entity_type
->isInternal();
}
return $entity_type
->id() === 'content_moderation_state';
}
protected static function isLocatableResourceType(EntityTypeInterface $entity_type) {
return $entity_type
->getStorageClass() !== ContentEntityNullStorage::class;
}
protected function calculateRelatableResourceTypes(ResourceType $resource_type) {
$entity_type = $this->entityTypeManager
->getDefinition($resource_type
->getEntityTypeId());
if ($entity_type
->entityClassImplements(FieldableEntityInterface::class)) {
$field_definitions = $this->entityFieldManager
->getFieldDefinitions($resource_type
->getEntityTypeId(), $resource_type
->getBundle());
return array_map(function ($field_definition) {
return $this
->getRelatableResourceTypesFromFieldDefinition($field_definition);
}, array_filter($field_definitions, function ($field_definition) {
return $this
->isReferenceFieldDefinition($field_definition);
}));
}
return [];
}
protected function getRelatableResourceTypesFromFieldDefinition(FieldDefinitionInterface $field_definition) {
$item_definition = $field_definition
->getItemDefinition();
$entity_type_id = $item_definition
->getSetting('target_type');
$handler_settings = $item_definition
->getSetting('handler_settings');
$has_target_bundles = isset($handler_settings['target_bundles']) && !empty($handler_settings['target_bundles']);
$target_bundles = $has_target_bundles ? $handler_settings['target_bundles'] : $this
->getAllBundlesForEntityType($entity_type_id);
return array_map(function ($target_bundle) use ($entity_type_id) {
return $this
->get($entity_type_id, $target_bundle);
}, $target_bundles);
}
protected function isReferenceFieldDefinition(FieldDefinitionInterface $field_definition) {
$item_definition = $field_definition
->getItemDefinition();
$main_property = $item_definition
->getMainPropertyName();
$property_definition = $item_definition
->getPropertyDefinition($main_property);
return $property_definition instanceof DataReferenceTargetDefinition;
}
protected function getAllBundlesForEntityType($entity_type_id) {
return array_keys($this->entityTypeBundleInfo
->getBundleInfo($entity_type_id));
}
}