vendor/terminal42/notification_center/src/Config/ConfigLoader.php line 115

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Terminal42\NotificationCenterBundle\Config;
  4. use Contao\DcaLoader;
  5. use Contao\StringUtil;
  6. use Doctrine\DBAL\Connection;
  7. use Symfony\Contracts\Service\ResetInterface;
  8. class ConfigLoader implements ResetInterface
  9. {
  10. /**
  11. * @var array<string, array<int, array<string, mixed>>>
  12. */
  13. private array $cache = [];
  14. public function __construct(private readonly Connection $connection)
  15. {
  16. }
  17. public function loadGateway(int $id): GatewayConfig|null
  18. {
  19. return $this->loadConfig($id, 'tl_nc_gateway', GatewayConfig::class);
  20. }
  21. public function loadNotification(int $id): NotificationConfig|null
  22. {
  23. return $this->loadConfig($id, 'tl_nc_notification', NotificationConfig::class);
  24. }
  25. public function loadMessage(int $id): MessageConfig|null
  26. {
  27. return $this->loadConfig($id, 'tl_nc_message', MessageConfig::class);
  28. }
  29. public function loadModule(int $id): ModuleConfig|null
  30. {
  31. return $this->loadConfig($id, 'tl_module', ModuleConfig::class);
  32. }
  33. public function loadForm(int $id): FormConfig|null
  34. {
  35. return $this->loadConfig($id, 'tl_form', FormConfig::class);
  36. }
  37. /**
  38. * @return array<MessageConfig>
  39. */
  40. public function loadMessagesForNotification(int $notificationId): array
  41. {
  42. $messages = [];
  43. $query = $this->connection->createQueryBuilder()
  44. ->select('*')
  45. ->from('tl_nc_message')
  46. ->where('pid = :pid')
  47. ->setParameter('pid', $notificationId)
  48. ->orderBy('sorting')
  49. ;
  50. foreach ($query->fetchAllAssociative() as $row) {
  51. $row = $this->cleanParameters($row, 'tl_nc_message');
  52. $this->cache['tl_nc_message'][$row['id']] = $row;
  53. $messages[] = MessageConfig::fromArray($row);
  54. }
  55. return $messages;
  56. }
  57. public function loadLanguage(int $id): LanguageConfig|null
  58. {
  59. return $this->loadConfig($id, 'tl_nc_language', LanguageConfig::class);
  60. }
  61. public function loadLanguageForMessageAndLocale(int $messageId, string|null $locale = null): LanguageConfig|null
  62. {
  63. $query = $this->connection->createQueryBuilder()
  64. ->select('*')
  65. ->from('tl_nc_language')
  66. ->where('pid = :pid')
  67. ->setParameter('pid', $messageId)
  68. ;
  69. if (null === $locale) {
  70. $query
  71. ->andWhere('fallback = :fallback')
  72. ->setParameter('fallback', true)
  73. ;
  74. } else {
  75. $localeWithoutRegion = substr($locale, 0, 2);
  76. $query
  77. ->andWhere('language = :locale OR language = :localeWithoutRegion OR fallback = :fallback')
  78. ->orderBy('LENGTH(language) DESC, fallback') // First the exact match with region, then without region, then fallback
  79. ->setParameter('locale', $locale)
  80. ->setParameter('localeWithoutRegion', $localeWithoutRegion)
  81. ->setParameter('fallback', true)
  82. ;
  83. }
  84. $parameters = $query->fetchAssociative();
  85. if (false === $parameters) {
  86. return null;
  87. }
  88. $parameters = $this->cleanParameters($parameters, 'tl_nc_language');
  89. return LanguageConfig::fromArray($parameters);
  90. }
  91. public function reset(): void
  92. {
  93. $this->cache = [];
  94. }
  95. /**
  96. * @template T of AbstractConfig
  97. *
  98. * @param class-string<T> $className
  99. *
  100. * @return T|null
  101. */
  102. private function loadConfig(int $id, string $table, string $className): AbstractConfig|null
  103. {
  104. if (null === ($parameters = $this->loadParameters($id, $table))) {
  105. return null;
  106. }
  107. return $className::fromArray($parameters);
  108. }
  109. /**
  110. * @return array<string, mixed>|null
  111. */
  112. private function loadParameters(int $id, string $table): array|null
  113. {
  114. if (isset($this->cache[$table][$id])) {
  115. return $this->cache[$table][$id];
  116. }
  117. if (!isset($this->cache[$table])) {
  118. $this->cache[$table] = [];
  119. }
  120. try {
  121. $parameters = $this->connection->createQueryBuilder()
  122. ->select('*')
  123. ->from($table)
  124. ->where('id = :id')
  125. ->setParameter('id', $id)
  126. ->fetchAssociative()
  127. ;
  128. if (false === $parameters) {
  129. return $this->cache[$table][$id] = null;
  130. }
  131. $parameters = $this->cleanParameters($parameters, $table);
  132. return $this->cache[$table][$id] = $parameters;
  133. } catch (\Exception) {
  134. return $this->cache[$table][$id] = null;
  135. }
  136. }
  137. /**
  138. * @param array<mixed> $parameters
  139. *
  140. * @return array<mixed>
  141. */
  142. private function cleanParameters(array $parameters, string $table): array
  143. {
  144. $cleanedParameters = [];
  145. try {
  146. $dcaLoader = new DcaLoader($table);
  147. $dcaLoader->load();
  148. foreach ($parameters as $field => $parameter) {
  149. $cleanedParameters[$field] = $parameter;
  150. if (($GLOBALS['TL_DCA'][$table]['fields'][$field]['eval']['decodeEntities'] ?? false) && \is_string($parameter)) {
  151. $cleanedParameters[$field] = StringUtil::decodeEntities($parameter);
  152. }
  153. }
  154. } catch (\Exception) {
  155. $cleanedParameters = $parameters;
  156. }
  157. return $cleanedParameters;
  158. }
  159. }