341 lines
11 KiB
PHP
341 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* NOTICE OF LICENSE
|
|
*
|
|
* This source file is subject to the Open Software License version 3.0
|
|
* that is bundled with this package in the file LICENSE.md
|
|
* It is also available through the world-wide-web at this URL:
|
|
* https://opensource.org/license/osl-3-0-php
|
|
* If you did not receive a copy of the license and are unable to
|
|
* obtain it through the world-wide-web, please send an email
|
|
* to support@qloapps.com so we can send you a copy immediately.
|
|
*
|
|
* DISCLAIMER
|
|
*
|
|
* Do not edit or add to this file if you wish to upgrade this module to a newer
|
|
* versions in the future. If you wish to customize this module for your needs
|
|
* please refer to https://store.webkul.com/customisation-guidelines for more information.
|
|
*
|
|
* @author Webkul IN
|
|
* @copyright Since 2010 Webkul
|
|
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
|
|
*/
|
|
|
|
if (!defined('_PS_VERSION_')) {
|
|
exit;
|
|
}
|
|
|
|
require_once dirname(__FILE__).'/classes/QctmRequiredClasses.php';
|
|
|
|
class QloCronTaskManager extends Module
|
|
{
|
|
public function __construct()
|
|
{
|
|
$this->name = 'qlocrontaskmanager';
|
|
$this->tab = 'administration';
|
|
$this->version = '1.0.0';
|
|
$this->author = 'Webkul';
|
|
$this->need_instance = 0;
|
|
$this->bootstrap = true;
|
|
|
|
parent::__construct();
|
|
|
|
$this->displayName = $this->l('Cron Task Manager');
|
|
$this->description = $this->l('A centralized cron scheduling system where a single server cron entry manages all module tasks.');
|
|
$this->confirmUninstall = $this->l('Are you sure you want to uninstall this module? All cron task data will be lost.');
|
|
}
|
|
|
|
|
|
public function getContent()
|
|
{
|
|
$output = '';
|
|
|
|
if (Tools::isSubmit('submitCronTaskManagerSettings')) {
|
|
$output .= $this->processSaveSettings();
|
|
}
|
|
|
|
if (Tools::isSubmit('regenerateToken')) {
|
|
Configuration::updateValue('QCTM_CRON_TASK_MANAGER_TOKEN', Tools::passwdGen(32));
|
|
$output .= $this->displayConfirmation($this->l('Token has been regenerated. Update your server cron entry with the new URL.'));
|
|
}
|
|
|
|
if(Tools::getValue('module_name') === $this->name) {
|
|
$this->context->controller->addCSS($this->_path . 'views/css/admin/qlo_cron_task_manager_admin.css');
|
|
$this->context->controller->addJS($this->_path . 'views/js/admin/qlo_cron_task_manager_admin.js');
|
|
}
|
|
|
|
$output .= $this->renderCronCommandPanel();
|
|
$output .= $this->renderSettingsForm();
|
|
|
|
return $output;
|
|
}
|
|
|
|
protected function processSaveSettings()
|
|
{
|
|
$logRetention = Tools::getValue('QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS');
|
|
|
|
if(!Validate::isUnsignedInt($logRetention)) {
|
|
return $this->displayError($this->l('Log retention must be an integer value.'));
|
|
}
|
|
|
|
if ($logRetention < 1 || $logRetention > 365) {
|
|
return $this->displayError($this->l('Log retention must be between 1 and 365 days.'));
|
|
}
|
|
|
|
Configuration::updateValue('QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS', $logRetention);
|
|
|
|
return $this->displayConfirmation($this->l('Settings saved successfully.'));
|
|
}
|
|
|
|
protected function renderCronCommandPanel()
|
|
{
|
|
$token = Configuration::get('QCTM_CRON_TASK_MANAGER_TOKEN');
|
|
$cronUrl = Tools::getShopDomainSsl(true) . __PS_BASE_URI__
|
|
. 'modules/qlocrontaskmanager/cron.php?token=' . $token;
|
|
$cronCommand = '* * * * * curl -s "' . $cronUrl . '"';
|
|
|
|
$this->context->smarty->assign(array(
|
|
'cronCommand' => $cronCommand,
|
|
));
|
|
|
|
return $this->display(__FILE__, 'views/templates/admin/configure.tpl');
|
|
}
|
|
|
|
protected function renderSettingsForm()
|
|
{
|
|
$token = Configuration::get('QCTM_CRON_TASK_MANAGER_TOKEN');
|
|
|
|
$helper = new HelperForm();
|
|
$helper->module = $this;
|
|
$helper->name_controller = $this->name;
|
|
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
|
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
|
|
$helper->default_form_language = (int) Configuration::get('PS_LANG_DEFAULT');
|
|
|
|
$helper->fields_value = array(
|
|
'QCTM_CRON_TASK_MANAGER_TOKEN' => $token,
|
|
'QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS' => (int) Configuration::get('QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS'),
|
|
);
|
|
|
|
$fields_form = array(
|
|
'form' => array(
|
|
'legend' => array(
|
|
'title' => $this->l('Settings'),
|
|
'icon' => 'icon-cogs',
|
|
),
|
|
'input' => array(
|
|
array(
|
|
'type' => 'text',
|
|
'label' => $this->l('Secure Token'),
|
|
'name' => 'QCTM_CRON_TASK_MANAGER_TOKEN',
|
|
'readonly' => true,
|
|
'col' => 6,
|
|
'desc' => $this->l('This token secures the cron endpoint. After regenerating it, you will need to update your server cron entry.'),
|
|
),
|
|
array(
|
|
'type' => 'text',
|
|
'label' => $this->l('Log Retention (days)'),
|
|
'name' => 'QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS',
|
|
'col' => 2,
|
|
'required' => true,
|
|
'validation' => 'isUnsignedInt',
|
|
'suffix' => $this->l('days'),
|
|
'desc' => $this->l('Number of days to keep execution logs.'),
|
|
),
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
'class' => 'btn btn-default pull-right',
|
|
'name' => 'submitCronTaskManagerSettings',
|
|
),
|
|
'buttons' => array(
|
|
array(
|
|
'title' => $this->l('Regenerate Token'),
|
|
'icon' => 'process-icon-refresh',
|
|
'name' => 'regenerateToken',
|
|
'type' => 'submit',
|
|
'class' => 'btn btn-default',
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
return $helper->generateForm(array($fields_form));
|
|
}
|
|
|
|
public function hookActionModuleInstallAfter($params)
|
|
{
|
|
if (!isset($params['object']) || !($params['object'] instanceof Module)) {
|
|
return;
|
|
}
|
|
|
|
$module = $params['object'];
|
|
|
|
if (method_exists($module, 'hookRegisterCronTasks')) {
|
|
$tasks = $module->hookRegisterCronTasks();
|
|
if (!empty($tasks) && is_array($tasks)) {
|
|
$objCronTask = new QctmCronTask();
|
|
$objCronTask->registerTasksForModule($module->id, $tasks);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function hookDashboardZoneThree($params)
|
|
{
|
|
if ($this->isCrontabConfigured() !== false) {
|
|
return '';
|
|
}
|
|
|
|
$this->context->smarty->assign(array(
|
|
'qctmConfigureLink' => $this->context->link->getAdminLink('AdminModules') . '&configure=' . $this->name,
|
|
));
|
|
|
|
return $this->display(__FILE__, 'views/templates/admin/dashboard/qctm_cron_not_configured.tpl');
|
|
}
|
|
|
|
public function isCrontabConfigured()
|
|
{
|
|
if (!function_exists('shell_exec')) {
|
|
return null;
|
|
}
|
|
|
|
$disabled = array_map('trim', explode(',', (string) ini_get('disable_functions')));
|
|
if (in_array('shell_exec', $disabled, true)) {
|
|
return null;
|
|
}
|
|
|
|
$output = @shell_exec('crontab -l 2>/dev/null');
|
|
|
|
return strpos((string) $output, 'qlocrontaskmanager/cron.php') !== false;
|
|
}
|
|
|
|
public function hookActionModuleUninstallBefore($params)
|
|
{
|
|
if (!isset($params['object']) || !($params['object'] instanceof Module) || $params['object']->id == $this->id) {
|
|
return;
|
|
}
|
|
|
|
QctmCronTask::deleteByModule($params['object']->id);
|
|
}
|
|
|
|
/**
|
|
* Called by the system log-cleanup cron task (daily at midnight).
|
|
*/
|
|
public function runLogCleanup()
|
|
{
|
|
$days = (int) Configuration::get('QCTM_CRON_TASK_MANAGER_LOG_RETENTION_DAYS');
|
|
if ($days > 0) {
|
|
QctmCronTaskLog::deleteOlderThan($days);
|
|
}
|
|
|
|
}
|
|
|
|
public function install()
|
|
{
|
|
$db = new QctmCronTaskManagerDb();
|
|
$objCronTask = new QctmCronTask();
|
|
|
|
if (!parent::install()
|
|
|| !$this->registerHooks()
|
|
|| !$db->createTables()
|
|
|| !$db->installDefaultData()
|
|
|| !$this->installTabs()
|
|
|| !$this->installDefaultTasks()
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
$objCronTask->syncAllExistingModules();
|
|
|
|
return true;
|
|
}
|
|
|
|
public function registerHooks()
|
|
{
|
|
return $this->registerHook(
|
|
array(
|
|
'actionModuleInstallAfter',
|
|
'actionModuleUninstallBefore',
|
|
'dashboardZoneThree',
|
|
)
|
|
);
|
|
}
|
|
|
|
public function uninstall()
|
|
{
|
|
$db = new QctmCronTaskManagerDb();
|
|
|
|
if (!$this->uninstallTabs()
|
|
|| !$db->deleteConfigurations()
|
|
|| !$db->dropTables()
|
|
|| !parent::uninstall()
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected function installDefaultTasks()
|
|
{
|
|
if (QctmCronTask::getByModuleAndName($this->id, 'log_cleanup')) {
|
|
return true;
|
|
}
|
|
|
|
$task = new QctmCronTask();
|
|
$task->id_module = (int) $this->id;
|
|
$task->task_name = 'log_cleanup';
|
|
$task->description = 'Automatic log cleanup';
|
|
$task->cron_expression = '0 0 * * *';
|
|
$task->callback = 'runLogCleanup';
|
|
$task->active = 1;
|
|
$task->is_system = 1;
|
|
|
|
return $task->save();
|
|
}
|
|
|
|
protected function installTabs()
|
|
{
|
|
$tabCronTasks = new Tab();
|
|
$tabCronTasks->class_name = 'AdminCronTaskManager';
|
|
$tabCronTasks->id_parent = (int) Tab::getIdFromClassName('AdminTools');
|
|
$tabCronTasks->module = $this->name;
|
|
$tabCronTasks->position = Tab::getNewLastPosition($tabCronTasks->id_parent);
|
|
|
|
foreach (Language::getLanguages(false) as $language) {
|
|
$tabCronTasks->name[$language['id_lang']] = $this->l('Cron Task Manager');
|
|
}
|
|
|
|
if (!$tabCronTasks->add()) {
|
|
return false;
|
|
}
|
|
|
|
// Hidden tab — accessible via URL but not shown in navigation menu
|
|
$tabLogs = new Tab();
|
|
$tabLogs->class_name = 'AdminCronTaskLogs';
|
|
$tabLogs->id_parent = -1;
|
|
$tabLogs->module = $this->name;
|
|
|
|
foreach (Language::getLanguages(false) as $language) {
|
|
$tabLogs->name[$language['id_lang']] = $this->l('Cron Task Logs');
|
|
}
|
|
|
|
return $tabLogs->add();
|
|
}
|
|
|
|
protected function uninstallTabs()
|
|
{
|
|
foreach (array('AdminCronTaskManager', 'AdminCronTaskLogs') as $className) {
|
|
$idTab = (int) Tab::getIdFromClassName($className);
|
|
if ($idTab) {
|
|
$tab = new Tab($idTab);
|
|
if (!$tab->delete()) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|