218 lines
6.3 KiB
PHP
218 lines
6.3 KiB
PHP
<?php
|
|
// {{{ICINGA_LICENSE_HEADER}}}
|
|
// {{{ICINGA_LICENSE_HEADER}}}
|
|
|
|
namespace Icinga\Data;
|
|
|
|
use \Zend_Paginator;
|
|
use Icinga\Data\BaseQuery;
|
|
use Icinga\Application\Icinga;
|
|
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
|
|
|
class PivotTable
|
|
{
|
|
/**
|
|
* The query to fetch as pivot table
|
|
*
|
|
* @var BaseQuery
|
|
*/
|
|
protected $baseQuery;
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
protected $xAxisColumn;
|
|
|
|
/**
|
|
* The column that contains the labels for the y axis
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $yAxisColumn;
|
|
|
|
/**
|
|
* Create a new pivot table
|
|
*
|
|
* @param BaseQuery $query The query to fetch as pivot table
|
|
* @param string $xAxisColumn The column that contains the labels for the x axis
|
|
* @param string $yAxisColumn The column that contains the labels for the y axis
|
|
*/
|
|
public function __construct(BaseQuery $query, $xAxisColumn, $yAxisColumn)
|
|
{
|
|
$this->baseQuery = $query;
|
|
$this->xAxisColumn = $xAxisColumn;
|
|
$this->yAxisColumn = $yAxisColumn;
|
|
$this->prepareQueries()->adjustSorting();
|
|
}
|
|
|
|
/**
|
|
* Prepare the queries used for the pre processing
|
|
*
|
|
* @return self
|
|
*/
|
|
protected function prepareQueries()
|
|
{
|
|
$this->xAxisQuery = clone $this->baseQuery;
|
|
$this->xAxisQuery->distinct();
|
|
$this->xAxisQuery->setColumns(array($this->xAxisColumn));
|
|
$this->yAxisQuery = clone $this->baseQuery;
|
|
$this->yAxisQuery->distinct();
|
|
$this->yAxisQuery->setColumns(array($this->yAxisColumn));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set a default sorting for the x- and y-axis without losing any existing rules
|
|
*
|
|
* @return self
|
|
*/
|
|
protected function adjustSorting()
|
|
{
|
|
$currentOrderColumns = $this->baseQuery->getOrderColumns();
|
|
$xAxisOrderColumns = array(array($this->baseQuery->getMappedField($this->xAxisColumn), BaseQuery::SORT_ASC));
|
|
$yAxisOrderColumns = array(array($this->baseQuery->getMappedField($this->yAxisColumn), BaseQuery::SORT_ASC));
|
|
|
|
foreach ($currentOrderColumns as $orderInfo) {
|
|
if ($orderInfo[0] === $xAxisOrderColumns[0][0]) {
|
|
$xAxisOrderColumns[0] = $orderInfo;
|
|
} elseif ($orderInfo[0] === $yAxisOrderColumns[0][0]) {
|
|
$yAxisOrderColumns[0] = $orderInfo;
|
|
} else {
|
|
$xAxisOrderColumns[] = $orderInfo;
|
|
$yAxisOrderColumns[] = $orderInfo;
|
|
}
|
|
}
|
|
|
|
$this->xAxisQuery->setOrderColumns($xAxisOrderColumns);
|
|
$this->yAxisQuery->setOrderColumns($yAxisOrderColumns);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
$request = Icinga::app()->getFrontController()->getRequest();
|
|
|
|
$value = $request->getParam($param, '');
|
|
if (strpos($value, ',') > 0) {
|
|
$parts = explode(',', $value, 2);
|
|
return intval($parts[$axis === 'x' ? 0 : 1]);
|
|
}
|
|
|
|
return $default !== null ? $default : 0;
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
if ($limit === null || $page === null) {
|
|
if ($limit === null) {
|
|
$limit = $this->getPaginationParameter('x', 'limit', 20);
|
|
}
|
|
|
|
if ($page === null) {
|
|
$page = $this->getPaginationParameter('x', 'page', 1);
|
|
}
|
|
}
|
|
|
|
$this->xAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
|
|
|
|
$paginator = new Zend_Paginator(new QueryAdapter($this->xAxisQuery));
|
|
$paginator->setItemCountPerPage($limit);
|
|
$paginator->setCurrentPageNumber($page);
|
|
return $paginator;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public function paginateYAxis($limit = null, $page = null)
|
|
{
|
|
if ($limit === null || $page === null) {
|
|
if ($limit === null) {
|
|
$limit = $this->getPaginationParameter('y', 'limit', 20);
|
|
}
|
|
|
|
if ($page === null) {
|
|
$page = $this->getPaginationParameter('y', 'page', 1);
|
|
}
|
|
}
|
|
|
|
$this->yAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
|
|
|
|
$paginator = new Zend_Paginator(new QueryAdapter($this->yAxisQuery));
|
|
$paginator->setItemCountPerPage($limit);
|
|
$paginator->setCurrentPageNumber($page);
|
|
return $paginator;
|
|
}
|
|
|
|
/**
|
|
* Return the pivot table as array
|
|
*
|
|
* @return array
|
|
*/
|
|
public function toArray()
|
|
{
|
|
$pivot = array();
|
|
$xAxis = $this->xAxisQuery->fetchColumn();
|
|
$yAxis = $this->yAxisQuery->fetchColumn();
|
|
|
|
if (!empty($xAxis) && !empty($yAxis)) {
|
|
$this->baseQuery->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
|
|
|
|
foreach ($yAxis as $yLabel) {
|
|
foreach ($xAxis as $xLabel) {
|
|
$pivot[$yLabel][$xLabel] = null;
|
|
}
|
|
}
|
|
|
|
foreach ($this->baseQuery->fetchAll() as $row) {
|
|
$pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
|
|
}
|
|
}
|
|
|
|
return $pivot;
|
|
}
|
|
}
|