265 lines
8.7 KiB
PHP
265 lines
8.7 KiB
PHP
<?php
|
|
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
|
|
|
|
namespace Icinga\Web;
|
|
|
|
use Icinga\Data\Filterable;
|
|
use Icinga\Data\Sortable;
|
|
use Icinga\Data\QueryInterface;
|
|
use Icinga\Exception\Http\HttpBadRequestException;
|
|
use Icinga\Exception\Http\HttpNotFoundException;
|
|
use Icinga\Web\Controller\ModuleActionController;
|
|
use Icinga\Web\Widget\Limiter;
|
|
use Icinga\Web\Widget\Paginator;
|
|
use Icinga\Web\Widget\SortBox;
|
|
|
|
/**
|
|
* This is the controller all modules should inherit from
|
|
* We will flip code with the ModuleActionController as soon as a couple
|
|
* of pending feature branches are merged back to the master.
|
|
*
|
|
* @property View $view
|
|
*/
|
|
class Controller extends ModuleActionController
|
|
{
|
|
/**
|
|
* Cache for page size configured via user preferences
|
|
*
|
|
* @var false|int
|
|
*/
|
|
protected $userPageSize;
|
|
|
|
/**
|
|
* @see ActionController::init
|
|
*/
|
|
public function init()
|
|
{
|
|
parent::init();
|
|
$this->handleSortControlSubmit();
|
|
}
|
|
|
|
/**
|
|
* Check whether the sort control has been submitted and redirect using GET parameters
|
|
*/
|
|
protected function handleSortControlSubmit()
|
|
{
|
|
$request = $this->getRequest();
|
|
if (! $request->isPost()) {
|
|
return;
|
|
}
|
|
|
|
if (($sort = $request->getPost('sort')) || ($direction = $request->getPost('dir'))) {
|
|
$url = Url::fromRequest();
|
|
if ($sort) {
|
|
$url->setParam('sort', $sort);
|
|
$url->remove('dir');
|
|
} else {
|
|
$url->setParam('dir', $direction);
|
|
}
|
|
|
|
$this->redirectNow($url);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Immediately respond w/ HTTP 400
|
|
*
|
|
* @param string $message Exception message or exception format string
|
|
* @param mixed ...$arg Format string argument
|
|
*
|
|
* @throws HttpBadRequestException
|
|
*/
|
|
public function httpBadRequest($message)
|
|
{
|
|
throw HttpBadRequestException::create(func_get_args());
|
|
}
|
|
|
|
/**
|
|
* Immediately respond w/ HTTP 404
|
|
*
|
|
* @param string $message Exception message or exception format string
|
|
* @param mixed ...$arg Format string argument
|
|
*
|
|
* @throws HttpNotFoundException
|
|
*/
|
|
public function httpNotFound($message)
|
|
{
|
|
throw HttpNotFoundException::create(func_get_args());
|
|
}
|
|
|
|
/**
|
|
* Render the given form using a simple view script
|
|
*
|
|
* @param Form $form
|
|
* @param string $tab
|
|
*/
|
|
public function renderForm(Form $form, $tab)
|
|
{
|
|
$this->getTabs()->add(uniqid(), array(
|
|
'active' => true,
|
|
'label' => $tab,
|
|
'url' => Url::fromRequest()
|
|
));
|
|
$this->view->form = $form;
|
|
$this->render('simple-form', null, true);
|
|
}
|
|
|
|
/**
|
|
* Create a SortBox widget and apply its sort rules on the given query
|
|
*
|
|
* The widget is set on the `sortBox' view property only if the current view has not been requested as compact
|
|
*
|
|
* @param array $columns An array containing the sort columns, with the
|
|
* submit value as the key and the label as the value
|
|
* @param Sortable $query Query to apply the user chosen sort rules on
|
|
* @param array $defaults An array containing default sort directions for specific columns
|
|
*
|
|
* @return $this
|
|
*/
|
|
protected function setupSortControl(array $columns, Sortable $query = null, array $defaults = null)
|
|
{
|
|
$request = $this->getRequest();
|
|
$sortBox = SortBox::create('sortbox-' . $request->getActionName(), $columns, $defaults);
|
|
$sortBox->setRequest($request);
|
|
|
|
if ($query) {
|
|
$sortBox->setQuery($query);
|
|
$sortBox->handleRequest($request);
|
|
}
|
|
|
|
if (! $this->view->compact) {
|
|
$this->view->sortBox = $sortBox;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Create a Limiter widget at the `limiter' view property
|
|
*
|
|
* In case the current view has been requested as compact this method does nothing.
|
|
*
|
|
* @param int $itemsPerPage Default number of items per page
|
|
*
|
|
* @return $this
|
|
*/
|
|
protected function setupLimitControl($itemsPerPage = 25)
|
|
{
|
|
if (! $this->view->compact) {
|
|
$this->view->limiter = new Limiter();
|
|
$this->view->limiter->setDefaultLimit($this->getPageSize($itemsPerPage));
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get the page size configured via user preferences or return the default value
|
|
*
|
|
* @param ?int $default
|
|
*
|
|
* @return int
|
|
*/
|
|
protected function getPageSize($default)
|
|
{
|
|
if ($this->userPageSize === null) {
|
|
$user = $this->Auth()->getUser();
|
|
if ($user !== null) {
|
|
$pageSize = $user->getPreferences()->getValue('icingaweb', 'default_page_size');
|
|
$this->userPageSize = $pageSize ? (int) $pageSize : false;
|
|
} else {
|
|
$this->userPageSize = false;
|
|
}
|
|
}
|
|
|
|
return $this->userPageSize !== false ? $this->userPageSize : $default;
|
|
}
|
|
|
|
/**
|
|
* Apply the given page limit and number on the given query and setup a paginator for it
|
|
*
|
|
* The $itemsPerPage and $pageNumber parameters are only applied if not available in the current request.
|
|
* The paginator is set on the `paginator' view property only if the current view has not been requested as compact.
|
|
*
|
|
* @param QueryInterface $query The query to create a paginator for
|
|
* @param int $itemsPerPage Default number of items per page
|
|
* @param int $pageNumber Default page number
|
|
*
|
|
* @return $this
|
|
*/
|
|
protected function setupPaginationControl(QueryInterface $query, $itemsPerPage = 25, $pageNumber = 0)
|
|
{
|
|
$request = $this->getRequest();
|
|
$limit = $request->getParam('limit', $this->getPageSize($itemsPerPage));
|
|
$page = $request->getParam('page', $pageNumber);
|
|
$query->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
|
|
|
|
if (! $this->view->compact) {
|
|
$paginator = new Paginator();
|
|
$paginator->setQuery($query);
|
|
$this->view->paginator = $paginator;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Create a FilterEditor widget and apply the user's chosen filter options on the given filterable
|
|
*
|
|
* The widget is set on the `filterEditor' view property only if the current view has not been requested as compact.
|
|
* The optional $filterColumns parameter should be an array of key-value pairs where the key is the name of the
|
|
* column and the value the label to show to the user. The optional $searchColumns parameter should be an array
|
|
* of column names to be used to handle quick searches.
|
|
*
|
|
* If the given filterable is an instance of Icinga\Data\FilterColumns, $filterable->getFilterColumns() and
|
|
* $filterable->getSearchColumns() is called to provide the respective columns if $filterColumns or $searchColumns
|
|
* is not given.
|
|
*
|
|
* @param Filterable $filterable The filterable to create a filter editor for
|
|
* @param array $filterColumns The filter columns to offer to the user
|
|
* @param array $searchColumns The search columns to utilize for quick searches
|
|
* @param array $preserveParams The url parameters to preserve
|
|
*
|
|
* @return $this
|
|
*
|
|
* @todo Preserving and ignoring parameters should be configurable (another two method params? property magic?)
|
|
*/
|
|
protected function setupFilterControl(
|
|
Filterable $filterable,
|
|
array $filterColumns = null,
|
|
array $searchColumns = null,
|
|
array $preserveParams = null
|
|
) {
|
|
$defaultPreservedParams = array(
|
|
'limit', // setupPaginationControl()
|
|
'sort', // setupSortControl()
|
|
'dir', // setupSortControl()
|
|
'backend', // Framework
|
|
'showCompact', // Framework
|
|
'_dev' // Framework
|
|
);
|
|
|
|
$editor = Widget::create('filterEditor');
|
|
/** @var \Icinga\Web\Widget\FilterEditor $editor */
|
|
call_user_func_array(
|
|
array($editor, 'preserveParams'),
|
|
array_merge($defaultPreservedParams, $preserveParams ?: array())
|
|
);
|
|
|
|
$editor
|
|
->setQuery($filterable)
|
|
->ignoreParams('page') // setupPaginationControl()
|
|
->setColumns($filterColumns)
|
|
->setSearchColumns($searchColumns)
|
|
->handleRequest($this->getRequest());
|
|
|
|
if ($this->view->compact) {
|
|
$editor->setVisible(false);
|
|
}
|
|
|
|
$this->view->filterEditor = $editor;
|
|
|
|
return $this;
|
|
}
|
|
}
|