1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of Transfer. |
5
|
|
|
* |
6
|
|
|
* For the full copyright and license information, please view the LICENSE file located |
7
|
|
|
* in the root directory. |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace Transfer\EzPlatform\Repository\Manager; |
11
|
|
|
|
12
|
|
|
use eZ\Publish\API\Repository\ContentService; |
13
|
|
|
use eZ\Publish\API\Repository\ContentTypeService; |
14
|
|
|
use eZ\Publish\API\Repository\Exceptions\NotFoundException; |
15
|
|
|
use eZ\Publish\API\Repository\LocationService; |
16
|
|
|
use eZ\Publish\API\Repository\Repository; |
17
|
|
|
use eZ\Publish\API\Repository\Values\Content\Content; |
18
|
|
|
use eZ\Publish\API\Repository\Values\Content\ContentCreateStruct; |
19
|
|
|
use eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct; |
20
|
|
|
use eZ\Publish\API\Repository\Values\Content\Location; |
21
|
|
|
use Psr\Log\LoggerAwareInterface; |
22
|
|
|
use Psr\Log\LoggerInterface; |
23
|
|
|
use Transfer\Data\ObjectInterface; |
24
|
|
|
use Transfer\Data\ValueObject; |
25
|
|
|
use Transfer\EzPlatform\Exception\ObjectNotFoundException; |
26
|
|
|
use Transfer\EzPlatform\Repository\Values\ContentObject; |
27
|
|
|
use Transfer\EzPlatform\Repository\Values\LocationObject; |
28
|
|
|
use Transfer\EzPlatform\Exception\MissingIdentificationPropertyException; |
29
|
|
|
use Transfer\EzPlatform\Exception\UnsupportedObjectOperationException; |
30
|
|
|
use Transfer\EzPlatform\Repository\Manager\Type\CreatorInterface; |
31
|
|
|
use Transfer\EzPlatform\Repository\Manager\Type\FinderInterface; |
32
|
|
|
use Transfer\EzPlatform\Repository\Manager\Type\RemoverInterface; |
33
|
|
|
use Transfer\EzPlatform\Repository\Manager\Type\UpdaterInterface; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Content manager. |
37
|
|
|
* |
38
|
|
|
* @internal |
39
|
|
|
*/ |
40
|
|
|
class ContentManager implements LoggerAwareInterface, CreatorInterface, UpdaterInterface, RemoverInterface, FinderInterface |
41
|
|
|
{ |
42
|
|
|
/** |
43
|
|
|
* @var LocationManager |
44
|
|
|
*/ |
45
|
|
|
private $locationManager; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var ContentService |
49
|
|
|
*/ |
50
|
|
|
protected $contentService; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @var ContentTypeService |
54
|
|
|
*/ |
55
|
|
|
protected $contentTypeService; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @var LocationService |
59
|
|
|
*/ |
60
|
|
|
protected $locationService; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @var LoggerInterface |
64
|
|
|
*/ |
65
|
|
|
protected $logger; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @param Repository $repository |
69
|
|
|
* @param LocationManager $locationManager |
70
|
|
|
*/ |
71
|
11 |
|
public function __construct(Repository $repository, LocationManager $locationManager) |
72
|
|
|
{ |
73
|
11 |
|
$this->locationManager = $locationManager; |
74
|
11 |
|
$this->contentService = $repository->getContentService(); |
75
|
11 |
|
$this->contentTypeService = $repository->getContentTypeService(); |
76
|
11 |
|
$this->locationService = $repository->getLocationService(); |
77
|
11 |
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* {@inheritdoc} |
81
|
|
|
*/ |
82
|
30 |
|
public function setLogger(LoggerInterface $logger) |
83
|
|
|
{ |
84
|
30 |
|
$this->logger = $logger; |
85
|
30 |
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* {@inheritdoc} |
89
|
|
|
*/ |
90
|
21 |
|
public function find(ValueObject $object) |
91
|
1 |
|
{ |
92
|
|
|
try { |
93
|
21 |
|
if ($object->getProperty('remote_id')) { |
94
|
21 |
|
$content = $this->contentService->loadContentByRemoteId($object->getProperty('remote_id')); |
95
|
16 |
|
} |
96
|
21 |
|
} catch (NotFoundException $notFoundException) { |
97
|
|
|
// We'll throw our own exception later instead. |
98
|
|
|
} |
99
|
|
|
|
100
|
21 |
|
if (!isset($content)) { |
101
|
10 |
|
throw new ObjectNotFoundException(Content::class, array('remote_id')); |
102
|
|
|
} |
103
|
|
|
|
104
|
16 |
|
return $content; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* {@inheritdoc} |
109
|
|
|
*/ |
110
|
9 |
|
public function create(ObjectInterface $object) |
111
|
|
|
{ |
112
|
9 |
|
if (!$object instanceof ContentObject) { |
113
|
1 |
|
throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object)); |
114
|
|
|
} |
115
|
|
|
|
116
|
8 |
|
$createStruct = $this->contentService->newContentCreateStruct( |
117
|
8 |
|
$this->contentTypeService->loadContentTypeByIdentifier($object->getProperty('content_type_identifier')), |
118
|
8 |
|
$object->getProperty('language') |
119
|
8 |
|
); |
120
|
|
|
|
121
|
8 |
|
$this->mapObjectToContentStruct($object, $createStruct); |
122
|
|
|
|
123
|
|
|
/** @var LocationObject[] $locationObjects */ |
124
|
8 |
|
$locationObjects = $object->getProperty('parent_locations'); |
125
|
8 |
|
$locationCreateStructs = []; |
126
|
8 |
|
if (is_array($locationObjects) && count($locationObjects) > 0) { |
127
|
2 |
|
foreach ($locationObjects as $locationObject) { |
128
|
2 |
|
$locationCreateStruct = $this->locationService->newLocationCreateStruct($locationObject->data['parent_location_id']); |
129
|
2 |
|
$locationObject->getMapper()->getNewLocationCreateStruct($locationCreateStruct); |
130
|
2 |
|
$locationCreateStructs[] = $locationCreateStruct; |
131
|
2 |
|
} |
132
|
2 |
|
} |
133
|
|
|
|
134
|
8 |
|
$content = $this->contentService->createContent($createStruct, $locationCreateStructs); |
135
|
8 |
|
$this->contentService->publishVersion($content->versionInfo); |
136
|
|
|
|
137
|
8 |
|
if ($this->logger) { |
138
|
8 |
|
$this->logger->info(sprintf('Published new version of %s', $object->getProperty('name')), array('ContentManager::create')); |
139
|
8 |
|
} |
140
|
|
|
|
141
|
8 |
|
$object->setProperty('id', $content->contentInfo->id); |
142
|
8 |
|
$object->setProperty('version_info', $content->versionInfo); |
143
|
8 |
|
$object->setProperty('content_info', $content->contentInfo); |
144
|
|
|
|
145
|
8 |
|
return $object; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* {@inheritdoc} |
150
|
|
|
*/ |
151
|
18 |
|
public function update(ObjectInterface $object) |
152
|
|
|
{ |
153
|
16 |
|
if (!$object instanceof ContentObject) { |
154
|
1 |
|
throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object)); |
155
|
|
|
} |
156
|
|
|
|
157
|
15 |
|
$existingContent = $this->find($object); |
158
|
15 |
|
if (null === $object->getProperty('content_info')) { |
159
|
13 |
|
$object->setProperty('content_info', $existingContent->contentInfo); |
160
|
13 |
|
} |
161
|
|
|
|
162
|
15 |
|
$contentDraft = $this->contentService->createContentDraft($object->getProperty('content_info')); |
163
|
|
|
|
164
|
16 |
|
$contentUpdateStruct = $this->contentService->newContentUpdateStruct(); |
165
|
15 |
|
$this->mapObjectToUpdateStruct($object, $contentUpdateStruct); |
166
|
|
|
|
167
|
15 |
|
$contentDraft = $this->contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct); |
168
|
15 |
|
$content = $this->contentService->publishVersion($contentDraft->versionInfo); |
169
|
|
|
|
170
|
15 |
|
if ($this->logger) { |
171
|
15 |
|
$this->logger->info(sprintf('Published new version of %s', $object->getProperty('name')), array('ContentManager::update')); |
172
|
15 |
|
} |
173
|
|
|
|
174
|
15 |
|
$object->setProperty('id', $content->contentInfo->id); |
175
|
15 |
|
$object->setProperty('version_info', $content->versionInfo); |
176
|
15 |
|
$object->setProperty('content_info', $content->contentInfo); |
177
|
|
|
|
178
|
|
|
// Add/Update/Delete parent locations |
179
|
18 |
|
$this->locationManager->syncronizeLocationsFromContentObject($object); |
180
|
|
|
|
181
|
15 |
|
return $object; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* {@inheritdoc} |
186
|
|
|
*/ |
187
|
20 |
|
public function createOrUpdate(ObjectInterface $object) |
188
|
|
|
{ |
189
|
20 |
|
if (!$object instanceof ContentObject) { |
190
|
1 |
|
throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object)); |
191
|
|
|
} |
192
|
|
|
|
193
|
19 |
|
if (!$object->getProperty('content_id') && !$object->getProperty('remote_id')) { |
194
|
1 |
|
throw new MissingIdentificationPropertyException($object); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
try { |
198
|
18 |
|
$this->find($object); |
199
|
|
|
|
200
|
15 |
|
return $this->update($object); |
201
|
8 |
|
} catch (NotFoundException $notFound) { |
202
|
8 |
|
return $this->create($object); |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* {@inheritdoc} |
208
|
|
|
*/ |
209
|
3 |
View Code Duplication |
public function remove(ObjectInterface $object) |
|
|
|
|
210
|
|
|
{ |
211
|
3 |
|
if (!$object instanceof ContentObject) { |
212
|
1 |
|
throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object)); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
try { |
216
|
2 |
|
$content = $this->find($object); |
217
|
1 |
|
$this->contentService->deleteContent($content->contentInfo); |
218
|
|
|
|
219
|
1 |
|
return true; |
220
|
1 |
|
} catch (NotFoundException $notFound) { |
221
|
1 |
|
return false; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Assigns a main location ID for a content object. |
227
|
|
|
* |
228
|
|
|
* @param ContentObject $object Content object |
229
|
|
|
* @param Location $location Location |
230
|
|
|
* |
231
|
|
|
* @return Content |
232
|
|
|
*/ |
233
|
3 |
|
public function setMainLocation(ContentObject $object, Location $location) |
234
|
|
|
{ |
235
|
3 |
|
$contentMetadataUpdateStruct = $this->contentService->newContentMetadataUpdateStruct(); |
236
|
|
|
|
237
|
3 |
|
$contentMetadataUpdateStruct->mainLocationId = $location->id; |
238
|
|
|
|
239
|
3 |
|
$object->setProperty('main_location_id', $location->id); |
240
|
|
|
|
241
|
3 |
|
return $this->contentService->updateContentMetadata($object->getProperty('content_info'), $contentMetadataUpdateStruct); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Maps object data to create struct. |
246
|
|
|
* |
247
|
|
|
* @param ContentObject $object Content object to map from |
248
|
|
|
* @param ContentCreateStruct $createStruct Content create struct to map to |
249
|
|
|
* |
250
|
|
|
* @throws \InvalidArgumentException |
251
|
|
|
*/ |
252
|
8 |
|
private function mapObjectToContentStruct(ContentObject $object, ContentCreateStruct $createStruct) |
253
|
|
|
{ |
254
|
8 |
|
$this->assignStructFieldValues($object, $createStruct); |
255
|
|
|
|
256
|
8 |
|
if ($object->getProperty('language')) { |
257
|
8 |
|
$createStruct->mainLanguageCode = $object->getProperty('language'); |
258
|
8 |
|
} |
259
|
|
|
|
260
|
8 |
|
if ($object->getProperty('remote_id')) { |
261
|
8 |
|
$createStruct->remoteId = $object->getProperty('remote_id'); |
262
|
8 |
|
} |
263
|
8 |
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* Maps object data to update struct. |
267
|
|
|
* |
268
|
|
|
* @param ContentObject $object Content object to map from |
269
|
|
|
* @param ContentUpdateStruct $contentUpdateStruct Content update struct to map to |
270
|
|
|
* |
271
|
|
|
* @throws \InvalidArgumentException |
272
|
|
|
*/ |
273
|
15 |
|
private function mapObjectToUpdateStruct(ContentObject $object, ContentUpdateStruct $contentUpdateStruct) |
274
|
|
|
{ |
275
|
15 |
|
$this->assignStructFieldValues($object, $contentUpdateStruct); |
276
|
15 |
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Copies content object data from a struct. |
280
|
|
|
* |
281
|
|
|
* @param ContentObject $object Content object to get values from |
282
|
|
|
* @param object $struct Struct to assign values to |
283
|
|
|
*/ |
284
|
18 |
|
private function assignStructFieldValues(ContentObject $object, $struct) |
285
|
|
|
{ |
286
|
18 |
|
foreach ($object->data as $key => $value) { |
287
|
18 |
|
if (is_array($value)) { |
288
|
2 |
|
$value = end($value); |
289
|
2 |
|
} |
290
|
|
|
|
291
|
18 |
|
$struct->setField($key, $value); |
292
|
18 |
|
} |
293
|
18 |
|
} |
294
|
|
|
} |
295
|
|
|
|
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.