From a1161a6f90bb26a023133ca755319f6da6b0c27a Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Wed, 26 Feb 2025 15:52:53 +0100 Subject: [PATCH 1/7] Issue #3509161 by eduardo morales alberti: Do not delete rows on translation add --- src/Repository.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Repository.php b/src/Repository.php index 78b7c66..8969a33 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -251,12 +251,15 @@ class Repository implements RepositoryInterface { */ public function deleteSource(SourceInterface $source): bool { try { - $this->database + $query = $this->database ->delete(self::ENTITY_MESH_TABLE) ->condition('type', $source->getType()) ->condition('source_entity_type', $source->getSourceEntityType()) - ->condition('source_entity_id', $source->getSourceEntityId()) - ->execute(); + ->condition('source_entity_id', $source->getSourceEntityId()); + if (!empty($source->getSourceEntityLangcode())) { + $query->condition('source_entity_langcode', $source->getSourceEntityLangcode()); + } + $query->execute(); } catch (\Exception $e) { $this->logger->error($e->getMessage()); -- GitLab From 88bb261f80a876e97a6b1720cac104f1f8aa203c Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 12:17:32 +0100 Subject: [PATCH 2/7] Issue #3509161 by eduardo morales alberti: Use the right entity id --- entity_mesh.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entity_mesh.module b/entity_mesh.module index 6497455..372d667 100644 --- a/entity_mesh.module +++ b/entity_mesh.module @@ -90,7 +90,7 @@ function entity_mesh_process_entity(EntityInterface $entity, $operation) { return; } $entity_mesh = \Drupal::service($service); - $entity_mesh->deleteItem($entity->getEntityTypeId(), $entity->getEntityTypeId()); + $entity_mesh->deleteItem($entity->getEntityTypeId(), $entity->id()); } } -- GitLab From a301124df0b518c06ba83ac8c2141e5d05328f80 Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 12:50:06 +0100 Subject: [PATCH 3/7] Issue #3509161 by eduardo morales alberti: Detect links with access denied --- src/Entity.php | 8 ++++---- src/EntityRender.php | 9 +++++---- src/Plugin/views/filter/BaseSelectFilter.php | 6 +++++- src/Repository.php | 9 +++++---- tests/src/Kernel/EntityMeshEntityRenderTest.php | 5 +++-- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Entity.php b/src/Entity.php index fd9c065..f4451e9 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -86,15 +86,15 @@ abstract class Entity { /** * Process a translatable Entity. * - * @param \Drupal\Core\Entity\EntityInterface $entity + * @param \Drupal\Core\Entity\TranslatableInterface $entity * The entity to process. */ - protected function processTranslatableEntity(EntityInterface $entity) { - // @phpstan-ignore-next-line + protected function processTranslatableEntity(TranslatableInterface $entity) { + $translations = $entity->getTranslationLanguages(); $langcodes = array_keys($translations); foreach ($langcodes as $langcode) { - // @phpstan-ignore-next-line + $translation = $entity->getTranslation($langcode); if ($translation instanceof EntityInterface) { $this->processEntityItem($translation); diff --git a/src/EntityRender.php b/src/EntityRender.php index 2d08ec4..d6b2f34 100644 --- a/src/EntityRender.php +++ b/src/EntityRender.php @@ -8,6 +8,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Database\StatementInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Render\RendererInterface; @@ -80,7 +81,7 @@ class EntityRender extends Entity { LanguageNegotiatorSwitcher $language_negotiator_switcher, ModuleHandlerInterface $module_handler, ) { - parent::__construct($entity_mesh_repository, $entity_type_manager, $language_manager, $config_factory, $module_handler); + parent::__construct($entity_mesh_repository, $entity_type_manager, $language_manager, $config_factory); $this->renderer = $renderer; $this->accountSwitcher = $account_switcher; $this->type = 'entity_render'; @@ -201,7 +202,6 @@ class EntityRender extends Entity { $pre_render = $view_builder->view($entity, $view_mode, $langcode); - /** @var \Drupal\Core\Render\RendererInterface $renderer */ $render_output = DeprecationHelper::backwardsCompatibleCall( currentVersion: \Drupal::VERSION, deprecatedVersion: '10.3', @@ -279,8 +279,9 @@ class EntityRender extends Entity { */ protected function processInternalHref(TargetInterface $target) { - $alias = $this->entityMeshRepository->getPathWithoutLangPrefix($target->getPath()); - $target->setEntityLangcode($this->entityMeshRepository->getLangcodeFromPath($target->getPath())); + $path = (string) $target->getPath(); + $alias = $this->entityMeshRepository->getPathWithoutLangPrefix($path); + $target->setEntityLangcode($this->entityMeshRepository->getLangcodeFromPath($path)); $found_data = $this->setDataIfRedirection($alias, $target); diff --git a/src/Plugin/views/filter/BaseSelectFilter.php b/src/Plugin/views/filter/BaseSelectFilter.php index f73fa56..e368e3c 100644 --- a/src/Plugin/views/filter/BaseSelectFilter.php +++ b/src/Plugin/views/filter/BaseSelectFilter.php @@ -11,7 +11,11 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ abstract class BaseSelectFilter extends InOperator implements ContainerFactoryPluginInterface { - // phpcs:ignore + /** + * Value form type. + * + * @var string + */ protected $valueFormType = 'select'; /** diff --git a/src/Repository.php b/src/Repository.php index 8969a33..ce0e6a3 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\StreamWrapper\AssetsStream; use Drupal\file\FileInterface; use Drupal\media\MediaInterface; +use Drupal\redirect\Entity\Redirect; use Drupal\redirect\Exception\RedirectLoopException; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -159,6 +160,7 @@ class Repository implements RepositoryInterface { $this->logger->error($e->getMessage()); return FALSE; } + return TRUE; } @@ -417,7 +419,6 @@ class Repository implements RepositoryInterface { $redirect_repository = $container->get($service_redirect); try { - /** @var \Drupal\redirect\Entity\Redirect $redirect_object */ if (!empty($langcode)) { $redirect_object = $redirect_repository->findMatchingRedirect($path, [], $langcode); } @@ -430,7 +431,7 @@ class Repository implements RepositoryInterface { $this->logger->error($e->getMessage()); return NULL; } - if ($redirect_object === NULL) { + if (!($redirect_object instanceof Redirect)) { return NULL; } @@ -464,7 +465,7 @@ class Repository implements RepositoryInterface { public function handlePrefixFromRedirection($uri, $langcode = '') { $prefixes = ['internal:', 'entity:', $langcode]; foreach ($prefixes as $prefix) { - $uri = preg_replace('/^' . $prefix . '/', '', $uri); + $uri = (string) preg_replace('/^' . $prefix . '/', '', $uri); $uri = trim($uri, '/'); } return $uri; @@ -479,7 +480,7 @@ class Repository implements RepositoryInterface { return $path; } $path = ltrim($path, '/'); - return str_replace($prefix, '', $path ?? ''); + return str_replace($prefix, '', $path); } /** diff --git a/tests/src/Kernel/EntityMeshEntityRenderTest.php b/tests/src/Kernel/EntityMeshEntityRenderTest.php index 2a2e0c3..65cd535 100644 --- a/tests/src/Kernel/EntityMeshEntityRenderTest.php +++ b/tests/src/Kernel/EntityMeshEntityRenderTest.php @@ -21,7 +21,7 @@ class EntityMeshEntityRenderTest extends KernelTestBase { /** * Modules to enable. * - * @var array + * @var array<string> */ protected static $modules = [ 'system', @@ -263,7 +263,8 @@ class EntityMeshEntityRenderTest extends KernelTestBase { 'target_title', 'target_entity_langcode', ]); - return $query->execute()->fetchAllAssoc('id', \PDO::FETCH_ASSOC); + $result = $query->execute(); + return $result ? $result->fetchAllAssoc('id', \PDO::FETCH_ASSOC): []; } /** -- GitLab From e1bb168fe0f96e5befe02e1b543f79c9083b0d1e Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 12:53:53 +0100 Subject: [PATCH 4/7] Issue #3509161 by eduardo morales alberti: Detect links with access denied --- tests/src/Kernel/EntityMeshEntityRenderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Kernel/EntityMeshEntityRenderTest.php b/tests/src/Kernel/EntityMeshEntityRenderTest.php index 65cd535..6bb7d35 100644 --- a/tests/src/Kernel/EntityMeshEntityRenderTest.php +++ b/tests/src/Kernel/EntityMeshEntityRenderTest.php @@ -264,7 +264,7 @@ class EntityMeshEntityRenderTest extends KernelTestBase { 'target_entity_langcode', ]); $result = $query->execute(); - return $result ? $result->fetchAllAssoc('id', \PDO::FETCH_ASSOC): []; + return $result ? $result->fetchAllAssoc('id', \PDO::FETCH_ASSOC) : []; } /** -- GitLab From c537391012e33f603a786a1522dd474d54c2948d Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 12:55:10 +0100 Subject: [PATCH 5/7] Issue #3509161 by eduardo morales alberti: Detect links with access denied --- src/Repository.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Repository.php b/src/Repository.php index ce0e6a3..6d3592f 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -253,15 +253,12 @@ class Repository implements RepositoryInterface { */ public function deleteSource(SourceInterface $source): bool { try { - $query = $this->database + $this->database ->delete(self::ENTITY_MESH_TABLE) ->condition('type', $source->getType()) ->condition('source_entity_type', $source->getSourceEntityType()) - ->condition('source_entity_id', $source->getSourceEntityId()); - if (!empty($source->getSourceEntityLangcode())) { - $query->condition('source_entity_langcode', $source->getSourceEntityLangcode()); - } - $query->execute(); + ->condition('source_entity_id', $source->getSourceEntityId()) + ->execute(); } catch (\Exception $e) { $this->logger->error($e->getMessage()); @@ -309,10 +306,6 @@ class Repository implements RepositoryInterface { * {@inheritdoc} */ public function saveSource(SourceInterface $source): bool { - // Remove source rows from the database to avoid duplicates. - if (!$this->deleteSource($source)) { - return FALSE; - } if (!$this->insertSource($source)) { return FALSE; } -- GitLab From 5fc09e8295574f80d3fbf9f60ff6fbfc3f910c77 Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 14:25:49 +0100 Subject: [PATCH 6/7] Issue #3509161 by eduardo morales alberti: Detect links with access denied --- src/EntityRender.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EntityRender.php b/src/EntityRender.php index d6b2f34..4c30712 100644 --- a/src/EntityRender.php +++ b/src/EntityRender.php @@ -8,7 +8,6 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Database\StatementInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Render\RendererInterface; -- GitLab From 74d67af85acef08e5dead6ded7b8445f72772fbb Mon Sep 17 00:00:00 2001 From: Eduardo Morales <eduardo.morales@metadrop.net> Date: Thu, 27 Feb 2025 14:30:07 +0100 Subject: [PATCH 7/7] Issue #3509161 by eduardo morales alberti: Do not delete rows on translation add --- src/Entity.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Entity.php b/src/Entity.php index f4451e9..217c85e 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -75,6 +75,13 @@ abstract class Entity { * The entity to process. */ public function processEntity(EntityInterface $entity) { + // Delete source before process entities. + $source = $this->createSourceFromEntity($entity); + if (!$source instanceof SourceInterface) { + return; + } + $this->entityMeshRepository->deleteSource($source); + // Check if entity is translatable. if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) { $this->processTranslatableEntity($entity); -- GitLab