瀏覽代碼

Refactor filter to use the Form Framework

Thomas Rabaix 14 年之前
父節點
當前提交
ae3cdfdcf8

+ 15 - 5
Admin/Admin.php

@@ -338,7 +338,9 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
         'side_menu'     => false,
     );
 
-    protected $formTheme = array('SonataAdminBundle:Form:admin_fields.html.twig');
+    protected $formTheme = array('SonataAdminBundle:Form:form_admin_fields.html.twig');
+
+    protected $filterTheme = array('SonataAdminBundle:Form:filter_admin_fields.html.twig');
 
     /**
      * This method can be overwritten to tweak the form construction, by default the form
@@ -552,7 +554,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
             $parameters = array_merge(
                 $this->getModelManager()->getDefaultSortValues($this->getClass()),
                 $this->datagridValues,
-                $this->request->query->all()
+                $this->request->query->get('filter', array())
             );
 
             // always force the parent value
@@ -575,10 +577,8 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
             return;
         }
 
-        $parameters = $this->getFilterParameters();
-
         // initialize the datagrid
-        $this->datagrid = $this->getDatagridBuilder()->getBaseDatagrid($this, $parameters);
+        $this->datagrid = $this->getDatagridBuilder()->getBaseDatagrid($this, $this->getFilterParameters());
 
         $this->datagrid->getPager()->setMaxPerPage($this->maxPerPage);
 
@@ -2027,4 +2027,14 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     {
         return $this->formTheme;
     }
+
+    public function setFilterTheme($filterTheme)
+    {
+        $this->filterTheme = $filterTheme;
+    }
+
+    public function getFilterTheme()
+    {
+        return $this->filterTheme;
+    }
 }

+ 10 - 18
Builder/ORM/DatagridBuilder.php

@@ -21,6 +21,7 @@ use Sonata\AdminBundle\Datagrid\ORM\ProxyQuery;
 use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
 use Sonata\AdminBundle\Guesser\TypeGuesserInterface;
 use Sonata\AdminBundle\Filter\FilterFactoryInterface;
+use Symfony\Component\Form\FormFactory;
 
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
 
@@ -28,16 +29,20 @@ class DatagridBuilder implements DatagridBuilderInterface
 {
     protected $filterFactory;
 
+    protected $formFactory;
+
     protected $guesser;
 
     /**
+     * @param \Symfony\Component\Form\FormFactory $formFactory
      * @param \Sonata\AdminBundle\Filter\FilterFactoryInterface $filterFactory
      * @param \Sonata\AdminBundle\Guesser\TypeGuesserInterface $guesser
      */
