From 3d20f2a304822472ee344345d519abafdd0ff561 Mon Sep 17 00:00:00 2001 From: iYogesharma <44565761+iYogesharma@users.noreply.github.com> Date: Fri, 10 Jun 2022 13:36:37 +0530 Subject: [PATCH] Support For Having Clause In Query Added support for having clause in case of raw queries in select statement System is throwing error in search query if query builder contains Raw columns (columns that are instance of Illuminate\Database\Query\Expression class) This commit will fix this issue in search query by introducing having clause in case of raw/expression columns --- src/AbstractDatatable.php | 93 ++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/src/AbstractDatatable.php b/src/AbstractDatatable.php index 86bf1bf..c2c1a33 100755 --- a/src/AbstractDatatable.php +++ b/src/AbstractDatatable.php @@ -20,6 +20,13 @@ abstract class AbstractDatatable implements DatatableDriverInterface */ protected $whereColumns = []; + /** + * Columns for having conditions + * + * @var array + */ + protected $havingColumns = []; + /** * Searchable Columns for where conditions * @@ -188,21 +195,30 @@ protected function setColumns() protected function setWhereColumns() { foreach ($this->query->columns as $c) { - if (!strpos($c, '_id')) { + if(gettype($c) === 'object'){ + $c = $c->getValue(); + if (strpos($c, ' as ')) { + $column = explode(' as ', $c); + if (in_array(trim($column[1]), $this->searchColumns, true)) { + $this->havingColumns[] = trim($column[1]); + } + } + } + else if (!strpos($c, '_id')) { if (strpos($c, ' as ')) { $column = explode(' as ', $c); if (in_array(trim($column[1]), $this->searchColumns, true)) { - $this->whereColumns[] = $column[0]; + $this->whereColumns[] = trim($column[0]); } } else { if (isset(explode('.', $c)[1])) { if (in_array(explode('.', $c)[1], $this->searchColumns, true)) { - $this->whereColumns[] = $c; + $this->whereColumns[] = trim($c); } } else { - $this->whereColumns[] = $c; + $this->whereColumns[] = trim($c); } } } @@ -251,9 +267,9 @@ protected function checkIfQueryIsForSearchingPurpose() */ protected function setTotalDataAndFiltered() { - if( ! $this->totalData ) - { - // to get correct result count in case of group by + if( ! $this->totalData ) + { + // to get correct result count in case of group by if( $this->query->groups ) { $this->totalData = $this->query->getCountForPagination(); @@ -264,11 +280,22 @@ protected function setTotalDataAndFiltered() } $this->totalFiltered = $this->totalData; - } - else - { - $this->totalFiltered = $this->query->count(); - } + } + else + { + + $this->totalFiltered = $this->query->count(); + if( !$this->totalFiltered ) + { + if (!empty($this->havingColumns)) + { + $this->query->bindings['where'] = []; + $this->query->wheres = []; + $this->havingCondition($this->request->getSearchString(), $this->havingColumns); + $this->totalFiltered = $this->query->count(); + } + } + } } /** @@ -318,7 +345,6 @@ protected function searchQuery() if (!empty($this->whereColumns)) { $this->query = $this->condition($this->request->getSearchString(), $this->whereColumns); } - } /** @@ -328,27 +354,55 @@ protected function searchQuery() * * @return mixed */ - protected function condition($search, $columns) + protected function condition($search, $columns, $type = 'Where') { return $this->query->where(function ($q) use ($search, $columns) { $q->where($columns[0], 'LIKE', "%{$search}%"); - return $this->nestedWheres($q); + return $this->nestedWheres($q,$search); }); } + /** + * Apply having clause on query + * @param string $search + * @param array $columns + * + * @return mixed + */ + protected function havingCondition($search, $columns ) + { + $this->query->havingRaw("{$columns[0]} LIKE '%{$search}%'"); + return $this->nestedHaving($search); + } + /** * Return all where conditions to be nested * * @param mixed $q + * @param string $search search string * * @return \Illuminate\Database\Eloquent\Builder instance */ - protected function nestedWheres($q) + protected function nestedWheres($q,$search) { for ($i = 1; $i < count($this->whereColumns); $i++) { - $q->orWhere($this->whereColumns[$i], 'LIKE', "%{$this->request->getSearchString()}%"); + $q->orWhere($this->whereColumns[$i], 'LIKE', "%{$search}%"); + } + return $q; + } + + /** + * Return all having clauses to be nested + * + * @param string $type search string + * + * @return \Illuminate\Database\Eloquent\Builder instance + */ + protected function nestedHaving($search) + { + for ($i = 1; $i < count($this->havingColumns); $i++) { + $this->query->orHavingRaw("{$this->havingColumns[$i]} LIKE '%{$search}%'"); } - return $q; } /** @@ -385,7 +439,6 @@ public function response() public function jsonResponse() { return json_encode($this->response()); - } /** @@ -453,7 +506,6 @@ public function addColumns(array $column) foreach ($this->result as $r) { $r->$c = $cols->call($this, $r); } - } return $this; } @@ -488,3 +540,4 @@ public function getQuery() return $this->query; } } +