浏览代码

Add ModelFilter

Thomas Rabaix 13 年之前
父节点
当前提交
cf15783349

+ 1 - 1
Admin/BaseFieldDescription.php

@@ -411,7 +411,7 @@ abstract class BaseFieldDescription implements FieldDescriptionInterface
      */
     public function mergeOptions(array $options = array())
     {
-        $this->setOptions(array_merge($this->options, $options));
+        $this->setOptions(array_merge_recursive($this->options, $options));
     }
 
     /**

+ 1 - 3
Builder/ORM/DatagridBuilder.php

@@ -88,9 +88,7 @@ class DatagridBuilder implements DatagridBuilderInterface
             $fieldDescription->setType($guessType->getType());
             $options = $guessType->getOptions();
 
-            $fieldDescription->setOption('options',       array_merge($options['options'], $fieldDescription->getOption('options', array())));
-            $fieldDescription->setOption('field_options', array_merge($options['field_options'], $fieldDescription->getOption('field_options', array())));
-            $fieldDescription->setOption('field_type',    $fieldDescription->getOption('field_type', $options['field_type']));
+            $fieldDescription->mergeOptions($options);
         } else {
             $fieldDescription->setType($type);
         }

+ 2 - 2
Filter/Filter.php

@@ -18,14 +18,14 @@ use Symfony\Component\Form\FormFactory;
 
 abstract class Filter implements FilterInterface
 {
-    protected $fieldDescription = array();
-
     protected $name = null;
 
     protected $value = null;
 
     protected $options = array();
 
+    protected $fieldDescription = array();
+
     public function setFieldDescription(FieldDescriptionInterface $fieldDescription)
     {
         $this->name               = $fieldDescription->getName();

+ 2 - 10
Filter/FilterFactory.php

@@ -28,6 +28,7 @@ class FilterFactory implements FilterFactoryInterface
 
     /**
      * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+     * @param array $types
      */
     public function __construct(ContainerInterface $container, array $types = array())
     {
@@ -37,7 +38,7 @@ class FilterFactory implements FilterFactoryInterface
 
     /**
      * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription
-     * @return void
+     * @return \Sonata\AdminBundle\Filter\FilterInterface
      */
     public function create(FieldDescriptionInterface $fieldDescription)
     {
@@ -46,15 +47,6 @@ class FilterFactory implements FilterFactoryInterface
         }
 
         $type = $fieldDescription->getType();
-//        $
-//        switch($fieldDescription->getMappingType()) {
-//            case ClassMetadataInfo::MANY_TO_ONE:
-//                $options = $fieldDescription->getOption('filter_field_options');
-//                $filter = new \Sonata\AdminBundle\Filter\ORM\IntegerFilter($fieldDescription);
-//
-//                break;
-//
-//        }
 
         $id = isset($this->types[$type]) ? $this->types[$type] : false;
 

+ 0 - 1
Filter/ORM/ChoiceFilter.php

@@ -41,7 +41,6 @@ class ChoiceFilter extends Filter
             }
 
             $queryBuilder->andWhere(sprintf('%s.%s = :%s', $alias, $field, $this->getName()));
-
             $queryBuilder->setParameter($this->getName(), $value);
         }
     }

+ 0 - 10
Filter/ORM/Filter.php

@@ -28,16 +28,6 @@ abstract class Filter extends BaseFilter
 
     protected function association($queryBuilder, $value)
     {
-        if ($value && $this->getFieldDescription()->getMappingType() == ClassMetadataInfo::MANY_TO_MANY) {
-            $queryBuilder->leftJoin(
-                sprintf('%s.%s', $queryBuilder->getRootAlias(), $this->getFieldDescription()->getFieldName()),
-                $this->getName()
-            );
-
-            // todo : use the metadata information to find the correct column name
-            return array($this->getName(), 'id');
-        }
-
         return array($queryBuilder->getRootAlias(), $this->getFieldDescription()->getFieldName());
     }
 }

+ 71 - 0
Filter/ORM/ModelFilter.php

