sparql_entity_storage-8.x-1.0-alpha8/src/ParamConverter/SparqlEntityStorageConverter.php
src/ParamConverter/SparqlEntityStorageConverter.php
<?php
declare(strict_types=1);
namespace Drupal\sparql_entity_storage\ParamConverter;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\ParamConverter\EntityConverter;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\sparql_entity_storage\Entity\Query\Sparql\SparqlArg;
use Drupal\sparql_entity_storage\Event\ActiveGraphEvent;
use Drupal\sparql_entity_storage\Event\SparqlEntityStorageEvents;
use Drupal\sparql_entity_storage\SparqlEntityStorageInterface;
use Drupal\sparql_entity_storage\UriEncoder;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
/**
* Converts the escaped URI's in the path into valid URI's.
*
* @see \Drupal\sparql_entity_storage\RouteProcessor\SparqlEntityStorageRouteProcessor
* @see \Drupal\sparql_entity_storage\UrlEncoder
*/
class SparqlEntityStorageConverter extends EntityConverter {
/**
* The event dispatcher service.
*/
protected EventDispatcherInterface $eventDispatcher;
/**
* Constructs a new param converter service instance.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, EventDispatcherInterface $event_dispatcher) {
parent::__construct($entity_type_manager, $entity_repository);
$this->eventDispatcher = $event_dispatcher;
}
/**
* {@inheritdoc}
*/
public function applies($definition, $name, Route $route): bool {
if (!empty($definition['type']) && strpos($definition['type'], 'entity:') === 0) {
$entity_type_id = substr($definition['type'], strlen('entity:'));
// In case of dynamic types, we say we apply whenever the slug is present
// in the path of the route.
if (strpos($definition['type'], '{') !== FALSE) {
$entity_type_slug = substr($entity_type_id, 1, -1);
return $name != $entity_type_slug && in_array($entity_type_slug, $route->compile()->getVariables(), TRUE);
}
// This converter only applies SPARQL entities.
return $this->entityTypeManager->hasDefinition($entity_type_id) &&
$this->entityTypeManager->getStorage($entity_type_id) instanceof SparqlEntityStorageInterface;
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function convert($value, $definition, $name, array $defaults) {
$entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults);
if (!$this->entityTypeManager->hasDefinition($entity_type_id)) {
return NULL;
}
$storage = $this->entityTypeManager->getStorage($entity_type_id);
// In case of dynamic entity types, we cannot be sure about that the entity
// to be converted is a SparQL-stored object. But since we have to say that
// this converter applies to those routes in order to load SparQL-stored
// objects properly, in case of non-SparQL stored objects, we return what
// EntityConverter does.
if (!$storage instanceof SparqlEntityStorageInterface) {
return parent::convert($value, $definition, $name, $defaults);
}
// The parameter converter is not called only when trying to resolve an ID
// from the URL. When constructing a \Drupal\Core\Url from route with
// parameters given, calling the ::access method will attempt to also
// resolve the ID but the ID might be passed as decoded already.
if (!SparqlArg::isValidResource($value)) {
$value = UriEncoder::decodeUrl($value);
}
// If the URL still contains unsupported characters, then it should not be
// processed any further.
if (!empty(SparqlArg::getUnsupportedUriCharacters($value))) {
return NULL;
}
$event = new ActiveGraphEvent($name, $value, $entity_type_id, $definition, $defaults);
// Determine the graph by dispatching an event.
$event = $this->eventDispatcher->dispatch($event, SparqlEntityStorageEvents::GRAPH_ENTITY_CONVERT);
$entity = $storage->load($value, $event->getGraphs());
// If the entity type is translatable, ensure we return the proper
// translation object for the current context.
if ($entity instanceof EntityInterface && $entity instanceof TranslatableInterface) {
$entity = $this->entityRepository->getTranslationFromContext($entity, NULL, ['operation' => 'entity_upcast']);
}
if (
!empty($definition['bundle']) &&
$entity instanceof EntityInterface &&
!in_array($entity->bundle(), $definition['bundle'], TRUE)
) {
return NULL;
}
return $entity;
}
}
