Pool::getTitleLogo()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 InvalidArgumentException;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\PropertyAccess\PropertyAccess;
19
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
20
21
/**
22
 * @final since sonata-project/admin-bundle 3.52
23
 *
24
 * @author Thomas Rabaix <[email protected]>
25
 */
26
class Pool
27
{
28
    /**
29
     * @var ContainerInterface
30
     */
31
    protected $container;
32
33
    /**
34
     * @var string[]
35
     */
36
    protected $adminServiceIds = [];
37
38
    /**
39
     * @var array
40
     */
41
    protected $adminGroups = [];
42
43
    /**
44
     * @var array
45
     */
46
    protected $adminClasses = [];
47
48
    /**
49
     * @var array
50
     */
51
    protected $assets = [];
52
53
    /**
54
     * @var string
55
     */
56
    protected $title;
57
58
    /**
59
     * @var string
60
     */
61
    protected $titleLogo;
62
63
    /**
64
     * @var array
65
     */
66
    protected $options = [];
67
68
    /**
69
     * @var PropertyAccessorInterface
70
     */
71
    protected $propertyAccessor;
72
73
    public function __construct(
74
        ContainerInterface $container,
75
        string $title,
76
        string $logoTitle,
77
        array $options = [],
78
        ?PropertyAccessorInterface $propertyAccessor = null
79
    ) {
80
        $this->container = $container;
81
        $this->title = $title;
82
        $this->titleLogo = $logoTitle;
83
        $this->options = $options;
84
        $this->propertyAccessor = $propertyAccessor;
85
    }
86
87
    public function getGroups(): array
88
    {
89
        $groups = $this->adminGroups;
90
91
        foreach ($this->adminGroups as $name => $adminGroup) {
92
            foreach ($adminGroup as $id => $options) {
93
                $groups[$name][$id] = $this->getInstance($id);
94
            }
95
        }
96
97
        return $groups;
98
    }
99
100
    /**
101
     * Returns whether an admin group exists or not.
102
     */
103
    public function hasGroup(string $group): bool
104
    {
105
        return isset($this->adminGroups[$group]);
106
    }
107
108
    public function getDashboardGroups(): array
109
    {
110
        $groups = $this->adminGroups;
111
112
        foreach ($this->adminGroups as $name => $adminGroup) {
113
            if (isset($adminGroup['items'])) {
114
                foreach ($adminGroup['items'] as $key => $item) {
115
                    // Only Admin Group should be returned
116
                    if ('' !== $item['admin']) {
117
                        $admin = $this->getInstance($item['admin']);
118
119
                        if ($admin->showIn(AbstractAdmin::CONTEXT_DASHBOARD)) {
120
                            $groups[$name]['items'][$key] = $admin;
121
                        } else {
122
                            unset($groups[$name]['items'][$key]);
123
                        }
124
                    } else {
125
                        unset($groups[$name]['items'][$key]);
126
                    }
127
                }
128
            }
129
130
            if (empty($groups[$name]['items'])) {
131
                unset($groups[$name]);
132
            }
133
        }
134
135
        return $groups;
136
    }
137
138
    /**
139
     * Returns all admins related to the given $group.
140
     *
141
     * @throws \InvalidArgumentException
142
     *
143
     * @return AdminInterface[]
144
     */
145
    public function getAdminsByGroup(string $group): array
146
    {
147
        if (!isset($this->adminGroups[$group])) {
148
            throw new \InvalidArgumentException(sprintf('Group "%s" not found in admin pool.', $group));
149
        }
150
151
        $admins = [];
152
153
        if (!isset($this->adminGroups[$group]['items'])) {
154
            return $admins;
155
        }
156
157
        foreach ($this->adminGroups[$group]['items'] as $item) {
158
            $admins[] = $this->getInstance($item['admin']);
159
        }
160
161
        return $admins;
162
    }
163
164
    /**
165
     * Return the admin related to the given $class.
166
     */
167
    public function getAdminByClass(string $class): AdminInterface
168
    {
169
        if (!$this->hasAdminByClass($class)) {
170
            throw new \LogicException(sprintf('Pool has no admin for the class %s.', $class));
171
        }
172
173
        if (!\is_array($this->adminClasses[$class])) {
174
            throw new \RuntimeException('Invalid format for the Pool::adminClass property');
175
        }
176
177
        if (\count($this->adminClasses[$class]) > 1) {
178
            throw new \RuntimeException(sprintf(
179
                'Unable to find a valid admin for the class: %s, there are too many registered: %s',
180
                $class,
181
                implode(', ', $this->adminClasses[$class])
182
            ));
183
        }
184
185
        return $this->getInstance($this->adminClasses[$class][0]);
186
    }
187
188
    public function hasAdminByClass(string $class): bool
189
    {
190
        return isset($this->adminClasses[$class]);
191
    }
192
193
    /**
194
     * Returns an admin class by its Admin code
195
     * ie : sonata.news.admin.post|sonata.news.admin.comment => return the child class of post.
196
     *
197
     * @throws \InvalidArgumentException if the root admin code is an empty string
198
     */
199
    public function getAdminByAdminCode(string $adminCode): AdminInterface
200
    {
201
        $codes = explode('|', $adminCode);
202
        $code = trim(array_shift($codes));
203
204
        if ('' === $code) {
205
            throw new \InvalidArgumentException(
206
                'Root admin code must contain a valid admin reference, empty string given.'
207
            );
208
        }
209
210
        $admin = $this->getInstance($code);
211
212
        foreach ($codes as $code) {
213
            if (!\in_array($code, $this->adminServiceIds, true)) {
214
                throw new \InvalidArgumentException(sprintf(
215
                    'Argument 1 passed to %s() must contain a valid admin reference, "%s" found at "%s".',
216
                    __METHOD__,
217
                    $code,
218
                    $adminCode
219
                ));
220
            }
221
222
            if (!$admin->hasChild($code)) {
223
                throw new \InvalidArgumentException(sprintf(
224
                    'Argument 1 passed to %s() must contain a valid admin hierarchy, "%s" is not a valid child for "%s"',
225
                    __METHOD__,
226
                    $code,
227
                    $admin->getCode()
228
                ));
229
            }
230
231
            $admin = $admin->getChild($code);
232
        }
233
234
        return $admin;
235
    }
236
237
    /**
238
     * Checks if an admin with a certain admin code exists.
239
     */
240
    final public function hasAdminByAdminCode(string $adminCode): bool
241
    {
242
        try {
243
            $this->getAdminByAdminCode($adminCode);
244
        } catch (\InvalidArgumentException $e) {
245
            return false;
246
        }
247
248
        return true;
249
    }
250
251
    /**
252
     * Returns a new admin instance depends on the given code.
253
     *
254
     * @throws \InvalidArgumentException
255
     */
256
    public function getInstance(string $id): AdminInterface
257
    {
258
        if (!\in_array($id, $this->adminServiceIds, true)) {
259
            $msg = sprintf('Admin service "%s" not found in admin pool.', $id);
260
            $shortest = -1;
261
            $closest = null;
262
            $alternatives = [];
263
            foreach ($this->adminServiceIds as $adminServiceId) {
264
                $lev = levenshtein($id, $adminServiceId);
265
                if ($lev <= $shortest || $shortest < 0) {
266
                    $closest = $adminServiceId;
267
                    $shortest = $lev;
268
                }
269
                if ($lev <= \strlen($adminServiceId) / 3 || false !== strpos($adminServiceId, $id)) {
270
                    $alternatives[$adminServiceId] = $lev;
271
                }
272
            }
273
            if (null !== $closest) {
274
                asort($alternatives);
275
                unset($alternatives[$closest]);
276
                $msg = sprintf(
277
                    'Admin service "%s" not found in admin pool. Did you mean "%s" or one of those: [%s]?',
278
                    $id,
279
                    $closest,
280
                    implode(', ', array_keys($alternatives))
281
                );
282
            }
283
            throw new \InvalidArgumentException($msg);
284
        }
285
286
        $admin = $this->container->get($id);
287
288
        if (!$admin instanceof AdminInterface) {
289
            throw new InvalidArgumentException(sprintf('Found service "%s" is not a valid admin service', $id));
290
        }
291
292
        return $admin;
293
    }
294
295
    public function getContainer(): ContainerInterface
296
    {
297
        return $this->container;
298
    }
299
300
    public function setAdminGroups(array $adminGroups): void
301
    {
302
        $this->adminGroups = $adminGroups;
303
    }
304
305
    public function getAdminGroups(): array
306
    {
307
        return $this->adminGroups;
308
    }
309
310
    public function setAdminServiceIds(array $adminServiceIds): void
311
    {
312
        $this->adminServiceIds = $adminServiceIds;
313
    }
314
315
    public function getAdminServiceIds(): array
316
    {
317
        return $this->adminServiceIds;
318
    }
319
320
    public function setAdminClasses(array $adminClasses): void
321
    {
322
        $this->adminClasses = $adminClasses;
323
    }
324
325
    public function getAdminClasses(): array
326
    {
327
        return $this->adminClasses;
328
    }
329
330
    public function getTitleLogo(): string
331
    {
332
        return $this->titleLogo;
333
    }
334
335
    public function getTitle(): string
336
    {
337
        return $this->title;
338
    }
339
340
    /**
341
     * @param mixed $default
342
     *
343
     * @return mixed
344
     */
345
    public function getOption(string $name, $default = null)
346
    {
347
        if (isset($this->options[$name])) {
348
            return $this->options[$name];
349
        }
350
351
        return $default;
352
    }
353
354
    public function getPropertyAccessor(): PropertyAccessorInterface
355
    {
356
        if (null === $this->propertyAccessor) {
357
            $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
358
        }
359
360
        return $this->propertyAccessor;
361
    }
362
}
363