Không dễ như tôi tưởng.
Trước tiên, bạn cần cập nhật crontab.xml
để thiết lập đường dẫn cấu hình theo tần số của bạn:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../app/code/Magento/Cron/etc/crontab.xsd">
<group id="default">
<job name="tm-feed-job" instance="TM\Feed\Model\Cron" method="export">
<config_path>crontab/default/jobs/tm_feed_job/schedule/cron_expr</config_path>
</job>
</group>
</config>
Bây giờ bạn cần thêm một trường vào cấu hình để có thể chọn tần số trong adminhtml/system.xml
:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="vendor">
<group id="module" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Cron 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>Vendor\Module\Model\Config\Backend\Frequency</backend_model>
</field>
<field id="time" translate="label" type="time" sortOrder="2" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Start Time</label>
</field>
</group>
</section>
</system>
</config>
Bây giờ chúng ta cần tạo Vendor\Module\Model\Config\Backend\Frequency
cho mô hình phụ trợ tần số:
<?php
namespace Vendor\Module\Model\Config\Backend;
class Frequency extends \Magento\Framework\App\Config\Value
{
/**
* Cron string path
*/
const CRON_STRING_PATH = 'crontab/default/jobs/tm_feed_job/schedule/cron_expr';
/**
* Cron model path
*/
const CRON_MODEL_PATH = 'crontab/default/jobs/tm_feed_job/run/model';
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
protected $_configValueFactory;
/**
* @var string
*/
protected $_runModelPath = '';
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$runModelPath = '',
array $data = []
) {
$this->_runModelPath = $runModelPath;
$this->_configValueFactory = $configValueFactory;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* {@inheritdoc}
*
* @return $this
* @throws \Exception
*/
public function afterSave()
{
$time = $this->getData('groups/module/fields/time/value');
$frequency = $this->getData('groups/module/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();
}
}
Mã này thoạt nhìn có vẻ khó khăn nhưng về cơ bản nó tạo ra crontab/default/jobs/tm_feed_job/schedule/cron_expr
đường dẫn cấu hình dựa trên những gì bạn đã chọn trong trình đơn thả xuống tần số.
Tìm kiếm ghi chú bên thú vị: điều này được triển khai cho một vài mô-đun trong M2 nguyên bản bao gồm tiền tệ, cảnh báo sản phẩm, sao lưu, sơ đồ trang web. Điều thú vị là nơi mô hình phụ trợ được xác định cho một số mô-đun đó:
- Thông báo sản phẩm:
Magento\Cron\Model\Config\Backend\Product\Alert
- Sơ đồ trang web:
Magento\Cron\Model\Config\Backend\Sitemap
Vì vậy, yeah bạn đọc nó đúng. Thay vì nằm trong thư mục mô-đun tương ứng, các mô hình phụ trợ này được đặt trong Magento\Cron
thư mục mô-đun.