|
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 Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface; |
|
17
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
|
18
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccess; |
|
19
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* @author Thomas Rabaix <[email protected]> |
|
23
|
|
|
*/ |
|
24
|
|
|
class Pool |
|
25
|
|
|
{ |
|
26
|
|
|
/** |
|
27
|
|
|
* @var ContainerInterface |
|
28
|
|
|
*/ |
|
29
|
|
|
protected $container; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @var string[] |
|
33
|
|
|
*/ |
|
34
|
|
|
protected $adminServiceIds = []; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @var array |
|
38
|
|
|
*/ |
|
39
|
|
|
protected $adminGroups = []; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var array |
|
43
|
|
|
*/ |
|
44
|
|
|
protected $adminClasses = []; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* @deprecated since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" instead |
|
48
|
|
|
* |
|
49
|
|
|
* @var array |
|
50
|
|
|
*/ |
|
51
|
|
|
protected $templates = []; |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* @var array |
|
55
|
|
|
*/ |
|
56
|
|
|
protected $assets = []; |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* @var string |
|
60
|
|
|
*/ |
|
61
|
|
|
protected $title; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @var string |
|
65
|
|
|
*/ |
|
66
|
|
|
protected $titleLogo; |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @var array |
|
70
|
|
|
*/ |
|
71
|
|
|
protected $options; |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* @var PropertyAccessorInterface |
|
75
|
|
|
*/ |
|
76
|
|
|
protected $propertyAccessor; |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* @var MutableTemplateRegistryInterface |
|
80
|
|
|
*/ |
|
81
|
|
|
private $templateRegistry; |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* @param string $title |
|
85
|
|
|
* @param string $logoTitle |
|
86
|
|
|
* @param array $options |
|
87
|
|
|
*/ |
|
88
|
|
|
public function __construct( |
|
89
|
|
|
ContainerInterface $container, |
|
90
|
|
|
$title, |
|
91
|
|
|
$logoTitle, |
|
92
|
|
|
$options = [], |
|
93
|
|
|
PropertyAccessorInterface $propertyAccessor = null |
|
94
|
|
|
) { |
|
95
|
|
|
$this->container = $container; |
|
96
|
|
|
$this->title = $title; |
|
97
|
|
|
$this->titleLogo = $logoTitle; |
|
98
|
|
|
$this->options = $options; |
|
99
|
|
|
$this->propertyAccessor = $propertyAccessor; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* @return array |
|
104
|
|
|
*/ |
|
105
|
|
|
public function getGroups() |
|
106
|
|
|
{ |
|
107
|
|
|
$groups = $this->adminGroups; |
|
108
|
|
|
|
|
109
|
|
|
foreach ($this->adminGroups as $name => $adminGroup) { |
|
110
|
|
|
foreach ($adminGroup as $id => $options) { |
|
111
|
|
|
$groups[$name][$id] = $this->getInstance($id); |
|
112
|
|
|
} |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
return $groups; |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
/** |
|
119
|
|
|
* Returns whether an admin group exists or not. |
|
120
|
|
|
* |
|
121
|
|
|
* @param string $group |
|
122
|
|
|
* |
|
123
|
|
|
* @return bool |
|
124
|
|
|
*/ |
|
125
|
|
|
public function hasGroup($group) |
|
126
|
|
|
{ |
|
127
|
|
|
return isset($this->adminGroups[$group]); |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
/** |
|
131
|
|
|
* @return array |
|
132
|
|
|
*/ |
|
133
|
|
|
public function getDashboardGroups() |
|
134
|
|
|
{ |
|
135
|
|
|
$groups = $this->adminGroups; |
|
136
|
|
|
|
|
137
|
|
|
foreach ($this->adminGroups as $name => $adminGroup) { |
|
138
|
|
|
if (isset($adminGroup['items'])) { |
|
139
|
|
|
foreach ($adminGroup['items'] as $key => $item) { |
|
140
|
|
|
// Only Admin Group should be returned |
|
141
|
|
|
if ('' != $item['admin']) { |
|
142
|
|
|
$admin = $this->getInstance($item['admin']); |
|
143
|
|
|
|
|
144
|
|
|
if ($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD)) { |
|
145
|
|
|
$groups[$name]['items'][$key] = $admin; |
|
146
|
|
|
} else { |
|
147
|
|
|
unset($groups[$name]['items'][$key]); |
|
148
|
|
|
} |
|
149
|
|
|
} else { |
|
150
|
|
|
unset($groups[$name]['items'][$key]); |
|
151
|
|
|
} |
|
152
|
|
|
} |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
if (empty($groups[$name]['items'])) { |
|
156
|
|
|
unset($groups[$name]); |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
return $groups; |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* Returns all admins related to the given $group. |
|
165
|
|
|
* |
|
166
|
|
|
* @param string $group |
|
167
|
|
|
* |
|
168
|
|
|
* @throws \InvalidArgumentException |
|
169
|
|
|
* |
|
170
|
|
|
* @return array |
|
171
|
|
|
*/ |
|
172
|
|
|
public function getAdminsByGroup($group) |
|
173
|
|
|
{ |
|
174
|
|
|
if (!isset($this->adminGroups[$group])) { |
|
175
|
|
|
throw new \InvalidArgumentException(sprintf('Group "%s" not found in admin pool.', $group)); |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
$admins = []; |
|
179
|
|
|
|
|
180
|
|
|
if (!isset($this->adminGroups[$group]['items'])) { |
|
181
|
|
|
return $admins; |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
foreach ($this->adminGroups[$group]['items'] as $item) { |
|
185
|
|
|
$admins[] = $this->getInstance($item['admin']); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
return $admins; |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* Return the admin related to the given $class. |
|
193
|
|
|
* |
|
194
|
|
|
* @param string $class |
|
195
|
|
|
* |
|
196
|
|
|
* @return \Sonata\AdminBundle\Admin\AdminInterface|null |
|
197
|
|
|
*/ |
|
198
|
|
|
public function getAdminByClass($class) |
|
199
|
|
|
{ |
|
200
|
|
|
if (!$this->hasAdminByClass($class)) { |
|
201
|
|
|
return; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
if (!is_array($this->adminClasses[$class])) { |
|
205
|
|
|
throw new \RuntimeException('Invalid format for the Pool::adminClass property'); |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
if (count($this->adminClasses[$class]) > 1) { |
|
209
|
|
|
throw new \RuntimeException(sprintf( |
|
210
|
|
|
'Unable to find a valid admin for the class: %s, there are too many registered: %s', |
|
211
|
|
|
$class, |
|
212
|
|
|
implode(', ', $this->adminClasses[$class]) |
|
213
|
|
|
)); |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
return $this->getInstance($this->adminClasses[$class][0]); |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* @param string $class |
|
221
|
|
|
* |
|
222
|
|
|
* @return bool |
|
223
|
|
|
*/ |
|
224
|
|
|
public function hasAdminByClass($class) |
|
225
|
|
|
{ |
|
226
|
|
|
return isset($this->adminClasses[$class]); |
|
227
|
|
|
} |
|
228
|
|
|
|
|
229
|
|
|
/** |
|
230
|
|
|
* Returns an admin class by its Admin code |
|
231
|
|
|
* ie : sonata.news.admin.post|sonata.news.admin.comment => return the child class of post. |
|
232
|
|
|
* |
|
233
|
|
|
* @param string $adminCode |
|
234
|
|
|
* |
|
235
|
|
|
* @return \Sonata\AdminBundle\Admin\AdminInterface|false|null |
|
236
|
|
|
*/ |
|
237
|
|
|
public function getAdminByAdminCode($adminCode) |
|
238
|
|
|
{ |
|
239
|
|
|
$codes = explode('|', $adminCode); |
|
240
|
|
|
|
|
241
|
|
|
if (false === $codes) { |
|
242
|
|
|
return false; |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
$admin = $this->getInstance($codes[0]); |
|
246
|
|
|
array_shift($codes); |
|
247
|
|
|
|
|
248
|
|
|
if (empty($codes)) { |
|
249
|
|
|
return $admin; |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
foreach ($codes as $code) { |
|
253
|
|
|
if (!$admin->hasChild($code)) { |
|
254
|
|
|
return false; |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
$admin = $admin->getChild($code); |
|
258
|
|
|
} |
|
259
|
|
|
|
|
260
|
|
|
return $admin; |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
/** |
|
264
|
|
|
* Returns a new admin instance depends on the given code. |
|
265
|
|
|
* |
|
266
|
|
|
* @param string $id |
|
267
|
|
|
* |
|
268
|
|
|
* @throws \InvalidArgumentException |
|
269
|
|
|
* |
|
270
|
|
|
* @return AdminInterface |
|
271
|
|
|
*/ |
|
272
|
|
|
public function getInstance($id) |
|
273
|
|
|
{ |
|
274
|
|
|
if (!in_array($id, $this->adminServiceIds)) { |
|
275
|
|
|
$msg = sprintf('Admin service "%s" not found in admin pool.', $id); |
|
276
|
|
|
$shortest = -1; |
|
277
|
|
|
$closest = null; |
|
278
|
|
|
$alternatives = []; |
|
279
|
|
|
foreach ($this->adminServiceIds as $adminServiceId) { |
|
280
|
|
|
$lev = levenshtein($id, $adminServiceId); |
|
281
|
|
|
if ($lev <= $shortest || $shortest < 0) { |
|
282
|
|
|
$closest = $adminServiceId; |
|
283
|
|
|
$shortest = $lev; |
|
284
|
|
|
} |
|
285
|
|
|
if ($lev <= strlen($adminServiceId) / 3 || false !== strpos($adminServiceId, $id)) { |
|
286
|
|
|
$alternatives[$adminServiceId] = $lev; |
|
287
|
|
|
} |
|
288
|
|
|
} |
|
289
|
|
|
if (null !== $closest) { |
|
290
|
|
|
asort($alternatives); |
|
291
|
|
|
unset($alternatives[$closest]); |
|
292
|
|
|
$msg = sprintf( |
|
293
|
|
|
'Admin service "%s" not found in admin pool. Did you mean "%s" or one of those: [%s]?', |
|
294
|
|
|
$id, |
|
295
|
|
|
$closest, |
|
296
|
|
|
implode(', ', array_keys($alternatives)) |
|
297
|
|
|
); |
|
298
|
|
|
} |
|
299
|
|
|
throw new \InvalidArgumentException($msg); |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
return $this->container->get($id); |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
/** |
|
306
|
|
|
* @return ContainerInterface|null |
|
307
|
|
|
*/ |
|
308
|
|
|
public function getContainer() |
|
309
|
|
|
{ |
|
310
|
|
|
return $this->container; |
|
311
|
|
|
} |
|
312
|
|
|
|
|
313
|
|
|
public function setAdminGroups(array $adminGroups): void |
|
314
|
|
|
{ |
|
315
|
|
|
$this->adminGroups = $adminGroups; |
|
316
|
|
|
} |
|
317
|
|
|
|
|
318
|
|
|
/** |
|
319
|
|
|
* @return array |
|
320
|
|
|
*/ |
|
321
|
|
|
public function getAdminGroups() |
|
322
|
|
|
{ |
|
323
|
|
|
return $this->adminGroups; |
|
324
|
|
|
} |
|
325
|
|
|
|
|
326
|
|
|
public function setAdminServiceIds(array $adminServiceIds): void |
|
327
|
|
|
{ |
|
328
|
|
|
$this->adminServiceIds = $adminServiceIds; |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
/** |
|
332
|
|
|
* @return array |
|
333
|
|
|
*/ |
|
334
|
|
|
public function getAdminServiceIds() |
|
335
|
|
|
{ |
|
336
|
|
|
return $this->adminServiceIds; |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
public function setAdminClasses(array $adminClasses): void |
|
340
|
|
|
{ |
|
341
|
|
|
$this->adminClasses = $adminClasses; |
|
342
|
|
|
} |
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* @return array |
|
346
|
|
|
*/ |
|
347
|
|
|
public function getAdminClasses() |
|
348
|
|
|
{ |
|
349
|
|
|
return $this->adminClasses; |
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
final public function setTemplateRegistry(MutableTemplateRegistryInterface $templateRegistry): void |
|
353
|
|
|
{ |
|
354
|
|
|
$this->templateRegistry = $templateRegistry; |
|
355
|
|
|
} |
|
356
|
|
|
|
|
357
|
|
|
/** |
|
358
|
|
|
* @deprecated since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" instead |
|
359
|
|
|
*/ |
|
360
|
|
|
public function setTemplates(array $templates): void |
|
361
|
|
|
{ |
|
362
|
|
|
// NEXT MAJOR: Remove this line |
|
363
|
|
|
$this->templates = $templates; |
|
|
|
|
|
|
364
|
|
|
|
|
365
|
|
|
$this->templateRegistry->setTemplates($templates); |
|
366
|
|
|
} |
|
367
|
|
|
|
|
368
|
|
|
/** |
|
369
|
|
|
* @deprecated since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" instead |
|
370
|
|
|
* |
|
371
|
|
|
* @return array |
|
372
|
|
|
*/ |
|
373
|
|
|
public function getTemplates() |
|
374
|
|
|
{ |
|
375
|
|
|
return $this->templateRegistry->getTemplates(); |
|
376
|
|
|
} |
|
377
|
|
|
|
|
378
|
|
|
/** |
|
379
|
|
|
* @deprecated since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" instead |
|
380
|
|
|
* |
|
381
|
|
|
* @param string $name |
|
382
|
|
|
* |
|
383
|
|
|
* @return null|string |
|
384
|
|
|
*/ |
|
385
|
|
|
public function getTemplate($name) |
|
386
|
|
|
{ |
|
387
|
|
|
return $this->templateRegistry->getTemplate($name); |
|
388
|
|
|
} |
|
389
|
|
|
|
|
390
|
|
|
/** |
|
391
|
|
|
* @return string |
|
392
|
|
|
*/ |
|
393
|
|
|
public function getTitleLogo() |
|
394
|
|
|
{ |
|
395
|
|
|
return $this->titleLogo; |
|
396
|
|
|
} |
|
397
|
|
|
|
|
398
|
|
|
/** |
|
399
|
|
|
* @return string |
|
400
|
|
|
*/ |
|
401
|
|
|
public function getTitle() |
|
402
|
|
|
{ |
|
403
|
|
|
return $this->title; |
|
404
|
|
|
} |
|
405
|
|
|
|
|
406
|
|
|
/** |
|
407
|
|
|
* @param string $name |
|
408
|
|
|
* @param mixed $default |
|
409
|
|
|
* |
|
410
|
|
|
* @return mixed |
|
411
|
|
|
*/ |
|
412
|
|
|
public function getOption($name, $default = null) |
|
413
|
|
|
{ |
|
414
|
|
|
if (isset($this->options[$name])) { |
|
415
|
|
|
return $this->options[$name]; |
|
416
|
|
|
} |
|
417
|
|
|
|
|
418
|
|
|
return $default; |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
public function getPropertyAccessor() |
|
422
|
|
|
{ |
|
423
|
|
|
if (null === $this->propertyAccessor) { |
|
424
|
|
|
$this->propertyAccessor = PropertyAccess::createPropertyAccessor(); |
|
425
|
|
|
} |
|
426
|
|
|
|
|
427
|
|
|
return $this->propertyAccessor; |
|
428
|
|
|
} |
|
429
|
|
|
} |
|
430
|
|
|
|
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.