vendor/vich/uploader-bundle/src/DependencyInjection/VichUploaderExtension.php line 53

Open in your IDE?
  1. <?php
  2. namespace Vich\UploaderBundle\DependencyInjection;
  3. use Doctrine\Common\Annotations\AnnotationReader;
  4. use Symfony\Component\Config\FileLocator;
  5. use Symfony\Component\DependencyInjection\Alias;
  6. use Symfony\Component\DependencyInjection\ChildDefinition;
  7. use Symfony\Component\DependencyInjection\ContainerBuilder;
  8. use Symfony\Component\DependencyInjection\Definition;
  9. use Symfony\Component\DependencyInjection\Extension\Extension;
  10. use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  11. use Symfony\Component\DependencyInjection\Reference;
  12. use Vich\UploaderBundle\Metadata\CacheWarmer;
  13. use Vich\UploaderBundle\Storage\StorageInterface;
  14. /**
  15.  * @author Dustin Dobervich <[email protected]>
  16.  *
  17.  * @internal
  18.  */
  19. final class VichUploaderExtension extends Extension
  20. {
  21.     /**
  22.      * @var array
  23.      */
  24.     protected $tagMap = [
  25.         'orm' => 'doctrine.event_subscriber',
  26.         'mongodb' => 'doctrine_mongodb.odm.event_subscriber',
  27.         'phpcr' => 'doctrine_phpcr.event_subscriber',
  28.     ];
  29.     public function load(array $configsContainerBuilder $container): void
  30.     {
  31.         $configuration = new Configuration();
  32.         $config $this->processConfiguration($configuration$configs);
  33.         $config $this->fixDbDriverConfig($config);
  34.         $config $this->createNamerServices($container$config);
  35.         // define a few parameters
  36.         $container->setParameter('vich_uploader.default_filename_attribute_suffix'$config['default_filename_attribute_suffix']);
  37.         $container->setParameter('vich_uploader.mappings'$config['mappings']);
  38.         if (=== \strpos($config['storage'], '@')) {
  39.             $container->setAlias('vich_uploader.storage', \substr($config['storage'], 1));
  40.         } else {
  41.             $container->setAlias('vich_uploader.storage''vich_uploader.storage.'.$config['storage']);
  42.         }
  43.         $container->setAlias(StorageInterface::class, new Alias('vich_uploader.storage'false));
  44.         $this->loadServicesFiles($container$config);
  45.         $this->registerMetadataDirectories($container$config);
  46.         $this->registerAnnotationStrategy($container$config);
  47.         $this->registerCacheStrategy($container$config);
  48.         $this->registerListeners($container$config);
  49.         $this->registerFormTheme($container);
  50.     }
  51.     protected function loadServicesFiles(ContainerBuilder $container, array $config): void
  52.     {
  53.         $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../config'));
  54.         $toLoad = [
  55.             'adapter.xml''listener.xml''storage.xml''injector.xml',
  56.             'mapping.xml''factory.xml''namer.xml''handler.xml''command.xml''collector.xml',
  57.         ];
  58.         foreach ($toLoad as $file) {
  59.             $loader->load($file);
  60.         }
  61.         if (\in_array($config['storage'], ['gaufrette''flysystem'], true)) {
  62.             $loader->load($config['storage'].'.xml');
  63.         }
  64.         if ($config['form']) {
  65.             $loader->load('form.xml');
  66.         }
  67.         if ($config['twig']) {
  68.             $loader->load('twig.xml');
  69.         }
  70.     }
  71.     protected function registerMetadataDirectories(ContainerBuilder $container, array $config): void
  72.     {
  73.         $bundles $container->getParameter('kernel.bundles');
  74.         // directories
  75.         $directories = [];
  76.         if ($config['metadata']['auto_detection']) {
  77.             $projectDir $container->getParameter('kernel.project_dir');
  78.             if (\is_string($projectDir)) {
  79.                 $appConfigDirectory $projectDir.'/config/vich_uploader';
  80.                 if (\is_dir($appConfigDirectory)) {
  81.                     $directories['App'] = $appConfigDirectory;
  82.                 }
  83.             }
  84.             foreach ($bundles as $class) {
  85.                 $ref = new \ReflectionClass($class);
  86.                 $directory = \dirname($ref->getFileName()).'/../config/vich_uploader';
  87.                 if (!\is_dir($directory)) {
  88.                     $directory = \dirname($ref->getFileName()).'/Resources/config/vich_uploader';
  89.                     if (\is_dir($directory)) {
  90.                         @\trigger_error('Using Resources/config/vich_uploader for auto config discovery is deprecated use ../config/vich_uploader, relative to the Bundle class, instead', \E_USER_DEPRECATED);
  91.                     }
  92.                 }
  93.                 if (!\is_dir($directory)) {
  94.                     continue;
  95.                 }
  96.                 $directories[$ref->getNamespaceName()] = $directory;
  97.             }
  98.         }
  99.         foreach ($config['metadata']['directories'] as $directory) {
  100.             $directory['path'] = \rtrim(\str_replace('\\''/'$directory['path']), '/');
  101.             if ('@' === $directory['path'][0]) {
  102.                 $bundleName = \substr($directory['path'], 1, \strpos($directory['path'], '/') - 1);
  103.                 if (!isset($bundles[$bundleName])) {
  104.                     throw new \RuntimeException(\sprintf('The bundle "%s" has not been registered with Kernel. Available bundles: %s'$bundleName, \implode(', ', \array_keys($bundles))));
  105.                 }
  106.                 $ref = new \ReflectionClass($bundles[$bundleName]);
  107.                 $directory['path'] = \dirname($ref->getFileName()).\substr($directory['path'], \strlen('@'.$bundleName));
  108.             }
  109.             $directories[\rtrim($directory['namespace_prefix'], '\\')] = \rtrim($directory['path'], '\\/');
  110.         }
  111.         $container
  112.             ->getDefinition('vich_uploader.metadata.file_locator')
  113.             ->replaceArgument(0$directories)
  114.         ;
  115.     }
  116.     protected function registerAnnotationStrategy(ContainerBuilder $container, array $config): void
  117.     {
  118.         if (!$container->has('vich_uploader.metadata_driver.annotation')) {
  119.             return;
  120.         }
  121.         switch ($config['metadata']['type']) {
  122.             case 'attribute':
  123.                 $container->setDefinition(
  124.                     'vich_uploader.metadata.reader',
  125.                     $container->getDefinition('vich_uploader.metadata.attribute_reader')
  126.                 );
  127.                 break;
  128.             default:
  129.                 $container->setDefinition(
  130.                     'vich_uploader.metadata.reader',
  131.                     new Definition(AnnotationReader::class)
  132.                 );
  133.         }
  134.     }
  135.     protected function registerCacheStrategy(ContainerBuilder $container, array $config): void
  136.     {
  137.         if ('none' === $config['metadata']['cache']) {
  138.             $container->removeAlias('vich_uploader.metadata.cache');
  139.         } elseif ('file' === $config['metadata']['cache']) {
  140.             $container
  141.                 ->getDefinition('vich_uploader.metadata.cache.file_cache')
  142.                 ->replaceArgument(0$config['metadata']['file_cache']['dir'])
  143.             ;
  144.             $container
  145.                 ->getDefinition(CacheWarmer::class)
  146.                 ->replaceArgument(0$config['metadata']['file_cache']['dir'])
  147.             ;
  148.             $dir $container->getParameterBag()->resolveValue($config['metadata']['file_cache']['dir']);
  149.             if (!\file_exists($dir) && !@\mkdir($dir0777true)) {
  150.                 throw new \RuntimeException(\sprintf('Could not create cache directory "%s".'$dir));
  151.             }
  152.         } else {
  153.             $container->setAlias('vich_uploader.metadata.cache', new Alias($config['metadata']['cache'], false));
  154.         }
  155.     }
  156.     protected function fixDbDriverConfig(array $config): array
  157.     {
  158.         // mapping with no declared db_driver use the top-level one
  159.         foreach ($config['mappings'] as &$mapping) {
  160.             $mapping['db_driver'] = $mapping['db_driver'] ?: $config['db_driver'];
  161.         }
  162.         return $config;
  163.     }
  164.     protected function registerListeners(ContainerBuilder $container, array $config): void
  165.     {
  166.         $servicesMap = [
  167.             'inject_on_load' => ['name' => 'inject''priority' => 0],
  168.             'delete_on_update' => ['name' => 'clean''priority' => 50],
  169.             'delete_on_remove' => ['name' => 'remove''priority' => 0],
  170.         ];
  171.         foreach ($config['mappings'] as $name => $mapping) {
  172.             $driver $mapping['db_driver'];
  173.             // create optional listeners
  174.             foreach ($servicesMap as $configOption => $service) {
  175.                 if (!$mapping[$configOption]) {
  176.                     continue;
  177.                 }
  178.                 $this->createListener($container$name$service['name'], $driver$service['priority']);
  179.             }
  180.             // the upload listener is mandatory
  181.             $this->createListener($container$name'upload'$driver);
  182.         }
  183.     }
  184.     protected function createNamerServices(ContainerBuilder $container, array $config): array
  185.     {
  186.         foreach ($config['mappings'] as $name => $mapping) {
  187.             if (!empty($mapping['namer']['service'])) {
  188.                 $config['mappings'][$name] = $this->createNamerService($container$name$mapping);
  189.             }
  190.         }
  191.         return $config;
  192.     }
  193.     protected function createNamerService(ContainerBuilder $containerstring $mappingName, array $mapping): array
  194.     {
  195.         $serviceId = \sprintf('%s.%s'$mapping['namer']['service'], $mappingName);
  196.         $container->setDefinition($serviceId, new ChildDefinition($mapping['namer']['service']));
  197.         $mapping['namer']['service'] = $serviceId;
  198.         return $mapping;
  199.     }
  200.     protected function createListener(
  201.         ContainerBuilder $container,
  202.         string $name,
  203.         string $type,
  204.         string $driver,
  205.         int $priority 0
  206.     ): void {
  207.         $definition $container
  208.             ->setDefinition(\sprintf('vich_uploader.listener.%s.%s'$type$name), new ChildDefinition(\sprintf('vich_uploader.listener.%s.%s'$type$driver)))
  209.             ->replaceArgument(0$name)
  210.             ->replaceArgument(1, new Reference('vich_uploader.adapter.'.$driver));
  211.         if (isset($this->tagMap[$driver])) {
  212.             $definition->addTag($this->tagMap[$driver], ['priority' => $priority]);
  213.         }
  214.     }
  215.     private function registerFormTheme(ContainerBuilder $container): void
  216.     {
  217.         $resources $container->hasParameter('twig.form.resources') ?
  218.             $container->getParameter('twig.form.resources') : [];
  219.         \array_unshift($resources'@VichUploader/Form/fields.html.twig');
  220.         $container->setParameter('twig.form.resources'$resources);
  221.     }
  222. }