}> */ public function resolve(RecordInterface $record, FieldTypeInterface $fieldInformation, Context $context): array { $sortedAndGroupedIds = $this->getGroupedRelationIds($record, $fieldInformation, $context); $groupedByTable = []; // group sorted items by table foreach ($sortedAndGroupedIds as $item) { $groupedByTable[$item['table']][] = (int)$item['id']; } $unorderedRows = $this->getRelationalRows($groupedByTable, $context); $sortedRows = []; // Sort the relation rows based on the field value foreach ($sortedAndGroupedIds as $item) { if (isset($unorderedRows[$item['table']][(int)$item['id']])) { $sortedRows[] = $unorderedRows[$item['table']][(int)$item['id']]; } } return $sortedRows; } /** * @return FileReference[] */ public function resolveFileReferences(RecordInterface $record, FieldTypeInterface $fieldInformation, Context $context): array { $sortedAndGroupedIds = $this->getGroupedRelationIds($record, $fieldInformation, $context); $sortedFileReferenceIds = array_map(static fn(array $item) => (int)$item['id'], $sortedAndGroupedIds); $unorderedRows = $this->greedyDatabaseBackend->getRows('sys_file_reference', $sortedFileReferenceIds, $context); $unorderedRowsByUid = []; foreach ($unorderedRows as $row) { $unorderedRowsByUid[(int)$row['uid']] = $row; } $fileReferenceObjects = []; foreach ($sortedAndGroupedIds as $item) { if (isset($unorderedRowsByUid[(int)$item['id']])) { $fileReferenceRow = $unorderedRowsByUid[(int)$item['id']]; $fileReferenceObjects[] = $this->resourceFactory->createFileReferenceObject($fileReferenceRow); } } return $fileReferenceObjects; } /** * We currently use the RelationHandler to resolve all records attached to a given field. * @todo This will be replaced by querying the RefIndex directly in the future. * * @return array> */ protected function getGroupedRelationIds(RecordInterface $record, FieldTypeInterface $fieldInformation, Context $context): array { $rawRecord = $record instanceof Record ? $record->getRawRecord() : $record; $recordData = $rawRecord->toArray(); $relationHandler = GeneralUtility::makeInstance(RelationHandler::class); $relationHandler->setWorkspaceId($context->getPropertyFromAspect('workspace', 'id', 0)); if ($rawRecord instanceof RawRecord && $rawRecord->getComputedProperties()->getLocalizedUid() > 0) { $relationHandler->initializeForField($record->getMainType(), $fieldInformation, $rawRecord->getComputedProperties()->getLocalizedUid(), $recordData[$fieldInformation->getName()] ?? null); } else { $relationHandler->initializeForField($record->getMainType(), $fieldInformation, $recordData, $recordData[$fieldInformation->getName()] ?? null); } $relationHandler->processDeletePlaceholder(); return $relationHandler->itemArray; } /** * Find the relations relevant for this field. This could be multiple tables! * * Note: While $necessaryRelationsOfRequestedField is sorted, the result will be the plain unsorted database rows. * * @return array}>> */ protected function getRelationalRows(array $necessaryRelationsOfRequestedField, Context $context): array { $finalRows = []; foreach ($necessaryRelationsOfRequestedField as $dbTable => $uids) { // Let's loop over all tables, and fetch all records of the PIDs of the given UIDs in a greedy way $rows = $this->greedyDatabaseBackend->getRows($dbTable, $uids, $context); foreach ($rows as $row) { $finalRows[$dbTable][(int)$row['uid']] = [ 'table' => $dbTable, 'row' => $row, ]; } } return $finalRows; } }