diff --git a/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php index 9b810638a9236dac7a8fd51ccf2674938220e513..2c698e759b87c14eafcb6785766daaa5be9ad2ca 100644 --- a/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php +++ b/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php @@ -93,6 +93,7 @@ final readonly class FluidBasedContentPreviewRenderer if ($table === 'tt_content' && !empty($row['pi_flexform'])) { $view->assign('pi_flexform_transformed', $this->flexFormService->convertFlexFormContentToArray($row['pi_flexform'])); } + // @todo Should we make sure that "record" is actually a Record object? $view->assign('record', $this->recordFactory->createResolvedRecordFromDatabaseRow($table, $row)); return $view->render(); } catch (\Exception $e) { diff --git a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php index 9338a6022dd1011b787357e252a5ceb111852e38..b6f5b1e76b4dd2a41c38df8a64382fc39dbe086d 100644 --- a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php +++ b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php @@ -115,17 +115,19 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger case 'header': break; case 'uploads': - if ($recordObj['media'] ?? false) { - $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['media']), $record); + if ($recordObj->has('media') && ($media = $recordObj->get('media'))) { + $out .= $this->linkEditContent($this->getThumbCodeUnlinked($media), $record); } break; case 'shortcut': - if (!empty($recordObj['records'])) { + if ($recordObj->has('records') && ($records = $recordObj->get('records'))) { $shortcutContent = ''; - $shortcutRecords = $recordObj['records'] instanceof \Traversable ? $recordObj['records'] : [$recordObj['records']]; + $shortcutRecords = $records instanceof \Traversable ? $records : [$records]; foreach ($shortcutRecords as $shortcutRecord) { $shortcutTableName = $shortcutRecord->getMainType(); - $shortcutRecord = $this->translateShortcutRecord($recordObj, $shortcutRecord, $shortcutTableName); + if ($recordObj instanceof Record) { + $shortcutRecord = $this->translateShortcutRecord($recordObj, $shortcutRecord, $shortcutTableName); + } $icon = $this->getIconFactory()->getIconForRecord($shortcutTableName, $shortcutRecord->toArray(), IconSize::SMALL)->render(); $icon = BackendUtility::wrapClickMenuOnIcon( $icon, @@ -168,17 +170,17 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger } break; default: - if ($recordObj['bodytext'] ?? false) { - $out .= $this->linkEditContent($this->renderText($record['bodytext']), $record); + if ($recordObj->has('bodytext') && ($bodytext = $recordObj->get('bodytext'))) { + $out .= $this->linkEditContent($this->renderText($bodytext), $record); } - if ($recordObj['image'] ?? false) { - $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['image']), $record); + if ($recordObj->has('image') && ($image = $recordObj->get('image'))) { + $out .= $this->linkEditContent($this->getThumbCodeUnlinked($image), $record); } - if ($recordObj['media'] ?? false) { - $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['media']), $record); + if ($recordObj->has('media') && ($media = $recordObj->get('media'))) { + $out .= $this->linkEditContent($this->getThumbCodeUnlinked($media), $record); } - if ($recordObj['assets'] ?? false) { - $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['assets']), $record); + if ($recordObj->has('assets') && ($assets = $recordObj->get('assets'))) { + $out .= $this->linkEditContent($this->getThumbCodeUnlinked($assets), $record); } } diff --git a/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php b/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php index 09cfc3afc793e6c12be2da2d8414b810acc5c720..40175c70727baf7dda36319755694e8fec9ff1ec 100644 --- a/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php +++ b/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php @@ -84,7 +84,7 @@ readonly class RecordFieldTransformer public function transformField(FieldTypeInterface $fieldInformation, RawRecord $rawRecord, Context $context): mixed { - $fieldValue = $rawRecord[$fieldInformation->getName()]; + $fieldValue = $rawRecord->get($fieldInformation->getName()); // type=file needs to be handled before RelationalFieldTypeInterface if ($fieldInformation instanceof FileFieldType) { diff --git a/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php b/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php new file mode 100644 index 0000000000000000000000000000000000000000..f2f384725bb4598e36ce48e32b94e17a91f9673a --- /dev/null +++ b/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php @@ -0,0 +1,25 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Domain\Exception; + +use TYPO3\CMS\Core\Exception; + +/** + * @internal + */ +class IncompleteRecordException extends Exception {} diff --git a/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php new file mode 100644 index 0000000000000000000000000000000000000000..9ddfe64e121cb90ea2f8511e09969bf03c0a4e9a --- /dev/null +++ b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php @@ -0,0 +1,26 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Domain\Exception; + +use Psr\Container\ContainerExceptionInterface; +use TYPO3\CMS\Core\Exception; + +/** + * @internal + */ +class RecordPropertyException extends Exception implements ContainerExceptionInterface {} diff --git a/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php new file mode 100644 index 0000000000000000000000000000000000000000..4bbe0628e7ffb76786646f8130746b97861497bd --- /dev/null +++ b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php @@ -0,0 +1,26 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Domain\Exception; + +use Psr\Container\NotFoundExceptionInterface; +use TYPO3\CMS\Core\Exception; + +/** + * @internal + */ +class RecordPropertyNotFoundException extends Exception implements NotFoundExceptionInterface {} diff --git a/typo3/sysext/core/Classes/Domain/RawRecord.php b/typo3/sysext/core/Classes/Domain/RawRecord.php index 2acb42c89d73fdd071018d8fa08a1c60557a14f3..3f3287b5e61a27eddc256b288275e12c219277ab 100644 --- a/typo3/sysext/core/Classes/Domain/RawRecord.php +++ b/typo3/sysext/core/Classes/Domain/RawRecord.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Domain; +use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException; use TYPO3\CMS\Core\Domain\Record\ComputedProperties; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -25,7 +26,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; * * @internal not part of public API, as this needs to be streamlined and proven */ -readonly class RawRecord implements \ArrayAccess, RecordInterface +readonly class RawRecord implements RecordInterface { public function __construct( protected int $uid, @@ -71,36 +72,30 @@ readonly class RawRecord implements \ArrayAccess, RecordInterface return $this->properties + ['uid' => $this->uid, 'pid' => $this->pid]; } - /** - * In addition to `isset()`, this considers `null` values as well. - */ - public function isDefined(int|string $offset): bool + public function has(string $id): bool { - return array_key_exists($offset, $this->properties); + return array_key_exists($id, $this->properties); } - public function offsetExists(mixed $offset): bool + public function get(string $id): mixed { - return isset($this->properties[$offset]); - } - - public function offsetGet(mixed $offset): mixed - { - return $this->properties[$offset] ?? null; - } + if (!$this->has($id)) { + throw new RecordPropertyNotFoundException( + 'Record property "' . $id . '" is not available.', + 1725892140 + ); + } - public function offsetSet(mixed $offset, mixed $value): void - { - throw new \InvalidArgumentException('Record properties cannot be set.', 1712139284); + return $this->properties[$id] ?? null; } - public function offsetUnset(mixed $offset): void + public function getComputedProperties(): ComputedProperties { - throw new \InvalidArgumentException('Record properties cannot be unset.', 1712139283); + return $this->computedProperties; } - public function getComputedProperties(): ComputedProperties + public function getRawRecord(): RawRecord { - return $this->computedProperties; + return $this; } } diff --git a/typo3/sysext/core/Classes/Domain/Record.php b/typo3/sysext/core/Classes/Domain/Record.php index 05931dd47c2bb3d6ea0ca31669d34d006481dc58..c5f42222ccd893c81415b652fafa0efd1de2aca6 100644 --- a/typo3/sysext/core/Classes/Domain/Record.php +++ b/typo3/sysext/core/Classes/Domain/Record.php @@ -17,6 +17,8 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Domain; +use TYPO3\CMS\Core\Domain\Exception\RecordPropertyException; +use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException; use TYPO3\CMS\Core\Domain\Record\ComputedProperties; use TYPO3\CMS\Core\Domain\Record\LanguageInfo; use TYPO3\CMS\Core\Domain\Record\SystemProperties; @@ -27,12 +29,12 @@ use TYPO3\CMS\Core\Domain\Record\VersionInfo; * * @internal not part of public API, as this needs to be streamlined and proven */ -class Record implements \ArrayAccess, RecordInterface +class Record implements RecordInterface { public function __construct( protected readonly RawRecord $rawRecord, protected array $properties, - protected readonly ?SystemProperties $systemProperties + protected readonly ?SystemProperties $systemProperties = null, ) {} public function getUid(): int @@ -73,18 +75,18 @@ class Record implements \ArrayAccess, RecordInterface return ['uid' => $this->getUid(), 'pid' => $this->getPid()] + $this->properties; } - public function offsetExists(mixed $offset): bool + public function has(string $id): bool { - if (isset($this->properties[$offset])) { + if (array_key_exists($id, $this->properties)) { return true; } - if (in_array($offset, ['uid', 'pid'], true)) { + if (in_array($id, ['uid', 'pid'], true)) { // Enable access of uid and pid via array access return true; } - if ($this->getRecordType() === null && isset($this->rawRecord[$offset])) { + if ($this->getRecordType() === null && $this->rawRecord->has($id)) { // Only fall back to the raw record in case no record type is defined. // This allows to properly check for only record type specific fields. return true; @@ -93,39 +95,38 @@ class Record implements \ArrayAccess, RecordInterface return false; } - public function offsetGet(mixed $offset): mixed + public function get(string $id): mixed { - if (isset($this->properties[$offset])) { - $property = $this->properties[$offset]; + if (array_key_exists($id, $this->properties)) { + $property = $this->properties[$id]; if ($property instanceof RecordPropertyClosure) { - $property = $property->instantiate(); - $this->properties[$offset] = $property; + try { + $property = $property->instantiate(); + } catch (\Exception $e) { + // Consumers of this method can rely on catching ContainerExceptionInterface + throw new RecordPropertyException( + 'An exception occured while instantiating record property "' . $id . '"', + 1725892139, + $e + ); + } + $this->properties[$id] = $property; } return $property; } - if (in_array($offset, ['uid', 'pid'], true)) { + if (in_array($id, ['uid', 'pid'], true)) { // Enable access of uid and pid via array access - return $this->rawRecord[$offset]; + return $this->rawRecord->get($id); } - if ($this->getRecordType() === null && isset($this->rawRecord[$offset])) { + if ($this->getRecordType() === null && $this->rawRecord->has($id)) { // Only fall back to the raw record in case no record type is defined. // This ensures that only record type specific fields are being returned. - return $this->rawRecord[$offset]; + return $this->rawRecord->get($id); } - return null; - } - - public function offsetSet(mixed $offset, mixed $value): void - { - throw new \InvalidArgumentException('Record properties cannot be modified.', 1712139281); - } - - public function offsetUnset(mixed $offset): void - { - throw new \InvalidArgumentException('Record properties cannot be unset.', 1712139282); + throw new RecordPropertyNotFoundException('Record property "' . $id . '" is not available.', 1725892138); } public function getVersionInfo(): ?VersionInfo diff --git a/typo3/sysext/core/Classes/Domain/RecordFactory.php b/typo3/sysext/core/Classes/Domain/RecordFactory.php index 60c3e8b65f2d9f06ac5245f6459c7d3597b638a5..76b5384f0bc0729ae8d678f590e059941eb66088 100644 --- a/typo3/sysext/core/Classes/Domain/RecordFactory.php +++ b/typo3/sysext/core/Classes/Domain/RecordFactory.php @@ -20,6 +20,8 @@ namespace TYPO3\CMS\Core\Domain; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\DataHandling\RecordFieldTransformer; +use TYPO3\CMS\Core\Domain\Exception\IncompleteRecordException; +use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException; use TYPO3\CMS\Core\Domain\Record\ComputedProperties; use TYPO3\CMS\Core\Domain\Record\LanguageInfo; use TYPO3\CMS\Core\Domain\Record\SystemProperties; @@ -64,7 +66,7 @@ readonly class RecordFactory * This method does not handle special expansion of fields. * @todo Now unused - we might want to remove this again */ - public function createFromDatabaseRow(string $table, array $record): Record + public function createFromDatabaseRow(string $table, array $record): RecordInterface { $rawRecord = $this->createRawRecord($table, $record); $schema = $this->schemaFactory->get($table); @@ -89,7 +91,7 @@ readonly class RecordFactory * their values resolved and extended. A typical use-case is resolving * of related records, or using \DateTimeImmutable objects for datetime fields. */ - public function createResolvedRecordFromDatabaseRow(string $table, array $record, ?Context $context = null): Record + public function createResolvedRecordFromDatabaseRow(string $table, array $record, ?Context $context = null): RecordInterface { $context = $context ?? GeneralUtility::makeInstance(Context::class); $properties = []; @@ -152,7 +154,7 @@ readonly class RecordFactory /** * Quick helper function in order to avoid duplicate code. */ - protected function createRecord(RawRecord $rawRecord, array $properties): Record + protected function createRecord(RawRecord $rawRecord, array $properties): RecordInterface { $schema = $this->schemaFactory->get($rawRecord->getMainType()); [$properties, $systemProperties] = $this->extractSystemInformation( @@ -189,15 +191,22 @@ readonly class RecordFactory $languageCapability = $schema->getCapability(TcaSchemaCapability::Language); $languageField = $languageCapability->getLanguageField()->getName(); $transOrigPointerField = $languageCapability->getTranslationOriginPointerField()->getName(); - $translationSourceField = $languageCapability->hasTranslationSourceField() ? $languageCapability->getTranslationSourceField()->getName() : null; - $systemProperties['language'] = new LanguageInfo( - (int)$rawRecord[$languageField], - (int)$rawRecord[$transOrigPointerField], - $translationSourceField ? (int)$rawRecord[$translationSourceField] : null, - ); + $translationSourceField = $languageCapability->hasTranslationSourceField() ? $languageCapability->getTranslationSourceField()->getName() : ''; + try { + $systemProperties['language'] = new LanguageInfo( + (int)$rawRecord->get($languageField), + (int)$rawRecord->get($transOrigPointerField), + $rawRecord->has($translationSourceField) ? (int)$rawRecord->get($translationSourceField) : null, + ); + } catch (RecordPropertyNotFoundException $e) { + throw new IncompleteRecordException( + 'Table "' . $schema->getName() . '" is defined as language aware but the record misses necessary fields: ' . $e->getMessage(), + 1726046917 + ); + } unset($properties[$languageField]); unset($properties[$transOrigPointerField]); - if ($translationSourceField !== null) { + if ($translationSourceField !== '') { unset($properties[$translationSourceField]); } if ($languageCapability->hasDiffSourceField()) { @@ -208,12 +217,19 @@ readonly class RecordFactory // Workspaces. if ($schema->isWorkspaceAware()) { - $systemProperties['version'] = new VersionInfo( - (int)$rawRecord['t3ver_wsid'], - (int)$rawRecord['t3ver_oid'], - VersionState::tryFrom((int)$rawRecord['t3ver_state']), - (int)$rawRecord['t3ver_stage'], - ); + try { + $systemProperties['version'] = new VersionInfo( + (int)$rawRecord->get('t3ver_wsid'), + (int)$rawRecord->get('t3ver_oid'), + VersionState::tryFrom((int)$rawRecord->get('t3ver_state')), + (int)$rawRecord->get('t3ver_stage'), + ); + } catch (RecordPropertyNotFoundException $e) { + throw new IncompleteRecordException( + 'Table "' . $schema->getName() . '" is defined as workspace aware but the record misses necessary fields: ' . $e->getMessage(), + 1726046918 + ); + } unset( $properties['t3ver_wsid'], $properties['t3ver_oid'], @@ -230,43 +246,45 @@ readonly class RecordFactory /** @var SystemInternalFieldCapability|FieldCapability $capabilityInstance */ $capabilityInstance = $schema->getCapability($capability); $fieldName = $capabilityInstance->getFieldName(); - // Field is not set in the original record, just skip it - if (!$rawRecord->isDefined($fieldName)) { - continue; + if (!$rawRecord->has($fieldName)) { + throw new IncompleteRecordException( + 'Table "' . $schema->getName() . '" has capability "' . $capability->name . '" set but the record misses the corresponding field "' . $fieldName . '"', + 1726046919 + ); } switch ($capability) { case TcaSchemaCapability::CreatedAt: - $systemProperties['createdAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]); + $systemProperties['createdAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName)); break; case TcaSchemaCapability::UpdatedAt: - $systemProperties['lastUpdatedAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]); + $systemProperties['lastUpdatedAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName)); break; case TcaSchemaCapability::RestrictionStartTime: - $systemProperties['publishAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]); + $systemProperties['publishAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName)); break; case TcaSchemaCapability::RestrictionEndTime: - $systemProperties['publishUntil'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]); + $systemProperties['publishUntil'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName)); break; case TcaSchemaCapability::SoftDelete: - $systemProperties['isDeleted'] = (bool)($rawRecord[$fieldName]); + $systemProperties['isDeleted'] = (bool)($rawRecord->get($fieldName)); break; case TcaSchemaCapability::EditLock: - $systemProperties['isLockedForEditing'] = (bool)($rawRecord[$fieldName]); + $systemProperties['isLockedForEditing'] = (bool)($rawRecord->get($fieldName)); break; case TcaSchemaCapability::RestrictionDisabledField: - $systemProperties['isDisabled'] = (bool)($rawRecord[$fieldName]); + $systemProperties['isDisabled'] = (bool)($rawRecord->get($fieldName)); break; case TcaSchemaCapability::InternalDescription: - $systemProperties['description'] = $rawRecord[$fieldName]; + $systemProperties['description'] = $rawRecord->get($fieldName); break; case TcaSchemaCapability::SortByField: - $systemProperties['sorting'] = (int)($rawRecord[$fieldName]); + $systemProperties['sorting'] = (int)($rawRecord->get($fieldName)); break; case TcaSchemaCapability::RestrictionUserGroup: $systemProperties['userGroupRestriction'] = GeneralUtility::intExplode( ',', - $rawRecord[$fieldName], + $rawRecord->get($fieldName), true ); break; diff --git a/typo3/sysext/core/Classes/Domain/RecordInterface.php b/typo3/sysext/core/Classes/Domain/RecordInterface.php index 6f8adb7409c7e14783f132dbc1735d9a21c68ce6..a7267a923d7cf068983bb352ba07a9d56e6df8f4 100644 --- a/typo3/sysext/core/Classes/Domain/RecordInterface.php +++ b/typo3/sysext/core/Classes/Domain/RecordInterface.php @@ -17,10 +17,13 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Domain; +use Psr\Container\ContainerInterface; +use TYPO3\CMS\Core\Domain\Record\ComputedProperties; + /** * An interface for database / TCA records. */ -interface RecordInterface +interface RecordInterface extends ContainerInterface { public function getUid(): int; public function getPid(): int; @@ -43,4 +46,8 @@ interface RecordInterface public function getMainType(): string; public function toArray(): array; + + public function getRawRecord(): ?RawRecord; + + public function getComputedProperties(): ComputedProperties; } diff --git a/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst index 1597e548c4df21c1b08ebc812681b855eaa16749..34b95e086bcb718109a764014156309199d8a8aa 100644 --- a/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst +++ b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst @@ -89,9 +89,9 @@ is most of all a better organized overview of all available information. E.g. the property `properties` lists all relevant fields for the current Content Type. -We are dealing with an object here, which behaves like an array. In short: you -can access your record properties as you are used to with :html:`{record.title}` -or :html:`{record.uid}`. In addition, you gain special, context-aware properties +We are dealing with an object here. You however can access your record +properties as you are used to with :html:`{record.title}` or +:html:`{record.uid}`. In addition, you gain special, context-aware properties like the language :html:`{record.languageId}` or workspace :html:`{data.versionInfo.workspaceId}`. diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php index 75f11ff40db7f1168369f120f9c7cf272a1ad7ad..f2735f5f740730fee223d2400ff91feaed048b8a 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php @@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\LanguageAspect; use TYPO3\CMS\Core\Context\WorkspaceAspect; use TYPO3\CMS\Core\DataHandling\RecordFieldTransformer; +use TYPO3\CMS\Core\Domain\RawRecord; use TYPO3\CMS\Core\Domain\Record; use TYPO3\CMS\Core\Domain\RecordFactory; use TYPO3\CMS\Core\Domain\RecordPropertyClosure; @@ -58,7 +59,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -70,8 +71,8 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertIsArray($result->getProperties()); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(FileReference::class, $resolvedRecord['image']); - self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['image']->getIdentifier()); + self::assertInstanceOf(FileReference::class, $resolvedRecord->get('image')); + self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('image')->getIdentifier()); } #[Test] @@ -83,7 +84,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -92,7 +93,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertNull($result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertNull($resolvedRecord['image']); + self::assertNull($resolvedRecord->get('image')); } #[Test] @@ -104,7 +105,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -117,9 +118,9 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertInstanceOf(LazyFileReferenceCollection::class, $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord['media']); - self::assertInstanceOf(FileReference::class, $resolvedRecord['media'][0]); - self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['media'][0]->getIdentifier()); + self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord->get('media')); + self::assertInstanceOf(FileReference::class, $resolvedRecord->get('media')[0]); + self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('media')[0]->getIdentifier()); } #[Test] @@ -131,7 +132,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -144,10 +145,10 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertInstanceOf(LazyFileReferenceCollection::class, $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertCount(1, $resolvedRecord['assets']); - self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord['assets']); - self::assertInstanceOf(FileReference::class, $resolvedRecord['assets'][0]); - self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['assets'][0]->getIdentifier()); + self::assertCount(1, $resolvedRecord->get('assets')); + self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord->get('assets')); + self::assertInstanceOf(FileReference::class, $resolvedRecord->get('assets')[0]); + self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('assets')[0]->getIdentifier()); } #[Test] @@ -159,7 +160,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -171,10 +172,10 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertCount(1, $result->getFiles()); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(Folder::class, $resolvedRecord['typo3tests_contentelementb_folder']); - self::assertEquals('/', $resolvedRecord['typo3tests_contentelementb_folder']->getIdentifier()); - self::assertEquals('1:/', $resolvedRecord['typo3tests_contentelementb_folder']->getCombinedIdentifier()); - self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_folder']->getFiles()); + self::assertInstanceOf(Folder::class, $resolvedRecord->get('typo3tests_contentelementb_folder')); + self::assertEquals('/', $resolvedRecord->get('typo3tests_contentelementb_folder')->getIdentifier()); + self::assertEquals('1:/', $resolvedRecord->get('typo3tests_contentelementb_folder')->getCombinedIdentifier()); + self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_folder')->getFiles()); } #[Test] @@ -186,7 +187,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -195,7 +196,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertNull($result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertNull($resolvedRecord['typo3tests_contentelementb_folder']); + self::assertNull($resolvedRecord->get('typo3tests_contentelementb_folder')); } #[Test] @@ -207,7 +208,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class), ); @@ -225,12 +226,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertCount(1, $result[1]->getFiles()); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyFolderCollection::class, $resolvedRecord['typo3tests_contentelementb_folder_recursive']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_folder_recursive']); - self::assertInstanceOf(Folder::class, $resolvedRecord['typo3tests_contentelementb_folder_recursive'][0]); - self::assertEquals('/sub/', $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getIdentifier()); - self::assertEquals('1:/sub/', $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getCombinedIdentifier()); - self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getFiles()); + self::assertInstanceOf(LazyFolderCollection::class, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')); + self::assertInstanceOf(Folder::class, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[0]); + self::assertEquals('/sub/', $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getIdentifier()); + self::assertEquals('1:/sub/', $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getCombinedIdentifier()); + self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getFiles()); } #[Test] @@ -242,20 +243,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('lorem foo bar', $result[0]['fieldA']); - self::assertSame('lorem foo bar 2', $result[1]['fieldA']); + self::assertSame('lorem foo bar', $result[0]->get('fieldA')); + self::assertSame('lorem foo bar 2', $result[1]->get('fieldA')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection']); - self::assertSame('lorem foo bar', $resolvedRecord['typo3tests_contentelementb_collection'][0]['fieldA']); - self::assertSame('lorem foo bar 2', $resolvedRecord['typo3tests_contentelementb_collection'][1]['fieldA']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection')); + self::assertSame('lorem foo bar', $resolvedRecord->get('typo3tests_contentelementb_collection')[0]->get('fieldA')); + self::assertSame('lorem foo bar 2', $resolvedRecord->get('typo3tests_contentelementb_collection')[1]->get('fieldA')); } #[Test] @@ -267,26 +268,26 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('lorem foo bar A', $result[0]['fieldA']); - self::assertSame('lorem foo bar A2', $result[1]['fieldA']); - self::assertCount(2, $result[0]['collection_inner']); - self::assertSame('lorem foo bar B', $result[0]['collection_inner'][0]['fieldB']); - self::assertSame('lorem foo bar B2', $result[0]['collection_inner'][1]['fieldB']); + self::assertSame('lorem foo bar A', $result[0]->get('fieldA')); + self::assertSame('lorem foo bar A2', $result[1]->get('fieldA')); + self::assertCount(2, $result[0]->get('collection_inner')); + self::assertSame('lorem foo bar B', $result[0]->get('collection_inner')[0]->get('fieldB')); + self::assertSame('lorem foo bar B2', $result[0]->get('collection_inner')[1]->get('fieldB')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection_recursive']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection_recursive']); - self::assertSame('lorem foo bar A', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['fieldA']); - self::assertSame('lorem foo bar A2', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][1]['fieldA']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner']); - self::assertSame('lorem foo bar B', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner'][0]['fieldB']); - self::assertSame('lorem foo bar B2', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner'][1]['fieldB']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')); + self::assertSame('lorem foo bar A', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('fieldA')); + self::assertSame('lorem foo bar A2', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[1]->get('fieldA')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner')); + self::assertSame('lorem foo bar B', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner')[0]->get('fieldB')); + self::assertSame('lorem foo bar B2', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner')[1]->get('fieldB')); } #[Test] @@ -306,20 +307,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('lorem foo bar WS', $result[0]['fieldA']); - self::assertSame('lorem foo bar 2 WS', $result[1]['fieldA']); + self::assertSame('lorem foo bar WS', $result[0]->get('fieldA')); + self::assertSame('lorem foo bar 2 WS', $result[1]->get('fieldA')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection']); - self::assertSame('lorem foo bar WS', $resolvedRecord['typo3tests_contentelementb_collection'][0]['fieldA']); - self::assertSame('lorem foo bar 2 WS', $resolvedRecord['typo3tests_contentelementb_collection'][1]['fieldA']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection')); + self::assertSame('lorem foo bar WS', $resolvedRecord->get('typo3tests_contentelementb_collection')[0]->get('fieldA')); + self::assertSame('lorem foo bar 2 WS', $resolvedRecord->get('typo3tests_contentelementb_collection')[1]->get('fieldA')); } #[Test] @@ -331,19 +332,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); - self::assertSame('Category 1', $result[0]['title']); - self::assertSame('Category 2', $result[1]['title']); + self::assertSame('Category 1', $result[0]->get('title')); + self::assertSame('Category 2', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']); - self::assertSame('Category 2', $resolvedRecord['typo3tests_contentelementb_categories_mm'][1]['title']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title')); + self::assertSame('Category 2', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[1]->get('title')); } #[Test] @@ -365,14 +366,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); // @todo: this should be the other way around, but currently RelationResolver cannot handle different sorting in WS - self::assertSame('Category 2 ws', $result[1]['title']); - self::assertSame('Category 1 ws', $result[0]['title']); + self::assertSame('Category 2 ws', $result[1]->get('title')); + self::assertSame('Category 1 ws', $result[0]->get('title')); } #[Test] @@ -392,17 +393,17 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $context ); self::assertCount(1, $result); - self::assertSame('Category 1 translated', $result[0]['title']); + self::assertSame('Category 1 translated', $result[0]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', array_replace($dummyRecord->toArray(), ['uid' => 381]), $context); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertSame('Category 1 translated', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertSame('Category 1 translated', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title')); } #[Test] @@ -422,17 +423,17 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $context ); self::assertCount(1, $result); - self::assertSame('Category 1 translated', $result[0]['title']); + self::assertSame('Category 1 translated', $result[0]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', array_replace($dummyRecord->toArray(), ['uid' => 381]), $context); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_categories_mm']); - self::assertSame('Category 1 translated', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_categories_mm')); + self::assertSame('Category 1 translated', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title')); } #[Test] @@ -446,7 +447,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -454,12 +455,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $result = $propertyClosure->instantiate(); self::assertInstanceOf(Record::class, $result); self::assertSame(2, $result->getUid()); - self::assertSame('Category 1', $result['title']); + self::assertSame('Category 1', $result->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertInstanceOf(Record::class, $resolvedRecord['typo3tests_contentelementb_categories_11']); - self::assertSame(2, $resolvedRecord['typo3tests_contentelementb_categories_11']['uid']); - self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_11']['title']); + self::assertInstanceOf(Record::class, $resolvedRecord->get('typo3tests_contentelementb_categories_11')); + self::assertSame(2, $resolvedRecord->get('typo3tests_contentelementb_categories_11')->getUid()); + self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_11')->get('title')); } #[Test] @@ -473,20 +474,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('Category 1', $result[0]['title']); - self::assertSame('Category 2', $result[1]['title']); + self::assertSame('Category 1', $result[0]->get('title')); + self::assertSame('Category 2', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_categories_1m']); - self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_1m']); - self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_1m'][0]['title']); - self::assertSame('Category 2', $resolvedRecord['typo3tests_contentelementb_categories_1m'][1]['title']); + self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_categories_1m')); + self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_1m')); + self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_1m')[0]->get('title')); + self::assertSame('Category 2', $resolvedRecord->get('typo3tests_contentelementb_categories_1m')[1]->get('title')); } #[Test] @@ -500,7 +501,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -508,15 +509,15 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $result = $propertyClosure->instantiate(); self::assertInstanceOf(Record::class, $result); self::assertSame(1906, $result->getUid()); - self::assertSame(1906, $result['uid']); - self::assertSame('Page 1', $result['title']); + self::assertSame(1906, $result->get('uid')); + self::assertSame('Page 1', $result->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relation']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relation'); self::assertInstanceOf(Record::class, $resolvedRelation); self::assertSame(1906, $resolvedRelation->getUid()); - self::assertSame(1906, $resolvedRelation['uid']); - self::assertSame('Page 1', $resolvedRelation['title']); + self::assertSame(1906, $resolvedRelation->get('uid')); + self::assertSame('Page 1', $resolvedRelation->get('title')); } #[Test] @@ -530,23 +531,23 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('Page 1', $result[0]['title']); - self::assertSame('Page 2', $result[1]['title']); + self::assertSame('Page 1', $result[0]->get('title')); + self::assertSame('Page 2', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relations']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relations'); self::assertCount(2, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertSame(1906, $resolvedRelation[0]->getUid()); - self::assertSame(1906, $resolvedRelation[0]['uid']); - self::assertSame('Page 1', $resolvedRelation[0]['title']); - self::assertSame('Page 2', $resolvedRelation[1]['title']); + self::assertSame(1906, $resolvedRelation[0]->get('uid')); + self::assertSame('Page 1', $resolvedRelation[0]->get('title')); + self::assertSame('Page 2', $resolvedRelation[1]->get('title')); } #[Test] @@ -560,7 +561,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -569,11 +570,11 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertSame(260, $result[0]->getUid()); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_circular_relation']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_circular_relation'); self::assertCount(1, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $result); self::assertSame(260, $resolvedRelation[0]->getUid()); - self::assertSame(260, $resolvedRelation[0]['uid']); + self::assertSame(260, $resolvedRelation[0]->get('uid')); } #[Test] @@ -587,29 +588,29 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertInstanceOf(LazyRecordCollection::class, $result); self::assertCount(2, $result); - self::assertSame('Record 1', $result[0]['title']); - self::assertSame('Record 2', $result[1]['title']); - self::assertCount(1, $result[0]['record_collection']); - self::assertCount(1, $result[1]['record_collection']); - self::assertSame('Collection 1', $result[0]['record_collection'][0]['text']); - self::assertSame('Collection 2', $result[1]['record_collection'][0]['text']); + self::assertSame('Record 1', $result[0]->get('title')); + self::assertSame('Record 2', $result[1]->get('title')); + self::assertCount(1, $result[0]->get('record_collection')); + self::assertCount(1, $result[1]->get('record_collection')); + self::assertSame('Collection 1', $result[0]->get('record_collection')[0]->get('text')); + self::assertSame('Collection 2', $result[1]->get('record_collection')[0]->get('text')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_record_relation_recursive']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_record_relation_recursive'); self::assertCount(2, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); - self::assertSame('Record 1', $resolvedRelation[0]['title']); - self::assertSame('Record 2', $resolvedRelation[1]['title']); - self::assertCount(1, $resolvedRelation[0]['record_collection']); - self::assertCount(1, $resolvedRelation[1]['record_collection']); - self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']); - self::assertSame('Collection 2', $resolvedRelation[1]['record_collection'][0]['text']); + self::assertSame('Record 1', $resolvedRelation[0]->get('title')); + self::assertSame('Record 2', $resolvedRelation[1]->get('title')); + self::assertCount(1, $resolvedRelation[0]->get('record_collection')); + self::assertCount(1, $resolvedRelation[1]->get('record_collection')); + self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text')); + self::assertSame('Collection 2', $resolvedRelation[1]->get('record_collection')[0]->get('text')); } #[Test] @@ -630,21 +631,21 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('Page 1 ws', $result[0]['title']); - self::assertSame('Page 2 ws', $result[1]['title']); + self::assertSame('Page 1 ws', $result[0]->get('title')); + self::assertSame('Page 2 ws', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relations']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relations'); self::assertCount(2, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); - self::assertSame('Page 1 ws', $resolvedRelation[0]['title']); - self::assertSame('Page 2 ws', $resolvedRelation[1]['title']); + self::assertSame('Page 1 ws', $resolvedRelation[0]->get('title')); + self::assertSame('Page 2 ws', $resolvedRelation[1]->get('title')); } #[Test] @@ -658,24 +659,24 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(4, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('Page 1', $result[0]['title']); - self::assertSame('Page 2', $result[1]['title']); - self::assertSame('Content 1', $result[2]['header']); - self::assertSame('Content 2', $result[3]['header']); + self::assertSame('Page 1', $result[0]->get('title')); + self::assertSame('Page 2', $result[1]->get('title')); + self::assertSame('Content 1', $result[2]->get('header')); + self::assertSame('Content 2', $result[3]->get('header')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_content_relation']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_content_relation'); self::assertCount(4, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); - self::assertSame('Page 1', $resolvedRelation[0]['title']); - self::assertSame('Page 2', $resolvedRelation[1]['title']); - self::assertSame('Content 1', $resolvedRelation[2]['header']); - self::assertSame('Content 2', $resolvedRelation[3]['header']); + self::assertSame('Page 1', $resolvedRelation[0]->get('title')); + self::assertSame('Page 2', $resolvedRelation[1]->get('title')); + self::assertSame('Content 1', $resolvedRelation[2]->get('header')); + self::assertSame('Content 2', $resolvedRelation[3]->get('header')); } #[Test] @@ -690,21 +691,21 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); - self::assertSame('Page 1', $result[0]['title']); - self::assertSame('Page 2', $result[1]['title']); + self::assertSame('Page 1', $result[0]->get('title')); + self::assertSame('Page 2', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_mm']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_mm'); self::assertCount(2, $resolvedRelation); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); - self::assertSame('Page 1', $resolvedRelation[0]['title']); - self::assertSame('Page 2', $resolvedRelation[1]['title']); + self::assertSame('Page 1', $resolvedRelation[0]->get('title')); + self::assertSame('Page 2', $resolvedRelation[1]->get('title')); } public static function multipleItemsAsArrayConversionDataProvider(): \Generator @@ -752,14 +753,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertSame($expected, $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertSame($expected, $resolvedRecord[$fieldName]); + self::assertSame($expected, $resolvedRecord->get($fieldName)); } public static function canConvertDateTimeDataProvider(): \Generator @@ -802,14 +803,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertSame($expected, $result?->format('c')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertSame($expected, $resolvedRecord[$fieldName]?->format('c')); + self::assertSame($expected, $resolvedRecord->get($fieldName)?->format('c')); } #[Test] @@ -822,14 +823,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertSame('1', $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertSame('1', $resolvedRecord['typo3tests_contentelementb_select_single']); + self::assertSame('1', $resolvedRecord->get('typo3tests_contentelementb_select_single')); } #[Test] @@ -843,19 +844,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertInstanceOf(RecordPropertyClosure::class, $propertyClosure); $result = $propertyClosure->instantiate(); self::assertInstanceOf(Record::class, $result); - self::assertSame('Record 1', $result['title']); + self::assertSame('Record 1', $result->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_one_to_one']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_one_to_one'); self::assertInstanceOf(Record::class, $resolvedRelation); - self::assertSame('Record 1', $resolvedRelation['title']); + self::assertSame('Record 1', $resolvedRelation->get('title')); } /** @@ -872,19 +873,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertInstanceOf(RecordPropertyClosure::class, $propertyClosure); $result = $propertyClosure->instantiate(); self::assertInstanceOf(Record::class, $result); - self::assertSame('Record 1', $result['title']); + self::assertSame('Record 1', $result->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedField = $resolvedRecord['typo3tests_contentelementb_select_foreign_native']; + $resolvedField = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_native'); self::assertInstanceOf(Record::class, $resolvedField); - self::assertSame('Record 1', $resolvedField['title']); + self::assertSame('Record 1', $resolvedField->get('title')); } /** @@ -901,7 +902,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $propertyClosure = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -910,7 +911,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertNull($result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - self::assertNull($resolvedRecord['typo3tests_contentelementb_select_foreign_native']); + self::assertNull($resolvedRecord->get('typo3tests_contentelementb_select_foreign_native')); } /** @@ -927,7 +928,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -935,7 +936,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertCount(0, $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign'); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertCount(0, $resolvedRelation); } @@ -954,7 +955,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -962,7 +963,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertCount(0, $result); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple'); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertCount(0, $resolvedRelation); } @@ -978,20 +979,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); - self::assertSame('Record 1', $result[0]['title']); - self::assertSame('Record 2', $result[1]['title']); + self::assertSame('Record 1', $result[0]->get('title')); + self::assertSame('Record 2', $result[1]->get('title')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple'); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertCount(2, $resolvedRelation); - self::assertSame('Record 1', $resolvedRelation[0]['title']); - self::assertSame('Record 2', $resolvedRelation[1]['title']); + self::assertSame('Record 1', $resolvedRelation[0]->get('title')); + self::assertSame('Record 2', $resolvedRelation[1]->get('title')); } #[Test] @@ -1005,25 +1006,25 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(2, $result); - self::assertSame('Record 1', $result[0]['title']); - self::assertSame('Collection 1', $result[0]['record_collection'][0]['text']); - self::assertSame('Record 1', $result[1]['title']); - self::assertSame('Collection 1', $result[1]['record_collection'][0]['text']); + self::assertSame('Record 1', $result[0]->get('title')); + self::assertSame('Collection 1', $result[0]->get('record_collection')[0]->get('text')); + self::assertSame('Record 1', $result[1]->get('title')); + self::assertSame('Collection 1', $result[1]->get('record_collection')[0]->get('text')); self::assertSame($result[0], $result[1]); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple'); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertCount(2, $resolvedRelation); - self::assertSame('Record 1', $resolvedRelation[0]['title']); - self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']); - self::assertSame('Record 1', $resolvedRelation[1]['title']); - self::assertSame('Collection 1', $resolvedRelation[1]['record_collection'][0]['text']); + self::assertSame('Record 1', $resolvedRelation[0]->get('title')); + self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text')); + self::assertSame('Record 1', $resolvedRelation[1]->get('title')); + self::assertSame('Collection 1', $resolvedRelation[1]->get('record_collection')[0]->get('text')); self::assertSame($resolvedRelation[0], $resolvedRelation[1]); } @@ -1038,24 +1039,24 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); self::assertCount(1, $result); self::assertInstanceOf(LazyRecordCollection::class, $result); $result = $result[0]; - self::assertSame('Record 1', $result['title']); - self::assertCount(1, $result['record_collection']); - self::assertSame('Collection 1', $result['record_collection'][0]['text']); + self::assertSame('Record 1', $result->get('title')); + self::assertCount(1, $result->get('record_collection')); + self::assertSame('Collection 1', $result->get('record_collection')[0]->get('text')); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign'); self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation); self::assertCount(1, $resolvedRelation); - self::assertSame('Record 1', $resolvedRelation[0]['title']); - self::assertCount(1, $resolvedRelation[0]['record_collection']); - self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']); + self::assertSame('Record 1', $resolvedRelation[0]->get('title')); + self::assertCount(1, $resolvedRelation[0]->get('record_collection')); + self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text')); } #[Test] @@ -1083,7 +1084,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -1092,7 +1093,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertSame('Text in Flex', $result['textarea']); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_flexfield']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_flexfield'); self::assertIsArray($resolvedRelation); self::assertSame('Header in Flex', $resolvedRelation['header']); self::assertSame('Text in Flex', $resolvedRelation['textarea']); @@ -1133,7 +1134,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase $subject = $this->get(RecordFieldTransformer::class); $result = $subject->transformField( $fieldInformation, - $dummyRecord->getRawRecord(), + $dummyRecord, $this->get(Context::class) ); @@ -1144,7 +1145,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase self::assertSame('12', $result['number']); $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray()); - $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_flexfield']; + $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_flexfield'); self::assertIsArray($resolvedRelation); self::assertSame('Header in Flex', $resolvedRelation['header']); self::assertSame('Text in Flex', $resolvedRelation['textarea']); @@ -1165,6 +1166,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase 'pid' => 1, 'sys_language_uid' => 0, 'l18n_parent' => 0, + 't3ver_wsid' => 0, + 't3ver_oid' => 0, + 't3ver_state' => 0, + 't3ver_stage' => 0, + 'crdate' => 0, + 'tstamp' => 0, + 'deleted' => 0, + 'sorting' => 0, 'hidden' => 0, 'starttime' => 0, 'endtime' => 0, @@ -1201,10 +1210,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase ]; } - protected function createTestRecordObject(array $overriddenValues = []): Record + protected function createTestRecordObject(array $overriddenValues = []): RawRecord { $dummyRecordData = $this->getTestRecord(); $dummyRecordData = array_replace($dummyRecordData, $overriddenValues); - return $this->get(RecordFactory::class)->createFromDatabaseRow('tt_content', $dummyRecordData); + return $this->get(RecordFactory::class) + ->createFromDatabaseRow('tt_content', $dummyRecordData) + ->getRawRecord(); } } diff --git a/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php b/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php index c2ccd11ccde857e9b09c6052b55f251877d1492f..20ba0106c027f286554cc978f16a670d903a3126 100644 --- a/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php +++ b/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php @@ -21,6 +21,8 @@ use PHPUnit\Framework\Attributes\Test; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\LanguageAspect; +use TYPO3\CMS\Core\Domain\Exception\IncompleteRecordException; +use TYPO3\CMS\Core\Domain\Record; use TYPO3\CMS\Core\Domain\RecordFactory; use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -41,8 +43,10 @@ final class RecordFactoryTest extends FunctionalTestCase $dbRow = BackendUtility::getRecord('pages', 1); $subject = $this->get(RecordFactory::class); $result = $subject->createFromDatabaseRow('pages', $dbRow); - self::assertSame(1, $result['uid']); - self::assertSame(0, $result['pid']); + self::assertSame(1, $result->getUid()); + self::assertSame(1, $result->get('uid')); + self::assertSame(0, $result->getPid()); + self::assertSame(0, $result->get('pid')); } #[Test] @@ -50,6 +54,7 @@ final class RecordFactoryTest extends FunctionalTestCase { $dbRow = BackendUtility::getRecord('pages', 1); $subject = $this->get(RecordFactory::class); + /** @var Record $result */ $result = $subject->createFromDatabaseRow('pages', $dbRow); self::assertSame($dbRow, $result->getRawRecord()->toArray()); self::assertArrayNotHasKey('mount_pid', $result->toArray()); @@ -68,6 +73,7 @@ final class RecordFactoryTest extends FunctionalTestCase { $dbRow = BackendUtility::getRecord('tt_content', 1); $subject = $this->get(RecordFactory::class); + /** @var Record $result */ $result = $subject->createFromDatabaseRow('tt_content', $dbRow); self::assertSame($dbRow, $result->getRawRecord()->toArray()); self::assertArrayNotHasKey('pi_flexform', $result->toArray()); @@ -82,11 +88,12 @@ final class RecordFactoryTest extends FunctionalTestCase { $dbRow = BackendUtility::getRecord('be_groups', 9); $subject = $this->get(RecordFactory::class); + /** @var Record $result */ $result = $subject->createFromDatabaseRow('be_groups', $dbRow); self::assertNull($result->getRecordType()); self::assertSame('be_groups', $result->getFullType()); self::assertSame($dbRow, $result->getRawRecord()->toArray()); - self::assertSame('readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', $result['file_permissions']); + self::assertSame('readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', $result->get('file_permissions')); } #[Test] @@ -97,6 +104,7 @@ final class RecordFactoryTest extends FunctionalTestCase $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context); $dbRow = $pageRepository->getPage(3); $subject = $this->get(RecordFactory::class); + /** @var Record $result */ $result = $subject->createFromDatabaseRow('pages', $dbRow); self::assertSame(903, $result->getOverlaidUid()); self::assertSame(903, $result->getComputedProperties()->getLocalizedUid()); @@ -113,6 +121,7 @@ final class RecordFactoryTest extends FunctionalTestCase $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context); $dbRow = $pageRepository->getPage(3); $subject = $this->get(RecordFactory::class); + /** @var Record $result */ $result = $subject->createFromDatabaseRow('pages', $dbRow); self::assertSame(0, $result->getVersionInfo()->getWorkspaceId()); self::assertSame(3, $result->getLanguageInfo()->getTranslationParent()); @@ -123,4 +132,40 @@ final class RecordFactoryTest extends FunctionalTestCase self::assertSame(1, $result->getComputedProperties()->getRequestedOverlayLanguageId()); self::assertNull($result->getComputedProperties()->getVersionedUid()); } + + #[Test] + public function throwsIncompleteRecordExceptionForMissingLangauegField(): void + { + $dbRow = BackendUtility::getRecord('pages', 1); + unset($dbRow['sys_language_uid']); + + $this->expectException(IncompleteRecordException::class); + $this->expectExceptionCode(1726046917); + + $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow); + } + + #[Test] + public function throwsIncompleteRecordExceptionForMissingWorkspaceField(): void + { + $dbRow = BackendUtility::getRecord('pages', 1); + unset($dbRow['t3ver_oid']); + + $this->expectException(IncompleteRecordException::class); + $this->expectExceptionCode(1726046918); + + $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow); + } + + #[Test] + public function throwsIncompleteRecordExceptionForMissingSystemPropertyField(): void + { + $dbRow = BackendUtility::getRecord('pages', 1); + unset($dbRow['deleted']); + + $this->expectException(IncompleteRecordException::class); + $this->expectExceptionCode(1726046919); + + $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow); + } } diff --git a/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php b/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php index 938ed168a9d6305cd9590a45f676b582bb021be9..77022492753daa19bb8cf2c27e40ed6df92c91cb 100644 --- a/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php +++ b/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php @@ -88,9 +88,9 @@ final class RecordFactoryTest extends UnitTestCase ]); $subject = new RecordFactory($schemaFactory, $this->createMock(RecordFieldTransformer::class)); $recordObject = $subject->createFromDatabaseRow('foo', ['uid' => 1, 'pid' => 2, 'type' => 'foo', 'foo' => 'fooValue', 'bar' => 'barValue']); - self::assertFalse($recordObject->offsetExists('bar')); - self::assertTrue($recordObject->offsetExists('foo')); - self::assertTrue($recordObject->getRawRecord()->offsetExists('foo')); - self::assertTrue($recordObject->getRawRecord()->offsetExists('bar')); + self::assertFalse($recordObject->has('bar')); + self::assertTrue($recordObject->has('foo')); + self::assertTrue($recordObject->getRawRecord()->has('foo')); + self::assertTrue($recordObject->getRawRecord()->has('bar')); } } diff --git a/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php b/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php index b2b4b698e1ee172df135a371315f6b0aab0c544a..e0663761b22c43c5a2a10aa4202ac5e0ea11bde4 100644 --- a/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php +++ b/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php @@ -107,7 +107,7 @@ readonly class PageContentFetchingProcessor implements DataProcessorInterface ); // 1b. Sort the records into the contentArea they belong to foreach ($flatRecords as $recordToSort) { - $colPosOfRecord = (int)$recordToSort['colPos']; + $colPosOfRecord = (int)$recordToSort->get('colPos'); $groupIdentifier = $contentAreasWithoutSlideMode[$colPosOfRecord]['identifier']; $groupedContents[$groupIdentifier]['records'][] = $recordToSort; } diff --git a/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php b/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php index ba9a5d60e64a2067785ad94735308dd545cad612..b1d1e1709e66f852a0f00e7006e2f76462d37a46 100644 --- a/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php +++ b/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php @@ -104,6 +104,7 @@ readonly class RecordTransformationProcessor implements DataProcessorInterface $defaultTargetVariableName = 'record'; } $targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, $defaultTargetVariableName); + // @todo Should we make sure that $output is actually a Record object? $processedData[$targetVariableName] = $output; return $processedData; }