Sfoglia il codice sorgente

Add extension feature (allows to alter an Admin Instance from an external service)

Thomas Rabaix 13 anni fa
parent
commit
f6380b316f

+ 42 - 1
Admin/Admin.php

@@ -342,6 +342,8 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
 
 
     protected $filterTheme = array('SonataAdminBundle:Form:filter_admin_fields.html.twig');
     protected $filterTheme = array('SonataAdminBundle:Form:filter_admin_fields.html.twig');
 
 
+    protected $extensions = array();
+
     /**
     /**
      * This method can be overwritten to tweak the form construction, by default the form
      * This method can be overwritten to tweak the form construction, by default the form
      * is built by reading the FieldDescription
      * is built by reading the FieldDescription
@@ -416,6 +418,20 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
 
 
     }
     }
 
 
+    /**
+     * @param \Sonata\AdminBundle\Validator\ErrorElement $errorElement
+     * @param $object
+     * @return void
+     */
+    public function doValidate(ErrorElement $errorElement, $object)
+    {
+        $this->validate($errorElement, $object);
+
+        foreach ($this->extensions as $extension) {
+            $extension->validate($this, $errorElement, $object);
+        }
+    }
+
     /**
     /**
      * @param string $code
      * @param string $code
      * @param string $class
      * @param string $class
@@ -538,6 +554,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
         }
         }
 
 
         $this->configureListFields($mapper);
         $this->configureListFields($mapper);
+
+        foreach($this->extensions as $extension) {
+            $extension->configureListFields($mapper);
+        }
     }
     }
 
 
     /**
     /**
@@ -597,6 +617,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
                 'operator_type' => 'hidden'
                 'operator_type' => 'hidden'
             ));
             ));
         }
         }
+
+        foreach($this->extensions as $extension) {
+            $extension->configureDatagridFilters($mapper);
+        }
     }
     }
 
 
     /**
     /**
@@ -807,6 +831,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
 
 
         $this->configureRoutes($collection);
         $this->configureRoutes($collection);
 
 
+        foreach($this->extensions as $extension) {
+            $extension->configureRoutes($this, $collection);
+        }
+
         $this->routes = $collection;
         $this->routes = $collection;
     }
     }
 
 
@@ -962,7 +990,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
         $metadata = $this->validator->getMetadataFactory()->getClassMetadata($this->class);
         $metadata = $this->validator->getMetadataFactory()->getClassMetadata($this->class);
         $metadata->addConstraint(new \Sonata\AdminBundle\Validator\Constraints\InlineConstraint(array(
         $metadata->addConstraint(new \Sonata\AdminBundle\Validator\Constraints\InlineConstraint(array(
             'service' => $this,
             'service' => $this,
-            'method'  => 'validate'
+            'method'  => 'doValidate'
         )));
         )));
 
 
         $this->formOptions['data_class'] = $this->getClass();
         $this->formOptions['data_class'] = $this->getClass();
@@ -986,6 +1014,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
         $mapper = new FormMapper($this->getFormContractor(), $formBuilder, $this);
         $mapper = new FormMapper($this->getFormContractor(), $formBuilder, $this);
 
 
         $this->configureFormFields($mapper);
         $this->configureFormFields($mapper);
+
+        foreach($this->extensions as $extension) {
+            $extension->configureFormFields($mapper);
+        }
     }
     }
 
 
     /**
     /**
@@ -1071,6 +1103,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
 
 
         $this->configureSideMenu($menu, $action, $childAdmin);
         $this->configureSideMenu($menu, $action, $childAdmin);
 
 
+        foreach ($this->extensions as $extension) {
+            $extension->configureSideMenu($this, $menu, $action, $childAdmin);
+        }
+
         $this->menu = $menu;
         $this->menu = $menu;
     }
     }
 
 
@@ -2034,4 +2070,9 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     {
     {
         return $this->filterTheme;
         return $this->filterTheme;
     }
     }
+
+    public function addExtension(AdminExtensionInterface $extension)
+    {
+        $this->extensions[] = $extension;
+    }
 }
 }

+ 79 - 0
Admin/AdminExtensionInterface.php

@@ -0,0 +1,79 @@
+<?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\Form\FormMapper;
+use Sonata\AdminBundle\Datagrid\ListMapper;
+use Sonata\AdminBundle\Datagrid\DatagridMapper;
+use Sonata\AdminBundle\Show\ShowMapper;
+use Sonata\AdminBundle\Route\RouteCollection;
+use Sonata\AdminBundle\Validator\ErrorElement;
+use Sonata\AdminBundle\Admin\AdminInterface;
+
+use Knp\Bundle\MenuBundle\MenuItem;
+
+interface AdminExtensionInterface
+{
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Form\FormMapper $form
+     * @return void
+     */
+    function configureFormFields(FormMapper $form);
+
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Datagrid\ListMapper $list
+     * @return void
+     */
+    function configureListFields(ListMapper $list);
+
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Datagrid\DatagridMapper $filter
+     * @return void
+     */
+    function configureDatagridFilters(DatagridMapper $filter);
+
+    /**
+     * @abstract
+     * @param \Sonata\AdminBundle\Show\ShowMapper $filter
+     * @return void
+     */
+    function configureShowField(ShowMapper $filter);
+
+    /**
+     * @abstract
+     * @param Admin $admin
+     * @param \Sonata\AdminBundle\Route\RouteCollection $collection
+     * @return void
+     */
+    function configureRoutes(Admin $admin, RouteCollection $collection);
+
+    /**
+     * @abstract
+     * @param Admin $admin
+     * @param \Knp\Bundle\MenuBundle\MenuItem $menu
+     * @param string $action
+     * @param null|Admin $childAdmin
+     * @return void
+     */
+    function configureSideMenu(Admin $admin, MenuItem $menu, $action, Admin $childAdmin = null);
+
+    /**
+     * @abstract
+     * @param Admin $admin
+     * @param \Sonata\AdminBundle\Validator\ErrorElement $errorElement
+     * @param $object
+     * @return void
+     */
+    function validate(Admin $admin, ErrorElement $errorElement, $object);
+}

