From bdc6087164c3ea3884e19dc440ef8790cf7cb487 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Mon, 4 Jul 2022 15:46:17 +0600 Subject: [PATCH 01/13] #65: optimize search --- src/Traits/SearchTrait.php | 82 +++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 05d25104..b65ea6b9 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -23,6 +23,25 @@ trait SearchTrait protected $attachedRelations = []; protected $attachedRelationsCount = []; + protected $reservedFilters = [ + 'with', + 'with_count', + 'with_trashed', + 'query', + 'order_by', + 'all', + 'per_page', + 'page', + 'desc', + 'from', + 'to' + ]; + + protected $listPostfixs = [ + '_in_list', + '_not_in_list' + ]; + public function paginate(): LengthAwarePaginator { $defaultPerPage = config('defaults.items_per_page'); @@ -32,33 +51,6 @@ public function paginate(): LengthAwarePaginator return $this->query->paginate($perPage, ['*'], 'page', $page); } - /** - * @param $field string filtered field, you can pass field name with dots to filter by field of relation - * @param $filterName string|null key from filters which contains filter value - * - * @return self - */ - public function filterBy(string $field, ?string $filterName = null): self - { - if (empty($filterName)) { - if (Str::contains($field, '.')) { - list ($filterName) = extract_last_part($field); - } else { - $filterName = $field; - } - } - - if (Arr::has($this->filter, $filterName)) { - $values = Arr::wrap($this->filter[$filterName]); - - $this->applyWhereCallback($this->query, $field, function (&$query, $conditionField) use ($values) { - $query->whereIn($conditionField, $values); - }); - } - - return $this; - } - public function filterByQuery(array $fields): self { if (!empty($this->filter['query'])) { @@ -90,13 +82,47 @@ public function searchQuery(array $filter): self $this->withTrashed(); } - $this->query = $this->getQuery(); + $this->query = $this + ->with(Arr::get($filter, 'with', [])) + ->withCount(Arr::get($filter, 'with_count', [])) + ->getQuery(); $this->filter = $filter; + if (!empty($this->filter)) { + foreach ($this->filter as $field => $values) { + if (!in_array($field, $this->reservedFilters) && is_array($values) || !in_array($field, $this->reservedFilters) && is_string($values)) { + $notInList = strpos($field, $this->listPostfixs[1]); + + if ($notInList) { + $this->filter($this->listPostfixs[1], 'whereNotIn', $field, $values); + } else { + $this->filter($this->listPostfixs[0], 'whereIn', $field, $values); + } + } + } + } + return $this; } + protected function filter($postfix, $where, $field, $values) + { + $fieldWithoutPostfix = Str::replace($postfix, '', $field); + + if (!is_array($values) || !Arr::isAssoc($values)) { + $this->query->{$where}($fieldWithoutPostfix, Arr::wrap($values)); + } else { + foreach ($values as $relationFiled => $value) { + $fieldWithRelation = $fieldWithoutPostfix . '.' . $relationFiled; + } + + $this->applyWhereCallback($this->query, $fieldWithRelation, function (&$query, $conditionField) use ($value, $where) { + $query->{$where}($conditionField, Arr::wrap($value)); + }); + } + } + public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); From c53d6fb3d7e2a914cb96ce69bcc4edd67f44279d Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Mon, 4 Jul 2022 16:00:06 +0600 Subject: [PATCH 02/13] #65: optimize search --- src/Traits/SearchTrait.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index b65ea6b9..a2bdbcbf 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -82,11 +82,6 @@ public function searchQuery(array $filter): self $this->withTrashed(); } - $this->query = $this - ->with(Arr::get($filter, 'with', [])) - ->withCount(Arr::get($filter, 'with_count', [])) - ->getQuery(); - $this->filter = $filter; if (!empty($this->filter)) { From 22211aec3f26f42986879571e19f6b70185135c7 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Mon, 4 Jul 2022 16:00:55 +0600 Subject: [PATCH 03/13] #65: optimize search --- src/Traits/SearchTrait.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index a2bdbcbf..245ed642 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -82,6 +82,8 @@ public function searchQuery(array $filter): self $this->withTrashed(); } + $this->query = $this->getQuery(); + $this->filter = $filter; if (!empty($this->filter)) { From 8761d297d524fbf2a885ef4516aec3b1e1da4c5c Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Thu, 7 Jul 2022 16:19:42 +0600 Subject: [PATCH 04/13] #65: optimize search --- src/Traits/SearchTrait.php | 57 +++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 245ed642..30082e34 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -86,16 +86,21 @@ public function searchQuery(array $filter): self $this->filter = $filter; - if (!empty($this->filter)) { - foreach ($this->filter as $field => $values) { - if (!in_array($field, $this->reservedFilters) && is_array($values) || !in_array($field, $this->reservedFilters) && is_string($values)) { - $notInList = strpos($field, $this->listPostfixs[1]); - - if ($notInList) { - $this->filter($this->listPostfixs[1], 'whereNotIn', $field, $values); - } else { - $this->filter($this->listPostfixs[0], 'whereIn', $field, $values); - } + if (!empty($filter)) { + foreach($filter as $fieldName => $value) { + $isNotReservedFilter = (!in_array($fieldName, $this->reservedFilters) && (is_array($value) || is_string($value))); + if ($isNotReservedFilter || Str::endWith($fieldName, '_in_list')) { + $field = Str::replace($fieldName, '_in_list', ''); + $this->filterBy($field, $value); + } elseif (Str::endWith($fieldName, '_not_in_list')) { + $field = Str::replace($fieldName, '_not_in_list', ''); + $this->query->whereNotIn($field, $value); + } elseif (Str::endWith($fieldName, '_from')) { + $field = Str::replace($fieldName, '_from', ''); + $this->filterFrom($field, $value); + } elseif (Str::endWith($fieldName, '_to')) { + $field = Str::replace($fieldName, '_to', ''); + $this->filterTo($field, $value); } } } @@ -103,22 +108,22 @@ public function searchQuery(array $filter): self return $this; } - protected function filter($postfix, $where, $field, $values) - { - $fieldWithoutPostfix = Str::replace($postfix, '', $field); - - if (!is_array($values) || !Arr::isAssoc($values)) { - $this->query->{$where}($fieldWithoutPostfix, Arr::wrap($values)); - } else { - foreach ($values as $relationFiled => $value) { - $fieldWithRelation = $fieldWithoutPostfix . '.' . $relationFiled; - } - - $this->applyWhereCallback($this->query, $fieldWithRelation, function (&$query, $conditionField) use ($value, $where) { - $query->{$where}($conditionField, Arr::wrap($value)); - }); - } - } +// protected function filter($postfix, $where, $field, $values) +// { +// $fieldWithoutPostfix = Str::replace($postfix, '', $field); +// +// if (!is_array($values) || !Arr::isAssoc($values)) { +// $this->query->{$where}($fieldWithoutPostfix, Arr::wrap($values)); +// } else { +// foreach ($values as $relationFiled => $value) { +// $fieldWithRelation = $fieldWithoutPostfix . '.' . $relationFiled; +// } +// +// $this->applyWhereCallback($this->query, $fieldWithRelation, function (&$query, $conditionField) use ($value, $where) { +// $query->{$where}($conditionField, Arr::wrap($value)); +// }); +// } +// } public function getSearchResults(): LengthAwarePaginator { From d23f005c524de02af311ea1f68b823125745449e Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Fri, 8 Jul 2022 14:11:15 +0600 Subject: [PATCH 05/13] #65: optimize search --- src/Traits/SearchTrait.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 30082e34..d79779f9 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -108,23 +108,6 @@ public function searchQuery(array $filter): self return $this; } -// protected function filter($postfix, $where, $field, $values) -// { -// $fieldWithoutPostfix = Str::replace($postfix, '', $field); -// -// if (!is_array($values) || !Arr::isAssoc($values)) { -// $this->query->{$where}($fieldWithoutPostfix, Arr::wrap($values)); -// } else { -// foreach ($values as $relationFiled => $value) { -// $fieldWithRelation = $fieldWithoutPostfix . '.' . $relationFiled; -// } -// -// $this->applyWhereCallback($this->query, $fieldWithRelation, function (&$query, $conditionField) use ($value, $where) { -// $query->{$where}($conditionField, Arr::wrap($value)); -// }); -// } -// } - public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); From 75708f75730f291462f0b56d554aa902d295f78e Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Fri, 8 Jul 2022 14:16:24 +0600 Subject: [PATCH 06/13] #65: optimize search --- src/Traits/SearchTrait.php | 68 +++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index dd47d32b..d1534e62 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -32,14 +32,7 @@ trait SearchTrait 'all', 'per_page', 'page', - 'desc', - 'from', - 'to' - ]; - - protected $listPostfixs = [ - '_in_list', - '_not_in_list' + 'desc' ]; public function paginate(): LengthAwarePaginator @@ -51,6 +44,33 @@ public function paginate(): LengthAwarePaginator return $this->query->paginate($perPage, ['*'], 'page', $page); } + /** + * @param $field string filtered field, you can pass field name with dots to filter by field of relation + * @param $filterName string|null key from filters which contains filter value + * + * @return self + */ + public function filterBy(string $field, ?string $filterName = null): self + { + if (empty($filterName)) { + if (Str::contains($field, '.')) { + list ($filterName) = extract_last_part($field); + } else { + $filterName = $field; + } + } + + if (Arr::has($this->filter, $filterName)) { + $values = Arr::wrap($this->filter[$filterName]); + + $this->applyWhereCallback($this->query, $field, function (&$query, $conditionField) use ($values) { + $query->whereIn($conditionField, $values); + }); + } + + return $this; + } + public function filterByQuery(array $fields): self { if (!empty($this->filter['query'])) { @@ -91,19 +111,25 @@ public function searchQuery(array $filter): self if (!empty($filter)) { foreach($filter as $fieldName => $value) { - $isNotReservedFilter = (!in_array($fieldName, $this->reservedFilters) && (is_array($value) || is_string($value))); - if ($isNotReservedFilter || Str::endWith($fieldName, '_in_list')) { - $field = Str::replace($fieldName, '_in_list', ''); - $this->filterBy($field, $value); - } elseif (Str::endWith($fieldName, '_not_in_list')) { - $field = Str::replace($fieldName, '_not_in_list', ''); + $isNotReservedFilter = (!in_array($fieldName, $this->reservedFilters)); + + $isValidValue = (is_array($value) || is_string($value) || is_integer($value) || is_double($value) || is_bool($value)); + + if (Str::endsWith($fieldName, '_not_in_list') && $isValidValue) { + $field = Str::replace('_not_in_list', '', $fieldName); $this->query->whereNotIn($field, $value); - } elseif (Str::endWith($fieldName, '_from')) { - $field = Str::replace($fieldName, '_from', ''); - $this->filterFrom($field, $value); - } elseif (Str::endWith($fieldName, '_to')) { - $field = Str::replace($fieldName, '_to', ''); - $this->filterTo($field, $value); + } elseif (Str::endsWith($fieldName, '_from') && $isValidValue) { + $field = Str::replace('_from', '', $fieldName); + $this->filter[$field] = $value; + $this->filterFrom($field, true, $field); + } elseif (Str::endsWith($fieldName, '_to') && $isValidValue) { + $field = Str::replace('_to', '', $fieldName); + $this->filter[$field] = $value; + $this->filterTo($field, true, $field); + } elseif ($isNotReservedFilter || Str::endsWith($fieldName, '_in_list') && $isValidValue) { + $field = Str::replace('_in_list', '', $fieldName); + $this->filter[$field] = $value; + $this->filterBy($field); } } } @@ -111,6 +137,8 @@ public function searchQuery(array $filter): self return $this; } + + public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); From a63556af8b562662daed7a256efb9f23c638f398 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Fri, 8 Jul 2022 14:18:57 +0600 Subject: [PATCH 07/13] #65: optimize search --- src/Traits/SearchTrait.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index d1534e62..4c55f9e7 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -136,9 +136,7 @@ public function searchQuery(array $filter): self return $this; } - - - + public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); From a273890ce82dde61a158e5c36f36d226b19d3149 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Fri, 8 Jul 2022 20:41:49 +0600 Subject: [PATCH 08/13] #65: optimize search --- src/Traits/SearchTrait.php | 42 +++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 4c55f9e7..0c0d4fac 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -96,7 +96,7 @@ public function filterByQuery(array $fields): self return $this; } - public function searchQuery(array $filter): self + public function searchQuery(array $filter = []): self { if (!empty($filter['with_trashed'])) { $this->withTrashed(); @@ -109,28 +109,24 @@ public function searchQuery(array $filter): self $this->filter = $filter; - if (!empty($filter)) { - foreach($filter as $fieldName => $value) { - $isNotReservedFilter = (!in_array($fieldName, $this->reservedFilters)); - - $isValidValue = (is_array($value) || is_string($value) || is_integer($value) || is_double($value) || is_bool($value)); - - if (Str::endsWith($fieldName, '_not_in_list') && $isValidValue) { - $field = Str::replace('_not_in_list', '', $fieldName); - $this->query->whereNotIn($field, $value); - } elseif (Str::endsWith($fieldName, '_from') && $isValidValue) { - $field = Str::replace('_from', '', $fieldName); - $this->filter[$field] = $value; - $this->filterFrom($field, true, $field); - } elseif (Str::endsWith($fieldName, '_to') && $isValidValue) { - $field = Str::replace('_to', '', $fieldName); - $this->filter[$field] = $value; - $this->filterTo($field, true, $field); - } elseif ($isNotReservedFilter || Str::endsWith($fieldName, '_in_list') && $isValidValue) { - $field = Str::replace('_in_list', '', $fieldName); - $this->filter[$field] = $value; - $this->filterBy($field); - } + foreach($filter as $fieldName => $value) { + $isNotReservedFilter = (!in_array($fieldName, $this->reservedFilters)); + + if (Str::endsWith($fieldName, '_not_in_list')) { + $field = Str::replace('_not_in_list', '', $fieldName); + $this->query->whereNotIn($field, $value); + } elseif (Str::endsWith($fieldName, '_from')) { + $field = Str::replace('_from', '', $fieldName); + $this->filter[$field] = $value; + $this->filterFrom($field, true, $field); + } elseif (Str::endsWith($fieldName, '_to')) { + $field = Str::replace('_to', '', $fieldName); + $this->filter[$field] = $value; + $this->filterTo($field, true, $field); + } elseif ($isNotReservedFilter || Str::endsWith($fieldName, '_in_list')) { + $field = Str::replace('_in_list', '', $fieldName); + $this->filter[$field] = $value; + $this->filterBy($field); } } From dd18d5527f81d173fd1d86bb2b02821afb2cc5e5 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Mon, 11 Jul 2022 15:59:08 +0600 Subject: [PATCH 09/13] #65: optimize search --- src/Traits/SearchTrait.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 0c0d4fac..40edd0d0 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -117,15 +117,13 @@ public function searchQuery(array $filter = []): self $this->query->whereNotIn($field, $value); } elseif (Str::endsWith($fieldName, '_from')) { $field = Str::replace('_from', '', $fieldName); - $this->filter[$field] = $value; - $this->filterFrom($field, true, $field); + $this->filterFrom($field, false, $fieldName); } elseif (Str::endsWith($fieldName, '_to')) { $field = Str::replace('_to', '', $fieldName); $this->filter[$field] = $value; - $this->filterTo($field, true, $field); + $this->filterTo($field, false, $fieldName); } elseif ($isNotReservedFilter || Str::endsWith($fieldName, '_in_list')) { $field = Str::replace('_in_list', '', $fieldName); - $this->filter[$field] = $value; $this->filterBy($field); } } From 79c5857bf25b14bceaced326a79f485d3e01dc46 Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Mon, 11 Jul 2022 15:59:55 +0600 Subject: [PATCH 10/13] #65: optimize search --- src/Traits/SearchTrait.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 40edd0d0..50e5e1f2 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -120,7 +120,6 @@ public function searchQuery(array $filter = []): self $this->filterFrom($field, false, $fieldName); } elseif (Str::endsWith($fieldName, '_to')) { $field = Str::replace('_to', '', $fieldName); - $this->filter[$field] = $value; $this->filterTo($field, false, $fieldName); } elseif ($isNotReservedFilter || Str::endsWith($fieldName, '_in_list')) { $field = Str::replace('_in_list', '', $fieldName); From c51c757a7beb5023f45b5dc6385ab1eca533f013 Mon Sep 17 00:00:00 2001 From: roman <98943794+pirs1337@users.noreply.github.com> Date: Tue, 12 Jul 2022 11:45:24 +0600 Subject: [PATCH 11/13] #65: fix tab --- src/Traits/SearchTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 50e5e1f2..e6b3460d 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -129,7 +129,7 @@ public function searchQuery(array $filter = []): self return $this; } - + public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); @@ -142,7 +142,7 @@ public function getSearchResults(): LengthAwarePaginator return $this->wrapPaginatedData($data); } - + public function wrapPaginatedData(Collection $data): LengthAwarePaginator { $total = $data->count(); From 97763759fc8bcff925ac005cd35acf6a2b33f9ce Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Tue, 12 Jul 2022 11:46:21 +0600 Subject: [PATCH 12/13] #65: fix tab --- src/Traits/SearchTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index 50e5e1f2..a0c7bce5 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -129,7 +129,7 @@ public function searchQuery(array $filter = []): self return $this; } - + public function getSearchResults(): LengthAwarePaginator { $this->orderBy(); From 5ef5fab6200821a986d67941d7a456e85694c05e Mon Sep 17 00:00:00 2001 From: "roman2027@internet.ru" Date: Tue, 12 Jul 2022 11:47:09 +0600 Subject: [PATCH 13/13] #65: fix tab --- src/Traits/SearchTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/SearchTrait.php b/src/Traits/SearchTrait.php index e6b3460d..a0c7bce5 100644 --- a/src/Traits/SearchTrait.php +++ b/src/Traits/SearchTrait.php @@ -142,7 +142,7 @@ public function getSearchResults(): LengthAwarePaginator return $this->wrapPaginatedData($data); } - + public function wrapPaginatedData(Collection $data): LengthAwarePaginator { $total = $data->count();