sonata-project / SonataAdminBundle

The missing Symfony Admin Generator
https://docs.sonata-project.org/projects/SonataAdminBundle
MIT License
2.11k stars 1.26k forks source link

Global search adding the option to choose filters type (CONTAINS, STARTS_WITH, ENDS_WITH, NOT_CONTAINS, EQUAL, NOT_EQUAL) f #8067

Closed aleksanderkakol closed 11 months ago

aleksanderkakol commented 1 year ago

Is it possible to add the option to choose the filter type in the global search?

The current implementation sets the setValue in the datagrid to null, which results in the default usage of the StringFilter with the "Contains" filter

StringFilter.php

    public function filter(ProxyQueryInterface $query, string $alias, string $field, FilterData $data): void
    {
        if (!$data->hasValue()) {
            return;
        }

        $value = $this->trim((string) ($data->getValue() ?? ''));
+        $type = $data->getType() ?? StringOperatorType::TYPE_CONTAINS;

        $allowEmpty = $this->getOption('allow_empty', false);
        \assert(\is_bool($allowEmpty));

The type is hardcoded to null at all times:

SearchHandler.php

        foreach ($datagrid->getFilters() as $filter) {
            $formName = $filter->getFormName();

            if ($filter instanceof SearchableFilterInterface && $filter->isSearchEnabled()) {
                if (null !== $previousFilter) {
                    $filter->setPreviousFilter($previousFilter);
                }

                $filter->setCondition(FilterInterface::CONDITION_OR);
+                $datagrid->setValue($formName, null, $term);
                $found = true;

                $previousFilter = $filter;
            } elseif (isset($datagridValues[$formName])) {
                // Remove any previously set filter that is not configured for the global search.
                $datagrid->removeFilter($formName);
            }
        }
VincentLanglet commented 1 year ago

Is it possible to add the option to choose the filter type in the global search?

You're talking like all the filters are using the same filter type but it's not the case. What if the global search is using two stringFilter and one numberFilter.

Maybe something like https://github.com/sonata-project/SonataAdminBundle/blob/4.x/src/Search/SearchHandler.php#L60

$defaultSearchType = $filter instanceof SomeNewInterface ? $filter->getSearchType() : null
$datagrid->setValue($formName, $defaultSearchType, $term);

with

public function getSearchType(): int
    {
        return $this->getOption('global_search_type');
    }

and it will require to set

global_search => true,
global_search_type => ...::CONTAINS

Or maybe global_search could be a bool or a filter type

global_search => ...::CONTAINS
aleksanderkakol commented 1 year ago

What if the global search is using two stringFilter and one numberFilter.

The global search currently uses only filters with SearchableFilterInterface, which is currently implemented only for stringFilter. https://github.com/sonata-project/SonataAdminBundle/blob/4.x/src/Search/SearchHandler.php#L54

VincentLanglet commented 1 year ago

And the Uid filter too you mean https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/6f45c37d06c168827f1965cc00c3e8a0191f1fb5/src/Filter/UidFilter.php#L26 ?

And any custom filter every developer can implement on personal projects.

So my comment is still valid.

github-actions[bot] commented 11 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.