baseQuery = $query; $this->xAxisColumn = $xAxisColumn; $this->yAxisColumn = $yAxisColumn; } /** * {@inheritdoc} */ public function getOrder() { return $this->order; } /** * {@inheritdoc} */ public function hasOrder() { return ! empty($this->order); } /** * {@inheritdoc} */ public function order($field, $direction = null) { $this->order[$field] = $direction; return $this; } /** * Set the filter to apply on the query for the x-axis * * @param Filter $filter * * @return $this */ public function setXAxisFilter(Filter $filter = null) { $this->xAxisFilter = $filter; return $this; } /** * Set the filter to apply on the query for the y-axis * * @param Filter $filter * * @return $this */ public function setYAxisFilter(Filter $filter = null) { $this->yAxisFilter = $filter; return $this; } /** * Get the x-axis header * * Defaults to {@link $xAxisColumn} in case no x-axis header has been set using {@link setXAxisHeader()} * * @return string */ public function getXAxisHeader() { return $this->xAxisHeader !== null ? $this->xAxisHeader : $this->xAxisColumn; } /** * Set the x-axis header * * @param string $xAxisHeader * * @return $this */ public function setXAxisHeader($xAxisHeader) { $this->xAxisHeader = (string) $xAxisHeader; return $this; } /** * Get the y-axis header * * Defaults to {@link $yAxisColumn} in case no x-axis header has been set using {@link setYAxisHeader()} * * @return string */ public function getYAxisHeader() { return $this->yAxisHeader !== null ? $this->yAxisHeader : $this->yAxisColumn; } /** * Set the y-axis header * * @param string $yAxisHeader * * @return $this */ public function setYAxisHeader($yAxisHeader) { $this->yAxisHeader = (string) $yAxisHeader; 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()->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; } /** * Query horizontal (x) axis * * @return SimpleQuery */ protected function queryXAxis() { if ($this->xAxisQuery === null) { $this->xAxisQuery = clone $this->baseQuery; $this->xAxisQuery->clearGroupingRules(); $xAxisHeader = $this->getXAxisHeader(); $columns = array($this->xAxisColumn, $xAxisHeader); $this->xAxisQuery->group(array_unique($columns)); // xAxisColumn and header may be the same column $this->xAxisQuery->columns($columns); if ($this->xAxisFilter !== null) { $this->xAxisQuery->addFilter($this->xAxisFilter); } $this->xAxisQuery->order( $xAxisHeader, isset($this->order[$xAxisHeader]) ? $this->order[$xAxisHeader] : self::SORT_ASC ); } return $this->xAxisQuery; } /** * Query vertical (y) axis * * @return SimpleQuery */ protected function queryYAxis() { if ($this->yAxisQuery === null) { $this->yAxisQuery = clone $this->baseQuery; $this->yAxisQuery->clearGroupingRules(); $yAxisHeader = $this->getYAxisHeader(); $columns = array($this->yAxisColumn, $yAxisHeader); $this->yAxisQuery->group(array_unique($columns)); // yAxisColumn and header may be the same column $this->yAxisQuery->columns($columns); if ($this->yAxisFilter !== null) { $this->yAxisQuery->addFilter($this->yAxisFilter); } $this->yAxisQuery->order( $yAxisHeader, isset($this->order[$yAxisHeader]) ? $this->order[$yAxisHeader] : self::SORT_ASC ); } return $this->yAxisQuery; } /** * 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); } } $query = $this->queryXAxis(); $query->limit($limit, $page > 0 ? ($page - 1) * $limit : 0); $paginator = new Zend_Paginator(new QueryAdapter($query)); $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); } } $query = $this->queryYAxis(); $query->limit($limit, $page > 0 ? ($page - 1) * $limit : 0); $paginator = new Zend_Paginator(new QueryAdapter($query)); $paginator->setItemCountPerPage($limit); $paginator->setCurrentPageNumber($page); return $paginator; } /** * Return the pivot table as an array of pivot data and pivot header * * @return array */ public function toArray() { if ( ($this->xAxisFilter === null && $this->yAxisFilter === null) || ($this->xAxisFilter !== null && $this->yAxisFilter !== null) ) { $xAxis = $this->queryXAxis()->fetchPairs(); $yAxis = $this->queryYAxis()->fetchPairs(); $xAxisKeys = array_keys($xAxis); $yAxisKeys = array_keys($yAxis); } else { if ($this->xAxisFilter !== null) { $xAxis = $this->queryXAxis()->fetchPairs(); $xAxisKeys = array_keys($xAxis); $yAxis = $this->queryYAxis()->where($this->xAxisColumn, $xAxisKeys)->fetchPairs(); $yAxisKeys = array_keys($yAxis); } else { // $this->yAxisFilter !== null $yAxis = $this->queryYAxis()->fetchPairs(); $yAxisKeys = array_keys($yAxis); $xAxis = $this->queryXAxis()->where($this->yAxisColumn, $yAxisKeys)->fetchPairs(); $xAxisKeys = array_keys($xAxis); } } $pivotData = array(); $pivotHeader = array( 'cols' => $xAxis, 'rows' => $yAxis ); if (! empty($xAxis) && ! empty($yAxis)) { $this->baseQuery ->where($this->xAxisColumn, array_map( function($key) { return (string) $key; }, $xAxisKeys )) ->where($this->yAxisColumn, array_map( function($key) { return (string) $key; }, $yAxisKeys )); foreach ($yAxisKeys as $yAxisKey) { foreach ($xAxisKeys as $xAxisKey) { $pivotData[$yAxisKey][$xAxisKey] = null; } } foreach ($this->baseQuery as $row) { $pivotData[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row; } } return array($pivotData, $pivotHeader); } }