Issue #3216107 by amateescu, adriancid, alexpott, Fabianx: Workspace association data is not updated when an entity is deleted
parent
231e771847
commit
b13dae8bd0
|
@ -214,16 +214,31 @@ class WorkspaceAssociation implements WorkspaceAssociationInterface {
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function deleteAssociations($workspace_id, $entity_type_id = NULL, $entity_ids = NULL) {
|
public function deleteAssociations($workspace_id = NULL, $entity_type_id = NULL, $entity_ids = NULL, $revision_ids = NULL) {
|
||||||
$query = $this->database->delete(static::TABLE)
|
if (!$workspace_id && !$entity_type_id) {
|
||||||
->condition('workspace', $workspace_id);
|
throw new \InvalidArgumentException('A workspace ID or an entity type ID must be provided.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $this->database->delete(static::TABLE);
|
||||||
|
|
||||||
|
if ($workspace_id) {
|
||||||
|
$query->condition('workspace', $workspace_id);
|
||||||
|
}
|
||||||
|
|
||||||
if ($entity_type_id) {
|
if ($entity_type_id) {
|
||||||
|
if (!$entity_ids && !$revision_ids) {
|
||||||
|
throw new \InvalidArgumentException('A list of entity IDs or revision IDs must be provided for an entity type.');
|
||||||
|
}
|
||||||
|
|
||||||
$query->condition('target_entity_type_id', $entity_type_id, '=');
|
$query->condition('target_entity_type_id', $entity_type_id, '=');
|
||||||
|
|
||||||
if ($entity_ids) {
|
if ($entity_ids) {
|
||||||
$query->condition('target_entity_id', $entity_ids, 'IN');
|
$query->condition('target_entity_id', $entity_ids, 'IN');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($revision_ids) {
|
||||||
|
$query->condition('target_entity_revision_id', $revision_ids, 'IN');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$query->execute();
|
$query->execute();
|
||||||
|
|
|
@ -97,16 +97,22 @@ interface WorkspaceAssociationInterface {
|
||||||
/**
|
/**
|
||||||
* Deletes all the workspace association records for the given workspace.
|
* Deletes all the workspace association records for the given workspace.
|
||||||
*
|
*
|
||||||
* @param string $workspace_id
|
* @param string|null $workspace_id
|
||||||
* A workspace entity ID.
|
* (optional) A workspace entity ID. Defaults to NULL.
|
||||||
* @param string|null $entity_type_id
|
* @param string|null $entity_type_id
|
||||||
* (optional) The target entity type of the associations to delete. Defaults
|
* (optional) The target entity type of the associations to delete. Defaults
|
||||||
* to NULL.
|
* to NULL.
|
||||||
* @param int[]|string[]|null $entity_ids
|
* @param int[]|string[]|null $entity_ids
|
||||||
* (optional) The target entity IDs of the associations to delete. Defaults
|
* (optional) The target entity IDs of the associations to delete. Defaults
|
||||||
* to NULL.
|
* to NULL.
|
||||||
|
* @param int[]|string[]|null $revision_ids
|
||||||
|
* (optional) The target entity revision IDs of the associations to delete.
|
||||||
|
* Defaults to NULL.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* If neither $workspace_id nor $entity_type_id arguments were provided.
|
||||||
*/
|
*/
|
||||||
public function deleteAssociations($workspace_id, $entity_type_id = NULL, $entity_ids = NULL);
|
public function deleteAssociations($workspace_id = NULL, $entity_type_id = NULL, $entity_ids = NULL, $revision_ids = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a workspace with all the associations of its parent.
|
* Initializes a workspace with all the associations of its parent.
|
||||||
|
|
|
@ -367,6 +367,55 @@ class WorkspaceIntegrationTest extends KernelTestBase {
|
||||||
$this->assertEmpty($workspace_publisher->getDifferringRevisionIdsOnSource());
|
$this->assertEmpty($workspace_publisher->getDifferringRevisionIdsOnSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the workspace association data integrity for entity CRUD operations.
|
||||||
|
*
|
||||||
|
* @covers ::workspaces_entity_presave
|
||||||
|
* @covers ::workspaces_entity_insert
|
||||||
|
* @covers ::workspaces_entity_delete
|
||||||
|
* @covers ::workspaces_entity_revision_delete
|
||||||
|
*/
|
||||||
|
public function testWorkspaceAssociationDataIntegrity() {
|
||||||
|
$this->initializeWorkspacesModule();
|
||||||
|
|
||||||
|
// Check the initial empty state.
|
||||||
|
$expected_workspace_association = ['stage' => []];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
|
||||||
|
// Add a new unpublished node in 'stage' and check that new revision is
|
||||||
|
// tracked in the workspace association data.
|
||||||
|
$this->switchToWorkspace('stage');
|
||||||
|
$unpublished_node = $this->createNode(['title' => 'stage - 3 - r3 - unpublished', 'created' => $this->createdTimestamp++, 'status' => FALSE]);
|
||||||
|
$expected_workspace_association = ['stage' => [3]];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
|
||||||
|
// Add a new revision for the unpublished node.
|
||||||
|
$unpublished_node->title = 'stage - 3 - r4 - unpublished';
|
||||||
|
$unpublished_node->save();
|
||||||
|
$expected_workspace_association = ['stage' => [4]];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
|
||||||
|
// Delete the unpublished node and check that the association data has been
|
||||||
|
// updated.
|
||||||
|
$unpublished_node->delete();
|
||||||
|
$expected_workspace_association = ['stage' => []];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
|
||||||
|
// Add a new published node in 'stage' and check that new workspace-specific
|
||||||
|
// revision is tracked in the workspace association data. Note that revision
|
||||||
|
// '5' has been created as an unpublished default revision in Live, so it is
|
||||||
|
// not tracked.
|
||||||
|
$this->createNode(['title' => 'stage - 4 - r6 - published', 'created' => $this->createdTimestamp++, 'status' => TRUE]);
|
||||||
|
$expected_workspace_association = ['stage' => [6]];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
|
||||||
|
// Delete revision '6' and check that the workspace association does not
|
||||||
|
// track it anymore.
|
||||||
|
$this->entityTypeManager->getStorage('node')->deleteRevision(6);
|
||||||
|
$expected_workspace_association = ['stage' => []];
|
||||||
|
$this->assertWorkspaceAssociation($expected_workspace_association, 'node');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests entity tracking in workspace descendants.
|
* Tests entity tracking in workspace descendants.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -143,6 +143,26 @@ function workspaces_entity_predelete(EntityInterface $entity) {
|
||||||
->entityPredelete($entity);
|
->entityPredelete($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_entity_delete().
|
||||||
|
*/
|
||||||
|
function workspaces_entity_delete(EntityInterface $entity) {
|
||||||
|
if (\Drupal::service('workspaces.manager')->isEntityTypeSupported($entity->getEntityType())) {
|
||||||
|
\Drupal::service('workspaces.association')
|
||||||
|
->deleteAssociations(NULL, $entity->getEntityTypeId(), [$entity->id()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_entity_revision_delete().
|
||||||
|
*/
|
||||||
|
function workspaces_entity_revision_delete(EntityInterface $entity) {
|
||||||
|
if (\Drupal::service('workspaces.manager')->isEntityTypeSupported($entity->getEntityType())) {
|
||||||
|
\Drupal::service('workspaces.association')
|
||||||
|
->deleteAssociations(NULL, $entity->getEntityTypeId(), [$entity->id()], [$entity->getRevisionId()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_entity_access().
|
* Implements hook_entity_access().
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue