Completed
Push — master ( 31a9ea...5d6556 )
by
unknown
03:38 queued 11s
created

SonataMediaExtension::configureStringExtension()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 2
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\MediaBundle\DependencyInjection;
15
16
use Sonata\ClassificationBundle\Model\CategoryInterface;
17
use Sonata\EasyExtendsBundle\Mapper\DoctrineCollector;
18
use Symfony\Component\Config\Definition\Processor;
19
use Symfony\Component\Config\FileLocator;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
23
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
24
use Symfony\Component\DependencyInjection\Reference;
25
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
26
27
/**
28
 * @final since sonata-project/media-bundle 3.21.0
29
 *
30
 * @author Thomas Rabaix <[email protected]>
31
 */
32
class SonataMediaExtension extends Extension implements PrependExtensionInterface
33
{
34
    /**
35
     * @var array
36
     */
37
    private $bundleConfigs;
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function load(array $configs, ContainerBuilder $container): void
43
    {
44
        $processor = new Processor();
45
        $configuration = new Configuration();
46
        $config = $processor->processConfiguration($configuration, $configs);
47
48
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
49
        $loader->load('provider.xml');
50
        $loader->load('media.xml');
51
        $loader->load('twig.xml');
52
        $loader->load('security.xml');
53
        $loader->load('extra.xml');
54
        $loader->load('form.xml');
55
        $loader->load('gaufrette.xml');
56
        $loader->load('validators.xml');
57
        $loader->load('serializer.xml');
58
        $loader->load('command.xml');
59
60
        $bundles = $container->getParameter('kernel.bundles');
61
62
        if (isset($bundles['FOSRestBundle'], $bundles['NelmioApiDocBundle'])) {
63
            $loader->load(sprintf('api_form_%s.xml', $config['db_driver']));
64
65
            if ('doctrine_orm' === $config['db_driver']) {
66
                $loader->load('api_controllers.xml');
67
            }
68
        }
69
70
        if (isset($bundles['SonataNotificationBundle'])) {
71
            $loader->load('consumer.xml');
72
        }
73
74
        if (isset($bundles['SonataFormatterBundle'])) {
75
            $loader->load('formatter.xml');
76
        }
77
78
        if (isset($bundles['SonataBlockBundle'])) {
79
            $loader->load('block.xml');
80
        }
81
82
        if (isset($bundles['SonataSeoBundle'])) {
83
            $loader->load('seo_block.xml');
84
        }
85
86
        if (!isset($bundles['LiipImagineBundle'])) {
87
            $container->removeDefinition('sonata.media.thumbnail.liip_imagine');
88
        }
89
90
        if ($this->isClassificationEnabled($config)) {
91
            $loader->load('category.xml');
92
            $categoryManagerAlias = 'sonata.media.manager.category';
93
            $container->setAlias($categoryManagerAlias, $config['category_manager']);
94
            $categoryManager = $container->getAlias($categoryManagerAlias);
95
            $categoryManager->setPublic(true);
96
        }
97
98
        if (!\array_key_exists($config['default_context'], $config['contexts'])) {
99
            throw new \InvalidArgumentException(sprintf('SonataMediaBundle - Invalid default context : %s, available : %s', $config['default_context'], json_encode(array_keys($config['contexts']))));
100
        }
101
102
        $loader->load(sprintf('%s.xml', $config['db_driver']));
103
104
        if (isset($bundles['SonataAdminBundle'])) {
105
            $loader->load(sprintf('%s_admin.xml', $config['db_driver']));
106
107
            $sonataAdminConfig = $this->bundleConfigs['SonataAdminBundle'];
108
109
            $sonataRoles = [];
110
            if (isset($sonataAdminConfig['security']['role_admin'])) {
111
                $sonataRoles[] = $sonataAdminConfig['security']['role_admin'];
112
            } else {
113
                $sonataRoles[] = 'ROLE_ADMIN';
114
            }
115
116
            if (isset($sonataAdminConfig['security']['role_super_admin'])) {
117
                $sonataRoles[] = $sonataAdminConfig['security']['role_super_admin'];
118
            } else {
119
                $sonataRoles[] = 'ROLE_SUPER_ADMIN';
120
            }
121
122
            $container->getDefinition('sonata.media.security.superadmin_strategy')
123
                ->replaceArgument(2, $sonataRoles);
124
        }
125
126
        $this->configureFilesystemAdapter($container, $config);
127
        $this->configureCdnAdapter($container, $config);
128
129
        $pool = $container->getDefinition('sonata.media.pool');
130
        $pool->replaceArgument(0, $config['default_context']);
131
132
        $strategies = [];
133
134
        foreach ($config['contexts'] as $name => $settings) {
135
            $formats = [];
136
137
            foreach ($settings['formats'] as $format => $value) {
138
                $formats[$name.'_'.$format] = $value;
139
            }
140
141
            $strategies[] = $settings['download']['strategy'];
142
            $pool->addMethodCall('addContext', [$name, $settings['providers'], $formats, $settings['download']]);
143
        }
144
145
        $container->setParameter('sonata.media.admin_format', $config['admin_format']);
146
147
        $strategies = array_unique($strategies);
148
149
        foreach ($strategies as $strategyId) {
150
            $pool->addMethodCall('addDownloadStrategy', [$strategyId, new Reference($strategyId)]);
151
        }
152
153
        if ('doctrine_orm' === $config['db_driver']) {
154
            $this->registerDoctrineMapping($config);
155
        }
156
157
        $container->setParameter('sonata.media.resizer.simple.adapter.mode', $config['resizer']['simple']['mode']);
158
        $container->setParameter('sonata.media.resizer.square.adapter.mode', $config['resizer']['square']['mode']);
159
160
        $this->configureParameterClass($container, $config);
161
        $this->configureExtra($container, $config);
162
        $this->configureBuzz($container, $config);
163
        $this->configureProviders($container, $config);
164
        $this->configureAdapters($container, $config);
165
        $this->configureResizers($container, $config);
166
    }
167
168
    public function configureProviders(ContainerBuilder $container, array $config): void
169
    {
170
        $container->getDefinition('sonata.media.provider.image')
171
            ->replaceArgument(5, array_map('strtolower', $config['providers']['image']['allowed_extensions']))
172
            ->replaceArgument(6, $config['providers']['image']['allowed_mime_types'])
173
            ->replaceArgument(7, new Reference($config['providers']['image']['adapter']))
174
        ;
175
176
        $container->getDefinition('sonata.media.provider.file')
177
            ->replaceArgument(5, $config['providers']['file']['allowed_extensions'])
178
            ->replaceArgument(6, $config['providers']['file']['allowed_mime_types'])
179
        ;
180
181
        $container->getDefinition('sonata.media.provider.youtube')->replaceArgument(7, $config['providers']['youtube']['html5']);
182
    }
183
184
    public function configureBuzz(ContainerBuilder $container, array $config): void
185
    {
186
        $container->getDefinition('sonata.media.buzz.browser')
187
            ->replaceArgument(0, new Reference($config['buzz']['connector']));
188
189
        foreach ([
190
            'sonata.media.buzz.connector.curl',
191
            'sonata.media.buzz.connector.file_get_contents',
192
        ] as $connector) {
193
            $container->getDefinition($connector)
194
                ->addMethodCall('setIgnoreErrors', [$config['buzz']['client']['ignore_errors']])
195
                ->addMethodCall('setMaxRedirects', [$config['buzz']['client']['max_redirects']])
196
                ->addMethodCall('setTimeout', [$config['buzz']['client']['timeout']])
197
                ->addMethodCall('setVerifyPeer', [$config['buzz']['client']['verify_peer']])
198
                ->addMethodCall('setProxy', [$config['buzz']['client']['proxy']]);
199
        }
200
    }
201
202
    public function configureParameterClass(ContainerBuilder $container, array $config): void
203
    {
204
        $container->setParameter('sonata.media.admin.media.entity', $config['class']['media']);
205
        $container->setParameter('sonata.media.admin.gallery.entity', $config['class']['gallery']);
206
        $container->setParameter('sonata.media.admin.gallery_item.entity', $config['class']['gallery_item']);
207
208
        $container->setParameter('sonata.media.media.class', $config['class']['media']);
209
        $container->setParameter('sonata.media.gallery.class', $config['class']['gallery']);
210
211
        $container->getDefinition('sonata.media.form.type.media')->replaceArgument(1, $config['class']['media']);
212
    }
213
214
    public function registerDoctrineMapping(array $config): void
215
    {
216
        $collector = DoctrineCollector::getInstance();
217
218
        $collector->addAssociation($config['class']['media'], 'mapOneToMany', [
219
            'fieldName' => 'galleryItems',
220
            'targetEntity' => $config['class']['gallery_item'],
221
            'cascade' => [
222
                'persist',
223
            ],
224
            'mappedBy' => 'media',
225
            'orphanRemoval' => false,
226
        ]);
227
228
        $collector->addAssociation($config['class']['gallery_item'], 'mapManyToOne', [
229
            'fieldName' => 'gallery',
230
            'targetEntity' => $config['class']['gallery'],
231
            'cascade' => [
232
                'persist',
233
            ],
234
            'mappedBy' => null,
235
            'inversedBy' => 'galleryItems',
236
            'joinColumns' => [
237
                [
238
                    'name' => 'gallery_id',
239
                    'referencedColumnName' => 'id',
240
                    'onDelete' => 'CASCADE',
241
                ],
242
            ],
243
            'orphanRemoval' => false,
244
        ]);
245
246
        $collector->addAssociation($config['class']['gallery_item'], 'mapManyToOne', [
247
            'fieldName' => 'media',
248
            'targetEntity' => $config['class']['media'],
249
            'cascade' => [
250
                 'persist',
251
            ],
252
            'mappedBy' => null,
253
            'inversedBy' => 'galleryItems',
254
            'joinColumns' => [
255
                [
256
                    'name' => 'media_id',
257
                    'referencedColumnName' => 'id',
258
                    'onDelete' => 'CASCADE',
259
                ],
260
            ],
261
            'orphanRemoval' => false,
262
        ]);
263
264
        $collector->addAssociation($config['class']['gallery'], 'mapOneToMany', [
265
            'fieldName' => 'galleryItems',
266
            'targetEntity' => $config['class']['gallery_item'],
267
            'cascade' => [
268
                'persist',
269
            ],
270
            'mappedBy' => 'gallery',
271
            'orphanRemoval' => true,
272
            'orderBy' => [
273
                'position' => 'ASC',
274
            ],
275
        ]);
276
277
        if ($this->isClassificationEnabled($config)) {
278
            $collector->addAssociation($config['class']['media'], 'mapManyToOne', [
279
                'fieldName' => 'category',
280
                'targetEntity' => $config['class']['category'],
281
                'cascade' => [
282
                    'persist',
283
                ],
284
                'mappedBy' => null,
285
                'inversedBy' => null,
286
                'joinColumns' => [
287
                    [
288
                     'name' => 'category_id',
289
                     'referencedColumnName' => 'id',
290
                     'onDelete' => 'SET NULL',
291
                    ],
292
                ],
293
                'orphanRemoval' => false,
294
            ]);
295
        }
296
    }
297
298
    /**
299
     * Inject CDN dependency to default provider.
300
     */
301
    public function configureCdnAdapter(ContainerBuilder $container, array $config): void
302
    {
303
        // add the default configuration for the server cdn
304
        if ($container->hasDefinition('sonata.media.cdn.server') && isset($config['cdn']['server'])) {
305
            $container->getDefinition('sonata.media.cdn.server')
306
                ->replaceArgument(0, $config['cdn']['server']['path'])
307
            ;
308
        } else {
309
            $container->removeDefinition('sonata.media.cdn.server');
310
        }
311
312
        if ($container->hasDefinition('sonata.media.cdn.panther') && isset($config['cdn']['panther'])) {
313
            $container->getDefinition('sonata.media.cdn.panther')
314
                ->replaceArgument(0, $config['cdn']['panther']['path'])
315
                ->replaceArgument(1, $config['cdn']['panther']['username'])
316
                ->replaceArgument(2, $config['cdn']['panther']['password'])
317
                ->replaceArgument(3, $config['cdn']['panther']['site_id'])
318
            ;
319
        } else {
320
            $container->removeDefinition('sonata.media.cdn.panther');
321
        }
322
323
        if ($container->hasDefinition('sonata.media.cdn.cloudfront') && isset($config['cdn']['cloudfront'])) {
324
            $container->getDefinition('sonata.media.cdn.cloudfront')
325
                ->replaceArgument(0, $config['cdn']['cloudfront']['path'])
326
                ->replaceArgument(1, $config['cdn']['cloudfront']['key'])
327
                ->replaceArgument(2, $config['cdn']['cloudfront']['secret'])
328
                ->replaceArgument(3, $config['cdn']['cloudfront']['distribution_id'])
329
            ;
330
        } else {
331
            $container->removeDefinition('sonata.media.cdn.cloudfront');
332
        }
333
334
        if ($container->hasDefinition('sonata.media.cdn.fallback') && isset($config['cdn']['fallback'])) {
335
            $container->getDefinition('sonata.media.cdn.fallback')
336
                ->replaceArgument(0, new Reference($config['cdn']['fallback']['master']))
337
                ->replaceArgument(1, new Reference($config['cdn']['fallback']['fallback']))
338
            ;
339
        } else {
340
            $container->removeDefinition('sonata.media.cdn.fallback');
341
        }
342
    }
343
344
    /**
345
     * Inject filesystem dependency to default provider.
346
     */
347
    public function configureFilesystemAdapter(ContainerBuilder $container, array $config): void
348
    {
349
        // add the default configuration for the local filesystem
350
        if ($container->hasDefinition('sonata.media.adapter.filesystem.local') && isset($config['filesystem']['local'])) {
351
            $container->getDefinition('sonata.media.adapter.filesystem.local')
352
                ->addArgument($config['filesystem']['local']['directory'])
353
                ->addArgument($config['filesystem']['local']['create'])
354
            ;
355
        } else {
356
            $container->removeDefinition('sonata.media.adapter.filesystem.local');
357
        }
358
359
        // add the default configuration for the FTP filesystem
360
        if ($container->hasDefinition('sonata.media.adapter.filesystem.ftp') && isset($config['filesystem']['ftp'])) {
361
            $container->getDefinition('sonata.media.adapter.filesystem.ftp')
362
                ->addArgument($config['filesystem']['ftp']['directory'])
363
                ->addArgument($config['filesystem']['ftp']['host'])
364
                ->addArgument([
365
                    'port' => $config['filesystem']['ftp']['port'],
366
                    'username' => $config['filesystem']['ftp']['username'],
367
                    'password' => $config['filesystem']['ftp']['password'],
368
                    'passive' => $config['filesystem']['ftp']['passive'],
369
                    'create' => $config['filesystem']['ftp']['create'],
370
                    'mode' => $config['filesystem']['ftp']['mode'],
371
                ])
372
            ;
373
        } else {
374
            $container->removeDefinition('sonata.media.adapter.filesystem.ftp');
375
            $container->removeDefinition('sonata.media.filesystem.ftp');
376
        }
377
378
        // add the default configuration for the S3 filesystem
379
        if ($container->hasDefinition('sonata.media.adapter.filesystem.s3') && isset($config['filesystem']['s3'])) {
380
            $container->getDefinition('sonata.media.adapter.filesystem.s3')
381
                ->replaceArgument(0, new Reference('sonata.media.adapter.service.s3'))
382
                ->replaceArgument(1, $config['filesystem']['s3']['bucket'])
383
                ->replaceArgument(2, ['create' => $config['filesystem']['s3']['create'], 'region' => $config['filesystem']['s3']['region'], 'directory' => $config['filesystem']['s3']['directory'], 'ACL' => $config['filesystem']['s3']['acl']])
384
            ;
385
386
            $container->getDefinition('sonata.media.metadata.amazon')
387
                ->replaceArgument(0, [
388
                        'acl' => $config['filesystem']['s3']['acl'],
389
                        'storage' => $config['filesystem']['s3']['storage'],
390
                        'encryption' => $config['filesystem']['s3']['encryption'],
391
                        'meta' => $config['filesystem']['s3']['meta'],
392
                        'cache_control' => $config['filesystem']['s3']['cache_control'],
393
                ])
394
            ;
395
396
            if (3 === $config['filesystem']['s3']['sdk_version']) {
397
                $arguments = [
398
                    'region' => $config['filesystem']['s3']['region'],
399
                    'version' => $config['filesystem']['s3']['version'],
400
                ];
401
402
                if (isset($config['filesystem']['s3']['secretKey'], $config['filesystem']['s3']['accessKey'])) {
403
                    $arguments['credentials'] = [
404
                        'secret' => $config['filesystem']['s3']['secretKey'],
405
                        'key' => $config['filesystem']['s3']['accessKey'],
406
                    ];
407
                }
408
409
                $container->getDefinition('sonata.media.adapter.service.s3')
410
                    ->replaceArgument(0, $arguments)
411
                ;
412
            } else {
413
                $container->getDefinition('sonata.media.adapter.service.s3')
414
                    ->replaceArgument(0, [
415
                        'secret' => $config['filesystem']['s3']['secretKey'],
416
                        'key' => $config['filesystem']['s3']['accessKey'],
417
                    ])
418
                ;
419
            }
420
        } else {
421
            $container->removeDefinition('sonata.media.adapter.filesystem.s3');
422
            $container->removeDefinition('sonata.media.filesystem.s3');
423
        }
424
425
        if ($container->hasDefinition('sonata.media.adapter.filesystem.replicate') && isset($config['filesystem']['replicate'])) {
426
            $container->getDefinition('sonata.media.adapter.filesystem.replicate')
427
                ->replaceArgument(0, new Reference($config['filesystem']['replicate']['master']))
428
                ->replaceArgument(1, new Reference($config['filesystem']['replicate']['slave']))
429
            ;
430
        } else {
431
            $container->removeDefinition('sonata.media.adapter.filesystem.replicate');
432
            $container->removeDefinition('sonata.media.filesystem.replicate');
433
        }
434
435
        if ($container->hasDefinition('sonata.media.adapter.filesystem.mogilefs') && isset($config['filesystem']['mogilefs'])) {
436
            $container->getDefinition('sonata.media.adapter.filesystem.mogilefs')
437
                ->replaceArgument(0, $config['filesystem']['mogilefs']['domain'])
438
                ->replaceArgument(1, $config['filesystem']['mogilefs']['hosts'])
439
            ;
440
        } else {
441
            $container->removeDefinition('sonata.media.adapter.filesystem.mogilefs');
442
            $container->removeDefinition('sonata.media.filesystem.mogilefs');
443
        }
444
445
        if ($container->hasDefinition('sonata.media.adapter.filesystem.opencloud') &&
446
            (isset($config['filesystem']['openstack']) || isset($config['filesystem']['rackspace']))) {
447
            if (isset($config['filesystem']['openstack'])) {
448
                $container->setParameter('sonata.media.adapter.filesystem.opencloud.class', 'OpenCloud\OpenStack');
449
                $settings = 'openstack';
450
            } else {
451
                $container->setParameter('sonata.media.adapter.filesystem.opencloud.class', 'OpenCloud\Rackspace');
452
                $settings = 'rackspace';
453
            }
454
            $container->getDefinition('sonata.media.adapter.filesystem.opencloud.connection')
455
                ->replaceArgument(0, $config['filesystem'][$settings]['url'])
456
                ->replaceArgument(1, $config['filesystem'][$settings]['secret'])
457
                ;
458
            $container->getDefinition('sonata.media.adapter.filesystem.opencloud')
459
                ->replaceArgument(1, $config['filesystem'][$settings]['containerName'])
460
                ->replaceArgument(2, $config['filesystem'][$settings]['create_container']);
461
            $container->getDefinition('sonata.media.adapter.filesystem.opencloud.objectstore')
462
                ->replaceArgument(1, $config['filesystem'][$settings]['region']);
463
        } else {
464
            $container->removeDefinition('sonata.media.adapter.filesystem.opencloud');
465
            $container->removeDefinition('sonata.media.adapter.filesystem.opencloud.connection');
466
            $container->removeDefinition('sonata.media.adapter.filesystem.opencloud.objectstore');
467
            $container->removeDefinition('sonata.media.filesystem.opencloud');
468
        }
469
    }
470
471
    public function configureExtra(ContainerBuilder $container, array $config): void
472
    {
473
        if ($config['pixlr']['enabled']) {
474
            $container->getDefinition('sonata.media.extra.pixlr')
475
                ->replaceArgument(0, $config['pixlr']['referrer'])
476
                ->replaceArgument(1, $config['pixlr']['secret'])
477
            ;
478
        } else {
479
            $container->removeDefinition('sonata.media.extra.pixlr');
480
        }
481
    }
482
483
    /**
484
     * Allow an extension to prepend the extension configurations.
485
     */
486
    public function prepend(ContainerBuilder $container): void
487
    {
488
        $bundles = $container->getParameter('kernel.bundles');
489
490
        // Store SonataAdminBundle configuration for later use
491
        if (isset($bundles['SonataAdminBundle'])) {
492
            $this->bundleConfigs['SonataAdminBundle'] = current($container->getExtensionConfig('sonata_admin'));
493
        }
494
    }
495
496
    /**
497
     * Checks if the classification of media is enabled.
498
     */
499
    private function isClassificationEnabled(array $config): bool
500
    {
501
        return interface_exists(CategoryInterface::class)
502
            && !$config['force_disable_category'];
503
    }
504
505
    private function configureAdapters(ContainerBuilder $container, array $config): void
506
    {
507
        foreach (['gd', 'imagick', 'gmagick'] as $adapter) {
508
            if ($container->hasParameter('sonata.media.adapter.image.'.$adapter.'.class')) {
509
                $container->register(
510
                    'sonata.media.adapter.image.'.$adapter,
511
                    $container->getParameter('sonata.media.adapter.image.'.$adapter.'.class')
512
                );
513
            }
514
        }
515
        $container->setAlias('sonata.media.adapter.image.default', $config['adapters']['default']);
516
    }
517
518
    private function configureResizers(ContainerBuilder $container, array $config): void
519
    {
520
        if ($container->hasParameter('sonata.media.resizer.simple.class')) {
521
            $class = $container->getParameter('sonata.media.resizer.simple.class');
522
            $definition = new Definition($class, [
523
                new Reference('sonata.media.adapter.image.default'),
524
                '%sonata.media.resizer.simple.adapter.mode%',
525
                new Reference('sonata.media.metadata.proxy'),
526
            ]);
527
            $definition->addTag('sonata.media.resizer');
528
            $container->setDefinition('sonata.media.resizer.simple', $definition);
529
        }
530
531
        if ($container->hasParameter('sonata.media.resizer.square.class')) {
532
            $class = $container->getParameter('sonata.media.resizer.square.class');
533
            $definition = new Definition($class, [
534
                new Reference('sonata.media.adapter.image.default'),
535
                '%sonata.media.resizer.square.adapter.mode%',
536
                new Reference('sonata.media.metadata.proxy'),
537
            ]);
538
            $definition->addTag('sonata.media.resizer');
539
            $container->setDefinition('sonata.media.resizer.square', $definition);
540
        }
541
542
        $container->setAlias('sonata.media.resizer.default', $config['resizers']['default']);
543
    }
544
}
545