diff --git a/jsonld.services.yml b/jsonld.services.yml index 39da23b..9f18315 100644 --- a/jsonld.services.yml +++ b/jsonld.services.yml @@ -17,10 +17,10 @@ services: class: Drupal\jsonld\Normalizer\FileEntityNormalizer tags: - { name: normalizer, priority: 20 } - arguments: ['@entity_type.manager', '@http_client', '@hal.link_manager', '@module_handler', '@file_system', '@config.factory'] + arguments: ['@entity_type.manager', '@http_client', '@hal.link_manager', '@module_handler', '@file_system', '@config.factory', '@language_manager', '@router.route_provider'] serializer.normalizer.entity.jsonld: class: Drupal\jsonld\Normalizer\ContentEntityNormalizer - arguments: ['@hal.link_manager', '@entity_type.manager', '@module_handler', '@config.factory'] + arguments: ['@hal.link_manager', '@entity_type.manager', '@module_handler', '@config.factory', '@language_manager', '@router.route_provider'] tags: - { name: normalizer, priority: 10 } serializer.encoder.jsonld: diff --git a/src/Normalizer/ContentEntityNormalizer.php b/src/Normalizer/ContentEntityNormalizer.php index 8b56bd7..49a899d 100644 --- a/src/Normalizer/ContentEntityNormalizer.php +++ b/src/Normalizer/ContentEntityNormalizer.php @@ -6,8 +6,12 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Routing\RouteProviderInterface; +use Drupal\Core\Url; use Drupal\hal\LinkManager\LinkManagerInterface; use Drupal\jsonld\Form\JsonLdSettingsForm; +use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; /** @@ -52,6 +56,20 @@ class ContentEntityNormalizer extends NormalizerBase { */ protected $config; + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * The route provider. + * + * @var \Drupal\Core\Routing\RouteProviderInterface + */ + protected $routeProvider; + /** * Constructs an ContentEntityNormalizer object. * @@ -63,16 +81,24 @@ class ContentEntityNormalizer extends NormalizerBase { * The module handler. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider + * The route provider. */ public function __construct(LinkManagerInterface $link_manager, EntityTypeManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, - ConfigFactoryInterface $config_factory) { + ConfigFactoryInterface $config_factory, + LanguageManagerInterface $language_manager, + RouteProviderInterface $route_provider) { $this->linkManager = $link_manager; $this->entityManager = $entity_manager; $this->moduleHandler = $module_handler; $this->config = $config_factory->get(JsonLdSettingsForm::CONFIG_NAME); + $this->languageManager = $language_manager; + $this->routeProvider = $route_provider; } /** @@ -261,6 +287,9 @@ public function denormalize($data, $class, $format = NULL, array $context = []) * * @return string * The entity URI. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + * When $entity->toUrl() fails. */ protected function getEntityUri(EntityInterface $entity) { @@ -272,7 +301,23 @@ protected function getEntityUri(EntityInterface $entity) { } return ""; } - $url = $entity->toUrl('canonical', ['absolute' => TRUE]); + + try { + $undefined = $this->languageManager->getLanguage('und'); + $entity_type = $entity->getEntityTypeId(); + + // This throws the RouteNotFoundException if the route doesn't exist. + $this->routeProvider->getRouteByName("rest.entity.$entity_type.GET"); + + $url = Url::fromRoute( + "rest.entity.$entity_type.GET", + [$entity_type => $entity->id()], + ['absolute' => TRUE, 'language' => $undefined] + ); + } + catch (RouteNotFoundException $e) { + $url = $entity->toUrl('canonical', ['absolute' => TRUE]); + } if (!$this->config->get(JsonLdSettingsForm::REMOVE_JSONLD_FORMAT)) { $url->setRouteParameter('_format', 'jsonld'); } diff --git a/src/Normalizer/FileEntityNormalizer.php b/src/Normalizer/FileEntityNormalizer.php index 01057b7..c40df1e 100644 --- a/src/Normalizer/FileEntityNormalizer.php +++ b/src/Normalizer/FileEntityNormalizer.php @@ -6,6 +6,8 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Routing\RouteProviderInterface; use Drupal\hal\LinkManager\LinkManagerInterface; use GuzzleHttp\ClientInterface; @@ -50,15 +52,21 @@ class FileEntityNormalizer extends ContentEntityNormalizer { * The file system handler. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider + * The route provider. */ public function __construct(EntityTypeManagerInterface $entity_manager, ClientInterface $http_client, LinkManagerInterface $link_manager, ModuleHandlerInterface $module_handler, FileSystemInterface $file_system, - ConfigFactoryInterface $config_factory) { + ConfigFactoryInterface $config_factory, + LanguageManagerInterface $language_manager, + RouteProviderInterface $route_provider) { - parent::__construct($link_manager, $entity_manager, $module_handler, $config_factory); + parent::__construct($link_manager, $entity_manager, $module_handler, $config_factory, $language_manager, $route_provider); $this->httpClient = $http_client; $this->fileSystem = $file_system; diff --git a/tests/src/Kernel/JsonldKernelTestBase.php b/tests/src/Kernel/JsonldKernelTestBase.php index 76673cc..3ad82b2 100644 --- a/tests/src/Kernel/JsonldKernelTestBase.php +++ b/tests/src/Kernel/JsonldKernelTestBase.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\jsonld\Kernel; use Drupal\Core\Cache\MemoryBackend; -use Drupal\Core\Entity\EntityInterface; use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -75,12 +74,29 @@ abstract class JsonldKernelTestBase extends KernelTestBase { */ protected $rdfMapping; + /** + * The Language manager for our tests. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * A route provider for our tests. + * + * @var \Drupal\Core\Routing\RouteProviderInterface + */ + protected $routeProvider; + /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); + $this->languageManager = \Drupal::service('language_manager'); + $this->routeProvider = \Drupal::service('router.route_provider'); + $this->installEntitySchema('user'); $this->installEntitySchema('entity_test'); @@ -170,7 +186,7 @@ protected function setUp() { // Set up the mock serializer. $normalizers = [ - new ContentEntityNormalizer($link_manager, $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory')), + new ContentEntityNormalizer($link_manager, $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), $this->languageManager, $this->routeProvider), new EntityReferenceItemNormalizer($link_manager, $chain_resolver, $jsonld_context_generator), new FieldItemNormalizer($jsonld_context_generator), new FieldNormalizer(), @@ -182,29 +198,6 @@ protected function setUp() { $this->serializer = new Serializer($normalizers, $encoders); } - /** - * Constructs the entity URI. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity. - * - * @return string - * The entity URI. - * - * @throws \Drupal\Core\Entity\EntityMalformedException - * The toUrl() call fails. - */ - protected function getEntityUri(EntityInterface $entity) { - - // Some entity types don't provide a canonical link template, at least call - // out to ->url(). - if ($entity->isNew() || !$entity->hasLinkTemplate('canonical')) { - return $entity->toUrl('canonical', []); - } - $url = $entity->toUrl('canonical', ['absolute' => TRUE]); - return $url->setRouteParameter('_format', 'jsonld')->toString(); - } - /** * Generate a test entity and the expected normalized array. * @@ -272,16 +265,20 @@ protected function generateTestEntity() { $entity = EntityTest::create($values); $entity->save(); + $id = "http://localhost/entity_test/" . $entity->id() . "?_format=jsonld"; + $target_id = "http://localhost/entity_test/" . $target_entity->id() . "?_format=jsonld"; + $user_id = "http://localhost/user/" . $target_user->id() . "?_format=jsonld"; + $expected = [ "@graph" => [ [ - "@id" => $this->getEntityUri($entity), + "@id" => $id, "@type" => [ 'http://schema.org/ImageObject', ], "http://purl.org/dc/terms/references" => [ [ - "@id" => $this->getEntityUri($target_entity), + "@id" => $target_id, ], ], "http://purl.org/dc/terms/description" => [ @@ -298,7 +295,7 @@ protected function generateTestEntity() { ], "http://schema.org/author" => [ [ - "@id" => $this->getEntityUri($target_user), + "@id" => $user_id, ], ], "http://schema.org/dateCreated" => [ @@ -309,11 +306,11 @@ protected function generateTestEntity() { ], ], [ - "@id" => $this->getEntityUri($target_user), + "@id" => $user_id, "@type" => "http://localhost/rest/type/user/user", ], [ - "@id" => $this->getEntityUri($target_entity), + "@id" => $target_id, "@type" => [ "http://schema.org/ImageObject", ],