Skip to content

Commit

Permalink
add functionalities : extend dashboard & modify admin dependency inje…
Browse files Browse the repository at this point in the history
…ction in the config.yml
  • Loading branch information
Charley Maillot committed Aug 23, 2011
1 parent f197534 commit 8a65d45
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 65 deletions.
11 changes: 2 additions & 9 deletions Admin/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,8 @@ public function getDashboardGroups()

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])) {
Expand Down
143 changes: 95 additions & 48 deletions DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
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.
Expand All @@ -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();
Expand All @@ -48,7 +51,7 @@ public function process(ContainerBuilder $container)
$definition->replaceArgument(2, 'SonataAdminBundle:CRUD');
}

$this->applyDefaults($definition, $attributes);
$this->applyDefaults($container, $id, $attributes, $settings);

$arguments = $definition->getArguments();
if (preg_match('/%(.*)%/', $arguments[1], $matches)) {
Expand All @@ -62,13 +65,30 @@ public function process(ContainerBuilder $container)

$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));
Expand All @@ -79,66 +99,93 @@ public function process(ContainerBuilder $container)
$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 changes: 34 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,46 @@ private function addTemplateSection(ArrayNodeDefinition $rootNode)
$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();
}
Expand Down
18 changes: 14 additions & 4 deletions DependencyInjection/SonataAdminExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -56,15 +56,25 @@ public function load(array $configs, ContainerBuilder $container)

$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) {

Expand All @@ -73,7 +83,7 @@ protected function configSetupTemplates($config, $container)
}

foreach ($config[$ns] as $type => $template) {
if (!isset($config[$ns][$type])) {
if (!isset($configs[$ns][$type])) {
continue;
}

Expand Down
1 change: 1 addition & 0 deletions Resources/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Reference Guide
reference/security
reference/conditional_validation
reference/update
reference/advance


Doctrine ORM
Expand Down
27 changes: 27 additions & 0 deletions Resources/doc/reference/advance.rst
Original file line number Diff line number Diff line change
@@ -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
41 changes: 40 additions & 1 deletion Resources/doc/reference/dashboard.rst
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading

0 comments on commit 8a65d45

Please sign in to comment.