Magento 2: how to use a configuration field for the crontab expression?
Following ProductAlerts in M2:
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="catalog_product_alert" instance="Magento\ProductAlert\Model\Observer" method="process">
<config_path>crontab/default/jobs/catalog_product_alert/schedule/cron_expr</config_path>
</job>
</group>
</config>
You should be able to define something similarly:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="custom_job_name" instance="Namespace\Module\Model\Observer" method="process">
<config_path>namespace/module/schedule/cron_expr</config_path>
</job>
</group>
</config>
You could leverage the way they interpret the expression through multiple fields but it shouldn't be required, such as:
<group id="productalert_cron" translate="label" type="text" sortOrder="260" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Product Alerts Run Settings</label>
<field id="frequency" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Frequency</label>
<source_model>Magento\Cron\Model\Config\Source\Frequency</source_model>
<backend_model>Magento\Cron\Model\Config\Backend\Product\Alert</backend_model>
</field>
<field id="time" translate="label" type="time" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Start Time</label>
</field>
This would make the input user-friendly (so-to-speak) but is not required, a simple text field that allows you to enter an expression like 7 7 * * *
would be fine as well, I would just put some validation on that field to make sure the expression is correct.
You can achieve this same as magento 1
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="my_cron" instance="Namespace\Modulename\Observer\Cron" method="execute">
<config_path>section-id/group-id/field-id</config_path>
</job>
</group>
</config>
See code vendor\magento\module-product-alert\etc\crontab.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="catalog_product_alert" instance="Magento\ProductAlert\Model\Observer" method="process">
<config_path>crontab/default/jobs/catalog_product_alert/schedule/cron_expr</config_path>
</job>
</group>
</config>
It is a config path crontab/default/jobs/catalog_product_alert/schedule/cron_expr
it has time schedule value if you see in database core_config_data
vendor\magento\module-cron\Model\Config\Backend\Product\Alert.php
in afterSave function
const CRON_STRING_PATH = 'crontab/default/jobs/catalog_product_alert/schedule/cron_expr';
public function afterSave()
{
$time = $this->getData('groups/productalert_cron/fields/time/value');
$frequency = $this->getData('groups/productalert_cron/fields/frequency/value');
$cronExprArray = [
intval($time[1]), //Minute
intval($time[0]), //Hour
$frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY ? '1' : '*', //Day of the Month
'*', //Month of the Year
$frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_WEEKLY ? '1' : '*', //Day of the Week
];
$cronExprString = join(' ', $cronExprArray);
try {
$this->_configValueFactory->create()->load(
self::CRON_STRING_PATH,
'path'
)->setValue(
$cronExprString
)->setPath(
self::CRON_STRING_PATH
)->save();
$this->_configValueFactory->create()->load(
self::CRON_MODEL_PATH,
'path'
)->setValue(
$this->_runModelPath
)->setPath(
self::CRON_MODEL_PATH
)->save();
} catch (\Exception $e) {
throw new \Exception(__('We can\'t save the cron expression.'));
}
return parent::afterSave();
}
In above function set that config_path value from store > Configuration > Catalog > catalog > Product Alerts Run Settings