|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* File containing the DomainMapper class. |
|
5
|
|
|
* |
|
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
|
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
|
8
|
|
|
*/ |
|
9
|
|
|
namespace eZ\Publish\Core\Repository\Helper; |
|
10
|
|
|
|
|
11
|
|
|
use eZ\Publish\SPI\Persistence\Content\Handler as ContentHandler; |
|
12
|
|
|
use eZ\Publish\SPI\Persistence\Content\Location\Handler as LocationHandler; |
|
13
|
|
|
use eZ\Publish\SPI\Persistence\Content\Language\Handler as LanguageHandler; |
|
14
|
|
|
use eZ\Publish\SPI\Persistence\Content\Type\Handler as TypeHandler; |
|
15
|
|
|
use eZ\Publish\Core\Repository\Values\Content\Content; |
|
16
|
|
|
use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo; |
|
17
|
|
|
use eZ\Publish\Core\Repository\Values\Content\VersionInfo; |
|
18
|
|
|
use eZ\Publish\API\Repository\Values\Content\ContentInfo; |
|
19
|
|
|
use eZ\Publish\API\Repository\Values\ContentType\ContentType; |
|
20
|
|
|
use eZ\Publish\API\Repository\Values\Content\Field; |
|
21
|
|
|
use eZ\Publish\Core\Repository\Values\Content\Relation; |
|
22
|
|
|
use eZ\Publish\API\Repository\Values\Content\Location as APILocation; |
|
23
|
|
|
use eZ\Publish\Core\Repository\Values\Content\Location; |
|
24
|
|
|
use eZ\Publish\SPI\Persistence\Content as SPIContent; |
|
25
|
|
|
use eZ\Publish\SPI\Persistence\Content\Location as SPILocation; |
|
26
|
|
|
use eZ\Publish\SPI\Persistence\Content\VersionInfo as SPIVersionInfo; |
|
27
|
|
|
use eZ\Publish\SPI\Persistence\Content\ContentInfo as SPIContentInfo; |
|
28
|
|
|
use eZ\Publish\SPI\Persistence\Content\Relation as SPIRelation; |
|
29
|
|
|
use eZ\Publish\SPI\Persistence\Content\Type as SPIType; |
|
30
|
|
|
use eZ\Publish\SPI\Persistence\Content\Location\CreateStruct as SPILocationCreateStruct; |
|
31
|
|
|
use eZ\Publish\API\Repository\Exceptions\NotFoundException; |
|
32
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException; |
|
33
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue; |
|
34
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentType; |
|
35
|
|
|
use DateTime; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* DomainMapper is an internal service. |
|
39
|
|
|
* |
|
40
|
|
|
* @internal Meant for internal use by Repository. |
|
41
|
|
|
*/ |
|
42
|
|
|
class DomainMapper |
|
43
|
|
|
{ |
|
44
|
|
|
/** |
|
45
|
|
|
* @var \eZ\Publish\SPI\Persistence\Content\Handler |
|
46
|
|
|
*/ |
|
47
|
|
|
protected $contentHandler; |
|
48
|
|
|
|
|
49
|
|
|
/** |
|
50
|
|
|
* @var \eZ\Publish\SPI\Persistence\Content\Location\Handler |
|
51
|
|
|
*/ |
|
52
|
|
|
protected $locationHandler; |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* @var \eZ\Publish\SPI\Persistence\Content\Type\Handler |
|
56
|
|
|
*/ |
|
57
|
|
|
protected $contentTypeHandler; |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* @var \eZ\Publish\SPI\Persistence\Content\Language\Handler |
|
61
|
|
|
*/ |
|
62
|
|
|
protected $contentLanguageHandler; |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* @var FieldTypeRegistry |
|
66
|
|
|
*/ |
|
67
|
|
|
protected $fieldTypeRegistry; |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Setups service with reference to repository. |
|
71
|
|
|
* |
|
72
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Handler $contentHandler |
|
73
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Location\Handler $locationHandler |
|
74
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Type\Handler $contentTypeHandler |
|
75
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $contentLanguageHandler |
|
76
|
|
|
* @param FieldTypeRegistry $fieldTypeRegistry |
|
77
|
|
|
*/ |
|
78
|
|
|
public function __construct( |
|
79
|
|
|
ContentHandler $contentHandler, |
|
80
|
|
|
LocationHandler $locationHandler, |
|
81
|
|
|
TypeHandler $contentTypeHandler, |
|
82
|
|
|
LanguageHandler $contentLanguageHandler, |
|
83
|
|
|
FieldTypeRegistry $fieldTypeRegistry |
|
84
|
|
|
) { |
|
85
|
|
|
$this->contentHandler = $contentHandler; |
|
86
|
|
|
$this->locationHandler = $locationHandler; |
|
87
|
|
|
$this->contentTypeHandler = $contentTypeHandler; |
|
88
|
|
|
$this->contentLanguageHandler = $contentLanguageHandler; |
|
89
|
|
|
$this->fieldTypeRegistry = $fieldTypeRegistry; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Builds a Content domain object from value object returned from persistence. |
|
94
|
|
|
* |
|
95
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content $spiContent |
|
96
|
|
|
* @param ContentType|SPIType $contentType |
|
97
|
|
|
* @param array|null $fieldLanguages Language codes to filter fields on |
|
98
|
|
|
* @param string|null $fieldAlwaysAvailableLanguage Language code fallback if a given field is not found in $fieldLanguages |
|
99
|
|
|
* |
|
100
|
|
|
* @return \eZ\Publish\Core\Repository\Values\Content\Content |
|
101
|
|
|
*/ |
|
102
|
|
|
public function buildContentDomainObject(SPIContent $spiContent, $contentType = null, array $fieldLanguages = null, $fieldAlwaysAvailableLanguage = null) |
|
103
|
|
|
{ |
|
104
|
|
|
if ($contentType === null) { |
|
105
|
|
|
$contentType = $this->contentTypeHandler->load( |
|
106
|
|
|
$spiContent->versionInfo->contentInfo->contentTypeId |
|
107
|
|
|
); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
$prioritizedFieldLanguageCode = null; |
|
111
|
|
|
$prioritizedLanguages = $fieldLanguages ?: []; |
|
112
|
|
|
if (!empty($prioritizedLanguages)) { |
|
113
|
|
|
$availableFieldLanguageMap = array_fill_keys($spiContent->versionInfo->languageCodes, true); |
|
114
|
|
|
foreach ($prioritizedLanguages as $prioritizedLanguage) { |
|
115
|
|
|
if (isset($availableFieldLanguageMap[$prioritizedLanguage])) { |
|
116
|
|
|
$prioritizedFieldLanguageCode = $prioritizedLanguage; |
|
117
|
|
|
break; |
|
118
|
|
|
} |
|
119
|
|
|
} |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
return new Content( |
|
123
|
|
|
array( |
|
124
|
|
|
'internalFields' => $this->buildDomainFields($spiContent->fields, $contentType, $fieldLanguages, $fieldAlwaysAvailableLanguage), |
|
125
|
|
|
'versionInfo' => $this->buildVersionInfoDomainObject($spiContent->versionInfo, $prioritizedLanguages), |
|
126
|
|
|
'prioritizedFieldLanguageCode' => $prioritizedFieldLanguageCode, |
|
127
|
|
|
) |
|
128
|
|
|
); |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
/** |
|
132
|
|
|
* Returns an array of domain fields created from given array of SPI fields. |
|
133
|
|
|
* |
|
134
|
|
|
* @throws InvalidArgumentType On invalid $contentType |
|
135
|
|
|
* |
|
136
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Field[] $spiFields |
|
137
|
|
|
* @param ContentType|SPIType $contentType |
|
138
|
|
|
* @param array $languages A language priority, filters returned fields and is used as prioritized language code on |
|
139
|
|
|
* returned value object. If not given all languages are returned. |
|
140
|
|
|
* @param string|null $alwaysAvailableLanguage Language code fallback if a given field is not found in $languages |
|
141
|
|
|
* |
|
142
|
|
|
* @return array |
|
143
|
|
|
*/ |
|
144
|
|
|
public function buildDomainFields( |
|
145
|
|
|
array $spiFields, |
|
146
|
|
|
$contentType, |
|
147
|
|
|
array $languages = null, |
|
148
|
|
|
$alwaysAvailableLanguage = null |
|
149
|
|
|
) { |
|
150
|
|
|
if (!$contentType instanceof SPIType && !$contentType instanceof ContentType) { |
|
151
|
|
|
throw new InvalidArgumentType('$contentType', 'SPI ContentType | API ContentType'); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
$fieldIdentifierMap = array(); |
|
155
|
|
|
foreach ($contentType->fieldDefinitions as $fieldDefinitions) { |
|
156
|
|
|
$fieldIdentifierMap[$fieldDefinitions->id] = $fieldDefinitions->identifier; |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
$fieldInFilterLanguagesMap = array(); |
|
160
|
|
|
if (!empty($languages) && $alwaysAvailableLanguage !== null) { |
|
161
|
|
|
foreach ($spiFields as $spiField) { |
|
162
|
|
|
if (in_array($spiField->languageCode, $languages)) { |
|
163
|
|
|
$fieldInFilterLanguagesMap[$spiField->fieldDefinitionId] = true; |
|
164
|
|
|
} |
|
165
|
|
|
} |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
$fields = array(); |
|
169
|
|
|
foreach ($spiFields as $spiField) { |
|
170
|
|
|
// We ignore fields in content not part of the content type |
|
171
|
|
|
if (!isset($fieldIdentifierMap[$spiField->fieldDefinitionId])) { |
|
172
|
|
|
continue; |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
if (!empty($languages) && !in_array($spiField->languageCode, $languages)) { |
|
176
|
|
|
// If filtering is enabled we ignore fields in other languages then $fieldLanguages, if: |
|
177
|
|
|
if ($alwaysAvailableLanguage === null) { |
|
178
|
|
|
// Ignore field if we don't have $alwaysAvailableLanguageCode fallback |
|
179
|
|
|
continue; |
|
180
|
|
|
} elseif (!empty($fieldInFilterLanguagesMap[$spiField->fieldDefinitionId])) { |
|
181
|
|
|
// Ignore field if it exists in one of the filtered languages |
|
182
|
|
|
continue; |
|
183
|
|
|
} elseif ($spiField->languageCode !== $alwaysAvailableLanguage) { |
|
184
|
|
|
// Also ignore if field is not in $alwaysAvailableLanguageCode |
|
185
|
|
|
continue; |
|
186
|
|
|
} |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
|
$fields[] = new Field( |
|
190
|
|
|
array( |
|
191
|
|
|
'id' => $spiField->id, |
|
192
|
|
|
'value' => $this->fieldTypeRegistry->getFieldType($spiField->type) |
|
193
|
|
|
->fromPersistenceValue($spiField->value), |
|
194
|
|
|
'languageCode' => $spiField->languageCode, |
|
195
|
|
|
'fieldDefIdentifier' => $fieldIdentifierMap[$spiField->fieldDefinitionId], |
|
196
|
|
|
'fieldTypeIdentifier' => $spiField->type, |
|
197
|
|
|
) |
|
198
|
|
|
); |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
return $fields; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
/** |
|
205
|
|
|
* Builds a VersionInfo domain object from value object returned from persistence. |
|
206
|
|
|
* |
|
207
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $spiVersionInfo |
|
208
|
|
|
* @param array $prioritizedLanguages |
|
209
|
|
|
* |
|
210
|
|
|
* @return \eZ\Publish\Core\Repository\Values\Content\VersionInfo |
|
211
|
|
|
*/ |
|
212
|
|
|
public function buildVersionInfoDomainObject(SPIVersionInfo $spiVersionInfo, array $prioritizedLanguages = []) |
|
213
|
|
|
{ |
|
214
|
|
|
// Map SPI statuses to API |
|
215
|
|
|
switch ($spiVersionInfo->status) { |
|
216
|
|
|
case SPIVersionInfo::STATUS_ARCHIVED: |
|
217
|
|
|
$status = APIVersionInfo::STATUS_ARCHIVED; |
|
218
|
|
|
break; |
|
219
|
|
|
|
|
220
|
|
|
case SPIVersionInfo::STATUS_PUBLISHED: |
|
221
|
|
|
$status = APIVersionInfo::STATUS_PUBLISHED; |
|
222
|
|
|
break; |
|
223
|
|
|
|
|
224
|
|
|
case SPIVersionInfo::STATUS_DRAFT: |
|
225
|
|
|
default: |
|
226
|
|
|
$status = APIVersionInfo::STATUS_DRAFT; |
|
227
|
|
|
} |
|
228
|
|
|
|
|
229
|
|
|
// Find prioritised language among names |
|
230
|
|
|
$prioritizedNameLanguageCode = null; |
|
231
|
|
|
foreach ($prioritizedLanguages as $prioritizedLanguage) { |
|
232
|
|
|
if (isset($spiVersionInfo->names[$prioritizedLanguage])) { |
|
233
|
|
|
$prioritizedNameLanguageCode = $prioritizedLanguage; |
|
234
|
|
|
break; |
|
235
|
|
|
} |
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
return new VersionInfo( |
|
239
|
|
|
array( |
|
240
|
|
|
'id' => $spiVersionInfo->id, |
|
241
|
|
|
'versionNo' => $spiVersionInfo->versionNo, |
|
242
|
|
|
'modificationDate' => $this->getDateTime($spiVersionInfo->modificationDate), |
|
243
|
|
|
'creatorId' => $spiVersionInfo->creatorId, |
|
244
|
|
|
'creationDate' => $this->getDateTime($spiVersionInfo->creationDate), |
|
245
|
|
|
'status' => $status, |
|
246
|
|
|
'initialLanguageCode' => $spiVersionInfo->initialLanguageCode, |
|
247
|
|
|
'languageCodes' => $spiVersionInfo->languageCodes, |
|
248
|
|
|
'names' => $spiVersionInfo->names, |
|
249
|
|
|
'contentInfo' => $this->buildContentInfoDomainObject($spiVersionInfo->contentInfo), |
|
250
|
|
|
'prioritizedNameLanguageCode' => $prioritizedNameLanguageCode, |
|
251
|
|
|
) |
|
252
|
|
|
); |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
/** |
|
256
|
|
|
* Builds a ContentInfo domain object from value object returned from persistence. |
|
257
|
|
|
* |
|
258
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\ContentInfo $spiContentInfo |
|
259
|
|
|
* |
|
260
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\ContentInfo |
|
261
|
|
|
*/ |
|
262
|
|
|
public function buildContentInfoDomainObject(SPIContentInfo $spiContentInfo) |
|
263
|
|
|
{ |
|
264
|
|
|
// Map SPI statuses to API |
|
265
|
|
|
switch ($spiContentInfo->status) { |
|
266
|
|
|
case SPIContentInfo::STATUS_TRASHED: |
|
267
|
|
|
$status = ContentInfo::STATUS_TRASHED; |
|
268
|
|
|
break; |
|
269
|
|
|
|
|
270
|
|
|
case SPIContentInfo::STATUS_PUBLISHED: |
|
271
|
|
|
$status = ContentInfo::STATUS_PUBLISHED; |
|
272
|
|
|
break; |
|
273
|
|
|
|
|
274
|
|
|
case SPIContentInfo::STATUS_DRAFT: |
|
275
|
|
|
default: |
|
276
|
|
|
$status = ContentInfo::STATUS_DRAFT; |
|
277
|
|
|
} |
|
278
|
|
|
|
|
279
|
|
|
return new ContentInfo( |
|
280
|
|
|
array( |
|
281
|
|
|
'id' => $spiContentInfo->id, |
|
282
|
|
|
'contentTypeId' => $spiContentInfo->contentTypeId, |
|
283
|
|
|
'name' => $spiContentInfo->name, |
|
284
|
|
|
'sectionId' => $spiContentInfo->sectionId, |
|
285
|
|
|
'currentVersionNo' => $spiContentInfo->currentVersionNo, |
|
286
|
|
|
'published' => $spiContentInfo->isPublished, |
|
|
|
|
|
|
287
|
|
|
'ownerId' => $spiContentInfo->ownerId, |
|
288
|
|
|
'modificationDate' => $spiContentInfo->modificationDate == 0 ? |
|
289
|
|
|
null : |
|
290
|
|
|
$this->getDateTime($spiContentInfo->modificationDate), |
|
291
|
|
|
'publishedDate' => $spiContentInfo->publicationDate == 0 ? |
|
292
|
|
|
null : |
|
293
|
|
|
$this->getDateTime($spiContentInfo->publicationDate), |
|
294
|
|
|
'alwaysAvailable' => $spiContentInfo->alwaysAvailable, |
|
295
|
|
|
'remoteId' => $spiContentInfo->remoteId, |
|
296
|
|
|
'mainLanguageCode' => $spiContentInfo->mainLanguageCode, |
|
297
|
|
|
'mainLocationId' => $spiContentInfo->mainLocationId, |
|
298
|
|
|
'status' => $status, |
|
299
|
|
|
) |
|
300
|
|
|
); |
|
301
|
|
|
} |
|
302
|
|
|
|
|
303
|
|
|
/** |
|
304
|
|
|
* Builds API Relation object from provided SPI Relation object. |
|
305
|
|
|
* |
|
306
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Relation $spiRelation |
|
307
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $sourceContentInfo |
|
308
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $destinationContentInfo |
|
309
|
|
|
* |
|
310
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Relation |
|
311
|
|
|
*/ |
|
312
|
|
|
public function buildRelationDomainObject( |
|
313
|
|
|
SPIRelation $spiRelation, |
|
314
|
|
|
ContentInfo $sourceContentInfo, |
|
315
|
|
|
ContentInfo $destinationContentInfo |
|
316
|
|
|
) { |
|
317
|
|
|
$sourceFieldDefinitionIdentifier = null; |
|
318
|
|
|
if ($spiRelation->sourceFieldDefinitionId !== null) { |
|
319
|
|
|
$contentType = $this->contentTypeHandler->load($sourceContentInfo->contentTypeId); |
|
320
|
|
|
foreach ($contentType->fieldDefinitions as $fieldDefinition) { |
|
321
|
|
|
if ($fieldDefinition->id !== $spiRelation->sourceFieldDefinitionId) { |
|
322
|
|
|
continue; |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
$sourceFieldDefinitionIdentifier = $fieldDefinition->identifier; |
|
326
|
|
|
break; |
|
327
|
|
|
} |
|
328
|
|
|
} |
|
329
|
|
|
|
|
330
|
|
|
return new Relation( |
|
331
|
|
|
array( |
|
332
|
|
|
'id' => $spiRelation->id, |
|
333
|
|
|
'sourceFieldDefinitionIdentifier' => $sourceFieldDefinitionIdentifier, |
|
334
|
|
|
'type' => $spiRelation->type, |
|
335
|
|
|
'sourceContentInfo' => $sourceContentInfo, |
|
336
|
|
|
'destinationContentInfo' => $destinationContentInfo, |
|
337
|
|
|
) |
|
338
|
|
|
); |
|
339
|
|
|
} |
|
340
|
|
|
|
|
341
|
|
|
/** |
|
342
|
|
|
* Builds domain location object from provided persistence location. |
|
343
|
|
|
* |
|
344
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Location $spiLocation |
|
345
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\ContentInfo $spiContentInfo pre-loaded Content Info |
|
346
|
|
|
* |
|
347
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Location |
|
348
|
|
|
* |
|
349
|
|
|
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException In case if the given Content does not belong to the given Location |
|
350
|
|
|
*/ |
|
351
|
|
|
public function buildLocationDomainObject(SPILocation $spiLocation, SPIContentInfo $spiContentInfo = null) |
|
352
|
|
|
{ |
|
353
|
|
|
// TODO: this is hardcoded workaround for missing ContentInfo on root location |
|
354
|
|
|
if ($spiLocation->id == 1) { |
|
355
|
|
|
$legacyDateTime = $this->getDateTime(1030968000); // first known commit of eZ Publish 3.x |
|
356
|
|
|
$contentInfo = new ContentInfo( |
|
357
|
|
|
array( |
|
358
|
|
|
'id' => 0, |
|
359
|
|
|
'name' => 'Top Level Nodes', |
|
360
|
|
|
'sectionId' => 1, |
|
361
|
|
|
'mainLocationId' => 1, |
|
362
|
|
|
'contentTypeId' => 1, |
|
363
|
|
|
'currentVersionNo' => 1, |
|
364
|
|
|
'published' => 1, |
|
365
|
|
|
'ownerId' => 14, // admin user |
|
366
|
|
|
'modificationDate' => $legacyDateTime, |
|
367
|
|
|
'publishedDate' => $legacyDateTime, |
|
368
|
|
|
'alwaysAvailable' => 1, |
|
369
|
|
|
'remoteId' => null, |
|
370
|
|
|
'mainLanguageCode' => 'eng-GB', |
|
371
|
|
|
) |
|
372
|
|
|
); |
|
373
|
|
|
} elseif (null !== $spiContentInfo) { |
|
374
|
|
|
if ($spiLocation->contentId !== $spiContentInfo->id) { |
|
375
|
|
|
throw new InvalidArgumentException( |
|
376
|
|
|
'$spiContentInfo', |
|
377
|
|
|
sprintf( |
|
378
|
|
|
'Content Id %d does not belong to the Location %d', |
|
379
|
|
|
$spiContentInfo->id, |
|
380
|
|
|
$spiLocation->id |
|
381
|
|
|
) |
|
382
|
|
|
); |
|
383
|
|
|
} |
|
384
|
|
|
|
|
385
|
|
|
$contentInfo = $this->buildContentInfoDomainObject($spiContentInfo); |
|
386
|
|
|
} else { |
|
387
|
|
|
$contentInfo = $this->buildContentInfoDomainObject( |
|
388
|
|
|
$this->contentHandler->loadContentInfo($spiLocation->contentId) |
|
389
|
|
|
); |
|
390
|
|
|
} |
|
391
|
|
|
|
|
392
|
|
|
return new Location( |
|
393
|
|
|
array( |
|
394
|
|
|
'contentInfo' => $contentInfo, |
|
395
|
|
|
'id' => $spiLocation->id, |
|
396
|
|
|
'priority' => $spiLocation->priority, |
|
397
|
|
|
'hidden' => $spiLocation->hidden, |
|
398
|
|
|
'invisible' => $spiLocation->invisible, |
|
399
|
|
|
'remoteId' => $spiLocation->remoteId, |
|
400
|
|
|
'parentLocationId' => $spiLocation->parentId, |
|
401
|
|
|
'pathString' => $spiLocation->pathString, |
|
402
|
|
|
'depth' => $spiLocation->depth, |
|
403
|
|
|
'sortField' => $spiLocation->sortField, |
|
404
|
|
|
'sortOrder' => $spiLocation->sortOrder, |
|
405
|
|
|
) |
|
406
|
|
|
); |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
/** |
|
410
|
|
|
* Creates an array of SPI location create structs from given array of API location create structs. |
|
411
|
|
|
* |
|
412
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
|
413
|
|
|
* |
|
414
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct $locationCreateStruct |
|
415
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Location $parentLocation |
|
416
|
|
|
* @param mixed $mainLocation |
|
417
|
|
|
* @param mixed $contentId |
|
418
|
|
|
* @param mixed $contentVersionNo |
|
419
|
|
|
* |
|
420
|
|
|
* @return \eZ\Publish\SPI\Persistence\Content\Location\CreateStruct |
|
421
|
|
|
*/ |
|
422
|
|
|
public function buildSPILocationCreateStruct( |
|
423
|
|
|
$locationCreateStruct, |
|
424
|
|
|
APILocation $parentLocation, |
|
425
|
|
|
$mainLocation, |
|
426
|
|
|
$contentId, |
|
427
|
|
|
$contentVersionNo |
|
428
|
|
|
) { |
|
429
|
|
|
if ($locationCreateStruct->priority !== null && !is_int($locationCreateStruct->priority)) { |
|
430
|
|
|
throw new InvalidArgumentValue('priority', $locationCreateStruct->priority, 'LocationCreateStruct'); |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
if (!is_bool($locationCreateStruct->hidden)) { |
|
434
|
|
|
throw new InvalidArgumentValue('hidden', $locationCreateStruct->hidden, 'LocationCreateStruct'); |
|
435
|
|
|
} |
|
436
|
|
|
|
|
437
|
|
|
if ($locationCreateStruct->remoteId !== null && (!is_string($locationCreateStruct->remoteId) || empty($locationCreateStruct->remoteId))) { |
|
438
|
|
|
throw new InvalidArgumentValue('remoteId', $locationCreateStruct->remoteId, 'LocationCreateStruct'); |
|
439
|
|
|
} |
|
440
|
|
|
|
|
441
|
|
|
if ($locationCreateStruct->sortField !== null && !$this->isValidLocationSortField($locationCreateStruct->sortField)) { |
|
442
|
|
|
throw new InvalidArgumentValue('sortField', $locationCreateStruct->sortField, 'LocationCreateStruct'); |
|
443
|
|
|
} |
|
444
|
|
|
|
|
445
|
|
|
if ($locationCreateStruct->sortOrder !== null && !$this->isValidLocationSortOrder($locationCreateStruct->sortOrder)) { |
|
446
|
|
|
throw new InvalidArgumentValue('sortOrder', $locationCreateStruct->sortOrder, 'LocationCreateStruct'); |
|
447
|
|
|
} |
|
448
|
|
|
|
|
449
|
|
|
$remoteId = $locationCreateStruct->remoteId; |
|
450
|
|
|
if (null === $remoteId) { |
|
451
|
|
|
$remoteId = $this->getUniqueHash($locationCreateStruct); |
|
452
|
|
|
} else { |
|
453
|
|
|
try { |
|
454
|
|
|
$this->locationHandler->loadByRemoteId($remoteId); |
|
455
|
|
|
throw new InvalidArgumentException( |
|
456
|
|
|
'$locationCreateStructs', |
|
457
|
|
|
"Another Location with remoteId '{$remoteId}' exists" |
|
458
|
|
|
); |
|
459
|
|
|
} catch (NotFoundException $e) { |
|
460
|
|
|
// Do nothing |
|
461
|
|
|
} |
|
462
|
|
|
} |
|
463
|
|
|
|
|
464
|
|
|
return new SPILocationCreateStruct( |
|
465
|
|
|
array( |
|
466
|
|
|
'priority' => $locationCreateStruct->priority, |
|
467
|
|
|
'hidden' => $locationCreateStruct->hidden, |
|
468
|
|
|
// If we declare the new Location as hidden, it is automatically invisible |
|
469
|
|
|
// Otherwise it picks up visibility from parent Location |
|
470
|
|
|
// Note: There is no need to check for hidden status of parent, as hidden Location |
|
471
|
|
|
// is always invisible as well |
|
472
|
|
|
'invisible' => ($locationCreateStruct->hidden === true || $parentLocation->invisible), |
|
473
|
|
|
'remoteId' => $remoteId, |
|
474
|
|
|
'contentId' => $contentId, |
|
475
|
|
|
'contentVersion' => $contentVersionNo, |
|
476
|
|
|
// pathIdentificationString will be set in storage |
|
477
|
|
|
'pathIdentificationString' => null, |
|
478
|
|
|
'mainLocationId' => $mainLocation, |
|
479
|
|
|
'sortField' => $locationCreateStruct->sortField !== null ? $locationCreateStruct->sortField : Location::SORT_FIELD_NAME, |
|
480
|
|
|
'sortOrder' => $locationCreateStruct->sortOrder !== null ? $locationCreateStruct->sortOrder : Location::SORT_ORDER_ASC, |
|
481
|
|
|
'parentId' => $locationCreateStruct->parentLocationId, |
|
482
|
|
|
) |
|
483
|
|
|
); |
|
484
|
|
|
} |
|
485
|
|
|
|
|
486
|
|
|
/** |
|
487
|
|
|
* Checks if given $sortField value is one of the defined sort field constants. |
|
488
|
|
|
* |
|
489
|
|
|
* @param mixed $sortField |
|
490
|
|
|
* |
|
491
|
|
|
* @return bool |
|
492
|
|
|
*/ |
|
493
|
|
|
public function isValidLocationSortField($sortField) |
|
494
|
|
|
{ |
|
495
|
|
|
switch ($sortField) { |
|
496
|
|
|
case APILocation::SORT_FIELD_PATH: |
|
497
|
|
|
case APILocation::SORT_FIELD_PUBLISHED: |
|
498
|
|
|
case APILocation::SORT_FIELD_MODIFIED: |
|
499
|
|
|
case APILocation::SORT_FIELD_SECTION: |
|
500
|
|
|
case APILocation::SORT_FIELD_DEPTH: |
|
501
|
|
|
case APILocation::SORT_FIELD_CLASS_IDENTIFIER: |
|
502
|
|
|
case APILocation::SORT_FIELD_CLASS_NAME: |
|
503
|
|
|
case APILocation::SORT_FIELD_PRIORITY: |
|
504
|
|
|
case APILocation::SORT_FIELD_NAME: |
|
505
|
|
|
case APILocation::SORT_FIELD_MODIFIED_SUBNODE: |
|
|
|
|
|
|
506
|
|
|
case APILocation::SORT_FIELD_NODE_ID: |
|
507
|
|
|
case APILocation::SORT_FIELD_CONTENTOBJECT_ID: |
|
508
|
|
|
return true; |
|
509
|
|
|
} |
|
510
|
|
|
|
|
511
|
|
|
return false; |
|
512
|
|
|
} |
|
513
|
|
|
|
|
514
|
|
|
/** |
|
515
|
|
|
* Checks if given $sortOrder value is one of the defined sort order constants. |
|
516
|
|
|
* |
|
517
|
|
|
* @param mixed $sortOrder |
|
518
|
|
|
* |
|
519
|
|
|
* @return bool |
|
520
|
|
|
*/ |
|
521
|
|
|
public function isValidLocationSortOrder($sortOrder) |
|
522
|
|
|
{ |
|
523
|
|
|
switch ($sortOrder) { |
|
524
|
|
|
case APILocation::SORT_ORDER_DESC: |
|
525
|
|
|
case APILocation::SORT_ORDER_ASC: |
|
526
|
|
|
return true; |
|
527
|
|
|
} |
|
528
|
|
|
|
|
529
|
|
|
return false; |
|
530
|
|
|
} |
|
531
|
|
|
|
|
532
|
|
|
/** |
|
533
|
|
|
* Validates given translated list $list, which should be an array of strings with language codes as keys. |
|
534
|
|
|
* |
|
535
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
|
536
|
|
|
* |
|
537
|
|
|
* @param mixed $list |
|
538
|
|
|
* @param string $argumentName |
|
539
|
|
|
*/ |
|
540
|
|
|
public function validateTranslatedList($list, $argumentName) |
|
541
|
|
|
{ |
|
542
|
|
|
if (!is_array($list)) { |
|
543
|
|
|
throw new InvalidArgumentType($argumentName, 'array', $list); |
|
544
|
|
|
} |
|
545
|
|
|
|
|
546
|
|
|
foreach ($list as $languageCode => $translation) { |
|
547
|
|
|
$this->contentLanguageHandler->loadByLanguageCode($languageCode); |
|
548
|
|
|
|
|
549
|
|
|
if (!is_string($translation)) { |
|
550
|
|
|
throw new InvalidArgumentType($argumentName . "['$languageCode']", 'string', $translation); |
|
551
|
|
|
} |
|
552
|
|
|
} |
|
553
|
|
|
} |
|
554
|
|
|
|
|
555
|
|
|
/** |
|
556
|
|
|
* Returns \DateTime object from given $timestamp in environment timezone. |
|
557
|
|
|
* |
|
558
|
|
|
* This method is needed because constructing \DateTime with $timestamp will |
|
559
|
|
|
* return the object in UTC timezone. |
|
560
|
|
|
* |
|
561
|
|
|
* @param int $timestamp |
|
562
|
|
|
* |
|
563
|
|
|
* @return \DateTime |
|
564
|
|
|
*/ |
|
565
|
|
|
public function getDateTime($timestamp) |
|
566
|
|
|
{ |
|
567
|
|
|
$dateTime = new DateTime(); |
|
568
|
|
|
$dateTime->setTimestamp($timestamp); |
|
569
|
|
|
|
|
570
|
|
|
return $dateTime; |
|
571
|
|
|
} |
|
572
|
|
|
|
|
573
|
|
|
/** |
|
574
|
|
|
* Creates unique hash string for given $object. |
|
575
|
|
|
* |
|
576
|
|
|
* Used for remoteId. |
|
577
|
|
|
* |
|
578
|
|
|
* @param object $object |
|
579
|
|
|
* |
|
580
|
|
|
* @return string |
|
581
|
|
|
*/ |
|
582
|
|
|
public function getUniqueHash($object) |
|
583
|
|
|
{ |
|
584
|
|
|
return md5(uniqid(get_class($object), true)); |
|
585
|
|
|
} |
|
586
|
|
|
} |
|
587
|
|
|
|
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.