getConnectionForTable('sys_registry'); // Get all extensionDataImport registry entries $queryBuilder = $connection->createQueryBuilder(); $result = $queryBuilder ->select('entry_key', 'entry_value') ->from('sys_registry') ->where( $queryBuilder->expr()->eq( 'entry_namespace', $queryBuilder->createNamedParameter('extensionDataImport') ) ) ->orderBy('uid') ->executeQuery(); $registry = GeneralUtility::makeInstance(Registry::class); while ($row = $result->fetchAssociative()) { $oldKey = $row['entry_key']; $value = $row['entry_value']; if ($oldKey === '') { continue; } // Skip entries that already use the new format (contain ":") if (str_contains($oldKey, ':') && !str_starts_with($oldKey, 'EXT:')) { continue; } $newKey = $this->convertPathToExtensionKey($oldKey); if ($newKey !== null && $newKey !== $oldKey) { // Set the new key with the same value $registry->set('extensionDataImport', $newKey, unserialize($value, ['allowed_classes' => false])); // Remove the old key $registry->remove('extensionDataImport', $oldKey); } } return true; } public function updateNecessary(): bool { $connection = GeneralUtility::makeInstance(ConnectionPool::class) ->getConnectionForTable('sys_registry'); $queryBuilder = $connection->createQueryBuilder(); $count = $queryBuilder ->count('*') ->from('sys_registry') ->where( $queryBuilder->expr()->eq( 'entry_namespace', $queryBuilder->createNamedParameter('extensionDataImport') ), $queryBuilder->expr()->notLike( 'entry_key', $queryBuilder->createNamedParameter('%:%') ) ) ->executeQuery() ->fetchOne(); return $count > 0; } public function getPrerequisites(): array { return [ CoreDatabaseUpdatedPrerequisite::class, ]; } /** * Convert a path-based registry key to an extension key-based format */ protected function convertPathToExtensionKey(string $pathKey): ?string { // Pattern 1: typo3conf/ext/... or typo3/sysext/... if (preg_match('#^(?:typo3conf/ext|typo3/sysext)/([^/]+)/(.+)$#', $pathKey, $matches)) { $extensionKey = $matches[1]; $filePart = $matches[2]; return $extensionKey . ':' . $filePart; } // Pattern 2: EXT:extension_name/... if (preg_match('#^EXT:([^/]+)/(.+)$#', $pathKey, $matches)) { $extensionKey = $matches[1]; $filePart = $matches[2]; return $extensionKey . ':' . $filePart; } // Pattern 3: composer-based mode (vendor/...), in this case we take the last path part before // "Initialisation/Files" or "ext_tables_static+adt.sql" $pathSegments = GeneralUtility::revExplode('/', $pathKey, 2); if (count($pathSegments) !== 2) { return null; } if ($pathSegments[1] === 'Files' || $pathSegments[1] === 'dataImported') { $pathSegments[0] = GeneralUtility::revExplode('/', $pathSegments[0], 2)[0]; $pathSegments[1] = 'Initialisation/' . $pathSegments[1]; } if (preg_match('#^([^/]+)/(.+)$#', $pathSegments[0], $matches) && in_array($pathSegments[1], ['Initialisation/Files', 'Initialisation/dataImported', 'ext_tables_static+adt.sql'])) { $extensionKey = (GeneralUtility::revExplode('/', $matches[0], 2)[1] ?? ''); $extensionKey = str_replace('-', '_', $extensionKey); // Normalize dashes to underscores if (str_starts_with($extensionKey, 'cms_')) { $extensionKey = substr($extensionKey, strlen('cms_')); } $filePart = $pathSegments[1]; return $extensionKey . ':' . $filePart; } return null; } }