DB-field mapping per import model, so editors * configure the mapper once and reuse it on every delivery. * * Plain table without TCA (tx_vitec_import_mapping) - the records are pure * tool configuration, never edited through FormEngine. * * The same row also stores record aliases (CSV identity value -> record * uid) for rows whose name differs slightly from the TYPO3 record, so a * hand-made link survives every future delivery of the same CSV. */ final class MappingRepository { private const TABLE = 'tx_vitec_import_mapping'; /** * @return array{mapping: array, identity: string, aliases: array}|null */ public function load(string $model): ?array { $qb = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::TABLE); $row = $qb->select('mapping', 'identity_field', 'record_aliases')->from(self::TABLE) ->where($qb->expr()->eq('model', $qb->createNamedParameter($model, ParameterType::STRING))) ->setMaxResults(1) ->executeQuery()->fetchAssociative(); if (!$row) { return null; } // A row may exist with aliases only (saveAliases before the first // saveMapping) - an unparsable mapping degrades to [], not to null. $mapping = json_decode((string)$row['mapping'], true); $aliases = json_decode((string)($row['record_aliases'] ?? ''), true); return [ 'mapping' => is_array($mapping) ? array_map('strval', $mapping) : [], 'identity' => (string)$row['identity_field'], 'aliases' => is_array($aliases) ? array_map('intval', $aliases) : [], ]; } /** @param array $mapping */ public function save(string $model, array $mapping, string $identity): void { $values = [ 'mapping' => (string)json_encode($mapping, JSON_UNESCAPED_UNICODE), 'identity_field' => $identity, 'tstamp' => time(), ]; $this->upsert($model, $values); } /** @param array $aliases */ public function saveAliases(string $model, array $aliases): void { $this->upsert($model, [ 'record_aliases' => (string)json_encode($aliases, JSON_UNESCAPED_UNICODE), 'tstamp' => time(), ]); } /** @param array $values */ private function upsert(string $model, array $values): void { $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable(self::TABLE); $exists = $connection->count('uid', self::TABLE, ['model' => $model]) > 0; if ($exists) { $connection->update(self::TABLE, $values, ['model' => $model]); } else { $connection->insert(self::TABLE, $values + [ 'model' => $model, 'pid' => 0, 'crdate' => time(), ]); } } }