oroinc / platform

Main OroPlatform package with core functionality.
Other
627 stars 351 forks source link

Datagrid Default filter not working with empty value #1042

Open sadortun opened 3 years ago

sadortun commented 3 years ago

Summary
Hi Guys,

We are using a default filter type on some fields in the contact-grid. https://github.com/oroinc/platform/blob/4.1/src/Oro/Bundle/FilterBundle/Resources/doc/reference/grid_extension.md#string-filter

datagrids:
  contacts-grid:
    filters:
      default:
        firstName: { value: '',  type: Oro\Bundle\FilterBundle\Form\Type\Filter\TextFilterType::TYPE_STARTS_WITH }
        lastName:  { value: '',  type: Oro\Bundle\FilterBundle\Form\Type\Filter\TextFilterType::TYPE_STARTS_WITH }
        email:     { value: '',  type: Oro\Bundle\FilterBundle\Form\Type\Filter\TextFilterType::TYPE_STARTS_WITH }

I am not sure when the issue started exactly, but it seems that contacts that have an empty value (first, last or email) are no longer displayed in the grid.

After some investigation, we found out that the SQL generated look like this

SELECT .... 
FROM orocrm_contact o0_
.....
WHERE
    o0_.first_name LIKE '%' AND o0_.last_name LIKE '%' 

After looking into StringFilter::parseValue()

            case TextFilterType::TYPE_STARTS_WITH:
                return sprintf('%s%%', $value);

The problem come from the fact that when parseData() is called $data['value'] = null;, and the filter explicitly look for a '' value.

I had a look at every filters that implement AbstractFilter::parseData() and all of them return false when !$data['value'] or empty($data['value']

The change originally made in da7d585bf1ad4e964f30c6730c17ea644620bdda was to avoid the case where the string '0' was provided, but ignored by the filter. Unfortunatly the change was not implemented correctly and should have been :

    protected function parseData($data)
    {
        $type = isset($data['type']) ? $data['type'] : null;
        if (!in_array($type, [FilterUtility::TYPE_EMPTY, FilterUtility::TYPE_NOT_EMPTY])
-            && (!is_array($data) || !array_key_exists('value', $data) || $data['value'] === '')
+            && (!is_array($data) || !array_key_exists('value', $data) || ($data['value'] !== '0' && empty($data['value'])))
        ) {
            return false;
        }

        $data['type'] = $type;
        $data['value'] = $this->parseValue($data['type'], $data['value']);

        return $data;
    }

Steps to reproduce

Actual Result

SELECT .... 
FROM orocrm_contact o0_
.....
WHERE
    o0_.first_name LIKE '%' AND o0_.last_name LIKE '%' 

Expected Result

SELECT .... 
FROM orocrm_contact o0_
.....
WHERE
....

Details about your environment