Skip to content
38 changes: 32 additions & 6 deletions administrator/components/com_users/src/Model/UsersModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,13 +378,26 @@ protected function getListQuery()
}
}

// Add filter for registration time ranges select list
// Add filter for registration time ranges select list. UI Visitors get a range of predefined
// values. API users can do a full range based on ISO8601
$range = $this->getState('filter.range');
$registrationStart = $this->getState('filter.registrationDateStart');
$registrationEnd = $this->getState('filter.registrationDateEnd');

// Apply the range filter.
if ($range)
if ($range || ($registrationStart && $registrationEnd))
{
$dates = $this->buildDateRange($range);
if ($range)
{
$dates = $this->buildDateRange($range);
}
else
{
$dates = [
'dNow' => $registrationEnd,
'dStart' => $registrationStart,
];
}

if ($dates['dStart'] !== false)
{
Expand All @@ -406,13 +419,26 @@ protected function getListQuery()
}
}

// Add filter for last visit time ranges select list
// Add filter for last visit time ranges select list. UI Visitors get a range of predefined
// values. API users can do a full range based on ISO8601
$lastvisitrange = $this->getState('filter.lastvisitrange');
$lastVisitStart = $this->getState('filter.lastVisitStart');
$lastVisitEnd = $this->getState('filter.lastVisitEnd');

// Apply the range filter.
if ($lastvisitrange)
if ($lastvisitrange || ($lastVisitStart && $lastVisitEnd))
{
$dates = $this->buildDateRange($lastvisitrange);
if ($lastvisitrange)
{
$dates = $this->buildDateRange($lastvisitrange);
}
else
{
$dates = [
'dNow' => $lastVisitEnd,
'dStart' => $lastVisitStart,
];
}

if ($dates['dStart'] === false)
{
Expand Down
116 changes: 115 additions & 1 deletion api/components/com_users/src/Controller/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@

\defined('_JEXEC') or die;

use Joomla\CMS\Date\Date;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\ApiController;
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
use Tobscure\JsonApi\Exception\InvalidParameterException;

/**
* The users controller
Expand All @@ -33,7 +37,7 @@ class UsersController extends ApiController
* The default view for the display method.
*
* @var string
* @since 3.0
* @since 4.0.0
*/
protected $default_view = 'users';

Expand Down Expand Up @@ -65,4 +69,114 @@ protected function save($recordKey = null)

return parent::save($recordKey);
}

/**
* User list view with filtering of data
*
* @return static A BaseController object to support chaining.
*
* @since __DEPLOY_VERSION__
* @throws InvalidParameterException
*/
public function displayList()
{
$apiFilterInfo = $this->input->get('filter', [], 'array');
$filter = InputFilter::getInstance();

if (array_key_exists('state', $apiFilterInfo))
{
$this->modelState->set('filter.state', $filter->clean($apiFilterInfo['state'], 'INT'));
}

if (array_key_exists('active', $apiFilterInfo))
{
$this->modelState->set('filter.active', $filter->clean($apiFilterInfo['active'], 'INT'));
}

if (array_key_exists('groupid', $apiFilterInfo))
{
$this->modelState->set('filter.group_id', $filter->clean($apiFilterInfo['groupid'], 'INT'));
}

if (array_key_exists('search', $apiFilterInfo))
{
$this->modelState->set('filter.search', $filter->clean($apiFilterInfo['search'], 'STRING'));
}

if (array_key_exists('registrationDateStart', $apiFilterInfo))
{
$registrationStartInput = $filter->clean($apiFilterInfo['registrationDateStart'], 'STRING');
$registrationStartDate = Date::createFromFormat(\DateTime::RFC3339, $registrationStartInput);

if (!$registrationStartDate)
{
// Send the error response
$error = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'registrationDateStart');

throw new InvalidParameterException($error, 400, null, 'registrationDateStart');
}

$this->modelState->set('filter.registrationDateStart', $registrationStartDate);
}

if (array_key_exists('registrationDateEnd', $apiFilterInfo))
{
$registrationEndInput = $filter->clean($apiFilterInfo['registrationDateEnd'], 'STRING');
$registrationEndDate = Date::createFromFormat(\DateTime::RFC3339, $registrationEndInput);

if (!$registrationEndDate)
{
// Send the error response
$error = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'registrationDateEnd');
throw new InvalidParameterException($error, 400, null, 'registrationDateEnd');
}

$this->modelState->set('filter.registrationDateEnd', $registrationEndDate);
}
elseif (array_key_exists('registrationDateStart', $apiFilterInfo)
&& !array_key_exists('registrationDateEnd', $apiFilterInfo))
{
// If no end date specified the end date is now
$this->modelState->set('filter.registrationDateEnd', new Date);
}

if (array_key_exists('lastVisitDateStart', $apiFilterInfo))
{
$lastVisitStartInput = $filter->clean($apiFilterInfo['lastVisitDateStart'], 'STRING');
$lastVisitStartDate = Date::createFromFormat(\DateTime::RFC3339, $lastVisitStartInput);

if (!$lastVisitStartDate)
{
// Send the error response
$error = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'lastVisitDateStart');
throw new InvalidParameterException($error, 400, null, 'lastVisitDateStart');
}

$this->modelState->set('filter.lastVisitStart', $lastVisitStartDate);
}

if (array_key_exists('lastVisitDateEnd', $apiFilterInfo))
{
$lastVisitEndInput = $filter->clean($apiFilterInfo['lastVisitDateEnd'], 'STRING');
$lastVisitEndDate = Date::createFromFormat(\DateTime::RFC3339, $lastVisitEndInput);

if (!$lastVisitEndDate)
{
// Send the error response
$error = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'lastVisitDateEnd');

throw new InvalidParameterException($error, 400, null, 'lastVisitDateEnd');
}

$this->modelState->set('filter.lastVisitEnd', $lastVisitEndDate);
}
elseif (array_key_exists('lastVisitDateStart', $apiFilterInfo)
&& !array_key_exists('lastVisitDateEnd', $apiFilterInfo))
{
// If no end date specified the end date is now
$this->modelState->set('filter.lastVisitEnd', new Date);
}

return parent::displayList();
}
}