Mercurial > hg > isophonics-drupal-site
view core/modules/workspaces/src/WorkspacePublisher.php @ 19:fa3358dc1485 tip
Add ndrum files
author | Chris Cannam |
---|---|
date | Wed, 28 Aug 2019 13:14:47 +0100 |
parents | af1871eacc83 |
children |
line wrap: on
line source
<?php namespace Drupal\workspaces; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityTypeManagerInterface; /** * Default implementation of the workspace publisher. * * @internal */ class WorkspacePublisher implements WorkspacePublisherInterface { /** * The source workspace entity. * * @var \Drupal\workspaces\WorkspaceInterface */ protected $sourceWorkspace; /** * The target workspace entity. * * @var \Drupal\workspaces\WorkspaceInterface */ protected $targetWorkspace; /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The database connection. * * @var \Drupal\Core\Database\Connection */ protected $database; /** * The workspace association storage. * * @var \Drupal\workspaces\WorkspaceAssociationStorageInterface */ protected $workspaceAssociationStorage; /** * The workspace manager. * * @var \Drupal\workspaces\WorkspaceManagerInterface */ protected $workspaceManager; /** * Constructs a new WorkspacePublisher. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Database\Connection $database * Database connection. * @param \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager * The workspace manager. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, Connection $database, WorkspaceManagerInterface $workspace_manager, WorkspaceInterface $source) { $this->entityTypeManager = $entity_type_manager; $this->database = $database; $this->workspaceAssociationStorage = $entity_type_manager->getStorage('workspace_association'); $this->workspaceManager = $workspace_manager; $this->sourceWorkspace = $source; $this->targetWorkspace = $this->entityTypeManager->getStorage('workspace')->load(WorkspaceInterface::DEFAULT_WORKSPACE); } /** * {@inheritdoc} */ public function publish() { if ($this->checkConflictsOnTarget()) { throw new WorkspaceConflictException(); } $transaction = $this->database->startTransaction(); try { // @todo Handle the publishing of a workspace with a batch operation in // https://www.drupal.org/node/2958752. $this->workspaceManager->executeInWorkspace($this->targetWorkspace->id(), function () { foreach ($this->getDifferringRevisionIdsOnSource() as $entity_type_id => $revision_difference) { $entity_revisions = $this->entityTypeManager->getStorage($entity_type_id) ->loadMultipleRevisions(array_keys($revision_difference)); $default_revisions = $this->entityTypeManager->getStorage($entity_type_id) ->loadMultiple(array_values($revision_difference)); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ foreach ($entity_revisions as $entity) { // When pushing workspace-specific revisions to the default // workspace (Live), we simply need to mark them as default // revisions. $entity->setSyncing(TRUE); $entity->isDefaultRevision(TRUE); $entity->original = $default_revisions[$entity->id()]; $entity->save(); } } }); } catch (\Exception $e) { $transaction->rollBack(); watchdog_exception('workspaces', $e); throw $e; } // Notify the workspace association storage that a workspace has been // pushed. $this->workspaceAssociationStorage->postPush($this->sourceWorkspace); } /** * {@inheritdoc} */ public function getSourceLabel() { return $this->sourceWorkspace->label(); } /** * {@inheritdoc} */ public function getTargetLabel() { return $this->targetWorkspace->label(); } /** * {@inheritdoc} */ public function checkConflictsOnTarget() { // Nothing to do for now, we can not get to a conflicting state because an // entity which is being edited in a workspace can not be edited in any // other workspace. } /** * {@inheritdoc} */ public function getDifferringRevisionIdsOnTarget() { $target_revision_difference = []; $tracked_entities = $this->workspaceAssociationStorage->getTrackedEntities($this->sourceWorkspace->id()); foreach ($tracked_entities as $entity_type_id => $tracked_revisions) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); // Get the latest revision IDs for all the entities that are tracked by // the source workspace. $query = $this->entityTypeManager ->getStorage($entity_type_id) ->getQuery() ->condition($entity_type->getKey('id'), $tracked_revisions, 'IN') ->latestRevision(); $result = $query->execute(); // Now we compare the revision IDs which are tracked by the source // workspace to the latest revision IDs of those entities and the // difference between these two arrays gives us all the entities which // have been modified on the target. if ($revision_difference = array_diff_key($result, $tracked_revisions)) { $target_revision_difference[$entity_type_id] = $revision_difference; } } return $target_revision_difference; } /** * {@inheritdoc} */ public function getDifferringRevisionIdsOnSource() { // Get the Workspace association revisions which haven't been pushed yet. return $this->workspaceAssociationStorage->getTrackedEntities($this->sourceWorkspace->id()); } /** * {@inheritdoc} */ public function getNumberOfChangesOnTarget() { $total_changes = $this->getDifferringRevisionIdsOnTarget(); return count($total_changes, COUNT_RECURSIVE) - count($total_changes); } /** * {@inheritdoc} */ public function getNumberOfChangesOnSource() { $total_changes = $this->getDifferringRevisionIdsOnSource(); return count($total_changes, COUNT_RECURSIVE) - count($total_changes); } }