-    public function __construct(FilterFactoryInterface $filterFactory, TypeGuesserInterface $guesser)
+    public function __construct(FormFactory $formFactory, FilterFactoryInterface $filterFactory, TypeGuesserInterface $guesser)
     {
+        $this->formFactory   = $formFactory;
         $this->filterFactory = $filterFactory;
-        $this->guesser = $guesser;
+        $this->guesser       = $guesser;
     }
 
     /**
@@ -66,22 +71,7 @@ class DatagridBuilder implements DatagridBuilderInterface
 
         $fieldDescription->setOption('code', $fieldDescription->getOption('code', $fieldDescription->getName()));
         $fieldDescription->setOption('label', $fieldDescription->getOption('label', $fieldDescription->getName()));
-        $fieldDescription->setOption('filter_value', $fieldDescription->getOption('filter_value', null));
-        $fieldDescription->setOption('filter_options', $fieldDescription->getOption('filter_options', null));
-        $fieldDescription->setOption('filter_field_options', $fieldDescription->getOption('filter_field_options', null));
         $fieldDescription->setOption('name', $fieldDescription->getOption('name', $fieldDescription->getName()));
-
-        if (!$fieldDescription->getTemplate()) {
-            $fieldDescription->setTemplate(sprintf('SonataAdminBundle:CRUD:filter_%s.html.twig', $fieldDescription->getType()));
-
-            if ($fieldDescription->getMappingType() == ClassMetadataInfo::MANY_TO_ONE) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:filter_many_to_one.html.twig');
-            }
-
-            if ($fieldDescription->getMappingType() == ClassMetadataInfo::MANY_TO_MANY) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:filter_many_to_many.html.twig');
-            }
-        }
     }
 
     /**
@@ -128,6 +118,8 @@ class DatagridBuilder implements DatagridBuilderInterface
         $pager = new Pager;
         $pager->setCountColumn($admin->getModelManager()->getIdentifierFieldNames($admin->getClass()));
 
-        return new Datagrid($query, $admin->getList(), $pager, $values);
+        $formBuilder = $this->formFactory->createNamedBuilder('form', 'filter');
+
+        return new Datagrid($query, $admin->getList(), $pager, $formBuilder, $values);
     }
 }

+ 9 - 1
Controller/CRUDController.php

@@ -139,8 +139,16 @@ class CRUDController extends Controller
             throw new AccessDeniedException();
         }
 
+        $datagrid = $this->admin->getDatagrid();
+        $formView = $datagrid->getForm()->createView();
+
+        // set the theme for the current Admin Form
+        $this->get('twig')->getExtension('form')->setTheme($formView, $this->admin->getFilterTheme());
+
         return $this->render($this->admin->getListTemplate(), array(
-            'action'            => 'list',
+            'action'   => 'list',
+            'form'     => $formView,
+            'datagrid' => $this->admin->getDatagrid()
         ));
     }
 

+ 51 - 6
Datagrid/Datagrid.php

@@ -16,7 +16,7 @@ use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
 use Sonata\AdminBundle\Filter\FilterInterface;
 use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
 
-use Symfony\Component\Form\FormFactory;
+use Symfony\Component\Form\FormBuilder;
 
 class Datagrid implements DatagridInterface
 {
@@ -37,16 +37,26 @@ class Datagrid implements DatagridInterface
 
     protected $query;
 
-    protected $formFactory;
+    protected $formBuilder;
+
+    protected $form;
 
     protected $results;
 
-    public function __construct(ProxyQueryInterface $query, FieldDescriptionCollection $columns, PagerInterface $pager, array $values = array())
+    /**
+     * @param ProxyQueryInterface $query
+     * @param \Sonata\AdminBundle\Admin\FieldDescriptionCollection $columns
+     * @param PagerInterface $pager
+     * @param \Symfony\Component\Form\FormBuilder $formBuilder
+     * @param array $values
+     */
+    public function __construct(ProxyQueryInterface $query, FieldDescriptionCollection $columns, PagerInterface $pager, FormBuilder $formBuilder, array $values = array())
     {
         $this->pager    = $pager;
         $this->query    = $query;
         $this->values   = $values;
         $this->columns  = $columns;
+        $this->formBuilder = $formBuilder;
     }
 
     /**
@@ -57,6 +67,9 @@ class Datagrid implements DatagridInterface
         return $this->pager;
     }
 
+    /**
+     * @return array
+     */
     public function getResults()
     {
         $this->buildPager();
@@ -68,6 +81,9 @@ class Datagrid implements DatagridInterface
         return $this->results;
     }
 
+    /**
+     * @return void
+     */
     public function buildPager()
     {
         if ($this->bound) {
@@ -75,12 +91,19 @@ class Datagrid implements DatagridInterface
         }
 
         foreach ($this->getFilters() as $name => $filter) {
-            $value = isset($this->values[$name]) ? $this->values[$name] : null;
+            $this->formBuilder->add($name, $filter->getFieldType(), $filter->getFieldOptions());
 
-            $filter->getField()->bind($value);
-            $filter->apply($this->query, $value);
+            $this->values[$name] = isset($this->values[$name]) ? $this->values[$name] : null;
+            $filter->apply($this->query, $this->values[$name]);
         }
 
+        $this->formBuilder->add('_sort_by', 'hidden');
+        $this->formBuilder->add('_sort_order', 'hidden');
+        $this->formBuilder->add('_page', 'hidden');
+
+        $this->form = $this->formBuilder->getForm();
+        $this->form->bind($this->values);
+
         $this->query->setSortBy(isset($this->values['_sort_by']) ? $this->values['_sort_by'] : null);
         $this->query->setSortOrder(isset($this->values['_sort_order']) ? $this->values['_sort_order'] : null);
 
@@ -100,23 +123,45 @@ class Datagrid implements DatagridInterface
         $this->filters[$filter->getName()] = $filter;
     }
 
+    /**
+     * @return array
+     */
     public function getFilters()
     {
         return $this->filters;
     }
 
+    /**
+     * @return array
+     */
     public function getValues()
     {
         return $this->values;
     }
 
+    /**
+     * @return \Sonata\AdminBundle\Admin\FieldDescriptionCollection
+     */
     public function getColumns()
     {
         return $this->columns;
     }
 
+    /**
+     * @return ProxyQueryInterface
+     */
     public function getQuery()
     {
         return $this->query;
     }
+
+    /**
+     * @return \Symfony\Component\Form\Form
+     */
+    public function getForm()
+    {
+        $this->buildPager();
+
+        return $this->form;
+    }
 }

+ 1 - 23
Filter/Filter.php

