mirror of
https://github.com/werkraum-media/events.git
synced 2024-11-23 00:56:11 +01:00
267 lines
8 KiB
PHP
267 lines
8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
namespace WerkraumMedia\Events\Updates;
|
|
|
|
use Exception;
|
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
|
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
|
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
|
use TYPO3\CMS\Core\Log\Logger;
|
|
use TYPO3\CMS\Core\Log\LogManager;
|
|
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
|
|
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
|
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
|
|
|
#[UpgradeWizard(MigrateOldLocations::class)]
|
|
class MigrateOldLocations implements UpgradeWizardInterface
|
|
{
|
|
private readonly Logger $logger;
|
|
|
|
private array $uidsForTranslation = [];
|
|
|
|
public function __construct(
|
|
private readonly ConnectionPool $connectionPool,
|
|
private readonly DataHandler $dataHandler,
|
|
LogManager $logManager
|
|
) {
|
|
$this->logger = $logManager->getLogger(self::class);
|
|
}
|
|
|
|
public function getTitle(): string
|
|
{
|
|
return 'Migrate EXT:event location data.';
|
|
}
|
|
|
|
public function getDescription(): string
|
|
{
|
|
return 'Checks for legacy location data stored within events and will create dedicated location records and relations.';
|
|
}
|
|
|
|
public function updateNecessary(): bool
|
|
{
|
|
return $this->hasOldColumns()
|
|
&& $this->getQueryBuilder()->count('*')->executeQuery()->fetchOne() > 0;
|
|
}
|
|
|
|
public function executeUpdate(): bool
|
|
{
|
|
$result = $this->getQueryBuilder()->executeQuery()->iterateAssociative();
|
|
foreach ($result as $eventRecord) {
|
|
$this->logger->info('Updating event record.', ['record' => $eventRecord]);
|
|
$eventRecord['location'] = $this->getLocationUid($eventRecord);
|
|
$this->uidsForTranslation[$eventRecord['uid'] . '-' . $eventRecord['sys_language_uid']] = $eventRecord['location'];
|
|
$this->updateEvent($eventRecord);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private function getLocationUid(array $event): int
|
|
{
|
|
$existingUid = $this->getExitingLocationUid($event);
|
|
if ($existingUid > 0) {
|
|
$this->logger->info('Location already exists', ['uid' => $existingUid, 'event' => $event]);
|
|
return $existingUid;
|
|
}
|
|
|
|
return $this->createLocation($event);
|
|
}
|
|
|
|
private function getExitingLocationUid(array $event): int
|
|
{
|
|
$columns = [
|
|
'sys_language_uid',
|
|
'name',
|
|
'street',
|
|
'district',
|
|
'city',
|
|
'zip',
|
|
'country',
|
|
'phone',
|
|
'latitude',
|
|
'longitude',
|
|
];
|
|
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_location');
|
|
$qb->select('uid', 'l10n_parent');
|
|
$qb->from('tx_events_domain_model_location');
|
|
foreach ($columns as $column) {
|
|
$qb->andWhere($qb->expr()->eq($column, $qb->createNamedParameter($event[$column])));
|
|
}
|
|
|
|
$uids = $qb->executeQuery()->fetchAssociative();
|
|
if (is_bool($uids)) {
|
|
return 0;
|
|
}
|
|
|
|
return $uids['l10n_parent'] ?: $uids['uid'];
|
|
}
|
|
|
|
private function createLocation(array $event): int
|
|
{
|
|
$this->logger->info('Location will be created.', ['event' => $event]);
|
|
|
|
$columnsToMap = [
|
|
'pid',
|
|
'sys_language_uid',
|
|
'name',
|
|
'street',
|
|
'district',
|
|
'city',
|
|
'zip',
|
|
'country',
|
|
'phone',
|
|
'latitude',
|
|
'longitude',
|
|
];
|
|
$record = [];
|
|
|
|
foreach ($columnsToMap as $columnName) {
|
|
$record[$columnName] = $event[$columnName];
|
|
}
|
|
$recordUid = 'NEW12121';
|
|
$l10nParentUid = $this->uidsForTranslation[$event['l10n_parent'] . '-0'] ?? 0;
|
|
$dataHandler = clone $this->dataHandler;
|
|
|
|
if ($event['sys_language_uid'] > 0 && $l10nParentUid > 0) {
|
|
$this->logger->info('Foreign language, create translation.', [
|
|
'l10nParentUid' => $l10nParentUid,
|
|
'event' => $event,
|
|
]);
|
|
|
|
$dataHandler->start([], [
|
|
'tx_events_domain_model_location' => [
|
|
$l10nParentUid => [
|
|
'localize' => $event['sys_language_uid'],
|
|
],
|
|
],
|
|
]);
|
|
$dataHandler->process_cmdmap();
|
|
$recordUid = $dataHandler->copyMappingArray_merged['tx_events_domain_model_location'][$l10nParentUid] ?? 0;
|
|
}
|
|
|
|
$this->logger->info('Create or update loation.', [
|
|
'recordUid' => $recordUid,
|
|
'l10nParentUid' => $l10nParentUid,
|
|
'event' => $event,
|
|
'record' => $record,
|
|
]);
|
|
|
|
$dataHandler->start([
|
|
'tx_events_domain_model_location' => [
|
|
$recordUid => $record,
|
|
],
|
|
], []);
|
|
$dataHandler->process_datamap();
|
|
|
|
$uid = $dataHandler->substNEWwithIDs[$recordUid] ?? 0;
|
|
$this->logger->info('Created or updated location.', [
|
|
'uid' => $uid,
|
|
]);
|
|
if ($uid > 0) {
|
|
return $uid;
|
|
}
|
|
if ($l10nParentUid > 0) {
|
|
return $l10nParentUid;
|
|
}
|
|
|
|
throw new Exception('Could not create location: ' . implode(', ', $dataHandler->errorLog), 1672916613);
|
|
}
|
|
|
|
private function updateEvent(array $event): void
|
|
{
|
|
$this->connectionPool
|
|
->getConnectionForTable('tx_events_domain_model_event')
|
|
->update(
|
|
'tx_events_domain_model_event',
|
|
['location' => $event['location']],
|
|
['uid' => $event['uid']]
|
|
)
|
|
;
|
|
}
|
|
|
|
private function getQueryBuilder(): QueryBuilder
|
|
{
|
|
$columns = $this->columnsToFetch();
|
|
|
|
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_event');
|
|
$qb->getRestrictions()->removeAll();
|
|
$qb->select(...$columns);
|
|
$qb->addSelect('uid', 'pid', 'sys_language_uid', 'l10n_parent');
|
|
$qb->from('tx_events_domain_model_event');
|
|
foreach ($columns as $columnName) {
|
|
$qb->orWhere($qb->expr()->neq($columnName, $qb->createNamedParameter('')));
|
|
}
|
|
$qb->orderBy('sys_language_uid', 'ASC');
|
|
$qb->addOrderBy('l10n_parent', 'ASC');
|
|
$qb->addOrderBy('uid', 'ASC');
|
|
|
|
return $qb;
|
|
}
|
|
|
|
public function getIdentifier(): string
|
|
{
|
|
return self::class;
|
|
}
|
|
|
|
public function getPrerequisites(): array
|
|
{
|
|
return [
|
|
DatabaseUpdatedPrerequisite::class,
|
|
];
|
|
}
|
|
|
|
private function hasOldColumns(): bool
|
|
{
|
|
$schema = $this->connectionPool
|
|
->getConnectionForTable('tx_events_domain_model_event')
|
|
->getSchemaInformation()
|
|
->introspectTable('tx_events_domain_model_event')
|
|
;
|
|
|
|
foreach ($this->columnsToFetch() as $column) {
|
|
if ($schema->hasColumn($column) === false) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return string[]
|
|
*/
|
|
private function columnsToFetch(): array
|
|
{
|
|
return [
|
|
'name',
|
|
'street',
|
|
'district',
|
|
'city',
|
|
'zip',
|
|
'country',
|
|
'phone',
|
|
'latitude',
|
|
'longitude',
|
|
];
|
|
}
|
|
}
|