Skip to content

Commit 60bd1f1

Browse files
committed
[TASK] Add migration wizard for switching to new Scheduler task class, resolves #403
1 parent bde40e1 commit 60bd1f1

4 files changed

Lines changed: 138 additions & 0 deletions

File tree

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2026-08-08 Francois Suter (Idéative) <typo3@ideative.ch>
2+
3+
* Add migration wizard for switching to new Scheduler task class, resolves #403
4+
15
2026-08-07 Francois Suter (Idéative) <typo3@ideative.ch>
26

37
* Support TYPO3 14, adapt to Scheduler changes, resolves #396
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the TYPO3 CMS project.
7+
*
8+
* It is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU General Public License, either version 2
10+
* of the License, or any later version.
11+
*
12+
* For the full copyright and license information, please read the
13+
* LICENSE.txt file that was distributed with this source code.
14+
*
15+
* The TYPO3 project - inspiring people to share!
16+
*/
17+
18+
namespace Cobweb\ExternalImport\Upgrades;
19+
20+
use Cobweb\ExternalImport\Domain\Model\ConfigurationKey;
21+
use Cobweb\ExternalImport\Task\AutomatedSyncTask;
22+
use Cobweb\ExternalImport\Task\SynchronizationTask;
23+
use TYPO3\CMS\Core\Attribute\UpgradeWizard;
24+
use TYPO3\CMS\Core\Database\ConnectionPool;
25+
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
26+
use TYPO3\CMS\Core\Upgrades\DatabaseUpdatedPrerequisite;
27+
use TYPO3\CMS\Core\Upgrades\UpgradeWizardInterface;
28+
use TYPO3\CMS\Scheduler\Task\TaskSerializer;
29+
30+
/**
31+
* Migrate from old to new synchronization task.
32+
*
33+
* TODO: remove in next major version
34+
*/
35+
#[UpgradeWizard('externalImport_schedulerTaskMigration')]
36+
final class SchedulerTaskMigration implements UpgradeWizardInterface
37+
{
38+
public function __construct(
39+
private ConnectionPool $connectionPool,
40+
protected TaskSerializer $taskSerializer,
41+
) {}
42+
43+
public function getTitle(): string
44+
{
45+
return 'Migrate old AutomatedSyncTask to newer SynchronizationTask';
46+
}
47+
48+
public function getDescription(): string
49+
{
50+
return '
51+
Extract information from existing Scheduler entries, change task type and set information in a structured way.
52+
Please execute "Migrate the contents of the tx_scheduler_task database table into a more structured form" wizard first.
53+
';
54+
}
55+
56+
/**
57+
* @throws \Doctrine\DBAL\Exception
58+
* @throws \JsonException
59+
*/
60+
public function executeUpdate(): bool
61+
{
62+
$failures = 0;
63+
$queryBuilder = $this->getQueryBuilder();
64+
$tasks = $queryBuilder->select('*')
65+
->from('tx_scheduler_task')
66+
->where(
67+
$queryBuilder->expr()->eq(
68+
'tasktype',
69+
$queryBuilder->createNamedParameter(AutomatedSyncTask::class)
70+
)
71+
)
72+
->executeQuery()
73+
->fetchAllAssociative();
74+
foreach ($tasks as $task) {
75+
$parameters = json_decode($task['parameters'], true, 512, JSON_THROW_ON_ERROR);
76+
$configurationKey = new ConfigurationKey();
77+
$configurationKey->setTableAndIndex($parameters['table'], (string)$parameters['index']);
78+
$queryBuilder = $this->getQueryBuilder();
79+
$result = $queryBuilder->update('tx_scheduler_task')
80+
->set('tasktype', SynchronizationTask::class)
81+
->set('sync_item', $configurationKey->getConfigurationKey())
82+
->set('sync_storage', $task['parameters']['storage'] ?? 0)
83+
->where(
84+
$queryBuilder->expr()->eq('uid', $task['uid'])
85+
)
86+
->executeStatement();
87+
if ($result < 1) {
88+
$failures++;
89+
}
90+
}
91+
return $failures === 0;
92+
}
93+
94+
/**
95+
* Return true if at least on task of type AutomatedSyncTask is found
96+
*
97+
* @throws \Doctrine\DBAL\Exception
98+
*/
99+
public function updateNecessary(): bool
100+
{
101+
$queryBuilder = $this->getQueryBuilder();
102+
$tasks = $queryBuilder->count('tasktype')
103+
->from('tx_scheduler_task')
104+
->where(
105+
$queryBuilder->expr()->eq(
106+
'tasktype',
107+
$queryBuilder->createNamedParameter(AutomatedSyncTask::class)
108+
)
109+
)
110+
->executeQuery()
111+
->fetchOne();
112+
return $tasks > 0;
113+
}
114+
115+
public function getPrerequisites(): array
116+
{
117+
return [DatabaseUpdatedPrerequisite::class];
118+
}
119+
120+
protected function getQueryBuilder(): QueryBuilder
121+
{
122+
return $this->connectionPool->getQueryBuilderForTable('tx_scheduler_task');
123+
}
124+
}
121 KB
Loading

Documentation/Installation/Index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ to admin users. Rather than trying to work around this even more than what was d
3131
adding, editing and deleting Scheduler tasks from the External Import backend module has been
3232
restricted to admin users.
3333

34+
Another consequence of this restructuring is that a new Scheduler task :php:`Cobweb\ExternalImport\Task\SynchronizationTask`
35+
replacing :php:`Cobweb\ExternalImport\Task\AutomatedSyncTask` with a cleaner structure.
36+
An upgrade wizard is provided for migrating registered Scheduler task from the old type to the new type.
37+
General Scheduler migration wizard must have been run before.
38+
39+
.. figure:: ../Images/SchedulerTaskMigration.png
40+
:alt: Scheduler task upgrade wizard
41+
42+
Upgrade wizard indicating that there are old synchronization tasks to migrate
43+
3444

3545
.. _installation-upgrade-820:
3646

0 commit comments

Comments
 (0)