diff --git a/Datatable/Options.php b/Datatable/Options.php index fd3b33ee..d528dc52 100644 --- a/Datatable/Options.php +++ b/Datatable/Options.php @@ -299,7 +299,7 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('global_search_type', 'string'); $resolver->setAllowedValues('individual_filtering_position', ['head', 'foot', 'both']); - $resolver->setAllowedValues('global_search_type', ['like', '%like', 'like%', 'notLike', 'eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in', 'notIn', 'isNull', 'isNotNull']); + $resolver->setAllowedValues('global_search_type', ['like', 'keywords_string', '%like', 'like%', 'notLike', 'eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in', 'notIn', 'isNull', 'isNotNull']); return $this; } diff --git a/Resources/doc/options.md b/Resources/doc/options.md index 8ff25e49..43d74a49 100644 --- a/Resources/doc/options.md +++ b/Resources/doc/options.md @@ -26,7 +26,7 @@ With 'null' initialized options uses the default value of the DataTables plugin. | individual_filtering | bool | false | Enable or disable individual filtering. | | individual_filtering_position | string | 'head' | Position of individual search filter ('head', 'foot' or 'both'). | | search_in_non_visible_columns | bool | false | Determines whether to search in non-visible columns. | -| global_search_type | string | 'like' | The global search type (example: 'eq'). | +| global_search_type | string | 'like' | The global search type (example: 'eq'). Use 'keywords_string' to search by multiple keywords. | ``` php class PostDatatable extends AbstractDatatable diff --git a/Response/DatatableQueryBuilder.php b/Response/DatatableQueryBuilder.php index ae714cb6..7c5d3f7d 100644 --- a/Response/DatatableQueryBuilder.php +++ b/Response/DatatableQueryBuilder.php @@ -500,29 +500,61 @@ private function setJoins(QueryBuilder $qb) */ private function setWhere(QueryBuilder $qb) { + // Retrieving parameter counter + $parameterCounter = self::INIT_PARAMETER_COUNTER; + // global filtering if (isset($this->requestParams['search']) && '' !== $this->requestParams['search']['value']) { - $orExpr = $qb->expr()->orX(); $globalSearch = $this->requestParams['search']['value']; $globalSearchType = $this->options->getGlobalSearchType(); - foreach ($this->columns as $key => $column) { - if (true === $this->isSearchableColumn($column)) { - /** @var AbstractFilter $filter */ - $filter = $this->accessor->getValue($column, 'filter'); - $searchType = $globalSearchType; - $searchFields = (array) $this->searchColumns[$key]; - $searchValue = $globalSearch; - $searchTypeOfField = $column->getTypeOfField(); - foreach ($searchFields as $searchField) { - $orExpr = $filter->addOrExpression($orExpr, $qb, $searchType, $searchField, $searchValue, $searchTypeOfField, $key); + // If global search type is a list of key words + if ($globalSearchType == 'keywords_string') { + + // Removing unnecessary spaces at the beginning and at the end + $globalSearch = trim($globalSearch); + + // Removing multiples spaces + $globalSearch = preg_replace('!\s+!', ' ', $globalSearch); + + // Parsing search value to array of keywords + $keywords = explode(' ', $globalSearch); + + // Setting type of search type to 'like' + $globalSearchType = 'like'; + + // Else considering only one searchstring + } else { + $keywords = [$globalSearch]; + } + + // Iterating through each keyword + foreach ($keywords as $k => $word) { + + // Initialising 'OR' expression + $orExpr = $qb->expr()->orX(); + + // Iterating through columns + foreach ($this->columns as $key => $column) { + + if (true === $this->isSearchableColumn($column)) { + /** @var AbstractFilter $filter */ + $filter = $this->accessor->getValue($column, 'filter'); + $searchType = $globalSearchType; + $searchFields = (array) $this->searchColumns[$key]; + $searchValue = $keywords[$k]; + $searchTypeOfField = $column->getTypeOfField(); + foreach ($searchFields as $searchField) { + $orExpr = $filter->addOrExpression($orExpr, $qb, $searchType, $searchField, $searchValue, $searchTypeOfField, $parameterCounter); + } } } - } - - if ($orExpr->count() > 0) { - $qb->andWhere($orExpr); + + // Adding 'OR' expression to global 'WHERE' + if ($orExpr->count() > 0) { + $qb->andWhere($orExpr); + } } } @@ -530,8 +562,6 @@ private function setWhere(QueryBuilder $qb) if (true === $this->accessor->getValue($this->options, 'individualFiltering')) { $andExpr = $qb->expr()->andX(); - $parameterCounter = self::INIT_PARAMETER_COUNTER; - foreach ($this->columns as $key => $column) { if (true === $this->isSearchableColumn($column)) { if (false === \array_key_exists($key, $this->requestParams['columns'])) {