Add pagination support to the servicematrix

refs #4180
This commit is contained in:
Johannes Meyer 2014-03-13 16:26:14 +01:00
parent dbab546f0a
commit 617b6822d7
4 changed files with 133 additions and 98 deletions

View File

@ -41,6 +41,11 @@ title = "Services"
url = "monitoring/list/services" url = "monitoring/list/services"
priority = 50 priority = 50
[Overview.Servicematrix]
title = "Servicematrix"
url = "monitoring/list/servicematrix"
priority = 51
[Overview.Servicegroups] [Overview.Servicegroups]
title = "Servicegroups" title = "Servicegroups"
url = "monitoring/list/servicegroups" url = "monitoring/list/servicegroups"

View File

@ -4,7 +4,10 @@
namespace Icinga\Data; namespace Icinga\Data;
use \Zend_Paginator;
use Icinga\Data\BaseQuery; use Icinga\Data\BaseQuery;
use Icinga\Application\Icinga;
use Icinga\Web\Paginator\Adapter\QueryAdapter;
class PivotTable class PivotTable
{ {
@ -13,121 +16,144 @@ class PivotTable
* *
* @var BaseQuery * @var BaseQuery
*/ */
protected $query; protected $baseQuery;
/** /**
* The column to use for the x axis * The query to fetch the x axis labels
*
* @var BaseQuery
*/
protected $xAxisQuery;
/**
* The query to fetch the y axis labels
*
* @var BaseQuery
*/
protected $yAxisQuery;
/**
* The column that contains the labels for the x axis
* *
* @var string * @var string
*/ */
protected $xAxisColumn; protected $xAxisColumn;
/** /**
* The column to use for the y axis * The column that contains the labels for the y axis
* *
* @var string * @var string
*/ */
protected $yAxisColumn; protected $yAxisColumn;
protected $limit;
protected $offset;
protected $verticalLimit;
protected $horizontalLimit;
/** /**
* Create a new pivot table * Create a new pivot table
* *
* @param BaseQuery $query The query to fetch as pivot table * @param BaseQuery $query The query to fetch as pivot table
* @param string $xAxisColumn The column to use for the x axis * @param string $xAxisColumn The column that contains the labels for the x axis
* @param string $yAxisColumn The column to use for the y axis * @param string $yAxisColumn The column that contains the labels for the y axis
*/ */
public function __construct(BaseQuery $query, $xAxisColumn, $yAxisColumn) public function __construct(BaseQuery $query, $xAxisColumn, $yAxisColumn)
{ {
$this->query = $query; $this->baseQuery = $query;
$this->xAxisColumn = $xAxisColumn; $this->xAxisColumn = $xAxisColumn;
$this->yAxisColumn = $yAxisColumn; $this->yAxisColumn = $yAxisColumn;
$this->prepareQueries();
} }
public function limit($limit = null, $offset = null) /**
* Prepare the queries used for the pre processing
*/
protected function prepareQueries()
{ {
$this->limit = $limit; $this->xAxisQuery = clone $this->baseQuery;
$this->offset = $offset; $this->xAxisQuery->distinct();
return $this; $this->xAxisQuery->setColumns(array($this->xAxisColumn));
$this->yAxisQuery = clone $this->baseQuery;
$this->yAxisQuery->distinct();
$this->yAxisQuery->setColumns(array($this->yAxisColumn));
} }
public function getLimit() /**
* Return the value for the given request parameter
*
* @param string $axis The axis for which to return the parameter ('x' or 'y')
* @param string $param The parameter name to return
* @param int $default The default value to return
*
* @return int
*/
protected function getPaginationParameter($axis, $param, $default = null)
{ {
if ($this->limit === null) { $request = Icinga::app()->getFrontController()->getRequest();
return 20;
} $value = $request->getParam($param, '');
return $this->limit; if (strpos($value, ',') > 0) {
$parts = explode(',', $value, 2);
return intval($parts[$axis === 'x' ? 0 : 1]);
} }
public function getOffset() return $default !== null ? $default : 0;
{
if ($this->limit === null) {
return 20;
}
return $this->offset;
} }
public function verticalLimit($limit = null, $offset = null) /**
* Return a pagination adapter for the x axis query
*
* $limit and $page are taken from the current request if not given.
*
* @param int $limit The maximum amount of entries to fetch
* @param int $page The page to set as current one
*
* @return Zend_Paginator
*/
public function paginateXAxis($limit = null, $page = null)
{ {
// TODO: Trigger limit by calling $this->limit()? if ($limit === null || $page === null) {
if ($limit === null) { if ($limit === null) {
$limit = $this->getLimit(); $limit = $this->getPaginationParameter('x', 'limit', 20);
}
if ($offset === null) {
$offset = $this->getOffset();
}
$this->verticalLimit = $limit;
$this->verticalOffset = $offset;
return $this;
} }
public function paginateVertical($limit = null, $offset = null) if ($page === null) {
{ $page = $this->getPaginationParameter('x', 'page', 1);
$this->verticalLimit($limit, $offset); }
return Paginator($this);
} }
public function getVerticalLimit() $this->xAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
{
if ($this->verticalLimit === null) {
return 20;
}
return $this->verticalLimit;
}
public function getVerticalOffset() $paginator = new Zend_Paginator(new QueryAdapter($this->xAxisQuery));
{ $paginator->setItemCountPerPage($limit);
if ($this->verticalLimit === null) { $paginator->setCurrentPageNumber($page);
return 20; return $paginator;
}
return $this->verticalOffset;
} }
/** /**
* Fetch the values to label the x axis with * Return a pagination adapter for the y axis query
*
* $limit and $page are taken from the current request if not given.
*
* @param int $limit The maximum amount of entries to fetch
* @param int $page The page to set as current one
*
* @return Zend_Paginator
*/ */
protected function fetchXAxis() public function paginateYAxis($limit = null, $page = null)
{ {
$query = clone $this->query; if ($limit === null || $page === null) {
$query->setColumns(array($this->xAxisColumn)); if ($limit === null) {
return $query->fetchColumn(); $limit = $this->getPaginationParameter('y', 'limit', 20);
} }
/** if ($page === null) {
* Fetch the values to label the y axis with $page = $this->getPaginationParameter('y', 'page', 1);
*/ }
protected function fetchYAxis() }
{
$query = clone $this->query; $this->yAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
$query->setColumns(array($this->yAxisColumn));
return $query->fetchColumn(); $paginator = new Zend_Paginator(new QueryAdapter($this->yAxisQuery));
$paginator->setItemCountPerPage($limit);
$paginator->setCurrentPageNumber($page);
return $paginator;
} }
/** /**
@ -137,13 +163,14 @@ class PivotTable
*/ */
public function toArray() public function toArray()
{ {
$xAxis = $this->fetchXAxis(); $xAxis = $this->xAxisQuery->fetchColumn();
$yAxis = $this->fetchYAxis(); $yAxis = $this->yAxisQuery->fetchColumn();
$this->query->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
$pivot = array(); $pivot = array();
foreach ($this->query->fetchAll() as $row) { if (!empty($xAxis) && !empty($yAxis)) {
$this->baseQuery->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
foreach ($this->baseQuery->fetchAll() as $row) {
if (!array_key_exists($row->{$this->yAxisColumn}, $pivot)) { if (!array_key_exists($row->{$this->yAxisColumn}, $pivot)) {
$defaults = array(); $defaults = array();
foreach ($xAxis as $label) { foreach ($xAxis as $label) {
@ -154,6 +181,7 @@ class PivotTable
$pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row; $pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
} }
}
return $pivot; return $pivot;
} }

View File

@ -481,7 +481,9 @@ class Monitoring_ListController extends Controller
) )
); );
$this->view->matrix = $dataview->pivot('service_description', 'host_name')->toArray(); $this->view->pivot = $dataview->pivot('service_description', 'host_name');
$this->view->horizontalPaginator = $this->view->pivot->paginateXAxis();
$this->view->verticalPaginator = $this->view->pivot->paginateYAxis();
} }
/** /**

View File

@ -9,7 +9,7 @@
<div class="content" data-base-target="_next"> <div class="content" data-base-target="_next">
<table class="pivot servicestates"> <table class="pivot servicestates">
<?php $hasHeader = false; ?> <?php $hasHeader = false; ?>
<?php foreach ($this->matrix as $host_name => $serviceStates): ?> <?php foreach ($this->pivot->toArray() as $host_name => $serviceStates): ?>
<?php if (!$hasHeader): ?> <?php if (!$hasHeader): ?>
<thead> <thead>
<tr> <tr>