From da6fd1d30d562a7e085cd72dee35d245c99867b2 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Fri, 21 Sep 2018 19:53:01 +0200 Subject: [PATCH 01/26] cli scheduler --- cli/scheduler.php | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 cli/scheduler.php diff --git a/cli/scheduler.php b/cli/scheduler.php new file mode 100644 index 0000000000000..a0e9a5a3f0de2 --- /dev/null +++ b/cli/scheduler.php @@ -0,0 +1,153 @@ +debug); + +// Configure error reporting to maximum for CLI output. +error_reporting(E_ALL); +ini_set('display_errors', 1); +use Joomla\Registry\Registry; + +// Load Library language +$lang = JFactory::getLanguage(); + +// Try the finder_cli file in the current language (without allowing the loading of the file in the default language) +$lang->load('scheduler_cli', JPATH_SITE, null, false, false) +// Fallback to the finder_cli file in the default language +|| $lang->load('scheduler_cli', JPATH_SITE, null, true); + +/** + * A command line cron job to run the job plugins event. + * + * @since __DEPLOY_VERSION__ + */ +class SchedulerCli extends JApplicationCli +{ + /** + * Start time for the process + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $time = null; + + /** + * Entry point for the Scheduler CLI script + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function doExecute() + { + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_cli.php'; + + JLog::addLogger($options, JLog::INFO, array('scheduler')); + + try + { + JLog::add( + 'Starting Scheduler', JLog::INFO, 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Print a blank line. + $this->out(JText::_('SCHEDULER_CLI')); + $this->out('============================'); + + // Initialize the time value. + $this->time = microtime(true); + + // Remove the script time limit. + @set_time_limit(0); + + // Fool the system into thinking we are running as JSite. + $_SERVER['HTTP_HOST'] = 'domain.com'; + JFactory::getApplication('site'); + + $this->Trigger(); + + // Total reporting. + $this->out(JText::sprintf('SCHEDULER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), true); + $this->out(JText::sprintf('SCHEDULER_CLI_PEAK_MEMORY_USAGE', number_format(memory_get_peak_usage(true)))); + + // Print a blank line at the end. + $this->out(); + + try + { + JLog::add( + 'Ending Scheduler:' . JText::sprintf('SCHEDULER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), JLog::INFO, 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + + /** + * Trigger the jobs + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function Trigger() + { + // Unleash hell + JPluginHelper::importPlugin('job'); + $dispatcher = \JEventDispatcher::getInstance(); + + // Trigger the ExecuteTask event + $dispatcher->trigger('onExecuteScheduledTask', array()); + + } +} + +// Instantiate the application object, passing the class name to JCli::getInstance +// and use chaining to execute the application. +JApplicationCli::getInstance('SchedulerCli')->execute(); From 9237d3cfe8c99f2486b6c09857166e8e7a464bf0 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Fri, 21 Sep 2018 19:57:01 +0200 Subject: [PATCH 02/26] the system/web scheduler plugin --- plugins/system/scheduler/scheduler.php | 206 +++++++++++++++++++++++++ plugins/system/scheduler/scheduler.xml | 43 ++++++ 2 files changed, 249 insertions(+) create mode 100644 plugins/system/scheduler/scheduler.php create mode 100644 plugins/system/scheduler/scheduler.xml diff --git a/plugins/system/scheduler/scheduler.php b/plugins/system/scheduler/scheduler.php new file mode 100644 index 0000000000000..ca03b5f2fb6c8 --- /dev/null +++ b/plugins/system/scheduler/scheduler.php @@ -0,0 +1,206 @@ +params->get('cachetimeout', 1); + $cache_timeout = 60 * $cache_timeout; + + // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current + // timestamp. If the difference is greater than the cache timeout we shall not execute again. + $now = time(); + $last = (int) $this->params->get('lastrun', 0); + + if ((abs($now - $last) < $cache_timeout)) + { + return; + } + + // Log events + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_web.php'; + + JLog::addLogger($options, JLog::INFO, array('scheduler')); + + try + { + JLog::add( + 'Starting Scheduler', JLog::INFO, 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + }; + + // Update last run status + $this->params->set('lastrun', $now); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('params') . ' = ' . $db->quote($this->params->toString('JSON'))) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('scheduler')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (Exception $e) + { + // If we can't lock the tables it's too risky to continue execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (Exception $exc) + { + // If we failed to execute + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (JDatabaseException $e) + { + // If we can't unlock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + + // Trigger all job plugin events + $this->Trigger(); + + // Log the time it took to run + $endTime = microtime(true); + $timeToLoad = sprintf('%0.2f', $endTime - $startTime); + + try + { + JLog::add( + 'Ending Scheduler:' . JText::sprintf('SCHEDULER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), JLog::INFO, 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + + /** + * Trigger the jobs + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function Trigger() + { + // Unleash hell + JPluginHelper::importPlugin('job'); + $dispatcher = \JEventDispatcher::getInstance(); + + // Trigger the ExecuteTask event + $dispatcher->trigger('onExecuteScheduledTask', array()); + } + + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } +} diff --git a/plugins/system/scheduler/scheduler.xml b/plugins/system/scheduler/scheduler.xml new file mode 100644 index 0000000000000..4345e72f9a8fb --- /dev/null +++ b/plugins/system/scheduler/scheduler.xml @@ -0,0 +1,43 @@ + + + plg_system_scheduler + Joomla! Project + June 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_SYSTEM_SCHEDULER_XML_DESCRIPTION + + scheduler.php + + + en-GB.plg_system_scheduler.ini + en-GB.plg_system_scheduler.sys.ini + + + +
+ + +
+
+
+
From e057fb7ec912d295fb5b73b4c338a91779a185cb Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Fri, 21 Sep 2018 19:59:04 +0200 Subject: [PATCH 03/26] the logrotation plugin job --- plugins/job/logrotation/logrotation.php | 338 ++++++++++++++++++++++++ plugins/job/logrotation/logrotation.xml | 63 +++++ 2 files changed, 401 insertions(+) create mode 100644 plugins/job/logrotation/logrotation.php create mode 100644 plugins/job/logrotation/logrotation.xml diff --git a/plugins/job/logrotation/logrotation.php b/plugins/job/logrotation/logrotation.php new file mode 100644 index 0000000000000..71da6093215b7 --- /dev/null +++ b/plugins/job/logrotation/logrotation.php @@ -0,0 +1,338 @@ +params, true); + $now = time(); + + // Sanity check + if ((!isset($taskParams['lastrun'])) || (!isset($taskParams['cachetimeout'])) || (!isset($taskParams['unit']))) + { + return; + } + + $last = (int) $taskParams['lastrun']; + $cache_timeout = (int) $taskParams['cachetimeout']; + $cache_timeout = 60 * $cache_timeout; + + if ((abs($now - $last) < $cache_timeout)) + { + return; + } + + $startTime = microtime(true); + + try + { + JLog::add( + 'Running:' . $this->_name . ':', JLog::INFO, 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Execute the job + $this->logRotationTask(); + + // Update job execution data + $this->updateLastRun(); + + $endTime = microtime(true); + $timeToLoad = sprintf('%0.2f', $endTime - $startTime); + + try + { + JLog::add( + 'Executed:' . $this->_name . ' took ' . $timeToLoad . ' seconds', + JLog::INFO, + 'scheduler' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + + /** + * Update last run. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function updateLastRun() + { + // Update last run status + $this->params->set('lastrun', time()); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('params') . ' = ' . $db->quote($this->params)) + ->where($db->quoteName('element') . ' = ' . $db->quote($this->_name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($this->_type)); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (JDatabaseException $e) + { + // If we can't lock the tables it's too risky to continue execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (JDatabaseException $exc) + { + // If we failed to execute + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (JDatabaseException $e) + { + // If we can't unlock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + } + + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } + + /** + * The log check and rotation code event. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function logRotationTask() + { + + // Get the number of logs to keep as configured in plugin parameters + $logsToKeep = (int) $this->params->get('logstokeep', 1); + + // Get the log path + $logPath = Path::clean($this->app->get('log_path')); + + // Invalid path, stop processing further + if (!is_dir($logPath)) + { + return; + } + + $logFiles = $this->getLogFiles($logPath); + + // Sort log files by version number in reserve order + krsort($logFiles, SORT_NUMERIC); + + foreach ($logFiles as $version => $files) + { + if ($version >= $logsToKeep) + { + // Delete files which has version greater than or equals $logsToKeep + foreach ($files as $file) + { + File::delete($logPath . '/' . $file); + } + } + else + { + // For files which has version smaller than $logsToKeep, rotate (increase version number) + foreach ($files as $file) + { + $this->rotate($logPath, $file, $version); + } + } + } + } + + /** + * Get log files from log folder + * + * @param string $path The folder to get log files + * + * @return array The log files in the given path grouped by version number (not rotated files has number 0) + * + * @since __DEPLOY_VERSION__ + */ + private function getLogFiles($path) + { + $logFiles = array(); + $files = Folder::files($path, '\.php$'); + + foreach ($files as $file) + { + $parts = explode('.', $file); + + /* + * Rotated log file has this filename format [VERSION].[FILENAME].php. So if $parts has at least 3 elements + * and the first element is a number, we know that it's a rotated file and can get it's current version + */ + if (count($parts) >= 3 && is_numeric($parts[0])) + { + $version = (int) $parts[0]; + } + else + { + $version = 0; + } + + if (!isset($logFiles[$version])) + { + $logFiles[$version] = array(); + } + + $logFiles[$version][] = $file; + } + + return $logFiles; + } + + /** + * Method to rotate (increase version) of a log file + * + * @param string $path Path to file to rotate + * @param string $filename Name of file to rotate + * @param int $currentVersion The current version number + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function rotate($path, $filename, $currentVersion) + { + if ($currentVersion === 0) + { + $rotatedFile = $path . '/1.' . $filename; + } + else + { + /* + * Rotated log file has this filename format [VERSION].[FILENAME].php. To rotate it, we just need to explode + * the filename into an array, increase value of first element (keep version) and implode it back to get the + * rotated file name + */ + $parts = explode('.', $filename); + $parts[0] = $currentVersion + 1; + + $rotatedFile = $path . '/' . implode('.', $parts); + } + + File::move($path . '/' . $filename, $rotatedFile); + } + +} diff --git a/plugins/job/logrotation/logrotation.xml b/plugins/job/logrotation/logrotation.xml new file mode 100644 index 0000000000000..a85a757fb5c02 --- /dev/null +++ b/plugins/job/logrotation/logrotation.xml @@ -0,0 +1,63 @@ + + + plg_job_logrotation + Joomla! Project + May 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + PLG_JOB_LOGROTATION_XML_DESCRIPTION + + logrotation.php + + + en-GB.plg_job_logrotation.ini + en-GB.plg_job_logrotation.sys.ini + + + +
+ + + + + + +
+
+
+
From 0cbc2f29c9d84c7995eabc46dcef9a1aa8825ce8 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:41:00 +0200 Subject: [PATCH 04/26] webcron option --- plugins/system/scheduler/scheduler.xml | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/plugins/system/scheduler/scheduler.xml b/plugins/system/scheduler/scheduler.xml index 4345e72f9a8fb..57b793a7b22a1 100644 --- a/plugins/system/scheduler/scheduler.xml +++ b/plugins/system/scheduler/scheduler.xml @@ -31,12 +31,51 @@ filter="int" validate="number" /> + + + + + + + + + + + + From be83d620d16d88a2bbf17049252e86b1efc64c78 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:43:11 +0200 Subject: [PATCH 05/26] tab 4 --- plugins/system/scheduler/scheduler.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/scheduler/scheduler.xml b/plugins/system/scheduler/scheduler.xml index 57b793a7b22a1..7a364d09753a4 100644 --- a/plugins/system/scheduler/scheduler.xml +++ b/plugins/system/scheduler/scheduler.xml @@ -2,7 +2,7 @@ plg_system_scheduler Joomla! Project - June 2018 + July 2018 Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org From 49933924f071ef3a3217cab3e078b0b319bf838b Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:45:07 +0200 Subject: [PATCH 06/26] webcron option --- plugins/system/scheduler/scheduler.php | 145 +++++++------------------ 1 file changed, 41 insertions(+), 104 deletions(-) diff --git a/plugins/system/scheduler/scheduler.php b/plugins/system/scheduler/scheduler.php index ca03b5f2fb6c8..ffe6776d41d71 100644 --- a/plugins/system/scheduler/scheduler.php +++ b/plugins/system/scheduler/scheduler.php @@ -20,12 +20,12 @@ class PlgSystemScheduler extends JPlugin { /** - * Start time for the process + * Status for the process * * @var string * @since __DEPLOY_VERSION__ */ - private $time = null; + protected $status; /** * Load plugin language files automatically @@ -46,93 +46,67 @@ public function onAfterRespond() { $startTime = microtime(true); + $app = JFactory::getApplication(); + + //WebCron check + if ($this->params->get('webcron', 0)) + { + $webcronkey = $app->input->get('webcronkey', '', 'cmd'); + + if ($webcronkey !== $this->params->get('webcronkey', '')) + { + return; + } + } + + // Pseudo Lock + if (!JPluginHelper::lock($this->_name, $this->_type, $this->status)) + { + return; + } // Get the timeout for Joomla! system scheduler /** @var \Joomla\Registry\Registry $params */ $cache_timeout = (int) $this->params->get('cachetimeout', 1); - $cache_timeout = 60 * $cache_timeout; + $unit = (int) $this->params->get('unit', 60); + $cache_timeout = ($unit * $cache_timeout); // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current // timestamp. If the difference is greater than the cache timeout we shall not execute again. - $now = time(); - $last = (int) $this->params->get('lastrun', 0); - - if ((abs($now - $last) < $cache_timeout)) - { - return; - } + $now = time(); + $last = $this->status; // Log events $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_web.php'; - + JLog::addLogger($options, JLog::INFO, array('scheduler')); - try - { - JLog::add( - 'Starting Scheduler', JLog::INFO, 'scheduler' - ); - } - catch (RuntimeException $exception) + if ((abs($now - $last) < $cache_timeout)) { - // Informational log only - }; - - // Update last run status - $this->params->set('lastrun', $now); + JPluginHelper::unLock($this->_name, $this->_type, false); - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->update($db->quoteName('#__extensions')) - ->set($db->quoteName('params') . ' = ' . $db->quote($this->params->toString('JSON'))) - ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) - ->where($db->quoteName('element') . ' = ' . $db->quote('scheduler')); - - try - { - // Lock the tables to prevent multiple plugin executions causing a race condition - $db->lockTable('#__extensions'); - } - catch (Exception $e) - { - // If we can't lock the tables it's too risky to continue execution return; } try { - // Update the plugin parameters - $result = $db->setQuery($query)->execute(); - - $this->clearCacheGroups(array('com_plugins'), array(0, 1)); - } - catch (Exception $exc) - { - // If we failed to execute - $db->unlockTables(); - $result = false; - } - - try - { - // Unlock the tables after writing - $db->unlockTables(); + JLog::add( + JText::_('PLG_SYSTEM_SCHEDULER_START'), + JLog::INFO, + 'scheduler' + ); + } - catch (JDatabaseException $e) + catch (RuntimeException $exception) { - // If we can't unlock the tables assume we have somehow failed - $result = false; + // Informational log only } - // Abort on failure - if (!$result) - { - return; - } + // Trigger jobs + $this->triggerJobs(); - // Trigger all job plugin events - $this->Trigger(); + // Update job execution data + $taskid = JPluginHelper::unLock($this->_name, $this->_type); // Log the time it took to run $endTime = microtime(true); @@ -141,7 +115,7 @@ public function onAfterRespond() try { JLog::add( - 'Ending Scheduler:' . JText::sprintf('SCHEDULER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), JLog::INFO, 'scheduler' + JText::sprintf('PLG_SYSTEM_SCHEDULER_END', $taskid) . ' '. JText::sprintf('PLG_SYSTEM_SCHEDULER_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' ); } catch (RuntimeException $exception) @@ -157,7 +131,7 @@ public function onAfterRespond() * * @since __DEPLOY_VERSION__ */ - private function Trigger() + private function triggerJobs() { // Unleash hell JPluginHelper::importPlugin('job'); @@ -166,41 +140,4 @@ private function Trigger() // Trigger the ExecuteTask event $dispatcher->trigger('onExecuteScheduledTask', array()); } - - /** - * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. - * - * @param array $clearGroups The cache groups to clean - * @param array $cacheClients The cache clients (site, admin) to clean - * - * @return void - * - * @since __DEPLOY_VERSION__ - */ - private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) - { - $conf = JFactory::getConfig(); - - foreach ($clearGroups as $group) - { - foreach ($cacheClients as $client_id) - { - try - { - $options = array( - 'defaultgroup' => $group, - 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : - $conf->get('cache_path', JPATH_SITE . '/cache') - ); - - $cache = JCache::getInstance('callback', $options); - $cache->clean(); - } - catch (Exception $e) - { - // Ignore it - } - } - } - } } From fdea076c0814867ca98b6dc4bbc5def6969d8fbc Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:47:20 +0200 Subject: [PATCH 07/26] language 1/2 --- .../language/en-GB/en-GB.plg_system_scheduler.sys.ini | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 administrator/language/en-GB/en-GB.plg_system_scheduler.sys.ini diff --git a/administrator/language/en-GB/en-GB.plg_system_scheduler.sys.ini b/administrator/language/en-GB/en-GB.plg_system_scheduler.sys.ini new file mode 100644 index 0000000000000..eae93cff7fe55 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_scheduler.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SCHEDULER="System - Job Scheduler" +PLG_SYSTEM_SCHEDULER_XML_DESCRIPTION="This plugin looks for job plugin tasks to run." From cd04129ec0020dd9b3ddfbd6d3e9583c244dd8c5 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:47:55 +0200 Subject: [PATCH 08/26] language 2/2 --- .../en-GB/en-GB.plg_system_scheduler.ini | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 administrator/language/en-GB/en-GB.plg_system_scheduler.ini diff --git a/administrator/language/en-GB/en-GB.plg_system_scheduler.ini b/administrator/language/en-GB/en-GB.plg_system_scheduler.ini new file mode 100644 index 0000000000000..c0e06a98abbe4 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_scheduler.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SCHEDULER="System - Job Scheduler" +PLG_SYSTEM_SCHEDULER_CACHETIMEOUT_LABEL="Frequency (in minutes)" +PLG_SYSTEM_SCHEDULER_CACHETIMEOUT_DESC="How often should the scheduler run." +PLG_SYSTEM_SCHEDULER_END="Scheduler end running task: %s" +PLG_SYSTEM_SCHEDULER_PROCESS_COMPLETE="Total Processing Time: %s seconds." +PLG_SYSTEM_SCHEDULER_START="Scheduler start" +PLG_SYSTEM_SCHEDULER_WEBCRON_DESC="Webcron services enable" +PLG_SYSTEM_SCHEDULER_WEBCRON_LABEL="Webcron" +PLG_SYSTEM_SCHEDULER_WEBCRONKEY_DESC="Webcron service activation key" +PLG_SYSTEM_SCHEDULER_WEBCRONKEY_LABEL="Key" +PLG_SYSTEM_SCHEDULER_XML_DESCRIPTION="This plugin looks for job plugin tasks to run." From 151b731816ea6461915464f9ce7c2085df6c955b Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 07:52:22 +0200 Subject: [PATCH 09/26] lock() and unLock() helper --- libraries/src/Plugin/PluginHelper.php | 172 ++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 647727145e64b..c6f4c647e5b80 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -10,6 +10,8 @@ defined('JPATH_PLATFORM') or die; +use Joomla\Registry\Registry; + /** * Plugin helper class * @@ -365,4 +367,174 @@ protected static function load() return static::$plugins; } + + /** + * Pseudo Lock the row. + * @param string $name The plugin name. + * @param string $type The plugin type, relates to the subdirectory in the plugins directory. + * @param string $lastrun The plugin last run time. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public static function lock($name, $type, &$lastrun) + { + // Prevent multiple execution + $db = \JFactory::getDbo(); + + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->qn('checked_out_time') .' = '. $db->q('1918-01-01 00:00:00')) + ->where($db->quoteName('element') . ' = ' . $db->quote($name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($type)) + ->where($db->quoteName('checked_out_time') . ' != ' . $db->q('1918-01-01 00:00:00')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (JDatabaseException $e) + { + // If we can't lock the tables it's too risky to continue execution + return false; + } + + $db->setQuery($query); + + try + { + // Update the plugin parameters + $db->execute(); + + } + catch (JDatabaseException $exc) + { + // If we failed to execute + $db->unlockTables(); + return false; + } + + $result = (int) $db->getAffectedRows(); + if ($result === 0) + { + return false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (JDatabaseException $e) + { + // If we can't unlock the tables assume we have somehow failed + return false; + } + + $query = $db->getQuery(true) + ->select($db->quoteName('params')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote($name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($type)) + ->where($db->quoteName('checked_out_time') . ' = ' . $db->q('1918-01-01 00:00:00')); + + $db->setQuery($query); + $params = $db->loadColumn(); + $taskParams = json_decode($params[0], true); + $lastrun = $taskParams['lastrun']; + + return true; + } + + /** + * Pseudo unLock the row. + * @param string $name The plugin name. + * @param string $type The plugin type, relates to the subdirectory in the plugins directory. + * @param string $unlock The unlock type. + * + * @return string The task id. + * + * @since __DEPLOY_VERSION__ + */ + public static function unLock($name, $type, $unlock = true) + { + + $taskid = null; + $db = \JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('params')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote($name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($type)) + ->where($db->quoteName('checked_out_time') . ' = ' . $db->q('1918-01-01 00:00:00')); + + $db->setQuery($query); + $params = $db->loadColumn(); + + if ($unlock) + { + // Update last run and taskid + $taskParams = json_decode($params[0], true); + $taskid = $taskParams['taskid']; + + $taskid++; + $registry = new Registry($taskParams); + $registry->set('taskid', $taskid); + $registry->set('lastrun', time()); + + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('params') . ' = ' . $db->quote($registry->toString('JSON'))) + ->set($db->qn('checked_out_time') .' = '. $db->quote(\JFactory::getDate()->toSql())) + ->where($db->quoteName('element') . ' = ' . $db->quote($name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($type)); + } + else + { + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->qn('checked_out_time') .' = '. $db->quote(\JFactory::getDate()->toSql())) + ->where($db->quoteName('element') . ' = ' . $db->quote($name)) + ->where($db->quoteName('folder') . ' = ' . $db->quote($type)); + } + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (JDatabaseException $e) + { + // If we can't lock the tables it's too risky to continue execution + return false; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + } + catch (JDatabaseException $exc) + { + // If we failed to execute + $db->unlockTables(); + return false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (JDatabaseException $e) + { + // If we can't unlock the tables assume we have somehow failed + return false; + } + + return $taskid; + + } } From ee0c8d989d647e997fb601ee188139962cb54fe0 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:19:59 +0200 Subject: [PATCH 10/26] logrotation options --- plugins/job/logrotation/logrotation.xml | 40 +++++++++++++++++-------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/plugins/job/logrotation/logrotation.xml b/plugins/job/logrotation/logrotation.xml index a85a757fb5c02..b9a1823d0d9dc 100644 --- a/plugins/job/logrotation/logrotation.xml +++ b/plugins/job/logrotation/logrotation.xml @@ -20,27 +20,27 @@
@@ -51,11 +51,25 @@ default="0" filter="integer" /> + + + + + + +
From 601ce9e0be9869df7a42ece2b35921740872ac1a Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:21:58 +0200 Subject: [PATCH 11/26] plugin job logrotation --- plugins/job/logrotation/logrotation.php | 151 ++++-------------------- 1 file changed, 24 insertions(+), 127 deletions(-) diff --git a/plugins/job/logrotation/logrotation.php b/plugins/job/logrotation/logrotation.php index 71da6093215b7..32fe5410689a5 100644 --- a/plugins/job/logrotation/logrotation.php +++ b/plugins/job/logrotation/logrotation.php @@ -12,7 +12,6 @@ use Joomla\Filesystem\File; use Joomla\Filesystem\Folder; use Joomla\Filesystem\Path; -use Joomla\Registry\Registry; /** * Joomla! Log Rotation plugin @@ -47,6 +46,14 @@ class PlgJobLogrotation extends JPlugin */ protected $db; + /** + * Status. + * + * @var The status + * @since __DEPLOY_VERSION__ + */ + protected $status; + /** * The log check and rotation code event. * @@ -57,52 +64,41 @@ class PlgJobLogrotation extends JPlugin public function onExecuteScheduledTask($task = array()) { + $startTime = microtime(true); - - $taskParams = json_decode($this->params, true); - $now = time(); - - // Sanity check - if ((!isset($taskParams['lastrun'])) || (!isset($taskParams['cachetimeout'])) || (!isset($taskParams['unit']))) + // Pseudo Lock + if (!JPluginHelper::lock($this->_name, $this->_type, $this->status)) { return; } - $last = (int) $taskParams['lastrun']; - $cache_timeout = (int) $taskParams['cachetimeout']; - $cache_timeout = 60 * $cache_timeout; + // Get the timeout for Joomla! job LogRotation task + $now = time(); + + $last = $this->status; + $cache_timeout = (int) $this->params->get('cachetimeout', 1); + $unit = (int) $this->params->get('unit', 86400); + $cache_timeout = ($unit * $cache_timeout); if ((abs($now - $last) < $cache_timeout)) { + // Release the lock + JPluginHelper::unLock($this->_name, $this->_type, false); return; } - $startTime = microtime(true); - - try - { - JLog::add( - 'Running:' . $this->_name . ':', JLog::INFO, 'scheduler' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - // Execute the job $this->logRotationTask(); // Update job execution data - $this->updateLastRun(); - - $endTime = microtime(true); - $timeToLoad = sprintf('%0.2f', $endTime - $startTime); + $taskid = JPluginHelper::unLock($this->_name, $this->_type); try { JLog::add( - 'Executed:' . $this->_name . ' took ' . $timeToLoad . ' seconds', + JText::sprintf('PLG_JOB_LOGROTATION_END', $this->_name) . + JText::sprintf('PLG_JOB_LOGROTATION_TASK', $taskid) . + JText::sprintf('PLG_JOB_LOGROTATION_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' ); @@ -113,105 +109,6 @@ public function onExecuteScheduledTask($task = array()) } } - /** - * Update last run. - * - * @return void - * - * @since __DEPLOY_VERSION__ - */ - private function updateLastRun() - { - // Update last run status - $this->params->set('lastrun', time()); - - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->update($db->quoteName('#__extensions')) - ->set($db->quoteName('params') . ' = ' . $db->quote($this->params)) - ->where($db->quoteName('element') . ' = ' . $db->quote($this->_name)) - ->where($db->quoteName('folder') . ' = ' . $db->quote($this->_type)); - - try - { - // Lock the tables to prevent multiple plugin executions causing a race condition - $db->lockTable('#__extensions'); - } - catch (JDatabaseException $e) - { - // If we can't lock the tables it's too risky to continue execution - return; - } - - try - { - // Update the plugin parameters - $result = $db->setQuery($query)->execute(); - - $this->clearCacheGroups(array('com_plugins'), array(0, 1)); - } - catch (JDatabaseException $exc) - { - // If we failed to execute - $db->unlockTables(); - $result = false; - } - - try - { - // Unlock the tables after writing - $db->unlockTables(); - } - catch (JDatabaseException $e) - { - // If we can't unlock the tables assume we have somehow failed - $result = false; - } - - // Abort on failure - if (!$result) - { - return; - } - } - - /** - * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. - * - * @param array $clearGroups The cache groups to clean - * @param array $cacheClients The cache clients (site, admin) to clean - * - * @return void - * - * @since __DEPLOY_VERSION__ - */ - private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) - { - $conf = JFactory::getConfig(); - - foreach ($clearGroups as $group) - { - foreach ($cacheClients as $client_id) - { - try - { - $options = array( - 'defaultgroup' => $group, - 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : - $conf->get('cache_path', JPATH_SITE . '/cache') - ); - - $cache = JCache::getInstance('callback', $options); - $cache->clean(); - } - catch (Exception $e) - { - // Ignore it - } - } - } - } - /** * The log check and rotation code event. * From 9293a72a7c3510a4527bb37a28839bb896cf4be7 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:24:28 +0200 Subject: [PATCH 12/26] job logrotation lang --- .../language/en-GB/en-GB.plg_job_logrotation.ini | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 administrator/language/en-GB/en-GB.plg_job_logrotation.ini diff --git a/administrator/language/en-GB/en-GB.plg_job_logrotation.ini b/administrator/language/en-GB/en-GB.plg_job_logrotation.ini new file mode 100644 index 0000000000000..9630033a55963 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_job_logrotation.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_JOB_LOGROTATION="Job - Log Rotation" +PLG_JOB_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." +PLG_JOB_LOGROTATION_LOGSTOKEEP_DESC="The maximum number of old logs to keep." +PLG_JOB_LOGROTATION_LOGSTOKEEP_LABEL="Maximum Logs" +PLG_JOB_LOGROTATION_CACHETIMEOUT_LABEL="Frequency (in unit)" +PLG_JOB_LOGROTATION_CACHETIMEOUT_DESC="How often should the job run." +PLG_JOB_LOGROTATION_UNIT_LABEL="Unit of time" +PLG_JOB_LOGROTATION_UNIT_DESC="How often should the job run." +PLG_JOB_LOGROTATION_PROCESS_COMPLETE="Processing Time: %s seconds." +PLG_JOB_LOGROTATION_END="Executed Plugin: %s " +PLG_JOB_LOGROTATION_TASK="Task: %s " From 6aa3cad0351b8b3963420a0198ed3698882ccbe3 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:25:03 +0200 Subject: [PATCH 13/26] job logrotation lang --- .../language/en-GB/en-GB.plg_job_logrotation.sys.ini | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 administrator/language/en-GB/en-GB.plg_job_logrotation.sys.ini diff --git a/administrator/language/en-GB/en-GB.plg_job_logrotation.sys.ini b/administrator/language/en-GB/en-GB.plg_job_logrotation.sys.ini new file mode 100644 index 0000000000000..569a2f7c4dc87 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_job_logrotation.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_JOB_LOGROTATION="Job - Log Rotation" +PLG_JOB_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." From 512941214ca9d43ab1898294d260aa3f2a09763a Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:38:39 +0200 Subject: [PATCH 14/26] install the 2 new plugin --- installation/sql/mysql/joomla.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 9c5d6ca57481d..f8c29f93f06d4 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -667,6 +667,8 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(495, 0, 'plg_system_scheduler', 'plugin', 'scheduler', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(496, 0, 'plg_job_logrotation', 'plugin', 'logrotation', 'job', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), From 7564909fcd973812550c7adda4ab932929e1f6ea Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:50:04 +0200 Subject: [PATCH 15/26] cli lang --- language/en-GB/en-GB.scheduler_cli.ini | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 language/en-GB/en-GB.scheduler_cli.ini diff --git a/language/en-GB/en-GB.scheduler_cli.ini b/language/en-GB/en-GB.scheduler_cli.ini new file mode 100644 index 0000000000000..86bdd923c1f9e --- /dev/null +++ b/language/en-GB/en-GB.scheduler_cli.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +SCHEDULER_CLI="Scheduler job plugin task" +SCHEDULER_CLI_PEAK_MEMORY_USAGE="Peak memory usage: %s bytes" +SCHEDULER_CLI_PROCESS_COMPLETE="Total Processing Time: %s seconds." From 3ec09790e0728b5fe4ca8549babb50f77d83f9bb Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:52:18 +0200 Subject: [PATCH 16/26] the cli script --- cli/scheduler.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cli/scheduler.php b/cli/scheduler.php index a0e9a5a3f0de2..f5d995b738788 100644 --- a/cli/scheduler.php +++ b/cli/scheduler.php @@ -44,14 +44,13 @@ // Configure error reporting to maximum for CLI output. error_reporting(E_ALL); ini_set('display_errors', 1); -use Joomla\Registry\Registry; // Load Library language $lang = JFactory::getLanguage(); -// Try the finder_cli file in the current language (without allowing the loading of the file in the default language) +// Try the scheduler_cli file in the current language (without allowing the loading of the file in the default language) $lang->load('scheduler_cli', JPATH_SITE, null, false, false) -// Fallback to the finder_cli file in the default language +// Fallback to the scheduler_cli file in the default language || $lang->load('scheduler_cli', JPATH_SITE, null, true); /** @@ -108,7 +107,7 @@ public function doExecute() $_SERVER['HTTP_HOST'] = 'domain.com'; JFactory::getApplication('site'); - $this->Trigger(); + $this->triggerJobs(); // Total reporting. $this->out(JText::sprintf('SCHEDULER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), true); @@ -136,7 +135,7 @@ public function doExecute() * * @since __DEPLOY_VERSION__ */ - private function Trigger() + private function triggerJobs() { // Unleash hell JPluginHelper::importPlugin('job'); From feaaaad3d4f5c122f5f42449889d7381f480e4a5 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 08:57:00 +0200 Subject: [PATCH 17/26] cs --- plugins/job/logrotation/logrotation.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/job/logrotation/logrotation.xml b/plugins/job/logrotation/logrotation.xml index b9a1823d0d9dc..177eebd2b8eac 100644 --- a/plugins/job/logrotation/logrotation.xml +++ b/plugins/job/logrotation/logrotation.xml @@ -28,7 +28,7 @@ last="10" step="1" default="1" - filter="int" + filter="integer" validate="number" /> @@ -41,7 +41,7 @@ last="120" step="1" default="30" - filter="int" + filter="integer" validate="number" /> From 1626f67fc38953af8c4fe5d9a80901ce769c8445 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:02:49 +0200 Subject: [PATCH 18/26] drone cs --- plugins/system/scheduler/scheduler.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/system/scheduler/scheduler.php b/plugins/system/scheduler/scheduler.php index ffe6776d41d71..500e603f3ef99 100644 --- a/plugins/system/scheduler/scheduler.php +++ b/plugins/system/scheduler/scheduler.php @@ -48,7 +48,7 @@ public function onAfterRespond() $app = JFactory::getApplication(); - //WebCron check + // WebCron check if ($this->params->get('webcron', 0)) { $webcronkey = $app->input->get('webcronkey', '', 'cmd'); @@ -115,7 +115,8 @@ public function onAfterRespond() try { JLog::add( - JText::sprintf('PLG_SYSTEM_SCHEDULER_END', $taskid) . ' '. JText::sprintf('PLG_SYSTEM_SCHEDULER_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' + JText::sprintf('PLG_SYSTEM_SCHEDULER_END', $taskid) . ' ' . + JText::sprintf('PLG_SYSTEM_SCHEDULER_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' ); } catch (RuntimeException $exception) From 10f7eeb025cec78ef233acb8d04e035bb17079bd Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:08:45 +0200 Subject: [PATCH 19/26] drone cs --- libraries/src/Plugin/PluginHelper.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index c6f4c647e5b80..5224f38a82594 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -370,9 +370,10 @@ protected static function load() /** * Pseudo Lock the row. - * @param string $name The plugin name. - * @param string $type The plugin type, relates to the subdirectory in the plugins directory. - * @param string $lastrun The plugin last run time. + * + * @param string $name The plugin name. + * @param string $type The plugin type, relates to the subdirectory in the plugins directory. + * @param string $lastrun The plugin last run time. * * @return boolean True on success. * @@ -385,7 +386,7 @@ public static function lock($name, $type, &$lastrun) $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) - ->set($db->qn('checked_out_time') .' = '. $db->q('1918-01-01 00:00:00')) + ->set($db->qn('checked_out_time') . ' = ' . $db->q('1918-01-01 00:00:00')) ->where($db->quoteName('element') . ' = ' . $db->quote($name)) ->where($db->quoteName('folder') . ' = ' . $db->quote($type)) ->where($db->quoteName('checked_out_time') . ' != ' . $db->q('1918-01-01 00:00:00')); @@ -450,6 +451,7 @@ public static function lock($name, $type, &$lastrun) /** * Pseudo unLock the row. + * * @param string $name The plugin name. * @param string $type The plugin type, relates to the subdirectory in the plugins directory. * @param string $unlock The unlock type. @@ -487,7 +489,7 @@ public static function unLock($name, $type, $unlock = true) $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('params') . ' = ' . $db->quote($registry->toString('JSON'))) - ->set($db->qn('checked_out_time') .' = '. $db->quote(\JFactory::getDate()->toSql())) + ->set($db->qn('checked_out_time') . ' = ' . $db->quote(\JFactory::getDate()->toSql())) ->where($db->quoteName('element') . ' = ' . $db->quote($name)) ->where($db->quoteName('folder') . ' = ' . $db->quote($type)); } From 7b063b57a15cf89c8f8b848c07af6ecdf2166af0 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:18:49 +0200 Subject: [PATCH 20/26] drone cs --- libraries/src/Plugin/PluginHelper.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 5224f38a82594..81ec6e43fbc6b 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -371,9 +371,9 @@ protected static function load() /** * Pseudo Lock the row. * - * @param string $name The plugin name. - * @param string $type The plugin type, relates to the subdirectory in the plugins directory. - * @param string $lastrun The plugin last run time. + * @param string $name The plugin name. + * @param string $type The plugin type, relates to the subdirectory in the plugins directory. + * @param string &$lastrun The plugin last run time. * * @return boolean True on success. * @@ -497,7 +497,7 @@ public static function unLock($name, $type, $unlock = true) { $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) - ->set($db->qn('checked_out_time') .' = '. $db->quote(\JFactory::getDate()->toSql())) + ->set($db->qn('checked_out_time') . ' = ' . $db->quote(\JFactory::getDate()->toSql())) ->where($db->quoteName('element') . ' = ' . $db->quote($name)) ->where($db->quoteName('folder') . ' = ' . $db->quote($type)); } From 1d7ac7a6ae15d4955db6667974b992bbf8ce2f77 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:22:25 +0200 Subject: [PATCH 21/26] drone cs --- plugins/system/scheduler/scheduler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/scheduler/scheduler.php b/plugins/system/scheduler/scheduler.php index 500e603f3ef99..bcd7a65d5293b 100644 --- a/plugins/system/scheduler/scheduler.php +++ b/plugins/system/scheduler/scheduler.php @@ -115,7 +115,7 @@ public function onAfterRespond() try { JLog::add( - JText::sprintf('PLG_SYSTEM_SCHEDULER_END', $taskid) . ' ' . + JText::sprintf('PLG_SYSTEM_SCHEDULER_END', $taskid) . ' ' . JText::sprintf('PLG_SYSTEM_SCHEDULER_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' ); } From b69ccbc0683f6eec01862df5283bb01bd46f5d8c Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:25:09 +0200 Subject: [PATCH 22/26] drone cs --- plugins/job/logrotation/logrotation.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/job/logrotation/logrotation.php b/plugins/job/logrotation/logrotation.php index 32fe5410689a5..1b9dafbdfabe5 100644 --- a/plugins/job/logrotation/logrotation.php +++ b/plugins/job/logrotation/logrotation.php @@ -57,6 +57,8 @@ class PlgJobLogrotation extends JPlugin /** * The log check and rotation code event. * + * @param array $task An array of options + *. * @return void * * @since __DEPLOY_VERSION__ @@ -96,8 +98,8 @@ public function onExecuteScheduledTask($task = array()) try { JLog::add( - JText::sprintf('PLG_JOB_LOGROTATION_END', $this->_name) . - JText::sprintf('PLG_JOB_LOGROTATION_TASK', $taskid) . + JText::sprintf('PLG_JOB_LOGROTATION_END', $this->_name) . + JText::sprintf('PLG_JOB_LOGROTATION_TASK', $taskid) . JText::sprintf('PLG_JOB_LOGROTATION_PROCESS_COMPLETE', $timeToLoad), JLog::INFO, 'scheduler' From 45fb701c5385a1f0867f2b7db112ac8c62c87699 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 29 Sep 2018 09:29:22 +0200 Subject: [PATCH 23/26] cs --- plugins/job/logrotation/logrotation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/job/logrotation/logrotation.php b/plugins/job/logrotation/logrotation.php index 1b9dafbdfabe5..815f42ac2e1ff 100644 --- a/plugins/job/logrotation/logrotation.php +++ b/plugins/job/logrotation/logrotation.php @@ -58,7 +58,7 @@ class PlgJobLogrotation extends JPlugin * The log check and rotation code event. * * @param array $task An array of options - *. + * * @return void * * @since __DEPLOY_VERSION__ From b62e56b7f4aaa4f3884b33e8945f2eeef4f867ff Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Mon, 1 Oct 2018 20:11:35 +0200 Subject: [PATCH 24/26] identation --- plugins/job/logrotation/logrotation.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/job/logrotation/logrotation.xml b/plugins/job/logrotation/logrotation.xml index 177eebd2b8eac..c748c1a8f4e49 100644 --- a/plugins/job/logrotation/logrotation.xml +++ b/plugins/job/logrotation/logrotation.xml @@ -60,9 +60,9 @@ default="86400" filter="integer" > - - - + + +
Date: Mon, 1 Oct 2018 20:17:01 +0200 Subject: [PATCH 25/26] atomicity of update --- libraries/src/Plugin/PluginHelper.php | 44 ++------------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 81ec6e43fbc6b..514bdc88077e4 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -391,17 +391,6 @@ public static function lock($name, $type, &$lastrun) ->where($db->quoteName('folder') . ' = ' . $db->quote($type)) ->where($db->quoteName('checked_out_time') . ' != ' . $db->q('1918-01-01 00:00:00')); - try - { - // Lock the tables to prevent multiple plugin executions causing a race condition - $db->lockTable('#__extensions'); - } - catch (JDatabaseException $e) - { - // If we can't lock the tables it's too risky to continue execution - return false; - } - $db->setQuery($query); try @@ -413,7 +402,6 @@ public static function lock($name, $type, &$lastrun) catch (JDatabaseException $exc) { // If we failed to execute - $db->unlockTables(); return false; } @@ -422,17 +410,6 @@ public static function lock($name, $type, &$lastrun) { return false; } - - try - { - // Unlock the tables after writing - $db->unlockTables(); - } - catch (JDatabaseException $e) - { - // If we can't unlock the tables assume we have somehow failed - return false; - } $query = $db->getQuery(true) ->select($db->quoteName('params')) @@ -502,17 +479,6 @@ public static function unLock($name, $type, $unlock = true) ->where($db->quoteName('folder') . ' = ' . $db->quote($type)); } - try - { - // Lock the tables to prevent multiple plugin executions causing a race condition - $db->lockTable('#__extensions'); - } - catch (JDatabaseException $e) - { - // If we can't lock the tables it's too risky to continue execution - return false; - } - try { // Update the plugin parameters @@ -521,18 +487,12 @@ public static function unLock($name, $type, $unlock = true) catch (JDatabaseException $exc) { // If we failed to execute - $db->unlockTables(); return false; } - try - { - // Unlock the tables after writing - $db->unlockTables(); - } - catch (JDatabaseException $e) + $result = (int) $db->getAffectedRows(); + if ($result === 0) { - // If we can't unlock the tables assume we have somehow failed return false; } From 7fb4bfb2160c4faeb89da08de496509cddd49601 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Mon, 1 Oct 2018 20:26:46 +0200 Subject: [PATCH 26/26] desc --- administrator/language/en-GB/en-GB.plg_job_logrotation.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/language/en-GB/en-GB.plg_job_logrotation.ini b/administrator/language/en-GB/en-GB.plg_job_logrotation.ini index 9630033a55963..90ae5e79bd2f8 100644 --- a/administrator/language/en-GB/en-GB.plg_job_logrotation.ini +++ b/administrator/language/en-GB/en-GB.plg_job_logrotation.ini @@ -10,7 +10,7 @@ PLG_JOB_LOGROTATION_LOGSTOKEEP_LABEL="Maximum Logs" PLG_JOB_LOGROTATION_CACHETIMEOUT_LABEL="Frequency (in unit)" PLG_JOB_LOGROTATION_CACHETIMEOUT_DESC="How often should the job run." PLG_JOB_LOGROTATION_UNIT_LABEL="Unit of time" -PLG_JOB_LOGROTATION_UNIT_DESC="How often should the job run." +PLG_JOB_LOGROTATION_UNIT_DESC="Choose from minutes, days, months." PLG_JOB_LOGROTATION_PROCESS_COMPLETE="Processing Time: %s seconds." PLG_JOB_LOGROTATION_END="Executed Plugin: %s " PLG_JOB_LOGROTATION_TASK="Task: %s "