Guten Tag liebste Gemeinde,
tldr;
Warum unterscheiden sich die registrierten cron Eventlistener auf CLI und im Browser?
ich habe folgendes Problem. Ich habe diverse SW5.1 und älter Plugins geschrieben welche Cronjobs beinhalten. Registriert wurden sie alle gleich und wie folgt (Bootstrap::install()):
$this->subscribeEvent(
'Shopware_CronJob_MeinCronJob',
'onRunMeinCronJob'
);
Funktioniert beim Großteil der Plugins einwandfrei, und die Cronjobs lassen sich sowohl über den BackendController " https://domain.de/backend/cron" als auch über die CLI ausführen " sw:cron:run -f MeineCronAction". Aber seit kurzem habe ich vermehrt das Problem das einige dieser Cronjobs sich lediglich über den BackendController ausführen lassen. Bei Ausführung über die CLI steht zwar da " Processing MeinCron…", aber er läuft nicht mal in die zugehörige onRun Funktion hinein.
Nach einigem Debuggen habe ich nun festgestellt, dass auf der CLI die benötigten EventListener nicht zur Verfügung stehen und er daher in der EventManager::notifyUntil Funktion direkt am Anfang beim ersten IF statement aussteigt.
public function notifyUntil($event, $eventArgs = null)
{
if (!$this->hasListeners($event)) {
return null;
}
...
Wie gesagt, bei Aufruf über den Cron-BackendController stehen diese aber zur Verfügung und der Cron wird ohne weiteres ausgeführt. Wenn man sich die beiden Cron Anlaufpunkte genauer anschaut, sehen die soweit eigentlich gleich aus.
class Shopware_Controllers_Backend_Cron extends Enlight_Controller_Action implements CSRFWhitelistAware
{
public function init()
{
Shopware()->Plugins()->Backend()->Auth()->setNoAuth();
Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
}
public function indexAction()
{
if (!Shopware()->Plugins()->Core()->Cron()->authorizeCronAction($this->Request())) {
$this->Response()
->clearHeaders()
->setHttpResponseCode(403)
->appendBody('Forbidden');
return;
}
/** @var $cronManager Enlight_Components_Cron_Manager */
$cronManager = Shopware()->Cron();
set_time_limit(0);
while (($job = $cronManager->getNextJob()) !== null) {
echo 'Processing ' . $job->getName() . "\n";
$cronManager->runJob($job);
}
}
...
class CronRunCommand extends ShopwareCommand
{
...
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->registerErrorHandler($output);
$this->container->load('plugins');
/** @var Enlight_Components_Cron_Manager $manager */
$manager = $this->container->get('cron');
$cronjob = $input->getArgument('cronjob');
$force = $input->getOption('force');
if (!empty($cronjob)) {
try {
$this->runSingleCronjob($output, $manager, $cronjob, $force);
} catch (\Exception $e) {
$output->writeln('' . $e->getMessage() . '');
$output->writeln('Please use the action name of a cronjob. You can see existing cronjobs in shopware backend or via sw:cron:list command.');
return 1;
}
return 0;
}
...
}
/**
* @param OutputInterface $output
* @param Enlight_Components_Cron_Manager $manager
* @param string $cronjob
* @param bool $force
*/
private function runSingleCronjob(OutputInterface $output, Enlight_Components_Cron_Manager $manager, $cronjob, $force)
{
$job = $this->getJobByActionName($manager, $cronjob);
if (!$this->allowRun($force, $job)) {
return;
}
$output->writeln('Processing ' . $job->getName());
$manager->runJob($job);
}
...
Systeminfo :
Shopware 5.2.26
PHP: 5.6.30
OS: Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-66-generic x86_64) (Shopware vagrant VM) (tritt aber auch beim Kunden auf)
Webserver: Apache
Die initialisierten Job Objekte sehen identisch aus, und auch wenn ich im CronCommand „$manager = $this->container->get(‚cron‘);“ wie im BackendController über „Shopware()->Cron()“ lade bleibt das Ergebnis das gleiche. Ich habe auch bereits testweise im CronCommand den ShopContext registriert, aber auch das brachte keinen Erfolg.
Bei 5.2 Plugins trat dieses Problem bisher noch nicht auf.
Jemand eine Idee woran das liegen könnte, dass sich die registrierten EventListener zwischen CLI und BackendControllern unterscheiden? Und wie ich bewirke, dass dem nicht so ist?
Beste Grüße
Daniel