Completed
Push — master ( 2ff8b4...848fca )
by Grégoire
20s
created

SonataAdminExtension::buildJavascripts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
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\DependencyInjection;
15
16
use JMS\DiExtraBundle\DependencyInjection\Configuration;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Sonata\AdminBundle\Depen...Injection\Configuration.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
use Sonata\AdminBundle\Admin\AbstractAdmin;
18
use Sonata\AdminBundle\Admin\AbstractAdminExtension;
19
use Sonata\AdminBundle\Admin\AdminExtensionInterface;
20
use Sonata\AdminBundle\Admin\AdminHelper;
21
use Sonata\AdminBundle\Admin\AdminInterface;
22
use Sonata\AdminBundle\Admin\BaseFieldDescription;
23
use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
24
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
25
use Sonata\AdminBundle\Admin\Pool;
26
use Sonata\AdminBundle\Block\AdminListBlockService;
27
use Sonata\AdminBundle\Builder\DatagridBuilderInterface;
28
use Sonata\AdminBundle\Builder\FormContractorInterface;
29
use Sonata\AdminBundle\Builder\ListBuilderInterface;
30
use Sonata\AdminBundle\Builder\RouteBuilderInterface;
31
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
32
use Sonata\AdminBundle\Datagrid\Datagrid;
33
use Sonata\AdminBundle\Datagrid\DatagridInterface;
34
use Sonata\AdminBundle\Datagrid\DatagridMapper;
35
use Sonata\AdminBundle\Datagrid\ListMapper;
36
use Sonata\AdminBundle\Datagrid\Pager;
37
use Sonata\AdminBundle\Datagrid\PagerInterface;
38
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
39
use Sonata\AdminBundle\Exception\ModelManagerException;
40
use Sonata\AdminBundle\Exception\NoValueException;
41
use Sonata\AdminBundle\Filter\Filter;
42
use Sonata\AdminBundle\Filter\FilterFactory;
43
use Sonata\AdminBundle\Filter\FilterFactoryInterface;
44
use Sonata\AdminBundle\Filter\FilterInterface;
45
use Sonata\AdminBundle\Form\DataTransformer\ArrayToModelTransformer;
46
use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
47
use Sonata\AdminBundle\Form\DataTransformer\ModelToIdTransformer;
48
use Sonata\AdminBundle\Form\EventListener\MergeCollectionListener;
49
use Sonata\AdminBundle\Form\Extension\Field\Type\FormTypeFieldExtension;
50
use Sonata\AdminBundle\Form\FormMapper;
51
use Sonata\AdminBundle\Form\Type\AdminType;
52
use Sonata\AdminBundle\Form\Type\Filter\ChoiceType;
53
use Sonata\AdminBundle\Form\Type\Filter\DateRangeType;
54
use Sonata\AdminBundle\Form\Type\Filter\DateTimeRangeType;
55
use Sonata\AdminBundle\Form\Type\Filter\DateTimeType;
56
use Sonata\AdminBundle\Form\Type\Filter\DateType;
57
use Sonata\AdminBundle\Form\Type\Filter\DefaultType;
58
use Sonata\AdminBundle\Form\Type\Filter\NumberType;
59
use Sonata\AdminBundle\Form\Type\ModelListType;
60
use Sonata\AdminBundle\Form\Type\ModelReferenceType;
61
use Sonata\AdminBundle\Form\Type\ModelType;
62
use Sonata\AdminBundle\Guesser\TypeGuesserChain;
63
use Sonata\AdminBundle\Guesser\TypeGuesserInterface;
64
use Sonata\AdminBundle\Model\AuditManager;
65
use Sonata\AdminBundle\Model\AuditManagerInterface;
66
use Sonata\AdminBundle\Model\AuditReaderInterface;
67
use Sonata\AdminBundle\Model\ModelManagerInterface;
68
use Sonata\AdminBundle\Route\AdminPoolLoader;
69
use Sonata\AdminBundle\Route\DefaultRouteGenerator;
70
use Sonata\AdminBundle\Route\PathInfoBuilder;
71
use Sonata\AdminBundle\Route\QueryStringBuilder;
72
use Sonata\AdminBundle\Route\RouteCollection;
73
use Sonata\AdminBundle\Route\RouteGeneratorInterface;
74
use Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap;
75
use Sonata\AdminBundle\Security\Acl\Permission\MaskBuilder;
76
use Sonata\AdminBundle\Security\Handler\AclSecurityHandler;
77
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
78
use Sonata\AdminBundle\Security\Handler\NoopSecurityHandler;
79
use Sonata\AdminBundle\Security\Handler\RoleSecurityHandler;
80
use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface;
81
use Sonata\AdminBundle\Show\ShowMapper;
82
use Sonata\AdminBundle\Translator\BCLabelTranslatorStrategy;
83
use Sonata\AdminBundle\Translator\FormLabelTranslatorStrategy;
84
use Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface;
85
use Sonata\AdminBundle\Translator\NativeLabelTranslatorStrategy;
86
use Sonata\AdminBundle\Translator\NoopLabelTranslatorStrategy;
87
use Sonata\AdminBundle\Translator\UnderscoreLabelTranslatorStrategy;
88
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension as TwigSonataAdminExtension;
89
use Sonata\AdminBundle\Util\AdminAclManipulator;
90
use Sonata\AdminBundle\Util\AdminAclManipulatorInterface;
91
use Sonata\AdminBundle\Util\FormBuilderIterator;
92
use Sonata\AdminBundle\Util\FormViewIterator;
93
use Sonata\AdminBundle\Util\ObjectAclManipulator;
94
use Sonata\AdminBundle\Util\ObjectAclManipulatorInterface;
95
use Symfony\Component\Config\FileLocator;
96
use Symfony\Component\DependencyInjection\ContainerBuilder;
97
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
98
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
99
use Symfony\Component\DependencyInjection\Reference;
100
use Symfony\Component\Form\Extension\Core\Type\ChoiceType as SymfonyChoiceType;
101
use Symfony\Component\Form\Extension\Core\Type\DateTimeType as SymfonyDateTimeType;
102
use Symfony\Component\Form\Extension\Core\Type\DateType as SymfonyDateType;
103
use Symfony\Component\Form\Extension\Core\Type\EmailType as SymfonyEmailType;
104
use Symfony\Component\Form\Extension\Core\Type\IntegerType as SymfonyIntegerType;
105
use Symfony\Component\Form\Extension\Core\Type\TextareaType as SymfonyTextareaType;
106
use Symfony\Component\Form\Extension\Core\Type\TextType as SymfonyTextType;
107
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
108
109
/**
110
 * @author Thomas Rabaix <[email protected]>
111
 * @author Michael Williams <[email protected]>
112
 */
