Completed
Push — master ( 2eb0ca...af375c )
by Marko
14s
created

Pool::getInstance()   B

Complexity

Conditions 8
Paths 11

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 8.1635
c 0
b 0
f 0
cc 8
nc 11
nop 1
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;
0 ignored issues
show
Deprecated Code introduced by
The property Sonata\AdminBundle\Admin\Pool::$templates has been deprecated with message: since 3.34, will be dropped in 4.0. Use TemplateRegistry "sonata.admin.global_template_registry" instead

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.

Loading history...
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