Spaces:
No application file
No application file
| declare(strict_types=1); | |
| namespace Mautic\ConfigBundle\Form\DataTransformer; | |
| use Mautic\ConfigBundle\Form\Type\EscapeTransformer; | |
| use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
| use Mautic\CoreBundle\Helper\Dsn\Dsn; | |
| use Symfony\Component\Form\DataTransformerInterface; | |
| /** | |
| * @implements DataTransformerInterface<string, array> | |
| */ | |
| class DsnTransformer implements DataTransformerInterface | |
| { | |
| private const PASSWORD_MASK = '🔒'; | |
| public function __construct( | |
| private CoreParametersHelper $coreParametersHelper, | |
| private EscapeTransformer $escapeTransformer, | |
| private string $configKey, | |
| private bool $allowEmpty | |
| ) { | |
| } | |
| /** | |
| * @return array<string, mixed> | |
| */ | |
| public function transform($value): array | |
| { | |
| // unescape the DSN before the transformation to array | |
| $value = $this->escapeTransformer->transform((string) $value); | |
| try { | |
| $dsn = Dsn::fromString($value); | |
| } catch (\InvalidArgumentException) { | |
| return []; | |
| } | |
| return [ | |
| 'scheme' => $dsn->getScheme(), | |
| 'host' => $dsn->getHost(), | |
| 'user' => $dsn->getUser(), | |
| 'password' => $dsn->getPassword() ? self::PASSWORD_MASK : null, | |
| 'port' => $dsn->getPort(), | |
| 'path' => $dsn->getPath(), | |
| 'options' => $dsn->getOptions(), | |
| ]; | |
| } | |
| /** | |
| * @param array<string, mixed> $value | |
| */ | |
| public function reverseTransform($value): string | |
| { | |
| if ($this->allowEmpty && !array_filter($value)) { | |
| return ''; | |
| } | |
| // unescape the values as they are escaped by the escape transformer applied to the child elements | |
| $value = $this->escapeTransformer->transform($value); | |
| $dsn = new Dsn( | |
| (string) $value['scheme'], | |
| (string) $value['host'], | |
| $value['user'], | |
| $value['password'], | |
| $value['port'] ? (int) $value['port'] : null, | |
| $value['path'], | |
| $value['options'], | |
| ); | |
| if (self::PASSWORD_MASK === $dsn->getPassword()) { | |
| $previousDsn = Dsn::fromString($this->coreParametersHelper->get($this->configKey)); | |
| $dsn = $dsn->setPassword($previousDsn->getPassword()); | |
| } | |
| // escape the DSN to prevent "missing parameter" errors | |
| return $this->escapeTransformer->reverseTransform((string) $dsn); | |
| } | |
| } | |