Hi everyone,
since I’ve been sitting over this issue for at least 2 days while digging into the Shopware Core I now decided to try my luck here.
First off you should know that I still use the legacy plugin system since I need to support older Shopware versions.
The following two file plugin should give you an idea, what I do in a bigger scale:
Bootstrap.php:
get('Loader')->registerNamespace('Shopware\\Plugins\\DemoPlugin', $this->Path());
}
protected function registerEvents()
{
$this->subscribeEvent('Enlight_Controller_Front_DispatchLoopStartup', 'onDispatchLoopStartup');
}
public function onDispatchLoopStartup(Enlight_Event_EventArgs $args)
{
// Add new Subscriber
$this->Application()->Events()->addSubscriber(
new \Shopware\Plugins\DemoPlugin\Subscribers\CronJobs($this, Shopware()->Container())
);
}
/**
* Custom cron job register logic, since Shopware just adds cronjobs without a check if they exist already.
* Until they fail to execute later...
*/
public function registerCronJobs()
{
// Define cronjobs here with the action as the key
$cronJobs = [
'DemoPluginCron' => [
'name' => 'DemoPlugin Cron',
'interval' => 600,
'active' => 1,
'disableOnError' => false,
],
];
// Get already created cronjobs
$sql = "SELECT `action` FROM `s_crontab` WHERE `pluginID` = ?";
$dbJobs = Shopware()->Db()->fetchCol($sql, array($this->getId()));
if($dbJobs == null) {
$dbJobs = array();
} else {
// Remove prefix "Shopware_CronJob_" from the actions of the jobs in the DB
array_walk($dbJobs, function(&$element, $key, $prefix) {
$element = str_replace($prefix, '', $element);
}, 'Shopware_CronJob_');
}
// Difference between our cronjobs and the jobs in the DB
$jobsToCreate = array_diff(array_keys($cronJobs), $dbJobs);
// Now create all jobs that were not in the DB
foreach ($jobsToCreate as $jobAction) {
$job = $cronJobs[$jobAction];
$this->createCronJob(
$job['name'],
$jobAction,
$job['interval'],
$job['active'],
$job['disableOnError']
);
}
}
public function unRegisterCronJobs()
{
$sql = "DELETE FROM s_crontab WHERE pluginID = ?";
Shopware()->Db()->query($sql, array($this->getId()));
}
/* Irrelevant functions */
/**
* Perform all necessary install tasks
*
* @param $update bool
*
* @return array
*/
public function install($update = false)
{
$this->registerEvents();
try {
$this->registerCronJobs();
} catch (Exception $e) {
// check if already exists
}
return array('success' => true, 'invalidateCache' => array('proxy'));
}
/**
* Uninstall method
*
* @param $removeAttributes bool
*
* @return boolean
*/
public function uninstall($removeAttributes = false)
{
$this->unRegisterCronJobs();
return true;
}
/**
* Update plugin, check previous versions
*
* @param $oldVersion string
*
* @return array
*/
public function update($oldVersion)
{
return $this->install(true);
}
/**
* Activation method
*
* @return array
*/
public function enable()
{
return array(
'success' => true,
'invalidateCache' => array('proxy'),
);
}
/**
* Disabling method
*
* @return array
*/
public function disable()
{
return array(
'success' => true,
'invalidateCache' => array('proxy'),
);
}
/**
* Deactivation method
*
* @return array
*/
public function deactivate(DeactivateContext $deactivateContext)
{
$deactivateContext->scheduleClearCache(DeactivateContext::CACHE_LIST_ALL);
}
/**
* Returns list of actions this plugin is capable of
*
* @return array
*/
public function getCapabilities()
{
return array(
'install' => true,
'update' => true,
'enable' => true
);
}
/**
* Returns the information about this plugin as array.
*
* @return array
* @throws Exception
*/
public function getInfo()
{
return array(
'label' => "Demo Plugin",
'author' => "Vincent Mrose",
'version' => $this->getVersion(),
'description' => "Demo Plugin",
'solution_name' => "demoplugin"
);
}
/**
* Returns the version of this plugin
*
* @return string
* @throws Exception
*/
public function getVersion()
{
return "1.0.0";
}
/**
* Returns plugin label
*
* @throws Exception
* @return string
*/
public function getLabel()
{
return "Demo Plugin";
}
}
Note the event “Enlight_Controller_Front_DispatchLoopStartup” I subscribe to, to add my Subscriber.
CronJob Subscriber:
bootstrap = $bootstrap;
$this->container = $container;
}
/**
* returns array with subscribed events
*
* @return array
*/
public static function getSubscribedEvents()
{
return array(
'Shopware_CronJob_DemoPluginCron' => 'onCronRun',
);
}
/**
* Cron Run function
*
* @param \Enlight_Event_EventArgs $args
*
* @return mixed
*/
public function onCronRun(\Enlight_Event_EventArgs $args)
{
$logger = $this->container->get('pluginlogger');
$logger->info('DemoPlugin Cron was executed');
}
}
Now when you install and activate this plugin and execute the console command
./bin/console sw:cron:run -f “Shopware_CronJob_DemoPluginCron”
to run the cron it should cause the plugins constructor to write “Demo Plugin got loaded, yay” to the php error log and to write a plugin log entry “DemoPlugin Cron was executed”.
However it does not do any of that in my installation of Shopware 5.6.2.
Only when I execute it via the /backend/cron endpoint it triggers those logging statements.
So my questions are:
Why is the cron subscriber not triggered when the cron:run command is run and only when I do it via /backend/cron?
Does this have to do with the event I use to add my Subscriber (“Enlight_Controller_Front_DispatchLoopStartup”)?
If so, which event should I subscribe to, to get my cronjob executed correctly?
Or am I not able to use separate files for Subscribers in conjunction with the command?