Thomas 14 éve
szülő
commit
db776aa19c

+ 1 - 6
Admin/Admin.php

@@ -19,7 +19,6 @@ use Symfony\Component\HttpFoundation\Request;
 use Sonata\AdminBundle\Form\FormMapper;
 use Sonata\AdminBundle\Datagrid\ListMapper;
 use Sonata\AdminBundle\Datagrid\DatagridMapper;
-use Sonata\AdminBundle\Datagrid\Datagrid;
 
 use Sonata\AdminBundle\Admin\Pool;
 use Sonata\AdminBundle\Builder\FormBuilderInterface;
@@ -863,11 +862,7 @@ abstract class Admin implements AdminInterface
      */
     public function getBaseDatagrid($values = array())
     {
-        return new Datagrid(
-            $this->getClass(),
-            $this->getModelManager(),
-            $values
-        );
+        return $this->getDatagridBuilder()->getBaseDatagrid($this, $values);
     }
 
     /**

+ 42 - 13
Builder/DatagridBuilder.php

@@ -9,11 +9,12 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Builder;
+namespace Sonata\AdminBundle\Builder\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Sonata\AdminBundle\Admin\Admin;
-use Sonata\AdminBundle\Datagrid\Datagrid;
+use Sonata\AdminBundle\Datagrid\ORM\Datagrid;
+use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
 
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
 
@@ -28,18 +29,24 @@ class DatagridBuilder implements DatagridBuilderInterface
      * @var array
      */
     protected $filterClasses = array(
-        'string'     =>  'Sonata\\AdminBundle\\Filter\\StringFilter',
-        'text'       =>  'Sonata\\AdminBundle\\Filter\\StringFilter',
-        'boolean'    =>  'Sonata\\AdminBundle\\Filter\\BooleanFilter',
-        'integer'    =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'tinyint'    =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'smallint'   =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'mediumint'  =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'bigint'     =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'decimal'    =>  'Sonata\\AdminBundle\\Filter\\IntegerFilter',
-        'callback'   =>  'Sonata\\AdminBundle\\Filter\\CallbackFilter',
+        'string'     =>  'Sonata\\AdminBundle\\Filter\\ORM\\StringFilter',
+        'text'       =>  'Sonata\\AdminBundle\\Filter\\ORM\\StringFilter',
+        'boolean'    =>  'Sonata\\AdminBundle\\Filter\\ORM\\BooleanFilter',
+        'integer'    =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'tinyint'    =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'smallint'   =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'mediumint'  =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'bigint'     =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'decimal'    =>  'Sonata\\AdminBundle\\Filter\\ORM\\IntegerFilter',
+        'callback'   =>  'Sonata\\AdminBundle\\Filter\\ORM\\CallbackFilter',
     );
 
+    /**
+     * @throws \RuntimeException
+     * @param \Sonata\AdminBundle\Admin\Admin $admin
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @return void
+     */
     public function fixFieldDescription(Admin $admin, FieldDescription $fieldDescription)
     {
         // set default values
@@ -109,6 +116,10 @@ class DatagridBuilder implements DatagridBuilderInterface
         return $class;
     }
 
+    /**
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @return array
+     */
     public function getChoices(FieldDescription $fieldDescription)
     {
         $targets = $fieldDescription->getAdmin()->getModelManager()
@@ -132,6 +143,11 @@ class DatagridBuilder implements DatagridBuilderInterface
         return $choices;
     }
 
+    /**
+     * @param \Sonata\AdminBundle\Datagrid\ORM\Datagrid $datagrid
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @return bool
+     */
     public function addFilter(Datagrid $datagrid, FieldDescription $fieldDescription)
     {
 
@@ -168,5 +184,18 @@ class DatagridBuilder implements DatagridBuilderInterface
 
         $datagrid->addFilter($filter);
     }
-   
+
+    /**
+     * @param \Sonata\AdminBundle\Admin\Admin $admin
+     * @param array $values
+     * @return \Sonata\AdminBundle\Datagrid\ORM\Datagrid
+     */
+    public function getBaseDatagrid(Admin $admin, array $values)
+    {
+        return new Datagrid(
+            $admin->getClass(),
+            $admin->getModelManager(),
+            $admin
+        );
+    }
 }

