1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Kaliop\eZMigrationBundle\Core\Executor; |
4
|
|
|
|
5
|
|
|
use eZ\Publish\API\Repository\Values\Content\Location; |
6
|
|
|
use Kaliop\eZMigrationBundle\API\Collection\ContentCollection; |
7
|
|
|
use Kaliop\eZMigrationBundle\Core\Matcher\ContentMatcher; |
8
|
|
|
|
9
|
|
|
class LocationManager extends RepositoryExecutor |
10
|
|
|
{ |
11
|
|
|
protected $supportedStepTypes = array('location'); |
12
|
|
|
|
13
|
|
|
protected $contentMatcher; |
14
|
|
|
|
15
|
|
|
public function __construct(ContentMatcher $contentMatcher) |
16
|
|
|
{ |
17
|
|
|
$this->contentMatcher = $contentMatcher; |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* NB: weirdly enough, it returns contents, not locations |
22
|
|
|
* |
23
|
|
|
* @param string $action |
24
|
|
|
* @return ContentCollection |
25
|
|
|
* @throws \Exception |
26
|
|
|
*/ |
27
|
|
View Code Duplication |
protected function matchContents($action) |
|
|
|
|
28
|
|
|
{ |
29
|
|
|
if (!isset($this->dsl['object_id']) && !isset($this->dsl['remote_id']) && !isset($this->dsl['match'])) { |
30
|
|
|
throw new \Exception("The ID or remote ID of an object or a Match Condition is required to $action a new location."); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
// Backwards compat |
34
|
|
|
if (!isset($this->dsl['match'])) { |
35
|
|
|
if (isset($this->dsl['object_id'])) { |
36
|
|
|
$this->dsl['match'] = array('content_id' => $this->dsl['object_id']); |
37
|
|
|
} elseif (isset($this->dsl['remote_id'])) { |
38
|
|
|
$this->dsl['match'] = array('content_remote_id' => $this->dsl['remote_id']); |
39
|
|
|
} |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
$match = $this->dsl['match']; |
43
|
|
|
|
44
|
|
|
// convert the references passed in the match |
45
|
|
|
foreach ($match as $condition => $values) { |
46
|
|
|
if (is_array($values)) { |
47
|
|
|
foreach ($values as $position => $value) { |
48
|
|
|
if ($this->referenceResolver->isReference($value)) { |
49
|
|
|
$match[$condition][$position] = $this->referenceResolver->getReferenceValue($value); |
50
|
|
|
} |
51
|
|
|
} |
52
|
|
|
} else { |
53
|
|
|
if ($this->referenceResolver->isReference($values)) { |
54
|
|
|
$match[$condition] = $this->referenceResolver->getReferenceValue($values); |
55
|
|
|
} |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
return $this->contentMatcher->matchContent($match); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Method to handle the create operation of the migration instructions |
64
|
|
|
*/ |
65
|
|
|
protected function create() |
66
|
|
|
{ |
67
|
|
|
$this->loginUser(); |
68
|
|
|
|
69
|
|
|
$locationService = $this->repository->getLocationService(); |
70
|
|
|
|
71
|
|
|
if (!isset($this->dsl['parent_location_id'])) { |
72
|
|
|
throw new \Exception('Missing parent location id. This is required to create the new location.'); |
73
|
|
|
} |
74
|
|
|
if (!is_array($this->dsl['parent_location_id'])) { |
75
|
|
|
$this->dsl['parent_location_id'] = array($this->dsl['parent_location_id']); |
76
|
|
|
} |
77
|
|
|
foreach ($this->dsl['parent_location_id'] as $id => $parentLocationId) { |
78
|
|
|
if ($this->referenceResolver->isReference($parentLocationId)) { |
79
|
|
|
$this->dsl['parent_location_id'][$id] = $this->referenceResolver->getReferenceValue($parentLocationId); |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
$contentCollection = $this->matchContents('create'); |
84
|
|
|
|
85
|
|
|
foreach ($contentCollection as $content) { |
|
|
|
|
86
|
|
|
$contentInfo = $content->contentInfo; |
87
|
|
|
|
88
|
|
|
foreach ($this->dsl['parent_location_id'] as $parentLocationId) { |
|
|
|
|
89
|
|
|
$locationCreateStruct = $locationService->newLocationCreateStruct($parentLocationId); |
90
|
|
|
|
91
|
|
|
$locationCreateStruct->hidden = isset($this->dsl['is_hidden']) ?: false; |
92
|
|
|
|
93
|
|
|
if (isset($this->dsl['priority'])) { |
94
|
|
|
$locationCreateStruct->priority = $this->dsl['priority']; |
|
|
|
|
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
$locationCreateStruct->sortOrder = $this->getSortOrder(); |
98
|
|
|
$locationCreateStruct->sortField = $this->getSortField(); |
99
|
|
|
|
100
|
|
|
$locationService->createLocation($contentInfo, $locationCreateStruct); |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Method to handle the update operation of the migration instructions |
107
|
|
|
* |
108
|
|
|
* Updates basic information for a location like priority, sort field and sort order. |
109
|
|
|
* Updates the visibility of the location when needed |
110
|
|
|
* |
111
|
|
|
* Can move a location and it's children to a new parent location or swap two locations |
112
|
|
|
*/ |
113
|
|
|
protected function update() |
114
|
|
|
{ |
115
|
|
|
$this->loginUser(); |
116
|
|
|
|
117
|
|
|
$locationService = $this->repository->getLocationService(); |
118
|
|
|
|
119
|
|
|
if (!isset($this->dsl['location_id'])) { |
120
|
|
|
throw new \Exception('No location set for update.'); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
if (isset($this->dsl['swap_with_location']) && isset($this->dsl['patent_location_id'])) { |
124
|
|
|
throw new \Exception('Cannot move location to a new parent and swap location with another location at the same time.'); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$locationId = $this->dsl['location_id']; |
128
|
|
|
if ($this->referenceResolver->isReference($locationId)) { |
129
|
|
|
$locationId = $this->referenceResolver->getReferenceValue($locationId); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
$location = $locationService->loadLocation($locationId); |
133
|
|
|
|
134
|
|
|
if (array_key_exists('priority', $this->dsl) |
135
|
|
|
|| array_key_exists('sort_field', $this->dsl) |
136
|
|
|
|| array_key_exists('sort_order', $this->dsl) |
137
|
|
|
) { |
138
|
|
|
$locationUpdateStruct = $locationService->newLocationUpdateStruct(); |
139
|
|
|
|
140
|
|
|
if (isset($this->dsl['priority'])) { |
141
|
|
|
$locationUpdateStruct->priority = $this->dsl['priority']; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
if (isset($this->dsl['sort_field'])) { |
145
|
|
|
$locationUpdateStruct->sortField = $this->getSortField($location->sortField); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
if (isset($this->dsl['sort_order'])) { |
149
|
|
|
$locationUpdateStruct->sortOrder = $this->getSortOrder($location->sortOrder); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
$locationService->updateLocation($location, $locationUpdateStruct); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
// Check if visibility needs to be updated |
156
|
|
|
if (isset($this->dsl['is_hidden'])) { |
157
|
|
|
if ($this->dsl['is_hidden']) { |
158
|
|
|
$locationService->hideLocation($location); |
159
|
|
|
} else { |
160
|
|
|
$locationService->unhideLocation($location); |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
// Move or swap location |
165
|
|
|
if (isset($this->dsl['parent_location_id'])) { |
166
|
|
|
// Move the location and all it's children to a new parent |
167
|
|
|
$parentLocationId = $this->dsl['parent_location_id']; |
168
|
|
|
if ($this->referenceResolver->isReference($parentLocationId)) { |
169
|
|
|
$parentLocationId = $this->referenceResolver->getReferenceValue($parentLocationId); |
170
|
|
|
} |
171
|
|
|
$newParentLocation = $locationService->loadLocation($parentLocationId); |
172
|
|
|
$locationService->moveSubtree($location, $newParentLocation); |
173
|
|
View Code Duplication |
} elseif (isset($this->dsl['swap_with_location'])) { |
|
|
|
|
174
|
|
|
//Swap locations |
175
|
|
|
$swapLocationId = $this->dsl['swap_with_location']; |
176
|
|
|
if ($this->referenceResolver->isReference($swapLocationId)) { |
177
|
|
|
$swapLocationId = $this->referenceResolver->getReferenceValue($swapLocationId); |
178
|
|
|
} |
179
|
|
|
$locationToSwap = $locationService->loadLocation($swapLocationId); |
180
|
|
|
|
181
|
|
|
$locationService->swapLocation($location, $locationToSwap); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
$this->setReferences($location); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Method to handle the delete operation of the migration instructions |
189
|
|
|
* |
190
|
|
|
* Delete locations identified by their ids. |
191
|
|
|
*/ |
192
|
|
|
protected function delete() |
193
|
|
|
{ |
194
|
|
|
$this->loginUser(); |
195
|
|
|
|
196
|
|
|
$locationService = $this->repository->getLocationService(); |
197
|
|
|
|
198
|
|
|
if (!isset($this->dsl['location_id'])) { |
199
|
|
|
throw new \Exception('No location provided for deletion'); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
if (!is_array($this->dsl['location_id'])) { |
203
|
|
|
$this->dsl['location_id'] = array($this->dsl['location_id']); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
foreach ($this->dsl['location_id'] as $locationId) { |
207
|
|
|
$location = $locationService->loadLocation($locationId); |
208
|
|
|
$locationService->deleteLocation($location); |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
protected function getSortField($currentValue = null) |
213
|
|
|
{ |
214
|
|
|
$sortField = Location::SORT_FIELD_PUBLISHED; |
215
|
|
|
|
216
|
|
|
if (!is_null($currentValue)) { |
217
|
|
|
$sortField = $currentValue; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
if (isset($this->dsl['sort_field'])) { |
221
|
|
|
$sortFieldId = "SORT_FIELD_" . strtoupper($this->dsl['sort_field']); |
222
|
|
|
|
223
|
|
|
$ref = new \ReflectionClass('eZ\Publish\API\Repository\Values\Content\Location'); |
224
|
|
|
|
225
|
|
|
$sortField = $ref->getConstant($sortFieldId); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
return $sortField; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Get the sort order based on the current value and the value in the DSL definition. |
233
|
|
|
* |
234
|
|
|
* If no current value is set and there is no value in the DSL it will default to Location::SORT_ORDER_ASC |
235
|
|
|
* |
236
|
|
|
* @see \eZ\Publish\API\Repository\Values\Content\Location::SORT_ORDER_* |
237
|
|
|
* |
238
|
|
|
* @param int $currentValue |
239
|
|
|
* @return int |
240
|
|
|
*/ |
241
|
|
|
protected function getSortOrder($currentValue = null) |
242
|
|
|
{ |
243
|
|
|
$sortOrder = Location::SORT_ORDER_ASC; |
244
|
|
|
if (!is_null($currentValue)) { |
245
|
|
|
$sortOrder = $currentValue; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
if (isset($this->dsl['sort_order'])) { |
249
|
|
|
if (strtoupper($this->dsl['sort_order']) === 'ASC') { |
250
|
|
|
$sortOrder = Location::SORT_ORDER_ASC; |
251
|
|
|
} else { |
252
|
|
|
$sortOrder = Location::SORT_ORDER_DESC; |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
return $sortOrder; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Sets references to object attributes |
261
|
|
|
* |
262
|
|
|
* The Location Manager currently supports setting references to location id. |
263
|
|
|
* |
264
|
|
|
* @throws \InvalidArgumentException When trying to set a reference to an unsupported attribute. |
265
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Location $location |
266
|
|
|
* @return boolean |
267
|
|
|
*/ |
268
|
|
View Code Duplication |
protected function setReferences($location) |
|
|
|
|
269
|
|
|
{ |
270
|
|
|
if (!array_key_exists('references', $this->dsl)) { |
271
|
|
|
return false; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
foreach ($this->dsl['references'] as $reference) { |
275
|
|
|
switch ($reference['attribute']) { |
276
|
|
|
case 'location_id': |
277
|
|
|
case 'id': |
278
|
|
|
$value = $location->id; |
279
|
|
|
break; |
280
|
|
|
default: |
281
|
|
|
throw new \InvalidArgumentException('Location Manager does not support setting references for attribute ' . $reference['attribute']); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
$this->referenceResolver->addReference($reference['identifier'], $value); |
|
|
|
|
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
return true; |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.