Thomas Gelf 307787cfb7 DataView: use default sort order if none given
We should not be forced to order(null) to have the default order, that
should be the default in case order has not been called.

refs #6644
2014-09-02 12:54:38 +02:00

332 lines
8.4 KiB
PHP

<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\DataView;
use Icinga\Data\Filter\Filter;
use Icinga\Data\SimpleQuery;
use Icinga\Data\Browsable;
use Icinga\Data\PivotTable;
use Icinga\Data\Sortable;
use Icinga\Data\ConnectionInterface;
use Icinga\Data\Filterable;
use Icinga\Web\Request;
use Icinga\Web\Url;
use Icinga\Module\Monitoring\Backend;
/**
* A read-only view of an underlying query
*/
abstract class DataView implements Browsable, Filterable, Sortable
{
/**
* The query used to populate the view
*
* @var SimpleQuery
*/
private $query;
protected $filter;
protected $connection;
protected $isSorted = false;
/**
* Create a new view
*
* @param SimpleQuery $query Which backend to query
* @param array $columns Select columns
*/
public function __construct(ConnectionInterface $connection, array $columns = null)
{
$this->connection = $connection;
$queryClass = $connection->getQueryClass($this->getQueryName());
$this->query = new $queryClass($this->connection->getResource(), $columns);
$this->filter = Filter::matchAll();
}
/**
* Get the query name this data view relies on
*
* By default this is this class' name without its namespace
*
* @return string
*/
public static function getQueryName()
{
$tableName = explode('\\', get_called_class());
$tableName = end($tableName);
return $tableName;
}
public function where($condition, $value = null)
{
$this->filter->addFilter(Filter::where($condition, $value));
$this->query->where($condition, $value);
return $this;
}
public function dump()
{
return $this->query->dump();
}
/**
* Retrieve columns provided by this view
*
* @return array
*/
abstract public function getColumns();
/**
* Create view from request
*
* @param Request $request
* @param array $columns
*
* @return static
* @deprecated Use $backend->select()->from($viewName) instead
*/
public static function fromRequest($request, array $columns = null)
{
$view = new static(Backend::createBackend($request->getParam('backend')), $columns);
$view->applyUrlFilter($request);
return $view;
}
// TODO: This is not the right place for this, move it away
protected function applyUrlFilter($request = null)
{
$url = Url::fromRequest();
$limit = $url->shift('limit');
$sort = $url->shift('sort');
$dir = $url->shift('dir');
$page = $url->shift('page');
$format = $url->shift('format');
$view = $url->shift('view');
$view = $url->shift('backend');
foreach ($url->getParams() as $k => $v) {
$this->where($k, $v);
}
if ($sort) {
$this->order($sort, $dir);
}
}
/**
* Create view from params
*
* @param array $params
* @param array $columns
*
* @return static
*/
public static function fromParams(array $params, array $columns = null)
{
$view = new static(Backend::createBackend($params['backend']), $columns);
foreach ($params as $key => $value) {
if ($view->isValidFilterTarget($key)) {
$view->where($key, $value);
}
}
if (isset($params['sort'])) {
$order = isset($params['order']) ? $params['order'] : null;
if ($order !== null) {
if (strtolower($order) === 'desc') {
$order = self::SORT_DESC;
} else {
$order = self::SORT_ASC;
}
}
$view->sort($params['sort'], $order);
}
return $view;
}
/**
* Check whether the given column is a valid filter column, i.e. the view actually provides the column or it's
* a non-queryable filter column
*
* @param string $column
*
* @return bool
*/
public function isValidFilterTarget($column)
{
return in_array($column, $this->getColumns()) || in_array($column, $this->getFilterColumns());
}
public function getFilterColumns()
{
return array();
}
public function getFilter()
{
return $this->filter;
}
/**
* Return a pivot table for the given columns based on the current query
*
* @param string $xAxisColumn The column to use for the x axis
* @param string $yAxisColumn The column to use for the y axis
*
* @return PivotTable
*/
public function pivot($xAxisColumn, $yAxisColumn)
{
return new PivotTable($this->query, $xAxisColumn, $yAxisColumn);
}
/**
* Sort the rows, according to the specified sort column and order
*
* @param string $column Sort column
* @param int $order Sort order, one of the SORT_ constants
*
* @return self
* @see DataView::SORT_ASC
* @see DataView::SORT_DESC
* @deprecated Use DataView::order() instead
*/
public function sort($column = null, $order = null)
{
$sortRules = $this->getSortRules();
if ($sortRules !== null) {
if ($column === null) {
$sortColumns = reset($sortRules);
if (!isset($sortColumns['columns'])) {
$sortColumns['columns'] = array(key($sortRules));
}
} else {
if (isset($sortRules[$column])) {
$sortColumns = $sortRules[$column];
if (!isset($sortColumns['columns'])) {
$sortColumns['columns'] = array($column);
}
} else {
$sortColumns = array(
'columns' => array($column),
'order' => $order
);
};
}
$order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : self::SORT_ASC) : $order;
$order = (strtoupper($order) === self::SORT_ASC) ? 'ASC' : 'DESC';
foreach ($sortColumns['columns'] as $column) {
$this->query->order($column, $order);
}
$this->isSorted = true;
}
return $this;
}
/**
* Retrieve default sorting rules for particular columns. These involve sort order and potential additional to sort
*
* @return array
*/
public function getSortRules()
{
return null;
}
/**
* Sort result set either by the given column (and direction) or the sort defaults
*
* @param string $column
* @param string $direction
*
* @return self
*/
public function order($column = null, $direction = null)
{
return $this->sort($column, $direction);
}
/**
* Whether an order is set
*
* @return bool
*/
public function hasOrder()
{
return $this->query->hasOrder();
}
/**
* Get the order if any
*
* @return array|null
*/
public function getOrder()
{
return $this->query->getOrder();
}
public function getMappedField($field)
{
return $this->query->getMappedField($field);
}
/**
* Return the query which was created in the constructor
*
* @return mixed
*/
public function getQuery()
{
if (! $this->isSorted) { $this->sort(); }
return $this->query;
}
public function applyFilter(Filter $filter)
{
return $this->addFilter($filter);
}
public function clearFilter()
{
$this->query->clearFilter();
return $this;
}
public function setFilter(Filter $filter)
{
$this->query->setFilter($filter);
return $this;
}
public function addFilter(Filter $filter)
{
$this->query->addFilter(clone($filter));
$this->filter = $filter; // TODO: Hmmmm.... and?
return $this;
}
/**
* Paginate data
*
* @param int $itemsPerPage Number of items per page
* @param int $pageNumber Current page number
*
* @return Zend_Paginator
*/
public function paginate($itemsPerPage = null, $pageNumber = null)
{
return $this->query->paginate($itemsPerPage, $pageNumber);
}
}