BreadcrumbsBuilder.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. /*
  3. * This file is part of the Sonata Project package.
  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\Admin;
  11. use Knp\Menu\ItemInterface;
  12. use Symfony\Component\OptionsResolver\OptionsResolver;
  13. /**
  14. * Stateless breadcrumbs builder (each method needs an Admin object).
  15. *
  16. * @author Grégoire Paris <postmaster@greg0ire.fr>
  17. */
  18. final class BreadcrumbsBuilder implements BreadcrumbsBuilderInterface
  19. {
  20. /**
  21. * @var string[]
  22. */
  23. protected $config = array();
  24. /**
  25. * @param string[] $config
  26. */
  27. public function __construct(array $config = array())
  28. {
  29. $resolver = new OptionsResolver();
  30. $this->configureOptions($resolver);
  31. $this->config = $resolver->resolve($config);
  32. }
  33. /**
  34. * @param OptionsResolver $resolver
  35. */
  36. public function configureOptions(OptionsResolver $resolver)
  37. {
  38. $resolver->setDefaults(array(
  39. 'child_admin_route' => 'edit',
  40. ));
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. public function getBreadcrumbs(AdminInterface $admin, $action)
  46. {
  47. $breadcrumbs = array();
  48. if ($admin->isChild()) {
  49. return $this->getBreadcrumbs($admin->getParent(), $action);
  50. }
  51. $menu = $this->buildBreadcrumbs($admin, $action);
  52. do {
  53. $breadcrumbs[] = $menu;
  54. } while ($menu = $menu->getParent());
  55. $breadcrumbs = array_reverse($breadcrumbs);
  56. array_shift($breadcrumbs);
  57. return $breadcrumbs;
  58. }
  59. /**
  60. * {@inheritdoc}
  61. * NEXT_MAJOR : make this method private.
  62. */
  63. public function buildBreadcrumbs(AdminInterface $admin, $action, ItemInterface $menu = null)
  64. {
  65. if (!$menu) {
  66. $menu = $admin->getMenuFactory()->createItem('root');
  67. $menu = $this->createMenuItem(
  68. $admin,
  69. $menu,
  70. 'dashboard',
  71. 'SonataAdminBundle',
  72. array('uri' => $admin->getRouteGenerator()->generate(
  73. 'sonata_admin_dashboard'
  74. ))
  75. );
  76. }
  77. $menu = $this->createMenuItem(
  78. $admin,
  79. $menu,
  80. sprintf('%s_list', $admin->getClassnameLabel()),
  81. $admin->getTranslationDomain(),
  82. array(
  83. 'uri' => $admin->hasRoute('list') && $admin->isGranted('LIST') ?
  84. $admin->generateUrl('list') :
  85. null,
  86. )
  87. );
  88. $childAdmin = $admin->getCurrentChildAdmin();
  89. if ($childAdmin) {
  90. $id = $admin->getRequest()->get($admin->getIdParameter());
  91. $menu = $menu->addChild(
  92. $admin->toString($admin->getSubject()),
  93. array(
  94. 'uri' => $admin->hasRoute($this->config['child_admin_route']) && $admin->hasAccess($this->config['child_admin_route'], $admin->getSubject()) ?
  95. $admin->generateUrl($this->config['child_admin_route'], array('id' => $id)) :
  96. null,
  97. 'extras' => array(
  98. 'translation_domain' => false,
  99. ),
  100. )
  101. );
  102. $menu->setExtra('safe_label', false);
  103. return $this->buildBreadcrumbs($childAdmin, $action, $menu);
  104. }
  105. if ('list' === $action && $admin->isChild()) {
  106. $menu->setUri(false);
  107. } elseif ('create' !== $action && $admin->hasSubject()) {
  108. $menu = $menu->addChild($admin->toString($admin->getSubject()), array(
  109. 'extras' => array(
  110. 'translation_domain' => false,
  111. ),
  112. ));
  113. } else {
  114. $menu = $this->createMenuItem(
  115. $admin,
  116. $menu,
  117. sprintf('%s_%s', $admin->getClassnameLabel(), $action),
  118. $admin->getTranslationDomain()
  119. );
  120. }
  121. return $menu;
  122. }
  123. /**
  124. * Creates a new menu item from a simple name. The name is normalized and
  125. * translated with the specified translation domain.
  126. *
  127. * @param AdminInterface $admin used for translation
  128. * @param ItemInterface $menu will be modified and returned
  129. * @param string $name the source of the final label
  130. * @param string $translationDomain for label translation
  131. * @param array $options menu item options
  132. *
  133. * @return ItemInterface
  134. */
  135. private function createMenuItem(
  136. AdminInterface $admin,
  137. ItemInterface $menu,
  138. $name,
  139. $translationDomain = null,
  140. $options = array()
  141. ) {
  142. $options = array_merge(array(
  143. 'extras' => array(
  144. 'translation_domain' => $translationDomain,
  145. ),
  146. ), $options);
  147. return $menu->addChild(
  148. $admin->getLabelTranslatorStrategy()->getLabel(
  149. $name,
  150. 'breadcrumb',
  151. 'link'
  152. ),
  153. $options
  154. );
  155. }
  156. }