diff --git a/src/UriExtractor.php b/src/UriExtractor.php index a79903b..c439783 100644 --- a/src/UriExtractor.php +++ b/src/UriExtractor.php @@ -32,26 +32,27 @@ class UriExtractor { /** * Returns a URI to the file. * - * @param object|null $input + * @param Object|null $input * An object that contains the URI. * * @return string|null * A URI that may be used to access the file. */ public function extractUri(?object $input): ?string { - if ($input instanceof ContentEntityInterface) { - return self::getUriFromEntity($input); - } - elseif ($input instanceof EntityReferenceFieldItemListInterface) { - $item = $input->first(); - if (!empty($item) && $input->entity instanceof ContentEntityInterface) { - return $this->getUriFromEntity($item->entity); + $entity = $input; + if ($input instanceof EntityReferenceFieldItemListInterface) { + if ($item = $input->first()) { + $entity = $item->entity; } } - elseif ($input instanceof EntityReferenceItem && $input->entity instanceof ContentEntityInterface) { - return self::getUriFromEntity($input->entity); + elseif ($input instanceof EntityReferenceItem) { + $entity = $input->entity; } - return NULL; + // Drupal does not clean up references to deleted entities. So that the + // entity property might be empty while the field item might not. + // @see https://www.drupal.org/project/drupal/issues/2723323 + return $entity instanceof ContentEntityInterface ? + $this->getUriFromEntity($entity) : NULL; } /** @@ -61,7 +62,7 @@ class UriExtractor { * Entity object that contains information about the file. * * @return string|null - * A URI that may be used to access the file. + * A URI that can be used to access the file. */ private function getUriFromEntity(ContentEntityInterface $entity): ?string { if ($entity instanceof MediaInterface) { diff --git a/src/UrlExtractor.php b/src/UrlExtractor.php index 6f89617..fee6727 100644 --- a/src/UrlExtractor.php +++ b/src/UrlExtractor.php @@ -47,25 +47,27 @@ class UrlExtractor { $url = file_create_url($input); return $relative ? file_url_transform_relative($url) : $url; } - elseif ($input instanceof ContentEntityInterface) { - return $this->getUrlFromEntity($input, $relative); - } - elseif ($input instanceof EntityReferenceFieldItemListInterface) { - $item = $input->first(); - if (!empty($item) && $input->entity instanceof ContentEntityInterface) { - return $this->getUrlFromEntity($item->entity, $relative); - } - } - elseif ($input instanceof EntityReferenceItem && $input->entity instanceof ContentEntityInterface) { - return $this->getUrlFromEntity($input->entity, $relative); - } elseif ($input instanceof LinkItemInterface) { return $input->getUrl()->toString(); } elseif ($input instanceof FieldItemList && $input->first() instanceof LinkItemInterface) { return $input->first()->getUrl()->toString(); } - return NULL; + + $entity = $input; + if ($input instanceof EntityReferenceFieldItemListInterface) { + if ($item = $input->first()) { + $entity = $item->entity; + } + } + elseif ($input instanceof EntityReferenceItem) { + $entity = $input->entity; + } + // Drupal does not clean up references to deleted entities. So that the + // entity property might be empty while the field item might not. + // @see https://www.drupal.org/project/drupal/issues/2723323 + return $entity instanceof ContentEntityInterface ? + $this->getUrlFromEntity($entity, $relative) : NULL; } /** diff --git a/tests/src/Kernel/UriExtractorTest.php b/tests/src/Kernel/UriExtractorTest.php index 1ac3730..4dc8314 100644 --- a/tests/src/Kernel/UriExtractorTest.php +++ b/tests/src/Kernel/UriExtractorTest.php @@ -12,7 +12,7 @@ final class UriExtractorTest extends AbstractExtractorTestCase { /** * Test callback. */ - public function testUrlExtractor(): void { + public function testUriExtractor(): void { $extractor = $this->container->get('twig_tweak.uri_extractor');