+ 7 - 6
Builder/FormBuilder.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Builder;
+namespace Sonata\AdminBundle\Builder\ORM;
 
 use Sonata\AdminBundle\Form\ValueTransformer\EntityToIDTransformer;
 use Sonata\AdminBundle\Form\ValueTransformer\ArrayToObjectTransformer;
@@ -17,7 +17,8 @@ use Sonata\AdminBundle\Form\EditableCollectionField;
 use Sonata\AdminBundle\Form\EditableFieldGroup;
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Sonata\AdminBundle\Admin\Admin;
-
+use Sonata\AdminBundle\Builder\FormBuilderInterface;
+    
 use Symfony\Component\Form\Form;
 use Symfony\Component\Form\FormInterface;
 use Symfony\Component\Form\FormContextInterface;
@@ -402,22 +403,22 @@ class FormBuilder implements FormBuilderInterface
         }
 
         if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_ONE) {
-            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_one_to_one.html.twig');
+            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_one_to_one.html.twig');
             $admin->attachAdminClass($fieldDescription);
         }
 
         if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_ONE) {
-            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_many_to_one.html.twig');
+            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_many_to_one.html.twig');
             $admin->attachAdminClass($fieldDescription);
         }
 
         if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_MANY) {
-            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_many_to_many.html.twig');
+            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_many_to_many.html.twig');
             $admin->attachAdminClass($fieldDescription);
         }
 
         if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_MANY) {
-            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_one_to_many.html.twig');
+            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_orm_one_to_many.html.twig');
 
             if ($fieldDescription->getOption('edit') == 'inline' && !$fieldDescription->getOption('widget_form_field')) {
                 $fieldDescription->setOption('widget_form_field', 'Bundle\\Sonata\\AdminBundle\\Form\\EditableFieldGroup');

+ 7 - 6
Builder/ListBuilder.php

@@ -9,12 +9,13 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Builder;
+namespace Sonata\AdminBundle\Builder\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Sonata\AdminBundle\Admin\Admin;
 use Sonata\AdminBundle\Datagrid\ListCollection;
-    
+use Sonata\AdminBundle\Builder\ListBuilderInterface;
+
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
 
 class ListBuilder implements ListBuilderInterface
@@ -66,19 +67,19 @@ class ListBuilder implements ListBuilderInterface
             $fieldDescription->setTemplate(sprintf('SonataAdminBundle:CRUD:list_%s.html.twig', $fieldDescription->getType()));
 
             if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_ONE) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_many_to_one.html.twig');
+                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_orm_many_to_one.html.twig');
             }
 
             if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_ONE) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_one_to_one.html.twig');
+                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_orm_one_to_one.html.twig');
             }
 
             if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_MANY) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_one_to_many.html.twig');
+                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_orm_one_to_many.html.twig');
             }
 
             if ($fieldDescription->getType() == ClassMetadataInfo::MANY_TO_MANY) {
-                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_many_to_many.html.twig');
+                $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list_orm_many_to_many.html.twig');
             }
         }
 

+ 1 - 1
Datagrid/DatagridMapper.php

@@ -12,7 +12,7 @@ namespace Sonata\AdminBundle\Datagrid;
 
 use Sonata\AdminBundle\Admin\Admin;
 use Sonata\AdminBundle\Admin\FieldDescription;
-use Sonata\AdminBundle\Datagrid\Datagrid;
+use Sonata\AdminBundle\Datagrid\ORM\Datagrid;
 use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
 
 /**

+ 1 - 1
Datagrid/ListMapper.php

@@ -10,7 +10,7 @@
  */
 namespace Sonata\AdminBundle\Datagrid;
 
-use Sonata\AdminBundle\Admin\Admin;
+use Sonata\AdminBundle\Admin\admin;
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Sonata\AdminBundle\Datagrid\ListCollection;
 use Sonata\AdminBundle\Builder\ListBuilderInterface;

+ 2 - 7
Datagrid/Datagrid.php

@@ -9,14 +9,9 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Datagrid;
+namespace Sonata\AdminBundle\Datagrid\ORM;
 
