Bläddra i källkod

add functionalities : extend dashboard & modify admin dependency injection in the config.yml

Charley Maillot 13 år sedan
förälder
incheckning
8a65d45e19

+ 2 - 9
Admin/Pool.php

@@ -47,15 +47,8 @@ class Pool
 
         foreach ($this->adminGroups as $name => $adminGroup) {
 
-            foreach ($adminGroup as $id => $options) {
-
-                if (!$options['show_in_dashboard']) {
-                    unset($groups[$name][$id]);
-                    continue;
-
-                }
-
-                $groups[$name][$id] = $this->container->get($id);
+            foreach ($adminGroup['items'] as $key => $id) {
+                $groups[$name]['items'][$key] = $this->container->get($id);
             }
 
             if (empty($groups[$name])) {

+ 95 - 48
DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php

@@ -17,6 +17,8 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
 /**
  * Add all dependencies to the Admin class, this avoid to write to many lines
  * in the configuration files.
@@ -30,12 +32,13 @@ class AddDependencyCallsCompilerPass implements CompilerPassInterface
      */
     public function process(ContainerBuilder $container)
     {
+        $settings = $this->fixSettings($container);
+
         $groups = $admins = $classes = array();
 
         $pool = $container->getDefinition('sonata.admin.pool');
 
         foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $attributes) {
-
             $definition = $container->getDefinition($id);
 
             $arguments = $definition->getArguments();
@@ -48,7 +51,7 @@ class AddDependencyCallsCompilerPass implements CompilerPassInterface
                 $definition->replaceArgument(2, 'SonataAdminBundle:CRUD');
             }
 
-            $this->applyDefaults($definition, $attributes);
+            $this->applyDefaults($container, $id, $attributes, $settings);
 
             $arguments = $definition->getArguments();
             if (preg_match('/%(.*)%/', $arguments[1], $matches)) {
@@ -62,13 +65,30 @@ class AddDependencyCallsCompilerPass implements CompilerPassInterface
 
             $group_name = isset($attributes[0]['group']) ? $attributes[0]['group'] : 'default';
 
-            if (!isset($groups[$group_name])) {
-                $groups[$group_name] = array();
+            if (!isset($groupDefaults[$group_name])) {
+                $groupDefaults[$group_name] = array(
+                    'label' => $group_name
+                );
             }
 
-            $groups[$group_name][$id] = array(
-                'show_in_dashboard' => (boolean)(isset($attributes[0]['show_in_dashboard']) ? $attributes[0]['show_in_dashboard'] : true)
-            );
+            $groupDefaults[$group_name]['items'][] = $id;
+        }
+
+        if (isset($settings['dashboard_groups'])) {
+
+            $groups = $settings['dashboard_groups'];
+
+            foreach ($groups as $group_name => $group) {
+                if(empty($group['items'])) {
+                    $groups[$group_name]['items'] = $groupDefaults[$group_name]['items'];
+                }
+                if(empty($group['label'])) {
+                    $groups[$group_name]['label'] = $groupDefaults[$group_name]['label'];
+                }
+            }
+        }
+        else {
+            $groups = $groupDefaults;
         }
 
         $pool->addMethodCall('setAdminServiceIds', array($admins));
@@ -79,66 +99,93 @@ class AddDependencyCallsCompilerPass implements CompilerPassInterface
         $routeLoader->replaceArgument(1, $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())
+    public function fixSettings($container)
     {
-        $definition->setScope(ContainerInterface::SCOPE_PROTOTYPE);
-
-        $manager_type = $attributes[0]['manager_type'];
+        $pool = $container->getDefinition('sonata.admin.pool');
 
-        if (!$definition->hasMethodCall('setModelManager')) {
-            $definition->addMethodCall('setModelManager', array(new Reference(sprintf('sonata.admin.manager.%s', $manager_type))));
+        // not very clean but don't know how to do that for now
+        $settings = false;
+        $methods  = $pool->getMethodCalls();
+        foreach ($methods as $pos => $calls) {
+            if ($calls[0] == '__hack__') {
+                $settings = $calls[1];
+                break;
+            }
         }
 
-        if (!$definition->hasMethodCall('setFormContractor')) {
-            $definition->addMethodCall('setFormContractor', array(new Reference(sprintf('sonata.admin.builder.%s_form', $manager_type))));
+        if ($settings) {
+            unset($methods[$pos]);
         }
 
-        if (!$definition->hasMethodCall('setShowBuilder')) {
-            $definition->addMethodCall('setShowBuilder', array(new Reference(sprintf('sonata.admin.builder.%s_show', $manager_type))));
-        }
+        $pool->setMethodCalls($methods);
 
-        if (!$definition->hasMethodCall('setListBuilder')) {
-            $definition->addMethodCall('setListBuilder', array(new Reference(sprintf('sonata.admin.builder.%s_list', $manager_type))));
-        }
+        return $settings;
+    }
 
-        if (!$definition->hasMethodCall('setDatagridBuilder')) {
-            $definition->addMethodCall('setDatagridBuilder', array(new Reference(sprintf('sonata.admin.builder.%s_datagrid', $manager_type))));
-        }
+    /**
+     * Apply the default values required by the AdminInterface to the Admin service definition
+     *
+     * @param ContainerBuilder $container
+     * @param interger $serviceId
+     * @param array $attributes
+     * @param array $settings
+     * @return \Symfony\Component\DependencyInjection\Definition
+     */
+    public function applyDefaults(ContainerBuilder $container, $serviceId, array $attributes = array(), array $settings = array())
+    {
+        $definition = $container->getDefinition($serviceId);
 
-        if (!$definition->hasMethodCall('setTranslator')) {
-            $definition->addMethodCall('setTranslator', array(new Reference('translator')));
-        }
+        $definition->setScope(ContainerInterface::SCOPE_PROTOTYPE);
 
-        if (!$definition->hasMethodCall('setConfigurationPool')) {
-            $definition->addMethodCall('setConfigurationPool', array(new Reference('sonata.admin.pool')));
-        }
+        $manager_type = $attributes[0]['manager_type'];
 
-        if (!$definition->hasMethodCall('setRouter')) {
-            $definition->addMethodCall('setRouter', array(new Reference('router')));
+        $addServices = isset($settings['admin_services'][$serviceId]) ? $settings['admin_services'][$serviceId] : false;
+
+        $defaultAddServices = array(
+            'model_manager'      => sprintf('sonata.admin.manager.%s', $manager_type),
+            'form_contractor'    => sprintf('sonata.admin.builder.%s_form', $manager_type),
+            'show_builder'       => sprintf('sonata.admin.builder.%s_show', $manager_type),
+            'list_builder'       => sprintf('sonata.admin.builder.%s_list', $manager_type),
+            'datagrid_builder'   => sprintf('sonata.admin.builder.%s_datagrid', $manager_type),
+            'translator'         => 'translator',
+            'configuration_pool' => 'sonata.admin.pool',
+            'router'             => 'router',
+            'validator'          => 'validator',
+            'security_handler'   => 'sonata.admin.security.handler'
+        );
+
+        foreach ($defaultAddServices as $attr => $addServiceId) {
+            $method = 'set'.$this->camelize($attr);
+
+            if(isset($addServices[$attr]) || !$definition->hasMethodCall($method)) {
+                $definition->addMethodCall($method, array(new Reference(isset($addServices[$attr]) ? $addServices[$attr] : $addServiceId)));
+            }
         }
 
-        if (!$definition->hasMethodCall('setValidator')) {
-            $definition->addMethodCall('setValidator', array(new Reference('validator')));
+        if (isset($service['label'])) {
+            $label = $service['label'];
         }
-
-        if (!$definition->hasMethodCall('setSecurityHandler')) {
-            $definition->addMethodCall('setSecurityHandler', array(new Reference('sonata.admin.security.handler')));
+        elseif (isset($attributes[0]['label'])) {
+            $label = $attributes[0]['label'];
         }
-
-        if (!$definition->hasMethodCall('setLabel')) {
-            $label = isset($attributes[0]['label']) ? $attributes[0]['label'] : '-';
-            $definition->addMethodCall('setLabel', array($label));
+        else {
+            $label = '-';
         }
+        $definition->addMethodCall('setLabel', array($label));
 
         $definition->addMethodCall('configure');
 
         return $definition;
     }
+
+    /**
+     * method taken from PropertyPath
+     *
+     * @param  $property
+     * @return mixed
+     */
+    protected function camelize($property)
+    {
+       return preg_replace(array('/(^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
+    }
 }

+ 34 - 0
DependencyInjection/Configuration.php

@@ -45,12 +45,46 @@ class Configuration implements ConfigurationInterface
         $rootNode
             ->children()
                 ->scalarNode('security_handler')->defaultValue('sonata.admin.security.handler.noop')->end()
+
+                ->arrayNode('dashboard_groups')
+                    ->useAttributeAsKey('id')
+                    ->prototype('array')
+                        ->children()
+                            ->scalarNode('label')->end()
+                            ->arrayNode('items')
+                                ->prototype('scalar')->end()
+                            ->end()
+                        ->end()
+                    ->end()
+                ->end()
+
+                ->arrayNode('admin_services')
+                    ->useAttributeAsKey('__')
+                    ->prototype('array')
+                        ->children()
+                            ->scalarNode('id')->end()
+                            ->scalarNode('model_manager')->end()
+                            ->scalarNode('form_contractor')->end()
+                            ->scalarNode('show_builder')->end()
+                            ->scalarNode('list_builder')->end()
+                            ->scalarNode('datagrid_builder')->end()
+                            ->scalarNode('translator')->end()
+                            ->scalarNode('configuration_pool')->end()
+                            ->scalarNode('router')->end()
+                            ->scalarNode('validator')->end()
+                            ->scalarNode('security_handler')->end()
+                            ->scalarNode('label')->end()
+                        ->end()
+                    ->end()
+                ->end()
+
                 ->arrayNode('templates')
                     ->children()
                         ->scalarNode('layout')->cannotBeEmpty()->end()
                         ->scalarNode('ajax')->cannotBeEmpty()->end()
                     ->end()
                 ->end()
+        
             ->end()
         ->end();
     }

+ 14 - 4
DependencyInjection/SonataAdminExtension.php

@@ -44,7 +44,7 @@ class SonataAdminExtension extends Extension
      * @param array            $configs    An array of configuration settings
      * @param ContainerBuilder $container A ContainerBuilder instance
      */
-    public function load(array $configs, ContainerBuilder $container)
+    public function load(array $config, ContainerBuilder $container)
     {
         $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
         $loader->load('templates.xml');
@@ -56,15 +56,25 @@ class SonataAdminExtension extends Extension
 
         $configuration = new Configuration();
         $processor = new Processor();
-        $config = $processor->processConfiguration($configuration, $configs);
+        $config = $processor->processConfiguration($configuration, $config);
 
         // setups parameters with values in config.yml, default values from external files used if not
         $this->configSetupTemplates($config, $container);
 
+        $pool = $container->getDefinition('sonata.admin.pool');
+        $pool->addMethodCall('__hack__', $config);
+
         $container->setAlias('sonata.admin.security.handler', $config['security_handler']);
     }
 
-    protected function configSetupTemplates($config, $container)
+    /**
+     * setup the templates config
+     *
+     * @param array $config An array of configuration settings
+     * @param ContainerBuilder $container A ContainerBuilder instance
+     * @return void
+     */
+    protected function configSetupTemplates(array $config, ContainerBuilder $container)
     {
         foreach ($this->configNamespaces as $ns => $params) {
 
@@ -73,7 +83,7 @@ class SonataAdminExtension extends Extension
             }
 
             foreach ($config[$ns] as $type => $template) {
-                if (!isset($config[$ns][$type])) {
+                if (!isset($configs[$ns][$type])) {
                     continue;
                 }
 

+ 1 - 0
Resources/doc/index.rst

@@ -27,6 +27,7 @@ Reference Guide
    reference/security
    reference/conditional_validation
    reference/update
+   reference/advance
 
 
 Doctrine ORM

+ 27 - 0
Resources/doc/reference/advance.rst

@@ -0,0 +1,27 @@
+Advance
+=========
+
+By default services who are injected to the admin service are
+    method name         |    Service Id
+---------------------------------------------------------------------
+    model_manager       |    sonata.admin.manager.%manager-type%
+    form_contractor     |    sonata.admin.builder.%manager-type%_form
+    show_builder        |    sonata.admin.builder.%manager-type%_show
+    list_builder        |    sonata.admin.builder.%manager-type%_list
+    datagrid_builder    |    sonata.admin.builder.%manager-type%_datagrid
+    translator          |    translator
+    configuration_pool  |    sonata.admin.pool
+    router              |    router
+    validator           |    validator
+    security_handler    |    sonata.admin.security.handler
+
+Note: %manager-type% is replace by the manager type (orm, odm...)
+
+If you want to modify the service who are going to be injected, add the following code to your
+application's config file:
+.. code-block:: yaml
+    # app/config/config.yml
+    admins:
+        sonata_admin: #method name, you can find the list in the table above
+            sonata.order.admin.order: #id of the admin service's
+                model_manager: sonata.order.admin.order.manager #id of the your service

+ 40 - 1
Resources/doc/reference/dashboard.rst

@@ -1,8 +1,47 @@
 Dashboard
 =========
 
-The dashboard is the main landing page. For now the dashboard lists the
+The dashboard is the main landing page. By default the dashboard lists the
 different admin areas available.
+If you want to custom the dashbord, add the following code to your
+application's config file:
+.. code-block:: yaml
+
+    # app/config/config.yml
+    sonata_admin:
+        dashboard:
+    ... your config ...
+
+
+Some examples of config file:
+1 - Set the label group
+.. code-block:: yaml
+
+    # app/config/config.yml
+    sonata_admin:
+        dashboard:
+          sonata_page:
+            label: Page
+            items: ~
+
+2 - Set items group
+.. code-block:: yaml
+
+    # app/config/config.yml
+    sonata_admin:
+        dashboard:
+          sonata_page:
+            items:
+                - sonata.page.admin.page
+
+3 - Add an item of the group
+.. code-block:: yaml
+
+    # app/config/config.yml
+    sonata_admin:
+        dashboard:
+          sonata_page: ~
+
 
 .. image:: ../images/dashboard.png
            :alt: Dashboard

+ 3 - 3
Resources/views/Core/dashboard.html.twig

@@ -15,16 +15,16 @@ file that was distributed with this source code.
 {% block breadcrumb %}{% trans from 'SonataAdminBundle' %}title_dashboard{% endtrans %}{% endblock %}
 {% block content %}
 
-    {% for code, group in groups %}
+    {% for group in groups %}
         <table class="sonata-ba-list">
             <thead>
                 <tr>
-                    <th colspan="3">{{ code|trans({}, 'SonataAdminBundle') }}</th>
+                    <th colspan="3">{{ group.label|trans({}, 'SonataAdminBundle') }}</th>
                 </tr>
             </thead>
 
             <tbody>
-                {% for admin in group %}
+                {% for admin in group.items %}
                     <tr>
                         <td class="sonata-ba-list-label">{{ admin.label|trans({}, admin.translationdomain) }}</td>
                         <td>