‪TYPO3CMS  ‪main
DataMapper.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\Instantiator\InstantiatorInterface;
21 use Psr\EventDispatcher\EventDispatcherInterface;
52 
58 {
62  protected ‪$query;
63 
64  public function ‪__construct(
65  private readonly ‪ReflectionService $reflectionService,
66  private readonly ‪QueryObjectModelFactory $qomFactory,
67  private readonly ‪Session $persistenceSession,
68  private readonly ‪DataMapFactory $dataMapFactory,
69  private readonly ‪QueryFactoryInterface $queryFactory,
70  private readonly EventDispatcherInterface $eventDispatcher,
71  private readonly InstantiatorInterface $instantiator,
72  ) {}
73 
74  public function ‪setQuery(‪QueryInterface ‪$query): void
75  {
76  $this->query = ‪$query;
77  }
78 
89  public function ‪map($className, array $rows)
90  {
91  $objects = [];
92  foreach ($rows as $row) {
93  $objects[] = $this->‪mapSingleRow($this->‪getTargetType($className, $row), $row);
94  }
95  return $objects;
96  }
97 
107  public function ‪getTargetType($className, array $row)
108  {
109  $dataMap = $this->‪getDataMap($className);
110  $targetType = $className;
111  if ($dataMap->getRecordTypeColumnName() !== null) {
112  foreach ($dataMap->getSubclasses() as $subclassName) {
113  $recordSubtype = $this->‪getDataMap($subclassName)->‪getRecordType();
114  if ((string)$row[$dataMap->getRecordTypeColumnName()] === (string)$recordSubtype) {
115  $targetType = $subclassName;
116  break;
117  }
118  }
119  }
120  return $targetType;
121  }
122 
133  protected function ‪mapSingleRow($className, array $row)
134  {
135  // @todo: this also needs to contain the query's languageAspect with its configuration
136  // which should be changed along with https://review.typo3.org/c/Packages/TYPO3.CMS/+/75093
137  ‪$identifier = $row['uid'] . (isset($row['_LOCALIZED_UID']) ? '_' . $row['_LOCALIZED_UID'] : '');
138  if ($this->persistenceSession->hasIdentifier(‪$identifier, $className)) {
139  $object = $this->persistenceSession->getObjectByIdentifier(‪$identifier, $className);
140  } else {
141  $object = $this->‪createEmptyObject($className);
142  $this->persistenceSession->registerObject($object, ‪$identifier);
143  $this->‪thawProperties($object, $row);
144  $event = new AfterObjectThawedEvent($object, $row);
145  $this->eventDispatcher->dispatch($event);
146  $object->_memorizeCleanState();
147  $this->persistenceSession->registerReconstitutedEntity($object);
148  }
149  return $object;
150  }
151 
164  protected function ‪createEmptyObject(string $className): DomainObjectInterface
165  {
166  // Note: The class_implements() function also invokes autoload to assure that the interfaces
167  // and the class are loaded. Would end up with __PHP_Incomplete_Class without it.
168  if (!in_array(DomainObjectInterface::class, class_implements($className) ?: [])) {
169  throw new InvalidClassException('Cannot create empty instance of the class "' . $className
170  . '" because it does not implement the TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface.', 1234386924);
171  }
172  // Use GU::getClassName() to obey class implementation overrides.
173  $object = $this->instantiator->instantiate(GeneralUtility::getClassName($className));
174  if (is_callable($callable = [$object, 'initializeObject'])) {
175  $callable();
176  }
177  return $object;
178  }
179 
187  protected function ‪thawProperties(DomainObjectInterface $object, array $row)
188  {
189  $className = get_class($object);
190  $classSchema = $this->reflectionService->getClassSchema($className);
191  $dataMap = $this->‪getDataMap($className);
192  $object->_setProperty(‪AbstractDomainObject::PROPERTY_UID, (int)$row['uid']);
193  $object->_setProperty(‪AbstractDomainObject::PROPERTY_PID, (int)($row['pid'] ?? 0));
194  $object->_setProperty(‪AbstractDomainObject::PROPERTY_LOCALIZED_UID, (int)$row['uid']);
195  $object->_setProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID, (int)$row['uid']);
196  if ($dataMap->getLanguageIdColumnName() !== null) {
197  $object->_setProperty(‪AbstractDomainObject::PROPERTY_LANGUAGE_UID, (int)($row[$dataMap->getLanguageIdColumnName()] ?? 0));
198  if (isset($row['_LOCALIZED_UID'])) {
199  $object->_setProperty(‪AbstractDomainObject::PROPERTY_LOCALIZED_UID, (int)$row['_LOCALIZED_UID']);
200  }
201  }
202  if (!empty($row['_ORIG_uid']) && !empty(‪$GLOBALS['TCA'][$dataMap->getTableName()]['ctrl']['versioningWS'])) {
203  $object->_setProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID, (int)$row['_ORIG_uid']);
204  }
205  foreach ($classSchema->getDomainObjectProperties() as $property) {
206  $propertyName = $property->getName();
207  if (!$dataMap->isPersistableProperty($propertyName)) {
208  continue;
209  }
210  $columnMap = $dataMap->getColumnMap($propertyName);
211  if (!$columnMap instanceof ColumnMap) {
212  continue;
213  }
214 
215  $columnName = $columnMap->‪getColumnName();
216  if (!isset($row[$columnName])) {
217  continue;
218  }
219 
220  $propertyValue = $row[$columnName];
221 
222  $nonProxyPropertyTypes = $property->getFilteredTypes([$property, 'filterLazyLoadingProxyAndLazyObjectStorage']);
223  if ($nonProxyPropertyTypes === []) {
224  throw new UnknownPropertyTypeException(
225  'The type of property ' . $className . '::' . $propertyName . ' could not be identified, therefore the desired value (' .
226  var_export($propertyValue, true) . ') cannot be mapped onto it. The type of a class property is usually defined via property types or php doc blocks. ' .
227  'Make sure the property has a property type or valid @var tag set which defines the type.',
228  1579965021
229  );
230  }
231 
232  if (count($nonProxyPropertyTypes) > 1) {
233  throw new UnknownPropertyTypeException(
234  'The type of property ' . $className . '::' . $propertyName . ' could not be identified because the property is defined as union or intersection type, therefore the desired value (' .
235  var_export($propertyValue, true) . ') cannot be mapped onto it. Make sure to use only a single type.',
236  1660215701
237  );
238  }
239 
240  $primaryType = $nonProxyPropertyTypes[0];
241 
242  $propertyType = $primaryType->getBuiltinType();
243  $propertyClassName = $primaryType->getClassName();
244 
245  $propertyValue = match ($propertyType) {
246  'int', 'integer' => (int)$propertyValue,
247  'bool', 'boolean' => (bool)$propertyValue,
248  'float' => (float)$propertyValue,
249  'string' => (string)$propertyValue,
250  'array' => null, // $this->mapArray($propertyValue); // Not supported, yet!
251  'object' => $this->‪thawObjectProperty($property, $columnMap, $object, $propertyName, $propertyValue, $propertyClassName),
252  default => null,
253  };
254 
255  if ($propertyValue !== null || $property->isNullable()) {
256  $object->_setProperty($propertyName, $propertyValue);
257  }
258  }
259  }
260 
265  private function ‪thawObjectProperty(
266  Property $propertySchema,
267  ColumnMap $columnMap,
268  DomainObjectInterface $parent,
269  string $propertyName,
270  mixed $propertyValue,
271  ?string $targetClassName
272  ): ?object {
273  if ($targetClassName === null) {
274  return null;
275  }
276 
277  if (is_subclass_of($targetClassName, \BackedEnum::class)) {
278  return $propertySchema->isNullable()
279  ? $targetClassName::tryFrom($propertyValue)
280  : $targetClassName::from($propertyValue);
281  }
282 
283  if (in_array($targetClassName, [\SplObjectStorage::class, ObjectStorage::class], true)) {
284  return $this->‪mapResultToPropertyValue(
285  $parent,
286  $propertyName,
287  $this->‪fetchRelated($parent, $propertyName, $propertyValue)
288  );
289  }
290 
291  if (is_subclass_of($targetClassName, \DateTimeInterface::class)) {
292  return $this->‪mapDateTime(
293  $propertyValue,
294  $columnMap->getDateTimeStorageFormat(),
295  $targetClassName
296  );
297  }
298 
299  if (‪TypeHandlingUtility::isCoreType($targetClassName)) {
300  return $this->‪mapCoreType($targetClassName, $propertyValue);
301  }
302 
303  return $this->‪mapObjectToClassProperty(
304  $parent,
305  $propertyName,
306  $propertyValue
307  );
308  }
309 
317  protected function ‪mapCoreType($type, $value)
318  {
319  return new $type($value);
320  }
321 
331  protected function ‪mapDateTime($value, $storageFormat = null, $targetType = \DateTime::class)
332  {
333  $dateTimeTypes = ‪QueryHelper::getDateTimeTypes();
334 
335  // Invalid values are converted to NULL
336  if (empty($value) || $value === '0000-00-00' || $value === '0000-00-00 00:00:00' || $value === '00:00:00') {
337  return null;
338  }
339  if (!in_array($storageFormat, $dateTimeTypes, true)) {
340  // Integer timestamps are also stored "as is" in the database, but are UTC by definition,
341  // so we convert the timestamp to an ISO representation.
342  $value = date('c', (int)$value);
343  }
344  // All date/datetime/time values are stored in the database "as is", independent of any time zone information.
345  // It is therefore only important to use the same time zone in PHP when storing and retrieving the values.
346  return GeneralUtility::makeInstance($targetType, $value);
347  }
348 
358  public function ‪fetchRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $enableLazyLoading = true)
359  {
360  $property = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
361  if ($enableLazyLoading && $property->isLazy()) {
362  if ($property->isObjectStorageType()) {
363  $result = GeneralUtility::makeInstance(LazyObjectStorage::class, $parentObject, $propertyName, $fieldValue, $this);
364  } elseif (empty($fieldValue)) {
365  $result = null;
366  } else {
367  $result = GeneralUtility::makeInstance(LazyLoadingProxy::class, $parentObject, $propertyName, $fieldValue, $this);
368  }
369  } else {
370  $result = $this->‪fetchRelatedEager($parentObject, $propertyName, $fieldValue);
371  }
372  return $result;
373  }
374 
383  protected function ‪fetchRelatedEager(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
384  {
385  return $fieldValue === '' ? $this->‪getEmptyRelationValue($parentObject, $propertyName) : $this->‪getNonEmptyRelationValue($parentObject, $propertyName, $fieldValue);
386  }
387 
392  protected function ‪getEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName)
393  {
394  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
395  $relatesToOne = $columnMap->‪getTypeOfRelation() == Relation::HAS_ONE;
396  return $relatesToOne ? null : [];
397  }
398 
404  protected function ‪getNonEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
405  {
406  ‪$query = $this->‪getPreparedQuery($parentObject, $propertyName, $fieldValue);
407  return ‪$query->‪execute();
408  }
409 
417  protected function ‪getPreparedQuery(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
418  {
419  $dataMap = $this->‪getDataMap(get_class($parentObject));
420  $columnMap = $dataMap->getColumnMap($propertyName);
421  $type = $this->‪getType(get_class($parentObject), $propertyName);
422  ‪$query = $this->queryFactory->create($type);
423  if ($this->query && ‪$query instanceof Query) {
424  ‪$query->setParentQuery($this->query);
425  }
428 
429  $languageAspect = ‪$query->‪getQuerySettings()->‪getLanguageAspect();
430  $languageUid = $languageAspect->getContentId();
431  if ($this->query) {
432  $languageAspect = $this->query->getQuerySettings()->getLanguageAspect();
433  $languageUid = $languageAspect->getContentId();
434  if ($dataMap->getLanguageIdColumnName() !== null && !$this->query->getQuerySettings()->getRespectSysLanguage()) {
435  //pass language of parent record to child objects, so they can be overlaid correctly in case
436  //e.g. findByUid is used.
437  //the languageUid is used for getRecordOverlay later on, despite RespectSysLanguage being false
438  $parentLanguageUid = (int)$parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_LANGUAGE_UID);
439  // do not override the language when the parent language uid is set to all languages (-1)
440  if ($parentLanguageUid !== -1) {
441  $languageUid = $parentLanguageUid;
442  }
443  }
444  }
445 
446  // we always want to overlay relations as most of the time they are stored in db using default language uids
447  $languageAspect = new LanguageAspect(
448  $languageUid,
449  $languageUid,
450  $languageAspect->getOverlayType() === ‪LanguageAspect::OVERLAYS_OFF ? ‪LanguageAspect::OVERLAYS_MIXED : $languageAspect->getOverlayType()
451  );
453 
454  if ($columnMap->getTypeOfRelation() === Relation::HAS_MANY) {
455  if (null !== ‪$orderings = $this->getOrderingsForColumnMap($columnMap)) {
457  }
458  } elseif ($columnMap->getTypeOfRelation() === Relation::HAS_AND_BELONGS_TO_MANY) {
459  ‪$query->‪setSource($this->‪getSource($parentObject, $propertyName));
460  if ($columnMap->getChildSortByFieldName() !== null) {
461  ‪$query->‪setOrderings([$columnMap->getChildSortByFieldName() => ‪QueryInterface::ORDER_ASCENDING]);
462  }
463  }
464  ‪$query->‪matching($this->‪getConstraint(‪$query, $parentObject, $propertyName, $fieldValue, (array)$columnMap->getRelationTableMatchFields()));
465  return ‪$query;
466  }
467 
474  public function getOrderingsForColumnMap(ColumnMap $columnMap): array|null
475  {
476  if ($columnMap->getChildSortByFieldName() !== null) {
477  return [$columnMap->getChildSortByFieldName() => ‪QueryInterface::ORDER_ASCENDING];
478  }
479 
480  if ($columnMap->getChildTableDefaultSortings() === null) {
481  return null;
482  }
483 
485  ‪$fields = ‪QueryHelper::parseOrderBy($columnMap->getChildTableDefaultSortings());
486  foreach (‪$fields as $field) {
487  $fieldName = $field[0] ?? null;
488  if ($fieldName === null) {
489  continue;
490  }
491 
492  if (($fieldOrdering = $field[1] ?? null) === null) {
494  continue;
495  }
496 
497  $fieldOrdering = strtoupper($fieldOrdering);
498  if (!in_array($fieldOrdering, [‪QueryInterface::ORDER_ASCENDING, ‪QueryInterface::ORDER_DESCENDING], true)) {
500  continue;
501  }
502 
503  ‪$orderings[$fieldName] = $fieldOrdering;
504  }
505  return ‪$orderings !== [] ? ‪$orderings : null;
506  }
507 
516  protected function ‪getConstraint(‪QueryInterface ‪$query, ‪DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $relationTableMatchFields = [])
517  {
518  $dataMap = $this->‪getDataMap(get_class($parentObject));
519  $columnMap = $dataMap->getColumnMap($propertyName);
520  $workspaceId = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('workspace', 'id');
521  if ($columnMap && $workspaceId > 0) {
522  $resolvedRelationIds = $this->‪resolveRelationValuesOfField($dataMap, $columnMap, $parentObject, $fieldValue, $workspaceId);
523  } else {
524  $resolvedRelationIds = [];
525  }
526  // Work with the UIDs directly in a workspace
527  if (!empty($resolvedRelationIds)) {
528  if (‪$query->‪getSource() instanceof Persistence\Generic\Qom\JoinInterface) {
529  $constraint = ‪$query->‪in(‪$query->‪getSource()->getJoinCondition()->getProperty1Name(), $resolvedRelationIds);
530  // When querying MM relations directly, Typo3DbQueryParser uses enableFields and thus, filters
531  // out versioned records by default. However, we directly query versioned UIDs here, so we want
532  // to include the versioned records explicitly.
533  if ($columnMap->getTypeOfRelation() === Relation::HAS_AND_BELONGS_TO_MANY) {
536  }
537  } else {
538  $constraint = ‪$query->‪in('uid', $resolvedRelationIds);
539  }
540  if ($columnMap->getParentTableFieldName() !== null) {
541  $constraint = ‪$query->‪logicalAnd(
542  $constraint,
543  ‪$query->‪equals($columnMap->getParentTableFieldName(), $dataMap->getTableName())
544  );
545  }
546  } elseif ($columnMap->getParentKeyFieldName() !== null) {
547  $value = $parentObject;
548  // If this a MM relation, and MM relations do not know about workspaces, the MM relations always point to the
549  // versioned record, so this must be taken into account here and the versioned record's UID must be used.
550  if ($columnMap->getTypeOfRelation() === Relation::HAS_AND_BELONGS_TO_MANY) {
551  // The versioned UID is used ideally the version ID of a translated record, so this takes precedence over the localized UID
552  if ($value->_hasProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) && $value->_getProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) > 0 && $value->_getProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) !== $value->getUid()) {
554  }
555  }
556  $constraint = ‪$query->‪equals($columnMap->getParentKeyFieldName(), $value);
557  if ($columnMap->getParentTableFieldName() !== null) {
558  $constraint = ‪$query->‪logicalAnd(
559  $constraint,
560  ‪$query->‪equals($columnMap->getParentTableFieldName(), $dataMap->getTableName())
561  );
562  }
563  } else {
564  // Note: $fieldValue is annotated as a string, but this cannot be trusted as the callers do not ensure this.
565  $constraint = ‪$query->‪in('uid', ‪GeneralUtility::intExplode(',', (string)$fieldValue));
566  }
567  if (!empty($relationTableMatchFields)) {
568  foreach ($relationTableMatchFields as $relationTableMatchFieldName => $relationTableMatchFieldValue) {
569  $constraint = ‪$query->‪logicalAnd($constraint, ‪$query->‪equals($relationTableMatchFieldName, $relationTableMatchFieldValue));
570  }
571  }
572  return $constraint;
573  }
574 
592  protected function ‪resolveRelationValuesOfField(DataMap $dataMap, ColumnMap $columnMap, DomainObjectInterface $parentObject, $fieldValue, int $workspaceId)
593  {
594  $parentId = $parentObject->getUid();
595  // versionedUid in a multi-language setup is the overlaid versioned AND translated ID
596  if ($parentObject->_hasProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) && $parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) > 0 && $parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID) !== $parentId) {
597  $parentId = $parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_VERSIONED_UID);
598  } elseif ($parentObject->_hasProperty(‪AbstractDomainObject::PROPERTY_LANGUAGE_UID) && $parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_LANGUAGE_UID) > 0) {
599  $parentId = $parentObject->_getProperty(‪AbstractDomainObject::PROPERTY_LOCALIZED_UID);
600  }
601  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
602  $relationHandler->setWorkspaceId($workspaceId);
603  $relationHandler->setUseLiveReferenceIds(true);
604  $relationHandler->setUseLiveParentIds(true);
605  $tableName = $dataMap->getTableName();
606  $fieldName = $columnMap->getColumnName();
607  $fieldConfiguration = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? null;
608  if (!is_array($fieldConfiguration)) {
609  return [];
610  }
611  $relationHandler->start(
612  $fieldValue,
613  $fieldConfiguration['allowed'] ?? $fieldConfiguration['foreign_table'] ?? '',
614  $fieldConfiguration['MM'] ?? '',
615  $parentId,
616  $tableName,
617  $fieldConfiguration
618  );
619  $relationHandler->processDeletePlaceholder();
620  $relatedUids = [];
621  if (!empty($relationHandler->tableArray)) {
622  $relatedUids = reset($relationHandler->tableArray);
623  }
624  return $relatedUids;
625  }
626 
633  protected function ‪getSource(DomainObjectInterface $parentObject, $propertyName)
634  {
635  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
636  $left = $this->qomFactory->selector(null, $columnMap->getRelationTableName());
637  $childClassName = $this->‪getType(get_class($parentObject), $propertyName);
638  $right = $this->qomFactory->selector($childClassName, $columnMap->getChildTableName());
639  $joinCondition = $this->qomFactory->equiJoinCondition($columnMap->getRelationTableName(), $columnMap->getChildKeyFieldName(), $columnMap->getChildTableName(), 'uid');
640  $source = $this->qomFactory->join($left, $right, ‪Query::JCR_JOIN_TYPE_INNER, $joinCondition);
641  return $source;
642  }
643 
659  protected function ‪mapObjectToClassProperty(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
660  {
661  if ($this->‪propertyMapsByForeignKey($parentObject, $propertyName)) {
662  $result = $this->‪fetchRelated($parentObject, $propertyName, $fieldValue);
663  return $this->‪mapResultToPropertyValue($parentObject, $propertyName, $result);
664  }
665 
666  if (empty($fieldValue)) {
667  return $this->‪getEmptyRelationValue($parentObject, $propertyName);
668  }
669 
670  $primaryType = $this->reflectionService
671  ->getClassSchema(get_class($parentObject))
672  ->getProperty($propertyName)
673  ->getPrimaryType();
674 
675  if ($primaryType === null) {
676  throw ‪NoPropertyTypesException::create($parentObject::class, $propertyName);
677  }
678 
679  $className = $primaryType->getClassName();
680  if (!is_string($className)) {
681  throw new \LogicException(
682  sprintf('Evaluated type of class property %s::%s is not a class name. Check the type declaration of the property to use a valid class name.', $parentObject::class, $propertyName),
683  1660217846
684  );
685  }
686 
687  if ($this->persistenceSession->hasIdentifier((string)$fieldValue, $className)) {
688  return $this->persistenceSession->getObjectByIdentifier((string)$fieldValue, $className);
689  }
690 
691  $result = $this->‪fetchRelated($parentObject, $propertyName, $fieldValue);
692  return $this->‪mapResultToPropertyValue($parentObject, $propertyName, $result);
693  }
694 
701  protected function ‪propertyMapsByForeignKey(DomainObjectInterface $parentObject, $propertyName)
702  {
703  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
704  return $columnMap->‪getParentKeyFieldName() !== null;
705  }
706 
714  public function ‪mapResultToPropertyValue(DomainObjectInterface $parentObject, $propertyName, $result)
715  {
716  $propertyValue = null;
717  if ($result instanceof LoadingStrategyInterface) {
718  $propertyValue = $result;
719  } else {
720  $property = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
721  $primaryType = $property->getPrimaryType();
722 
723  if ($primaryType === null) {
724  throw ‪NoPropertyTypesException::create($parentObject::class, $propertyName);
725  }
726 
727  if ($primaryType->getBuiltinType() === 'array' || in_array($primaryType->getClassName(), [\ArrayObject::class, \SplObjectStorage::class, ObjectStorage::class], true)) {
728  $objects = [];
729  foreach ($result as $value) {
730  $objects[] = $value;
731  }
732  if ($primaryType->getClassName() === \ArrayObject::class) {
733  $propertyValue = new \ArrayObject($objects);
734  } elseif ($primaryType->getClassName() === ObjectStorage::class) {
735  $propertyValue = new ObjectStorage();
736  foreach ($objects as $object) {
737  $propertyValue->attach($object);
738  }
739  $propertyValue->_memorizeCleanState();
740  } else {
741  $propertyValue = $objects;
742  }
743  } elseif (strpbrk((string)$primaryType->getClassName(), '_\\') !== false) {
744  // @todo: check the strpbrk function call. Seems to be a check for Tx_Foo_Bar style class names
745  if ($result instanceof QueryResultInterface) {
746  $propertyValue = $result->getFirst();
747  } else {
748  $propertyValue = $result;
749  }
750  }
751  }
752  return $propertyValue;
753  }
754 
763  public function ‪countRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
764  {
765  ‪$query = $this->‪getPreparedQuery($parentObject, $propertyName, $fieldValue);
766  return ‪$query->‪execute()->count();
767  }
768 
776  public function ‪getDataMap($className)
777  {
778  if (!is_string($className) || $className === '') {
779  throw new Exception('No class name was given to retrieve the Data Map for.', 1251315965);
780  }
781  return $this->dataMapFactory->buildDataMap($className);
782  }
783 
790  public function ‪convertClassNameToTableName($className)
791  {
792  return $this->‪getDataMap($className)->‪getTableName();
793  }
794 
802  public function ‪convertPropertyNameToColumnName($propertyName, $className = null)
803  {
804  if (!empty($className)) {
805  $dataMap = $this->‪getDataMap($className);
806  if ($dataMap !== null) {
807  $columnMap = $dataMap->getColumnMap($propertyName);
808  if ($columnMap !== null) {
809  return $columnMap->getColumnName();
810  }
811  }
812  }
814  }
815 
824  public function ‪getType($parentClassName, $propertyName)
825  {
826  try {
827  $primaryType = $this->reflectionService
828  ->getClassSchema($parentClassName)
829  ->getProperty($propertyName)
830  ->getPrimaryType();
831 
832  if ($primaryType === null) {
833  throw ‪NoPropertyTypesException::create($parentClassName, $propertyName);
834  }
835 
836  if ($primaryType->isCollection() && $primaryType->getCollectionValueTypes() !== []) {
837  $primaryCollectionValueType = $primaryType->getCollectionValueTypes()[0];
838  return $primaryCollectionValueType->getClassName()
839  ?? $primaryCollectionValueType->getBuiltinType();
840  }
841 
842  return $primaryType->getClassName()
843  ?? $primaryType->getBuiltinType();
844  } catch (NoSuchPropertyException|NoPropertyTypesException $e) {
845  }
846 
847  throw new UnexpectedTypeException('Could not determine the child object type.', 1251315967);
848  }
849 
860  public function ‪getPlainValue(mixed $input, ?ColumnMap $columnMap = null): int|string
861  {
862  if ($input === null) {
863  return 'NULL';
864  }
865 
866  if ($input instanceof \BackedEnum) {
867  return $input->value;
868  }
869 
870  if ($input instanceof LazyLoadingProxy) {
871  $input = $input->_loadRealInstance();
872  }
873 
874  if (is_bool($input)) {
875  return (int)$input;
876  }
877 
878  if (is_int($input)) {
879  return $input;
880  }
881 
882  if ($input instanceof \DateTimeInterface) {
883  if ($columnMap !== null && $columnMap->getDateTimeStorageFormat() !== null) {
884  $storageFormat = $columnMap->getDateTimeStorageFormat();
885  return match ($storageFormat) {
886  'datetime' => $input->format('Y-m-d H:i:s'),
887  'date' => $input->format('Y-m-d'),
888  'time' => $input->format('H:i'),
889  default => throw new \InvalidArgumentException('Column map DateTime format "' . $storageFormat . '" is unknown. Allowed values are date, datetime or time.', 1395353470),
890  };
891  }
892 
893  return $input->format('U');
894  }
895 
896  if ($input instanceof DomainObjectInterface) {
897  return (int)$input->getUid();
898  }
899 
901  $plainValueArray = [];
902  foreach ($input as $inputElement) {
903  $plainValueArray[] = $this->‪getPlainValue($inputElement, $columnMap);
904  }
905  return implode(',', $plainValueArray);
906  }
907 
908  if (is_object($input)) {
909  if (‪TypeHandlingUtility::isCoreType($input) || $input instanceof \Stringable) {
910  return (string)$input;
911  }
912 
913  throw new UnexpectedTypeException('An object of class "' . get_class($input) . '" could not be converted to a plain value.', 1274799934);
914  }
915 
916  return (string)$input;
917  }
918 }
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoSuchPropertyException
Definition: NoSuchPropertyException.php:24
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:44
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\map
‪array map($className, array $rows)
Definition: DataMapper.php:88
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapDateTime
‪DateTimeInterface mapDateTime($value, $storageFormat=null, $targetType=\DateTime::class)
Definition: DataMapper.php:330
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getDateTimeStorageFormat
‪getDateTimeStorageFormat()
Definition: ColumnMap.php:222
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapResultToPropertyValue
‪mixed mapResultToPropertyValue(DomainObjectInterface $parentObject, $propertyName, $result)
Definition: DataMapper.php:713
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getLanguageAspect
‪getLanguageAspect()
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getParentKeyFieldName
‪getParentKeyFieldName()
Definition: ColumnMap.php:192
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getColumnMap
‪ColumnMap null getColumnMap($propertyName)
Definition: DataMap.php:224
‪TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface
Definition: LoadingStrategyInterface.php:21
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_MIXED
‪const OVERLAYS_MIXED
Definition: LanguageAspect.php:75
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\createEmptyObject
‪createEmptyObject(string $className)
Definition: DataMapper.php:163
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getConstraint
‪TYPO3 CMS Extbase Persistence Generic Qom ConstraintInterface getConstraint(QueryInterface $query, DomainObjectInterface $parentObject, $propertyName, $fieldValue='', $relationTableMatchFields=[])
Definition: DataMapper.php:515
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap
Definition: DataMap.php:25
‪TYPO3\CMS\Extbase\Persistence\QueryInterface
Definition: QueryInterface.php:30
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\equals
‪TYPO3 CMS Extbase Persistence Generic Qom ComparisonInterface equals($propertyName, $operand, $caseSensitive=true)
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\logicalAnd
‪logicalAnd(ConstraintInterface ... $constraints)
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:36
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility\isCoreType
‪static isCoreType($type)
Definition: TypeHandlingUtility.php:117
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getTableName
‪string getTableName()
Definition: DataMap.php:163
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setIgnoreEnableFields
‪$this setIgnoreEnableFields(bool $ignoreEnableFields)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getRecordType
‪string null getRecordType()
Definition: DataMap.php:183
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getPlainValue
‪int string getPlainValue(mixed $input, ?ColumnMap $columnMap=null)
Definition: DataMapper.php:859
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getType
‪string getType($parentClassName, $propertyName)
Definition: DataMapper.php:823
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
Definition: ColumnMap.php:27
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\UnknownPropertyTypeException
Definition: UnknownPropertyTypeException.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setLanguageAspect
‪$this setLanguageAspect(LanguageAspect $languageAspect)
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_DESCENDING
‪const ORDER_DESCENDING
Definition: QueryInterface.php:100
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getRelationTableName
‪getRelationTableName()
Definition: ColumnMap.php:172
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\convertPropertyNameToColumnName
‪string convertPropertyNameToColumnName($propertyName, $className=null)
Definition: DataMapper.php:801
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\setOrderings
‪TYPO3 CMS Extbase Persistence QueryInterface setOrderings(array $orderings)
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_PID
‪const PROPERTY_PID
Definition: AbstractDomainObject.php:33
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
Definition: QueryObjectModelFactory.php:30
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\execute
‪TYPO3 CMS Extbase Persistence QueryResultInterface object[] execute($returnRawQueryResult=false)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getChildTableDefaultSortings
‪getChildTableDefaultSortings()
Definition: ColumnMap.php:152
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getChildTableName
‪getChildTableName()
Definition: ColumnMap.php:142
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getEmptyRelationValue
‪array null getEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:391
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapObjectToClassProperty
‪mixed mapObjectToClassProperty(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
Definition: DataMapper.php:658
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getQuerySettings
‪QuerySettingsInterface getQuerySettings()
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getTargetType
‪string getTargetType($className, array $row)
Definition: DataMapper.php:106
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
Definition: DataMapper.php:58
‪TYPO3\CMS\Core\Utility\GeneralUtility\camelCaseToLowerCaseUnderscored
‪static string camelCaseToLowerCaseUnderscored($string)
Definition: GeneralUtility.php:683
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_getProperty
‪_getProperty(string $propertyName)
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_LOCALIZED_UID
‪const PROPERTY_LOCALIZED_UID
Definition: AbstractDomainObject.php:34
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoPropertyTypesException
Definition: NoPropertyTypesException.php:24
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\propertyMapsByForeignKey
‪bool propertyMapsByForeignKey(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:700
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidClassException
Definition: InvalidClassException.php:25
‪TYPO3\CMS\Extbase\Persistence\ObjectStorage
Definition: ObjectStorage.php:34
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory
Definition: DataMapFactory.php:34
‪TYPO3\CMS\Extbase\Reflection\ReflectionService
Definition: ReflectionService.php:28
‪TYPO3\CMS\Extbase\Event\Persistence\AfterObjectThawedEvent
Definition: AfterObjectThawedEvent.php:26
‪TYPO3\CMS\Extbase\Persistence
Definition: ClassesConfiguration.php:18
‪TYPO3\CMS\Extbase\Exception
Definition: Exception.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$fields
‪$fields
Definition: DataMapper.php:484
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\in
‪ComparisonInterface in($propertyName, $operand)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapSingleRow
‪object mapSingleRow($className, array $row)
Definition: DataMapper.php:132
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getColumnName
‪getColumnName()
Definition: ColumnMap.php:132
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Property
Definition: Property.php:30
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$orderings
‪foreach($fields as $field) return $orderings
Definition: DataMapper.php:504
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_ASCENDING
‪const ORDER_ASCENDING
Definition: QueryInterface.php:99
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\thawProperties
‪thawProperties(DomainObjectInterface $object, array $row)
Definition: DataMapper.php:186
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility
Definition: TypeHandlingUtility.php:29
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getTypeOfRelation
‪getTypeOfRelation()
Definition: ColumnMap.php:127
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Extbase\Persistence\Generic\Query\JCR_JOIN_TYPE_INNER
‪const JCR_JOIN_TYPE_INNER
Definition: Query.php:45
‪TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface
Definition: QueryFactoryInterface.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getChildSortByFieldName
‪getChildSortByFieldName()
Definition: ColumnMap.php:162
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface
Definition: DomainObjectInterface.php:33
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\fetchRelatedEager
‪mixed fetchRelatedEager(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:382
‪TYPO3\CMS\Core\Database\Query\QueryHelper\getDateTimeTypes
‪static array getDateTimeTypes()
Definition: QueryHelper.php:211
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
Definition: AbstractDomainObject.php:31
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\matching
‪TYPO3 CMS Extbase Persistence QueryInterface matching($constraint)
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\getUid
‪getUid()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\setSource
‪setSource(SourceInterface $source)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$orderings
‪if($columnMap->getChildTableDefaultSortings()===null) $orderings
Definition: DataMapper.php:483
‪TYPO3\CMS\Extbase\Persistence\Generic\Session
Definition: Session.php:27
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getParentTableFieldName
‪getParentTableFieldName()
Definition: ColumnMap.php:202
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_LANGUAGE_UID
‪const PROPERTY_LANGUAGE_UID
Definition: AbstractDomainObject.php:35
‪TYPO3\CMS\Extbase\Persistence\QueryResultInterface
Definition: QueryResultInterface.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception
Definition: InconsistentQuerySettingsException.php:18
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_VERSIONED_UID
‪const PROPERTY_VERSIONED_UID
Definition: AbstractDomainObject.php:36
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\convertClassNameToTableName
‪string convertClassNameToTableName($className)
Definition: DataMapper.php:789
‪TYPO3\CMS\Core\Context\LanguageAspect
Definition: LanguageAspect.php:57
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\countRelated
‪int countRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:762
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_setProperty
‪_setProperty(string $propertyName, mixed $value)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\fetchRelated
‪TYPO3 CMS Extbase Persistence Generic LazyObjectStorage Persistence QueryResultInterface fetchRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue='', $enableLazyLoading=true)
Definition: DataMapper.php:357
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getChildKeyFieldName
‪getChildKeyFieldName()
Definition: ColumnMap.php:212
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnexpectedTypeException
Definition: UnexpectedTypeException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\thawObjectProperty
‪thawObjectProperty(Property $propertySchema, ColumnMap $columnMap, DomainObjectInterface $parent, string $propertyName, mixed $propertyValue, ?string $targetClassName)
Definition: DataMapper.php:264
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility\isValidTypeForMultiValueComparison
‪static isValidTypeForMultiValueComparison($value)
Definition: TypeHandlingUtility.php:147
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\NonExistentPropertyException
Definition: NonExistentPropertyException.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy
Definition: LazyLoadingProxy.php:30
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getNonEmptyRelationValue
‪Persistence QueryResultInterface getNonEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
Definition: DataMapper.php:403
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\resolveRelationValuesOfField
‪array false mixed resolveRelationValuesOfField(DataMap $dataMap, ColumnMap $columnMap, DomainObjectInterface $parentObject, $fieldValue, int $workspaceId)
Definition: DataMapper.php:591
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$query
‪QueryInterface null $query
Definition: DataMapper.php:61
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoPropertyTypesException\create
‪static create(string $className, string $propertyName)
Definition: NoPropertyTypesException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Query
Definition: Query.php:41
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setEnableFieldsToBeIgnored
‪$this setEnableFieldsToBeIgnored(array $enableFieldsToBeIgnored)
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_OFF
‪const OVERLAYS_OFF
Definition: LanguageAspect.php:74
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setRespectStoragePage
‪$this setRespectStoragePage(bool $respectStoragePage)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getPreparedQuery
‪Persistence QueryInterface getPreparedQuery(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:416
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_UID
‪const PROPERTY_UID
Definition: AbstractDomainObject.php:32
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper
‪TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage
Definition: LazyObjectStorage.php:36
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Property\isNullable
‪isNullable()
Definition: Property.php:143
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setRespectSysLanguage
‪$this setRespectSysLanguage(bool $respectSysLanguage)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:632
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\setQuery
‪setQuery(QueryInterface $query)
Definition: DataMapper.php:73
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getDataMap
‪DataMap getDataMap($className)
Definition: DataMapper.php:775
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\__construct
‪__construct(private readonly ReflectionService $reflectionService, private readonly QueryObjectModelFactory $qomFactory, private readonly Session $persistenceSession, private readonly DataMapFactory $dataMapFactory, private readonly QueryFactoryInterface $queryFactory, private readonly EventDispatcherInterface $eventDispatcher, private readonly InstantiatorInterface $instantiator,)
Definition: DataMapper.php:63
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\Relation
‪Relation
Definition: Relation.php:24
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_hasProperty
‪_hasProperty(string $propertyName)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapCoreType
‪TYPO3 CMS Core Type TypeInterface mapCoreType($type, $value)
Definition: DataMapper.php:316