‪TYPO3CMS  10.4
DataMapper.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\EventDispatcher\EventDispatcherInterface;
46 
52 {
56  protected ‪$reflectionService;
57 
61  protected ‪$qomFactory;
62 
66  protected ‪$persistenceSession;
67 
71  protected ‪$dataMapFactory;
72 
76  protected ‪$queryFactory;
77 
81  protected ‪$objectManager;
82 
86  protected ‪$eventDispatcher;
87 
91  protected ‪$query;
92 
104  public function ‪__construct(
111  EventDispatcherInterface ‪$eventDispatcher,
113  ) {
114  $this->query = ‪$query;
115  $this->reflectionService = ‪$reflectionService;
116  $this->qomFactory = ‪$qomFactory;
117  $this->persistenceSession = ‪$persistenceSession;
118  $this->dataMapFactory = ‪$dataMapFactory;
119  $this->queryFactory = ‪$queryFactory;
120  $this->objectManager = ‪$objectManager;
121  $this->eventDispatcher = ‪$eventDispatcher;
122 
123  if (‪$query !== null) {
124  trigger_error(
125  'Constructor argument $query will be removed in TYPO3 v11.0, use setQuery method instead.',
126  E_USER_DEPRECATED
127  );
128  $this->query = ‪$query;
129  }
130  }
131 
135  public function ‪setQuery(‪QueryInterface ‪$query): void
136  {
137  $this->query = ‪$query;
138  }
139 
147  public function ‪map($className, array $rows)
148  {
149  $objects = [];
150  foreach ($rows as $row) {
151  $objects[] = $this->‪mapSingleRow($this->‪getTargetType($className, $row), $row);
152  }
153  return $objects;
154  }
155 
163  public function ‪getTargetType($className, array $row)
164  {
165  $dataMap = $this->‪getDataMap($className);
166  $targetType = $className;
167  if ($dataMap->getRecordTypeColumnName() !== null) {
168  foreach ($dataMap->getSubclasses() as $subclassName) {
169  $recordSubtype = $this->‪getDataMap($subclassName)->‪getRecordType();
170  if ((string)$row[$dataMap->getRecordTypeColumnName()] === (string)$recordSubtype) {
171  $targetType = $subclassName;
172  break;
173  }
174  }
175  }
176  return $targetType;
177  }
178 
186  protected function ‪mapSingleRow($className, array $row)
187  {
188  if ($this->persistenceSession->hasIdentifier($row['uid'], $className)) {
189  $object = $this->persistenceSession->getObjectByIdentifier($row['uid'], $className);
190  } else {
191  $object = $this->‪createEmptyObject($className);
192  $this->persistenceSession->registerObject($object, $row['uid']);
193  $this->‪thawProperties($object, $row);
194  $event = new ‪AfterObjectThawedEvent($object, $row);
195  $this->eventDispatcher->dispatch($event);
196  $object->_memorizeCleanState();
197  $this->persistenceSession->registerReconstitutedEntity($object);
198  }
199  return $object;
200  }
201 
209  protected function ‪createEmptyObject($className)
210  {
211  // Note: The class_implements() function also invokes autoload to assure that the interfaces
212  // and the class are loaded. Would end up with __PHP_Incomplete_Class without it.
213  if (!in_array(DomainObjectInterface::class, class_implements($className))) {
214  throw new ‪CannotReconstituteObjectException('Cannot create empty instance of the class "' . $className
215  . '" because it does not implement the TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface.', 1234386924);
216  }
217  $object = $this->objectManager->getEmptyObject($className);
218  return $object;
219  }
220 
229  protected function ‪thawProperties(‪DomainObjectInterface $object, array $row)
230  {
231  $className = get_class($object);
232  $classSchema = $this->reflectionService->getClassSchema($className);
233  $dataMap = $this->‪getDataMap($className);
234  $object->‪_setProperty('uid', (int)$row['uid']);
235  $object->‪_setProperty('pid', (int)($row['pid'] ?? 0));
236  $object->‪_setProperty('_localizedUid', (int)$row['uid']);
237  $object->‪_setProperty('_versionedUid', (int)$row['uid']);
238  if ($dataMap->getLanguageIdColumnName() !== null) {
239  $object->‪_setProperty('_languageUid', (int)$row[$dataMap->getLanguageIdColumnName()]);
240  if (isset($row['_LOCALIZED_UID'])) {
241  $object->‪_setProperty('_localizedUid', (int)$row['_LOCALIZED_UID']);
242  }
243  }
244  if (!empty($row['_ORIG_uid']) && !empty(‪$GLOBALS['TCA'][$dataMap->getTableName()]['ctrl']['versioningWS'])) {
245  $object->‪_setProperty('_versionedUid', (int)$row['_ORIG_uid']);
246  }
247  $properties = $object->‪_getProperties();
248  foreach ($properties as $propertyName => $propertyValue) {
249  if (!$dataMap->isPersistableProperty($propertyName)) {
250  continue;
251  }
252  $columnMap = $dataMap->getColumnMap($propertyName);
253  $columnName = $columnMap->getColumnName();
254 
255  try {
256  $property = $classSchema->getProperty($propertyName);
257  } catch (NoSuchPropertyException $e) {
258  throw new NonExistentPropertyException(
259  'The type of property ' . $className . '::' . $propertyName . ' could not be identified, ' .
260  'as property ' . $propertyName . ' is unknown to the ' . ClassSchema::class . ' instance of class ' .
261  $className . '. Please make sure said property exists and that you cleared all caches to trigger ' .
262  'a new build of said ' . ClassSchema::class . ' instance.',
263  1580056272
264  );
265  }
266 
267  $propertyType = $property->getType();
268  if ($propertyType === null) {
269  throw new UnknownPropertyTypeException(
270  'The type of property ' . $className . '::' . $propertyName . ' could not be identified, therefore the desired value (' .
271  var_export($propertyValue, true) . ') cannot be mapped onto it. The type of a class property is usually defined via php doc blocks. ' .
272  'Make sure the property has a valid @var tag set which defines the type.',
273  1579965021
274  );
275  }
276  $propertyValue = null;
277  if (isset($row[$columnName])) {
278  switch ($propertyType) {
279  case 'int':
280  case 'integer':
281  $propertyValue = (int)$row[$columnName];
282  break;
283  case 'float':
284  $propertyValue = (double)$row[$columnName];
285  break;
286  case 'bool':
287  case 'boolean':
288  $propertyValue = (bool)$row[$columnName];
289  break;
290  case 'string':
291  $propertyValue = (string)$row[$columnName];
292  break;
293  case 'array':
294  // $propertyValue = $this->mapArray($row[$columnName]); // Not supported, yet!
295  break;
296  case \SplObjectStorage::class:
297  case ObjectStorage::class:
298  $propertyValue = $this->‪mapResultToPropertyValue(
299  $object,
300  $propertyName,
301  $this->‪fetchRelated($object, $propertyName, $row[$columnName])
302  );
303  break;
304  default:
305  if (is_subclass_of($propertyType, \DateTimeInterface::class)) {
306  $propertyValue = $this->‪mapDateTime(
307  $row[$columnName],
308  $columnMap->getDateTimeStorageFormat(),
309  $propertyType
310  );
311  } elseif (‪TypeHandlingUtility::isCoreType($propertyType)) {
312  $propertyValue = $this->‪mapCoreType($propertyType, $row[$columnName]);
313  } else {
314  $propertyValue = $this->‪mapObjectToClassProperty(
315  $object,
316  $propertyName,
317  $row[$columnName]
318  );
319  }
320 
321  }
322  }
323  if ($propertyValue !== null) {
324  $object->‪_setProperty($propertyName, $propertyValue);
325  }
326  }
327  }
328 
336  protected function ‪mapCoreType($type, $value)
337  {
338  return new $type($value);
339  }
340 
350  protected function ‪mapDateTime($value, $storageFormat = null, $targetType = \DateTime::class)
351  {
352  $dateTimeTypes = ‪QueryHelper::getDateTimeTypes();
353 
354  if (empty($value) || $value === '0000-00-00' || $value === '0000-00-00 00:00:00' || $value === '00:00:00') {
355  // 0 -> NULL !!!
356  return null;
357  }
358  if (in_array($storageFormat, $dateTimeTypes, true)) {
359  // native date/datetime/time values are stored in UTC
360  $utcTimeZone = new \DateTimeZone('UTC');
361  $utcDateTime = GeneralUtility::makeInstance($targetType, $value, $utcTimeZone);
362  $currentTimeZone = new \DateTimeZone(date_default_timezone_get());
363  return $utcDateTime->setTimezone($currentTimeZone);
364  }
365  // integer timestamps are local server time
366  return GeneralUtility::makeInstance($targetType, date('c', (int)$value));
367  }
368 
378  public function ‪fetchRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $enableLazyLoading = true)
379  {
380  $property = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
381  if ($enableLazyLoading === true && $property->isLazy()) {
382  if ($property->getType() === ObjectStorage::class) {
383  $result = $this->objectManager->get(LazyObjectStorage::class, $parentObject, $propertyName, $fieldValue, $this);
384  } else {
385  if (empty($fieldValue)) {
386  $result = null;
387  } else {
388  $result = $this->objectManager->get(LazyLoadingProxy::class, $parentObject, $propertyName, $fieldValue, $this);
389  }
390  }
391  } else {
392  $result = $this->‪fetchRelatedEager($parentObject, $propertyName, $fieldValue);
393  }
394  return $result;
395  }
396 
405  protected function ‪fetchRelatedEager(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
406  {
407  return $fieldValue === '' ? $this->‪getEmptyRelationValue($parentObject, $propertyName) : $this->‪getNonEmptyRelationValue($parentObject, $propertyName, $fieldValue);
408  }
409 
415  protected function ‪getEmptyRelationValue(‪DomainObjectInterface $parentObject, $propertyName)
416  {
417  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
418  $relatesToOne = $columnMap->‪getTypeOfRelation() == ‪ColumnMap::RELATION_HAS_ONE;
419  return $relatesToOne ? null : [];
420  }
421 
428  protected function ‪getNonEmptyRelationValue(‪DomainObjectInterface $parentObject, $propertyName, $fieldValue)
429  {
430  ‪$query = $this->‪getPreparedQuery($parentObject, $propertyName, $fieldValue);
431  return ‪$query->‪execute();
432  }
433 
442  protected function ‪getPreparedQuery(‪DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
443  {
444  $dataMap = $this->‪getDataMap(get_class($parentObject));
445  $columnMap = $dataMap->getColumnMap($propertyName);
446  $type = $this->‪getType(get_class($parentObject), $propertyName);
447  ‪$query = $this->queryFactory->create($type);
448  if ($this->query && ‪$query instanceof ‪Query) {
449  ‪$query->setParentQuery($this->query);
450  }
453 
454  // we always want to overlay relations as most of the time they are stored in db using default lang uids
456  if ($this->query) {
457  ‪$query->‪getQuerySettings()->‪setLanguageUid($this->query->getQuerySettings()->getLanguageUid());
458 
459  if ($dataMap->getLanguageIdColumnName() !== null && !$this->query->getQuerySettings()->getRespectSysLanguage()) {
460  //pass language of parent record to child objects, so they can be overlaid correctly in case
461  //e.g. findByUid is used.
462  //the languageUid is used for getRecordOverlay later on, despite RespectSysLanguage being false
463  $languageUid = (int)$parentObject->‪_getProperty('_languageUid');
465  }
466  }
467 
468  if ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_MANY) {
469  if ($columnMap->getChildSortByFieldName() !== null) {
470  ‪$query->‪setOrderings([$columnMap->getChildSortByFieldName() => ‪QueryInterface::ORDER_ASCENDING]);
471  }
472  } elseif ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
473  ‪$query->‪setSource($this->‪getSource($parentObject, $propertyName));
474  if ($columnMap->getChildSortByFieldName() !== null) {
475  ‪$query->‪setOrderings([$columnMap->getChildSortByFieldName() => ‪QueryInterface::ORDER_ASCENDING]);
476  }
477  }
478  ‪$query->‪matching($this->‪getConstraint(‪$query, $parentObject, $propertyName, $fieldValue, (array)$columnMap->getRelationTableMatchFields()));
479  return ‪$query;
480  }
481 
492  protected function ‪getConstraint(QueryInterface ‪$query, DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $relationTableMatchFields = [])
493  {
494  $dataMap = $this->‪getDataMap(get_class($parentObject));
495  $columnMap = $dataMap->getColumnMap($propertyName);
496  $workspaceId = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('workspace', 'id');
497  if ($columnMap && $workspaceId > 0) {
498  $resolvedRelationIds = $this->‪resolveRelationValuesOfField($dataMap, $columnMap, $parentObject, $fieldValue, $workspaceId);
499  } else {
500  $resolvedRelationIds = [];
501  }
502  // Work with the UIDs directly in a workspace
503  if (!empty($resolvedRelationIds)) {
504  if (‪$query->‪getSource() instanceof Persistence\Generic\Qom\JoinInterface) {
505  $constraint = ‪$query->‪in(‪$query->‪getSource()->getJoinCondition()->getProperty1Name(), $resolvedRelationIds);
506  // When querying MM relations directly, Typo3DbQueryParser uses enableFields and thus, filters
507  // out versioned records by default. However, we directly query versioned UIDs here, so we want
508  // to include the versioned records explicitly.
509  if ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
512  }
513  } else {
514  $constraint = ‪$query->‪in('uid', $resolvedRelationIds);
515  }
516  if ($columnMap->getParentTableFieldName() !== null) {
517  $constraint = ‪$query->‪logicalAnd(
518  $constraint,
519  ‪$query->‪equals($columnMap->getParentTableFieldName(), $dataMap->getTableName())
520  );
521  }
522  } elseif ($columnMap->getParentKeyFieldName() !== null) {
523  $value = $parentObject;
524  // If this a MM relation, and MM relations do not know about workspaces, the MM relations always point to the
525  // versioned record, so this must be taken into account here and the versioned record's UID must be used.
526  if ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
527  // The versioned UID is used ideally the version ID of a translated record, so this takes precedence over the localized UID
528  if ($value->_hasProperty('_versionedUid') && $value->_getProperty('_versionedUid') > 0 && $value->_getProperty('_versionedUid') !== $value->getUid()) {
529  $value = (int)$value->_getProperty('_versionedUid');
530  }
531  }
532  $constraint = ‪$query->‪equals($columnMap->getParentKeyFieldName(), $value);
533  if ($columnMap->getParentTableFieldName() !== null) {
534  $constraint = ‪$query->‪logicalAnd(
535  $constraint,
536  ‪$query->‪equals($columnMap->getParentTableFieldName(), $dataMap->getTableName())
537  );
538  }
539  } else {
540  $constraint = ‪$query->‪in('uid', ‪GeneralUtility::intExplode(',', $fieldValue));
541  }
542  if (!empty($relationTableMatchFields)) {
543  foreach ($relationTableMatchFields as $relationTableMatchFieldName => $relationTableMatchFieldValue) {
544  $constraint = ‪$query->‪logicalAnd($constraint, ‪$query->‪equals($relationTableMatchFieldName, $relationTableMatchFieldValue));
545  }
546  }
547  return $constraint;
548  }
549 
567  protected function ‪resolveRelationValuesOfField(DataMap $dataMap, ColumnMap $columnMap, DomainObjectInterface $parentObject, $fieldValue, int $workspaceId)
568  {
569  $parentId = $parentObject->getUid();
570  // versionedUid in a multi-language setup is the overlaid versioned AND translated ID
571  if ($parentObject->_hasProperty('_versionedUid') && $parentObject->_getProperty('_versionedUid') > 0 && $parentObject->_getProperty('_versionedUid') !== $parentId) {
572  $parentId = $parentObject->_getProperty('_versionedUid');
573  } elseif ($parentObject->_hasProperty('_languageUid') && $parentObject->_getProperty('_languageUid') > 0) {
574  $parentId = $parentObject->_getProperty('_localizedUid');
575  }
576  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
577  $relationHandler->setWorkspaceId($workspaceId);
578  $relationHandler->setUseLiveReferenceIds(true);
579  $relationHandler->setUseLiveParentIds(true);
580  $tableName = $dataMap->getTableName();
581  $fieldName = $columnMap->getColumnName();
582  $fieldConfiguration = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? null;
583  if (!is_array($fieldConfiguration)) {
584  return [];
585  }
586  $relationHandler->start(
587  $fieldValue,
588  $fieldConfiguration['allowed'] ?? $fieldConfiguration['foreign_table'] ?? '',
589  $fieldConfiguration['MM'] ?? '',
590  $parentId,
591  $tableName,
592  $fieldConfiguration
593  );
594  $relationHandler->processDeletePlaceholder();
595  $relatedUids = [];
596  if (!empty($relationHandler->tableArray)) {
597  $relatedUids = reset($relationHandler->tableArray);
598  }
599  return $relatedUids;
600  }
601 
609  protected function ‪getSource(‪DomainObjectInterface $parentObject, $propertyName)
610  {
611  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
612  $left = $this->qomFactory->selector(null, $columnMap->getRelationTableName());
613  $childClassName = $this->‪getType(get_class($parentObject), $propertyName);
614  $right = $this->qomFactory->selector($childClassName, $columnMap->getChildTableName());
615  $joinCondition = $this->qomFactory->equiJoinCondition($columnMap->getRelationTableName(), $columnMap->getChildKeyFieldName(), $columnMap->getChildTableName(), 'uid');
616  $source = $this->qomFactory->join($left, $right, ‪Query::JCR_JOIN_TYPE_INNER, $joinCondition);
617  return $source;
618  }
619 
635  protected function ‪mapObjectToClassProperty(‪DomainObjectInterface $parentObject, $propertyName, $fieldValue)
636  {
637  if ($this->‪propertyMapsByForeignKey($parentObject, $propertyName)) {
638  $result = $this->‪fetchRelated($parentObject, $propertyName, $fieldValue);
639  $propertyValue = $this->‪mapResultToPropertyValue($parentObject, $propertyName, $result);
640  } else {
641  if ($fieldValue === '') {
642  $propertyValue = $this->‪getEmptyRelationValue($parentObject, $propertyName);
643  } else {
644  $property = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
645  if ($this->persistenceSession->hasIdentifier($fieldValue, $property->getType())) {
646  $propertyValue = $this->persistenceSession->getObjectByIdentifier($fieldValue, $property->getType());
647  } else {
648  $result = $this->‪fetchRelated($parentObject, $propertyName, $fieldValue);
649  $propertyValue = $this->‪mapResultToPropertyValue($parentObject, $propertyName, $result);
650  }
651  }
652  }
653 
654  return $propertyValue;
655  }
656 
664  protected function ‪propertyMapsByForeignKey(‪DomainObjectInterface $parentObject, $propertyName)
665  {
666  $columnMap = $this->‪getDataMap(get_class($parentObject))->‪getColumnMap($propertyName);
667  return $columnMap->‪getParentKeyFieldName() !== null;
668  }
669 
678  public function ‪mapResultToPropertyValue(‪DomainObjectInterface $parentObject, $propertyName, $result)
679  {
680  $propertyValue = null;
681  if ($result instanceof ‪LoadingStrategyInterface) {
682  $propertyValue = $result;
683  } else {
684  $property = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
685  if (in_array($property->getType(), ['array', \ArrayObject::class, \SplObjectStorage::class, ObjectStorage::class], true)) {
686  $objects = [];
687  foreach ($result as $value) {
688  $objects[] = $value;
689  }
690  if ($property->getType() === \ArrayObject::class) {
691  $propertyValue = new \ArrayObject($objects);
692  } elseif ($property->getType() === ObjectStorage::class) {
693  $propertyValue = new ObjectStorage();
694  foreach ($objects as $object) {
695  $propertyValue->attach($object);
696  }
697  $propertyValue->_memorizeCleanState();
698  } else {
699  $propertyValue = $objects;
700  }
701  } elseif (strpbrk((string)$property->getType(), '_\\') !== false) {
702  // @todo: check the strpbrk function call. Seems to be a check for Tx_Foo_Bar style class names
703  if (is_object($result) && $result instanceof QueryResultInterface) {
704  $propertyValue = $result->getFirst();
705  } else {
706  $propertyValue = $result;
707  }
708  }
709  }
710  return $propertyValue;
711  }
712 
721  public function ‪countRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue = '')
722  {
723  ‪$query = $this->‪getPreparedQuery($parentObject, $propertyName, $fieldValue);
724  return ‪$query->‪execute()->count();
725  }
726 
735  public function ‪isPersistableProperty($className, $propertyName)
736  {
737  $dataMap = $this->‪getDataMap($className);
738  return $dataMap->isPersistableProperty($propertyName);
739  }
740 
748  public function ‪getDataMap($className)
749  {
750  if (!is_string($className) || $className === '') {
751  throw new ‪Exception('No class name was given to retrieve the Data Map for.', 1251315965);
752  }
753  return $this->dataMapFactory->buildDataMap($className);
754  }
755 
762  public function ‪convertClassNameToTableName($className)
763  {
764  return $this->‪getDataMap($className)->‪getTableName();
765  }
766 
774  public function ‪convertPropertyNameToColumnName($propertyName, $className = null)
775  {
776  if (!empty($className)) {
777  $dataMap = $this->‪getDataMap($className);
778  if ($dataMap !== null) {
779  $columnMap = $dataMap->getColumnMap($propertyName);
780  if ($columnMap !== null) {
781  return $columnMap->getColumnName();
782  }
783  }
784  }
786  }
787 
796  public function ‪getType($parentClassName, $propertyName)
797  {
798  try {
799  $property = $this->reflectionService->getClassSchema($parentClassName)->getProperty($propertyName);
800 
801  if ($property->getElementType() !== null) {
802  return $property->getElementType();
803  }
804 
805  if ($property->getType() !== null) {
806  return $property->getType();
807  }
808  } catch (NoSuchPropertyException $e) {
809  }
810 
811  throw new UnexpectedTypeException('Could not determine the child object type.', 1251315967);
812  }
813 
824  public function ‪getPlainValue($input, $columnMap = null)
825  {
826  if ($input === null) {
827  return 'NULL';
828  }
829  if ($input instanceof LazyLoadingProxy) {
830  $input = $input->_loadRealInstance();
831  }
832 
833  if (is_bool($input)) {
834  $parameter = (int)$input;
835  } elseif (is_int($input)) {
836  $parameter = $input;
837  } elseif ($input instanceof \DateTimeInterface) {
838  if ($columnMap !== null && $columnMap->getDateTimeStorageFormat() !== null) {
839  $storageFormat = $columnMap->getDateTimeStorageFormat();
840  $timeZoneToStore = clone $input;
841  // set to UTC to store in database
842  $timeZoneToStore->setTimezone(new \DateTimeZone('UTC'));
843  switch ($storageFormat) {
844  case 'datetime':
845  $parameter = $timeZoneToStore->format('Y-m-d H:i:s');
846  break;
847  case 'date':
848  $parameter = $timeZoneToStore->format('Y-m-d');
849  break;
850  case 'time':
851  $parameter = $timeZoneToStore->format('H:i');
852  break;
853  default:
854  throw new \InvalidArgumentException('Column map DateTime format "' . $storageFormat . '" is unknown. Allowed values are date, datetime or time.', 1395353470);
855  }
856  } else {
857  $parameter = $input->format('U');
858  }
859  } elseif ($input instanceof DomainObjectInterface) {
860  $parameter = (int)$input->getUid();
862  $plainValueArray = [];
863  foreach ($input as $inputElement) {
864  $plainValueArray[] = $this->‪getPlainValue($inputElement, $columnMap);
865  }
866  $parameter = implode(',', $plainValueArray);
867  } elseif (is_object($input)) {
869  $parameter = (string)$input;
870  } else {
871  throw new UnexpectedTypeException('An object of class "' . get_class($input) . '" could not be converted to a plain value.', 1274799934);
872  }
873  } else {
874  $parameter = (string)$input;
875  }
876  return $parameter;
877  }
878 }
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$qomFactory
‪TYPO3 CMS Extbase Persistence Generic Qom QueryObjectModelFactory $qomFactory
Definition: DataMapper.php:59
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoSuchPropertyException
Definition: NoSuchPropertyException.php:24
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\map
‪array map($className, array $rows)
Definition: DataMapper.php:139
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\getUid
‪int getUid()
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapDateTime
‪DateTimeInterface mapDateTime($value, $storageFormat=null, $targetType=\DateTime::class)
Definition: DataMapper.php:342
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapResultToPropertyValue
‪mixed mapResultToPropertyValue(DomainObjectInterface $parentObject, $propertyName, $result)
Definition: DataMapper.php:670
‪TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface
Definition: LoadingStrategyInterface.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getColumnMap
‪TYPO3 CMS Extbase Persistence Generic Mapper ColumnMap null getColumnMap($propertyName)
Definition: DataMap.php:226
‪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:484
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap
Definition: DataMap.php:23
‪TYPO3\CMS\Extbase\Persistence\QueryInterface
Definition: QueryInterface.php:29
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\equals
‪TYPO3 CMS Extbase Persistence Generic Qom ComparisonInterface equals($propertyName, $operand, $caseSensitive=true)
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:35
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getTableName
‪string getTableName()
Definition: DataMap.php:165
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap\getRecordType
‪string null getRecordType()
Definition: DataMap.php:185
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getType
‪string getType($parentClassName, $propertyName)
Definition: DataMapper.php:788
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$persistenceSession
‪TYPO3 CMS Extbase Persistence Generic Session $persistenceSession
Definition: DataMapper.php:63
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_setProperty
‪_setProperty(string $propertyName, $value)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getPlainValue
‪int string getPlainValue($input, $columnMap=null)
Definition: DataMapper.php:816
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
Definition: ColumnMap.php:28
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\UnknownPropertyTypeException
Definition: UnknownPropertyTypeException.php:23
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\convertPropertyNameToColumnName
‪string convertPropertyNameToColumnName($propertyName, $className=null)
Definition: DataMapper.php:766
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\setOrderings
‪TYPO3 CMS Extbase Persistence QueryInterface setOrderings(array $orderings)
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_getProperty
‪mixed _getProperty(string $propertyName)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_AND_BELONGS_TO_MANY
‪const RELATION_HAS_AND_BELONGS_TO_MANY
Definition: ColumnMap.php:52
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
Definition: QueryObjectModelFactory.php:27
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\execute
‪TYPO3 CMS Extbase Persistence QueryResultInterface object[] execute($returnRawQueryResult=false)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getEmptyRelationValue
‪array null getEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:407
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getColumnName
‪string getColumnName()
Definition: ColumnMap.php:215
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapObjectToClassProperty
‪mixed mapObjectToClassProperty(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
Definition: DataMapper.php:627
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getTargetType
‪string getTargetType($className, array $row)
Definition: DataMapper.php:155
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setRespectStoragePage
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setRespectStoragePage($respectStoragePage)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
Definition: DataMapper.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\camelCaseToLowerCaseUnderscored
‪static string camelCaseToLowerCaseUnderscored($string)
Definition: GeneralUtility.php:914
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\propertyMapsByForeignKey
‪bool propertyMapsByForeignKey(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:656
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_MANY
‪const RELATION_HAS_MANY
Definition: ColumnMap.php:42
‪TYPO3\CMS\Extbase\Object\ObjectManagerInterface
Definition: ObjectManagerInterface.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_ONE
‪const RELATION_HAS_ONE
Definition: ColumnMap.php:37
‪TYPO3\CMS\Extbase\Persistence\ObjectStorage
Definition: ObjectStorage.php:28
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory
Definition: DataMapFactory.php:42
‪TYPO3\CMS\Extbase\Reflection\ReflectionService
Definition: ReflectionService.php:31
‪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:26
‪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:178
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: DataMapper.php:79
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource()
‪TYPO3\CMS\Extbase\Reflection\ClassSchema
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_ASCENDING
‪const ORDER_ASCENDING
Definition: QueryInterface.php:98
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\thawProperties
‪thawProperties(DomainObjectInterface $object, array $row)
Definition: DataMapper.php:221
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility
Definition: TypeHandlingUtility.php:29
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\createEmptyObject
‪DomainObjectInterface createEmptyObject($className)
Definition: DataMapper.php:201
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$reflectionService
‪TYPO3 CMS Extbase Reflection ReflectionService $reflectionService
Definition: DataMapper.php:55
‪TYPO3\CMS\Extbase\Persistence\Generic\Query\JCR_JOIN_TYPE_INNER
‪const JCR_JOIN_TYPE_INNER
Definition: Query.php:42
‪TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface
Definition: QueryFactoryInterface.php:22
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface
Definition: DomainObjectInterface.php:29
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\fetchRelatedEager
‪mixed fetchRelatedEager(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:397
‪TYPO3\CMS\Core\Database\Query\QueryHelper\getDateTimeTypes
‪static array getDateTimeTypes()
Definition: QueryHelper.php:202
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\matching
‪TYPO3 CMS Extbase Persistence QueryInterface matching($constraint)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$queryFactory
‪TYPO3 CMS Extbase Persistence Generic QueryFactoryInterface $queryFactory
Definition: DataMapper.php:71
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\setSource
‪setSource(SourceInterface $source)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getParentKeyFieldName
‪string null getParentKeyFieldName()
Definition: ColumnMap.php:327
‪TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface\_getProperties
‪array _getProperties()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\logicalAnd
‪AndInterface logicalAnd($constraint1)
‪TYPO3\CMS\Extbase\Persistence\Generic\Session
Definition: Session.php:27
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\__construct
‪__construct(ReflectionService $reflectionService, QueryObjectModelFactory $qomFactory, Session $persistenceSession, DataMapFactory $dataMapFactory, QueryFactoryInterface $queryFactory, ObjectManagerInterface $objectManager, EventDispatcherInterface $eventDispatcher, ?QueryInterface $query=null)
Definition: DataMapper.php:96
‪TYPO3\CMS\Extbase\Persistence\QueryResultInterface
Definition: QueryResultInterface.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception
Definition: InconsistentQuerySettingsException.php:18
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility\isCoreType
‪static bool isCoreType($type)
Definition: TypeHandlingUtility.php:124
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\convertClassNameToTableName
‪string convertClassNameToTableName($className)
Definition: DataMapper.php:754
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: DataMapper.php:75
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\countRelated
‪int countRelated(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:713
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility\isValidTypeForMultiValueComparison
‪static bool isValidTypeForMultiValueComparison($value)
Definition: TypeHandlingUtility.php:158
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setRespectSysLanguage
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setRespectSysLanguage($respectSysLanguage)
‪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:370
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\isPersistableProperty
‪bool isPersistableProperty($className, $propertyName)
Definition: DataMapper.php:727
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnexpectedTypeException
Definition: UnexpectedTypeException.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\NonExistentPropertyException
Definition: NonExistentPropertyException.php:23
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getQuerySettings
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface getQuerySettings()
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setLanguageUid
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setLanguageUid($languageUid)
‪TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy
Definition: LazyLoadingProxy.php:29
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getNonEmptyRelationValue
‪Persistence QueryResultInterface getNonEmptyRelationValue(DomainObjectInterface $parentObject, $propertyName, $fieldValue)
Definition: DataMapper.php:420
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\resolveRelationValuesOfField
‪array false mixed resolveRelationValuesOfField(DataMap $dataMap, ColumnMap $columnMap, DomainObjectInterface $parentObject, $fieldValue, int $workspaceId)
Definition: DataMapper.php:559
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$query
‪QueryInterface null $query
Definition: DataMapper.php:83
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\$dataMapFactory
‪TYPO3 CMS Extbase Persistence Generic Mapper DataMapFactory $dataMapFactory
Definition: DataMapper.php:67
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static int[] intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:988
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setIgnoreEnableFields
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setIgnoreEnableFields($ignoreEnableFields)
‪TYPO3\CMS\Extbase\Persistence\Generic\Query
Definition: Query.php:38
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setLanguageOverlayMode
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setLanguageOverlayMode($languageOverlayMode)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getPreparedQuery
‪Persistence QueryInterface getPreparedQuery(DomainObjectInterface $parentObject, $propertyName, $fieldValue='')
Definition: DataMapper.php:434
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper
Definition: ColumnMap.php:18
‪TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage
Definition: LazyObjectStorage.php:30
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getTypeOfRelation
‪string getTypeOfRelation()
Definition: ColumnMap.php:199
‪TYPO3\CMS\Extbase\Object\Exception\CannotReconstituteObjectException
Definition: CannotReconstituteObjectException.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource(DomainObjectInterface $parentObject, $propertyName)
Definition: DataMapper.php:601
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\setQuery
‪setQuery(QueryInterface $query)
Definition: DataMapper.php:127
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\getDataMap
‪DataMap getDataMap($className)
Definition: DataMapper.php:740
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\setEnableFieldsToBeIgnored
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface setEnableFieldsToBeIgnored($enableFieldsToBeIgnored)
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper\mapCoreType
‪TYPO3 CMS Core Type TypeInterface mapCoreType($type, $value)
Definition: DataMapper.php:328