Skip to content

Commit

Permalink
Add filtering by lock state in TasksModel
Browse files Browse the repository at this point in the history
Adds support for filtering by the "lock" state of a task. Also in
the process defines different lock levels: hard locks and soft locks.
I think in the future, the filtering states should maybe
go into a namespace/class for constants.
  • Loading branch information
ditsuke committed Sep 6, 2021
1 parent 09892db commit 46bd367
Showing 1 changed file with 44 additions and 2 deletions.
46 changes: 44 additions & 2 deletions administrator/components/com_scheduler/src/Model/TasksModel.php
Expand Up @@ -14,7 +14,9 @@
// Restrict direct access
defined('_JEXEC') or die;

use DateInterval;
use Exception;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
Expand Down Expand Up @@ -160,7 +162,7 @@ protected function getListQuery(): QueryInterface
$extendWhereIfFiltered = function (
string $outerGlue, array $conditions, string $innerGlue
) use ($query, &$filterCount) {
if ($filterCount)
if ($filterCount++)
{
$query->extendWhere($outerGlue, $conditions, $innerGlue);
}
Expand Down Expand Up @@ -212,12 +214,52 @@ protected function getListQuery(): QueryInterface
if (is_numeric($due = $this->getState('filter.due')) && $due != 0)
{
$now = Factory::getDate('now', 'GMT')->toSql();
$operator = $due == 1 ? '<= ' : '> ';
$operator = $due == 1 ? ' <= ' : ' > ';
$filterCount++;
$query->where($db->qn('a.next_execution') . $operator . ':now')
->bind(':now', $now);
}

/*
* Filter locked ---
* Locks can be either hard locks or soft locks. Locks that have expired (exceeded the task timeout) are soft
* locks. Hard-locked tasks are assumed to be running. Soft-locked tasks are assumed to have suffered a fatal
* failure.
* {-2: exclude-all, -1: exclude-hard-locked, 0: include, 1: include-only-locked, 2: include-only-soft-locked}
*/
if (is_numeric($locked = $this->getState('filter.locked')) && $locked != 0)
{
$now = Factory::getDate('now', 'GMT');
$timeout = ComponentHelper::getParams('com_scheduler')->get('timeout', 300);
$timeout = new DateInterval(sprintf('PT%dS', $timeout));
$timeoutThreshold = (clone $now)->sub($timeout)->toSql();
$now = $now->toSql();

switch ($locked)
{
case -2:
$query->where($db->qn('a.locked') . 'IS NULL');
break;
case -1:
$extendWhereIfFiltered(
'AND',
[
$db->qn('a.locked') . ' IS NULL',
$db->qn('a.locked') . ' < :threshold'
],
'OR'
);
$query->bind(':threshold', $timeoutThreshold);
break;
case 1:
$query->where($db->qn('a.locked') . ' IS NOT NULL');
break;
case 2:
$query->where($db->qn('a.locked') . ' < :threshold')
->bind(':threshold', $timeoutThreshold);
}
}

// Filter over search string if set (title, type title, note, id) ----
$searchStr = $this->getState('filter.search');

Expand Down

0 comments on commit 46bd367

Please sign in to comment.