These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * This file is part of the Sonata Project package. |
||
7 | * |
||
8 | * (c) Thomas Rabaix <[email protected]> |
||
9 | * |
||
10 | * For the full copyright and license information, please view the LICENSE |
||
11 | * file that was distributed with this source code. |
||
12 | */ |
||
13 | |||
14 | namespace Sonata\AdminBundle\Admin; |
||
15 | |||
16 | use Knp\Menu\ItemInterface; |
||
17 | use Symfony\Component\OptionsResolver\OptionsResolver; |
||
18 | |||
19 | /** |
||
20 | * Stateless breadcrumbs builder (each method needs an Admin object). |
||
21 | * |
||
22 | * @author Grégoire Paris <[email protected]> |
||
23 | */ |
||
24 | final class BreadcrumbsBuilder implements BreadcrumbsBuilderInterface |
||
25 | { |
||
26 | /** |
||
27 | * @var string[] |
||
28 | */ |
||
29 | private $config = []; |
||
30 | |||
31 | /** |
||
32 | * @param string[] $config |
||
33 | */ |
||
34 | public function __construct(array $config = []) |
||
35 | { |
||
36 | $resolver = new OptionsResolver(); |
||
37 | $this->configureOptions($resolver); |
||
38 | |||
39 | $this->config = $resolver->resolve($config); |
||
40 | } |
||
41 | |||
42 | public function configureOptions(OptionsResolver $resolver): void |
||
43 | { |
||
44 | $resolver->setDefaults([ |
||
45 | 'child_admin_route' => 'edit', |
||
46 | ]); |
||
47 | } |
||
48 | |||
49 | public function getBreadcrumbs(AdminInterface $admin, $action): array |
||
50 | { |
||
51 | $breadcrumbs = []; |
||
52 | if ($admin->isChild()) { |
||
53 | return $this->getBreadcrumbs($admin->getParent(), $action); |
||
54 | } |
||
55 | |||
56 | $menu = $this->buildBreadcrumbs($admin, $action); |
||
57 | |||
58 | do { |
||
59 | $breadcrumbs[] = $menu; |
||
60 | } while ($menu = $menu->getParent()); |
||
61 | |||
62 | $breadcrumbs = array_reverse($breadcrumbs); |
||
63 | array_shift($breadcrumbs); |
||
64 | |||
65 | return $breadcrumbs; |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Builds breadcrumbs for $action, starting from $menu. |
||
70 | * |
||
71 | * Note: the method will be called by the top admin instance (parent => child) |
||
72 | * |
||
73 | * @param string $action |
||
74 | */ |
||
75 | public function buildBreadcrumbs( |
||
76 | AdminInterface $admin, |
||
77 | $action, |
||
78 | ItemInterface $menu = null |
||
79 | ): ItemInterface { |
||
80 | if (!$menu) { |
||
81 | $menu = $admin->getMenuFactory()->createItem('root'); |
||
82 | |||
83 | $menu = $menu->addChild( |
||
84 | 'link_breadcrumb_dashboard', |
||
85 | [ |
||
86 | 'uri' => $admin->getRouteGenerator()->generate('sonata_admin_dashboard'), |
||
87 | 'extras' => ['translation_domain' => 'SonataAdminBundle'], |
||
88 | ] |
||
89 | ); |
||
90 | } |
||
91 | |||
92 | $menu = $this->createMenuItem( |
||
93 | $admin, |
||
94 | $menu, |
||
95 | sprintf('%s_list', $admin->getClassnameLabel()), |
||
96 | $admin->getTranslationDomain(), |
||
97 | [ |
||
98 | 'uri' => $admin->hasRoute('list') && $admin->hasAccess('list') ? |
||
99 | $admin->generateUrl('list') : |
||
100 | null, |
||
101 | ] |
||
102 | ); |
||
103 | |||
104 | $childAdmin = $admin->getCurrentChildAdmin(); |
||
105 | |||
106 | if ($childAdmin) { |
||
107 | $id = $admin->getRequest()->get($admin->getIdParameter()); |
||
108 | |||
109 | $menu = $menu->addChild( |
||
110 | $admin->toString($admin->getSubject()), |
||
0 ignored issues
–
show
|
|||
111 | [ |
||
112 | 'uri' => $admin->hasRoute($this->config['child_admin_route']) && $admin->hasAccess($this->config['child_admin_route'], $admin->getSubject()) ? |
||
113 | $admin->generateUrl($this->config['child_admin_route'], ['id' => $id]) : |
||
114 | null, |
||
115 | 'extras' => [ |
||
116 | 'translation_domain' => false, |
||
117 | ], |
||
118 | ] |
||
119 | ); |
||
120 | |||
121 | $menu->setExtra('safe_label', false); |
||
122 | |||
123 | return $this->buildBreadcrumbs($childAdmin, $action, $menu); |
||
124 | } |
||
125 | |||
126 | if ('list' === $action) { |
||
127 | $menu->setUri(false); |
||
128 | |||
129 | return $menu; |
||
130 | } |
||
131 | if ('create' !== $action && $admin->hasSubject()) { |
||
132 | return $menu->addChild($admin->toString($admin->getSubject()), [ |
||
0 ignored issues
–
show
It seems like
$admin->getSubject() targeting Sonata\AdminBundle\Admin...Interface::getSubject() can also be of type null ; however, Sonata\AdminBundle\Admin...inInterface::toString() does only seem to accept object , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
133 | 'extras' => [ |
||
134 | 'translation_domain' => false, |
||
135 | ], |
||
136 | ]); |
||
137 | } |
||
138 | |||
139 | return $this->createMenuItem( |
||
140 | $admin, |
||
141 | $menu, |
||
142 | sprintf('%s_%s', $admin->getClassnameLabel(), $action), |
||
143 | $admin->getTranslationDomain() |
||
144 | ); |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Creates a new menu item from a simple name. The name is normalized and |
||
149 | * translated with the specified translation domain. |
||
150 | * |
||
151 | * @param AdminInterface $admin used for translation |
||
152 | * @param ItemInterface $menu will be modified and returned |
||
153 | * @param string $name the source of the final label |
||
154 | * @param string $translationDomain for label translation |
||
155 | * @param array $options menu item options |
||
156 | */ |
||
157 | private function createMenuItem( |
||
158 | AdminInterface $admin, |
||
159 | ItemInterface $menu, |
||
160 | string $name, |
||
161 | ?string $translationDomain = null, |
||
162 | array $options = [] |
||
163 | ): ItemInterface { |
||
164 | $options = array_merge([ |
||
165 | 'extras' => [ |
||
166 | 'translation_domain' => $translationDomain, |
||
167 | ], |
||
168 | ], $options); |
||
169 | |||
170 | return $menu->addChild( |
||
171 | $admin->getLabelTranslatorStrategy()->getLabel( |
||
172 | $name, |
||
173 | 'breadcrumb', |
||
174 | 'link' |
||
175 | ), |
||
176 | $options |
||
177 | ); |
||
178 | } |
||
179 | } |
||
180 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.