113
final class SonataAdminExtension extends Extension implements PrependExtensionInterface
114
{
115
    public function load(array $configs, ContainerBuilder $container): void
116
    {
117
        $bundles = $container->getParameter('kernel.bundles');
118
119
        if (isset($bundles['SonataUserBundle'])) {
120
            // integrate the SonataUserBundle / FOSUserBundle if the bundle exists
121
            array_unshift($configs, [
122
                'templates' => [
123
                    'user_block' => 'SonataUserBundle:Admin/Core:user_block.html.twig',
124
                ],
125
            ]);
126
        }
127
128
        if (isset($bundles['SonataIntlBundle'])) {
129
            // integrate the SonataUserBundle if the bundle exists
130
            array_unshift($configs, [
131
                'templates' => [
132
                    'history_revision_timestamp' => 'SonataIntlBundle:CRUD:history_revision_timestamp.html.twig',
133
                ],
134
            ]);
135
        }
136
137
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
138
        $loader->load('twig.xml');
139
        $loader->load('core.xml');
140
        $loader->load('form_types.xml');
141
        $loader->load('validator.xml');
142
        $loader->load('route.xml');
143
        $loader->load('block.xml');
144
        $loader->load('menu.xml');
145
        $loader->load('commands.xml');
146
147
        if (isset($bundles['SonataExporterBundle'])) {
148
            $loader->load('exporter.xml');
149
        }
150
151
        $container->getDefinition('sonata.admin.exporter')->setDeprecated(
152
            'The service "%service_id%" is deprecated in favor of the "sonata.exporter.exporter" service'
0 ignored issues
show
Documentation introduced by
'The service "%service_i...rter.exporter" service' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
153
        );
154
155
        $configuration = $this->getConfiguration($configs, $container);
156
        $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
Documentation introduced by
$configuration is of type object|null, but the function expects a object<Symfony\Component...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
157
158
        $config['options']['javascripts'] = $this->buildJavascripts($config);
159
        $config['options']['stylesheets'] = $this->buildStylesheets($config);
160
        $config['options']['role_admin'] = $config['security']['role_admin'];
161
        $config['options']['role_super_admin'] = $config['security']['role_super_admin'];
162
163
        $pool = $container->getDefinition('sonata.admin.pool');
164
        $pool->replaceArgument(1, $config['title']);
165
        $pool->replaceArgument(2, $config['title_logo']);
166
        $pool->replaceArgument(3, $config['options']);
167
168
        if (false === $config['options']['lock_protection']) {
169
            $container->removeDefinition('sonata.admin.lock.extension');
170
        }
171
172
        $container->setParameter('sonata.admin.configuration.global_search.empty_boxes', $config['global_search']['empty_boxes']);
173
        $container->setParameter('sonata.admin.configuration.templates', $config['templates'] + [
174
            'user_block' => 'SonataAdminBundle:Core:user_block.html.twig',
175
            'add_block' => 'SonataAdminBundle:Core:add_block.html.twig',
176
            'layout' => 'SonataAdminBundle::standard_layout.html.twig',
177
            'ajax' => 'SonataAdminBundle::ajax_layout.html.twig',
178
            'dashboard' => 'SonataAdminBundle:Core:dashboard.html.twig',
179
            'list' => 'SonataAdminBundle:CRUD:list.html.twig',
180
            'filter' => 'SonataAdminBundle:Form:filter_admin_fields.html.twig',
181
            'show' => 'SonataAdminBundle:CRUD:show.html.twig',
182
            'show_compare' => 'SonataAdminBundle:CRUD:show_compare.html.twig',
183
            'edit' => 'SonataAdminBundle:CRUD:edit.html.twig',
184
            'history' => 'SonataAdminBundle:CRUD:history.html.twig',
185
            'history_revision_timestamp' => 'SonataAdminBundle:CRUD:history_revision_timestamp.html.twig',
186
            'acl' => 'SonataAdminBundle:CRUD:acl.html.twig',
187
            'action' => 'SonataAdminBundle:CRUD:action.html.twig',
188
            'short_object_description' => 'SonataAdminBundle:Helper:short-object-description.html.twig',
189
            'preview' => 'SonataAdminBundle:CRUD:preview.html.twig',
190
            'list_block' => 'SonataAdminBundle:Block:block_admin_list.html.twig',
191
            'delete' => 'SonataAdminBundle:CRUD:delete.html.twig',
192
            'batch' => 'SonataAdminBundle:CRUD:list__batch.html.twig',
193
            'select' => 'SonataAdminBundle:CRUD:list__select.html.twig',
194
            'batch_confirmation' => 'SonataAdminBundle:CRUD:batch_confirmation.html.twig',
195
            'inner_list_row' => 'SonataAdminBundle:CRUD:list_inner_row.html.twig',
196
            'base_list_field' => 'SonataAdminBundle:CRUD:base_list_field.html.twig',
197
            'pager_links' => 'SonataAdminBundle:Pager:links.html.twig',
198
            'pager_results' => 'SonataAdminBundle:Pager:results.html.twig',
199
            'tab_menu_template' => 'SonataAdminBundle:Core:tab_menu_template.html.twig',
200
            'knp_menu_template' => 'SonataAdminBundle:Menu:sonata_menu.html.twig',
201
            'outer_list_rows_mosaic' => 'SonataAdminBundle:CRUD:list_outer_rows_mosaic.html.twig',
202
            'outer_list_rows_list' => 'SonataAdminBundle:CRUD:list_outer_rows_list.html.twig',
203
            'outer_list_rows_tree' => 'SonataAdminBundle:CRUD:list_outer_rows_tree.html.twig',
204
        ]);
205
        $container->setParameter('sonata.admin.configuration.admin_services', $config['admin_services']);
206
        $container->setParameter('sonata.admin.configuration.dashboard_groups', $config['dashboard']['groups']);
207
        $container->setParameter('sonata.admin.configuration.dashboard_blocks', $config['dashboard']['blocks']);
208
        $container->setParameter('sonata.admin.configuration.sort_admins', $config['options']['sort_admins']);
209
        $container->setParameter('sonata.admin.configuration.breadcrumbs', $config['breadcrumbs']);
210
211
        if (null === $config['security']['acl_user_manager'] && isset($bundles['FOSUserBundle'])) {
212
            $container->setParameter('sonata.admin.security.acl_user_manager', 'fos_user.user_manager');
213
        } else {
214
            $container->setParameter('sonata.admin.security.acl_user_manager', $config['security']['acl_user_manager']);
215
        }
216
217
        $container->setAlias('sonata.admin.security.handler', $config['security']['handler']);
218
219
        switch ($config['security']['handler']) {
220
            case 'sonata.admin.security.handler.role':
221
                if (0 === count($config['security']['information'])) {
222
                    $config['security']['information'] = [
223
                        'EDIT' => ['EDIT'],
224
                        'LIST' => ['LIST'],
225
                        'CREATE' => ['CREATE'],
226
                        'VIEW' => ['VIEW'],
227
                        'DELETE' => ['DELETE'],
228
                        'EXPORT' => ['EXPORT'],
229
                        'ALL' => ['ALL'],
230
                    ];
231
                }
232
233
                break;
234
            case 'sonata.admin.security.handler.acl':
235
                if (0 === count($config['security']['information'])) {
236
                    $config['security']['information'] = [
237
                        'GUEST' => ['VIEW', 'LIST'],
238
                        'STAFF' => ['EDIT', 'LIST', 'CREATE'],
239
                        'EDITOR' => ['OPERATOR', 'EXPORT'],
240
                        'ADMIN' => ['MASTER'],
241
                    ];
242
                }
243
244
                break;
245
        }
246
247
        $container->setParameter('sonata.admin.configuration.security.role_admin', $config['security']['role_admin']);
248
        $container->setParameter('sonata.admin.configuration.security.role_super_admin', $config['security']['role_super_admin']);
249
        $container->setParameter('sonata.admin.configuration.security.information', $config['security']['information']);
250
        $container->setParameter('sonata.admin.configuration.security.admin_permissions', $config['security']['admin_permissions']);
251
        $container->setParameter('sonata.admin.configuration.security.object_permissions', $config['security']['object_permissions']);
252
253
        $loader->load('security.xml');
254
255
        $container->setParameter('sonata.admin.extension.map', $config['extensions']);
256
257
        /*
258
         * This is a work in progress, so for now it is hardcoded
259
         */
260
        $classes = [
261
            'email' => '',
262
            'textarea' => '',
263
            'text' => '',
264
            'choice' => '',
265
            'integer' => '',
266
            'datetime' => 'sonata-medium-date',
267
            'date' => 'sonata-medium-date',
268
269
            // SF3+
270
            SymfonyChoiceType::class => '',
271
            SymfonyDateType::class => 'sonata-medium-date',
272
            SymfonyDateTimeType::class => 'sonata-medium-date',
273
            SymfonyEmailType::class => '',
274
            SymfonyIntegerType::class => '',
275
            SymfonyTextareaType::class => '',
276
            SymfonyTextType::class => '',
277
        ];
278
279
        $container->getDefinition('sonata.admin.form.extension.field')
280
            ->replaceArgument(0, $classes)
281
            ->replaceArgument(1, $config['options']);
282
283
        // remove non used service
284
        if (!isset($bundles['JMSTranslationBundle'])) {
285
            $container->removeDefinition('sonata.admin.translator.extractor.jms_translator_bundle');
286
        }
287
288
        //remove non-Mopa compatibility layer
289
        if (isset($bundles['MopaBootstrapBundle'])) {
290
            $container->removeDefinition('sonata.admin.form.extension.field.mopa');
291
        }
292
293
        // set filter persistence
294
        $container->setParameter('sonata.admin.configuration.filters.persist', $config['persist_filters']);
295
296
        $container->setParameter('sonata.admin.configuration.show.mosaic.button', $config['show_mosaic_button']);
297
298
        $container->setParameter('sonata.admin.configuration.translate_group_label', $config['translate_group_label']);
299
300
        if (\PHP_VERSION_ID < 70000) {
301
            $this->configureClassesToCompile();
302
        }
303
304
        $this->replacePropertyAccessor($container);
305
    }
306
307
    /**
308
     * Allow an extension to prepend the extension configurations.
309
     *
310
     * NEXT_MAJOR: remove all code that deals with JMSDiExtraBundle
311
     */
312
    public function prepend(ContainerBuilder $container): void
313
    {
314
        $bundles = $container->getParameter('kernel.bundles');
315
316
        if (!isset($bundles['JMSDiExtraBundle'])) {
317
            return;
318
        }
319
320
        $configs = $container->getExtensionConfig($this->getAlias());
321
        $config = $this->processConfiguration(new Configuration(), $configs);
322
        if (!$config['options']['enable_jms_di_extra_autoregistration']) {
323
            return;
324
        }
325
326
        $sonataAdminPattern = 'Sonata\AdminBundle\Annotation';
327
        $annotationPatternsConfigured = false;
328
329
        $diExtraConfigs = $container->getExtensionConfig('jms_di_extra');
330
        foreach ($diExtraConfigs as $diExtraConfig) {
331
            if (isset($diExtraConfig['annotation_patterns'])) {
332
                // don't add our own pattern if user has already done so
333
                if (false !== array_search($sonataAdminPattern, $diExtraConfig['annotation_patterns'])) {
334
                    return;
335
                }
336
                $annotationPatternsConfigured = true;
337
338
                break;
339
            }
340
        }
341
342
        @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
343
            'Automatic registration of annotations is deprecated since 3.14, to be removed in 4.0.',
344
            E_USER_DEPRECATED
345
        );
346
347
        if ($annotationPatternsConfigured) {
348
            $annotationPatterns = [$sonataAdminPattern];
349
        } else {
350
            // get annotation_patterns default from DiExtraBundle configuration
351
            $diExtraConfigDefinition = new Configuration();
352
            // FIXME: this will break if DiExtraBundle adds any mandatory configuration
353
            $diExtraConfig = $this->processConfiguration($diExtraConfigDefinition, []);
354
355
            $annotationPatterns = $diExtraConfig['annotation_patterns'];
356
            $annotationPatterns[] = $sonataAdminPattern;
357
        }
358
359
        $container->prependExtensionConfig(
360
            'jms_di_extra',
361
            [
362
                'annotation_patterns' => $annotationPatterns,
363
            ]
364
        );
365
    }
366
367
    public function configureClassesToCompile(): void
368
    {
369
        $this->addClassesToCompile([
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\HttpKe...::addClassesToCompile() has been deprecated with message: since version 3.3, to be removed in 4.0.

This method 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 method will be removed from the class and what other method or class to use instead.

Loading history...
370
            AbstractAdmin::class,
371
            AbstractAdminExtension::class,
372
            AdminExtensionInterface::class,
373
            AdminHelper::class,
374
            AdminInterface::class,
375
            BaseFieldDescription::class,
376
            FieldDescriptionCollection::class,
377
            FieldDescriptionInterface::class,
378
            Pool::class,
379
            AdminListBlockService::class,
380
            DatagridBuilderInterface::class,
381
            FormContractorInterface::class,
382
            ListBuilderInterface::class,
383
            RouteBuilderInterface::class,
384
            ShowBuilderInterface::class,
385
            Datagrid::class,
386
            DatagridInterface::class,
387
            DatagridMapper::class,
388
            ListMapper::class,
389
            Pager::class,
390
            PagerInterface::class,
391
            ProxyQueryInterface::class,
392
            ModelManagerException::class,
393
            NoValueException::class,
394
            Filter::class,
395
            FilterFactory::class,
396
            FilterFactoryInterface::class,
397
            FilterInterface::class,
398
            ArrayToModelTransformer::class,
399
            ModelsToArrayTransformer::class,
400
            ModelToIdTransformer::class,
401
            MergeCollectionListener::class,
402
            FormTypeFieldExtension::class,
403
            FormMapper::class,
404
            AdminType::class,
405
            ChoiceType::class,
406
            DateRangeType::class,
407
            DateTimeRangeType::class,
408
            DateTimeType::class,
409
            DateType::class,
410
            DefaultType::class,
411
            NumberType::class,
412
            ModelReferenceType::class,
413
            ModelType::class,
414
            ModelListType::class,
415
            TypeGuesserChain::class,
416
            TypeGuesserInterface::class,
417
            AuditManager::class,
418
            AuditManagerInterface::class,
419
            AuditReaderInterface::class,
420
            ModelManagerInterface::class,
421
            AdminPoolLoader::class,
422
            DefaultRouteGenerator::class,
423
            PathInfoBuilder::class,
424
            QueryStringBuilder::class,
425
            RouteCollection::class,
426
            RouteGeneratorInterface::class,
427
            AdminPermissionMap::class,
428
            MaskBuilder::class,
429
            AclSecurityHandler::class,
430
            AclSecurityHandlerInterface::class,
431
            NoopSecurityHandler::class,
432
            RoleSecurityHandler::class,
433
            SecurityHandlerInterface::class,
434
            ShowMapper::class,
435
            BCLabelTranslatorStrategy::class,
436
            FormLabelTranslatorStrategy::class,
437
            LabelTranslatorStrategyInterface::class,
438
            NativeLabelTranslatorStrategy::class,
439
            NoopLabelTranslatorStrategy::class,
440
            UnderscoreLabelTranslatorStrategy::class,
441
            TwigSonataAdminExtension::class,
442
            AdminAclManipulator::class,
443
            AdminAclManipulatorInterface::class,
444
            FormBuilderIterator::class,
445
            FormViewIterator::class,
446
            ObjectAclManipulator::class,
447
            ObjectAclManipulatorInterface::class,
448
        ]);
449
    }
450
451
    public function getNamespace()
452
    {
453
        return 'https://sonata-project.org/schema/dic/admin';
454
    }
455
456
    private function buildStylesheets($config)
457
    {
458
        return $this->mergeArray(
459
            $config['assets']['stylesheets'],
460
            $config['assets']['extra_stylesheets'],
461
            $config['assets']['remove_stylesheets']
462
        );
463
    }
464
465
    private function buildJavascripts($config)
466
    {
467
        return $this->mergeArray(
468
            $config['assets']['javascripts'],
469
            $config['assets']['extra_javascripts'],
470
            $config['assets']['remove_javascripts']
471
        );
472
    }
473
474
    private function mergeArray($array, $addArray, $removeArray = [])
475
    {
476
        foreach ($addArray as $toAdd) {
477
            array_push($array, $toAdd);
478
        }
479
        foreach ($removeArray as $toRemove) {
480
            if (in_array($toRemove, $array)) {
481
                array_splice($array, array_search($toRemove, $array), 1);
482
            }
483
        }
484
485
        return $array;
486
    }
487
488
    private function replacePropertyAccessor(ContainerBuilder $container): void
489
    {
490
        if (!$container->has('form.property_accessor')) {
491
            return;
492
        }
493
494
        $pool = $container->getDefinition('sonata.admin.pool');
495
        $pool->replaceArgument(4, new Reference('form.property_accessor'));
496
497
        $modelChoice = $container->getDefinition('sonata.admin.form.type.model_choice');
498
        $modelChoice->replaceArgument(0, new Reference('form.property_accessor'));
499
    }
500
}
501