src/Component/Configuration/Util/Config.php line 179

Open in your IDE?
  1. <?php
  2. namespace App\Component\Configuration\Util;
  3. use App\Component\Configuration\Cache\Adapter;
  4. use App\Component\Configuration\Doctrine\DBAL\Types\EncryptedType;
  5. use App\Component\Configuration\Doctrine\DBAL\Types\EntityType;
  6. use App\Entity\ConfigurationSetting;
  7. use App\Repository\ConfigurationSettingRepository;
  8. use Doctrine\DBAL\Platforms\MySQLPlatform;
  9. use Doctrine\DBAL\Types\ArrayType;
  10. use Doctrine\DBAL\Types\BooleanType;
  11. use Doctrine\DBAL\Types\DateTimeType;
  12. use Doctrine\DBAL\Types\FloatType;
  13. use Doctrine\DBAL\Types\IntegerType;
  14. use Doctrine\DBAL\Types\StringType;
  15. use Doctrine\DBAL\Types\Type;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Doctrine\Persistence\ObjectRepository;
  18. use RuntimeException;
  19. use SpecShaper\EncryptBundle\Encryptors\EncryptorInterface;
  20. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  21. use TypeError;
  22. class Config
  23. {
  24.     public const BOOLEAN_TYPE 'boolean';
  25.     public const STRING_TYPE 'string';
  26.     public const DATETIME_TYPE 'datetime';
  27.     public const ARRAY_TYPE 'array';
  28.     public const INTEGER_TYPE 'integer';
  29.     public const DOUBLE_TYPE 'double';
  30.     public const ENTITY_TYPE 'entity';
  31.     public const ENCRYPTED_TYPE 'encrypted';
  32.     public const ACCEPTED_TYPES = [
  33.         self::BOOLEAN_TYPE => BooleanType::class,
  34.         self::STRING_TYPE => StringType::class,
  35.         self::DATETIME_TYPE => DateTimeType::class,
  36.         self::ARRAY_TYPE => ArrayType::class,
  37.         self::INTEGER_TYPE => IntegerType::class,
  38.         self::DOUBLE_TYPE => FloatType::class,
  39.         self::ENTITY_TYPE => EntityType::class,
  40.         self::ENCRYPTED_TYPE => EncryptedType::class,
  41.     ];
  42.     private MySQLPlatform $platform;
  43.     /**
  44.      * Config constructor.
  45.      */
  46.     public function __construct(
  47.         private readonly EntityManagerInterface $entityManager,
  48.         private readonly Adapter $cacheAdapter,
  49.         private readonly ParameterBagInterface $parameterBag,
  50.         private readonly EntityManagerInterface $parentEntityManager,
  51.         private readonly EncryptorInterface $encryptor,
  52.     ) {
  53.         $this->platform = new MySQLPlatform();
  54.     }
  55.     /**
  56.      * @return mixed
  57.      */
  58.     public function get(string $namestring $connection 'default')
  59.     {
  60.         if ($this->cacheAdapter->has($name)) {
  61.             return $this->cacheAdapter->get($name);
  62.         }
  63.         $setting $this->getSetting($name);
  64.         $value $this->getType($setting->getType(), $connection)->convertToPHPValue($setting->getValue(), $this->platform);
  65.         // don't cache a entity type because it is used as an managed entity
  66.         if (self::ENTITY_TYPE !== $setting->getType()) {
  67.             $this->cacheAdapter->set($name$value);
  68.         }
  69.         return $value;
  70.     }
  71.     /**
  72.      * @param $value
  73.      */
  74.     public function set(string $name$value)
  75.     {
  76.         $setting $this->getSetting($name);
  77.         $type $setting->getType();
  78.         // in case of a string, string needs to be converted to object because of cache
  79.         if ('entity' === $type && 'string' === \gettype($value)) {
  80.             $value $this->getType($type)->convertToPHPValue($value$this->platform);
  81.         }
  82.         $databaseValue $this->toDatabaseValueByType($value$type);
  83.         $setting->setValue($databaseValue);
  84.         $this->entityManager->flush();
  85.         $this->cacheAdapter->set($name$value);
  86.     }
  87.     public function getBoolean(string $name): bool
  88.     {
  89.         $result $this->get($name);
  90.         return \is_bool($result) ? $result false;
  91.     }
  92.     public function getConfigIfTypeStringElseEmptyString(string $name): string
  93.     {
  94.         return $this->getConfigIfTypeStringElseNull($name) ?? '';
  95.     }
  96.     public function getConfigIfTypeStringElseNull(string $name): ?string
  97.     {
  98.         $result $this->get($name);
  99.         return \is_string($result) ? $result null;
  100.     }
  101.     /**
  102.      * @return array<int|string, mixed>
  103.      */
  104.     public function getConfigIfTypeArrayElseEmptyArray(string $name): array
  105.     {
  106.         return $this->getConfigIfTypeArrayElseNull($name) ?? [];
  107.     }
  108.     /**
  109.      * @return array<int|string, mixed>|null
  110.      */
  111.     public function getConfigIfTypeArrayElseNull(string $name): ?array
  112.     {
  113.         $result $this->get($name);
  114.         return \is_array($result) ? $result null;
  115.     }
  116.     protected function getSetting(string $name): ConfigurationSetting
  117.     {
  118.         if ($setting $this->getRepository()->findOneBy(['name' => $name])) {
  119.             return $setting;
  120.         }
  121.         // Temporary paramaterBag-fallback to cover unmigrated settings
  122.         // (mainly to support LocalisedSettingService)
  123.         // @todo : can be removed after migrating all parameters
  124.         if ($this->parameterBag->has($name)) {
  125.             $parameter $this->parameterBag->get($name);
  126.             $parameterType \gettype($parameter);
  127.             $configType self::STRING_TYPE;
  128.             if ('NULL' === $parameterType) {
  129.                 $parameterType self::STRING_TYPE;
  130.             }
  131.             switch ($parameterType) {
  132.                 case 'boolean':
  133.                     $configType self::BOOLEAN_TYPE;
  134.                     break;
  135.                 case 'integer':
  136.                     $configType self::INTEGER_TYPE;
  137.                     break;
  138.                 case 'array':
  139.                     $configType self::ARRAY_TYPE;
  140.                     break;
  141.             }
  142.             return (new ConfigurationSetting())
  143.                 ->setName($name)
  144.                 ->setValue($this->toDatabaseValueByType($parameter$parameterType))
  145.                 ->setType($configType)
  146.             ;
  147.         }
  148.         throw $this->createNotFoundException($name);
  149.     }
  150.     public function getType(string $settingTypestring $connection 'default'): ?Type
  151.     {
  152.         if (!\array_key_exists($settingTypeself::ACCEPTED_TYPES)) {
  153.             return null;
  154.         }
  155.         $typeClass self::ACCEPTED_TYPES[$settingType];
  156.         $type = new $typeClass();
  157.         if (method_exists($type'setEntityManager')) {
  158.             $entityManager $this->entityManager;
  159.             if ('parent' === $connection) {
  160.                 $entityManager $this->parentEntityManager;
  161.             }
  162.             $type->setEntityManager($entityManager);
  163.         }
  164.         if (method_exists($type'setEncryptor')) {
  165.             $type->setEncryptor($this->encryptor);
  166.         }
  167.         return $type;
  168.     }
  169.     /**
  170.      * @param string $section name of the section to fetch settings for
  171.      * @param bool   $fresh   is set to true, will force fresh (uncached and managed data)
  172.      *
  173.      * @return array with name => value
  174.      */
  175.     public function getBySection(string $sectionbool $fresh false): array
  176.     {
  177.         $configurationSettingCollection $this->getRepository()->findBy(['section' => $section]);
  178.         return $this->transformCollectionToKeyValue($configurationSettingCollection$fresh);
  179.     }
  180.     /**
  181.      * @param bool $fresh is set to true, will force fresh (uncached and managed data)
  182.      *
  183.      * @return array with name => value
  184.      */
  185.     public function getAll(bool $fresh false): array
  186.     {
  187.         $configurationSettingCollection $this->getRepository()->findAll();
  188.         return $this->transformCollectionToKeyValue($configurationSettingCollection$fresh);
  189.     }
  190.     /**
  191.      * @param $value
  192.      *
  193.      * @return mixed
  194.      */
  195.     protected function toDatabaseValueByType($valuestring $type)
  196.     {
  197.         $valueType \gettype($value);
  198.         if ('entity' === $type && \in_array($valueType, ['object''array''string'], true)) {
  199.             $valueType 'entity';
  200.         }
  201.         if ('encrypted' === $type && 'string' === $valueType) {
  202.             $valueType 'encrypted';
  203.         }
  204.         if ('object' === $valueType) {
  205.             $valueType mb_strtolower(\get_class($value));
  206.         }
  207.         if (null !== $value && $valueType !== $type) {
  208.             throw new TypeError(sprintf('setting must be of the type %s, %s given'$type$valueType));
  209.         }
  210.         return $this->getType($type)->convertToDatabaseValue($value$this->platform);
  211.     }
  212.     /**
  213.      * @return ConfigurationSettingRepository|ObjectRepository
  214.      */
  215.     protected function getRepository(): ObjectRepository
  216.     {
  217.         return $this->entityManager->getRepository(ConfigurationSetting::class);
  218.     }
  219.     /**
  220.      * @param string $name name of the setting
  221.      */
  222.     protected function createNotFoundException(string $name): RuntimeException
  223.     {
  224.         return new RuntimeException(sprintf('Setting "%s" couldn\'t be found.'$name));
  225.     }
  226.     /**
  227.      * Get a array list of all available config settings.
  228.      *
  229.      * @return array list of all config settings
  230.      */
  231.     public function getList(): array
  232.     {
  233.         return $this->getRepository()->getList();
  234.     }
  235.     /**
  236.      * @param bool $fresh is set to true, will force fresh (uncached and managed data)
  237.      *
  238.      * @return array with name => value
  239.      */
  240.     private function transformCollectionToKeyValue(array $configurationSettingCollectionbool $fresh false): array
  241.     {
  242.         $output = [];
  243.         foreach ($configurationSettingCollection as $setting) {
  244.             $name $setting->getName();
  245.             $output[$name] = (false === $fresh && $this->cacheAdapter->has($name))
  246.                 ? $this->cacheAdapter->get($name)
  247.                 : $this->getType($setting->getType())->convertToPHPValue($setting->getValue(), $this->platform)
  248.             ;
  249.         }
  250.         return $output;
  251.     }
  252. }