AddDependencyCallsCompilerPass.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /*
  3. * This file is part of the Sonata project.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\Definition;
  12. use Symfony\Component\DependencyInjection\ContainerBuilder;
  13. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  14. use Symfony\Component\DependencyInjection\Reference;
  15. use Symfony\Component\DependencyInjection\ContainerInterface;
  16. use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
  17. /**
  18. * Add all dependencies to the Admin class, this avoid to write to many lines
  19. * in the configuration files.
  20. *
  21. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  22. */
  23. class AddDependencyCallsCompilerPass implements CompilerPassInterface
  24. {
  25. /**
  26. * {@inheritDoc}
  27. */
  28. public function process(ContainerBuilder $container)
  29. {
  30. $settings = $this->fixSettings($container);
  31. $groups = $admins = $classes = array();
  32. $pool = $container->getDefinition('sonata.admin.pool');
  33. foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $attributes) {
  34. $definition = $container->getDefinition($id);
  35. $arguments = $definition->getArguments();
  36. if (strlen($arguments[0]) == 0) {
  37. $definition->replaceArgument(0, $id);
  38. }
  39. if (strlen($arguments[2]) == 0) {
  40. $definition->replaceArgument(2, 'SonataAdminBundle:CRUD');
  41. }
  42. $this->applyDefaults($container, $id, $attributes, $settings);
  43. $arguments = $definition->getArguments();
  44. if (preg_match('/%(.*)%/', $arguments[1], $matches)) {
  45. $class = $container->getParameter($matches[1]);
  46. } else {
  47. $class = $arguments[1];
  48. }
  49. $admins[] = $id;
  50. $classes[$class] = $id;
  51. $group_name = isset($attributes[0]['group']) ? $attributes[0]['group'] : 'default';
  52. if (!isset($groupDefaults[$group_name])) {
  53. $groupDefaults[$group_name] = array(
  54. 'label' => $group_name
  55. );
  56. }
  57. $groupDefaults[$group_name]['items'][] = $id;
  58. }
  59. if (!empty($settings['dashboard_groups'])) {
  60. $groups = $settings['dashboard_groups'];
  61. foreach ($groups as $group_name => $group) {
  62. if (empty($group['items'])) {
  63. $groups[$group_name]['items'] = $groupDefaults[$group_name]['items'];
  64. }
  65. if (empty($group['label'])) {
  66. $groups[$group_name]['label'] = $groupDefaults[$group_name]['label'];
  67. }
  68. if (!empty($groups[$group_name]['item_adds'])) {
  69. $groups[$group_name]['items'] = array_merge($groupDefaults[$group_name]['items'], $groups[$group_name]['item_adds']);
  70. }
  71. }
  72. }
  73. else {
  74. $groups = $groupDefaults;
  75. }
  76. $pool->addMethodCall('setAdminServiceIds', array($admins));
  77. $pool->addMethodCall('setAdminGroups', array($groups));
  78. $pool->addMethodCall('setAdminClasses', array($classes));
  79. $routeLoader = $container->getDefinition('sonata.admin.route_loader');
  80. $routeLoader->replaceArgument(1, $admins);
  81. }
  82. public function fixSettings($container)
  83. {
  84. $pool = $container->getDefinition('sonata.admin.pool');
  85. // not very clean but don't know how to do that for now
  86. $settings = false;
  87. $methods = $pool->getMethodCalls();
  88. foreach ($methods as $pos => $calls) {
  89. if ($calls[0] == '__hack__') {
  90. $settings = $calls[1];
  91. break;
  92. }
  93. }
  94. if ($settings) {
  95. unset($methods[$pos]);
  96. }
  97. $pool->setMethodCalls($methods);
  98. return $settings;
  99. }
  100. /**
  101. * Apply the default values required by the AdminInterface to the Admin service definition
  102. *
  103. * @param ContainerBuilder $container
  104. * @param interger $serviceId
  105. * @param array $attributes
  106. * @param array $settings
  107. * @return \Symfony\Component\DependencyInjection\Definition
  108. */
  109. public function applyDefaults(ContainerBuilder $container, $serviceId, array $attributes = array(), array $settings = array())
  110. {
  111. $definition = $container->getDefinition($serviceId);
  112. $definition->setScope(ContainerInterface::SCOPE_PROTOTYPE);
  113. $manager_type = $attributes[0]['manager_type'];
  114. $addServices = isset($settings['admin_services'][$serviceId]) ? $settings['admin_services'][$serviceId] : false;
  115. $defaultAddServices = array(
  116. 'model_manager' => sprintf('sonata.admin.manager.%s', $manager_type),
  117. 'form_contractor' => sprintf('sonata.admin.builder.%s_form', $manager_type),
  118. 'show_builder' => sprintf('sonata.admin.builder.%s_show', $manager_type),
  119. 'list_builder' => sprintf('sonata.admin.builder.%s_list', $manager_type),
  120. 'datagrid_builder' => sprintf('sonata.admin.builder.%s_datagrid', $manager_type),
  121. 'translator' => 'translator',
  122. 'configuration_pool' => 'sonata.admin.pool',
  123. 'router' => 'router',
  124. 'validator' => 'validator',
  125. 'security_handler' => 'sonata.admin.security.handler'
  126. );
  127. foreach ($defaultAddServices as $attr => $addServiceId) {
  128. $method = 'set'.$this->camelize($attr);
  129. if (isset($addServices[$attr]) || !$definition->hasMethodCall($method)) {
  130. $definition->addMethodCall($method, array(new Reference(isset($addServices[$attr]) ? $addServices[$attr] : $addServiceId)));
  131. }
  132. }
  133. if (isset($service['label'])) {
  134. $label = $service['label'];
  135. } elseif (isset($attributes[0]['label'])) {
  136. $label = $attributes[0]['label'];
  137. } else {
  138. $label = '-';
  139. }
  140. $definition->addMethodCall('setLabel', array($label));
  141. $definition->addMethodCall('configure');
  142. return $definition;
  143. }
  144. /**
  145. * method taken from PropertyPath
  146. *
  147. * @param $property
  148. * @return mixed
  149. */
  150. protected function camelize($property)
  151. {
  152. return preg_replace(array('/(^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
  153. }
  154. }