Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Ability to use multiple keywords in global search #898

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Datatable/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion Resources/doc/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 47 additions & 17 deletions Response/DatatableQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,38 +500,68 @@ 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);
}
}
}

// individual filtering
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'])) {
Expand Down