@@ -22,8 +22,6 @@ abstract class Filter implements FilterInterface
 
     protected $name = null;
 
-    protected $field = null;
-
     protected $value = null;
 
     protected $options = array();
@@ -32,7 +30,7 @@ abstract class Filter implements FilterInterface
     {
         $this->name               = $fieldDescription->getName();
         $this->fieldDescription   = $fieldDescription;
-        $this->options            = $fieldDescription->getOptions();
+        $this->options            = array_merge($this->getDefaultOptions(), $fieldDescription->getOptions());
     }
 
     public function initialize(array $options = array())
@@ -45,15 +43,6 @@ abstract class Filter implements FilterInterface
         return $this->name;
     }
 
-    public function getField()
-    {
-        if (!$this->field) {
-            throw new \RuntimeException(sprintf('No field instance attached for the filter `%s`', $this->name));
-        }
-
-        return $this->field;
-    }
-
     /**
      * @return \Sonata\AdminBundle\Admin\FieldDescriptionInterface
      */
@@ -76,17 +65,6 @@ abstract class Filter implements FilterInterface
         return $default;
     }
 
-    /**
-     * @param \Symfony\Component\Form\FormFactory $formFactory
-     * @return void
-     */
-    public function defineFieldBuilder(FormFactory $formFactory)
-    {
-        $builder = $formFactory->createNamedBuilder($this->getFieldType(), $this->getName(), null, $this->getFieldOptions());
-
-        $this->field = $builder->getForm();
-    }
-
     /**
      * @return string
      */

+ 0 - 15
Filter/FilterFactory.php

@@ -54,20 +54,6 @@ class FilterFactory implements FilterFactoryInterface
 //
 //                break;
 //
-//            case ClassMetadataInfo::MANY_TO_MANY:
-//                $options = $fieldDescription->getOption('filter_field_options');
-//                $options['choices'] = $this->getChoices($fieldDescription);
-//
-//
-//                $fieldDescription->setOption('filter_field_options', $options);
-//
-//                $filter = new \Sonata\AdminBundle\Filter\ORM\ChoiceFilter($fieldDescription);
-//
-//                break;
-//
-//            default:
-//                $class = $this->getFilterFieldClass($fieldDescription);
-//                $filter = new $class($fieldDescription);
 //        }
 
         $id = isset($this->types[$type]) ? $this->types[$type] : false;
@@ -84,7 +70,6 @@ class FilterFactory implements FilterFactoryInterface
 
         $fieldDescription->mergeOption('field_options', array('required' => false));
         $filter->setFieldDescription($fieldDescription);
-        $filter->defineFieldBuilder($this->container->get('form.factory'));
 
         return $filter;
     }

+ 0 - 18
Filter/FilterInterface.php

@@ -11,7 +11,6 @@
 
 namespace Sonata\AdminBundle\Filter;
 
-use Symfony\Component\Form\FormFactory;
 use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
 
 interface FilterInterface
@@ -28,15 +27,6 @@ interface FilterInterface
      */
     function filter($queryBuilder, $alias, $field, $value);
 
-    /**
-     * Define the related field builder
-     *
-     * @abstract
-     * @param \Symfony\Component\Form\FormFactory
-     * @return void
-     */
-    function defineFieldBuilder(FormFactory $formFactory);
-
     /**
      * Returns the filter name
      * @abstract
@@ -44,14 +34,6 @@ interface FilterInterface
      */
     function getName();
 
