# Sonata filter for ENUM field type

I'm using [fresh/DoctrineEnumBundle](https://github.com/fre5h/DoctrineEnumBundle/) for managing ENUM fields in database.

## Instructions

1. Create `AbstractBaseFilter.php`

    ```PHP
    <?php
    
    namespace AcmeBundle\Admin\Filter;
    
    use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
    use Sonata\DoctrineORMAdminBundle\Filter\Filter;
    use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList;
    
    /**
     * Base filter
     */
    abstract class AbstractBaseFilter extends Filter
    {
        /**
         * {@inheritdoc}
         */
        public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data)
        {
            if (!$data || !is_array($data) || !array_key_exists('type', $data) || !array_key_exists('value', $data)) {
                return;
            }
    
            if (in_array($data['value'], $this->getValues())) {
                $parameterName = $this->getNewParameterName($queryBuilder);
                $this->applyWhere($queryBuilder, sprintf('%s.%s = :%s', $alias, $field, $parameterName));
                $queryBuilder->setParameter($parameterName, $data['value']);
            } else {
                return;
            }
        }
    
        /**
         * {@inheritdoc}
         */
        public function getDefaultOptions()
        {
            return [];
        }
    
        /**
         * {@inheritdoc}
         */
        public function getFieldType()
        {
            return $this->getOption('field_type', 'choice');
        }
    
        /**
         * {@inheritdoc}
         */
        public function getFieldOptions()
        {
            return $this->getOption('choices', [
                'required'    => false,
                'choice_list' => new ChoiceList($this->getValues(), array_values($this->getChoices())),
            ]);
        }
    
        /**
         * {@inheritdoc}
         */
        public function getRenderSettings()
        {
            return [
                'sonata_type_filter_default', [
                    'operator_type' => 'sonata_type_equal',
                    'field_type'    => $this->getFieldType(),
                    'field_options' => $this->getFieldOptions(),
                    'label'         => $this->getLabel(),
                ],
            ];
        }
    
        /**
         * Get values
         *
         * @return array
         */
        abstract protected function getValues();
    
        /**
         * Get choices
         *
         * @return array
         */
        abstract protected function getChoices();
    }

    ```
2. [Create and register](https://github.com/fre5h/DoctrineEnumBundle/#using) custom ENUM type
3. Create custom filter

    ```PHP
    <?php
    
    namespace AcmeBundle\Admin\Filter;
    
    use AcmeBundle\DBAL\Types\MyEnumType;
    
    /**
     * MyEnumTypeFilter class
     */
    class MyEnumTypeFilter extends AbstractBaseFilter
    {
        /**
         * {@inheritdoc}
         */
        protected function getValues()
        {
            return MyEnumType::getValues();
        }
    
        /**
         * {@inheritdoc}
         */
        protected function getChoices()
        {
            return MyEnumType::getChoices();
        }
    }
    ```

4. Register filter as service

    ```YAML
    # AcmeBundle/Resources/config/admin.yml
    services:
        admin.filter.my_enum_type:
            class: AcmeBundle\Admin\Filter\MyEnumTypeFilter
            tags:
                - { name: sonata.admin.filter.type, alias: filter_my_enum_type }
    
    ```

5. Use filter in admin class

    ```PHP
    <?php
    
    namespace AcmeBundle\Admin;
    
    use Sonata\AdminBundle\Admin\Admin;
    use Sonata\AdminBundle\Datagrid\DatagridMapper;
    
    /**
     * My custom admin class
     */
    class MyCustomAdmin extends Admin
    {
        /**
         * {@inheritdoc}
         */
        protected function configureDatagridFilters(DatagridMapper $dataGridMapper)
        {
            $dataGridMapper
                ->add('id')
                ...
                ->add('status', 'filter_my_enum_type');
        }
        ...
    }
    
    ```

6. Enjoy filter for ENUM type :smile: