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