diff --git a/composer.json b/composer.json index a66b78db0c8c639d0dcf8c895024ac067a277eaf..9da1c71c8be6e9efd646717b7cc91cdde3938016 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "require": { "php": ">= 7.4", "ext-dom": "*", - "drupal/entity_usage": "^2" + "drupal/entity_usage": "^2.0-beta18" }, "require-dev": { "drupal/paragraphs": ">=1.0" diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a4b0751dfbe4269f0ff1dc046322e04c105f6adf..418fa2d1368bf1d70840f8e7e77be17cee27d938 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -50,16 +50,6 @@ parameters: count: 2 path: src/Plugin/EntityUsageUpdater/LinkIt.php - - - message: "#^PHPDoc tag @var for property Drupal\\\\entity_usage_updater\\\\Utility\\\\UrlHelper\\:\\:\\$inner with type Drupal\\\\entity_usage\\\\EntityUsageTrackBase is not subtype of native type Drupal\\\\entity_usage_updater\\\\Utility\\\\UrlHelperInner\\.$#" - count: 1 - path: src/Utility/UrlHelper.php - - - - message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" - count: 1 - path: src/Utility/UrlHelper.php - - message: "#^Call to an undefined method Drupal\\\\Core\\\\Entity\\\\EntityInterface\\:\\:set\\(\\)\\.$#" count: 1 diff --git a/src/Controller/LocalTaskUsageController.php b/src/Controller/LocalTaskUsageController.php index 6e5ffbdda1a6ab99ed967b46b382698dd973c33e..3f2991c7917569073cc18183002c46abb1e7dfe8 100644 --- a/src/Controller/LocalTaskUsageController.php +++ b/src/Controller/LocalTaskUsageController.php @@ -35,7 +35,7 @@ class LocalTaskUsageController extends BaseLocalTaskUsageController { /** * {@inheritdoc} */ - public function listUsageLocalTask(RouteMatchInterface $route_match) { + public function listUsageLocalTask(RouteMatchInterface $route_match): array { $entity = $this->getEntityFromRouteMatch($route_match); return $this->listUsagePage($entity->getEntityTypeId(), $entity->id()); } diff --git a/src/Form/LinkRemoverForm.php b/src/Form/LinkRemoverForm.php index 32416c6d2ba5be9ac93d4fb15caa86314a964de5..70294192614835f330db5297ff8631cca44038fd 100644 --- a/src/Form/LinkRemoverForm.php +++ b/src/Form/LinkRemoverForm.php @@ -15,9 +15,9 @@ use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\entity_usage\UrlToEntityInterface; use Drupal\entity_usage_updater\EntityUsageUpdater; use Drupal\entity_usage_updater\EntityUsageUpdaterInterface; -use Drupal\entity_usage_updater\Utility\UrlHelper; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -35,9 +35,9 @@ class LinkRemoverForm extends FormBase { /** * The URL helper. * - * @var \Drupal\entity_usage_updater\Utility\UrlHelper + * @var \Drupal\entity_usage\UrlToEntityInterface */ - protected UrlHelper $urlHelper; + protected UrlToEntityInterface $urlToEntity; /** * The entity type manager. @@ -64,7 +64,7 @@ class LinkRemoverForm extends FormBase { public static function create(ContainerInterface $container): static { $form = parent::create($container); $form->entityUsageUpdater = $container->get('entity_usage_updater.updater'); - $form->urlHelper = $container->get('class_resolver')->getInstanceFromDefinition(UrlHelper::class); + $form->urlToEntity = $container->get(UrlToEntityInterface::class); $form->entityTypeManager = $container->get('entity_type.manager'); if ($container->has('content_moderation.state_transition_validation')) { $form->contentModerationValidation = $container->get('content_moderation.state_transition_validation'); @@ -134,15 +134,15 @@ class LinkRemoverForm extends FormBase { if (empty($url)) { continue; } - $entity = $this->urlHelper->findEntityByUrlString($url); + $entity = $this->urlToEntity->findEntityIdByUrl($url); if (!$entity) { $urls_not_found[] = $url; continue; } - if (!isset($argument[$entity->getEntityTypeId()])) { - $argument[$entity->getEntityTypeId()] = []; + if (!isset($argument[$entity['type']])) { + $argument[$entity['type']] = []; } - $argument[$entity->getEntityTypeId()][] = $entity->id(); + $argument[$entity['type']][] = $entity['id']; } if (!empty($urls_not_found)) { diff --git a/src/LinkRemoverTrait.php b/src/LinkRemoverTrait.php index e56d541abbf092338e0d5dab25d5384b66106917..153617a3fa3373bb9d9ec898ca75d9bc43e602eb 100644 --- a/src/LinkRemoverTrait.php +++ b/src/LinkRemoverTrait.php @@ -4,8 +4,9 @@ namespace Drupal\entity_usage_updater; use Drupal\Component\Utility\Html; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\TypedData\Type\StringInterface; -use Drupal\entity_usage_updater\Utility\UrlHelper; +use Drupal\entity_usage\UrlToEntityInterface; trait LinkRemoverTrait { @@ -29,10 +30,12 @@ trait LinkRemoverTrait { * The target entity to remove references to. * @param \Drupal\Core\TypedData\Type\StringInterface $text * The string item to search within. - * @param \Drupal\entity_usage_updater\Utility\UrlHelper $url_helper - * A UrlHelper service object. + * @param \Drupal\entity_usage\UrlToEntityInterface $url_to_entity + * A UrlToEntity service object. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. */ - protected function removeLinks(EntityInterface $entity, StringInterface $text, UrlHelper $url_helper): void { + protected function removeLinks(EntityInterface $entity, StringInterface $text, UrlToEntityInterface $url_to_entity, EntityTypeManagerInterface $entity_type_manager): void { if (!trim($text->getValue())) { return; } @@ -45,7 +48,11 @@ trait LinkRemoverTrait { try { // Get the href value of the <a> element. $href = $element->getAttribute('href'); - $url_entity = $url_helper->findEntityByUrlString($href); + $url_entity = $url_to_entity->findEntityIdByUrl($href); + if ($url_entity === NULL) { + continue; + } + $url_entity = $entity_type_manager->getStorage($url_entity['type'])->load($url_entity['id']); // If using LinkIt and the uuids match remove the link. Sometimes // users hack the url causing the data-entity-uuid not match. If diff --git a/src/Plugin/EntityUsageUpdater/HtmlLink.php b/src/Plugin/EntityUsageUpdater/HtmlLink.php index 8523f3c5a3c353dadaf2df8967b711d0eb64dc52..06425e411a7690053334d4402ba216fc5fe8699b 100644 --- a/src/Plugin/EntityUsageUpdater/HtmlLink.php +++ b/src/Plugin/EntityUsageUpdater/HtmlLink.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Drupal\entity_usage_updater\Plugin\EntityUsageUpdater; use Drupal\Component\Utility\Html; -use Drupal\Component\Utility\UrlHelper as CoreUrlHelper; +use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldItemInterface; @@ -17,10 +17,10 @@ use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\Core\Url; +use Drupal\entity_usage\UrlToEntityInterface; use Drupal\entity_usage_updater\EntityUsageUpdaterException; use Drupal\entity_usage_updater\EntityUsageUpdaterPluginBase; use Drupal\entity_usage_updater\LinkRemoverTrait; -use Drupal\entity_usage_updater\Utility\UrlHelper; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -71,9 +71,9 @@ class HtmlLink extends EntityUsageUpdaterPluginBase implements ContainerFactoryP /** * The URL helper object. * - * @var \Drupal\entity_usage_updater\Utility\UrlHelper + * @var \Drupal\entity_usage\UrlToEntityInterface */ - protected UrlHelper $urlHelper; + protected UrlToEntityInterface $urlToEntity; /** * {@inheritdoc} @@ -84,7 +84,7 @@ class HtmlLink extends EntityUsageUpdaterPluginBase implements ContainerFactoryP $plugin->languageManager = $container->get('language_manager', ContainerInterface::NULL_ON_INVALID_REFERENCE); $plugin->languageNegotiator = $container->get('language_negotiator', ContainerInterface::NULL_ON_INVALID_REFERENCE); $plugin->logger = $container->get('logger.channel.entity_usage_updater'); - $plugin->urlHelper = $container->get('class_resolver')->getInstanceFromDefinition(UrlHelper::class); + $plugin->urlToEntity = $container->get(UrlToEntityInterface::class); $plugin->setStringTranslation($container->get('string_translation')); return $plugin; } @@ -144,11 +144,11 @@ class HtmlLink extends EntityUsageUpdaterPluginBase implements ContainerFactoryP public function remove(EntityInterface $old_target, FieldItemInterface $item): void { $value = $item->get('value'); assert($value instanceof StringInterface); - $this->removeLinks($old_target, $value, $this->urlHelper); + $this->removeLinks($old_target, $value, $this->urlToEntity, $this->entityTypeManager); if (isset($item->summary)) { $summary = $item->get('summary'); assert($summary instanceof StringInterface); - $this->removeLinks($old_target, $summary, $this->urlHelper); + $this->removeLinks($old_target, $summary, $this->urlToEntity, $this->entityTypeManager); } } @@ -189,11 +189,11 @@ class HtmlLink extends EntityUsageUpdaterPluginBase implements ContainerFactoryP } foreach ($hrefs as $language => $language_hrefs) { foreach ($language_hrefs as $href) { - $parts = CoreUrlHelper::parse($href); + $parts = UrlHelper::parse($href); $options = [ 'fragment' => $parts['fragment'], 'query' => $parts['query'], - 'absolute' => CoreUrlHelper::isExternal($href), + 'absolute' => UrlHelper::isExternal($href), ]; if ($this->configuration['convert_to_linkit'] ?? FALSE) { @@ -237,8 +237,9 @@ class HtmlLink extends EntityUsageUpdaterPluginBase implements ContainerFactoryP try { // Get the href value of the <a> element. $href = $element->getAttribute('href'); - $entity = $this->urlHelper->findEntityByUrlString($href); + $entity = $this->urlToEntity->findEntityIdByUrl($href); if ($entity) { + $entity = $this->entityTypeManager->getStorage($entity['type'])->load($entity['id']); if ($element->hasAttribute('data-entity-uuid')) { // Normally the Linkit plugin handles when a element has this // attribute, but sometimes users may change the HREF manually and diff --git a/src/Plugin/EntityUsageUpdater/LinkIt.php b/src/Plugin/EntityUsageUpdater/LinkIt.php index 500e9caaed18cd4144367b2048383c2ee5b5ae1f..7a4e94935de6636bfa7a37933617a29ea56d5508 100644 --- a/src/Plugin/EntityUsageUpdater/LinkIt.php +++ b/src/Plugin/EntityUsageUpdater/LinkIt.php @@ -9,9 +9,9 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\TypedData\Type\StringInterface; +use Drupal\entity_usage\UrlToEntityInterface; use Drupal\entity_usage_updater\EntityUsageUpdaterPluginBase; use Drupal\entity_usage_updater\LinkRemoverTrait; -use Drupal\entity_usage_updater\Utility\UrlHelper; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -36,9 +36,9 @@ class LinkIt extends EntityUsageUpdaterPluginBase implements ContainerFactoryPlu /** * The URL helper object. * - * @var \Drupal\entity_usage_updater\Utility\UrlHelper + * @var \Drupal\entity_usage\UrlToEntityInterface */ - protected UrlHelper $urlHelper; + protected UrlToEntityInterface $urlToEntity; /** * {@inheritdoc} @@ -46,7 +46,7 @@ class LinkIt extends EntityUsageUpdaterPluginBase implements ContainerFactoryPlu public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { $plugin = new static($configuration, $plugin_id, $plugin_definition); $plugin->entityTypeManager = $container->get('entity_type.manager'); - $plugin->urlHelper = $container->get('class_resolver')->getInstanceFromDefinition(UrlHelper::class); + $plugin->urlToEntity = $container->get(UrlToEntityInterface::class); return $plugin; } @@ -66,11 +66,11 @@ class LinkIt extends EntityUsageUpdaterPluginBase implements ContainerFactoryPlu public function remove(EntityInterface $old_target, FieldItemInterface $item): void { $value = $item->get('value'); assert($value instanceof StringInterface); - $this->removeLinks($old_target, $value, $this->urlHelper); + $this->removeLinks($old_target, $value, $this->urlToEntity, $this->entityTypeManager); if (isset($item->summary)) { $summary = $item->get('summary'); assert($summary instanceof StringInterface); - $this->removeLinks($old_target, $summary, $this->urlHelper); + $this->removeLinks($old_target, $summary, $this->urlToEntity, $this->entityTypeManager); } } diff --git a/src/Utility/UrlHelper.php b/src/Utility/UrlHelper.php deleted file mode 100644 index ea94e535ac7f42ce15d94e8af078f386c1c87787..0000000000000000000000000000000000000000 --- a/src/Utility/UrlHelper.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\entity_usage_updater\Utility; - -use Drupal\Core\Entity\EntityInterface; - -/** - * Provides a utility class for analyzing URLs. - */ -final class UrlHelper { - - /** - * The inner helper object. - * - * @var UrlHelperInner|\Drupal\entity_usage\EntityUsageTrackBase - */ - protected UrlHelperInner $inner; - - /** - * Creates the helper object. - */ - public function __construct() { - $this->inner = UrlHelperInner::create( - \Drupal::getContainer(), - [], - 'url_helper (not real plugin)', - [] - ); - } - - /** - * Try to retrieve an entity from an URL string. - * - * @param string $url - * A relative or absolute URL string. - * - * @return \Drupal\Core\Entity\EntityInterface|null - * The entity object that corresponds to the received URL, or NULL if no - * entity could be retrieved. - */ - public function findEntityByUrlString(string $url): ?EntityInterface { - return $this->inner->findEntityByUrlString($url); - } - -} diff --git a/src/Utility/UrlHelperInner.php b/src/Utility/UrlHelperInner.php deleted file mode 100644 index da6c3eb825da45d21b62f402243609db074cd40f..0000000000000000000000000000000000000000 --- a/src/Utility/UrlHelperInner.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\entity_usage_updater\Utility; - -use Drupal\Core\Field\FieldItemInterface; -use Drupal\entity_usage\EntityUsageTrackBase; - -/** - * Exposes Entity Usage logic for extracting entity details from a URL string. - * - * This is an ugly approach in that it extends EntityUsageTrackBase while it - * isn't an entity usage tracker. It should only be usd via UrlHelper which - * hides irrelevant public methods. Ideally this functionality could be - * factored out from the base class within Entity Usage itself. - * - * @internal - */ -final class UrlHelperInner extends EntityUsageTrackBase { - - /** - * This shouldn't be used. - */ - public function getTargetEntities(FieldItemInterface $item) { - throw new \LogicException("This isn't a real tracker."); - } - - /** - * Try to retrieve an entity from an URL string. - * - * @param string $url - * A relative or absolute URL string. - * - * @return \Drupal\Core\Entity\EntityInterface|null - * The entity object that corresponds to the received URL, or NULL if no - * entity could be retrieved. - */ - public function findEntityByUrlString($url) { - return parent::findEntityByUrlString($url); - } - -}