This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\Mapper; |
||
15 | |||
16 | /** |
||
17 | * This class is used to simulate the Form API. |
||
18 | * |
||
19 | * @author Thomas Rabaix <[email protected]> |
||
20 | */ |
||
21 | abstract class BaseGroupedMapper extends BaseMapper |
||
22 | { |
||
23 | /** |
||
24 | * @var string|null |
||
25 | */ |
||
26 | protected $currentGroup; |
||
27 | |||
28 | /** |
||
29 | * @var string|null |
||
30 | */ |
||
31 | protected $currentTab; |
||
32 | |||
33 | /** |
||
34 | * @var bool[] |
||
35 | */ |
||
36 | protected $apply = []; |
||
37 | |||
38 | /** |
||
39 | * Add new group or tab (if parameter "tab=true" is available in options). |
||
40 | * |
||
41 | * @throws \LogicException |
||
42 | */ |
||
43 | public function with(string $name, array $options = []): self |
||
44 | { |
||
45 | if (!$this->shouldApply()) { |
||
46 | return $this; |
||
47 | } |
||
48 | |||
49 | /* |
||
50 | * The current implementation should work with the following workflow: |
||
51 | * |
||
52 | * $formMapper |
||
53 | * ->with('group1') |
||
54 | * ->add('username') |
||
55 | * ->add('password') |
||
56 | * ->end() |
||
57 | * ->with('tab1', ['tab' => true]) |
||
58 | * ->with('group1') |
||
59 | * ->add('username') |
||
60 | * ->add('password') |
||
61 | * ->end() |
||
62 | * ->with('group2', ['collapsed' => true]) |
||
63 | * ->add('enabled') |
||
64 | * ->add('createdAt') |
||
65 | * ->end() |
||
66 | * ->end(); |
||
67 | * |
||
68 | */ |
||
69 | $defaultOptions = [ |
||
70 | 'collapsed' => false, |
||
71 | 'class' => false, |
||
72 | 'description' => false, |
||
73 | 'label' => $this->admin->getLabelTranslatorStrategy()->getLabel($name, $this->getName(), 'group'), |
||
74 | 'translation_domain' => null, |
||
75 | 'name' => $name, |
||
76 | 'box_class' => 'box box-primary', |
||
77 | 'empty_message' => 'message_form_group_empty', |
||
78 | 'empty_message_translation_domain' => 'SonataAdminBundle', |
||
79 | ]; |
||
80 | |||
81 | $code = $name; |
||
82 | |||
83 | // Open |
||
84 | if (\array_key_exists('tab', $options) && $options['tab']) { |
||
85 | $tabs = $this->getTabs(); |
||
86 | |||
87 | if ($this->currentTab) { |
||
0 ignored issues
–
show
|
|||
88 | if (isset($tabs[$this->currentTab]['auto_created']) && true === $tabs[$this->currentTab]['auto_created']) { |
||
89 | throw new \LogicException('New tab was added automatically when you have added field or group. You should close current tab before adding new one OR add tabs before adding groups and fields.'); |
||
90 | } |
||
91 | |||
92 | throw new \LogicException(sprintf( |
||
93 | 'You should close previous tab "%s" with end() before adding new tab "%s".', |
||
94 | $this->currentTab, |
||
95 | $name |
||
96 | )); |
||
97 | } |
||
98 | |||
99 | if ($this->currentGroup) { |
||
100 | throw new \LogicException(sprintf('You should open tab before adding new group "%s".', $name)); |
||
101 | } |
||
102 | |||
103 | if (!isset($tabs[$name])) { |
||
104 | $tabs[$name] = []; |
||
105 | } |
||
106 | |||
107 | $tabs[$code] = array_merge($defaultOptions, [ |
||
108 | 'auto_created' => false, |
||
109 | 'groups' => [], |
||
110 | ], $tabs[$code], $options); |
||
111 | |||
112 | $this->currentTab = $code; |
||
113 | } else { |
||
114 | if ($this->currentGroup) { |
||
0 ignored issues
–
show
The expression
$this->currentGroup of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
115 | throw new \LogicException(sprintf( |
||
116 | 'You should close previous group "%s" with end() before adding new tab "%s".', |
||
117 | $this->currentGroup, |
||
118 | $name |
||
119 | )); |
||
120 | } |
||
121 | |||
122 | if (!$this->currentTab) { |
||
0 ignored issues
–
show
The expression
$this->currentTab of type string|null is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
123 | // no tab define |
||
124 | $this->with('default', [ |
||
125 | 'tab' => true, |
||
126 | 'auto_created' => true, |
||
127 | 'translation_domain' => $options['translation_domain'] ?? null, |
||
128 | ]); // add new tab automatically |
||
129 | } |
||
130 | |||
131 | // if no tab is selected, we go the the main one named '_' .. |
||
132 | if ('default' !== $this->currentTab) { |
||
133 | // groups with the same name can be on different tabs, so we prefix them in order to make unique group name |
||
134 | $code = sprintf('%s.%s', $this->currentTab, $name); |
||
135 | } |
||
136 | |||
137 | $groups = $this->getGroups(); |
||
138 | if (!isset($groups[$code])) { |
||
139 | $groups[$code] = []; |
||
140 | } |
||
141 | |||
142 | $groups[$code] = array_merge($defaultOptions, [ |
||
143 | 'fields' => [], |
||
144 | ], $groups[$code], $options); |
||
145 | |||
146 | $this->currentGroup = $code; |
||
147 | $this->setGroups($groups); |
||
148 | $tabs = $this->getTabs(); |
||
149 | } |
||
150 | |||
151 | if ($this->currentGroup && isset($tabs[$this->currentTab]) && !\in_array($this->currentGroup, $tabs[$this->currentTab]['groups'], true)) { |
||
152 | $tabs[$this->currentTab]['groups'][] = $this->currentGroup; |
||
153 | } |
||
154 | |||
155 | $this->setTabs($tabs); |
||
156 | |||
157 | return $this; |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Only nested add if the condition match true. |
||
162 | */ |
||
163 | public function ifTrue(bool $bool): self |
||
164 | { |
||
165 | $this->apply[] = true === $bool; |
||
166 | |||
167 | return $this; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Only nested add if the condition match false. |
||
172 | */ |
||
173 | public function ifFalse(bool $bool): self |
||
174 | { |
||
175 | $this->apply[] = false === $bool; |
||
176 | |||
177 | return $this; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * @throws \LogicException |
||
182 | */ |
||
183 | public function ifEnd(): self |
||
184 | { |
||
185 | if (empty($this->apply)) { |
||
186 | throw new \LogicException('No open ifTrue() or ifFalse(), you cannot use ifEnd()'); |
||
187 | } |
||
188 | |||
189 | array_pop($this->apply); |
||
190 | |||
191 | return $this; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Add new tab. |
||
196 | */ |
||
197 | public function tab(string $name, array $options = []): self |
||
198 | { |
||
199 | return $this->with($name, array_merge($options, ['tab' => true])); |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Close the current group or tab. |
||
204 | * |
||
205 | * @throws \LogicException |
||
206 | */ |
||
207 | public function end(): self |
||
208 | { |
||
209 | if (!$this->shouldApply()) { |
||
210 | return $this; |
||
211 | } |
||
212 | |||
213 | if (null !== $this->currentGroup) { |
||
214 | $this->currentGroup = null; |
||
215 | } elseif (null !== $this->currentTab) { |
||
216 | $this->currentTab = null; |
||
217 | } else { |
||
218 | throw new \LogicException('No open tabs or groups, you cannot use end()'); |
||
219 | } |
||
220 | |||
221 | return $this; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Returns a boolean indicating if there is an open tab at the moment. |
||
226 | */ |
||
227 | public function hasOpenTab(): bool |
||
228 | { |
||
229 | return null !== $this->currentTab; |
||
230 | } |
||
231 | |||
232 | abstract protected function getGroups(): array; |
||
233 | |||
234 | abstract protected function getTabs(): array; |
||
235 | |||
236 | abstract protected function setGroups(array $groups): void; |
||
237 | |||
238 | abstract protected function setTabs(array $tabs): void; |
||
239 | |||
240 | abstract protected function getName(): string; |
||
241 | |||
242 | /** |
||
243 | * Add the field name to the current group. |
||
244 | */ |
||
245 | protected function addFieldToCurrentGroup(string $fieldName): array |
||
246 | { |
||
247 | // Note this line must happen before the next line. |
||
248 | // See https://github.com/sonata-project/SonataAdminBundle/pull/1351 |
||
249 | $currentGroup = $this->getCurrentGroupName(); |
||
250 | $groups = $this->getGroups(); |
||
251 | $groups[$currentGroup]['fields'][$fieldName] = $fieldName; |
||
252 | $this->setGroups($groups); |
||
253 | |||
254 | return $groups[$currentGroup]; |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Return the name of the currently selected group. The method also makes |
||
259 | * sure a valid group name is currently selected. |
||
260 | * |
||
261 | * Note that this can have the side effect to change the 'group' value |
||
262 | * returned by the getGroup function |
||
263 | */ |
||
264 | protected function getCurrentGroupName(): string |
||
265 | { |
||
266 | if (!$this->currentGroup) { |
||
267 | $this->with($this->admin->getLabel() ?: 'default', ['auto_created' => true]); |
||
268 | } |
||
269 | |||
270 | return $this->currentGroup; |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Check if all apply conditions are respected. |
||
275 | */ |
||
276 | final protected function shouldApply(): bool |
||
277 | { |
||
278 | return !\in_array(false, $this->apply, true); |
||
279 | } |
||
280 | } |
||
281 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: