Commit 55fbe8ac authored by catch's avatar catch
Browse files

Issue #3045177 by amateescu, darren oh, oily, krzysztof domański, catch,...

Issue #3045177 by amateescu, darren oh, oily, krzysztof domański, catch, manuel garcia, fabianx: Entity queries for latest revisions should return the latest workspace-specific revisions
parent 74bdd70d
Loading
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -53073,6 +53073,30 @@
	'count' => 1,
	'path' => __DIR__ . '/modules/workspaces/tests/src/Kernel/WorkspaceEntityDeleteTest.php',
];
$ignoreErrors[] = [
	'message' => '#^Method Drupal\\\\Tests\\\\workspaces\\\\Kernel\\\\WorkspaceEntityRepositoryTest\\:\\:assertWorkspaceAssociation\\(\\) has no return type specified\\.$#',
	'identifier' => 'missingType.return',
	'count' => 1,
	'path' => __DIR__ . '/modules/workspaces/tests/src/Kernel/WorkspaceEntityRepositoryTest.php',
];
$ignoreErrors[] = [
	'message' => '#^Method Drupal\\\\Tests\\\\workspaces\\\\Kernel\\\\WorkspaceEntityRepositoryTest\\:\\:createWorkspaceHierarchy\\(\\) has no return type specified\\.$#',
	'identifier' => 'missingType.return',
	'count' => 1,
	'path' => __DIR__ . '/modules/workspaces/tests/src/Kernel/WorkspaceEntityRepositoryTest.php',
];
$ignoreErrors[] = [
	'message' => '#^Method Drupal\\\\Tests\\\\workspaces\\\\Kernel\\\\WorkspaceEntityRepositoryTest\\:\\:initializeWorkspacesModule\\(\\) has no return type specified\\.$#',
	'identifier' => 'missingType.return',
	'count' => 1,
	'path' => __DIR__ . '/modules/workspaces/tests/src/Kernel/WorkspaceEntityRepositoryTest.php',
];
$ignoreErrors[] = [
	'message' => '#^Method Drupal\\\\Tests\\\\workspaces\\\\Kernel\\\\WorkspaceEntityRepositoryTest\\:\\:switchToWorkspace\\(\\) has no return type specified\\.$#',
	'identifier' => 'missingType.return',
	'count' => 1,
	'path' => __DIR__ . '/modules/workspaces/tests/src/Kernel/WorkspaceEntityRepositoryTest.php',
];
$ignoreErrors[] = [
	'message' => '#^Method Drupal\\\\Tests\\\\workspaces\\\\Kernel\\\\WorkspaceInformationTest\\:\\:assertWorkspaceAssociation\\(\\) has no return type specified\\.$#',
	'identifier' => 'missingType.return',
+2 −0
Original line number Diff line number Diff line
@@ -513,6 +513,8 @@ public function getLatestTranslationAffectedRevisionId($entity_id, $langcode) {
        ->range(0, 1)
        ->sort($this->entityType->getKey('revision'), 'DESC')
        ->accessCheck(FALSE)
        ->addMetaData('entity_id', $entity_id)
        ->addTag('latest_translated_affected_revision')
        ->execute();

      $this->latestRevisionIds[$entity_id][$langcode] = key($result);
+10 −2
Original line number Diff line number Diff line
@@ -57,11 +57,19 @@ public function __construct(EntityTypeInterface $entity_type, $conjunction, Conn
   * {@inheritdoc}
   */
  public function prepare() {
    // Latest revision queries have to return the latest workspace-specific
    // revisions, in order to prevent changes done outside the workspace from
    // leaking into the currently active one. For the same reason, latest
    // revision queries will return the default revision for entities that are
    // not tracked in the active workspace.
    if ($this->latestRevision && $this->workspaceInfo->isEntityTypeSupported($this->entityType) && $this->workspaceManager->hasActiveWorkspace()) {
      $this->allRevisions = FALSE;
      $this->latestRevision = FALSE;
    }

    parent::prepare();

    // Do not alter entity revision queries.
    // @todo How about queries for the latest revision? Should we alter them to
    //   look for the latest workspace-specific revision?
    if ($this->allRevisions) {
      return $this;
    }
+27 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Hook\Attribute\Hook;
@@ -255,6 +256,32 @@ public function entityRevisionDelete(EntityInterface $entity): void {
    }
  }

  /**
   * Implements hook_entity_query_tag__TAG_alter() for 'latest_translated_affected_revision'.
   */
  #[Hook('entity_query_tag__latest_translated_affected_revision_alter')]
  public function entityQueryTagLatestTranslatedAffectedRevisionAlter(QueryInterface $query): void {
    $entity_type = $this->entityTypeManager->getDefinition($query->getEntityTypeId());
    if (!$this->workspaceInfo->isEntityTypeSupported($entity_type) || !$this->workspaceManager->hasActiveWorkspace()) {
      return;
    }

    $active_workspace = $this->workspaceManager->getActiveWorkspace();
    $tracked_entities = $this->workspaceAssociation->getTrackedEntities($active_workspace->id());

    if (!isset($tracked_entities[$entity_type->id()])) {
      return;
    }

    if ($revision_id = array_search($query->getMetaData('entity_id'), $tracked_entities[$entity_type->id()])) {
      $query->condition($entity_type->getKey('revision'), $revision_id, '<=');
      $conditions = $query->orConditionGroup();
      $conditions->condition($entity_type->getRevisionMetadataKey('workspace'), $active_workspace->id());
      $conditions->condition($entity_type->getRevisionMetadataKey('revision_default'), TRUE);
      $query->condition($conditions);
    }
  }

  /**
   * Implements hook_form_alter().
   *
+5 −3
Original line number Diff line number Diff line
@@ -134,9 +134,11 @@ protected function doSwitchWorkspace($workspace) {
    $this->activeWorkspace = $workspace ?: FALSE;

    // Clear the static entity cache for the supported entity types.
    $cache_tags_to_invalidate = array_map(function ($entity_type_id) {
      return 'entity.memory_cache:' . $entity_type_id;
    }, array_keys($this->workspaceInfo->getSupportedEntityTypes()));
    $cache_tags_to_invalidate = [];
    foreach (array_keys($this->workspaceInfo->getSupportedEntityTypes()) as $entity_type_id) {
      $this->entityTypeManager->getStorage($entity_type_id)->resetCache();
      $cache_tags_to_invalidate[] = 'entity.memory_cache:' . $entity_type_id;
    }
    $this->entityMemoryCache->invalidateTags($cache_tags_to_invalidate);

    // Clear the static cache for path aliases. We can't inject the path alias
Loading