Module.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. namespace App\Service\Utils;
  3. use App\Entity\Organization\Organization;
  4. use Doctrine\Common\Cache\ApcuCache;
  5. use Symfony\Component\Config\FileLocator;
  6. use Symfony\Component\DependencyInjection\ContainerInterface;
  7. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  8. use Symfony\Component\Yaml\Yaml;
  9. class Module
  10. {
  11. const OPENTALENT_CONFIG = __DIR__.'/../../../config/opentalent';
  12. /** @var array */
  13. private $moduleConfig;
  14. /** @var array */
  15. private $moduleByConditionsConfig;
  16. /** @var ContainerInterface */
  17. private $container;
  18. public function __construct(ContainerInterface $container)
  19. {
  20. $this->container = $container;
  21. $this->moduleConfig = $this->getModuleConfig();
  22. $this->moduleByConditionsConfig = $this->getModuleByConditionsConfig();
  23. }
  24. /**
  25. * Parse and return the products.yaml content
  26. * @return array
  27. */
  28. private function getModuleConfig(): array{
  29. $configDirectories = [self::OPENTALENT_CONFIG];
  30. $fileLocator = new FileLocator($configDirectories);
  31. $yamlConfig = $fileLocator->locate('products.yaml', null, false)[0];
  32. return Yaml::parseFile($yamlConfig);
  33. }
  34. /**
  35. * Parse and return the modulesbyconditions.yaml content
  36. * @return array
  37. */
  38. private function getModuleByConditionsConfig(): array{
  39. $configDirectories = [self::OPENTALENT_CONFIG];
  40. $fileLocator = new FileLocator($configDirectories);
  41. $yamlConfig = $fileLocator->locate('modulesbyconditions.yaml', null, false)[0];
  42. return Yaml::parseFile($yamlConfig);
  43. }
  44. /**
  45. * Get the module who enabled the access to the resource
  46. * @param string $resource
  47. * @return int|null|string
  48. */
  49. public function getModuleByResourceName(string $resource): ?string {
  50. $modules = $this->moduleConfig['opentalent']['modules'];
  51. foreach ($modules as $module => $data) {
  52. if ($data['entities'] && in_array($resource, $data['entities'], true)) {
  53. return $module;
  54. }
  55. }
  56. return null;
  57. }
  58. /**
  59. * Get all the modules for one organization
  60. * @param Organization $organization
  61. * @return array
  62. */
  63. public function getOrganizationModules(Organization $organization): array {
  64. $cacheDriver = new ApcuCache();
  65. //If the modules are all ready available inside the APCu cache
  66. if($cacheDriver->contains('organization_modules_' . $organization->getId())){
  67. return $cacheDriver->fetch('organization_modules_' . $organization->getId());
  68. }
  69. $modulesBySettings = $this->getModuleBySettings($organization);
  70. $modulesByConditions = $this->getModulesByConditions($organization);
  71. $product = $organization->getSettings()->getProduct();
  72. $modulesForProduct = $this->getModulesByProductConfiguration($product);
  73. $organizationModules = array_merge_recursive($modulesForProduct, $modulesBySettings, $modulesByConditions);
  74. //Keep the modules inside the APCu cache
  75. $cacheDriver->save('organization_modules_' . $organization->getId(), $organizationModules, '86400');
  76. return $organizationModules;
  77. }
  78. /**
  79. * Get the module inside the organization's settings
  80. * @param Organization $organization
  81. * @return array
  82. */
  83. public function getModuleBySettings(Organization $organization): array{
  84. $moduleByOptions = [];
  85. $modulesOptions = $organization->getSettings()->getModules();
  86. if(!empty($modulesOptions)){
  87. foreach($modulesOptions as $moduleOptionName => $moduleOptionValue){
  88. if($moduleOptionValue)
  89. $moduleByOptions[] = $moduleOptionName;
  90. }
  91. }
  92. return $moduleByOptions;
  93. }
  94. /**
  95. * Get the modules by conditions, thanks to the modulebyconditions.yaml file
  96. * @param Organization $organization
  97. * @return array
  98. */
  99. public function getModulesByConditions(Organization $organization): array {
  100. $modulesByConditions = [];
  101. $modules = $this->moduleByConditionsConfig['opentalent']['modulesbyconditions'];
  102. foreach ($modules as $moduleName => $module) {
  103. try{
  104. $function = $this->container->get($module["conditions"]["service"]["name"]);
  105. $reflection = new \ReflectionClass(get_class($function));
  106. $method = $reflection->getMethod($module["conditions"]["service"]["function"]);
  107. $response = $method->invokeArgs($function, array($organization));
  108. if($response) {
  109. $modulesByConditions[] = $moduleName;
  110. }
  111. }catch (\Exception $exception){}
  112. }
  113. return $modulesByConditions;
  114. }
  115. /**
  116. * Get product configuration thanks to the products.yaml file
  117. * @param string $product
  118. * @return array|null
  119. */
  120. public function getModulesByProductConfiguration(string $product): ?array {
  121. $product = str_replace('-', '_', $product);
  122. if (!array_key_exists($product, $this->moduleConfig['opentalent']['products'])) {
  123. throw new AccessDeniedHttpException(sprintf('The product %s does not exist !', $product));
  124. }
  125. $productConfig = $this->moduleConfig['opentalent']['products'][$product];
  126. $modules = $productConfig['modules'] ?? [];
  127. if (array_key_exists('extend', $productConfig)) {
  128. $modules = array_merge($modules, $this->getModulesByProductConfiguration($productConfig['extend']));
  129. unset($productConfig['extend']);
  130. }
  131. return $modules;
  132. }
  133. }