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

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.         if ($setting->getValue() === (null !== $databaseValue \strval($databaseValue) : null)) {
  84.             return;
  85.         }
  86.         $setting->setValue($databaseValue);
  87.         $this->entityManager->flush();
  88.         $this->cacheAdapter->set($name$value);
  89.     }
  90.     public function getBoolean(string $name): bool
  91.     {
  92.         $result $this->get($name);
  93.         return \is_bool($result) ? $result false;
  94.     }
  95.     public function getConfigIfTypeStringElseEmptyString(string $name): string
  96.     {
  97.         return $this->getConfigIfTypeStringElseNull($name) ?? '';
  98.     }
  99.     public function getConfigIfTypeStringElseNull(string $name): ?string
  100.     {
  101.         $result $this->get($name);
  102.         return \is_string($result) ? $result null;
  103.     }
  104.     /**
  105.      * @return array<int|string, mixed>
  106.      */
  107.     public function getConfigIfTypeArrayElseEmptyArray(string $name): array
  108.     {
  109.         return $this->getConfigIfTypeArrayElseNull($name) ?? [];
  110.     }
  111.     /**
  112.      * @return array<int|string, mixed>|null
  113.      */
  114.     public function getConfigIfTypeArrayElseNull(string $name): ?array
  115.     {
  116.         $result $this->get($name);
  117.         return \is_array($result) ? $result null;
  118.     }
  119.     protected function getSetting(string $name): ConfigurationSetting
  120.     {
  121.         if ($setting $this->getRepository()->findOneBy(['name' => $name])) {
  122.             return $setting;
  123.         }
  124.         // Temporary paramaterBag-fallback to cover unmigrated settings
  125.         // (mainly to support LocalisedSettingService)
  126.         // @todo : can be removed after migrating all parameters
  127.         if ($this->parameterBag->has($name)) {
  128.             $parameter $this->parameterBag->get($name);
  129.             $parameterType \gettype($parameter);
  130.             $configType self::STRING_TYPE;
  131.             if ('NULL' === $parameterType) {
  132.                 $parameterType self::STRING_TYPE;
  133.             }
  134.             switch ($parameterType) {
  135.                 case 'boolean':
  136.                     $configType self::BOOLEAN_TYPE;
  137.                     break;
  138.                 case 'integer':
  139.                     $configType self::INTEGER_TYPE;
  140.                     break;
  141.                 case 'array':
  142.                     $configType self::ARRAY_TYPE;
  143.                     break;
  144.             }
  145.             return (new ConfigurationSetting())
  146.                 ->setName($name)
  147.                 ->setValue($this->toDatabaseValueByType($parameter$parameterType))
  148.                 ->setType($configType)
  149.             ;
  150.         }
  151.         throw $this->createNotFoundException($name);
  152.     }
  153.     public function getType(string $settingTypestring $connection 'default'): ?Type
  154.     {
  155.         if (!\array_key_exists($settingTypeself::ACCEPTED_TYPES)) {
  156.             return null;
  157.         }
  158.         $typeClass self::ACCEPTED_TYPES[$settingType];
  159.         $type = new $typeClass();
  160.         if (method_exists($type'setEntityManager')) {
  161.             $entityManager $this->entityManager;
  162.             if ('parent' === $connection) {
  163.                 $entityManager $this->parentEntityManager;
  164.             }
  165.             $type->setEntityManager($entityManager);
  166.         }
  167.         if (method_exists($type'setEncryptor')) {
  168.             $type->setEncryptor($this->encryptor);
  169.         }
  170.         return $type;
  171.     }
  172.     /**
  173.      * @param string $section name of the section to fetch settings for
  174.      * @param bool   $fresh   is set to true, will force fresh (uncached and managed data)
  175.      *
  176.      * @return array with name => value
  177.      */
  178.     public function getBySection(string $sectionbool $fresh false): array
  179.     {
  180.         $configurationSettingCollection $this->getRepository()->findBy(['section' => $section]);
  181.         return $this->transformCollectionToKeyValue($configurationSettingCollection$fresh);
  182.     }
  183.     /**
  184.      * @param bool $fresh is set to true, will force fresh (uncached and managed data)
  185.      *
  186.      * @return array with name => value
  187.      */
  188.     public function getAll(bool $fresh false): array
  189.     {
  190.         $configurationSettingCollection $this->getRepository()->findAll();
  191.         return $this->transformCollectionToKeyValue($configurationSettingCollection$fresh);
  192.     }
  193.     /**
  194.      * @param $value
  195.      *
  196.      * @return mixed
  197.      */
  198.     protected function toDatabaseValueByType($valuestring $type)
  199.     {
  200.         $valueType \gettype($value);
  201.         if ('entity' === $type && \in_array($valueType, ['object''array''string'], true)) {
  202.             $valueType 'entity';
  203.         }
  204.         if ('encrypted' === $type && 'string' === $valueType) {
  205.             $valueType 'encrypted';
  206.         }
  207.         if ('object' === $valueType) {
  208.             $valueType mb_strtolower(\get_class($value));
  209.         }
  210.         if (null !== $value && $valueType !== $type) {
  211.             throw new TypeError(sprintf('setting must be of the type %s, %s given'$type$valueType));
  212.         }
  213.         return $this->getType($type)->convertToDatabaseValue($value$this->platform);
  214.     }
  215.     /**
  216.      * @return ConfigurationSettingRepository|ObjectRepository
  217.      */
  218.     protected function getRepository(): ObjectRepository
  219.     {
  220.         return $this->entityManager->getRepository(ConfigurationSetting::class);
  221.     }
  222.     /**
  223.      * @param string $name name of the setting
  224.      */
  225.     protected function createNotFoundException(string $name): RuntimeException
  226.     {
  227.         return new RuntimeException(sprintf('Setting "%s" couldn\'t be found.'$name));
  228.     }
  229.     /**
  230.      * Get a array list of all available config settings.
  231.      *
  232.      * @return array list of all config settings
  233.      */
  234.     public function getList(): array
  235.     {
  236.         return $this->getRepository()->getList();
  237.     }
  238.     /**
  239.      * @param bool $fresh is set to true, will force fresh (uncached and managed data)
  240.      *
  241.      * @return array with name => value
  242.      */
  243.     private function transformCollectionToKeyValue(array $configurationSettingCollectionbool $fresh false): array
  244.     {
  245.         $output = [];
  246.         foreach ($configurationSettingCollection as $setting) {
  247.             $name $setting->getName();
  248.             $output[$name] = (false === $fresh && $this->cacheAdapter->has($name))
  249.                 ? $this->cacheAdapter->get($name)
  250.                 : $this->getType($setting->getType())->convertToPHPValue($setting->getValue(), $this->platform)
  251.             ;
  252.         }
  253.         return $output;
  254.     }
  255. }