Scheduler Tasks
Kommandos ausführen
Kommandos können via Scheduler ausgeführt werden und so Tasks im Hintergrund erledigen.
commandControllers
Die commandControllers wurden wieder abgelöst von Symfony\Component\Console\Command\Command. Leider ist es dadurch alles wieder komplizierter geworden, vor allem der Zugriff auf die TYPO3 Unmgebung ist nihct mehr so einfach. ich versuche hier einen kurzen Überblick zu geben über die wesentliche Verwendung der Symfony Command basierten Routinen für den Scheduler. Die Doku der commandControllers ist hier im Archiv.
Konfiguration
Zunächst in der Datei Configuration/Services.yaml das Command registrieren:
services:
RSYS\RsystemplateBootstrap\Command\CleanAdressesCommand:
tags:
- name: console.command
command: rsystemplate_bootstrap:cleanadresses
identifier: 'rsystemplate_bootstrap:cleanadresses'
schedulable: true
Dann die Klasse anlegen in Classes/Commend/CleanAdressesCommand.php - hier erst mal das Gerüst, ohne Methoden:
<?php
namespace RSYS\RsystemplateBootstrap\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Core\Bootstrap;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use RSYS\RsystemplateBootstrap\Utility\ArrayUtility;
class CleanAdressesCommand extends Command {
/**
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
*/
protected $configurationManager;
/**
* TS settings
* @var Array
*/
protected $settings=Array();
}
Methoden
Konfiguration
/**
* Configure the command by defining the name, options and arguments
*/
protected function configure()
{
$this->setDescription('Clean address records for non-confirmed addresses to be deleted.');
$this->setHelp('Clean address records.' . LF . 'If you want to get more detailed information, use the --verbose option.');
$this->addOption(
'dry-run',
null,
InputOption::VALUE_NONE,
'If this option is set, the records will not actually be deleted, but just the output which records would be deleted are shown'
);
}
Hauptfunktion
Hier der Rahmen der Einstiegs Funktion:
/**
* Executes the command for showing sys_log entries
*
* @param InputInterface $input
* @param OutputInterface $output
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
...
# this must be 0
return 0;
}
Innerhalb dieser Funktion hier einige wichtige Code Schnipsel:
Konfiguration
$this->configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class);
// settings
$typoscriptFull = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
$this->settings = ArrayUtility::replaceKeys($typoscriptFull['plugin.']['tx_rsystemplatebootstrap.']['settings.']);
Optionen
Am Beispiel der DryRun Option:
// type unsafe comparison and explicit boolean setting on purpose
$dryRun = $input->hasOption('dry-run') && $input->getOption('dry-run') != false ? true : false;
Aktion
Hier eine Beispiel Aktion zum löschen von Adressen:
$addressesDeleted = $this->removeDeleted($dryRun);
if(count($addressesDeleted) > 0) {
$io->text('Deleted ' . count($addressesDeleted) . ' records.');
}
Der Code $io->text gibt Text aus wenn man es von der Konsole aus startet
Die Löschroutine
protected function removeDeleted($dryRun)
{
// Register page
$pageIdUnsubscribed = $this->settings['newsletter']['pid']['unsubscribedAddressFolder'];
// Traverse tables of records that belongs to page
$tableName = 'tt_address';
// Select all records belonging to page:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$constraints = [];
$constraints[] = $queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($pageIdUnsubscribed, \PDO::PARAM_INT)
);
$constraints[] = $queryBuilder->expr()->eq(
'deleted',
$queryBuilder->createNamedParameter(1, \PDO::PARAM_INT)
);
$result = $queryBuilder
->select('*')
->from($tableName)
->where(...$constraints)
->execute();
$addressesDeleted = array();
while ($row = $result->fetch()) {
if(isset($row['email'])) {
$entry = array();
$entry['email'] = $row['email'];
$entry['uid'] = $row['uid'];
$entry['pid'] = $row['pid'];
$entry['date'] = date('d.m.Y H:i', $row['tstamp']);
$entry['tstamp'] = $row['tstamp'];
$addressesDeleted[] = $entry;
}
}
// delete !
if(! $dryRun) {
try {
$queryBuilder->delete($tableName)
->where(...$constraints)
->execute();
} catch (\Doctrine\DBAL\DBALException $e) {
}
}
return $addressesDeleted;
}
Zurück kommt ein Array der gelöschten Adressen zur weiteren Verarbeitung, z.B: eine Mail versenden.
Ausführen
Scheduler
Im Scheduler eine Task anlegen, dann auswählen Konsolenbefehle ausführen. Dann kann man nach dem speichern unten den Befehl auswählen (Planbarer Befehl. Speichern und erneut öffnen, um Argumente zu definieren ):
rsystemplate_bootstrap:cleanadresses: Clean address records for non-confirmed addresses to be deleted.
Kommandozeile
Zum Debuggen, oder direkt per Cron kann man den Befehl ausführen wie folgt:
php typo3/sysext/core/bin/typo3 rsystemplate_bootstrap:cleanadresses