From 8ec8de499a60248ad5d769d8e055cfbd363976da Mon Sep 17 00:00:00 2001 From: ajcastro Date: Tue, 18 Jun 2019 15:22:41 +0800 Subject: [PATCH 1/2] Simplify and improve codebase --- src/BaseSearchQuery.php | 65 +++++++++++++++++++++++++++++++----- src/Search/SublimeSearch.php | 4 +++ src/Searchable.php | 43 +++++++++++++++--------- src/SortTrait.php | 65 ------------------------------------ 4 files changed, 87 insertions(+), 90 deletions(-) delete mode 100644 src/SortTrait.php diff --git a/src/BaseSearchQuery.php b/src/BaseSearchQuery.php index 9632e3a..e00867a 100644 --- a/src/BaseSearchQuery.php +++ b/src/BaseSearchQuery.php @@ -6,8 +6,6 @@ abstract class BaseSearchQuery extends BaseGridQuery { - use SortTrait; - /** * Search operator. * Whether to use where or having in query to compare columns against search string. @@ -26,14 +24,12 @@ abstract class BaseSearchQuery extends BaseGridQuery protected $searchStr; /** - * Prepare and return the searchable query. + * If searching will be sorted by sort_index. + * This is the relevance score of the search string. * - * @return \Illuminate\Database\Eloquent\Builder + * @var bool */ - protected function searchableQuery() - { - return $this->query(); - } + protected $sort = true; /** * Apply a search query. @@ -54,7 +50,7 @@ public function search($searchStr) public function searcher() { return new SublimeSearch( - $this->searchableQuery(), + $this->query(), $this->columns(), $this->sort, $this->searchOperator @@ -83,4 +79,55 @@ public function setSearchOperator($searchOperator) return $this; } + + /** + * Alias of sortByRelevance. + * + * @param bool $bool + * @return $this + */ + public function sort($sort = true) + { + return $this->sortByRelevance($sort); + } + + /** + * Set sort boolean. + * + * @param bool $bool + * @return $this + */ + public function sortByRelevance($sort = true) + { + $this->sort = $sort; + + return $this; + } + + /** + * Whether this search query should sort by relevance with key of `sort_index`. + * + * @return boolean + */ + public function shouldSortByRelevance() + { + return $this->sort; + } + + /** + * Apply sorting query by relevance to the search. + * By default using mysql locate function. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $searchStr + * @return \Illuminate\Database\Eloquent\Builder + */ + public function applySortByRelevance() + { + if (!method_exists($this, 'sortColumns')) { + throw new \Exception("Sort by relevance requires sortColumns() method."); + } + + SortByRelevance::sort($this->query, $this->sortColumns(), $this->searchStr); + } } diff --git a/src/Search/SublimeSearch.php b/src/Search/SublimeSearch.php index 4218775..3cd1571 100644 --- a/src/Search/SublimeSearch.php +++ b/src/Search/SublimeSearch.php @@ -104,6 +104,10 @@ public function search($searchStr) $method = $this->searchOperator.'Raw'; $query = $this->query()->{$method}('('.join(' OR ', $conditions).')'); + if ($this->shouldSortByRelevance()) { + $this->applySortByRelevance(); + } + return $query; } diff --git a/src/Searchable.php b/src/Searchable.php index cac35fa..55124f6 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -12,6 +12,8 @@ trait Searchable protected $sortByRelevance = true; + protected $searchQuery; + /** * Return the searchable columns for this model's table. * @@ -109,15 +111,29 @@ protected function applySearchableJoins($query) * * @return mixed|\AjCastro\Searchable\Search\SublimeSearch */ - public static function searchQuery() + public function searchQuery() { - $model = new static; + if ($this->searchQuery) { + return $this->searchQuery; + } - if (method_exists($model, 'defaultSearchQuery')) { - return $model->defaultSearchQuery(); + if (method_exists($this, 'defaultSearchQuery')) { + return $this->searchQuery = $this->defaultSearchQuery(); } - return new SublimeSearch($model, $model->searchableColumns(), true, 'where'); + return $this->searchQuery = new SublimeSearch($this, $this->searchableColumns(), $this->sortByRelevance, 'where'); + } + + /** + * Set the model's search query. + * + * @param \AjCastro\Searchable\BaseSearchQuery $searchQuery + */ + public function setSearchQuery($searchQuery) + { + $this->searchQuery = $searchQuery; + + return $this; } /** @@ -125,23 +141,16 @@ public static function searchQuery() * * @param query $query * @param string $search - * @param \AjCastro\Searchable\BaseSearchQuery $searchQuery * * @return void */ - public function scopeSearch($query, $search, $searchQuery = null) + public function scopeSearch($query, $search) { - if (is_null($searchQuery)) { - $this->applySearchableJoins($query); - } - - $searchQuery = $searchQuery ?: static::searchQuery(); + $this->applySearchableJoins($query); - $searchQuery->setQuery($query)->search($search)->select($this->getTable().'.*'); + $query->select($this->getTable().'.*'); - if ($query->getModel()->shouldSortByRelevance()) { - $searchQuery->applySortByRelevance(); - } + $this->searchQuery()->setQuery($query)->search($search); } /** @@ -165,6 +174,8 @@ public function searchableSortByRelevance($sortByRelevance = true) { $this->sortByRelevance = $sortByRelevance; + $this->searchQuery()->sortByRelevance($sortByRelevance); + return $this; } diff --git a/src/SortTrait.php b/src/SortTrait.php deleted file mode 100644 index 7b3b531..0000000 --- a/src/SortTrait.php +++ /dev/null @@ -1,65 +0,0 @@ -sort = $sort; - - return $this; - } - - /** - * Set sort boolean. - * - * @param bool $bool - * @return $this - */ - public function sortByRelevance($sort = true) - { - return $this->sort($sort); - } - - /** - * Whether this search query should sort by relevance with key of `sort_index`. - * - * @return boolean - */ - public function shouldSortByRelevance() - { - return $this->sort; - } - - /** - * Apply sorting query by relevance to the search. - * By default using mysql locate function. - * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param string $searchStr - * @return \Illuminate\Database\Eloquent\Builder - */ - public function applySortByRelevance() - { - if (!method_exists($this, 'sortColumns')) { - throw new \Exception("Using SortTrait requires sortColumns() method."); - } - - SortByRelevance::sort($this->query, $this->sortColumns(), $this->searchStr); - } -} From 690068ad8979e5cc4211c14243c6fa9549a7e8bb Mon Sep 17 00:00:00 2001 From: ajcastro Date: Thu, 20 Jun 2019 10:02:10 +0800 Subject: [PATCH 2/2] Add warning in readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 370d84c..74e46fb 100644 --- a/README.md +++ b/README.md @@ -361,6 +361,11 @@ Post::isColumnValid(request('sort_by')); Post::getTableColumns(); ``` +## Warning + +Calling `select()` after `search()` will overwrite `sort_index` field, so it is recommended to call `select()` +before `search()` which is also the normal case. + ## Credits - Ray Anthony Madrona [@raymadrona](https://github.com/raymadrona), for the tips on using MySQL `LOCATE()` for sort relevance.