Merge branch 'bugfix/respect-default-sort-rules-6644'

fixes #6644
This commit is contained in:
Johannes Meyer 2015-07-28 12:14:00 +02:00
commit e15cd65ed4
7 changed files with 108 additions and 36 deletions

View File

@ -0,0 +1,14 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Data;
interface SortRules
{
/**
* Return some sort rules
*
* @return array
*/
public function getSortRules();
}

View File

@ -78,7 +78,7 @@ abstract class Repository implements Selectable
protected $filterColumns;
/**
* The default sort rules to be applied on a query
* The sort rules to be applied on a query
*
* This may be initialized by concrete repository implementations, in the following format
* <pre><code>
@ -284,7 +284,7 @@ abstract class Repository implements Selectable
}
/**
* Return the default sort rules to be applied on a query
* Return the sort rules to be applied on a query
*
* Calls $this->initializeSortRules() in case $this->sortRules is null.
*

View File

@ -9,12 +9,13 @@ use Icinga\Application\Benchmark;
use Icinga\Application\Logger;
use Icinga\Data\QueryInterface;
use Icinga\Data\Filter\Filter;
use Icinga\Data\SortRules;
use Icinga\Exception\QueryException;
/**
* Query class supposed to mediate between a repository and its datasource's query
*/
class RepositoryQuery implements QueryInterface, Iterator
class RepositoryQuery implements QueryInterface, SortRules, Iterator
{
/**
* The repository being used
@ -212,6 +213,16 @@ class RepositoryQuery implements QueryInterface, Iterator
return $this->query->getFilter();
}
/**
* Return the sort rules being applied on this query
*
* @return array
*/
public function getSortRules()
{
return $this->repository->getSortRules();
}
/**
* Add a sort rule for this query
*
@ -226,7 +237,7 @@ class RepositoryQuery implements QueryInterface, Iterator
*/
public function order($field = null, $direction = null, $ignoreDefault = false)
{
$sortRules = $this->repository->getSortRules();
$sortRules = $this->getSortRules();
if ($field === null) {
// Use first available sort rule as default
if (empty($sortRules)) {

View File

@ -3,30 +3,26 @@
namespace Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Data\Sortable;
use Icinga\Data\SortRules;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\Sortable;
use Icinga\Application\Icinga;
/**
* SortBox widget
*
* The "SortBox" Widget allows you to create a generic sort input for sortable views. It automatically creates a form
* containing a select box with all sort options and a dropbox with the sort direction. It also handles automatic
* submission of sorting changes and draws an additional submit button when JavaScript is disabled.
* The "SortBox" Widget allows you to create a generic sort input for sortable views. It automatically creates a select
* box with all sort options and a dropbox with the sort direction. It also handles automatic submission of sorting
* changes and draws an additional submit button when JavaScript is disabled.
*
* The constructor takes an string for the component name and an array containing the select options, where the key is
* The constructor takes a string for the component name and an array containing the select options, where the key is
* the value to be submitted and the value is the label that will be shown. You then should call setRequest in order
* to make sure the form is correctly populated when a request with a sort parameter is being made.
*
* Example:
* <pre><code>
* $this->view->sortControl = new SortBox(
* $this->getRequest()->getActionName(),
* $columns
* );
* $this->view->sortControl->setRequest($this->getRequest());
* </code></pre>
* Call setQuery in case you'll do not want to handle URL parameters manually, but to automatically apply the user's
* chosen sort rules on the given sortable query. This will also allow the SortBox to display the user the correct
* default sort rules if the given query provides already some sort rules.
*/
class SortBox extends AbstractWidget
{
@ -38,25 +34,25 @@ class SortBox extends AbstractWidget
protected $sortFields;
/**
* The name of the form that will be created
* The name used to uniquely identfy the forms being created
*
* @var string
*/
protected $name;
/**
* A request object used for initial form population
* The request to fetch sort rules from
*
* @var Request
*/
protected $request;
/**
* What to apply sort parameters on
* The query to apply sort rules on
*
* @var Sortable
*/
protected $query = null;
protected $query;
/**
* Create a SortBox with the entries from $sortFields
@ -84,9 +80,9 @@ class SortBox extends AbstractWidget
}
/**
* Apply the parameters from the given request on this SortBox
* Set the request to fetch sort rules from
*
* @param Request $request The request to use for populating the form
* @param Request $request
*
* @return $this
*/
@ -97,9 +93,11 @@ class SortBox extends AbstractWidget
}
/**
* @param Sortable $query
* Set the query to apply sort rules on
*
* @return $this
* @param Sortable $query
*
* @return $this
*/
public function setQuery(Sortable $query)
{
@ -107,19 +105,54 @@ class SortBox extends AbstractWidget
return $this;
}
/**
* Apply the sort rules from the given or current request on the query
*
* @param Request $request
*
* @return $this
*/
public function handleRequest(Request $request = null)
{
if ($this->query !== null) {
if ($request === null) {
$request = Icinga::app()->getFrontController()->getRequest();
}
if ($sort = $request->getParam('sort')) {
if (($sort = $request->getParam('sort'))) {
$this->query->order($sort, $request->getParam('dir'));
} elseif (($dir = $request->getParam('dir'))) {
$this->query->order(null, $dir);
}
}
return $this;
}
/**
* Return the default sort rule for the query
*
* @param string $column An optional column
*
* @return array An array of two values: $column, $direction
*/
protected function getSortDefaults($column = null)
{
$direction = null;
if ($this->query !== null && $this->query instanceof SortRules) {
$sortRules = $this->query->getSortRules();
if ($column === null) {
$column = key($sortRules);
}
if ($column !== null && isset($sortRules[$column]['order'])) {
$direction = strtoupper($sortRules[$column]['order']) === Sortable::SORT_DESC ? 'desc' : 'asc';
}
}
return array($column, $direction);
}
/**
* Render this SortBox as HTML
*
@ -166,17 +199,29 @@ class SortBox extends AbstractWidget
)
);
$column = null;
if ($this->request) {
$url = $this->request->getUrl();
if ($url->hasParam('sort')) {
$columnForm->populate(array('sort' => $url->getParam('sort')));
}
$column = $url->getParam('sort');
if ($url->hasParam('dir')) {
$orderForm->populate(array('dir' => $url->getParam('dir')));
if ($url->hasParam('dir')) {
$direction = $url->getParam('dir');
} else {
list($_, $direction) = $this->getSortDefaults($column);
}
} elseif ($url->hasParam('dir')) {
$direction = $url->getParam('dir');
list($column, $_) = $this->getSortDefaults();
}
}
if ($column === null) {
list($column, $direction) = $this->getSortDefaults();
}
$columnForm->populate(array('sort' => $column));
$orderForm->populate(array('dir' => $direction));
return '<div class="sort-control">' . $columnForm . $orderForm . '</div>';
}
}

View File

@ -36,8 +36,10 @@ class Customvar extends DataView
{
return array(
'varname' => array(
'varname' => self::SORT_ASC,
'varvalue' => self::SORT_ASC,
'columns' => array(
'varname',
'varvalue'
)
)
);
}

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Monitoring\DataView;
use IteratorAggregate;
use Icinga\Data\QueryInterface;
use Icinga\Data\SortRules;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterMatch;
use Icinga\Data\PivotTable;
@ -18,7 +19,7 @@ use Icinga\Module\Monitoring\Backend\MonitoringBackend;
/**
* A read-only view of an underlying query
*/
abstract class DataView implements QueryInterface, IteratorAggregate
abstract class DataView implements QueryInterface, SortRules, IteratorAggregate
{
/**
* The query used to populate the view

View File

@ -49,8 +49,7 @@ class EventHistory extends DataView
{
return array(
'timestamp' => array(
'columns' => array('timestamp'),
'order' => 'DESC'
'order' => self::SORT_DESC
)
);
}