Exponential 5.x Kernel 7.5.40 Exponential New Stack (Symfony-based) Kernel — PHP Class Reference

DomainMapper.php
Go to the documentation of this file.
1 <?php
2
7 namespace eZ\Publish\Core\Repository\Helper;
8
9 use eZ\Publish\API\Repository\Values\Content\Search\SearchResult;
10 use eZ\Publish\API\Repository\Values\Content\Content as APIContent;
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\Core\Repository\Values\Content\ContentProxy;
17 use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo;
18 use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
19 use eZ\Publish\API\Repository\Values\Content\ContentInfo;
20 use eZ\Publish\API\Repository\Values\ContentType\ContentType;
21 use eZ\Publish\API\Repository\Values\Content\Field;
22 use eZ\Publish\Core\Repository\Values\Content\Relation;
23 use eZ\Publish\API\Repository\Values\Content\Location as APILocation;
24 use eZ\Publish\Core\Repository\Values\Content\Location;
25 use eZ\Publish\SPI\Persistence\Content as SPIContent;
26 use eZ\Publish\SPI\Persistence\Content\Location as SPILocation;
27 use eZ\Publish\SPI\Persistence\Content\VersionInfo as SPIVersionInfo;
28 use eZ\Publish\SPI\Persistence\Content\ContentInfo as SPIContentInfo;
29 use eZ\Publish\SPI\Persistence\Content\Relation as SPIRelation;
30 use eZ\Publish\SPI\Persistence\Content\Type as SPIContentType;
31 use eZ\Publish\SPI\Persistence\Content\Location\CreateStruct as SPILocationCreateStruct;
32 use eZ\Publish\API\Repository\Exceptions\NotFoundException;
33 use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
34 use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue;
35 use eZ\Publish\Core\Base\Exceptions\InvalidArgumentType;
36 use DateTime;
37
43 class DomainMapper
44 {
45 const MAX_LOCATION_PRIORITY = 2147483647;
46 const MIN_LOCATION_PRIORITY = -2147483648;
47
49 protected $contentHandler;
50
52 protected $locationHandler;
53
55 protected $contentTypeHandler;
56
58 protected $contentTypeDomainMapper;
59
61 protected $contentLanguageHandler;
62
64 protected $fieldTypeRegistry;
65
76 public function __construct(
77 ContentHandler $contentHandler,
78 LocationHandler $locationHandler,
79 TypeHandler $contentTypeHandler,
80 ContentTypeDomainMapper $contentTypeDomainMapper,
81 LanguageHandler $contentLanguageHandler,
82 FieldTypeRegistry $fieldTypeRegistry
83 ) {
84 $this->contentHandler = $contentHandler;
85 $this->locationHandler = $locationHandler;
86 $this->contentTypeHandler = $contentTypeHandler;
87 $this->contentTypeDomainMapper = $contentTypeDomainMapper;
88 $this->contentLanguageHandler = $contentLanguageHandler;
89 $this->fieldTypeRegistry = $fieldTypeRegistry;
90 }
91
102 public function buildContentDomainObject(
103 SPIContent $spiContent,
104 ContentType $contentType,
105 array $prioritizedLanguages = [],
106 string $fieldAlwaysAvailableLanguage = null
107 ) {
108 $prioritizedFieldLanguageCode = null;
109 if (!empty($prioritizedLanguages)) {
110 $availableFieldLanguageMap = array_fill_keys($spiContent->versionInfo->languageCodes, true);
111 foreach ($prioritizedLanguages as $prioritizedLanguage) {
112 if (isset($availableFieldLanguageMap[$prioritizedLanguage])) {
113 $prioritizedFieldLanguageCode = $prioritizedLanguage;
114 break;
115 }
116 }
117 }
118
119 return new Content(
120 [
121 'internalFields' => $this->buildDomainFields($spiContent->fields, $contentType, $prioritizedLanguages, $fieldAlwaysAvailableLanguage),
122 'versionInfo' => $this->buildVersionInfoDomainObject($spiContent->versionInfo, $prioritizedLanguages),
123 'contentType' => $contentType,
124 'prioritizedFieldLanguageCode' => $prioritizedFieldLanguageCode,
125 ]
126 );
127 }
128
139 public function buildContentDomainObjectFromPersistence(
140 SPIContent $spiContent,
141 SPIContentType $spiContentType,
142 array $prioritizedLanguages = [],
143 ?string $fieldAlwaysAvailableLanguage = null
144 ): APIContent {
145 $contentType = $this->contentTypeDomainMapper->buildContentTypeDomainObject($spiContentType, $prioritizedLanguages);
146
147 return $this->buildContentDomainObject($spiContent, $contentType, $prioritizedLanguages, $fieldAlwaysAvailableLanguage);
148 }
149
153 public function buildContentProxy(
154 SPIContent\ContentInfo $info,
155 array $prioritizedLanguages = [],
156 bool $useAlwaysAvailable = true
157 ): APIContent {
158 $generator = $this->generatorForContentList([$info], $prioritizedLanguages, $useAlwaysAvailable);
159
160 return new ContentProxy($generator, $info->id);
161 }
162
172 public function buildContentProxyList(
173 array $infoList,
174 array $prioritizedLanguages = [],
175 bool $useAlwaysAvailable = true
176 ): array {
177 $list = [];
178 $generator = $this->generatorForContentList($infoList, $prioritizedLanguages, $useAlwaysAvailable);
179 foreach ($infoList as $info) {
180 $list[$info->id] = new ContentProxy($generator, $info->id);
181 }
182
183 return $list;
184 }
185
196 private function generatorForContentList(
197 array $infoList,
198 array $prioritizedLanguages = [],
199 bool $useAlwaysAvailable = true
200 ): \Generator {
201 $contentIds = [];
202 $contentTypeIds = [];
203 $translations = $prioritizedLanguages;
204 foreach ($infoList as $info) {
205 $contentIds[] = $info->id;
206 $contentTypeIds[] = $info->contentTypeId;
207 // Unless we are told to load all languages, we add main language to translations so they are loaded too
208 // Might in some case load more languages then intended, but prioritised handling will pick right one
209 if (!empty($prioritizedLanguages) && $useAlwaysAvailable && $info->alwaysAvailable) {
210 $translations[] = $info->mainLanguageCode;
211 }
212 }
213
214 unset($infoList);
215
216 $contentList = $this->contentHandler->loadContentList($contentIds, array_unique($translations));
217 $contentTypeList = $this->contentTypeHandler->loadContentTypeList(array_unique($contentTypeIds));
218 while (!empty($contentList)) {
219 $id = yield;
221 $info = $contentList[$id]->versionInfo->contentInfo;
222 yield $this->buildContentDomainObject(
223 $contentList[$id],
224 $this->contentTypeDomainMapper->buildContentTypeDomainObject(
225 $contentTypeList[$info->contentTypeId],
226 $prioritizedLanguages
227 ),
228 $prioritizedLanguages,
229 $info->alwaysAvailable ? $info->mainLanguageCode : null
230 );
231
232 unset($contentList[$id]);
233 }
234 }
235
249 public function buildDomainFields(
250 array $spiFields,
251 $contentType,
252 array $prioritizedLanguages = [],
253 string $alwaysAvailableLanguage = null
254 ) {
255 if (!$contentType instanceof SPIContentType && !$contentType instanceof ContentType) {
256 throw new InvalidArgumentType('$contentType', 'SPI ContentType | API ContentType');
257 }
258
259 $fieldDefinitionsMap = [];
260 foreach ($contentType->fieldDefinitions as $fieldDefinition) {
261 $fieldDefinitionsMap[$fieldDefinition->id] = $fieldDefinition;
262 }
263
264 $fieldInFilterLanguagesMap = [];
265 if (!empty($prioritizedLanguages) && $alwaysAvailableLanguage !== null) {
266 foreach ($spiFields as $spiField) {
267 if (in_array($spiField->languageCode, $prioritizedLanguages)) {
268 $fieldInFilterLanguagesMap[$spiField->fieldDefinitionId] = true;
269 }
270 }
271 }
272
273 $fields = [];
274 foreach ($spiFields as $spiField) {
275 // We ignore fields in content not part of the content type
276 if (!isset($fieldDefinitionsMap[$spiField->fieldDefinitionId])) {
277 continue;
278 }
279
280 $fieldDefinition = $fieldDefinitionsMap[$spiField->fieldDefinitionId];
281
282 if (!empty($prioritizedLanguages) && !in_array($spiField->languageCode, $prioritizedLanguages)) {
283 // If filtering is enabled we ignore fields in other languages then $prioritizedLanguages, if:
284 if ($alwaysAvailableLanguage === null) {
285 // Ignore field if we don't have $alwaysAvailableLanguageCode fallback
286 continue;
287 } elseif (!empty($fieldInFilterLanguagesMap[$spiField->fieldDefinitionId])) {
288 // Ignore field if it exists in one of the filtered languages
289 continue;
290 } elseif ($spiField->languageCode !== $alwaysAvailableLanguage) {
291 // Also ignore if field is not in $alwaysAvailableLanguageCode
292 continue;
293 }
294 }
295
296 $fields[$fieldDefinition->position][] = new Field(
297 [
298 'id' => $spiField->id,
299 'value' => $this->fieldTypeRegistry->getFieldType($spiField->type)
300 ->fromPersistenceValue($spiField->value),
301 'languageCode' => $spiField->languageCode,
302 'fieldDefIdentifier' => $fieldDefinition->identifier,
303 'fieldTypeIdentifier' => $spiField->type,
304 ]
305 );
306 }
307
308 // Sort fields by content type field definition priority
309 ksort($fields, SORT_NUMERIC);
310
311 // Flatten array
312 return array_merge(...$fields);
313 }
314
323 public function buildVersionInfoDomainObject(SPIVersionInfo $spiVersionInfo, array $prioritizedLanguages = [])
324 {
325 // Map SPI statuses to API
326 switch ($spiVersionInfo->status) {
327 case SPIVersionInfo::STATUS_ARCHIVED:
328 $status = APIVersionInfo::STATUS_ARCHIVED;
329 break;
330
331 case SPIVersionInfo::STATUS_PUBLISHED:
332 $status = APIVersionInfo::STATUS_PUBLISHED;
333 break;
334
335 case SPIVersionInfo::STATUS_DRAFT:
336 default:
337 $status = APIVersionInfo::STATUS_DRAFT;
338 }
339
340 // Find prioritised language among names
341 $prioritizedNameLanguageCode = null;
342 foreach ($prioritizedLanguages as $prioritizedLanguage) {
343 if (isset($spiVersionInfo->names[$prioritizedLanguage])) {
344 $prioritizedNameLanguageCode = $prioritizedLanguage;
345 break;
346 }
347 }
348
349 return new VersionInfo(
350 [
351 'id' => $spiVersionInfo->id,
352 'versionNo' => $spiVersionInfo->versionNo,
353 'modificationDate' => $this->getDateTime($spiVersionInfo->modificationDate),
354 'creatorId' => $spiVersionInfo->creatorId,
355 'creationDate' => $this->getDateTime($spiVersionInfo->creationDate),
356 'status' => $status,
357 'initialLanguageCode' => $spiVersionInfo->initialLanguageCode,
358 'languageCodes' => $spiVersionInfo->languageCodes,
359 'names' => $spiVersionInfo->names,
360 'contentInfo' => $this->buildContentInfoDomainObject($spiVersionInfo->contentInfo),
361 'prioritizedNameLanguageCode' => $prioritizedNameLanguageCode,
362 ]
363 );
364 }
365
373 public function buildContentInfoDomainObject(SPIContentInfo $spiContentInfo)
374 {
375 // Map SPI statuses to API
376 switch ($spiContentInfo->status) {
377 case SPIContentInfo::STATUS_TRASHED:
378 $status = ContentInfo::STATUS_TRASHED;
379 break;
380
381 case SPIContentInfo::STATUS_PUBLISHED:
382 $status = ContentInfo::STATUS_PUBLISHED;
383 break;
384
385 case SPIContentInfo::STATUS_DRAFT:
386 default:
387 $status = ContentInfo::STATUS_DRAFT;
388 }
389
390 return new ContentInfo(
391 [
392 'id' => $spiContentInfo->id,
393 'contentTypeId' => $spiContentInfo->contentTypeId,
394 'name' => $spiContentInfo->name,
395 'sectionId' => $spiContentInfo->sectionId,
396 'currentVersionNo' => $spiContentInfo->currentVersionNo,
397 'published' => $spiContentInfo->isPublished,
398 'ownerId' => $spiContentInfo->ownerId,
399 'modificationDate' => $spiContentInfo->modificationDate == 0 ?
400 null :
401 $this->getDateTime($spiContentInfo->modificationDate),
402 'publishedDate' => $spiContentInfo->publicationDate == 0 ?
403 null :
404 $this->getDateTime($spiContentInfo->publicationDate),
405 'alwaysAvailable' => $spiContentInfo->alwaysAvailable,
406 'remoteId' => $spiContentInfo->remoteId,
407 'mainLanguageCode' => $spiContentInfo->mainLanguageCode,
408 'mainLocationId' => $spiContentInfo->mainLocationId,
409 'status' => $status,
410 'isHidden' => $spiContentInfo->isHidden,
411 ]
412 );
413 }
414
424 public function buildRelationDomainObject(
425 SPIRelation $spiRelation,
426 ContentInfo $sourceContentInfo,
427 ContentInfo $destinationContentInfo
428 ) {
429 $sourceFieldDefinitionIdentifier = null;
430 if ($spiRelation->sourceFieldDefinitionId !== null) {
431 $contentType = $this->contentTypeHandler->load($sourceContentInfo->contentTypeId);
432 foreach ($contentType->fieldDefinitions as $fieldDefinition) {
433 if ($fieldDefinition->id !== $spiRelation->sourceFieldDefinitionId) {
434 continue;
435 }
436
437 $sourceFieldDefinitionIdentifier = $fieldDefinition->identifier;
438 break;
439 }
440 }
441
442 return new Relation(
443 [
444 'id' => $spiRelation->id,
445 'sourceFieldDefinitionIdentifier' => $sourceFieldDefinitionIdentifier,
446 'type' => $spiRelation->type,
447 'sourceContentInfo' => $sourceContentInfo,
448 'destinationContentInfo' => $destinationContentInfo,
449 ]
450 );
451 }
452
456 public function buildLocationDomainObject(
457 SPILocation $spiLocation,
458 SPIContentInfo $contentInfo = null
459 ) {
460 if ($contentInfo === null) {
461 return $this->buildLocation($spiLocation);
462 }
463
464 return $this->mapLocation(
465 $spiLocation,
466 $this->buildContentInfoDomainObject($contentInfo),
467 $this->buildContentProxy($contentInfo)
468 );
469 }
470
471 public function buildLocation(
472 SPILocation $spiLocation,
473 array $prioritizedLanguages = [],
474 bool $useAlwaysAvailable = true
475 ): APILocation {
476 if ($this->isRootLocation($spiLocation)) {
477 return $this->buildRootLocation($spiLocation);
478 }
479
480 $spiContentInfo = $this->contentHandler->loadContentInfo($spiLocation->contentId);
481
482 return $this->mapLocation(
483 $spiLocation,
484 $this->buildContentInfoDomainObject($spiContentInfo),
485 $this->buildContentProxy($spiContentInfo, $prioritizedLanguages, $useAlwaysAvailable)
486 );
487 }
488
498 public function buildLocationWithContent(
499 SPILocation $spiLocation,
500 ?APIContent $content,
501 ?SPIContentInfo $spiContentInfo = null
502 ): APILocation {
503 if ($this->isRootLocation($spiLocation)) {
504 return $this->buildRootLocation($spiLocation);
505 }
506
507 if ($content === null) {
508 throw new InvalidArgumentException('$content', "Location {$spiLocation->id} has missing Content");
509 }
510
511 if ($spiContentInfo !== null) {
512 $contentInfo = $this->buildContentInfoDomainObject($spiContentInfo);
513 } else {
514 $contentInfo = $content->contentInfo;
515 }
516
517 return $this->mapLocation($spiLocation, $contentInfo, $content);
518 }
519
527 private function buildRootLocation(SPILocation $spiLocation): APILocation
528 {
529 // first known commit of eZ Publish 3.x
530 $legacyDateTime = $this->getDateTime(1030968000);
531
532 // NOTE: this is hardcoded workaround for missing ContentInfo on root location
533 return $this->mapLocation(
534 $spiLocation,
535 new ContentInfo([
536 'id' => 0,
537 'name' => 'Top Level Nodes',
538 'sectionId' => 1,
539 'mainLocationId' => 1,
540 'contentTypeId' => 1,
541 'currentVersionNo' => 1,
542 'published' => 1,
543 'ownerId' => 14, // admin user
544 'modificationDate' => $legacyDateTime,
545 'publishedDate' => $legacyDateTime,
546 'alwaysAvailable' => 1,
547 'remoteId' => null,
548 'mainLanguageCode' => 'eng-GB',
549 ]),
550 new Content([])
551 );
552 }
553
554 private function mapLocation(SPILocation $spiLocation, ContentInfo $contentInfo, APIContent $content): APILocation
555 {
556 return new Location(
557 [
558 'content' => $content,
559 'contentInfo' => $contentInfo,
560 'id' => $spiLocation->id,
561 'priority' => $spiLocation->priority,
562 'hidden' => $spiLocation->hidden || $contentInfo->isHidden,
563 'invisible' => $spiLocation->invisible,
564 'explicitlyHidden' => $spiLocation->hidden,
565 'remoteId' => $spiLocation->remoteId,
566 'parentLocationId' => $spiLocation->parentId,
567 'pathString' => $spiLocation->pathString,
568 'depth' => $spiLocation->depth,
569 'sortField' => $spiLocation->sortField,
570 'sortOrder' => $spiLocation->sortOrder,
571 ]
572 );
573 }
574
585 public function buildContentDomainObjectsOnSearchResult(SearchResult $result, array $languageFilter)
586 {
587 if (empty($result->searchHits)) {
588 return [];
589 }
590
591 $contentIds = [];
592 $contentTypeIds = [];
593 $translations = $languageFilter['languages'] ?? [];
594 $useAlwaysAvailable = $languageFilter['useAlwaysAvailable'] ?? true;
595 foreach ($result->searchHits as $hit) {
597 $info = $hit->valueObject;
598 $contentIds[] = $info->id;
599 $contentTypeIds[] = $info->contentTypeId;
600 // Unless we are told to load all languages, we add main language to translations so they are loaded too
601 // Might in some case load more languages then intended, but prioritised handling will pick right one
602 if (!empty($languageFilter['languages']) && $useAlwaysAvailable && $info->alwaysAvailable) {
603 $translations[] = $info->mainLanguageCode;
604 }
605 }
606
607 $missingContentList = [];
608 $contentList = $this->contentHandler->loadContentList($contentIds, array_unique($translations));
609 $contentTypeList = $this->contentTypeHandler->loadContentTypeList(array_unique($contentTypeIds));
610 foreach ($result->searchHits as $key => $hit) {
611 if (isset($contentList[$hit->valueObject->id])) {
612 $hit->valueObject = $this->buildContentDomainObject(
613 $contentList[$hit->valueObject->id],
614 $this->contentTypeDomainMapper->buildContentTypeDomainObject(
615 $contentTypeList[$hit->valueObject->contentTypeId],
616 $languageFilter['languages'] ?? []
617 ),
618 $languageFilter['languages'] ?? [],
619 $useAlwaysAvailable ? $hit->valueObject->mainLanguageCode : null
620 );
621 } else {
622 $missingContentList[] = $hit->valueObject;
623 unset($result->searchHits[$key]);
624 --$result->totalCount;
625 }
626 }
627
628 return $missingContentList;
629 }
630
642 public function buildLocationDomainObjectsOnSearchResult(SearchResult $result, array $languageFilter)
643 {
644 if (empty($result->searchHits)) {
645 return [];
646 }
647
648 $contentIds = [];
649 foreach ($result->searchHits as $hit) {
650 $contentIds[] = $hit->valueObject->contentId;
651 }
652
653 $missingLocations = [];
654 $contentInfoList = $this->contentHandler->loadContentInfoList($contentIds);
655 $contentList = $this->buildContentProxyList(
656 $contentInfoList,
657 !empty($languageFilter['languages']) ? $languageFilter['languages'] : []
658 );
659 foreach ($result->searchHits as $key => $hit) {
660 if (isset($contentInfoList[$hit->valueObject->contentId])) {
661 $hit->valueObject = $this->buildLocationWithContent(
662 $hit->valueObject,
663 $contentList[$hit->valueObject->contentId],
664 $contentInfoList[$hit->valueObject->contentId]
665 );
666 } else {
667 $missingLocations[] = $hit->valueObject;
668 unset($result->searchHits[$key]);
669 --$result->totalCount;
670 }
671 }
672
673 return $missingLocations;
674 }
675
690 public function buildSPILocationCreateStruct(
691 $locationCreateStruct,
692 APILocation $parentLocation,
693 $mainLocation,
694 $contentId,
695 $contentVersionNo,
696 bool $isContentHidden
697 ) {
698 if (!$this->isValidLocationPriority($locationCreateStruct->priority)) {
699 throw new InvalidArgumentValue('priority', $locationCreateStruct->priority, 'LocationCreateStruct');
700 }
701
702 if (!is_bool($locationCreateStruct->hidden)) {
703 throw new InvalidArgumentValue('hidden', $locationCreateStruct->hidden, 'LocationCreateStruct');
704 }
705
706 if ($locationCreateStruct->remoteId !== null && (!is_string($locationCreateStruct->remoteId) || empty($locationCreateStruct->remoteId))) {
707 throw new InvalidArgumentValue('remoteId', $locationCreateStruct->remoteId, 'LocationCreateStruct');
708 }
709
710 if ($locationCreateStruct->sortField !== null && !$this->isValidLocationSortField($locationCreateStruct->sortField)) {
711 throw new InvalidArgumentValue('sortField', $locationCreateStruct->sortField, 'LocationCreateStruct');
712 }
713
714 if ($locationCreateStruct->sortOrder !== null && !$this->isValidLocationSortOrder($locationCreateStruct->sortOrder)) {
715 throw new InvalidArgumentValue('sortOrder', $locationCreateStruct->sortOrder, 'LocationCreateStruct');
716 }
717
718 $remoteId = $locationCreateStruct->remoteId;
719 if (null === $remoteId) {
720 $remoteId = $this->getUniqueHash($locationCreateStruct);
721 } else {
722 try {
723 $this->locationHandler->loadByRemoteId($remoteId);
724 throw new InvalidArgumentException(
725 '$locationCreateStructs',
726 "Another Location with remoteId '{$remoteId}' exists"
727 );
728 } catch (NotFoundException $e) {
729 // Do nothing
730 }
731 }
732
733 return new SPILocationCreateStruct(
734 [
735 'priority' => $locationCreateStruct->priority,
736 'hidden' => $locationCreateStruct->hidden,
737 // If we declare the new Location as hidden, it is automatically invisible
738 // Otherwise it picks up visibility from parent Location and Content
739 // Note: There is no need to check for hidden status of parent, as hidden Location
740 // is always invisible as well
741 'invisible' => ($locationCreateStruct->hidden === true || $parentLocation->invisible || $isContentHidden),
742 'remoteId' => $remoteId,
743 'contentId' => $contentId,
744 'contentVersion' => $contentVersionNo,
745 // pathIdentificationString will be set in storage
746 'pathIdentificationString' => null,
747 'mainLocationId' => $mainLocation,
748 'sortField' => $locationCreateStruct->sortField !== null ? $locationCreateStruct->sortField : Location::SORT_FIELD_NAME,
749 'sortOrder' => $locationCreateStruct->sortOrder !== null ? $locationCreateStruct->sortOrder : Location::SORT_ORDER_ASC,
750 'parentId' => $locationCreateStruct->parentLocationId,
751 ]
752 );
753 }
754
762 public function isValidLocationSortField($sortField)
763 {
764 switch ($sortField) {
765 case APILocation::SORT_FIELD_PATH:
766 case APILocation::SORT_FIELD_PUBLISHED:
767 case APILocation::SORT_FIELD_MODIFIED:
768 case APILocation::SORT_FIELD_SECTION:
769 case APILocation::SORT_FIELD_DEPTH:
770 case APILocation::SORT_FIELD_CLASS_IDENTIFIER:
771 case APILocation::SORT_FIELD_CLASS_NAME:
772 case APILocation::SORT_FIELD_PRIORITY:
773 case APILocation::SORT_FIELD_NAME:
774 case APILocation::SORT_FIELD_MODIFIED_SUBNODE:
775 case APILocation::SORT_FIELD_NODE_ID:
776 case APILocation::SORT_FIELD_CONTENTOBJECT_ID:
777 return true;
778 }
779
780 return false;
781 }
782
790 public function isValidLocationSortOrder($sortOrder)
791 {
792 switch ($sortOrder) {
793 case APILocation::SORT_ORDER_DESC:
794 case APILocation::SORT_ORDER_ASC:
795 return true;
796 }
797
798 return false;
799 }
800
808 public function isValidLocationPriority($priority)
809 {
810 if ($priority === null) {
811 return true;
812 }
813
814 return is_int($priority) && $priority >= self::MIN_LOCATION_PRIORITY && $priority <= self::MAX_LOCATION_PRIORITY;
815 }
816
825 public function validateTranslatedList($list, $argumentName)
826 {
827 if (!is_array($list)) {
828 throw new InvalidArgumentType($argumentName, 'array', $list);
829 }
830
831 foreach ($list as $languageCode => $translation) {
832 $this->contentLanguageHandler->loadByLanguageCode($languageCode);
833
834 if (!is_string($translation)) {
835 throw new InvalidArgumentType($argumentName . "['$languageCode']", 'string', $translation);
836 }
837 }
838 }
839
850 public function getDateTime($timestamp)
851 {
852 $dateTime = new DateTime();
853 $dateTime->setTimestamp($timestamp);
854
855 return $dateTime;
856 }
857
867 public function getUniqueHash($object)
868 {
869 return md5(uniqid(get_class($object), true));
870 }
871
879 private function isRootLocation(SPILocation $spiLocation): bool
880 {
881 return $spiLocation->id === $spiLocation->parentId;
882 }
883 }
eZ\Publish\API\Repository\Exceptions\NotFoundException
This Exception is thrown if an object referenced by an id or identifier could not be found in the rep...
Definition: API/Repository/Exceptions/NotFoundException.php:16
eZ\Publish\API\Repository\Values\ContentType\ContentType
Definition: API/Repository/Values/ContentType/ContentType.php:36
eZ\Publish\API\Repository\Values\Content\ContentInfo
Definition: API/Repository/Values/Content/ContentInfo.php:31
eZ\Publish\API\Repository\Values\Content\Content
Definition: Publish/API/Repository/Values/Content/Content.php:21
eZ\Publish\API\Repository\Values\Content\Field
Definition: API/Repository/Values/Content/Field.php:21
eZ\Publish\API\Repository\Values\Content\Location
Definition: API/Repository/Values/Content/Location.php:32
eZ\Publish\API\Repository\Values\Content\Search\SearchResult
This class represents a search result.
Definition: Content/Search/SearchResult.php:15
eZ\Publish\API\Repository\Values\Content\VersionInfo
Definition: API/Repository/Values/Content/VersionInfo.php:27
eZ\Publish\Core\Base\Exceptions\InvalidArgumentException
Invalid Argument Type Exception implementation.
Definition: Core/Base/Exceptions/InvalidArgumentException.php:20
eZ\Publish\Core\Base\Exceptions\InvalidArgumentType
Invalid Argument Type Exception implementation.
Definition: InvalidArgumentType.php:17
eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue
Invalid Argument Type Exception implementation.
Definition: Base/Exceptions/InvalidArgumentValue.php:17
eZ\Publish\Core\Repository\Helper\ContentTypeDomainMapper
ContentTypeDomainMapper is an internal service.
Definition: ContentTypeDomainMapper.php:39
eZ\Publish\Core\Repository\Helper\DomainMapper
DomainMapper is an internal service.
Definition: DomainMapper.php:44
eZ\Publish\Core\Repository\Helper\DomainMapper\buildRootLocation
buildRootLocation(SPILocation $spiLocation)
Builds API Location object for tree root.
Definition: DomainMapper.php:527
eZ\Publish\Core\Repository\Helper\DomainMapper\buildContentInfoDomainObject
buildContentInfoDomainObject(SPIContentInfo $spiContentInfo)
Builds a ContentInfo domain object from value object returned from persistence.
Definition: DomainMapper.php:373
eZ\Publish\Core\Repository\Helper\DomainMapper\buildRelationDomainObject
buildRelationDomainObject(SPIRelation $spiRelation, ContentInfo $sourceContentInfo, ContentInfo $destinationContentInfo)
Builds API Relation object from provided SPI Relation object.
Definition: DomainMapper.php:424
eZ\Publish\Core\Repository\Helper\DomainMapper\buildContentProxy
buildContentProxy(SPIContent\ContentInfo $info, array $prioritizedLanguages=[], bool $useAlwaysAvailable=true)
Builds a Content proxy object (lazy loaded, loads as soon as used).
Definition: DomainMapper.php:153
eZ\Publish\Core\Repository\Helper\DomainMapper\getDateTime
getDateTime($timestamp)
Returns \DateTime object from given $timestamp in environment timezone.
Definition: DomainMapper.php:850
eZ\Publish\Core\Repository\Helper\DomainMapper\MAX_LOCATION_PRIORITY
const MAX_LOCATION_PRIORITY
Definition: DomainMapper.php:45
eZ\Publish\Core\Repository\Helper\DomainMapper\$contentTypeDomainMapper
$contentTypeDomainMapper
Definition: DomainMapper.php:58
eZ\Publish\Core\Repository\Helper\DomainMapper\buildLocationDomainObject
buildLocationDomainObject(SPILocation $spiLocation, SPIContentInfo $contentInfo=null)
Definition: DomainMapper.php:456
eZ\Publish\Core\Repository\Helper\DomainMapper\validateTranslatedList
validateTranslatedList($list, $argumentName)
Validates given translated list $list, which should be an array of strings with language codes as key...
Definition: DomainMapper.php:825
eZ\Publish\Core\Repository\Helper\DomainMapper\__construct
__construct(ContentHandler $contentHandler, LocationHandler $locationHandler, TypeHandler $contentTypeHandler, ContentTypeDomainMapper $contentTypeDomainMapper, LanguageHandler $contentLanguageHandler, FieldTypeRegistry $fieldTypeRegistry)
Setups service with reference to repository.
Definition: DomainMapper.php:76
eZ\Publish\Core\Repository\Helper\DomainMapper\buildLocationWithContent
buildLocationWithContent(SPILocation $spiLocation, ?APIContent $content, ?SPIContentInfo $spiContentInfo=null)
Definition: DomainMapper.php:498
eZ\Publish\Core\Repository\Helper\DomainMapper\$locationHandler
$locationHandler
Definition: DomainMapper.php:52
eZ\Publish\Core\Repository\Helper\DomainMapper\buildSPILocationCreateStruct
buildSPILocationCreateStruct( $locationCreateStruct, APILocation $parentLocation, $mainLocation, $contentId, $contentVersionNo, bool $isContentHidden)
Creates an array of SPI location create structs from given array of API location create structs.
Definition: DomainMapper.php:690
eZ\Publish\Core\Repository\Helper\DomainMapper\$fieldTypeRegistry
$fieldTypeRegistry
Definition: DomainMapper.php:64
eZ\Publish\Core\Repository\Helper\DomainMapper\isRootLocation
isRootLocation(SPILocation $spiLocation)
Returns true if given location is a tree root.
Definition: DomainMapper.php:879
eZ\Publish\Core\Repository\Helper\DomainMapper\$contentHandler
$contentHandler
Definition: DomainMapper.php:49
eZ\Publish\Core\Repository\Helper\DomainMapper\getUniqueHash
getUniqueHash($object)
Creates unique hash string for given $object.
Definition: DomainMapper.php:867
eZ\Publish\Core\Repository\Helper\DomainMapper\buildContentDomainObjectFromPersistence
buildContentDomainObjectFromPersistence(SPIContent $spiContent, SPIContentType $spiContentType, array $prioritizedLanguages=[], ?string $fieldAlwaysAvailableLanguage=null)
Builds a Content domain object from value object returned from persistence.
Definition: DomainMapper.php:139
eZ\Publish\Core\Repository\Helper\DomainMapper\isValidLocationPriority
isValidLocationPriority($priority)
Checks if given $priority is valid.
Definition: DomainMapper.php:808
eZ\Publish\Core\Repository\Helper\DomainMapper\buildVersionInfoDomainObject
buildVersionInfoDomainObject(SPIVersionInfo $spiVersionInfo, array $prioritizedLanguages=[])
Builds a VersionInfo domain object from value object returned from persistence.
Definition: DomainMapper.php:323
eZ\Publish\Core\Repository\Helper\DomainMapper\buildContentDomainObject
buildContentDomainObject(SPIContent $spiContent, ContentType $contentType, array $prioritizedLanguages=[], string $fieldAlwaysAvailableLanguage=null)
Builds a Content domain object from value object.
Definition: DomainMapper.php:102
eZ\Publish\Core\Repository\Helper\DomainMapper\mapLocation
mapLocation(SPILocation $spiLocation, ContentInfo $contentInfo, APIContent $content)
Definition: DomainMapper.php:554
eZ\Publish\Core\Repository\Helper\DomainMapper\buildLocation
buildLocation(SPILocation $spiLocation, array $prioritizedLanguages=[], bool $useAlwaysAvailable=true)
Definition: DomainMapper.php:471
eZ\Publish\Core\Repository\Helper\DomainMapper\MIN_LOCATION_PRIORITY
const MIN_LOCATION_PRIORITY
Definition: DomainMapper.php:46
eZ\Publish\Core\Repository\Helper\DomainMapper\isValidLocationSortOrder
isValidLocationSortOrder($sortOrder)
Checks if given $sortOrder value is one of the defined sort order constants.
Definition: DomainMapper.php:790
eZ\Publish\Core\Repository\Helper\DomainMapper\$contentTypeHandler
$contentTypeHandler
Definition: DomainMapper.php:55
eZ\Publish\Core\Repository\Helper\DomainMapper\buildContentProxyList
buildContentProxyList(array $infoList, array $prioritizedLanguages=[], bool $useAlwaysAvailable=true)
Builds a list of Content proxy objects (lazy loaded, loads all as soon as one of them loads).
Definition: DomainMapper.php:172
eZ\Publish\Core\Repository\Helper\DomainMapper\isValidLocationSortField
isValidLocationSortField($sortField)
Checks if given $sortField value is one of the defined sort field constants.
Definition: DomainMapper.php:762
eZ\Publish\Core\Repository\Helper\DomainMapper\$contentLanguageHandler
$contentLanguageHandler
Definition: DomainMapper.php:61
eZ\Publish\Core\Repository\Helper\DomainMapper\buildLocationDomainObjectsOnSearchResult
buildLocationDomainObjectsOnSearchResult(SearchResult $result, array $languageFilter)
Build API Location and corresponding ContentInfo domain objects and apply to LocationSearchResult.
Definition: DomainMapper.php:642
eZ\Publish\Core\Repository\Helper\DomainMapper\buildDomainFields
buildDomainFields(array $spiFields, $contentType, array $prioritizedLanguages=[], string $alwaysAvailableLanguage=null)
Returns an array of domain fields created from given array of SPI fields.
Definition: DomainMapper.php:249
eZ\Publish\Core\Repository\Helper\FieldTypeRegistry
Registry for SPI FieldTypes.
Definition: Repository/Helper/FieldTypeRegistry.php:19
eZ\Publish\Core\Repository\Values\Content\ContentProxy
This class represents a (lazy loaded) proxy for a content value.
Definition: ContentProxy.php:19
eZ\Publish\Core\Repository\Values\Content\Content
Definition: Publish/Core/Repository/Values/Content/Content.php:24
eZ\Publish\Core\Repository\Values\Content\Location
This class represents a location in the repository.
Definition: Core/Repository/Values/Content/Location.php:17
eZ\Publish\Core\Repository\Values\Content\Relation
Definition: Core/Repository/Values/Content/Relation.php:23
eZ\Publish\Core\Repository\Values\Content\VersionInfo
Definition: Core/Repository/Values/Content/VersionInfo.php:29
eZ\Publish\SPI\Persistence\Content\ContentInfo
This class provides all version independent information of the content object.
Definition: SPI/Persistence/Content/ContentInfo.php:17
eZ\Publish\SPI\Persistence\Content\Location\CreateStruct
Definition: SPI/Persistence/Content/Location/CreateStruct.php:12
eZ\Publish\SPI\Persistence\Content\VersionInfo
This class holds version information data.
Definition: SPI/Persistence/Content/VersionInfo.php:15
eZ\Publish\SPI\Persistence\Content\Handler
The Content Handler interface defines content operations on the storage engine.
Definition: SPI/Persistence/Content/Handler.php:20
eZ\Publish\SPI\Persistence\Content\Language\Handler
Language Handler interface.
Definition: SPI/Persistence/Content/Language/Handler.php:15
eZ\Publish\SPI\Persistence\Content\Location\Handler
The Location Handler interface defines operations on Location elements in the storage engine.
Definition: SPI/Persistence/Content/Location/Handler.php:15
eZ\Publish\SPI\Persistence\Content\Type\Handler
Definition: SPI/Persistence/Content/Type/Handler.php:14
eZ\Publish\Core\Repository\Helper
Definition: ContentTypeDomainMapper.php:7
eZ\Publish\SPI\Persistence\Content\Location
Definition: SPI/Persistence/Content/Location/CreateStruct.php:7
eZ\Publish\SPI\Persistence\Content\Relation
Definition: SPI/Persistence/Content/Relation/CreateStruct.php:7
eZ\Publish\SPI\Persistence\Content\Type
Definition: SPI/Persistence/Content/Type/CreateStruct.php:7
eZ\Publish\SPI\Persistence\Content
Definition: SPI/Persistence/Content/ContentInfo.php:7
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.