Procházet zdrojové kódy

The admin classes are now non shared service defined in the DIC

Thomas před 14 roky
rodič
revize
a17cae0341

+ 245 - 85
Admin/Admin.php

@@ -11,19 +11,25 @@
 
 namespace Sonata\AdminBundle\Admin;
 
-use Symfony\Component\DependencyInjection\ContainerAware;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Form\Form;
-
+use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+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;
+use Sonata\AdminBundle\Builder\ListBuilderInterface;
+use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
+
 use Knplabs\MenuBundle\Menu;
 use Knplabs\MenuBundle\MenuItem;
 
-abstract class Admin extends ContainerAware
+abstract class Admin implements AdminInterface
 {
     /**
      * The class name managed by the admin class
@@ -215,6 +221,62 @@ abstract class Admin extends ContainerAware
      */
     protected $uniqid;
 
+    /**
+     * The Entity or Document manager
+     *
+     * @var object
+     */
+    protected $modelManager;
+
+    /**
+     * The current request object
+     *
+     * @var Symfony\Component\HttpFoundation\Request
+     */
+    protected $request;
+
+    /**
+     * The translator component
+     *
+     * @var Symfony\Component\Translation\TranslatorInterface
+     */
+    protected $translator;
+
+    /**
+     * The related form builder
+     *
+     * @var Sonata\AdminBundle\Builder\FormBuilderInterface
+     */
+    protected $formBuilder;
+
+    /**
+     * The related list builder
+     *
+     * @var Sonata\AdminBundle\Builder\ListBuilderInterface
+     */
+    protected $listBuilder;
+
+    /**
+     * The related datagrid builder
+     *
+     * @var Sonata\AdminBundle\Builder\DatagridBuilderInterface
+     */
+    protected $datagridBuilder;
+
+    /**
+     * The router intance
+     *
+     * @var Symfony\Component\Routing\RouterInterface
+     */
+    protected $router;
+
+    /**
+     * The configuration pool
+     * 
+     * @var Pool
+     */
+    protected $configurationPool;
+
     protected $loaded = array(
         'form_fields' => false,
         'form_groups' => false,
@@ -222,21 +284,18 @@ abstract class Admin extends ContainerAware
         'filter_fields' => false,
         'urls'        => false,
     );
-    
+
     /**
-     * return the entity manager
+     * return the doctrine class metadata handled by the Admin instance
      *
-     * @return EntityManager
+     * @return ClassMetadataInfo the doctrine class metadata handled by the Admin instance
      */
-    abstract public function getEntityManager();
-
-    abstract public function getListBuilder();
-
-    abstract public function getFormBuilder();
-
-    abstract public function getDatagridBuilder();
+    public function getClassMetaData()
+    {
 
-    abstract public function getClassMetaData();
+        return $this->getModelManager()
+            ->getClassMetaData($this->getClass());
+    }
 
     /**
      * This method can be overwritten to tweak the form construction, by default the form
@@ -265,19 +324,13 @@ abstract class Admin extends ContainerAware
     }
 
     /**
-     * @param string $code
-     * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
      * @param string $class
      * @param string $baseControllerName
      */
-    public function __construct($code, ContainerInterface $container, $class, $baseControllerName)
+    public function __construct($class, $baseControllerName)
     {
-        $this->code = $code;
         $this->class = $class;
         $this->baseControllerName = $baseControllerName;
-        
-        $this->setContainer($container);
-        $this->configure();
     }
 
     public function configure()
@@ -285,18 +338,19 @@ abstract class Admin extends ContainerAware
 
         $this->uniqid = uniqid();
         
-        if($this->parentAssociationMapping) {
-            if(!isset($this->getClassMetaData()->associationMappings[$this->parentAssociationMapping])) {
+        if ($this->parentAssociationMapping) {
+            if (!isset($this->getClassMetaData()->associationMappings[$this->parentAssociationMapping])) {
                 throw new \RuntimeException(sprintf('The value set to `relatedReflectionProperty` refer to a non existent association', $this->relatedReflectionProperty));
             }
             $this->parentAssociationMapping = $this->getClassMetaData()->associationMappings[$this->parentAssociationMapping];
         }
 
-        if(!$this->classnameLabel) {
+        if (!$this->classnameLabel) {
 
             $this->classnameLabel = $this->urlize(substr($this->class, strrpos($this->class, '\\') + 1), '_');
         }
 
+        $this->baseCodeRoute = $this->getCode();
     }
 
     public function configureUrls()
@@ -470,7 +524,7 @@ abstract class Admin extends ContainerAware
         if (!$this->baseRoutePattern) {
             preg_match('@([A-Za-z]*)\\\([A-Za-z]*)Bundle\\\(Entity|Document)\\\(.*)@', $this->getClass(), $matches);
 
-            if(!$matches) {
+            if (!$matches) {
                 throw new \RuntimeException(sprintf('Please define a default `baseRoutePattern` value for the admin class `%s`', get_class($this)));
             }
             
@@ -503,7 +557,7 @@ abstract class Admin extends ContainerAware
         if (!$this->baseRouteName) {
             preg_match('@([A-Za-z]*)\\\([A-Za-z]*)Bundle\\\(Entity|Document)\\\(.*)@', $this->getClass(), $matches);
 
-            if(!$matches) {
+            if (!$matches) {
                 throw new \RuntimeException(sprintf('Please define a default `baseRouteName` value for the admin class `%s`', get_class($this)));
             }
             
@@ -598,75 +652,77 @@ abstract class Admin extends ContainerAware
     /**
      * Build all the related urls to the current admin
      *
-     * @param string $baseCode
      * @return void
      */
-    public function buildUrls($baseCode = '')
+    public function buildUrls()
     {
         if ($this->loaded['urls']) {
             return;
         }
 
-        $this->baseCodeRoute = $baseCode;
-
         $this->loaded['urls'] = true;
         
         $this->urls =  array(
-            $baseCode . 'list' => array(
+            $this->baseCodeRoute . '.list' => array(
                 'name'      => $this->getBaseRouteName().'_list',
                 'pattern'   => $this->getBaseRoutePattern().'/list',
                 'defaults'  => array(
-                    '_controller' => $this->getBaseControllerName().':list'
+                    '_controller' => $this->getBaseControllerName().':list',
+                    '_sonata_admin' => $this->baseCodeRoute
                 ),
                 'requirements' => array(),
                 'options' => array(),
                 'params'    => array(),
             ),
-            $baseCode . 'create' => array(
+            $this->baseCodeRoute . '.create' => array(
                 'name'      => $this->getBaseRouteName().'_create',
                 'pattern'       => $this->getBaseRoutePattern().'/create',
                 'defaults'  => array(
-                    '_controller' => $this->getBaseControllerName().':create'
+                    '_controller' => $this->getBaseControllerName().':create',
+                    '_sonata_admin' => $this->baseCodeRoute
                 ),
                 'requirements' => array(),
                 'options' => array(),
                 'params'    => array(),
             ),
-            $baseCode . 'edit' => array(
+            $this->baseCodeRoute . '.edit' => array(
                 'name'      => $this->getBaseRouteName().'_edit',
                 'pattern'   => $this->getBaseRoutePattern().'/'.$this->getRouterIdParameter().'/edit',
                 'defaults'  => array(
-                    '_controller' => $this->getBaseControllerName().':edit'
+                    '_controller' => $this->getBaseControllerName().':edit',
+                    '_sonata_admin' => $this->baseCodeRoute
                 ),
                 'requirements' => array(),
                 'options' => array(),
                 'params'    => array(),
             ),
-            $baseCode . 'update' => array(
+            $this->baseCodeRoute . '.update' => array(
                 'name'      => $this->getBaseRouteName().'_update',
                 'pattern'       => $this->getBaseRoutePattern().'/update',
                 'defaults'  => array(
-                    '_controller' => $this->getBaseControllerName().':update'
+                    '_controller' => $this->getBaseControllerName().':update',
+                    '_sonata_admin' => $this->baseCodeRoute
                 ),
                 'requirements' => array(),
                 'options' => array(),
                 'params'    => array(),
             ),
-            $baseCode . 'batch' => array(
+            $this->baseCodeRoute . '.batch' => array(
                 'name'      => $this->getBaseRouteName().'_batch',
                 'pattern'       => $this->getBaseRoutePattern().'/batch',
                 'defaults'  => array(
-                    '_controller' => $this->getBaseControllerName().':batch'
+                    '_controller' => $this->getBaseControllerName().':batch',
+                    '_sonata_admin' => $this->baseCodeRoute
                 ),
                 'requirements' => array(),
                 'options' => array(),
                 'params'    => array(),
             )
         );
-
+        
         // add children urls
-        foreach ($this->getChildren() as $code => $children) {
-            $this->urls = array_merge($this->urls, $children->getUrls($code.'.'));
+        foreach ($this->getChildren() as $children) {
+            $this->urls = array_merge($this->urls, $children->getUrls());
         }
 
         $this->configureUrls();
@@ -700,30 +756,37 @@ abstract class Admin extends ContainerAware
      */
     public function generateUrl($name, array $params = array())
     {
-        
+
+        if (!$this->isChild()) {
+            if (strpos($name, '.')) {
+                $name = $this->getCode().'|'.$name;
+            } else {
+                $name = $this->getCode().'.'.$name;
+            }
+        }
         // if the admin is a child we automatically append the parent's id
-        if($this->isChild()) {
-            $name = $this->baseCodeRoute.$name;
+        else if ($this->isChild()) {
+            $name = $this->baseCodeRoute.'.'.$name;
 
             // twig template does not accept variable hash key ... so cannot use admin.idparameter ...
             // switch value
-            if(isset($params['id'])) {
+            if (isset($params['id'])) {
                 $params[$this->getIdParameter()] = $params['id'];
                 unset($params['id']);
             }
 
-            $params[$this->getParent()->getIdParameter()] = $this->container->get('request')->get($this->getParent()->getIdParameter());
+            $params[$this->getParent()->getIdParameter()] = $this->request->get($this->getParent()->getIdParameter());
         }
 
         // if the admin is linked to a FieldDescription (ie, embedded widget)
-        if($this->hasParentFieldDescription()) {
+        if ($this->hasParentFieldDescription()) {
             $params['uniqid']  = $this->getUniqid();
             $params['code']    = $this->getCode();
             $params['pcode']   = $this->getParentFieldDescription()->getAdmin()->getCode();
             $params['puniqid'] = $this->getParentFieldDescription()->getAdmin()->getUniqid();
         }
 
-        if($name == 'update' || substr($name, -7) == '.update') {
+        if ($name == 'update' || substr($name, -7) == '|update') {
             $params['uniqid'] = $this->getUniqid();
             $params['code']   = $this->getCode();
         }
@@ -734,7 +797,7 @@ abstract class Admin extends ContainerAware
             throw new \RuntimeException(sprintf('unable to find the url `%s`', $name));
         }
 
-        return $this->container->get('router')->generate($url['name'], $params);
+        return $this->router->generate($url['name'], $params);
     }
 
     /**
@@ -786,7 +849,7 @@ abstract class Admin extends ContainerAware
     public function getBaseForm($object, $options = array())
     {
         return $this->getFormBuilder()->getBaseForm(
-            'object_'.$this->getUniqid(),
+            $this->getUniqid(),
             $object,
             array_merge($this->formOptions, $options)
         );
@@ -800,7 +863,7 @@ abstract class Admin extends ContainerAware
     {
         return new Datagrid(
             $this->getClass(),
-            $this->getEntityManager(),
+            $this->getModelManager(),
             $values
         );
     }
@@ -830,7 +893,7 @@ abstract class Admin extends ContainerAware
     public function getObject($id)
     {
 
-        return $this->getEntityManager()
+        return $this->getModelManager()
             ->find($this->getClass(), $id);
     }
 
@@ -875,7 +938,7 @@ abstract class Admin extends ContainerAware
         // todo : clean the way the Admin class can retrieve set the object
         if ($this->isChild() && $this->getParentAssociationMapping()) {
             $mapping = $this->getParentAssociationMapping();
-            $parent = $this->getParent()->getObject($this->container->get('request')->get($this->getParent()->getIdParameter()));
+            $parent = $this->getParent()->getObject($this->request->get($this->getParent()->getIdParameter()));
 
             $propertyPath = new \Symfony\Component\Form\PropertyPath($mapping['fieldName']);
             $propertyPath->setValue($object, $parent);
@@ -892,7 +955,7 @@ abstract class Admin extends ContainerAware
         foreach ($this->getFormFieldDescriptions() as $fieldDescription) {
 
             // do not add field already set in the configureFormField method
-            if($mapper->has($fieldDescription->getFieldName())) {
+            if ($mapper->has($fieldDescription->getFieldName())) {
                 continue;
             }
 
@@ -922,7 +985,7 @@ abstract class Admin extends ContainerAware
         foreach ($this->getListFieldDescriptions() as $fieldDescription) {
 
             // do not add field already set in the configureFormField method
-            if($mapper->has($fieldDescription->getFieldName())) {
+            if ($mapper->has($fieldDescription->getFieldName())) {
                 continue;
             }
 
@@ -941,14 +1004,14 @@ abstract class Admin extends ContainerAware
     public function getDatagrid()
     {
 
-        $parameters = $this->container->get('request')->query->all();
+        $parameters = $this->request->query->all();
 
         $datagrid = $this->getBaseDatagrid($parameters);
         $datagrid->setMaxPerPage($this->maxPerPage);
 
-        if($this->isChild() && $this->getParentAssociationMapping()) {
+        if ($this->isChild() && $this->getParentAssociationMapping()) {
             $mapping = $this->getParentAssociationMapping();
-            $parameters[$mapping['fieldName']] = $this->container->get('request')->get($this->getParent()->getIdParameter());
+            $parameters[$mapping['fieldName']] = $this->request->get($this->getParent()->getIdParameter());
         }
 
         $datagrid->setValues($parameters);
@@ -1014,16 +1077,6 @@ abstract class Admin extends ContainerAware
         return $this->baseControllerName;
     }
 
-    public function getConfigurationPool()
-    {
-        return $this->container->get('sonata_admin.admin.pool');
-    }
-
-    public function getCode()
-    {
-        return $this->code;
-    }
-
     public function setLabel($label)
     {
         $this->label = $label;
@@ -1104,13 +1157,13 @@ abstract class Admin extends ContainerAware
      */
     public function getSubject()
     {
-        if($this->subject === null) {
+        if ($this->subject === null) {
 
-            $id = $this->container->get('request')->get($this->getIdParameter());
-            if(!is_numeric($id)) {
+            $id = $this->request->get($this->getIdParameter());
+            if (!is_numeric($id)) {
                 $this->subject = false;
             } else {
-                $this->subject = $this->getEntityManager()->find(
+                $this->subject = $this->getModelManager()->find(
                     $this->getClass(),
                     $id
                 );
@@ -1304,9 +1357,12 @@ abstract class Admin extends ContainerAware
      * @param Admin $child
      * @return void
      */
-    public function addChild($code, Admin $child)
+    public function addChild($code, AdminInterface $child)
     {
         $this->children[$code] = $child;
+        
+        $child->setCode($code);
+        $child->setBaseCodeRoute($this->getCode().'|'.$code);
         $child->setParent($this);
     }
 
@@ -1348,7 +1404,7 @@ abstract class Admin extends ContainerAware
      * @param Admin $parent
      * @return void
      */
-    public function setParent(Admin $parent)
+    public function setParent(AdminInterface $parent)
     {
         $this->parent = $parent;
     }
@@ -1370,7 +1426,7 @@ abstract class Admin extends ContainerAware
      */
     public function isChild()
     {
-        return $this->parent instanceof Admin;
+        return $this->parent instanceof AdminInterface;
     }
 
     /**
@@ -1434,7 +1490,7 @@ abstract class Admin extends ContainerAware
         $childAdmin = $this->getCurrentChildAdmin();
 
         if ($childAdmin) {
-            $id = $this->container->get('request')->get($this->getIdParameter());
+            $id = $this->request->get($this->getIdParameter());
 
             $child = $child->addChild(
                 (string) $this->getSubject(),
@@ -1445,7 +1501,7 @@ abstract class Admin extends ContainerAware
         
         } elseif ($this->isChild()) {
 
-            if($action != 'list') {
+            if ($action != 'list') {
                 $menu = $menu->addChild(
                     $this->trans(sprintf('link_%s_list', $this->getClassnameLabel())),
                     $this->generateUrl('list')
@@ -1456,7 +1512,7 @@ abstract class Admin extends ContainerAware
                 $this->trans(sprintf('link_%s_%s', $this->getClassnameLabel(), $action))
             );
 
-        } else if($action != 'list') {
+        } else if ($action != 'list') {
 
             $breadcrumbs = $child->getBreadcrumbsArray(
                 $this->trans(sprintf('link_%s_%s', $this->getClassnameLabel(), $action))
@@ -1501,8 +1557,8 @@ abstract class Admin extends ContainerAware
      */
     public function getCurrentChildAdmin()
     {
-        foreach($this->children as $children) {
-            if($children->getCurrentChild()) {
+        foreach ($this->children as $children) {
+            if ($children->getCurrentChild()) {
                 return $children;
             }
         }
@@ -1523,8 +1579,12 @@ abstract class Admin extends ContainerAware
     {
 
         $domain = $domain ?: $this->translationDomain;
-        
-        return $this->container->get('translator')->trans($id, $parameters, $domain, $locale);
+
+        if (!$this->translator) {
+            return $id;
+        }
+
+        return $this->translator->trans($id, $parameters, $domain, $locale);
     }
 
     /**
@@ -1547,4 +1607,104 @@ abstract class Admin extends ContainerAware
     {
         return $this->translationDomain;
     }
+
+    public function setTranslator(TranslatorInterface $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    public function getTranslator()
+    {
+        return $this->translator;
+    }
+
+    public function setRequest(Request $request)
+    {
+        $this->request = $request;
+    }
+
+    public function getRequest()
+    {
+        return $this->request;
+    }
+
+    public function setFormBuilder(FormBuilderInterface $formBuilder)
+    {
+        $this->formBuilder = $formBuilder;
+    }
+
+    public function getFormBuilder()
+    {
+        return $this->formBuilder;
+    }
+
+    public function setDatagridBuilder(DatagridBuilderInterface $datagridBuilder)
+    {
+        $this->datagridBuilder = $datagridBuilder;
+    }
+
+    public function getDatagridBuilder()
+    {
+        return $this->datagridBuilder;
+    }
+
+    public function setListBuilder(ListBuilderInterface $listBuilder)
+    {
+        $this->listBuilder = $listBuilder;
+    }
+
+    public function getListBuilder()
+    {
+        return $this->listBuilder;
+    }
+
+    public function setConfigurationPool(Pool $configurationPool)
+    {
+        $this->configurationPool = $configurationPool;
+    }
+
+    public function getConfigurationPool()
+    {
+        return $this->configurationPool;
+    }
+
+    public function setRouter(RouterInterface $router)
+    {
+        $this->router = $router;
+    }
+
+    public function getRouter()
+    {
+        return $this->router;
+    }
+
+    public function setModelManager($modelManager)
+    {
+        $this->modelManager = $modelManager;
+    }
+
+    public function getModelManager()
+    {
+        return $this->modelManager;
+    }
+
+    public function setCode($code)
+    {
+        $this->code = $code;
+    }
+
+    public function getCode()
+    {
+        return $this->code;
+    }
+
+    public function setBaseCodeRoute($baseCodeRoute)
+    {
+        $this->baseCodeRoute = $baseCodeRoute;
+    }
+
+    public function getBaseCodeRoute()
+    {
+        return $this->baseCodeRoute;
+    }
 }

+ 82 - 0
Admin/AdminInterface.php

@@ -0,0 +1,82 @@
+<?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\Admin;
+
+use Sonata\AdminBundle\Admin\Pool;
+use Sonata\AdminBundle\Builder\FormBuilderInterface;
+use Sonata\AdminBundle\Builder\ListBuilderInterface;
+use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
+    
+use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\HttpFoundation\Request;
+    
+interface AdminInterface
+{
+
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Builder\FormBuilderInterface $formBuilder
+     * @return void
+     */
+    function setFormBuilder(FormBuilderInterface $formBuilder);
+
+    /**
+     * @abstract
+     * @param ListBuilderInterface $listBuilder
+     * @return void
+     */
+    function setListBuilder(ListBuilderInterface $listBuilder);
+
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Builder\DatagridBuilderInterface $datagridBuilder
+     * @return void
+     */
+    function setDatagridBuilder(DatagridBuilderInterface $datagridBuilder);
+
+    /**
+     * @abstract
+     * @param \Symfony\Component\Translation\TranslatorInterface $translator
+     * @return void
+     */
+    function setTranslator(TranslatorInterface $translator);
+
+    /**
+     * @abstract
+     * @param \Symfony\Component\HttpFoundation\Request $request
+     * @return void
+     */
+    function setRequest(Request $request);
+
+    /**
+     * @abstract
+     * @param Pool $pool
+     * @return void
+     */
+    function setConfigurationPool(Pool $pool);
+
+
+    /**
+     * @abstract
+     * @param Doctrine\ORM\EntityManager|Doctrine\ODM\MongoDB\DocumentManager
+     * @return void
+     */
+    function setModelManager($manager);
+
+    /**
+     * @abstract
+     * @param \Symfony\Component\Routing\RouterInterface $router
+     * @return void
+     */
+    function setRouter(RouterInterface $router);
+}

+ 0 - 70
Admin/EntityAdmin.php

@@ -1,70 +0,0 @@
-<?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\Admin;
-
-
-abstract class EntityAdmin extends Admin
-{
-
-    /**
-     * return the entity manager
-     *
-     * @return EntityManager
-     */
-    public function getEntityManager()
-    {
-        return $this->container->get('doctrine.orm.default_entity_manager');
-    }
-
-    /**
-     * return the doctrine class metadata handled by the Admin instance
-     *
-     * @return ClassMetadataInfo the doctrine class metadata handled by the Admin instance
-     */
-    public function getClassMetaData()
-    {
-
-        return $this->getEntityManager()
-            ->getClassMetaData($this->getClass());
-    }
-
-    /**
-     * return the FormBuilder
-     *
-     * @return FormBuilder
-     */
-    public function getFormBuilder()
-    {
-        return $this->container->get('sonata_admin.builder.orm_form');
-    }
-
-    /**
-     * return the ListBuilder
-     *
-     * @return ListBuilder
-     */
-    public function getListBuilder()
-    {
-        return $this->container->get('sonata_admin.builder.orm_list');
-    }
-
-    /**
-     * return the DatagridBuilder
-     *
-     * @return DatagridBuilder
-     */
-    public function getDatagridBuilder()
-    {
-        return $this->container->get('sonata_admin.builder.orm_datagrid');
-    }
-
-}

+ 2 - 2
Admin/FieldDescription.php

@@ -437,11 +437,11 @@ class FieldDescription
      */
     public function mergeOption($name, array $options = array())
     {
-        if(!isset($this->options[$name])) {
+        if (!isset($this->options[$name])) {
             $this->options[$name] = array();
         }
 
-        if(!is_array($this->options[$name]))
+        if (!is_array($this->options[$name]))
         {
             throw new \RuntimeException(sprintf('The key `%s` does not point to an array value', $name));
         }

+ 53 - 119
Admin/Pool.php

@@ -16,27 +16,21 @@ class Pool
 {
     protected $container = null;
     
-    protected $configuration = array();
+    protected $adminServiceIds = array();
 
-    public function addConfiguration($code, $configuration)
-    {
-        $configuration['code'] = $code;
-        
-        $this->configuration[$code] = $configuration;
-    }
+    protected $adminGroups = array();
 
+    protected $adminClasses = array();
+    
     public function getGroups()
     {
+        $groups = $this->adminGroups;
 
-        $groups = array();
-
-        foreach ($this->configuration as $configuration) {
+        foreach ($this->adminGroups as $name => $adminGroup) {
 
-            if (!isset($groups[$configuration['group']])) {
-                $groups[$configuration['group']] = array();
+            foreach ($adminGroup as $id => $options) {
+                $groups[$name][$id] = $this->getInstance($id);
             }
-
-            $groups[$configuration['group']][$configuration['code']] = $this->getInstance($configuration['code']);
         }
 
         return $groups;
@@ -44,44 +38,23 @@ class Pool
     
     public function getDashboardGroups()
     {
+        $groups = $this->adminGroups;
 
-        $groups = array();
+        foreach ($this->adminGroups as $name => $adminGroup) {
 
-        foreach ($this->configuration as $configuration) {
-            
-            if($configuration['options']['show_in_dashboard']) {
-                if (!isset($groups[$configuration['group']])) {
-                    $groups[$configuration['group']] = array();
-                }
+            foreach ($adminGroup as $id => $options) {
 
-                $groups[$configuration['group']][$configuration['code']] = $this->getInstance($configuration['code']);
-            }
-        }
+                if (!$options['show_in_dashboard']) {
+                    unset($groups[$name][$id]);
+                    continue;
 
-        return $groups;
-    }
+                }
 
-    /**
-     * The admin classes are lazy loaded to avoid overhead
-     *
-     * @throws RuntimeException
-     * @param  $name
-     * @return
-     */
-    public function getAdminByControllerName($name)
-    {
-        $configuration_code = false;
-        foreach ($this->configuration as $code => $configuration) {
-            if ($configuration['controller'] == $name) {
-                $configuration_code = $code;
+                $groups[$name][$id] = $this->container->get($id);
             }
         }
 
-        if (!$configuration_code) {
-            return null;
-        }
-
-        return $this->getInstance($configuration_code);
+        return $groups;
     }
 
     /**
@@ -93,58 +66,34 @@ class Pool
     public function getAdminByClass($class)
     {
 
-        $configuration_code = false;
-
-        foreach ($this->configuration as $code => $configuration) {
-
-            if ($configuration['entity'] == $class) {
-                $configuration_code = $code;
-                break;
-            }
-        }
-
-        if (!$configuration_code) {
+        if (!isset($this->adminClasses[$class])) {
             return null;
         }
 
-        return $this->getInstance($code);
+        return $this->getInstance($this->adminClasses[$class]);
     }
 
     /**
-     * return the admin related to the given $actionName
+     * return an admin clas by its Admin code
+     * ie : sonata.news.admin.post|sonata.news.admin.comment => return the child class of post
      *
-     * @param string $actionName
+     * @param string $adminCode
      * @return Admin|null
      */
-    public function getAdminByActionName($actionName)
+    public function getAdminByAdminCode($adminCode)
     {
-        $codes = explode('.', $actionName);
-
-        $instance = false;
-        foreach ($codes as $pos => $code) {
-            if ($pos == 0) {
-                $instance = $this->getInstance($code);
-            } else if($instance->hasChildren()) {
-                if(!$instance->hasChild($code)) {
-                    break;
-                }
-
-                $instance = $instance->getChild($code);
 
-                if(!$instance instanceof Admin) {
-                    throw new \RuntimeException(sprintf('unable to retrieve the child admin related to the actionName : `%s`', $actionName));
-                }
-                
-            } else {
-                break;
+        $codes = explode('|', $adminCode);
+        $admin = false;
+        foreach ($codes as $code) {
+            if ($admin == false) {
+                $admin = $this->getInstance($code);
+            } else if ($admin->hasChild($code)) {
+                $admin = $admin->getChild($code);
             }
         }
 
-        if(!$instance instanceof Admin) {
-            throw new \RuntimeException(sprintf('unable to retrieve the admin related to the actionName : `%s`', $actionName));
-        }
-
-        return $instance;
+        return $admin;
     }
 
     /**
@@ -154,63 +103,48 @@ class Pool
      * @param $code
      * @return
      */
-    public function getInstance($code)
+    public function getInstance($id)
     {
-        if(!isset($this->configuration[$code])) {
-            throw new \RuntimeException(sprintf('The code `%s` does not exist', $code));
-        }
-
-        return $this->getInstanceFromConfiguration($code, $this->configuration[$code]);
+        return $this->container->get($id);
     }
 
-    protected function getInstanceFromConfiguration($code, $configuration)
+    public function setContainer($container)
     {
-        $class = $configuration['class'];
-        
-        $instance = new $class($code, $this->getContainer(), $configuration['entity'], $configuration['controller']);
-        $instance->setLabel($configuration['label']);
-
-        if(isset($configuration['children'])) {
-            foreach($configuration['children'] as $code => $child) {
-                $instance->addChild($code, $this->getInstanceFromConfiguration($code, $child));
-            }
-        }
+        $this->container = $container;
+    }
 
-        return $instance;
+    public function getContainer()
+    {
+        return $this->container;
     }
 
-    /**
-     * return a group of admin instance
-     *
-     * @return array
-     */
-    public function getInstances()
+    public function setAdminGroups($adminGroups)
     {
-        $instances = array();
-        foreach ($this->configuration as $code => $configuration) {
-            $instances[] = $this->getInstance($code);
-        }
+        $this->adminGroups = $adminGroups;
+    }
 
-        return $instances;
+    public function getAdminGroups()
+    {
+        return $this->adminGroups;
     }
 
-    public function setConfiguration(array $configuration = array())
+    public function setAdminServiceIds($adminServiceIds)
     {
-        $this->configuration = $configuration;
+        $this->adminServiceIds = $adminServiceIds;
     }
 
-    public function getConfiguration()
+    public function getAdminServiceIds()
     {
-        return $this->configuration;
+        return $this->adminServiceIds;
     }
 
-    public function setContainer($container)
+    public function setAdminClasses($adminClasses)
     {
-        $this->container = $container;
+        $this->adminClasses = $adminClasses;
     }
 
-    public function getContainer()
+    public function getAdminClasses()
     {
-        return $this->container;
+        return $this->adminClasses;
     }
 }

+ 3 - 3
Builder/DatagridBuilder.php

@@ -55,7 +55,7 @@ class DatagridBuilder implements DatagridBuilderInterface
             $fieldDescription->setAssociationMapping($admin->getClassMetaData()->associationMappings[$fieldDescription->getName()]);
         }
 
-        if(!$fieldDescription->getType()) {
+        if (!$fieldDescription->getType()) {
             throw new \RuntimeException(sprintf('Please define a type for field `%s` in `%s`', $fieldDescription->getName(), get_class($admin)));
         }
 
@@ -94,7 +94,7 @@ class DatagridBuilder implements DatagridBuilderInterface
     public function getFilterFieldClass(FieldDescription $fieldDescription)
     {
 
-        if($fieldDescription->getOption('filter_field_widget', false)) {
+        if ($fieldDescription->getOption('filter_field_widget', false)) {
 
             $class = $fieldDescription->getOption('filter_field_widget', false);
         } else {
@@ -111,7 +111,7 @@ class DatagridBuilder implements DatagridBuilderInterface
 
     public function getChoices(FieldDescription $fieldDescription)
     {
-        $targets = $fieldDescription->getAdmin()->getEntityManager()
+        $targets = $fieldDescription->getAdmin()->getModelManager()
             ->createQueryBuilder()
             ->select('t')
             ->from($fieldDescription->getTargetEntity(), 't')

+ 7 - 7
Builder/FormBuilder.php

@@ -94,7 +94,7 @@ class FormBuilder implements FormBuilderInterface
 
         // create the transformer
         $transformer = new ArrayToObjectTransformer(array(
-            'em'        => $fieldDescription->getAdmin()->getEntityManager(),
+            'em'        => $fieldDescription->getAdmin()->getModelManager(),
             'className' => $fieldDescription->getTargetEntity()
         ));
 
@@ -139,7 +139,7 @@ class FormBuilder implements FormBuilderInterface
 
             $class = array_key_exists($fieldDescription->getType(), $this->formFieldClasses) ? $this->formFieldClasses[$fieldDescription->getType()] : false;
 
-        } else if($fieldDescription->getOption('form_field_widget', false)) {
+        } else if ($fieldDescription->getOption('form_field_widget', false)) {
 
             $class = $fieldDescription->getOption('form_field_widget', false);
 
@@ -188,7 +188,7 @@ class FormBuilder implements FormBuilderInterface
         // TODO : remove this once an EntityField will be available
         $options = array(
             'value_transformer' => new EntityToIDTransformer(array(
-                'em'        => $fieldDescription->getAdmin()->getEntityManager(),
+                'em'        => $fieldDescription->getAdmin()->getModelManager(),
                 'className' => $fieldDescription->getTargetEntity()
             ))
         );
@@ -279,7 +279,7 @@ class FormBuilder implements FormBuilderInterface
 
         $options = array(
             'value_transformer' => new EntityToIDTransformer(array(
-                'em'        =>  $fieldDescription->getAdmin()->getEntityManager(),
+                'em'        =>  $fieldDescription->getAdmin()->getModelManager(),
                 'className' =>  $fieldDescription->getTargetEntity()
             ))
         );
@@ -351,7 +351,7 @@ class FormBuilder implements FormBuilderInterface
                 $class   = $this->getFormFieldClass($fieldDescription);
 
                 // there is no way to use a custom widget with the FieldFactory
-                if($class) {
+                if ($class) {
                     $field = new $class(
                         $fieldDescription->getFieldName(),
                         $fieldDescription->getOption('form_field_options', array())
@@ -389,7 +389,7 @@ class FormBuilder implements FormBuilderInterface
             $fieldDescription->setAssociationMapping($admin->getClassMetaData()->associationMappings[$fieldDescription->getName()]);
         }
 
-        if(!$fieldDescription->getType()) {
+        if (!$fieldDescription->getType()) {
             throw new \RuntimeException(sprintf('Please define a type for field `%s` in `%s`', $fieldDescription->getName(), get_class($admin)));
         }
 
@@ -419,7 +419,7 @@ class FormBuilder implements FormBuilderInterface
         if ($fieldDescription->getType() == ClassMetadataInfo::ONE_TO_MANY) {
             $fieldDescription->setTemplate('SonataAdminBundle:CRUD:edit_one_to_many.html.twig');
 
-            if($fieldDescription->getOption('edit') == 'inline' && !$fieldDescription->getOption('widget_form_field')) {
+            if ($fieldDescription->getOption('edit') == 'inline' && !$fieldDescription->getOption('widget_form_field')) {
                 $fieldDescription->setOption('widget_form_field', 'Bundle\\Sonata\\AdminBundle\\Form\\EditableFieldGroup');
             }
 

+ 26 - 0
Builder/FormBuilderInterface.php

@@ -22,11 +22,37 @@ use Symfony\Component\Form\FieldFactory\FieldFactoryInterface;
 interface FormBuilderInterface
 {
 
+    /**
+     * @abstract
+     * @param \Symfony\Component\Form\FieldFactory\FieldFactoryInterface $fieldFactory
+     * @param \Symfony\Component\Form\FormContextInterface $formContext
+     * @param \Symfony\Component\Validator\ValidatorInterface $validator
+     */
     function __construct(FieldFactoryInterface $fieldFactory, FormContextInterface $formContext, ValidatorInterface $validator);
 
+    /**
+     * @abstract
+     * @param \Symfony\Component\Form\Form $form
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @return void
+     */
     function addField(Form $form, FieldDescription $fieldDescription);
 
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Admin\Admin $admin
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @param array $options
+     * @return void
+     */
     function fixFieldDescription(Admin $admin, FieldDescription $fieldDescription, array $options = array());
 
+    /**
+     * @abstract
+     * @param  $name
+     * @param  $object
+     * @param array $options
+     * @return void
+     */
     function getBaseForm($name, $object, array $options = array());
 }

+ 1 - 1
Builder/ListBuilder.php

@@ -54,7 +54,7 @@ class ListBuilder implements ListBuilderInterface
             $fieldDescription->setAssociationMapping($admin->getClassMetaData()->associationMappings[$fieldDescription->getName()]);
         }
 
-        if(!$fieldDescription->getType()) {
+        if (!$fieldDescription->getType()) {
             throw new \RuntimeException(sprintf('Please define a type for field `%s` in `%s`', $fieldDescription->getName(), get_class($admin)));
         }        
 

+ 18 - 1
Builder/ListBuilderInterface.php

@@ -18,10 +18,27 @@ use Sonata\AdminBundle\Datagrid\ListCollection;
 
 interface ListBuilderInterface
 {
+    /**
+     * @abstract
+     * @param array $options
+     * @return void
+     */
     function getBaseList(array $options = array());
 
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Datagrid\ListCollection $list
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @return void
+     */
     function addField(ListCollection $list, FieldDescription $fieldDescription);
 
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Admin\Admin $admin
+     * @param \Sonata\AdminBundle\Admin\FieldDescription $fieldDescription
+     * @param array $options
+     * @return void
+     */
     function fixFieldDescription(Admin $admin, FieldDescription $fieldDescription, array $options = array());
-
 }

+ 12 - 14
Controller/CRUDController.php

@@ -42,7 +42,7 @@ class CRUDController extends Controller
         // fake content-type so browser does not show the download popup when this
         // response is rendered through an iframe (used by the jquery.form.js plugin)
         //  => don't know yet if it is the best solution
-        if($this->get('request')->get('_xml_http_request')
+        if ($this->get('request')->get('_xml_http_request')
            && strpos($this->get('request')->headers->get('Content-Type'), 'multipart/form-data') === 0) {
             $headers['Content-Type'] = 'text/plain';
         } else {
@@ -76,21 +76,19 @@ class CRUDController extends Controller
 
     public function configure()
     {
-        $actionName = $this->container->get('request')->get('_bab_action');
-        
-        $this->admin = $this->container
-            ->get('sonata_admin.admin.pool')
-            ->getAdminByActionName($actionName);
+        $adminCode = $this->container->get('request')->get('_sonata_admin');
+
+        $this->admin = $this->container->get('sonata_admin.admin.pool')->getAdminByAdminCode($adminCode);
 
-        if(!$this->admin) {
+        if (!$this->admin) {
             throw new \RuntimeException(sprintf('Unable to find the admin class related to the current controller (%s)', get_class($this)));
         }
 
-        if($this->container->get('request')->get('uniqid')) {
+        if ($this->container->get('request')->get('uniqid')) {
             $this->admin->setUniqid($this->container->get('request')->get('uniqid'));
         }
 
-        if($this->admin->isChild()) {
+        if ($this->admin->isChild()) {
             $this->admin->setCurrentChild(true);
         }
     }
@@ -137,7 +135,7 @@ class CRUDController extends Controller
      */
     public function batchActionDelete($idx)
     {
-        $em = $this->admin->getEntityManager();
+        $em = $this->admin->getModelManager();
 
         $query_builder = $em->createQueryBuilder();
         $objects = $query_builder
@@ -246,8 +244,8 @@ class CRUDController extends Controller
                 $this->admin->preUpdate($object);
             }
 
-            $this->admin->getEntityManager()->persist($object);
-            $this->admin->getEntityManager()->flush($object);
+            $this->admin->getModelManager()->persist($object);
+            $this->admin->getModelManager()->flush($object);
 
             if ($action == 'create') {
                 $this->admin->postInsert($object);
@@ -358,7 +356,7 @@ class CRUDController extends Controller
      */
     public function getSideMenu($action)
     {
-        if($this->admin->isChild()) {
+        if ($this->admin->isChild()) {
             return $this->admin->getParent()->getSideMenu($action, $this->admin);
         }
 
@@ -372,7 +370,7 @@ class CRUDController extends Controller
     public function getBreadcrumbs($action)
     {
         
-        if($this->admin->isChild()) {
+        if ($this->admin->isChild()) {
             return $this->admin->getParent()->getBreadcrumbs($action);
         }
 

+ 3 - 3
Controller/CoreController.php

@@ -58,7 +58,7 @@ class CoreController extends Controller
            ->get('sonata_admin.admin.pool')
            ->getInstance($code);
 
-        if($this->container->get('request')->get('uniqid')) {
+        if ($this->container->get('request')->get('uniqid')) {
             $admin->setUniqid($this->container->get('request')->get('uniqid'));
         }
 
@@ -129,7 +129,7 @@ class CoreController extends Controller
         // retrieve the posted data
         $data = $this->get('request')->get($form->getName());
 
-        if(!isset($data[$field_element->getKey()])) {
+        if (!isset($data[$field_element->getKey()])) {
             $data[$field_element->getKey()] = array();
         }
 
@@ -177,7 +177,7 @@ class CoreController extends Controller
         $uniqid     = $uniqid   ?: $this->get('request')->get('uniqid');
 
         $admin  = $this->container->get('sonata_admin.admin.pool')->getInstance($code);
-        if($uniqid) {
+        if ($uniqid) {
             $admin->setUniqid($uniqid);
         }
         

+ 129 - 0
DependencyInjection/AddDependencyCallsPass.php

@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of the Sonata project.
+ *
+ * (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\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Add all dependencies to the Admin class, this avoid to write to many lines
+ * in the configuration files.
+ *
+ * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ */
+class AddDependencyCallsPass implements CompilerPassInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+
+        $groups = $admins = $classes = array();
+
+        //
+        $pool = $container->getDefinition('sonata_admin.admin.pool');
+
+        foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $attributes) {
+
+            $definition = $container->getDefinition($id);
+            $calls = array(array('setCode', array($id))) + $definition->getMethodCalls();
+            $definition->setMethodCalls($calls);
+            $this->applyDefaults($definition, $attributes);
+
+            $arguments = $definition->getArguments();
+            if (preg_match('/%(.*)%/', $arguments[0], $matches)) {
+                $class = $container->getParameter($matches[1]);
+            }
+
+            $admins[] = $id;
+            $classes[$class] = $id;
+
+            $group_name = isset($attributes[0]['group']) ? $attributes[0]['group'] : 'default';
+
+            if (!isset($groups[$group_name])) {
+                $groups[$group_name] = array();
+            }
+
+            $groups[$group_name][$id] = array(
+                'show_in_dashboard' => (boolean)(isset($attributes[0]['show_in_dashboard']) ? $attributes[0]['show_in_dashboard'] : true)
+            );
+        }
+
+        $pool->addMethodCall('setAdminServiceIds', array($admins));
+        $pool->addMethodCall('setAdminGroups', array($groups));
+        $pool->addMethodCall('setAdminClasses', array($classes));
+
+        //
+        $routeLoader = $container->getDefinition('sonata_admin.route_loader');
+        $routeLoader->addArgument($admins);
+    }
+
+    /**
+     * Apply the default values required by the AdminInterface to the Admin service definition
+     *
+     * @param \Symfony\Component\DependencyInjection\Definition $definition
+     * @param array $attributes
+     * @return \Symfony\Component\DependencyInjection\Definition
+     */
+    public function applyDefaults(Definition $definition, array $attributes = array())
+    {
+
+        $definition->setScope(ContainerInterface::SCOPE_PROTOTYPE);
+
+        $manager_type = $attributes[0]['manager_type'];
+
+        if (!$definition->hasMethodCall('setModelManager')) {
+            $definition->addMethodCall('setModelManager', array(new Reference(sprintf('doctrine.%s.default_entity_manager', $manager_type))));
+        }
+
+        if (!$definition->hasMethodCall('setFormBuilder')) {
+            $definition->addMethodCall('setFormBuilder', array(new Reference(sprintf('sonata_admin.builder.%s_form', $manager_type))));
+        }
+
+        if (!$definition->hasMethodCall('setListBuilder')) {
+            $definition->addMethodCall('setListBuilder', array(new Reference(sprintf('sonata_admin.builder.%s_list', $manager_type))));
+        }
+
+        if (!$definition->hasMethodCall('setDatagridBuilder')) {
+            $definition->addMethodCall('setDatagridBuilder', array(new Reference(sprintf('sonata_admin.builder.%s_datagrid', $manager_type))));
+        }
+
+        if (!$definition->hasMethodCall('setRequest')) {
+            $definition->addMethodCall('setRequest', array(new Reference('request')));
+        }
+
+        if (!$definition->hasMethodCall('setTranslator')) {
+            $definition->addMethodCall('setTranslator', array(new Reference('translator')));
+        }
+
+        if (!$definition->hasMethodCall('setConfigurationPool')) {
+            $definition->addMethodCall('setConfigurationPool', array(new Reference('sonata_admin.admin.pool')));
+        }
+
+        if (!$definition->hasMethodCall('setRouter')) {
+            $definition->addMethodCall('setRouter', array(new Reference('router')));
+        }
+
+        if (!$definition->hasMethodCall('setLabel')) {
+            $label = isset($attributes[0]['label']) ? $attributes[0]['label'] : '-';
+            $definition->addMethodCall('setLabel', array($label));
+        }
+
+        $definition->addMethodCall('configure');
+        
+        return $definition;
+    }
+}

+ 0 - 26
DependencyInjection/Configuration.php

@@ -37,32 +37,6 @@ class Configuration
         $rootNode = $treeBuilder->root('sonata_admin', 'array');
 
         $rootNode
-            ->arrayNode('entities')
-                ->isRequired()
-                ->useAttributeAsKey('entity_name')
-                ->requiresAtLeastOneElement()
-                ->prototype('array')
-                    ->scalarNode('label')->cannotBeEmpty()->defaultValue('default')->end()
-                    ->scalarNode('group')->cannotBeEmpty()->defaultValue('default')->end()
-                    ->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
-                    ->scalarNode('entity')->isRequired()->cannotBeEmpty()->end()
-                    ->scalarNode('controller')->isRequired()->end()
-                    ->arrayNode('children')
-                        ->useAttributeAsKey('entity_name')
-                        ->prototype('array')
-                            ->scalarNode('label')->cannotBeEmpty()->defaultValue('default')->end()
-                            ->scalarNode('group')->cannotBeEmpty()->defaultValue('default')->end()
-                            ->scalarNode('class')->isRequired()->cannotBeEmpty()->end()
-                            ->scalarNode('entity')->isRequired()->cannotBeEmpty()->end()
-                            ->scalarNode('controller')->isRequired()->end()
-                        ->end()
-                    ->end()
-                    ->arrayNode('options')
-                        ->addDefaultsIfNotSet()
-                        ->booleanNode('show_in_dashboard')->defaultTrue()->end()
-                    ->end()
-                ->end()
-            ->end()
             ->arrayNode('templates')
                 ->scalarNode('layout')->cannotBeEmpty()->end()
                 ->scalarNode('ajax')->cannotBeEmpty()->end()

+ 4 - 27
DependencyInjection/SonataAdminExtension.php

@@ -31,7 +31,7 @@ use Symfony\Component\Finder\Finder;
  */
 class SonataAdminExtension extends Extension
 {    
-	protected $configNamespaces = array(
+    protected $configNamespaces = array(
         'templates' => array(
             'layout',
             'ajax'
@@ -39,27 +39,7 @@ class SonataAdminExtension extends Extension
     );
     
     /**
-     * Parses the configuration to setup the admin controllers and setup routing
-     * information. Format is following:
      * 
-     * sonata_admin:
-     *    entities:
-     *        post:
-     *           label:      post
-     *           group:      posts
-     *           class:      Funsational\SimpleBlogBundle\Admin\Entity\PostAdmin
-     *           entity:     Funsational\SimpleBlogBundle\Entity\Post
-     *           controller: Funsational\SimpleBlogBundle\Controller\PostAdminController
-     *           children:
-     *               comment:
-     *                  label:      comment
-     *                  group:      comments
-     *                  class:      Funsational\SimpleBlogBundle\Admin\Entity\CommentAdmin
-     *                  entity:     Funsational\SimpleBlogBundle\Entity\Comment
-     *                  controller: Funsational\SimpleBlogBundle\Controller\CommentAdminController
-     *          options:
-     *              show_in_dashboard: true
-     *
      * @param array            $config    An array of configuration settings
      * @param ContainerBuilder $container A ContainerBuilder instance
      */
@@ -95,14 +75,11 @@ class SonataAdminExtension extends Extension
         // registers crud action
         $definition = new Definition('Sonata\AdminBundle\Admin\Pool');
         $definition->addMethodCall('setContainer', array(new Reference('service_container')));
-        
-        foreach ($config['entities'] as $code => $configuration) {
-            $definition->addMethodCall('addConfiguration', array($code, $configuration));
-        }
-
         $container->setDefinition('sonata_admin.admin.pool', $definition);
 
-        $definition = new Definition('Sonata\AdminBundle\Route\AdminPoolLoader', array(new Reference('sonata_admin.admin.pool')));
+        $definition = new Definition('Sonata\AdminBundle\Route\AdminPoolLoader', array(
+            new Reference('sonata_admin.admin.pool'),
+        ));
         $definition->addTag('routing.loader');
 
         $container->setDefinition('sonata_admin.route_loader', $definition);

+ 2 - 2
Form/EditableFieldGroup.php

@@ -45,7 +45,7 @@ class EditableFieldGroup extends Form
         $iterator = new \RecursiveIteratorIterator($iterator);
 
         foreach ($iterator as $field) {
-            if($field->getKey() == '_delete') {
+            if ($field->getKey() == '_delete') {
                 continue;
             }
 
@@ -62,7 +62,7 @@ class EditableFieldGroup extends Form
         $iterator = new \RecursiveIteratorIterator($iterator);
 
         foreach ($iterator as $field) {
-            if($field->getKey() == '_delete') {
+            if ($field->getKey() == '_delete') {
                 continue;
             }
 

+ 1 - 1
Form/FormMapper.php

@@ -88,7 +88,7 @@ class FormMapper
         $fieldDescription->mergeOption('form_field_options', $fieldOptions);
 
         // nothing to build as a Field is provided
-        if($field) {
+        if ($field) {
             return $this->form->add($field);
         }
 

+ 2 - 2
Resources/config/routing/sonata_admin.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
-<routes xmlns="http://www.symfony-project.org/schema/routing"
+<routes xmlns="http://symfony.com/schema/routing"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.symfony-project.org/schema/routing http://www.symfony-project.org/schema/routing/routing-1.0.xsd">
+    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
 
     <route id="sonata_admin_dashboard" pattern="/dashboard">
         <default key="_controller">SonataAdminBundle:Core:dashboard</default>

+ 2 - 2
Resources/config/templates.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
-<container xmlns="http://www.symfony-project.org/schema/dic/services"
+<container xmlns="http://symfony.com/schema/dic/services"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-           xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
+           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
 
     <parameters>
         <parameter key="sonata_admin.templates.layout">SonataAdminBundle::standard_layout.html.twig</parameter>

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

@@ -23,7 +23,7 @@ file that was distributed with this source code.
 {% block side_menu %}{% if side_menu %}{{ side_menu.render|raw }}{% endif %}{% endblock %}
 
 {% block form %}
-    <form action="{{ admin.generateUrl('update', {'id': object.id}) }}"{% if form.isMultipart %} enctype="multipart/form-data"{% endif %} method="POST">
+    <form action="{{ admin.generateUrl('update', {'id': object.id, 'uniqid': admin.uniqid}) }}"{% if form.isMultipart %} enctype="multipart/form-data"{% endif %} method="POST">
 
         {{ form_hidden(form) }}
         

+ 4 - 4
Resources/views/CRUD/edit_many_association_script.html.twig

@@ -35,7 +35,7 @@ This code manage the many-to-[one|many] association field popup
         var element = jQuery(this).parents('#field_dialog_{{ field_element.id }} td.sonata-ba-list-field');
 
         // the user does does click on a row column
-        if(element.length == 0) {
+        if (element.length == 0) {
             // make a recursive call (ie: reset the filter)
             jQuery.ajax({
                 type: 'GET',
@@ -177,7 +177,7 @@ This code manage the many-to-[one|many] association field popup
             return;
         }
 
-        if(element.hasClass('sonata-ba-action')) {
+        if (element.hasClass('sonata-ba-action')) {
             Admin.log('[{{ field_element.id }}|field_dialog_form_action] reserved action stop catch all events');
             return;
         }
@@ -198,7 +198,7 @@ This code manage the many-to-[one|many] association field popup
             success: function(data) {
 
                 Admin.log('[{{ field_element.id }}|field_dialog_form_action] ajax success');
-                if(typeof data == 'string') {
+                if (typeof data == 'string') {
                     field_dialog_{{ field_element.id }}.html(data);
                     return;
                 };
@@ -255,7 +255,7 @@ This code manage the many-to-[one|many] association field popup
 
     function initialize_popup_{{ field_element.id }}() {
         // initialize component
-        if(!field_dialog_{{ field_element.id }}) {
+        if (!field_dialog_{{ field_element.id }}) {
             field_dialog_{{ field_element.id }} = jQuery("#field_dialog_{{ field_element.id }}");
 
             // move the dialog as a child of the root element, nested form breaks html ...

+ 13 - 5
Route/AdminPoolLoader.php

@@ -26,9 +26,15 @@ class AdminPoolLoader extends FileLoader
      */
     protected $pool;
 
-    public function __construct(Pool $pool)
+    /**
+     * @var array
+     */
+    protected $adminServiceIds = array();
+
+    public function __construct(Pool $pool, $adminServiceIds)
     {
         $this->pool = $pool;
+        $this->adminServiceIds = $adminServiceIds;
     }
 
     function supports($resource, $type = null)
@@ -43,16 +49,18 @@ class AdminPoolLoader extends FileLoader
     function load($resource, $type = null)
     {
         $collection = new RouteCollection;
-        foreach ($this->pool->getInstances() as $admin) {
+        foreach ($this->adminServiceIds as $id) {
+
+            $admin = $this->pool->getInstance($id);
+
             foreach ($admin->getUrls() as $action => $configuration) {
 
                 $defaults = isset($configuration['defaults'])       ? $configuration['defaults'] : array();
 
-                if(!isset($defaults['_controller'])) {
+                if (!isset($defaults['_controller'])) {
                     $defaults['_controller'] = sprintf('%s:%s', $admin->getBaseControllerName(), $this->actionify($action));
                 }
-                $defaults['_bab_action'] = sprintf('%s.%s', $admin->getCode(), $action);
-
+                
                 $collection->add($configuration['name'], new Route(
                     $configuration['pattern'],
                     $defaults,

+ 8 - 0
SonataAdminBundle.php

@@ -11,8 +11,16 @@
 namespace Sonata\AdminBundle;
 
 use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Sonata\AdminBundle\DependencyInjection\AddDependencyCallsPass;
 
 class SonataAdminBundle extends Bundle
 {
 
+    public function build(ContainerBuilder $container)
+    {
+        parent::build($container);
+
+        $container->addCompilerPass(new AddDependencyCallsPass());
+    }
 }

+ 1 - 1
Twig/Extension/SonataAdminExtension.php

@@ -97,7 +97,7 @@ class SonataAdminExtension extends \Twig_Extension
     public function getValueFromFieldDescription($object, FieldDescription $fieldDescription, array $params = array())
     {
 
-        if(isset($params['loop']) && $object instanceof \ArrayAccess) {
+        if (isset($params['loop']) && $object instanceof \ArrayAccess) {
             $object = $object[$params['loop']['index0']];
         }