From 1592cf64cfa4dcd80e621556b375f45dec9ae969 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 6 Jan 2021 00:14:16 +0100 Subject: [PATCH] breaks exporting rules to JS after non-static validator [Closes #259] --- src/Forms/Controls/TextBase.php | 6 ++++++ src/Forms/Controls/TextInput.php | 6 ++++++ src/Forms/Controls/UploadControl.php | 3 ++- src/Forms/Helpers.php | 10 ++++++++-- src/Forms/Rule.php | 8 ++++++++ tests/Forms/Controls.TextArea.render.phpt | 10 ++++++++++ tests/Forms/Controls.TextInput.render.phpt | 12 ++++++++++++ tests/Forms/Helpers.exportRules.phpt | 13 +++++++++++++ 8 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/Forms/Controls/TextBase.php b/src/Forms/Controls/TextBase.php index 3c3c52e08..d72d0750b 100644 --- a/src/Forms/Controls/TextBase.php +++ b/src/Forms/Controls/TextBase.php @@ -137,6 +137,12 @@ protected function getRenderedValue(): ?string /** @return static */ public function addRule($validator, $errorMessage = null, $arg = null) { + foreach ($this->getRules() as $rule) { + if (!$rule->canExport() && !$rule->branch) { + return $this; + } + } + if ($validator === Form::LENGTH || $validator === Form::MAX_LENGTH) { $tmp = is_array($arg) ? $arg[1] : $arg; if (is_scalar($tmp)) { diff --git a/src/Forms/Controls/TextInput.php b/src/Forms/Controls/TextInput.php index 15b354aff..8d3645267 100644 --- a/src/Forms/Controls/TextInput.php +++ b/src/Forms/Controls/TextInput.php @@ -68,6 +68,12 @@ public function getControl(): Nette\Utils\Html /** @return static */ public function addRule($validator, $errorMessage = null, $arg = null) { + foreach ($this->getRules() as $rule) { + if (!$rule->canExport() && !$rule->branch) { + return $this; + } + } + if ($this->control->type === null && in_array($validator, [Form::EMAIL, Form::URL, Form::INTEGER], true)) { static $types = [Form::EMAIL => 'email', Form::URL => 'url', Form::INTEGER => 'number']; $this->control->type = $types[$validator]; diff --git a/src/Forms/Controls/UploadControl.php b/src/Forms/Controls/UploadControl.php index 7024dbfb8..cbb481ecb 100644 --- a/src/Forms/Controls/UploadControl.php +++ b/src/Forms/Controls/UploadControl.php @@ -33,7 +33,8 @@ public function __construct($label = null, bool $multiple = false) $this->control->type = 'file'; $this->control->multiple = $multiple; $this->setOption('type', 'file'); - $this->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]); + $this->addCondition(true) // not to block the export of rules to JS + ->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]); $this->addRule(Form::MAX_FILE_SIZE, null, Forms\Helpers::iniGetSize('upload_max_filesize')); $this->monitor(Form::class, function (Form $form): void { diff --git a/src/Forms/Helpers.php b/src/Forms/Helpers.php index 3db7b1356..6a7d01f9a 100644 --- a/src/Forms/Helpers.php +++ b/src/Forms/Helpers.php @@ -100,12 +100,18 @@ public static function exportRules(Rules $rules): array { $payload = []; foreach ($rules as $rule) { - if (!is_string($op = $rule->validator)) { - if (!Nette\Utils\Callback::isStatic($op)) { + if (!$rule->canExport()) { + if ($rule->branch) { continue; } + break; + } + + $op = $rule->validator; + if (!is_string($op)) { $op = Nette\Utils\Callback::toString($op); } + if ($rule->branch) { $item = [ 'op' => ($rule->isNegative ? '~' : '') . $op, diff --git a/src/Forms/Rule.php b/src/Forms/Rule.php index 9f3c628f8..1d2fa0344 100644 --- a/src/Forms/Rule.php +++ b/src/Forms/Rule.php @@ -36,4 +36,12 @@ class Rule /** @var Rules|null for conditions */ public $branch; + + + /** @internal */ + public function canExport(): bool + { + return is_string($this->validator) + || Nette\Utils\Callback::isStatic($this->validator); + } } diff --git a/tests/Forms/Controls.TextArea.render.phpt b/tests/Forms/Controls.TextArea.render.phpt index 660f48d46..45e708c79 100644 --- a/tests/Forms/Controls.TextArea.render.phpt +++ b/tests/Forms/Controls.TextArea.render.phpt @@ -119,3 +119,13 @@ test('setEmptyValue & setNullable', function () { Assert::null($input->getValue()); Assert::same('', (string) $input->getControl()); }); + + +test('addFilter() & rules', function () { + $form = new Form; + $input = $form->addTextArea('text') + ->addFilter(function () {}) + ->addRule(Form::MAX_LENGTH, 'maxl', 10); + + Assert::same('', (string) $input->getControl()); +}); diff --git a/tests/Forms/Controls.TextInput.render.phpt b/tests/Forms/Controls.TextInput.render.phpt index 01ae9da13..397955472 100644 --- a/tests/Forms/Controls.TextInput.render.phpt +++ b/tests/Forms/Controls.TextInput.render.phpt @@ -235,3 +235,15 @@ test('addInteger', function () { Assert::same('', (string) $input->getControl()); }); + + +test('addFilter() & rules', function () { + $form = new Form; + $input = $form->addText('text') + ->addRule(Form::MIN, 'min', 1) + ->addFilter(function () {}) + ->addRule(Form::MAX, 'max', 10) + ->addRule(Form::MAX_LENGTH, 'maxl', 10); + + Assert::same('', (string) $input->getControl()); +}); diff --git a/tests/Forms/Helpers.exportRules.phpt b/tests/Forms/Helpers.exportRules.phpt index 1cfd41cf7..649602319 100644 --- a/tests/Forms/Helpers.exportRules.phpt +++ b/tests/Forms/Helpers.exportRules.phpt @@ -91,3 +91,16 @@ test('', function () { ], ], Helpers::exportRules($input2->getRules())); }); + + +test('addFilter', function () { + $form = new Form; + $input = $form->addText('text'); + $input->addRule(Form::PATTERN, 'match pattern', '\d+'); + $input->addFilter(function () {}); + $input->setRequired(false); + $input->addRule(Form::EMAIL); + Assert::same([ + ['op' => ':pattern', 'msg' => 'match pattern', 'arg' => '\\d+'], + ], Helpers::exportRules($input->getRules())); +});