ew_base/Classes/Updates/ParentChildToContainerService.php
Sebastian Fischer 5319bd35a5 First commit
2024-02-09 17:13:28 +01:00

169 lines
5.0 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace Evoweb\EwBase\Updates;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Service\FlexFormService;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentColPosOffset'] = 0;
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentMigrationMapping'] = [
'downloads' => [ 'CType' => 'container-downloads' ],
];
*/
class ParentChildToContainerService
{
private const TABLE_NAME = 'tt_content';
protected int $colPosOffset = 0;
protected array $configuration = [];
public function __construct(
protected ConnectionPool $connectionPool,
protected DataHandler $dataHandler,
protected FlexFormService $flexFormService,
) {
$config =& $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base'];
$this->colPosOffset = $config['childParentColPosOffset'] ?? 0;
$this->configuration = $config['childParentMigrationMapping'] ?? [];
}
public function migrate(): void
{
$this->initializeDataHandler();
$this->migrateConfiguredContainer();
}
protected function initializeDataHandler(): void
{
$backendUser = GeneralUtility::makeInstance(BackendUserAuthentication::class);
$backendUser->user = [
'uid' => 0,
'admin' => 1,
];
$this->dataHandler->start([], [], $backendUser);
}
protected function migrateConfiguredContainer(): void
{
array_walk($this->configuration, function($config, $key) {
$parents = $this->getParentsByCType((string)$key);
foreach ($parents as $parent) {
$this->processParentMigration($parent, $config);
}
});
}
protected function processParentMigration(array $parent, array $config): void
{
$children = $this->getChildren($parent['uid']);
foreach ($children as $child) {
$this->processChildMigration($child, $parent);
}
$this->updateElement(
$parent['uid'],
[
'CType' => $this->getCType($parent, $config),
'children' => 0,
]
);
}
protected function processChildMigration(array $child, array $parent): void
{
$this->updateElement(
$child['uid'],
[
'tx_container_parent' => $parent['uid'],
'colPos' => $child['colPos'] + $this->colPosOffset,
'parent' => 0,
]
);
}
protected function getCType(array $container, array $config): string
{
if (is_array($config['CType'])) {
$value = ArrayUtility::getValueByPath($container, $config['CType']['search']);
$result = $config['CType']['matches'][$value] ?? null;
} else {
$result = $config['CType'] ?? null;
}
if (empty($result)) {
throw new \Exception('CType must always be set');
}
return $result;
}
protected function updateElement(int $uid, array $changes): void
{
$this->connectionPool
->getConnectionForTable(self::TABLE_NAME)
->update(self::TABLE_NAME, $changes, ['uid' => $uid]);
}
protected function getChildren(int $parentUid): array
{
$queryBuilder = $this->getQueryBuilderForTable();
return $queryBuilder
->select('*')
->where(
$queryBuilder->expr()->eq(
'parent',
$queryBuilder->createNamedParameter($parentUid, \PDO::PARAM_INT)
)
)
->orderBy('sorting')
->executeQuery()
->fetchAllAssociative();
}
protected function getParentsByCType(string $cType): array
{
$queryBuilder = $this->getQueryBuilderForTable();
$expr = $queryBuilder->expr();
return $queryBuilder
->select('*')
->where(
$expr->eq('CType', $queryBuilder->createNamedParameter($cType))
)
->orderBy('sorting')
->executeQuery()
->fetchAllAssociative();
}
protected function getQueryBuilderForTable(string $table = 'tt_content'): QueryBuilder
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
$queryBuilder->from($table);
return $queryBuilder;
}
}