Mercurial > hg > isophonics-drupal-site
comparison core/modules/workspaces/src/WorkspacePublisher.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\workspaces; | |
4 | |
5 use Drupal\Core\Database\Connection; | |
6 use Drupal\Core\Entity\EntityTypeManagerInterface; | |
7 | |
8 /** | |
9 * Default implementation of the workspace publisher. | |
10 * | |
11 * @internal | |
12 */ | |
13 class WorkspacePublisher implements WorkspacePublisherInterface { | |
14 | |
15 /** | |
16 * The source workspace entity. | |
17 * | |
18 * @var \Drupal\workspaces\WorkspaceInterface | |
19 */ | |
20 protected $sourceWorkspace; | |
21 | |
22 /** | |
23 * The target workspace entity. | |
24 * | |
25 * @var \Drupal\workspaces\WorkspaceInterface | |
26 */ | |
27 protected $targetWorkspace; | |
28 | |
29 /** | |
30 * The entity type manager. | |
31 * | |
32 * @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
33 */ | |
34 protected $entityTypeManager; | |
35 | |
36 /** | |
37 * The database connection. | |
38 * | |
39 * @var \Drupal\Core\Database\Connection | |
40 */ | |
41 protected $database; | |
42 | |
43 /** | |
44 * The workspace association storage. | |
45 * | |
46 * @var \Drupal\workspaces\WorkspaceAssociationStorageInterface | |
47 */ | |
48 protected $workspaceAssociationStorage; | |
49 | |
50 /** | |
51 * Constructs a new WorkspacePublisher. | |
52 * | |
53 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager | |
54 * The entity type manager. | |
55 * @param \Drupal\Core\Database\Connection $database | |
56 * Database connection. | |
57 */ | |
58 public function __construct(EntityTypeManagerInterface $entity_type_manager, Connection $database, WorkspaceInterface $source) { | |
59 $this->entityTypeManager = $entity_type_manager; | |
60 $this->database = $database; | |
61 $this->workspaceAssociationStorage = $entity_type_manager->getStorage('workspace_association'); | |
62 $this->sourceWorkspace = $source; | |
63 $this->targetWorkspace = $this->entityTypeManager->getStorage('workspace')->load(WorkspaceInterface::DEFAULT_WORKSPACE); | |
64 } | |
65 | |
66 /** | |
67 * {@inheritdoc} | |
68 */ | |
69 public function publish() { | |
70 if ($this->checkConflictsOnTarget()) { | |
71 throw new WorkspaceConflictException(); | |
72 } | |
73 | |
74 $transaction = $this->database->startTransaction(); | |
75 try { | |
76 // @todo Handle the publishing of a workspace with a batch operation in | |
77 // https://www.drupal.org/node/2958752. | |
78 foreach ($this->getDifferringRevisionIdsOnSource() as $entity_type_id => $revision_difference) { | |
79 $entity_revisions = $this->entityTypeManager->getStorage($entity_type_id) | |
80 ->loadMultipleRevisions(array_keys($revision_difference)); | |
81 /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $entity */ | |
82 foreach ($entity_revisions as $entity) { | |
83 // When pushing workspace-specific revisions to the default workspace | |
84 // (Live), we simply need to mark them as default revisions. | |
85 // @todo Remove this dynamic property once we have an API for | |
86 // associating temporary data with an entity: | |
87 // https://www.drupal.org/node/2896474. | |
88 $entity->_isReplicating = TRUE; | |
89 $entity->isDefaultRevision(TRUE); | |
90 $entity->save(); | |
91 } | |
92 } | |
93 } | |
94 catch (\Exception $e) { | |
95 $transaction->rollBack(); | |
96 watchdog_exception('workspaces', $e); | |
97 throw $e; | |
98 } | |
99 | |
100 // Notify the workspace association storage that a workspace has been | |
101 // pushed. | |
102 $this->workspaceAssociationStorage->postPush($this->sourceWorkspace); | |
103 } | |
104 | |
105 /** | |
106 * {@inheritdoc} | |
107 */ | |
108 public function getSourceLabel() { | |
109 return $this->sourceWorkspace->label(); | |
110 } | |
111 | |
112 /** | |
113 * {@inheritdoc} | |
114 */ | |
115 public function getTargetLabel() { | |
116 return $this->targetWorkspace->label(); | |
117 } | |
118 | |
119 /** | |
120 * {@inheritdoc} | |
121 */ | |
122 public function checkConflictsOnTarget() { | |
123 // Nothing to do for now, we can not get to a conflicting state because an | |
124 // entity which is being edited in a workspace can not be edited in any | |
125 // other workspace. | |
126 } | |
127 | |
128 /** | |
129 * {@inheritdoc} | |
130 */ | |
131 public function getDifferringRevisionIdsOnTarget() { | |
132 $target_revision_difference = []; | |
133 | |
134 $tracked_entities = $this->workspaceAssociationStorage->getTrackedEntities($this->sourceWorkspace->id()); | |
135 foreach ($tracked_entities as $entity_type_id => $tracked_revisions) { | |
136 $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); | |
137 | |
138 // Get the latest revision IDs for all the entities that are tracked by | |
139 // the source workspace. | |
140 $query = $this->entityTypeManager | |
141 ->getStorage($entity_type_id) | |
142 ->getQuery() | |
143 ->condition($entity_type->getKey('id'), $tracked_revisions, 'IN') | |
144 ->latestRevision(); | |
145 $result = $query->execute(); | |
146 | |
147 // Now we compare the revision IDs which are tracked by the source | |
148 // workspace to the latest revision IDs of those entities and the | |
149 // difference between these two arrays gives us all the entities which | |
150 // have been modified on the target. | |
151 if ($revision_difference = array_diff_key($result, $tracked_revisions)) { | |
152 $target_revision_difference[$entity_type_id] = $revision_difference; | |
153 } | |
154 } | |
155 | |
156 return $target_revision_difference; | |
157 } | |
158 | |
159 /** | |
160 * {@inheritdoc} | |
161 */ | |
162 public function getDifferringRevisionIdsOnSource() { | |
163 // Get the Workspace association revisions which haven't been pushed yet. | |
164 return $this->workspaceAssociationStorage->getTrackedEntities($this->sourceWorkspace->id()); | |
165 } | |
166 | |
167 /** | |
168 * {@inheritdoc} | |
169 */ | |
170 public function getNumberOfChangesOnTarget() { | |
171 $total_changes = $this->getDifferringRevisionIdsOnTarget(); | |
172 return count($total_changes, COUNT_RECURSIVE) - count($total_changes); | |
173 } | |
174 | |
175 /** | |
176 * {@inheritdoc} | |
177 */ | |
178 public function getNumberOfChangesOnSource() { | |
179 $total_changes = $this->getDifferringRevisionIdsOnSource(); | |
180 return count($total_changes, COUNT_RECURSIVE) - count($total_changes); | |
181 } | |
182 | |
183 } |