@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * 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.
+ */
+
+namespace Sonata\AdminBundle\Filter\ORM;
+
+use Doctrine\ORM\QueryBuilder;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+class ModelFilter extends Filter
+{
+    /**
+     * @param QueryBuilder $queryBuilder
+     * @param string $alias
+     * @param string $field
+     * @param mixed $value
+     * @return
+     */
+    public function filter($queryBuilder, $alias, $field, $value)
+    {
+        if (is_array($value)) {
+            if (count($value) == 0) {
+                return;
+            }
+
+            $queryBuilder->andWhere($queryBuilder->expr()->in(sprintf('%s.%s', $alias, $field ), $value));
+        } else {
+
+            if (empty($value)) {
+                return;
+            }
+
+            $queryBuilder->andWhere(sprintf('%s.%s = :%s', $alias, $field, $this->getName()));
+            $queryBuilder->setParameter($this->getName(), $value);
+        }
+    }
+
+    protected function association($queryBuilder, $value)
+    {
+        $types = array(
+            ClassMetadataInfo::ONE_TO_ONE,
+            ClassMetadataInfo::ONE_TO_MANY,
+            ClassMetadataInfo::MANY_TO_MANY,
+            ClassMetadataInfo::MANY_TO_ONE,
+        );
+
+        if (!in_array($this->getOption('mapping_type'), $types)) {
+            throw new \RunTimeException('Invalid mapping type' .$this->getOption('mapping_type'));
+        }
+
+        $queryBuilder->leftJoin(sprintf('%s.%s', $queryBuilder->getRootAlias(), $this->getOption('field_name')), $this->getName());
+
+        // todo : use the metadata information to find the correct column name
+        return array($this->getName(), 'id');
+    }
+
+    public function getDefaultOptions()
+    {
+        return array(
+            'mapping_type' => false,
+            'field_name' => false
+        );
+    }
+}

+ 7 - 10
Guesser/ORM/FilterTypeGuesser.php

@@ -54,26 +54,23 @@ class FilterTypeGuesser implements TypeGuesserInterface
             $mapping = $metadata->getAssociationMapping($property);
 
             switch ($mapping['type']) {
+                case ClassMetadataInfo::ONE_TO_ONE:
                 case ClassMetadataInfo::ONE_TO_MANY:
+                case ClassMetadataInfo::MANY_TO_ONE:
                 case ClassMetadataInfo::MANY_TO_MANY:
+
                     $options['field_type'] = 'entity';
                     $options['field_options'] = array(
-                        'class' => $class
+                        'class' => $mapping['targetEntity']
                     );
+                    $options['field_name'] = $mapping['fieldName'];
+                    $options['mapping_type'] = $mapping['type'];
 
-                    return new TypeGuess('doctrine_orm_choice', $options, Guess::HIGH_CONFIDENCE);
-
-                case ClassMetadataInfo::MANY_TO_ONE:
-                    return new TypeGuess('doctrine_orm_many_to_one', $options, Guess::HIGH_CONFIDENCE);
-
-                case ClassMetadataInfo::ONE_TO_ONE:
-                    return new TypeGuess('doctrine_orm_one_to_one', $options, Guess::HIGH_CONFIDENCE);
+                    return new TypeGuess('doctrine_orm_model', $options, Guess::HIGH_CONFIDENCE);
             }
         }
 
         switch ($metadata->getTypeOfField($property)) {
-            //case 'array':
-            //  return new TypeGuess('Collection', $options, Guess::HIGH_CONFIDENCE);
             case 'boolean':
                 $options['field_type'] = 'sonata_type_filter_boolean';
                 $options['field_options'] = array();

+ 4 - 0
Resources/config/doctrine_orm_filter_types.xml

@@ -17,6 +17,10 @@
             <tag name="sonata.admin.filter.type" alias="doctrine_orm_choice" />
         </service>
 
+        <service id="sonata.admin.orm.filter.type.model" class="Sonata\AdminBundle\Filter\ORM\ModelFilter">
+            <tag name="sonata.admin.filter.type" alias="doctrine_orm_model" />
+        </service>
+
         <service id="sonata.admin.orm.filter.type.integer" class="Sonata\AdminBundle\Filter\ORM\IntegerFilter">
             <tag name="sonata.admin.filter.type" alias="doctrine_orm_integer" />
         </service>