diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 95f3cc0170365..bac44530eff41 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -11,6 +11,7 @@ namespace Joomla\Component\Scheduler\Administrator\Model; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; @@ -366,7 +367,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array { // Get stuff from the model state $listOrder = $this->getState('list.ordering', 'a.title'); - $listDirectionN = strtolower($this->getState('list.direction', 'asc')) == 'desc' ? -1 : 1; + $listDirectionN = strtolower($this->getState('list.direction', 'asc')) === 'desc' ? -1 : 1; // Set limit parameters and get object list $query->setLimit($limit, $limitstart); @@ -395,7 +396,7 @@ static function (array $arr) { $this->attachTaskOptions($responseList); // If ordering by non-db fields, we need to sort here in code - if ($listOrder == 'j.type_title') { + if ($listOrder === 'j.type_title') { $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } @@ -437,4 +438,34 @@ protected function populateState($ordering = 'a.title', $direction = 'ASC'): voi // Call the parent method parent::populateState($ordering, $direction); } + + /** + * Check if we have any enabled due tasks and no locked tasks. + * + * @param Date $time The next execution time to check against + * + * @return boolean + * @since __DEPLOY_VERSION__ + */ + public function hasDueTasks(Date $time): bool + { + $db = $this->getDatabase(); + $now = $time->toSql(); + + $query = $db->getQuery(true) + // Count due tasks + ->select('SUM(CASE WHEN ' . $db->quoteName('a.next_execution') . ' <= :now THEN 1 ELSE 0 END) AS due_count') + // Count locked tasks + ->select('SUM(CASE WHEN ' . $db->quoteName('a.locked') . ' IS NULL THEN 0 ELSE 1 END) AS locked_count') + ->from($db->quoteName('#__scheduler_tasks', 'a')) + ->where($db->quoteName('a.state') . ' = 1') + ->bind(':now', $now); + + $db->setQuery($query); + + $taskDetails = $db->loadObject(); + + // False if we don't have due tasks, or we have locked tasks + return $taskDetails && $taskDetails->due_count && !$taskDetails->locked_count; + } } diff --git a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php index f4f507229f66f..7bac5df8ba957 100644 --- a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php +++ b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php @@ -19,6 +19,7 @@ use Joomla\CMS\Session\Session; use Joomla\CMS\Table\Extension; use Joomla\CMS\User\UserHelper; +use Joomla\Component\Scheduler\Administrator\Model\TasksModel; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; use Joomla\Component\Scheduler\Administrator\Task\Task; use Joomla\Event\Event; @@ -109,22 +110,13 @@ public function injectLazyJS(EventInterface $event): void return; } - // Check if any task is due to decrease the load + /** @var TasksModel $model */ $model = $this->getApplication()->bootComponent('com_scheduler') ->getMVCFactory()->createModel('Tasks', 'Administrator', ['ignore_request' => true]); - $model->setState('filter.state', 1); - $model->setState('filter.due', 1); + $now = Factory::getDate('now', 'UTC'); - $items = $model->getItems(); - - // See if we are running currently - $model->setState('filter.locked', 1); - $model->setState('filter.due', 0); - - $items2 = $model->getItems(); - - if (empty($items) || !empty($items2)) { + if (!$model->hasDueTasks($now)) { return; } @@ -262,7 +254,7 @@ public function runTestCron(Event $event) ] ); - if (!is_null($task)) { + if ($task) { $task->run(); $event->addArgument('result', $task->getContent()); } else { @@ -286,7 +278,7 @@ public function runTestCron(Event $event) * @return ?Task * * @since 4.1.0 - * @throws RuntimeException + * @throws \RuntimeException */ private function runScheduler(int $id = 0): ?Task { @@ -301,7 +293,7 @@ private function runScheduler(int $id = 0): ?Task * @return void * * @since 4.1.0 - * @throws UnexpectedValueException|RuntimeException + * @throws \UnexpectedValueException|\RuntimeException * * @todo Move to another plugin? */