/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is designed
* to be called on the first call to the getState() method unless the model
* configuration flag to ignore the request is set.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 1.6
*/
protected function populateState($ordering = null, $direction = null)
{
// If the context is set, assume that stateful lists are used.
if ($this->context) {
$app = Factory::getApplication();
$inputFilter = InputFilter::getInstance();
// Receive & set filters
if ($filters = $app->getUserStateFromRequest($this->context . '.filter', 'filter', array(), 'array')) {
foreach ($filters as $name => $value) {
// Exclude if forbidden
if (!\in_array($name, $this->filterForbiddenList)) {
$this->setState('filter.' . $name, $value);
}
}
}
$limit = 0;
// Receive & set list options
if ($list = $app->getUserStateFromRequest($this->context . '.list', 'list', array(), 'array')) {
foreach ($list as $name => $value) {
// Exclude if forbidden
if (!\in_array($name, $this->listForbiddenList)) {
// Extra validations
switch ($name) {
case 'fullordering':
$orderingParts = explode(' ', $value);
if (\count($orderingParts) >= 2) {
// Latest part will be considered the direction
$fullDirection = end($orderingParts);
if (\in_array(strtoupper($fullDirection), array('ASC', 'DESC', ''))) {
$this->setState('list.direction', $fullDirection);
} else {
$this->setState('list.direction', $direction);
// Fallback to the default value
$value = $ordering . ' ' . $direction;
}
unset($orderingParts[\count($orderingParts) - 1]);
// The rest will be the ordering
$fullOrdering = implode(' ', $orderingParts);
if (\in_array($fullOrdering, $this->filter_fields)) {
$this->setState('list.ordering', $fullOrdering);
} else {
$this->setState('list.ordering', $ordering);
// Fallback to the default value
$value = $ordering . ' ' . $direction;
}
} else {
$this->setState('list.ordering', $ordering);
$this->setState('list.direction', $direction);
// Fallback to the default value
$value = $ordering . ' ' . $direction;
}
break;
case 'ordering':
if (!\in_array($value, $this->filter_fields)) {
$value = $ordering;
}
break;
case 'direction':
if (!\in_array(strtoupper($value), array('ASC', 'DESC', ''))) {
$value = $direction;
}
break;
case 'limit':
$value = $inputFilter->clean($value, 'int');
$limit = $value;
break;
case 'select':
$explodedValue = explode(',', $value);
foreach ($explodedValue as &$field) {
$field = $inputFilter->clean($field, 'cmd');
}
$value = implode(',', $explodedValue);
break;
}
$this->setState('list.' . $name, $value);
}
}
} else {
// Keep B/C for components previous to jform forms for filters
// Pre-fill the limits
$limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint');
$this->setState('list.limit', $limit);
// Check if the ordering field is in the allowed list, otherwise use the incoming value.
$value = $app->getUserStateFromRequest($this->context . '.ordercol', 'filter_order', $ordering);
if (!\in_array($value, $this->filter_fields)) {
$value = $ordering;
$app->setUserState($this->context . '.ordercol', $value);
}
$this->setState('list.ordering', $value);
// Check if the ordering direction is valid, otherwise use the incoming value.
$value = $app->getUserStateFromRequest($this->context . '.orderdirn', 'filter_order_Dir', $direction);
if (!$value || !\in_array(strtoupper($value), array('ASC', 'DESC', ''))) {
$value = $direction;
$app->setUserState($this->context . '.orderdirn', $value);
}
$this->setState('list.direction', $value);
}
// Support old ordering field
$oldOrdering = $app->input->get('filter_order');
if (!empty($oldOrdering) && \in_array($oldOrdering, $this->filter_fields)) {
$this->setState('list.ordering', $oldOrdering);
}
// Support old direction field
$oldDirection = $app->input->get('filter_order_Dir');
if (!empty($oldDirection) && \in_array(strtoupper($oldDirection), array('ASC', 'DESC', ''))) {
$this->setState('list.direction', $oldDirection);
}
$value = $app->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0, 'int');
$limitstart = $limit != 0 ? floor($value / $limit) * $limit : 0;
$this->setState('list.start', $limitstart);
} else {
$this->setState('list.start', 0);
$this->setState('list.limit', 0);
}
}