Skip to content

Instantly share code, notes, and snippets.

@LogansUA
Created December 18, 2015 16:03
Show Gist options
  • Save LogansUA/26ad7e097325231f278e to your computer and use it in GitHub Desktop.
Save LogansUA/26ad7e097325231f278e to your computer and use it in GitHub Desktop.
Sonata filter for ENUM field type

Sonata filter for ENUM field type

I'm using fresh/DoctrineEnumBundle for managing ENUM fields in database.

Instructions

  1. Create AbstractBaseFilter.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 custom ENUM type

  3. Create custom filter

    <?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

    # 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
    
    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 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment