diff --git a/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldComment.php b/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldComment.php
new file mode 100644
index 0000000..5dc0ef1
--- /dev/null
+++ b/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldComment.php
@@ -0,0 +1,38 @@
+config = $config;
+
+ parent::__construct($context);
+ }
+
+ /**
+ * @param $elementValue
+ * @return string
+ */
+ public function getCommentText($elementValue)
+ {
+ return 'Cron Expression: none';
+ }
+}
diff --git a/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldConfig.php b/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldConfig.php
new file mode 100644
index 0000000..2d192ad
--- /dev/null
+++ b/Block/Adminhtml/Form/Renderer/Config/ScheduleEveryFieldConfig.php
@@ -0,0 +1,57 @@
+select = $select;
+
+ parent::__construct($context);
+ }
+
+ /**
+ * @param AbstractElement $element
+ * @return string
+ */
+ protected function _getElementHtml(AbstractElement $element) {
+ $name = $element->getName();
+
+ $element->setStyle('width: 100px; margin-right: 20px;')->setName($name . '[]');
+
+ if ($element->getValue()) {
+ $values = explode(',', $element->getValue());
+ } else {
+ $values = [];
+ }
+
+ $field = $element->setValue(isset($values[0]) ? $values[0] : null)->getElementHtml();
+
+ $units = $this->select->setName($name . '[]')
+ ->setStyle('width: 142px;')
+ ->setForm($element->getForm())
+ ->setValues([
+ ['value' => 'min', 'label' => 'minute(s)'],
+ ['value' => 'hour', 'label' => 'hour(s)']
+ ])
+ ->setId('webscale_varnish_flush_cache_schedule_time')
+ ->setValue(isset($values[1]) ? $values[1] : null)
+ ->getElementHtml();
+
+ return '
' . $field . '
'
+ . '' . $units . '
'
+ . '';
+ }
+}
diff --git a/Block/System/Config/Scheduled.php b/Block/System/Config/Scheduled.php
new file mode 100644
index 0000000..2d9d675
--- /dev/null
+++ b/Block/System/Config/Scheduled.php
@@ -0,0 +1,39 @@
+getCacheConfigMessage() . $this->getScheduledConfigMessage();
+ }
+
+ /**
+ * Check if account and application is configured
+ *
+ * @return string
+ */
+ private function getScheduledConfigMessage(): string
+ {
+ return $this->getMessageWrapper(
+ __('Enabling this feature will disable partial cache invalidation.' .
+ ' Full varnish cache flush will be executed instead, according to the cron expression configured below.'
+ ), 'warning'
+ );
+ }
+}
diff --git a/Block/System/Config/Settings.php b/Block/System/Config/Settings.php
index f415f37..339481b 100644
--- a/Block/System/Config/Settings.php
+++ b/Block/System/Config/Settings.php
@@ -6,54 +6,17 @@
namespace Webscale\Varnish\Block\System\Config;
-use Webscale\Varnish\Helper\Config;
-use Magento\Backend\Block\Context;
-use Magento\Backend\Model\Auth\Session;
-use Magento\Config\Block\System\Config\Form\Fieldset;
-use Magento\Framework\View\Helper\Js;
-use Magento\Backend\Model\UrlInterface;
use Magento\PageCache\Model\Config as CacheConfig;
-use Magento\Framework\Data\Form\Element\AbstractElement;
/**
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
*/
-class Settings extends Fieldset
+class Settings extends \Webscale\Varnish\Block\System\Config\SettingsAbstract
{
- /**
- * @var Config $config
- */
- protected $config;
-
- /**
- * @param Context $context
- * @param Session $authSession
- * @param Js $jsHelper
- * @param Config $config
- * @param UrlInterface $urlBuilder
- * @param CacheConfig $cacheConfig
- * @param array $data
- */
- public function __construct(
- Context $context,
- Session $authSession,
- Js $jsHelper,
- Config $config,
- UrlInterface $urlBuilder,
- CacheConfig $cacheConfig,
- array $data = []
- ) {
- $this->config = $config;
- $this->urlBuilder = $urlBuilder;
- $this->cacheConfig = $cacheConfig;
-
- parent::__construct($context, $authSession, $jsHelper, $data);
- }
-
/**
* Return header comment part of html for fieldset
*
- * @param AbstractElement $element
+ * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
@@ -105,22 +68,4 @@ private function getApplicationConfigMessage(): string
return '';
}
-
- /**
- * Get message wrapper
- *
- * @param string $message
- * @param string $severity
- * @return string
- */
- private function getMessageWrapper(string $message = '', string $severity = 'notice'): string
- {
- $html = '';
- $html .= '
';
- $html .= '
';
- $html .= $message;
- $html .= '
';
-
- return $html;
- }
}
diff --git a/Block/System/Config/SettingsAbstract.php b/Block/System/Config/SettingsAbstract.php
new file mode 100644
index 0000000..03cfa0a
--- /dev/null
+++ b/Block/System/Config/SettingsAbstract.php
@@ -0,0 +1,66 @@
+config = $config;
+ $this->urlBuilder = $urlBuilder;
+ $this->cacheConfig = $cacheConfig;
+
+ parent::__construct($context, $authSession, $jsHelper);
+ }
+
+ /**
+ * Get message wrapper
+ *
+ * @param string $message
+ * @param string $severity
+ * @return string
+ */
+ public function getMessageWrapper(string $message = '', string $severity = 'notice'): string
+ {
+ $html = '';
+ $html .= '
';
+ $html .= '
';
+ $html .= $message;
+ $html .= '
';
+
+ return $html;
+ }
+}
diff --git a/Cron/CacheFlushScheduled.php b/Cron/CacheFlushScheduled.php
new file mode 100644
index 0000000..b48d2de
--- /dev/null
+++ b/Cron/CacheFlushScheduled.php
@@ -0,0 +1,58 @@
+config = $config;
+ $this->cacheConfig = $cacheConfig;
+ $this->purgeCache = $purgeCache;
+ }
+
+ /**
+ * @return void
+ */
+ public function execute() {
+ try {
+ if (
+ $this->cacheConfig->getType() == CacheConfig::VARNISH
+ && $this->config->isAvailable()
+ && !empty($this->config->getCronExpression())
+ ) {
+ $this->purgeCache->sendPurgeRequest(['tagsPattern' => ['.*'], 'event' => self::EVENT_NAME]);
+ $this->config->log('Executed scheduled varnish cache flush.');
+ }
+ } catch (\Exception $e) {
+ $this->config->log('Unable to execute scheduled varnish cache flush.');
+ $this->config->log($e->getMessage() . PHP_EOL . $e->getTraceAsString(), 'critical');
+ }
+
+ }
+}
diff --git a/Documentation/cache-events.png b/Documentation/cache-events.png
new file mode 100644
index 0000000..3cf0b91
Binary files /dev/null and b/Documentation/cache-events.png differ
diff --git a/Documentation/scheduled-full-cache-flush.png b/Documentation/scheduled-full-cache-flush.png
new file mode 100644
index 0000000..3d4215d
Binary files /dev/null and b/Documentation/scheduled-full-cache-flush.png differ
diff --git a/Helper/Config.php b/Helper/Config.php
index ccc898d..a2da7b3 100644
--- a/Helper/Config.php
+++ b/Helper/Config.php
@@ -6,12 +6,12 @@
namespace Webscale\Varnish\Helper;
+use Webscale\Varnish\Model\Config\Source\Cron\Frequency;
+use Webscale\Varnish\Model\Config\Cron\ScheduleFrequency;
use Magento\Framework\App\Config\Storage\WriterInterface;
-use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Module\ModuleListInterface;
-use Webscale\Varnish\Service\Api;
use Webscale\Varnish\Logger\Logger;
class Config extends AbstractHelper
@@ -28,6 +28,9 @@ class Config extends AbstractHelper
public const XML_PATH_EVENTS_PARTIAL = 'webscale_varnish/cache_events/partial_invalidate_events';
+ public const XML_PATH_CACHE_SCHEDULE_EVERY = 'webscale_varnish/flush_cache_schedule/every';
+
+ public const DEFAULT_CRON_EXPRESSION = ['*', '*', '*', '*', '*'];
/** @var ModuleListInterface $moduleList */
private $moduleList;
@@ -108,33 +111,48 @@ public function getApplicationId(): string
}
/**
- * Retrieve flush all events array
+ * Retrieve cache scheduled every
*
* @return array
*/
- public function getEventsFlushAll(): array
+ public function getCacheScheduleEvery(): array
{
- return $this->getEventList(self::XML_PATH_EVENTS_ALL);
+ $every = $this->scopeConfig->getValue(self::XML_PATH_CACHE_SCHEDULE_EVERY);
+
+ return is_array($every) ? $every : explode(',', $every);
}
/**
- * Retrieve partial invalidate events array
+ * Retrieve current value for cron expression
+ *
+ * @return string
+ */
+ public function getCronExpression(): string
+ {
+ return (string) $this->scopeConfig->getValue(ScheduleFrequency::CRON_STRING_PATH);
+ }
+
+ /**
+ * Retrieve flush all events array
*
* @return array
*/
- public function getEventsPartialInvalidate(): array
+ public function getEventsFlushAll(): array
{
- return $this->getEventList(self::XML_PATH_EVENTS_PARTIAL);
+ $events = $this->scopeConfig->getValue(self::XML_PATH_EVENTS_ALL);
+
+ return is_array($events) ? $events : explode(',', $events);
}
/**
- * @param string $scope
+ * Retrieve partial invalidate events array
+ *
* @return array
*/
- public function getEventList($scope): array
+ public function getEventsPartialInvalidate(): array
{
- $events = $this->scopeConfig->getValue($scope);
- if (empty($events)) $events = [];
+ $events = $this->scopeConfig->getValue(self::XML_PATH_EVENTS_PARTIAL);
+
return is_array($events) ? $events : explode(',', $events);
}
@@ -156,7 +174,7 @@ public function getCacheUri(): string
*/
public function generateCacheParams(array $purge = []): array
{
- return [
+ $params = [
'json' => [
'type' => 'invalidate-cache',
'target' => '/v2/applications/' . $this->getApplicationId(),
@@ -166,6 +184,8 @@ public function generateCacheParams(array $purge = []): array
]
],
];
+
+ return $params;
}
/**
@@ -186,6 +206,48 @@ public function getVersion(): string
return $version;
}
+ /**
+ * @param string $value
+ * @return string
+ */
+ public function getCronExpressionByValue($value, $data = ['every' => '', 'hours' => 0, 'minutes' => 0])
+ {
+ switch($value) {
+ case Frequency::CRON_HOURLY:
+ $result = array_replace(self::DEFAULT_CRON_EXPRESSION, ['0']);
+ break;
+ case Frequency::CRON_DAILY:
+ $result = array_replace( self::DEFAULT_CRON_EXPRESSION, [$data['minutes'], $data['hours']]);
+ break;
+ case Frequency::CRON_CUSTOM:
+ $result = $this->getCustomCronExpression($data['every']);
+ break;
+ default:
+ $result = [];
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param array $every
+ * @return array
+ */
+ private function getCustomCronExpression($every = []): array
+ {
+ $result = [];
+
+ if (is_array($every) && !empty($every[0]) && !empty($every[1])) {
+ if ($every[1] == 'hour') {
+ $result = array_replace( self::DEFAULT_CRON_EXPRESSION, ['0', '*/' . $every[0]]);
+ } else if ($every[1] == 'min') {
+ $result = array_replace( self::DEFAULT_CRON_EXPRESSION, ['*/' . $every[0]]);
+ }
+ }
+
+ return $result;
+ }
+
/**
* Write message to custom log
*
diff --git a/Model/Config/Cron/ScheduleFrequency.php b/Model/Config/Cron/ScheduleFrequency.php
new file mode 100644
index 0000000..9f6932f
--- /dev/null
+++ b/Model/Config/Cron/ScheduleFrequency.php
@@ -0,0 +1,137 @@
+_runModelPath = $runModelPath;
+ $this->_configValueFactory = $configValueFactory;
+ $this->config = $config;
+ parent::__construct($context, $registry, $scopeConfig, $cacheTypeList, $resource, $resourceCollection, $data);
+ }
+
+ /**
+ * @return ScheduleFrequency
+ * @throws \Exception
+ */
+ public function afterSave()
+ {
+ $time = $this->getData('groups/flush_cache_schedule/fields/start_time/value');
+ $frequency = $this->getData('groups/flush_cache_schedule/fields/frequency/value');
+ $every = $this->getData('groups/flush_cache_schedule/fields/every/value');
+
+ $cronExprArray = $this->getCronExpressionArray($frequency, $every, $time);
+ $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(__('Can\'t save the cron expression.'));
+ }
+
+ return parent::afterSave();
+ }
+
+ /**
+ * @param string $frequency
+ * @return array
+ */
+ protected function getCronExpressionArray($frequency = '', $every = '', $time = [])
+ {
+ switch ($frequency) {
+ case Frequency::CRON_HOURLY:
+ $cronExprArray = $this->config->getCronExpressionByValue(Frequency::CRON_HOURLY);
+ break;
+ case Frequency::CRON_DAILY:
+ $cronExprArray = $this->config->getCronExpressionByValue(Frequency::CRON_DAILY, [
+ 'hours' => intval($time[0]),
+ 'minutes' => intval($time[1])
+ ]);
+ break;
+ case Frequency::CRON_CUSTOM:
+ $cronExprArray = $this->config->getCronExpressionByValue(Frequency::CRON_CUSTOM, [
+ 'every' => $every
+ ]);
+ break;
+ default:
+ $cronExprArray = [];
+ break;
+ }
+
+ return $cronExprArray;
+ }
+}
diff --git a/Model/Config/Source/Cron/Frequency.php b/Model/Config/Source/Cron/Frequency.php
new file mode 100644
index 0000000..e1ea6b9
--- /dev/null
+++ b/Model/Config/Source/Cron/Frequency.php
@@ -0,0 +1,41 @@
+ __('Disabled'), 'value' => static::CRON_DISABLED],
+ ['label' => __('Hourly'), 'value' => static::CRON_HOURLY],
+ ['label' => __('Daily'), 'value' => static::CRON_DAILY],
+ ['label' => __('Custom'), 'value' => static::CRON_CUSTOM],
+ ];
+ }
+ return self::$options;
+ }
+}
diff --git a/Observer/FlushAllCacheObserver.php b/Observer/FlushAllCacheObserver.php
index c3423ff..3756b7b 100644
--- a/Observer/FlushAllCacheObserver.php
+++ b/Observer/FlushAllCacheObserver.php
@@ -54,6 +54,7 @@ public function execute(Observer $observer): void
if ($this->cacheConfig->getType() == CacheConfig::VARNISH
&& $this->config->isAvailable()
&& in_array($event->getName(), $events)
+ && empty($this->config->getCronExpression())
) {
$this->purgeCache->sendPurgeRequest(['tagsPattern' => ['.*'], 'event' => $event->getName()]);
}
diff --git a/Observer/InvalidateVarnishObserver.php b/Observer/InvalidateVarnishObserver.php
index b85a100..a344da8 100644
--- a/Observer/InvalidateVarnishObserver.php
+++ b/Observer/InvalidateVarnishObserver.php
@@ -62,6 +62,7 @@ public function execute(Observer $observer): void
if ($this->cacheConfig->getType() == CacheConfig::VARNISH
&& $this->config->isAvailable()
&& in_array($event->getName(), $events)
+ && empty($this->config->getCronExpression())
) {
$object = $event->getObject();
$tags = [];
diff --git a/README.md b/README.md
index 280f103..56dce29 100644
--- a/README.md
+++ b/README.md
@@ -40,23 +40,39 @@ Stores > Configuration > Webscale > Varnish
Enable the module by switching `Enabled` to `Yes` under `General Configuration` section and enter `API token` and `Application Id`:
-
+
Save the configuration. After setting up API token and Application Id navigate to `Stores > Configuration > Advanced > System`, open `Full Page Cache` section and select `Varnish` in `Caching Application` field:
-
+
-### Optional
+## Optional
-You can also select `Enable Debug` under `Developer` section - this option will enable more detailed server logs:
+### Debug Mode
-
+You can also select `Enable Debug` under `Developer` section - this will result to more detailed server logs:
+
+
Log file can be found at `MAGENTO_ROOT/var/log/webscale.log`.
+### Cache Events
+
+In this section all the magento observing events listed that is triggering varnish cache flush. By default - all selected, but it can be configured by selecting/deselecting items from list:
+
+
+
+### Scheduled Full Cache Flush
+
+> Enabling this feature will disable partial cache invalidation. Full varnish cache flush will be executed instead, according to the cron expression configured.
+
+
+
+Choose one of the three frequency modes: hourly, daily or custom. Cron expression helper will display configured cron expression to validate.
+
## Managing Varnish Cache
Webscale varnish cache will be flushed by default with all Magento native cache events, partial by tags or full cache flush.
To flush specifically Webscale varnish cache navigate to `System > Tools > Cache Management` and click `Flush Varnish Cache` button under `Additional Cache Management` section:
-
+
diff --git a/composer.json b/composer.json
index 3199850..5c36be9 100644
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,7 @@
"license": [
"MIT"
],
- "version": "1.1.1",
+ "version": "1.2.0",
"require": {
"php": "^7.2 || ^8.1",
"magento/magento2-base": "2.3.* || 2.4.*"
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 6d980af..db8b100 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -54,6 +54,30 @@
1
+
+
+ Webscale\Varnish\Block\System\Config\Scheduled
+
+
+ Webscale\Varnish\Model\Config\Source\Cron\Frequency
+ Webscale\Varnish\Model\Config\Cron\ScheduleFrequency
+
+
+
+
+ Webscale\Varnish\Block\Adminhtml\Form\Renderer\Config\ScheduleEveryFieldConfig
+ required-entry validate-digits
+
+ custom
+
+
+
+
+
+ D
+
+
+
diff --git a/etc/config.xml b/etc/config.xml
index fbc0ec6..04dfbd3 100644
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -19,9 +19,28 @@
+
+
+
+
+
0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/etc/crontab.xml b/etc/crontab.xml
new file mode 100644
index 0000000..f7f0b6b
--- /dev/null
+++ b/etc/crontab.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ crontab/default/jobs/webscale_varnish_cache_flush_scheduled/schedule/cron_expr
+
+
+
diff --git a/etc/module.xml b/etc/module.xml
index b62182d..98bae2d 100644
--- a/etc/module.xml
+++ b/etc/module.xml
@@ -7,5 +7,5 @@
-->
-
+
diff --git a/i18n/en_US.csv b/i18n/en_US.csv
index becc579..a85b055 100644
--- a/i18n/en_US.csv
+++ b/i18n/en_US.csv
@@ -1,8 +1,18 @@
+"Enabling this feature will disable partial cache invalidation. Full varnish cache flush will be executed instead, according to the cron expression configured below.","Enabling this feature will disable partial cache invalidation. Full varnish cache flush will be executed instead, according to the cron expression configured below."
"Magento is configured to use the built-in Full Page Cache. To use Webscale varnish caching please change ""Caching Application"" to ""Varnish Cache"" under the ""Full Page Cache"" tab in System Configuration","Magento is configured to use the built-in Full Page Cache. To use Webscale varnish caching please change ""Caching Application"" to ""Varnish Cache"" under the ""Full Page Cache"" tab in System Configuration"
-"Please configure API Token.","Please configure API Token."
+"Please configure API Token and Application Id.","Please configure API Token and Application Id."
"To be able to use Webscale varnish cache please configure ""Application Id"".","To be able to use Webscale varnish cache please configure ""Application Id""."
"Varnish cache flushed successfully.","Varnish cache flushed successfully."
"There is error occurred while trying to purge varnish cache. Please refer to logs for more information.","There is error occurred while trying to purge varnish cache. Please refer to logs for more information."
+"Can't save the cron expression.","Can't save the cron expression."
+Disabled,Disabled
+Hourly,Hourly
+Daily,Daily
+Custom,Custom
+Minute,Minute
+Hour,Hour
+Day,Day
+"--Please Select--","--Please Select--"
"Flush Varnish Cache","Flush Varnish Cache"
"Webscale varnish cache.","Webscale varnish cache."
Webscale,Webscale
@@ -12,5 +22,12 @@ Enabled,Enabled
Application,Application
"API Token","API Token"
"Application Id","Application Id"
+"Cache Events","Cache Events"
+"Flush All Events","Flush All Events"
+"Partial Invalidate Events","Partial Invalidate Events"
+"Scheduled Full Cache Flush","Scheduled Full Cache Flush"
+Frequency,Frequency
+Every,Every
+Time,Time
Developer,Developer
"Enable Debug","Enable Debug"
diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js
new file mode 100644
index 0000000..379689b
--- /dev/null
+++ b/view/adminhtml/requirejs-config.js
@@ -0,0 +1,9 @@
+/**
+ * Copyright © Webscale. All rights reserved.
+ * See LICENSE for license details.
+ */
+var config = {
+ deps: [
+ "Webscale_Varnish/js/cronexpression"
+ ]
+};
diff --git a/view/adminhtml/web/css/source/_module.less b/view/adminhtml/web/css/source/_module.less
index a11db74..70cf8a1 100644
--- a/view/adminhtml/web/css/source/_module.less
+++ b/view/adminhtml/web/css/source/_module.less
@@ -26,3 +26,9 @@
}
}
}
+
+/** Scheduled Cache Flush */
+#row_webscale_varnish_flush_cache_schedule_start_time td select:nth-of-type(3),
+#row_webscale_varnish_flush_cache_schedule_start_time td span:nth-of-type(2) {
+ display: none;
+}
diff --git a/view/adminhtml/web/js/cronexpression.js b/view/adminhtml/web/js/cronexpression.js
new file mode 100644
index 0000000..c9ae30a
--- /dev/null
+++ b/view/adminhtml/web/js/cronexpression.js
@@ -0,0 +1,72 @@
+/**
+ * Copyright © Webscale. All rights reserved.
+ * See LICENSE for license details.
+ */
+
+define(["jquery"], function($) {
+ "use strict";
+
+ let note = $('#row_webscale_varnish_flush_cache_schedule_frequency .note span')
+ let items = {
+ 'frequency': '#webscale_varnish_flush_cache_schedule_frequency',
+ 'everytext': '#webscale_varnish_flush_cache_schedule_every',
+ 'everytime': '#webscale_varnish_flush_cache_schedule_time',
+ 'timehour': '[data-ui-id="time-groups-flush-cache-schedule-fields-start-time-value-hour"]',
+ 'timeminute': '[data-ui-id="time-groups-flush-cache-schedule-fields-start-time-value-minute"]',
+ 'timesecond': '[data-ui-id="time-groups-flush-cache-schedule-fields-start-time-value-second"]'
+ };
+
+ let init = function () {
+ if (note && note.length) {
+ // $(items.timesecond).prop('disabled', 'disabled');
+ return bind();
+ }
+ }
+
+ let bind = function() {
+ for (const key in items) {
+ const instance = $(items[key]);
+ instance.on('change', function (e) {
+ return change(e, instance);
+ }.bind(instance));
+ }
+
+ $(items.frequency).trigger('change');
+ }
+
+ /**
+ * Trigger change event and combine cron expression
+ */
+ let change = function(e, element) {
+ let value = '',
+ frequency = $(items.frequency),
+ timeMinute = $(items.timeminute),
+ timeHour = $(items.timehour),
+ everyText = $(items.everytext),
+ everyTime = $(items.everytime);
+
+ switch(frequency.val()) {
+ case 'H':
+ value = '0 * * * *';
+ break;
+ case 'D':
+ value = parseInt($(timeMinute).val(), 10) + ' ' + parseInt($(timeHour).val(), 10) + ' * * *';
+ break;
+ case 'custom':
+ if (everyText.val() !== "undefined" && everyText.val() !== '') {
+ let txtValue = everyText.val();
+ if (everyTime.val() == 'hour') {
+ value = '0 */' + txtValue + ' * * *';
+ } else if (everyTime.val() == 'min') {
+ value = '*/' + txtValue + ' * * * *';
+ }
+ }
+ break;
+
+ }
+
+ note.html('Cron Expression: ' + (value ? '' + value + '' : 'none'));
+ }
+
+ return init();
+});