vendor/uvdesk/extension-framework/DependencyInjection/ContainerExtension.php line 32

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\ExtensionFrameworkBundle\DependencyInjection;
  3. use Symfony\Component\Yaml\Yaml;
  4. use Symfony\Component\Config\FileLocator;
  5. use Symfony\Component\DependencyInjection\Reference;
  6. use Symfony\Component\DependencyInjection\Definition;
  7. use Symfony\Component\DependencyInjection\ContainerBuilder;
  8. use Symfony\Component\HttpKernel\DependencyInjection\Extension;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
  11. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\MappingResource;
  12. use Webkul\UVDesk\ExtensionFrameworkBundle\Configurators\AppConfigurator;
  13. use Webkul\UVDesk\ExtensionFrameworkBundle\Configurators\PackageConfigurator;
  14. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\Package\PackageInterface;
  15. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\Routing\RoutingResourceInterface;
  16. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\Application\ApplicationInterface;
  17. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\Package\ConfigurablePackageInterface;
  18. use Webkul\UVDesk\ExtensionFrameworkBundle\Definition\Package\ContainerBuilderAwarePackageInterface;
  19. class ContainerExtension extends Extension
  20. {
  21.     public function getAlias()
  22.     {
  23.         return 'uvdesk_extensions';
  24.     }
  25.     public function getConfiguration(array $configsContainerBuilder $container)
  26.     {
  27.         return new Configuration();
  28.     }
  29.     public function load(array $configsContainerBuilder $container)
  30.     {
  31.         // Define parameters
  32.         foreach ($this->processConfiguration($this->getConfiguration($configs$container), $configs) as $param => $value) {
  33.             switch ($param) {
  34.                 case 'dir':
  35.                     $container->setParameter("uvdesk_extensions.dir"$value);
  36.                     break;
  37.                 default:
  38.                     break;
  39.             }
  40.         }
  41.         // Define services
  42.         $loader = new YamlFileLoader($container, new FileLocator(__DIR__ '/../Resources/config'));
  43.         $loader->load('services.yaml');
  44.         
  45.         // Compile modules
  46.         $env $container->getParameter('kernel.environment');
  47.         $path $container->getParameter("kernel.project_dir") . "/uvdesk.lock";
  48.         $mappingResource $container->findDefinition(MappingResource::class);
  49.         $availableConfigurations $this->parsePackageConfigurations($container->getParameter("kernel.project_dir") . "/config/extensions");
  50.         
  51.         foreach ($this->getCachedPackages($path) as $attributes) {
  52.             $reference current(array_keys($attributes['package']));
  53.             $supportedEnvironments $attributes['package'][$reference];
  54.             // Check if package is supported in the current environment
  55.             if (in_array('all'$supportedEnvironments) || in_array($env$supportedEnvironments)) {
  56.                 $class = new \ReflectionClass($reference);
  57.                 
  58.                 if (!$class->implementsInterface(PackageInterface::class)) {
  59.                     throw new \Exception("Class $reference could not be registered as a package. Please check that it implements the " PackageInterface::class . " interface.");
  60.                 }
  61.                 if ($class->implementsInterface(ConfigurablePackageInterface::class)) {
  62.                     $schema $class->newInstanceWithoutConstructor()->getConfiguration();
  63.                     if (!empty($schema)) {
  64.                         $qualifiedName str_replace(['/''-'], '_'$attributes['name']);
  65.     
  66.                         if (empty($availableConfigurations[$qualifiedName])) {
  67.                             throw new \Exception("No available configurations found for package '" $attributes['name'] . "'");
  68.                         }
  69.                         // Validate package configuration params
  70.                         $packageConfigurations $this->processConfiguration($schema$availableConfigurations[$qualifiedName]);
  71.                         // Unset and cache package params for later re-use
  72.                         unset($availableConfigurations[$qualifiedName]);
  73.                         $mappingResource->addMethodCall('setPackageConfigurations', array($reference$packageConfigurations));
  74.                     }
  75.                 }
  76.                 // Prepare package for configuration
  77.                 $this->loadPackageServices($class->getFileName(), $loader);
  78.                 if ($container->hasDefinition($reference)) {
  79.                     $mappingResource->addMethodCall('setPackageMetadata', array($reference$attributes));
  80.                 }
  81.             }
  82.         }
  83.         if (!empty($availableConfigurations)) {
  84.             // @TODO: Raise exception about invalid configurations
  85.             dump('Invalid configurations found');
  86.             dump($availableConfigurations);
  87.             die;
  88.         }
  89.         // Configure services
  90.         $container->registerForAutoconfiguration(PackageInterface::class)->addTag(PackageInterface::class)->setLazy(true)->setPublic(true);
  91.         $container->registerForAutoconfiguration(ApplicationInterface::class)->addTag(ApplicationInterface::class)->setLazy(true)->setPublic(true);
  92.         $container->registerForAutoconfiguration(ContainerBuilderAwarePackageInterface::class)->addTag(ContainerBuilderAwarePackageInterface::class);
  93.         $container->registerForAutoconfiguration(RoutingResourceInterface::class)->addTag(RoutingResourceInterface::class);
  94.     }
  95.     private function getCachedPackages($path) : array
  96.     {
  97.         try {
  98.             if (file_exists($path)) {
  99.                 return json_decode(file_get_contents($path), true)['packages'] ?? [];
  100.             }
  101.         } catch (\Exception $e) {
  102.             // Skip module compilation ...
  103.         }
  104.         return [];
  105.     }
  106.     private function loadPackageServices($classPathYamlFileLoader $loader)
  107.     {
  108.         $path dirname($classPath) . "/Resources/config/services.yaml";
  109.         if (file_exists($path)) {
  110.             $loader->load($path);
  111.         }
  112.     }
  113.     private function parsePackageConfigurations($prefix) : array
  114.     {
  115.         $configs = [];
  116.         if (file_exists($prefix) && is_dir($prefix)) {
  117.             foreach (array_diff(scandir($prefix), ['.''..']) as $extensionConfig) {
  118.                 $path "$prefix/$extensionConfig";
  119.     
  120.                 if (!is_dir($path) && 'yaml' === pathinfo($pathPATHINFO_EXTENSION)) {
  121.                     $configs[pathinfo($pathPATHINFO_FILENAME)] = Yaml::parseFile($path);
  122.                 }
  123.             }
  124.         }
  125.         return $configs;
  126.     }
  127. }