mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-27 07:44:05 +02:00
SimpleQueryBasedTable: add new table type...
...and move logic common with ZfQueryBasedTable to a new base class
This commit is contained in:
parent
3b394900c9
commit
4680fa5447
202
library/vendor/ipl/Web/Table/QueryBasedTable.php
vendored
Normal file
202
library/vendor/ipl/Web/Table/QueryBasedTable.php
vendored
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ipl\Web\Table;
|
||||||
|
|
||||||
|
use Countable;
|
||||||
|
use Icinga\Application\Benchmark;
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use ipl\Data\Paginatable;
|
||||||
|
use ipl\Db\Zf1\FilterRenderer;
|
||||||
|
use ipl\Html\Table;
|
||||||
|
use ipl\Translation\TranslationHelper;
|
||||||
|
use ipl\Web\Widget\ControlsAndContent;
|
||||||
|
use ipl\Web\Widget\Paginator;
|
||||||
|
use ipl\Web\Table\Extension\QuickSearch;
|
||||||
|
use ipl\Web\Url;
|
||||||
|
|
||||||
|
abstract class QueryBasedTable extends Table implements Countable
|
||||||
|
{
|
||||||
|
use TranslationHelper;
|
||||||
|
use QuickSearch;
|
||||||
|
|
||||||
|
protected $defaultAttributes = [
|
||||||
|
'class' => ['common-table', 'table-row-selectable'],
|
||||||
|
'data-base-target' => '_next',
|
||||||
|
];
|
||||||
|
|
||||||
|
private $fetchedRows;
|
||||||
|
|
||||||
|
protected $lastDay;
|
||||||
|
|
||||||
|
private $isUsEnglish;
|
||||||
|
|
||||||
|
protected $searchColumns = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Paginatable
|
||||||
|
*/
|
||||||
|
abstract protected function getPaginationAdapter();
|
||||||
|
|
||||||
|
abstract public function getQuery();
|
||||||
|
|
||||||
|
public function getPaginator(Url $url)
|
||||||
|
{
|
||||||
|
return new Paginator(
|
||||||
|
$this->getPaginationAdapter(),
|
||||||
|
$url
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return $this->getPaginationAdapter()->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyFilter(Filter $filter)
|
||||||
|
{
|
||||||
|
FilterRenderer::applyToQuery($filter, $this->getQuery());
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSearchColumns()
|
||||||
|
{
|
||||||
|
return $this->searchColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function search($search)
|
||||||
|
{
|
||||||
|
if (! empty($search)) {
|
||||||
|
$query = $this->getQuery();
|
||||||
|
$columns = $this->getSearchColumns();
|
||||||
|
if (strpos($search, ' ') === false) {
|
||||||
|
$filter = Filter::matchAny();
|
||||||
|
foreach ($columns as $column) {
|
||||||
|
$filter->addFilter(Filter::expression($column, '=', "*$search*"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$filter = Filter::matchAll();
|
||||||
|
foreach (explode(' ', $search) as $s) {
|
||||||
|
$sub = Filter::matchAny();
|
||||||
|
foreach ($columns as $column) {
|
||||||
|
$sub->addFilter(Filter::expression($column, '=', "*$s*"));
|
||||||
|
}
|
||||||
|
$filter->addFilter($sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterRenderer::applyToQuery($filter, $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function prepareQuery();
|
||||||
|
|
||||||
|
public function renderContent()
|
||||||
|
{
|
||||||
|
if (count($this->getColumnsToBeRendered())) {
|
||||||
|
$this->generateHeader();
|
||||||
|
}
|
||||||
|
$this->fetchRows();
|
||||||
|
|
||||||
|
return parent::renderContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function splitByDay($timestamp)
|
||||||
|
{
|
||||||
|
$this->renderDayIfNew((int) $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fetchRows()
|
||||||
|
{
|
||||||
|
foreach ($this->fetch() as $row) {
|
||||||
|
// Hint: do not fetch the body first, the row might want to replace it
|
||||||
|
$tr = $this->renderRow($row);
|
||||||
|
$this->body()->add($tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function isUsEnglish()
|
||||||
|
{
|
||||||
|
if ($this->isUsEnglish === null) {
|
||||||
|
$this->isUsEnglish = in_array(setlocale(LC_ALL, 0), array('en_US.UTF-8', 'C'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->isUsEnglish;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $timestamp
|
||||||
|
*/
|
||||||
|
protected function renderDayIfNew($timestamp)
|
||||||
|
{
|
||||||
|
if ($this->isUsEnglish()) {
|
||||||
|
$day = date('l, jS F Y', $timestamp);
|
||||||
|
} else {
|
||||||
|
$day = strftime('%A, %e. %B, %Y', $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->lastDay !== $day) {
|
||||||
|
$this->nextHeader()->add(
|
||||||
|
$this::th($day, [
|
||||||
|
'colspan' => 2,
|
||||||
|
'class' => 'table-header-day'
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->lastDay = $day;
|
||||||
|
$this->nextBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function fetchQueryRows();
|
||||||
|
|
||||||
|
public function fetch()
|
||||||
|
{
|
||||||
|
$parts = explode('\\', get_class($this));
|
||||||
|
$name = end($parts);
|
||||||
|
Benchmark::measure("Fetching data for $name table");
|
||||||
|
$rows = $this->fetchQueryRows();
|
||||||
|
$this->fetchedRows = count($rows);
|
||||||
|
Benchmark::measure("Fetched $this->fetchedRows rows for $name table");
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function initializeOptionalQuickSearch(ControlsAndContent $controller)
|
||||||
|
{
|
||||||
|
$columns = $this->getSearchColumns();
|
||||||
|
if (! empty($columns)) {
|
||||||
|
$this->search(
|
||||||
|
$this->getQuickSearch(
|
||||||
|
$controller->controls(),
|
||||||
|
$controller->url()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ControlsAndContent $controller
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function renderTo(ControlsAndContent $controller)
|
||||||
|
{
|
||||||
|
$url = $controller->url();
|
||||||
|
$c = $controller->content();
|
||||||
|
$paginator = $this->getPaginator($url);
|
||||||
|
$this->initializeOptionalQuickSearch($controller);
|
||||||
|
$controller->actions()->add($paginator);
|
||||||
|
$c->add($this);
|
||||||
|
|
||||||
|
// TODO: move elsewhere
|
||||||
|
if (method_exists($this, 'dumpSqlQuery')) {
|
||||||
|
if ($url->getParam('format') === 'sql') {
|
||||||
|
$c->prepend($this->dumpSqlQuery($url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
34
library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php
vendored
Normal file
34
library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ipl\Web\Table;
|
||||||
|
|
||||||
|
use Icinga\Data\SimpleQuery;
|
||||||
|
use ipl\Data\SimpleQueryPaginationAdapter;
|
||||||
|
|
||||||
|
abstract class SimpleQueryBasedTable extends QueryBasedTable
|
||||||
|
{
|
||||||
|
/** @var SimpleQuery */
|
||||||
|
private $query;
|
||||||
|
|
||||||
|
protected function getPaginationAdapter()
|
||||||
|
{
|
||||||
|
return new SimpleQueryPaginationAdapter($this->getQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fetchQueryRows()
|
||||||
|
{
|
||||||
|
return $this->query->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SimpleQuery
|
||||||
|
*/
|
||||||
|
public function getQuery()
|
||||||
|
{
|
||||||
|
if ($this->query === null) {
|
||||||
|
$this->query = $this->prepareQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
}
|
150
library/vendor/ipl/Web/Table/ZfQueryBasedTable.php
vendored
150
library/vendor/ipl/Web/Table/ZfQueryBasedTable.php
vendored
@ -10,23 +10,11 @@ use ipl\Html\Container;
|
|||||||
use ipl\Html\DeferredText;
|
use ipl\Html\DeferredText;
|
||||||
use ipl\Html\Html;
|
use ipl\Html\Html;
|
||||||
use ipl\Html\Link;
|
use ipl\Html\Link;
|
||||||
use ipl\Html\Table;
|
|
||||||
use ipl\Translation\TranslationHelper;
|
|
||||||
use ipl\Web\Widget\ControlsAndContent;
|
use ipl\Web\Widget\ControlsAndContent;
|
||||||
use ipl\Web\Widget\Paginator;
|
|
||||||
use ipl\Web\Table\Extension\QuickSearch;
|
|
||||||
use ipl\Web\Url;
|
use ipl\Web\Url;
|
||||||
|
|
||||||
abstract class ZfQueryBasedTable extends Table
|
abstract class ZfQueryBasedTable extends QueryBasedTable
|
||||||
{
|
{
|
||||||
use TranslationHelper;
|
|
||||||
use QuickSearch;
|
|
||||||
|
|
||||||
protected $defaultAttributes = [
|
|
||||||
'class' => ['common-table', 'table-row-selectable'],
|
|
||||||
'data-base-target' => '_next',
|
|
||||||
];
|
|
||||||
|
|
||||||
/** @var DbConnection */
|
/** @var DbConnection */
|
||||||
private $connection;
|
private $connection;
|
||||||
|
|
||||||
@ -35,20 +23,18 @@ abstract class ZfQueryBasedTable extends Table
|
|||||||
|
|
||||||
private $query;
|
private $query;
|
||||||
|
|
||||||
private $fetchedRows;
|
|
||||||
|
|
||||||
protected $lastDay;
|
|
||||||
|
|
||||||
private $isUsEnglish;
|
|
||||||
|
|
||||||
protected $searchColumns = [];
|
|
||||||
|
|
||||||
public function __construct(DbConnection $connection)
|
public function __construct(DbConnection $connection)
|
||||||
{
|
{
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
$this->db = $connection->getDbAdapter();
|
$this->db = $connection->getDbAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function show(ControlsAndContent $controller, DbConnection $db)
|
||||||
|
{
|
||||||
|
$table = new static($db);
|
||||||
|
$table->renderTo($controller);
|
||||||
|
}
|
||||||
|
|
||||||
public function getCountQuery()
|
public function getCountQuery()
|
||||||
{
|
{
|
||||||
return $this->getPaginationAdapter()->getCountQuery();
|
return $this->getPaginationAdapter()->getCountQuery();
|
||||||
@ -59,25 +45,12 @@ abstract class ZfQueryBasedTable extends Table
|
|||||||
return new SelectPaginationAdapter($this->getQuery());
|
return new SelectPaginationAdapter($this->getQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPaginator(Url $url)
|
|
||||||
{
|
|
||||||
return new Paginator(
|
|
||||||
$this->getPaginationAdapter(),
|
|
||||||
$url
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function applyFilter(Filter $filter)
|
public function applyFilter(Filter $filter)
|
||||||
{
|
{
|
||||||
FilterRenderer::applyToQuery($filter, $this->getQuery());
|
FilterRenderer::applyToQuery($filter, $this->getQuery());
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getSearchColumns()
|
|
||||||
{
|
|
||||||
return $this->searchColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function search($search)
|
protected function search($search)
|
||||||
{
|
{
|
||||||
if (! empty($search)) {
|
if (! empty($search)) {
|
||||||
@ -105,75 +78,9 @@ abstract class ZfQueryBasedTable extends Table
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected function prepareQuery();
|
protected function fetchQueryRows()
|
||||||
|
|
||||||
public function renderContent()
|
|
||||||
{
|
{
|
||||||
if (count($this->getColumnsToBeRendered())) {
|
return $this->db->fetchAll($this->getQuery());
|
||||||
$this->generateHeader();
|
|
||||||
}
|
|
||||||
$this->fetchRows();
|
|
||||||
|
|
||||||
return parent::renderContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function splitByDay($timestamp)
|
|
||||||
{
|
|
||||||
$this->renderDayIfNew((int) $timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function fetchRows()
|
|
||||||
{
|
|
||||||
foreach ($this->fetch() as $row) {
|
|
||||||
// Hint: do not fetch the body first, the row might want to replace it
|
|
||||||
$tr = $this->renderRow($row);
|
|
||||||
$this->body()->add($tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function isUsEnglish()
|
|
||||||
{
|
|
||||||
if ($this->isUsEnglish === null) {
|
|
||||||
$this->isUsEnglish = in_array(setlocale(LC_ALL, 0), array('en_US.UTF-8', 'C'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->isUsEnglish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $timestamp
|
|
||||||
*/
|
|
||||||
protected function renderDayIfNew($timestamp)
|
|
||||||
{
|
|
||||||
if ($this->isUsEnglish()) {
|
|
||||||
$day = date('l, jS F Y', $timestamp);
|
|
||||||
} else {
|
|
||||||
$day = strftime('%A, %e. %B, %Y', $timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->lastDay !== $day) {
|
|
||||||
$this->nextHeader()->add(
|
|
||||||
$this::th($day, [
|
|
||||||
'colspan' => 2,
|
|
||||||
'class' => 'table-header-day'
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->lastDay = $day;
|
|
||||||
$this->nextBody();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function fetch()
|
|
||||||
{
|
|
||||||
$rows = $this->db->fetchAll(
|
|
||||||
$this->getQuery()
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->fetchedRows = count($rows);
|
|
||||||
|
|
||||||
return $rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function connection()
|
public function connection()
|
||||||
@ -217,43 +124,4 @@ abstract class ZfQueryBasedTable extends Table
|
|||||||
)),
|
)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function show(ControlsAndContent $controller, DbConnection $db)
|
|
||||||
{
|
|
||||||
$table = new static($db);
|
|
||||||
$table->renderTo($controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function initializeOptionalQuickSearch(ControlsAndContent $controller)
|
|
||||||
{
|
|
||||||
$columns = $this->getSearchColumns();
|
|
||||||
if (! empty($columns)) {
|
|
||||||
$this->search(
|
|
||||||
$this->getQuickSearch(
|
|
||||||
$controller->controls(),
|
|
||||||
$controller->url()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ControlsAndContent $controller
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function renderTo(ControlsAndContent $controller)
|
|
||||||
{
|
|
||||||
$url = $controller->url();
|
|
||||||
$c = $controller->content();
|
|
||||||
$paginator = $this->getPaginator($url);
|
|
||||||
$this->initializeOptionalQuickSearch($controller);
|
|
||||||
$controller->actions()->add($paginator);
|
|
||||||
$c->add($this);
|
|
||||||
|
|
||||||
if ($url->getParam('format') === 'sql') {
|
|
||||||
$c->prepend($this->dumpSqlQuery($url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user