function WorkspaceAssociation::moveTrackedEntities
Moves tracked entities from one workspace to another.
Parameters
string $source_workspace_id: The ID of the source workspace.
string $target_workspace_id: The ID of the target workspace.
string|null $entity_type_id: (optional) The entity type ID to filter the move operation. If NULL, all entity types will be moved. Defaults to NULL.
int[]|string[]|null $entity_ids: (optional) An array of entity IDs to move. If NULL, all entities of the specified type (or all entities if no type specified) will be moved. Defaults to NULL.
Overrides WorkspaceAssociationInterface::moveTrackedEntities
File
-
core/
modules/ workspaces/ src/ WorkspaceAssociation.php, line 341
Class
- WorkspaceAssociation
- Provides a class for CRUD operations on workspace associations.
Namespace
Drupal\workspacesCode
public function moveTrackedEntities(string $source_workspace_id, string $target_workspace_id, ?string $entity_type_id = NULL, ?array $entity_ids = NULL) : void {
// Validate input parameters.
if ($source_workspace_id === $target_workspace_id) {
throw new \InvalidArgumentException('Source and target workspace IDs cannot be the same.');
}
if ($entity_type_id === NULL && $entity_ids !== NULL) {
throw new \InvalidArgumentException('Entity type ID must be provided when entity IDs are specified.');
}
// Validate that both workspaces are top-level, and don't have children.
$workspace_tree = $this->workspaceRepository
->loadTree();
if (!isset($workspace_tree[$source_workspace_id]) || !isset($workspace_tree[$target_workspace_id]) || $workspace_tree[$source_workspace_id]['depth'] !== 0 || $workspace_tree[$target_workspace_id]['depth'] !== 0 || !empty($workspace_tree[$source_workspace_id]['descendants']) || !empty($workspace_tree[$target_workspace_id]['descendants'])) {
throw new \DomainException('Both the source and target must be valid top-level workspaces.');
}
$transaction = $this->database
->startTransaction();
try {
// Update the workspace revision metadata field if needed.
$this->workspaceManager
->executeOutsideWorkspace(function () use ($source_workspace_id, $target_workspace_id, $entity_type_id, $entity_ids) {
// Gather a list of revision IDs that have to be moved.
if ($entity_type_id) {
$affected_revision_ids[$entity_type_id] = $this->getAssociatedRevisions($source_workspace_id, $entity_type_id, $entity_ids);
}
else {
$this->loadAssociatedRevisions($source_workspace_id);
$affected_revision_ids = $this->associatedRevisions[$source_workspace_id];
}
foreach ($affected_revision_ids as $entity_type_id => $entity_ids) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
// Move the revisions if they have the revision metadata field.
if ($field_name = $entity_type->getRevisionMetadataKey('workspace')) {
$affected_revisions = $this->entityTypeManager
->getStorage($entity_type_id)
->loadMultipleRevisions(array_keys($entity_ids));
foreach ($affected_revisions as $revision) {
$revision->{$field_name}->target_id = $target_workspace_id;
$revision->setNewRevision(FALSE);
$revision->setSyncing(TRUE);
$revision->save();
}
}
}
});
// Update the main association table.
$update_query = $this->database
->update(static::TABLE)
->fields([
'workspace' => $target_workspace_id,
])
->condition('workspace', $source_workspace_id);
if ($entity_type_id) {
$update_query->condition('target_entity_type_id', $entity_type_id);
if ($entity_ids) {
$update_query->condition(static::getIdField($entity_type_id), $entity_ids, 'IN');
}
}
$update_query->execute();
// Update the revision association table.
$update_revision_query = $this->database
->update(static::REVISION_TABLE)
->fields([
'workspace' => $target_workspace_id,
])
->condition('workspace', $source_workspace_id);
if ($entity_type_id) {
$update_revision_query->condition('target_entity_type_id', $entity_type_id);
if ($entity_ids) {
$update_revision_query->condition(static::getIdField($entity_type_id), $entity_ids, 'IN');
}
}
$update_revision_query->execute();
// Clear the cached associations.
$this->associatedRevisions = $this->associatedInitialRevisions = [];
} catch (\Exception $e) {
$transaction->rollBack();
Error::logException($this->logger, $e);
throw $e;
}
unset($transaction);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.