+ 47 - 0
DependencyInjection/Compiler/ExtensionCompilerPass.php

@@ -0,0 +1,47 @@
+<?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\Compiler;
+
+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;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ */
+class ExtensionCompilerPass implements CompilerPassInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        foreach ($container->findTaggedServiceIds('sonata.admin.extension') as $id => $attributes) {
+
+            $target = false;
+            if (isset($attributes[0]['target'])) {
+                $target = $attributes[0]['target'];
+            }
+
+            if (!$target || !$container->hasDefinition($target)) {
+                continue;
+            }
+
+            $container->getDefinition($target)
+                ->addMethodCall('addExtension', array(new Reference($id)));
+        }
+    }
+}

+ 3 - 1
SonataAdminBundle.php

@@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsCompilerPass;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsCompilerPass;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddGuesserCompilerPass;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddGuesserCompilerPass;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddFilterTypeCompilerPass;
 use Sonata\AdminBundle\DependencyInjection\Compiler\AddFilterTypeCompilerPass;
+use Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass;
 
 
 class SonataAdminBundle extends Bundle
 class SonataAdminBundle extends Bundle
 {
 {
@@ -23,5 +24,6 @@ class SonataAdminBundle extends Bundle
         $container->addCompilerPass(new AddDependencyCallsCompilerPass());
         $container->addCompilerPass(new AddDependencyCallsCompilerPass());
         $container->addCompilerPass(new AddGuesserCompilerPass());
         $container->addCompilerPass(new AddGuesserCompilerPass());
         $container->addCompilerPass(new AddFilterTypeCompilerPass());
         $container->addCompilerPass(new AddFilterTypeCompilerPass());
+        $container->addCompilerPass(new ExtensionCompilerPass());
     }
     }
-}
+}