From 4680fa5447d659fb514140ebd0fc7a309d10bc3d Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Sat, 12 Aug 2017 12:02:36 +0200 Subject: [PATCH] SimpleQueryBasedTable: add new table type... ...and move logic common with ZfQueryBasedTable to a new base class --- .../vendor/ipl/Web/Table/QueryBasedTable.php | 202 ++++++++++++++++++ .../ipl/Web/Table/SimpleQueryBasedTable.php | 34 +++ .../ipl/Web/Table/ZfQueryBasedTable.php | 150 +------------ 3 files changed, 245 insertions(+), 141 deletions(-) create mode 100644 library/vendor/ipl/Web/Table/QueryBasedTable.php create mode 100644 library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php diff --git a/library/vendor/ipl/Web/Table/QueryBasedTable.php b/library/vendor/ipl/Web/Table/QueryBasedTable.php new file mode 100644 index 00000000..8f67905f --- /dev/null +++ b/library/vendor/ipl/Web/Table/QueryBasedTable.php @@ -0,0 +1,202 @@ + ['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; + } +} diff --git a/library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php b/library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php new file mode 100644 index 00000000..246233c0 --- /dev/null +++ b/library/vendor/ipl/Web/Table/SimpleQueryBasedTable.php @@ -0,0 +1,34 @@ +getQuery()); + } + + protected function fetchQueryRows() + { + return $this->query->fetchAll(); + } + + /** + * @return SimpleQuery + */ + public function getQuery() + { + if ($this->query === null) { + $this->query = $this->prepareQuery(); + } + + return $this->query; + } +} diff --git a/library/vendor/ipl/Web/Table/ZfQueryBasedTable.php b/library/vendor/ipl/Web/Table/ZfQueryBasedTable.php index 573a4def..5a1d5acc 100644 --- a/library/vendor/ipl/Web/Table/ZfQueryBasedTable.php +++ b/library/vendor/ipl/Web/Table/ZfQueryBasedTable.php @@ -10,23 +10,11 @@ use ipl\Html\Container; use ipl\Html\DeferredText; use ipl\Html\Html; use ipl\Html\Link; -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 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 */ private $connection; @@ -35,20 +23,18 @@ abstract class ZfQueryBasedTable extends Table private $query; - private $fetchedRows; - - protected $lastDay; - - private $isUsEnglish; - - protected $searchColumns = []; - public function __construct(DbConnection $connection) { $this->connection = $connection; $this->db = $connection->getDbAdapter(); } + public static function show(ControlsAndContent $controller, DbConnection $db) + { + $table = new static($db); + $table->renderTo($controller); + } + public function getCountQuery() { return $this->getPaginationAdapter()->getCountQuery(); @@ -59,25 +45,12 @@ abstract class ZfQueryBasedTable extends Table return new SelectPaginationAdapter($this->getQuery()); } - public function getPaginator(Url $url) - { - return new Paginator( - $this->getPaginationAdapter(), - $url - ); - } - 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)) { @@ -105,75 +78,9 @@ abstract class ZfQueryBasedTable extends Table return $this; } - abstract protected function prepareQuery(); - - public function renderContent() + protected function fetchQueryRows() { - 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(); - } - } - - public function fetch() - { - $rows = $this->db->fetchAll( - $this->getQuery() - ); - - $this->fetchedRows = count($rows); - - return $rows; + return $this->db->fetchAll($this->getQuery()); } 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; - } }