From 55f3916543b3aa78af7d8aefea79e3894d33061e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0pa=C4=8Dek?= Date: Tue, 14 Jan 2025 04:43:18 +0100 Subject: [PATCH] Validate slug/action/alias name Validation rules added using the addRule(Form::Pattern, ...) call, not using any custom validation callback because I want the JS validation to be also used and don't want to add a custom one. --- app/config/services.neon | 1 + app/src/Form/FormValidators.php | 24 ++++++++++++ app/src/Form/PostFormFactory.php | 4 +- app/src/Form/TalkFormFactory.php | 4 +- app/src/Form/TalkSlidesFormFactory.php | 7 ++-- app/src/lang/messages.cs_CZ.neon | 2 + app/src/lang/messages.en_US.neon | 2 + app/tests/Form/FormValidatorsTest.phpt | 52 ++++++++++++++++++++++++++ 8 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 app/src/Form/FormValidators.php create mode 100644 app/tests/Form/FormValidatorsTest.phpt diff --git a/app/config/services.neon b/app/config/services.neon index bcec0a8a8..97eb42ae6 100644 --- a/app/config/services.neon +++ b/app/config/services.neon @@ -48,6 +48,7 @@ services: - MichalSpacekCz\Form\Controls\TrainingControlsFactory - MichalSpacekCz\Form\DeletePersonalDataFormFactory - MichalSpacekCz\Form\FormFactory + - MichalSpacekCz\Form\FormValidators - MichalSpacekCz\Form\InterviewFormFactory(videoThumbnails: @interviewVideoThumbnails) - MichalSpacekCz\Form\PostFormFactory - MichalSpacekCz\Form\Pulse\PasswordsStorageAlgorithmFormFactory diff --git a/app/src/Form/FormValidators.php b/app/src/Form/FormValidators.php new file mode 100644 index 000000000..3b57fe70a --- /dev/null +++ b/app/src/Form/FormValidators.php @@ -0,0 +1,24 @@ +addRule(Form::Pattern, $this->translator->translate('messages.forms.validateSlugParamsError'), '[a-z0-9.,_-]+'); + } + +} diff --git a/app/src/Form/PostFormFactory.php b/app/src/Form/PostFormFactory.php index 25390376b..8c5a70485 100644 --- a/app/src/Form/PostFormFactory.php +++ b/app/src/Form/PostFormFactory.php @@ -36,6 +36,7 @@ public function __construct( private FormFactory $factory, + private FormValidators $validators, private Translator $translator, private BlogPosts $blogPosts, private BlogPostFactory $blogPostFactory, @@ -62,8 +63,9 @@ public function create(callable $onSuccessAdd, callable $onSuccessEdit, DefaultT $form->addText('title', 'Titulek:') ->setRequired('Zadejte prosím titulek') ->addRule(Form::MinLength, 'Titulek musí mít alespoň %d znaky', 3); - $form->addText('slug', 'Slug:') + $slugInput = $form->addText('slug', 'Slug:') ->addRule(Form::MinLength, 'Slug musí mít alespoň %d znaky', 3); + $this->validators->addValidateSlugRules($slugInput); $this->addPublishedDate($form->addText('published', 'Vydáno:')) ->setDefaultValue(date('Y-m-d') . ' HH:MM'); $previewKeyInput = $form->addText('previewKey', 'Klíč pro náhled:') diff --git a/app/src/Form/TalkFormFactory.php b/app/src/Form/TalkFormFactory.php index f7cf45dea..5a75e5844 100644 --- a/app/src/Form/TalkFormFactory.php +++ b/app/src/Form/TalkFormFactory.php @@ -20,6 +20,7 @@ public function __construct( private FormFactory $factory, + private FormValidators $validators, private TrainingControlsFactory $trainingControlsFactory, private Talks $talks, private LinkGenerator $linkGenerator, @@ -42,9 +43,10 @@ public function create(callable $onSuccess, ?Talk $talk = null): UiForm $form->addSelect('locale', 'Jazyk:', $this->locales->getAllLocales()) ->setRequired('Zadejte prosím jazyk') ->setPrompt('- vyberte -'); - $form->addText('action', 'Akce:') + $actionInput = $form->addText('action', 'Akce:') ->setRequired(false) ->addRule(Form::MaxLength, 'Maximální délka akce je %d znaků', 200); + $this->validators->addValidateSlugRules($actionInput); $form->addText('title', 'Název:') ->setRequired('Zadejte prosím název') ->addRule(Form::MaxLength, 'Maximální délka názvu je %d znaků', 200); diff --git a/app/src/Form/TalkSlidesFormFactory.php b/app/src/Form/TalkSlidesFormFactory.php index 865075b36..4a180b181 100644 --- a/app/src/Form/TalkSlidesFormFactory.php +++ b/app/src/Form/TalkSlidesFormFactory.php @@ -19,6 +19,7 @@ public function __construct( private FormFactory $factory, + private FormValidators $validators, private TalkSlides $talkSlides, private TexyFormatter $texyFormatter, private SupportedImageFileFormats $supportedImageFileFormats, @@ -96,9 +97,9 @@ private function addSlideFields(UiForm $form, Container $container, ?int $filena $supportedImages = '*.' . implode(', *.', $this->supportedImageFileFormats->getMainExtensions()); $supportedAlternativeImages = '*.' . implode(', *.', $this->supportedImageFileFormats->getAlternativeExtensions()); $disableSlideUploads = (bool)$filenamesTalkId; - $container->addText('alias', 'Alias:') - ->setRequired('Zadejte prosím alias') - ->addRule(Form::Pattern, 'Alias musí být ve formátu [_.,a-z0-9-]+', '[_.,a-z0-9-]+'); + $aliasInput = $container->addText('alias', 'Alias:') + ->setRequired('Zadejte prosím alias'); + $this->validators->addValidateSlugRules($aliasInput); $container->addInteger('number', 'Slajd:') ->setDefaultValue(1) ->setHtmlAttribute('class', 'right slide-nr') diff --git a/app/src/lang/messages.cs_CZ.neon b/app/src/lang/messages.cs_CZ.neon index 98a3f4b12..c878f14ed 100644 --- a/app/src/lang/messages.cs_CZ.neon +++ b/app/src/lang/messages.cs_CZ.neon @@ -396,3 +396,5 @@ cookies: netteSameSiteCheck: "Používá se pro detekci \"//same-site//\":[blog:co-znamena-origin-site-etld-etld-plus-1-public-suffix-a-psl#same-site] požadavků." httpHeaders: headerNotSent: "hlavička neposlána" +forms: + validateSlugParamsError: "%label musí odpovídat formátu %d" diff --git a/app/src/lang/messages.en_US.neon b/app/src/lang/messages.en_US.neon index 5524ea9df..c5d697432 100644 --- a/app/src/lang/messages.en_US.neon +++ b/app/src/lang/messages.en_US.neon @@ -396,3 +396,5 @@ cookies: netteSameSiteCheck: "Used to detect \"//same-site//\":[blog:origin-site-etld-etld-plus-one-public-suffix-psl-what-are-they#same-site] requests." httpHeaders: headerNotSent: "header not sent" +forms: + validateSlugParamsError: "%label must match %d" diff --git a/app/tests/Form/FormValidatorsTest.phpt b/app/tests/Form/FormValidatorsTest.phpt new file mode 100644 index 000000000..2b8d98ddd --- /dev/null +++ b/app/tests/Form/FormValidatorsTest.phpt @@ -0,0 +1,52 @@ +value = $slug; + $this->validators->addValidateSlugRules($input); + /** @noinspection PhpInternalEntityUsedInspection */ + $input->setParent(new Form()); + $input->validate(); + Assert::same($result ? [] : ['messages.forms.validateSlugParamsError'], $input->getErrors()); + } + +} + +TestCaseRunner::run(FormValidatorsTest::class);