-    /**
-     * Returns the formBuilder instance
-     *
-     * @abstract
-     * @return \Symfony\Component\Form\FormBuilder
-     */
-    function getField();
-
     /**
      * @abstract
      * @return array

+ 1 - 1
Filter/ORM/BooleanFilter.php

@@ -27,7 +27,7 @@ class BooleanFilter extends Filter
      */
     public function filter($queryBuilder, $alias, $field, $value)
     {
-        if ($this->getField()->getAttribute('multiple')) {
+        if (is_array($value)) {
             $values = array();
             foreach ($value as $v) {
                 if (!in_array($v, array(BooleanType::TYPE_NO, BooleanType::TYPE_YES))) {

+ 2 - 2
Filter/ORM/ChoiceFilter.php

@@ -24,8 +24,8 @@ class ChoiceFilter extends Filter
      */
     public function filter($queryBuilder, $alias, $field, $value)
     {
-        if ($this->getField()->getAttribute('multiple')) {
-            if (!is_array($value) || count($value) == 0) {
+        if (is_array($value)) {
+            if (count($value) == 0) {
                 return;
             }
 

+ 0 - 1
Filter/ORM/StringFilter.php

@@ -28,7 +28,6 @@ class StringFilter extends Filter
 
         // c.name LIKE '%word%' => c.name LIKE :fieldName
         $queryBuilder->andWhere(sprintf('%s.%s LIKE :%s', $alias, $field, $this->getName()));
-
         $queryBuilder->setParameter($this->getName(), sprintf($this->getOption('format'), $value));
     }
 

+ 1 - 0
Resources/config/doctrine_orm.xml

@@ -45,6 +45,7 @@
 
         <!-- DatagridBuilder guesser -->
         <service id="sonata.admin.builder.orm_datagrid" class="Sonata\AdminBundle\Builder\ORM\DatagridBuilder">
+            <argument type="service" id="form.factory" />
             <argument type="service" id="sonata.admin.builder.filter.factory" />
             <argument type="service" id="sonata.admin.guesser.orm_datagrid_chain" />
         </service>

+ 3 - 3
Resources/views/CRUD/base_list.html.twig

@@ -136,11 +136,11 @@ file that was distributed with this source code.
     {% if admin.datagrid.filters %}
         <form class="sonata-filter-form" action="{{ admin.generateUrl('list') }}" method="GET">
             {% for filter in admin.datagrid.filters %}
-                <div>
-                    {{ filter|render_filter_element }}</td>
-                </div>
+                {{ form_row(form.getChild(filter.name)) }}
             {% endfor %}
 
+            {{ form_rest(form) }}
+
             <input type="submit" value="{% trans from 'SonataAdminBundle' %}btn_filter{% endtrans %}" />
 
             <a href="{{ admin.generateUrl('list') }}">{% trans from 'SonataAdminBundle' %}link_reset_filter{% endtrans %}</a>

+ 0 - 12
Resources/views/CRUD/filter_callback.html.twig

@@ -1,12 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}

+ 0 - 12
Resources/views/CRUD/filter_checkbox.html.twig

@@ -1,12 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}

+ 0 - 13
Resources/views/CRUD/filter_choice.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_identifier.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_integer.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_many_to_many.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_many_to_one.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_number.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_text.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 0 - 13
Resources/views/CRUD/filter_textarea.html.twig

@@ -1,13 +0,0 @@
-{#
-
-This file is part of the Sonata package.
-
-(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
-
-For the full copyright and license information, please view the LICENSE
-file that was distributed with this source code.
-
-#}
-
-{% extends 'SonataAdminBundle:CRUD:base_filter_field.html.twig' %}
-

+ 23 - 0
Resources/views/Form/filter_admin_fields.html.twig

@@ -0,0 +1,23 @@
+{#
+
+This file is part of the Sonata package.
+
+(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+
+For the full copyright and license information, please view the LICENSE
+file that was distributed with this source code.
+
+#}
+
+{% extends 'form_div_layout.html.twig' %}
+
+{% block field_row %}
+    <div>
+        {{ form_label(form) }}
+        <br />
+
+        <div class="sonata-ba-field">
+            {% block field %}{{ form_widget(form) }}{% endblock %}
+        </div>
+    </div>
+{% endblock field_row %}

Resources/views/Form/admin_fields.html.twig → Resources/views/Form/form_admin_fields.html.twig


+ 0 - 20
Twig/Extension/SonataAdminExtension.php

@@ -41,7 +41,6 @@ class SonataAdminExtension extends \Twig_Extension
     {
         return array(
             'render_list_element'     => new \Twig_Filter_Method($this, 'renderListElement', array('is_safe' => array('html'))),
-            'render_filter_element'   => new \Twig_Filter_Method($this, 'renderFilterElement', array('is_safe' => array('html'))),
             'render_view_element'     => new \Twig_Filter_Method($this, 'renderViewElement', array('is_safe' => array('html'))),
             'render_relation_element' => new \Twig_Filter_Method($this, 'renderRelationElement', array('is_safe' => array('html'))),
         );
@@ -148,25 +147,6 @@ class SonataAdminExtension extends \Twig_Extension
         return $value;
     }
 
-    /**
-     * render a filter element
-     *
-     * @param \Sonata\AdminBundle\Filter\FilterInterface $filter
-     * @param array $params
-     * @return string
-     */
-    public function renderFilterElement(FilterInterface $filter, array $params = array())
-    {
-        $fieldDescription = $filter->getFieldDescription();
-
-        $template = $this->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_filter_field.html.twig');
-
-        return $this->output($fieldDescription, $template, array_merge($params, array(
-            'filter'        => $filter,
-            'filter_form'   => $filter->getField()->createView()
-        )));
-    }
-
     /**
      * render a view element
      *