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

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 $configs, ContainerBuilder $container)
  26. {
  27. return new Configuration();
  28. }
  29. public function load(array $configs, ContainerBuilder $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. // Compile modules
  45. $env = $container->getParameter('kernel.environment');
  46. $path = $container->getParameter("kernel.project_dir") . "/uvdesk.lock";
  47. $mappingResource = $container->findDefinition(MappingResource::class);
  48. $availableConfigurations = $this->parsePackageConfigurations($container->getParameter("kernel.project_dir") . "/config/extensions");
  49. foreach ($this->getCachedPackages($path) as $attributes) {
  50. $reference = current(array_keys($attributes['package']));
  51. $supportedEnvironments = $attributes['package'][$reference];
  52. // Check if package is supported in the current environment
  53. if (in_array('all', $supportedEnvironments) || in_array($env, $supportedEnvironments)) {
  54. $class = new \ReflectionClass($reference);
  55. if (!$class->implementsInterface(PackageInterface::class)) {
  56. throw new \Exception("Class $reference could not be registered as a package. Please check that it implements the " . PackageInterface::class . " interface.");
  57. }
  58. if ($class->implementsInterface(ConfigurablePackageInterface::class)) {
  59. $schema = $class->newInstanceWithoutConstructor()->getConfiguration();
  60. if (!empty($schema)) {
  61. $qualifiedName = str_replace(['/', '-'], '_', $attributes['name']);
  62. if (empty($availableConfigurations[$qualifiedName])) {
  63. throw new \Exception("No available configurations found for package '" . $attributes['name'] . "'");
  64. }
  65. // Validate package configuration params
  66. $packageConfigurations = $this->processConfiguration($schema, $availableConfigurations[$qualifiedName]);
  67. // Unset and cache package params for later re-use
  68. unset($availableConfigurations[$qualifiedName]);
  69. $mappingResource->addMethodCall('setPackageConfigurations', array($reference, $packageConfigurations));
  70. }
  71. }
  72. // Prepare package for configuration
  73. $this->loadPackageServices($class->getFileName(), $loader);
  74. if ($container->hasDefinition($reference)) {
  75. $mappingResource->addMethodCall('setPackageMetadata', array($reference, $attributes));
  76. }
  77. }
  78. }
  79. if (!empty($availableConfigurations)) {
  80. // @TODO: Raise exception about invalid configurations
  81. dump('Invalid configurations found');
  82. dump($availableConfigurations);
  83. die;
  84. }
  85. // Configure services
  86. $container->registerForAutoconfiguration(PackageInterface::class)->addTag(PackageInterface::class)->setLazy(true)->setPublic(true);
  87. $container->registerForAutoconfiguration(ApplicationInterface::class)->addTag(ApplicationInterface::class)->setLazy(true)->setPublic(true);
  88. $container->registerForAutoconfiguration(ContainerBuilderAwarePackageInterface::class)->addTag(ContainerBuilderAwarePackageInterface::class);
  89. $container->registerForAutoconfiguration(RoutingResourceInterface::class)->addTag(RoutingResourceInterface::class);
  90. }
  91. private function getCachedPackages($path) : array
  92. {
  93. try {
  94. if (file_exists($path)) {
  95. return json_decode(file_get_contents($path), true)['packages'] ?? [];
  96. }
  97. } catch (\Exception $e) {
  98. // Skip module compilation ...
  99. }
  100. return [];
  101. }
  102. private function loadPackageServices($classPath, YamlFileLoader $loader)
  103. {
  104. $path = dirname($classPath) . "/Resources/config/services.yaml";
  105. if (file_exists($path)) {
  106. $loader->load($path);
  107. }
  108. }
  109. private function parsePackageConfigurations($prefix) : array
  110. {
  111. $configs = [];
  112. if (file_exists($prefix) && is_dir($prefix)) {
  113. foreach (array_diff(scandir($prefix), ['.', '..']) as $extensionConfig) {
  114. $path = "$prefix/$extensionConfig";
  115. if (!is_dir($path) && 'yaml' === pathinfo($path, PATHINFO_EXTENSION)) {
  116. $configs[pathinfo($path, PATHINFO_FILENAME)] = Yaml::parseFile($path);
  117. }
  118. }
  119. }
  120. return $configs;
  121. }
  122. }