-use Sonata\AdminBundle\Tool\DoctrinePager as Pager;
-
-use Sonata\AdminBundle\Admin\EntityAdmin;
-use Sonata\AdminBundle\Admin\FieldDescription;
-
-use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Sonata\AdminBundle\Datagrid\ORM\Pager;
 
 class Datagrid
 {

+ 88 - 0
Datagrid/ORM/Pager.php

@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ * (c) Jonathan H. Wage <jonwage@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Datagrid\ORM;
+
+use Sonata\AdminBundle\Datagrid\Pager as BasePager;
+use Doctrine\ORM\Query;
+use Doctrine\ORM\QueryBuilder;
+
+/**
+ * Doctrine pager class.
+ *
+ * @author     Jonathan H. Wage <jonwage@gmail.com>
+ * @version    SVN: $Id: sfDoctrinePager.class.php 28897 2010-03-30 20:30:24Z Jonathan.Wage $
+ */
+class Pager extends BasePager
+{
+
+    /**
+     * Returns a query for counting the total results.
+     *
+     * @return Doctrine\ORM\Query
+     */
+    public function getCountQuery()
+    {
+        $queryBuilder = clone $this->getQueryBuilder();
+
+        $queryBuilder->select(sprintf('count(%s.%s) as nb', $queryBuilder->getRootAlias(), $this->getCountColumn()));
+        
+        return $queryBuilder->getQuery();
+    }
+
+    /**
+     * @see Pager
+     */
+    public function init()
+    {
+        $this->resetIterator();
+
+        $countQuery = $this->getCountQuery();
+        $countQuery->setParameters($this->getParameters());
+
+        $count = $countQuery->getSingleScalarResult();
+
+        $this->setNbResults($count);
+
+        $query = $this->getQuery();
+        
+        $query
+            ->setParameters($this->getParameters())
+            ->setFirstResult(0)
+            ->setMaxResults(0);
+
+        if (0 == $this->getPage() || 0 == $this->getMaxPerPage() || 0 == $this->getNbResults()) {
+            $this->setLastPage(0);
+        }
+        else
+        {
+            $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
+
+            $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
+
+            $query
+                ->setFirstResult($offset)
+                ->setMaxResults($this->getMaxPerPage());
+        }
+    }
+
+    /**
+     * Get all the results for the pager instance
+     *
+     * @param mixed $hydrationMode A hydration mode identifier
+     *
+     * @return  array
+     */
+    public function getResults($hydrationMode = Query::HYDRATE_OBJECT)
+    {
+        return $this->getQuery()->execute(array(), $hydrationMode);
+    }
+}

+ 116 - 28
Tool/Pager.php

@@ -8,7 +8,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Tool;
+namespace Sonata\AdminBundle\Datagrid;
 
 /**
  * Pager class.
@@ -17,25 +17,28 @@ namespace Sonata\AdminBundle\Tool;
  * @subpackage addon
  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  */
-abstract class Pager implements \Iterator, \Countable
+abstract class Pager implements \Iterator, \Countable, \Serializable
 {
-    protected
-        $page = 1,
-        $maxPerPage = 0,
-        $lastPage = 1,
-        $nbResults = 0,
-        $class = '',
-        $tableName = '',
-        $objects = null,
-        $cursor = 1,
-        $parameters = array(),
-        $currentMaxLink = 1,
-        $parameterBag = null,
-        $maxRecordLimit = false,
-
-        // used by iterator interface
-        $results = null,
-        $resultsCounter = 0;
+
+    protected $page = 1;
+    protected $maxPerPage = 0;
+    protected $lastPage = 1;
+    protected $nbResults = 0;
+    protected $class = '';
+    protected $tableName = '';
+    protected $objects = null;
+    protected $cursor = 1;
+    protected $parameters = array();
+    protected $currentMaxLink = 1;
+    protected $parameterBag = null;
+    protected $maxRecordLimit = false;
+
+    // used by iterator interface
+    protected $results = null;
+    protected $resultsCounter = 0;
+    protected $query            = null;
+    protected $queryBuilder     = null;
+    protected $countColumn      = 'id';
 
     /**
      * Constructor.
@@ -63,15 +66,6 @@ abstract class Pager implements \Iterator, \Countable
      */
     abstract public function getResults();
 
-    /**
-     * Returns an object at a certain offset.
-     *
-     * Used internally by {@link getCurrent()}.
-     *
-     * @return mixed
-     */
-    abstract protected function retrieveObject($offset);
-
     /**
      * Returns the current pager's max link.
      *
@@ -597,4 +591,98 @@ abstract class Pager implements \Iterator, \Countable
     {
         return $this->getNbResults();
     }
+
+    /**
+     * Get the query builder for the pager.
+     *
+     * @return Doctrine\ORM\QueryBuilder
+     */
+    public function getQueryBuilder()
+    {
+
+        return $this->queryBuilder;
+    }
+
+    /**
+     * Set query object for the pager
+     *
+     * @param Doctrine\ORM\QueryBuilder $query
+     */
+    public function setQueryBuilder($queryBuilder)
+    {
+        $this->queryBuilder = $queryBuilder;
+    }
+
+    /**
+     * Get the query for the pager.
+     *
+     * @return Doctrine\ORM\Query
+     */
+
+    public function getQuery()
+    {
+
+        if (!$this->query) {
+            $this->query = $this->getQueryBuilder()->getQuery();
+        }
+
+        return $this->query;
+    }
+
+    /**
+     * Serialize the pager object
+     *
+     * @return string $serialized
+     */
+    public function serialize()
+    {
+        $vars = get_object_vars($this);
+        unset($vars['query']);
+        return serialize($vars);
+    }
+
+    /**
+     * Unserialize a pager object
+     *
+     * @param string $serialized
+     */
+    public function unserialize($serialized)
+    {
+        $array = unserialize($serialized);
+
+        foreach ($array as $name => $values)
+        {
+            $this->$name = $values;
+        }
+    }
+
+    public function getCountColumn()
+    {
+
+        return $this->countColumn;
+    }
+
+    public function setCountColumn($countColumn) {
+
+        return $this->countColumn = $countColumn;
+    }
+
+    /**
+     * Retrieve the object for a certain offset
+     *
+     * @param integer $offset
+     *
+     * @return object
+     */
+    protected function retrieveObject($offset)
+    {
+        $queryForRetrieve = clone $this->getQuery();
+        $queryForRetrieve
+            ->setFirstResult($offset - 1)
+            ->setMaxResults(1);
+
+        $results = $queryForRetrieve->execute();
+
+        return $results[0];
+    }
 }

+ 3 - 3
DependencyInjection/SonataAdminExtension.php

@@ -61,15 +61,15 @@ class SonataAdminExtension extends Extension
             ->addTag('twig.extension');
 
         // register form builder
-        $definition = new Definition('Sonata\AdminBundle\Builder\FormBuilder', array(new Reference('form.field_factory'), new Reference('form.context'), new Reference('validator')));
+        $definition = new Definition('Sonata\AdminBundle\Builder\ORM\FormBuilder', array(new Reference('form.field_factory'), new Reference('form.context'), new Reference('validator')));
         $container->setDefinition('sonata_admin.builder.orm_form', $definition);
 
         // register list builder
-        $definition = new Definition('Sonata\AdminBundle\Builder\ListBuilder');
+        $definition = new Definition('Sonata\AdminBundle\Builder\ORM\ListBuilder');
         $container->setDefinition('sonata_admin.builder.orm_list', $definition);
 
         // register filter builder
-        $definition = new Definition('Sonata\AdminBundle\Builder\DatagridBuilder');
+        $definition = new Definition('Sonata\AdminBundle\Builder\ORM\DatagridBuilder');
         $container->setDefinition('sonata_admin.builder.orm_datagrid', $definition);
 
         // registers crud action

+ 3 - 50
Filter/Filter.php

@@ -11,11 +11,12 @@
 
 namespace Sonata\AdminBundle\Filter;
 
-use Symfony\Component\Form\Configurable;
 use Sonata\AdminBundle\Admin\FieldDescription;
+use Sonata\AdminBundle\Filter\FilterInterface;
+use Symfony\Component\Form\Configurable;
 use Doctrine\ORM\QueryBuilder;
 
-abstract class Filter extends Configurable
+abstract class Filter extends Configurable implements FilterInterface
 {
 
     protected $description = array();
@@ -26,25 +27,6 @@ abstract class Filter extends Configurable
 
     protected $value = null;
 
-    /**
-     * apply the filter to the QueryBuilder instance
-     *
-     * @abstract
-     * @param  $query
-     * @param  $value
-     * @param  $alias the root alias
-     * @return void
-     */
-    abstract public function filter(QueryBuilder $queryBuilder, $alias, $field, $value);
-
-    /**
-     * get the related form field filter
-     *
-     * @abstract
-     * @return Field
-     */
-    abstract public function getFormField();
-
     public function __construct(FieldDescription $fieldDescription)
     {
         $this->name         = $fieldDescription->getName();
@@ -75,35 +57,6 @@ abstract class Filter extends Configurable
         return $this->description;
     }
 
-    public function apply(QueryBuilder $queryBuilder, $value)
-    {
-        $this->value = $value;
-
-        $this->field->submit($value);
-
-        list($alias, $field) = $this->association($queryBuilder, $this->field->getData());
-
-        $this->filter($queryBuilder, $alias, $field, $this->field->getData());
-    }
-
-    protected function association(QueryBuilder $queryBuilder, $value)
-    {
-        if ($value) {
-
-            if ($this->description->getType() == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY) {
-                $queryBuilder->leftJoin(
-                    sprintf('%s.%s', $queryBuilder->getRootAlias(), $this->description->getFieldName()),
-                    $this->getName()
-                );
-
-                // todo : use the metadata information to find the correct column name
-                return array($this->getName(), 'id');
-            }
-        }
-        
-        return array($queryBuilder->getRootAlias(), $this->description->getFieldName());
-    }
-
     public function setName($name)
     {
         $this->name = $name;

+ 35 - 0
Filter/FilterInterface.php

@@ -0,0 +1,35 @@
+<?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;
+
+interface FilterInterface
+{
+    /**
+     * apply the filter to the QueryBuilder instance
+     *
+     * @abstract
+     * @param  $queryBuilder
+     * @param string $alias
+     * @param string $field
+     * @param string $value
+     * @return void
+     */
+    function filter($queryBuilder, $alias, $field, $value);
+
+    /**
+     * get the related form field filter
+     *
+     * @abstract
+     * @return Field
+     */
+    function getFormField();
+}

+ 2 - 8
Filter/BooleanFilter.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Filter;
+namespace Sonata\AdminBundle\Filter\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Doctrine\ORM\QueryBuilder;
@@ -17,7 +17,7 @@ use Doctrine\ORM\QueryBuilder;
 class BooleanFilter extends Filter
 {
 
-    public function filter(QueryBuilder $queryBuilder, $alias, $field, $value)
+    public function filter($queryBuilder, $alias, $field, $value)
     {
 
         if ($this->getField()->isMultipleChoice()) {
@@ -58,12 +58,6 @@ class BooleanFilter extends Filter
         }
     }
 
-    protected function configure()
-    {
-
-        parent::configure();
-    }
-
     public function getFormField()
     {
 

+ 3 - 3
Filter/CallbackFilter.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Filter;
+namespace Sonata\AdminBundle\Filter\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Doctrine\ORM\QueryBuilder;
@@ -17,12 +17,12 @@ use Doctrine\ORM\QueryBuilder;
 class CallbackFilter extends Filter
 {
 
-    protected function association(QueryBuilder $queryBuilder, $value)
+    protected function association($queryBuilder, $value)
     {
         return array($queryBuilder->getRootAlias(), false);
     }
 
-    public function filter(QueryBuilder $queryBuilder, $alias, $field, $value)
+    public function filter($queryBuilder, $alias, $field, $value)
     {
 
         call_user_func($this->getOption('filter'), $queryBuilder, $alias, $field, $value);

+ 2 - 10
Filter/ChoiceFilter.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Filter;
+namespace Sonata\AdminBundle\Filter\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Doctrine\ORM\QueryBuilder;
@@ -17,10 +17,8 @@ use Doctrine\ORM\QueryBuilder;
 class ChoiceFilter extends Filter
 {
 
-    public function filter(QueryBuilder $queryBuilder, $alias, $field, $value)
+    public function filter($queryBuilder, $alias, $field, $value)
     {
-
-
         if ($this->getField()->isMultipleChoice()) {
 
             if (in_array('all', $value)) {
@@ -52,12 +50,6 @@ class ChoiceFilter extends Filter
         }
     }
 
-    protected function configure()
-    {
-
-        parent::configure();
-    }
-
     public function getFormField()
     {
         return new \Symfony\Component\Form\ChoiceField(

+ 50 - 0
Filter/ORM/Filter.php

@@ -0,0 +1,50 @@
+<?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 Sonata\AdminBundle\Admin\FieldDescription;
+use Sonata\AdminBundle\Filter\Filter as BaseFilter;
+use Symfony\Component\Form\Configurable;
+use Doctrine\ORM\QueryBuilder;
+
+abstract class Filter extends BaseFilter
+{
+
+    public function apply($queryBuilder, $value)
+    {
+        $this->value = $value;
+
+        $this->field->submit($value);
+
+        list($alias, $field) = $this->association($queryBuilder, $this->field->getData());
+
+        $this->filter($queryBuilder, $alias, $field, $this->field->getData());
+    }
+
+    protected function association($queryBuilder, $value)
+    {
+        if ($value) {
+
+            if ($this->description->getType() == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY) {
+                $queryBuilder->leftJoin(
+                    sprintf('%s.%s', $queryBuilder->getRootAlias(), $this->description->getFieldName()),
+                    $this->getName()
+                );
+
+                // todo : use the metadata information to find the correct column name
+                return array($this->getName(), 'id');
+            }
+        }
+        
+        return array($queryBuilder->getRootAlias(), $this->description->getFieldName());
+    }
+}

+ 1 - 1
Filter/IntegerFilter.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Filter;
+namespace Sonata\AdminBundle\Filter\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Doctrine\ORM\QueryBuilder;

+ 2 - 2
Filter/StringFilter.php

@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace Sonata\AdminBundle\Filter;
+namespace Sonata\AdminBundle\Filter\ORM;
 
 use Sonata\AdminBundle\Admin\FieldDescription;
 use Doctrine\ORM\QueryBuilder;
@@ -17,7 +17,7 @@ use Doctrine\ORM\QueryBuilder;
 class StringFilter extends Filter
 {
 
-    public function filter(QueryBuilder $queryBuilder, $alias, $field, $value)
+    public function filter($queryBuilder, $alias, $field, $value)
     {
 
         if ($value == null) {

Resources/views/CRUD/edit_many_association_script.html.twig → Resources/views/CRUD/edit_orm_many_association_script.html.twig


+ 1 - 1
Resources/views/CRUD/edit_many_to_many.html.twig

@@ -34,5 +34,5 @@ file that was distributed with this source code.
         </div>
     </div>
 
-    {% include 'SonataAdminBundle:CRUD:edit_many_association_script.html.twig' %}
+    {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %}
 {% endblock %}

+ 1 - 1
Resources/views/CRUD/edit_many_to_one.html.twig

@@ -66,6 +66,6 @@ file that was distributed with this source code.
             </div>
         </div>
 
-        {% include 'SonataAdminBundle:CRUD:edit_many_association_script.html.twig' %}
+        {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %}
     {% endif %}
 {% endblock %}

Resources/views/CRUD/edit_one_association_script.html.twig → Resources/views/CRUD/edit_orm_one_association_script.html.twig


+ 2 - 2
Resources/views/CRUD/edit_one_to_many.html.twig

@@ -112,7 +112,7 @@ file that was distributed with this source code.
             {% endif %}
 
             {# include association code #}
-            {% include 'SonataAdminBundle:CRUD:edit_one_association_script.html.twig' %}
+            {% include 'SonataAdminBundle:CRUD:edit_orm_one_association_script.html.twig' %}
             
         {% else %}
             <span id="field_actions_{{ field_element.id }}" >
@@ -131,7 +131,7 @@ file that was distributed with this source code.
 
             </div>
         
-            {% include 'SonataAdminBundle:CRUD:edit_many_association_script.html.twig' %}
+            {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %}
         {% endif %}
     </div>
 {% endblock %}

+ 1 - 1
Resources/views/CRUD/edit_one_to_one.html.twig

@@ -67,6 +67,6 @@ file that was distributed with this source code.
             </div>
         </div>
 
-        {% include 'SonataAdminBundle:CRUD:edit_many_association_script.html.twig' %}
+        {% include 'SonataAdminBundle:CRUD:edit_orm_many_association_script.html.twig' %}
     {% endif %}
 {% endblock %}

Resources/views/CRUD/list_many_to_many.html.twig → Resources/views/CRUD/list_orm_many_to_many.html.twig


Resources/views/CRUD/list_many_to_one.html.twig → Resources/views/CRUD/list_orm_many_to_one.html.twig


Resources/views/CRUD/list_one_to_many.html.twig → Resources/views/CRUD/list_orm_one_to_many.html.twig


Resources/views/CRUD/list_one_to_one.html.twig → Resources/views/CRUD/list_orm_one_to_one.html.twig


+ 0 - 188
Tool/DoctrinePager.php

@@ -1,188 +0,0 @@
-<?php
-
-/*
- * This file is part of the symfony package.
- * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
- * (c) Jonathan H. Wage <jonwage@gmail.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Sonata\AdminBundle\Tool;
-
-use Doctrine\ORM\Query;
-use Doctrine\ORM\QueryBuilder;
-
-/**
- * Doctrine pager class.
- *
- * @author     Jonathan H. Wage <jonwage@gmail.com>
- * @version    SVN: $Id: sfDoctrinePager.class.php 28897 2010-03-30 20:30:24Z Jonathan.Wage $
- */
-class DoctrinePager extends Pager implements \Serializable
-{
-
-    protected
-        $query                  = null,
-        $query_builder          = null,
-        $count_column           = 'id';
-    
-    /**
-     * Serialize the pager object
-     *
-     * @return string $serialized
-     */
-    public function serialize()
-    {
-        $vars = get_object_vars($this);
-        unset($vars['query']);
-        return serialize($vars);
-    }
-
-    /**
-     * Unserialize a pager object
-     *
-     * @param string $serialized
-     */
-    public function unserialize($serialized)
-    {
-        $array = unserialize($serialized);
-
-        foreach ($array as $name => $values)
-        {
-            $this->$name = $values;
-        }
-    }
-
-    /**
-     * Returns a query for counting the total results.
-     *
-     * @return Doctrine\ORM\Query
-     */
-    public function getCountQuery()
-    {
-        $query_builder = clone $this->getQueryBuilder();
-
-        $query_builder->select(sprintf('count(%s.%s) as nb', $query_builder->getRootAlias(), $this->getCountColumn()));
-        
-        return $query_builder->getQuery();
-    }
-
-    public function getCountColumn()
-    {
-
-        return $this->count_column;
-    }
-
-    public function setCountColumn($count_column) {
-
-        return $this->count_column = $count_column;
-    }
-
-    /**
-     * @see Pager
-     */
-    public function init()
-    {
-        $this->resetIterator();
-
-        $countQuery = $this->getCountQuery();
-        $countQuery->setParameters($this->getParameters());
-
-        $count = $countQuery->getSingleScalarResult();
-
-        $this->setNbResults($count);
-
-        $query = $this->getQuery();
-        
-        $query
-            ->setParameters($this->getParameters())
-            ->setFirstResult(0)
-            ->setMaxResults(0);
-
-        if (0 == $this->getPage() || 0 == $this->getMaxPerPage() || 0 == $this->getNbResults()) {
-            $this->setLastPage(0);
-        }
-        else
-        {
-            $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
-
-            $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
-
-            $query
-                ->setFirstResult($offset)
-                ->setMaxResults($this->getMaxPerPage());
-        }
-    }
-
-    /**
-     * Get the query builder for the pager.
-     *
-     * @return Doctrine\ORM\QueryBuilder
-     */
-    public function getQueryBuilder()
-    {
-
-        return $this->query_builder;
-    }
-
-    /**
-     * Set query object for the pager
-     *
-     * @param Doctrine\ORM\QueryBuilder $query
-     */
-    public function setQueryBuilder(\Doctrine\ORM\QueryBuilder $query_builder)
-    {
-        $this->query_builder = $query_builder;
-    }
-
-    /**
-     * Get the query for the pager.
-     *
-     * @return Doctrine\ORM\Query
-     */
-
-    public function getQuery()
-    {
-
-        if (!$this->query) {
-            $this->query = $this->getQueryBuilder()->getQuery();
-        }
-
-        return $this->query;
-    }
-
-    /**
-     * Retrieve the object for a certain offset
-     *
-     * @param integer $offset
-     *
-     * @return object
-     */
-    protected function retrieveObject($offset)
-    {
-        $queryForRetrieve = clone $this->getQuery();
-        $queryForRetrieve
-            ->setFirstResult($offset - 1)
-            ->setMaxResults(1);
-
-        $results = $queryForRetrieve->execute();
-
-        return $results[0];
-    }
-
-    /**
-     * Get all the results for the pager instance
-     *
-     * @param mixed $hydrationMode A hydration mode identifier
-     *
-     * @return  array
-     */
-    public function getResults($hydrationMode = Query::HYDRATE_OBJECT)
-    {
-
-        return $this->getQuery()->execute(array(), $hydrationMode);
-    }
-
-}