2 namespace TYPO3\CMS\Extbase\Persistence\Generic\Mapper;
17 use TYPO3\CMS\Extbase\Object\Exception\CannotReconstituteObjectException;
18 use TYPO3\CMS\Extbase\Persistence;
19 use TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnexpectedTypeException;
140 public function map($className, array $rows)
143 foreach ($rows as $row) {
159 $targetType = $className;
160 if ($dataMap->getRecordTypeColumnName() !== null) {
161 foreach ($dataMap->getSubclasses() as $subclassName) {
162 $recordSubtype = $this->
getDataMap($subclassName)->getRecordType();
163 if ($row[$dataMap->getRecordTypeColumnName()] === $recordSubtype) {
164 $targetType = $subclassName;
181 if ($this->persistenceSession->hasIdentifier($row[
'uid'], $className)) {
182 $object = $this->persistenceSession->getObjectByIdentifier($row[
'uid'], $className);
185 $this->persistenceSession->registerObject($object, $row[
'uid']);
188 $object->_memorizeCleanState();
189 $this->persistenceSession->registerReconstitutedEntity($object);
201 $this->signalSlotDispatcher->dispatch(__CLASS__,
'afterMappingSingleRow', array($object));
215 if (!in_array(\TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface::class, class_implements($className))) {
217 .
'" because it does not implement the TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface.', 1234386924);
219 $object = $this->objectManager->getEmptyObject($className);
232 $className = get_class($object);
233 $classSchema = $this->reflectionService->getClassSchema($className);
237 $object->
_setProperty(
'_localizedUid', (
int)$row[
'uid']);
238 $object->
_setProperty(
'_versionedUid', (
int)$row[
'uid']);
239 if ($dataMap->getLanguageIdColumnName() !== null) {
240 $object->
_setProperty(
'_languageUid', (
int)$row[$dataMap->getLanguageIdColumnName()]);
241 if (isset($row[
'_LOCALIZED_UID'])) {
242 $object->
_setProperty(
'_localizedUid', (
int)$row[
'_LOCALIZED_UID']);
245 if (!empty($row[
'_ORIG_uid']) && !empty(
$GLOBALS[
'TCA'][$dataMap->getTableName()][
'ctrl'][
'versioningWS'])) {
246 $object->
_setProperty(
'_versionedUid', (
int)$row[
'_ORIG_uid']);
249 foreach ($properties as $propertyName => $propertyValue) {
250 if (!$dataMap->isPersistableProperty($propertyName)) {
253 $columnMap = $dataMap->getColumnMap($propertyName);
254 $columnName = $columnMap->getColumnName();
255 $propertyData = $classSchema->getProperty($propertyName);
256 $propertyValue = null;
257 if ($row[$columnName] !== null) {
258 switch ($propertyData[
'type']) {
260 $propertyValue = (int)$row[$columnName];
263 $propertyValue = (double)$row[$columnName];
266 $propertyValue = (bool)$row[$columnName];
269 $propertyValue = (string)$row[$columnName];
274 case 'SplObjectStorage':
275 case \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class:
279 $this->
fetchRelated($object, $propertyName, $row[$columnName])
283 if ($propertyData[
'type'] ===
'DateTime' || in_array(
'DateTime', class_parents($propertyData[
'type']))) {
284 $propertyValue = $this->
mapDateTime($row[$columnName], $columnMap->getDateTimeStorageFormat(), $propertyData[
'type']);
286 $propertyValue = $this->
mapCoreType($propertyData[
'type'], $row[$columnName]);
297 if ($propertyValue !== null) {
312 return new $type($value);
324 protected function mapDateTime($value, $storageFormat = null, $targetType =
'DateTime')
326 if (empty($value) || $value ===
'0000-00-00' || $value ===
'0000-00-00 00:00:00') {
329 }
elseif ($storageFormat ===
'date' || $storageFormat ===
'datetime') {
331 $utcTimeZone = new \DateTimeZone(
'UTC');
332 $utcDateTime = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($targetType, $value, $utcTimeZone);
333 $currentTimeZone = new \DateTimeZone(date_default_timezone_get());
334 return $utcDateTime->setTimezone($currentTimeZone);
336 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($targetType, date(
'c', $value));
351 $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
352 if ($enableLazyLoading ===
true && $propertyMetaData[
'lazy']) {
353 if ($propertyMetaData[
'type'] === \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class) {
354 $result = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage::class, $parentObject, $propertyName, $fieldValue);
356 if (empty($fieldValue)) {
359 $result = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy::class, $parentObject, $propertyName, $fieldValue);
388 $columnMap = $this->
getDataMap(get_class($parentObject))->getColumnMap($propertyName);
390 return $relatesToOne ? null : array();
401 $query = $this->
getPreparedQuery($parentObject, $propertyName, $fieldValue);
402 return $query->execute();
415 $columnMap = $this->
getDataMap(get_class($parentObject))->getColumnMap($propertyName);
416 $type = $this->
getType(get_class($parentObject), $propertyName);
417 $query = $this->queryFactory->create($type);
418 $query->getQuerySettings()->setRespectStoragePage(
false);
419 $query->getQuerySettings()->setRespectSysLanguage(
false);
421 if ($columnMap->getChildSortByFieldName() !== null) {
422 $query->setOrderings(array($columnMap->getChildSortByFieldName() => Persistence\QueryInterface::ORDER_ASCENDING));
425 $query->setSource($this->
getSource($parentObject, $propertyName));
426 if ($columnMap->getChildSortByFieldName() !== null) {
427 $query->setOrderings(array($columnMap->getChildSortByFieldName() => Persistence\QueryInterface::ORDER_ASCENDING));
430 $query->matching($this->
getConstraint($query, $parentObject, $propertyName, $fieldValue, $columnMap->getRelationTableMatchFields()));
446 $columnMap = $this->
getDataMap(get_class($parentObject))->getColumnMap($propertyName);
447 if ($columnMap->getParentKeyFieldName() !== null) {
448 $constraint = $query->equals($columnMap->getParentKeyFieldName(), $parentObject);
449 if ($columnMap->getParentTableFieldName() !== null) {
450 $constraint = $query->logicalAnd(
452 $query->equals($columnMap->getParentTableFieldName(), $this->
getDataMap(get_class($parentObject))->getTableName())
458 if (!empty($relationTableMatchFields)) {
459 foreach ($relationTableMatchFields as $relationTableMatchFieldName => $relationTableMatchFieldValue) {
460 $constraint = $query->logicalAnd($constraint, $query->equals($relationTableMatchFieldName, $relationTableMatchFieldValue));
475 $columnMap = $this->
getDataMap(get_class($parentObject))->getColumnMap($propertyName);
476 $left = $this->qomFactory->selector(null, $columnMap->getRelationTableName());
477 $childClassName = $this->
getType(get_class($parentObject), $propertyName);
478 $right = $this->qomFactory->selector($childClassName, $columnMap->getChildTableName());
479 $joinCondition = $this->qomFactory->equiJoinCondition($columnMap->getRelationTableName(), $columnMap->getChildKeyFieldName(), $columnMap->getChildTableName(),
'uid');
502 $result = $this->
fetchRelated($parentObject, $propertyName, $fieldValue);
505 if ($fieldValue ===
'') {
508 $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
509 if ($this->persistenceSession->hasIdentifier($fieldValue, $propertyMetaData[
'type'])) {
510 $propertyValue = $this->persistenceSession->getObjectByIdentifier($fieldValue, $propertyMetaData[
'type']);
512 $result = $this->
fetchRelated($parentObject, $propertyName, $fieldValue);
518 return $propertyValue;
530 $columnMap = $this->
getDataMap(get_class($parentObject))->getColumnMap($propertyName);
531 return ($columnMap->getParentKeyFieldName() !== null);
544 $propertyValue = null;
546 $propertyValue = $result;
548 $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
549 if (in_array($propertyMetaData[
'type'], array(
'array',
'ArrayObject',
'SplObjectStorage', \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class),
true)) {
551 foreach ($result as $value) {
554 if ($propertyMetaData[
'type'] ===
'ArrayObject') {
555 $propertyValue = new \ArrayObject($objects);
556 }
elseif (in_array($propertyMetaData[
'type'], array(\TYPO3\CMS\Extbase\Persistence\ObjectStorage::class),
true)) {
558 foreach ($objects as $object) {
559 $propertyValue->attach($object);
561 $propertyValue->_memorizeCleanState();
563 $propertyValue = $objects;
565 }
elseif (strpbrk($propertyMetaData[
'type'],
'_\\') !==
false) {
567 $propertyValue = $result->getFirst();
569 $propertyValue = $result;
573 return $propertyValue;
586 $query = $this->
getPreparedQuery($parentObject, $propertyName, $fieldValue);
587 return $query->execute()->count();
601 return $dataMap->isPersistableProperty($propertyName);
613 if (!is_string($className) || $className ===
'') {
616 if (!isset($this->dataMaps[$className])) {
617 $this->dataMaps[$className] = $this->dataMapFactory->buildDataMap($className);
619 return $this->dataMaps[$className];
630 return $this->
getDataMap($className)->getTableName();
642 if (!empty($className)) {
644 if ($dataMap !== null) {
645 $columnMap = $dataMap->getColumnMap($propertyName);
646 if ($columnMap !== null) {
647 return $columnMap->getColumnName();
651 return \TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($propertyName);
662 public function getType($parentClassName, $propertyName)
664 $propertyMetaData = $this->reflectionService->getClassSchema($parentClassName)->getProperty($propertyName);
665 if (!empty($propertyMetaData[
'elementType'])) {
666 $type = $propertyMetaData[
'elementType'];
667 }
elseif (!empty($propertyMetaData[
'type'])) {
668 $type = $propertyMetaData[
'type'];
687 public function getPlainValue($input, $columnMap = null, $parseStringValueCallback = null, array $parseStringValueCallbackParameters = array())
689 if ($input === null) {
693 $input = $input->_loadRealInstance();
696 if (is_bool($input)) {
697 $parameter = (int)$input;
698 }
elseif ($input instanceof \DateTime) {
699 if (!is_null($columnMap) && !is_null($columnMap->getDateTimeStorageFormat())) {
700 $storageFormat = $columnMap->getDateTimeStorageFormat();
701 switch ($storageFormat) {
703 $parameter = $input->format(
'Y-m-d H:i:s');
706 $parameter = $input->format(
'Y-m-d');
709 throw new \InvalidArgumentException(
'Column map DateTime format "' . $storageFormat .
'" is unknown. Allowed values are datetime or date.', 1395353470);
712 $parameter = $input->format(
'U');
715 $plainValueArray = array();
716 foreach ($input as $inputElement) {
717 $plainValueArray[] = $this->
getPlainValue($inputElement, $columnMap, $parseStringValueCallback, $parseStringValueCallbackParameters);
719 $parameter = implode(
',', $plainValueArray);
721 $parameter = (int)$input->getUid();
722 }
elseif (is_object($input)) {
724 $parameter = $this->
getPlainStringValue($input, $parseStringValueCallback, $parseStringValueCallbackParameters);
726 throw new UnexpectedTypeException(
'An object of class "' . get_class($input) .
'" could not be converted to a plain value.', 1274799934);
729 $parameter = $this->
getPlainStringValue($input, $parseStringValueCallback, $parseStringValueCallbackParameters);
745 if (is_callable($callback)) {
746 $value = call_user_func($callback, $value, $additionalParameters);
748 return (
string)$value;