diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md deleted file mode 100644 index a4cd12634..000000000 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: "🐛 Bug Report" -about: "If something isn't working as expected 🤔" - ---- - -Version: ?.?.? - -### Bug Description -... A clear and concise description of what the bug is. A good bug report shouldn't leave others needing to chase you up for more information. - -### Steps To Reproduce -... If possible a minimal demo of the problem ... - -### Expected Behavior -... A clear and concise description of what you expected to happen. - -### Possible Solution -... Only if you have suggestions on a fix for the bug diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md deleted file mode 100644 index d2e219489..000000000 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: "🚀 Feature Request" -about: "I have a suggestion (and may want to implement it) 🙂" - ---- - -- Is your feature request related to a problem? Please describe. -- Explain your intentions. -- It's up to you to make a strong case to convince the project's developers of the merits of this feature. diff --git a/.github/ISSUE_TEMPLATE/Support_question.md b/.github/ISSUE_TEMPLATE/Support_question.md deleted file mode 100644 index 75c48b6ed..000000000 --- a/.github/ISSUE_TEMPLATE/Support_question.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: "🤗 Support Question" -about: "If you have a question 💬, please check out our forum!" - ---- - ---------------^ Click "Preview" for a nicer view! -We primarily use GitHub as an issue tracker; for usage and support questions, please check out these resources below. Thanks! 😁. - -* Nette Forum: https://forum.nette.org -* Nette Gitter: https://gitter.im/nette/nette -* Slack (czech): https://pehapkari.slack.com/messages/C2R30BLKA diff --git a/.github/ISSUE_TEMPLATE/Support_us.md b/.github/ISSUE_TEMPLATE/Support_us.md deleted file mode 100644 index 92d8a4c3a..000000000 --- a/.github/ISSUE_TEMPLATE/Support_us.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: "❤️ Support us" -about: "If you would like to support our efforts in maintaining this project 🙌" - ---- - ---------------^ Click "Preview" for a nicer view! - -> https://nette.org/donate - -Help support Nette! - -We develop Nette Framework for more than 14 years. In order to make your life more comfortable. Nette cares about the safety of your sites. Nette saves you time. And gives job opportunities. - -Nette earns you money. And is absolutely free. - -To ensure future development and improving the documentation, we need your donation. - -Whether you are chief of IT company which benefits from Nette, or developer who goes for advice on our forum, if you like Nette, [please make a donation now](https://nette.org/donate). - -Thank you! diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index 25adc9520..000000000 --- a/.github/funding.yml +++ /dev/null @@ -1,2 +0,0 @@ -github: dg -custom: "https://nette.org/donate" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index f8aa3f408..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,11 +0,0 @@ -- bug fix / new feature? -- BC break? yes/no -- doc PR: nette/docs#??? - - diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index c32a75810..c7ae52238 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 with: - php-version: 7.4 + php-version: 8.0 coverage: none - run: composer install --no-progress --prefer-dist diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index efc34d490..239bdc4d2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + php: ['8.0', '8.1', '8.2'] fail-fast: false @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 with: - php-version: 7.2 + php-version: 8.0 coverage: none - run: composer update --no-progress --prefer-dist --prefer-lowest --prefer-stable diff --git a/composer.json b/composer.json index a3bb333aa..610c00d48 100644 --- a/composer.json +++ b/composer.json @@ -15,15 +15,15 @@ } ], "require": { - "php": ">=7.2 <8.3", - "nette/component-model": "^3.0", - "nette/http": "^3.1", - "nette/utils": "^3.2.5 || ~4.0.0" + "php": ">=8.0 <8.3", + "nette/component-model": "^4.0", + "nette/http": "^4.0", + "nette/utils": "^4.0" }, "require-dev": { - "nette/application": "^3.0", - "nette/di": "^3.0", - "nette/tester": "^2.4", + "nette/application": "^4.0", + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.5", "latte/latte": "^2.10.2 || ^3.0.3", "tracy/tracy": "^2.9", "phpstan/phpstan-nette": "^1" @@ -41,7 +41,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } } } diff --git a/contributing.md b/contributing.md deleted file mode 100644 index 184152c02..000000000 --- a/contributing.md +++ /dev/null @@ -1,33 +0,0 @@ -How to contribute & use the issue tracker -========================================= - -Nette welcomes your contributions. There are several ways to help out: - -* Create an issue on GitHub, if you have found a bug -* Write test cases for open bug issues -* Write fixes for open bug/feature issues, preferably with test cases included -* Contribute to the [documentation](https://nette.org/en/writing) - -Issues ------- - -Please **do not use the issue tracker to ask questions**. We will be happy to help you -on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). - -A good bug report shouldn't leave others needing to chase you up for more -information. Please try to be as detailed as possible in your report. - -**Feature requests** are welcome. But take a moment to find out whether your idea -fits with the scope and aims of the project. It's up to *you* to make a strong -case to convince the project's developers of the merits of this feature. - -Contributing ------------- - -If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). - -The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. - -Please do not fix whitespace, format code, or make a purely cosmetic patch. - -Thanks! :heart: diff --git a/examples/custom-control.php b/examples/custom-control.php index d8c1041da..1db53b81c 100644 --- a/examples/custom-control.php +++ b/examples/custom-control.php @@ -18,12 +18,11 @@ class DateInput extends Nette\Forms\Controls\BaseControl { - /** @var string */ - private $day = ''; + private string $day = ''; - private $month = ''; + private string $month = ''; - private $year = ''; + private string $year = ''; public function __construct($label = null) @@ -88,7 +87,7 @@ public function getControl() . Helpers::createSelectBox( [1 => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [], - $this->month + $this->month, )->name($name . '[month]') . Html::el('input', [ diff --git a/readme.md b/readme.md index fe20b2ab8..090633666 100644 --- a/readme.md +++ b/readme.md @@ -44,7 +44,7 @@ The recommended way to install is via Composer: composer require nette/forms ``` -It requires PHP version 7.2 and supports PHP up to 8.2. +It requires PHP version 8.0 and supports PHP up to 8.2. Client-side support can be installed with npm or yarn: diff --git a/src/Bridges/FormsDI/FormsExtension.php b/src/Bridges/FormsDI/FormsExtension.php index 58281781b..5b4989f89 100644 --- a/src/Bridges/FormsDI/FormsExtension.php +++ b/src/Bridges/FormsDI/FormsExtension.php @@ -21,7 +21,7 @@ public function __construct() { $this->config = new class { /** @var string[] */ - public $messages = []; + public array $messages = []; }; } diff --git a/src/Bridges/FormsLatte/FormMacros.php b/src/Bridges/FormsLatte/FormMacros.php index 736ca3349..f05d50488 100644 --- a/src/Bridges/FormsLatte/FormMacros.php +++ b/src/Bridges/FormsLatte/FormMacros.php @@ -31,7 +31,7 @@ final class FormMacros extends MacroSet public static function install(Latte\Compiler $compiler): void { $me = new static($compiler); - $me->addMacro('form', [$me, 'macroForm'], 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack));'); + $me->addMacro('form', [$me, 'macroForm'], 'echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack));'); $me->addMacro('formContext', [$me, 'macroFormContext'], 'array_pop($this->global->formsStack);'); $me->addMacro('formContainer', [$me, 'macroFormContainer'], 'array_pop($this->global->formsStack); $formContainer = end($this->global->formsStack)'); $me->addMacro('label', [$me, 'macroLabel'], [$me, 'macroLabelEnd'], null, self::AUTO_EMPTY); @@ -67,12 +67,12 @@ public function macroForm(MacroNode $node, PhpWriter $writer) $node->replaced = true; $node->tokenizer->reset(); return $writer->write( - 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $this->global->formsStack[] = ' + 'echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = ' . ($name[0] === '$' ? 'is_object($ʟ_tmp = %node.word) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]' : '$this->global->uiControl[%node.word]') . ', %node.array)' - . " /* line $node->startLine */;" + . " /* line $node->startLine */;", ); } @@ -101,7 +101,7 @@ public function macroFormContext(MacroNode $node, PhpWriter $writer) . ($name[0] === '$' ? 'is_object($ʟ_tmp = %node.word) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]' : '$this->global->uiControl[%node.word]') - . " /* line $node->startLine */;" + . " /* line $node->startLine */;", ); } @@ -126,7 +126,7 @@ public function macroFormContainer(MacroNode $node, PhpWriter $writer) . ($name[0] === '$' ? 'is_object($ʟ_tmp = %node.word) ? $ʟ_tmp : end($this->global->formsStack)[$ʟ_tmp]' : 'end($this->global->formsStack)[%node.word]') - . " /* line $node->startLine */;" + . " /* line $node->startLine */;", ); } @@ -155,7 +155,7 @@ public function macroLabel(MacroNode $node, PhpWriter $writer) . '->%1.raw) echo $ʟ_label' . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : ''), $name, - $words ? ('getLabelPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')') : 'getLabel()' + $words ? ('getLabelPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')') : 'getLabel()', ); } @@ -196,7 +196,7 @@ public function macroInput(MacroNode $node, PhpWriter $writer) . ($node->tokenizer->isNext() ? '->addAttributes(%node.array)' : '') . " /* line $node->startLine */;", $name, - $words ? 'getControlPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')' : 'getControl()' + $words ? 'getControlPart(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')' : 'getControl()', ); } @@ -227,11 +227,11 @@ public function macroNameAttr(MacroNode $node, PhpWriter $writer) ? 'is_object($ʟ_tmp = %0.word) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]' : '$this->global->uiControl[%0.word]') . " /* line $node->startLine */; ?>", - $name + $name, ); return $writer->write( - 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin(end($this->global->formsStack), %0.var, false)', - array_fill_keys($definedHtmlAttributes, null) + 'echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), %0.var, false)', + array_fill_keys($definedHtmlAttributes, null), ); } else { $method = $tagName === 'label' ? 'getLabel' : 'getControl'; @@ -245,7 +245,7 @@ public function macroNameAttr(MacroNode $node, PhpWriter $writer) . " /* line $node->startLine */;", $name, $method . 'Part(' . implode(', ', array_map([$writer, 'formatWord'], $words)) . ')', - array_fill_keys($definedHtmlAttributes, null) + array_fill_keys($definedHtmlAttributes, null), ); } } @@ -265,7 +265,7 @@ public function macroNameEnd(MacroNode $node, PhpWriter $writer) { $tagName = strtolower($node->htmlNode->name); if ($tagName === 'form') { - $node->innerContent .= 'global->formsStack), false)' + $node->innerContent .= 'global->formsStack), false)' . " /* line $node->startLine */; ?>"; } elseif ($tagName === 'label') { if ($node->htmlNode->empty) { @@ -298,7 +298,7 @@ public function macroInputError(MacroNode $node, PhpWriter $writer) return $writer->write( '$ʟ_input = is_object($ʟ_tmp = %0.word) ? $ʟ_tmp : end($this->global->formsStack)[$ʟ_tmp];' . "echo %escape(\$ʟ_input->getError()) /* line $node->startLine */;", - $name + $name, ); } else { return $writer->write("echo %escape(end(\$this->global->formsStack)[%0.word]->getError()) /* line $node->startLine */;", $name); @@ -319,11 +319,9 @@ public function macroFormPrint(MacroNode $node, PhpWriter $writer) $node->tokenizer->reset(); return $writer->write( - 'Nette\Bridges\FormsLatte\Runtime::render' . $node->name . '(' - . ($name[0] === '$' - ? 'is_object($ʟ_tmp = %node.word) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]' - : '$this->global->uiControl[%node.word]') - . '); exit;' + 'Nette\Bridges\FormsLatte\Runtime2::render' . $node->name . '(' + . ($name[0] === '$' ? 'is_object(%node.word) ? %node.word : ' : '') + . '$this->global->uiControl[%node.word]); exit;', ); } } diff --git a/src/Bridges/FormsLatte/FormsExtension.php b/src/Bridges/FormsLatte/FormsExtension.php index 3e13a0b88..92dd0b20d 100644 --- a/src/Bridges/FormsLatte/FormsExtension.php +++ b/src/Bridges/FormsLatte/FormsExtension.php @@ -38,7 +38,13 @@ public function getTags(): array public function getProviders(): array { return [ - 'formsStack' => [], + 'forms' => new Runtime, ]; } + + + public function getCacheKey(Latte\Engine $engine): array + { + return ['version' => 2]; + } } diff --git a/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php b/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php index 78ce293a6..bbf3681ea 100644 --- a/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php +++ b/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php @@ -64,7 +64,7 @@ private function init(Tag $tag) $elName = strtolower($el->name); $tag->replaceNAttribute(new AuxiliaryNode(fn(PrintContext $context) => $context->format( - 'echo ($ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global))' + 'echo ($ʟ_input = $this->global->forms->item(%node))' . ($elName === 'label' ? '->getLabelPart(%node)' : '->getControlPart(%node)') . ($usedAttributes ? '->addAttributes(%dump)' : '') . '->attributes() %3.line;', diff --git a/src/Bridges/FormsLatte/Nodes/FormContainerNode.php b/src/Bridges/FormsLatte/Nodes/FormContainerNode.php index 36cd2aa9f..9569d8a85 100644 --- a/src/Bridges/FormsLatte/Nodes/FormContainerNode.php +++ b/src/Bridges/FormsLatte/Nodes/FormContainerNode.php @@ -41,9 +41,9 @@ public static function create(Tag $tag): \Generator public function print(PrintContext $context): string { return $context->format( - '$this->global->formsStack[] = $formContainer = Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global) %line; ' + '$this->global->forms->begin($formContainer = $this->global->forms->item(%node)) %line; ' . '%node ' - . 'array_pop($this->global->formsStack); $formContainer = end($this->global->formsStack);' + . '$this->global->forms->end(); $formContainer = $this->global->forms->current();' . "\n\n", $this->name, $this->position, diff --git a/src/Bridges/FormsLatte/Nodes/FormNNameNode.php b/src/Bridges/FormsLatte/Nodes/FormNNameNode.php index 2de161e4a..b46ceb866 100644 --- a/src/Bridges/FormsLatte/Nodes/FormNNameNode.php +++ b/src/Bridges/FormsLatte/Nodes/FormNNameNode.php @@ -42,13 +42,13 @@ public static function create(Tag $tag): \Generator public function print(PrintContext $context): string { return $context->format( - '$form = $this->global->formsStack[] = ' + '$this->global->forms->begin($form = ' . ($this->name instanceof StringNode ? '$this->global->uiControl[%node]' - : 'is_object($ʟ_tmp = %node) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]') - . ' %line;' + : '(is_object($ʟ_tmp = %node) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp])') + . ') %line;' . '%node ' - . 'array_pop($this->global->formsStack);', + . '$this->global->forms->end();', $this->name, $this->position, $this->content, @@ -61,7 +61,7 @@ private function init(Tag $tag) $el = $tag->htmlElement; $tag->replaceNAttribute(new AuxiliaryNode(fn(PrintContext $context) => $context->format( - 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin(end($this->global->formsStack), %dump, false) %line;', + 'echo $this->global->forms->renderFormBegin(%dump, false) %line;', array_fill_keys(FieldNNameNode::findUsedAttributes($el), null), $this->position, ))); @@ -69,7 +69,7 @@ private function init(Tag $tag) $el->content = new Latte\Compiler\Nodes\FragmentNode([ $el->content, new AuxiliaryNode(fn(PrintContext $context) => $context->format( - 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) %line;', + 'echo $this->global->forms->renderFormEnd(false) %line;', $this->position, )), ]); diff --git a/src/Bridges/FormsLatte/Nodes/FormNode.php b/src/Bridges/FormsLatte/Nodes/FormNode.php index c2902d78d..b98d6e3f9 100644 --- a/src/Bridges/FormsLatte/Nodes/FormNode.php +++ b/src/Bridges/FormsLatte/Nodes/FormNode.php @@ -61,19 +61,21 @@ public static function create(Tag $tag): \Generator public function print(PrintContext $context): string { return $context->format( - '$form = $this->global->formsStack[] = ' + '$this->global->forms->begin($form = ' . ($this->name instanceof StringNode ? '$this->global->uiControl[%node]' - : 'is_object($ʟ_tmp = %node) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]') - . ' %line;' + : '(is_object($ʟ_tmp = %node) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp])') + . ') %line;' . ($this->print - ? 'echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, %node) %1.line;' + ? 'echo $this->global->forms->renderFormBegin(%node) %1.line;' : '') . ' %3.node ' . ($this->print - ? 'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack))' - : 'array_pop($this->global->formsStack)') - . " %4.line;\n\n", + ? 'echo $this->global->forms->renderFormEnd()' + : '') + . ' %4.line;' + . '$this->global->forms->end();' + . "\n\n", $this->name, $this->position, $this->attributes, diff --git a/src/Bridges/FormsLatte/Nodes/FormPrintNode.php b/src/Bridges/FormsLatte/Nodes/FormPrintNode.php index 427beedbb..eb25d4b2c 100644 --- a/src/Bridges/FormsLatte/Nodes/FormPrintNode.php +++ b/src/Bridges/FormsLatte/Nodes/FormPrintNode.php @@ -39,10 +39,10 @@ public static function create(Tag $tag): static public function print(PrintContext $context): string { return $context->format( - 'Nette\Bridges\FormsLatte\Runtime::render%raw(' + '$this->global->forms->render%raw(' . ($this->name ? 'is_object($ʟ_tmp = %node) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp]' - : 'end($this->global->formsStack)') + : '$this->global->forms->current()') . ') %2.line; exit;', $this->mode, $this->name, diff --git a/src/Bridges/FormsLatte/Nodes/InputErrorNode.php b/src/Bridges/FormsLatte/Nodes/InputErrorNode.php index ba2767a61..c30a6bba4 100644 --- a/src/Bridges/FormsLatte/Nodes/InputErrorNode.php +++ b/src/Bridges/FormsLatte/Nodes/InputErrorNode.php @@ -9,7 +9,6 @@ namespace Nette\Bridges\FormsLatte\Nodes; -use Latte\Compiler\Nodes\Php\Expression\VariableNode; use Latte\Compiler\Nodes\Php\ExpressionNode; use Latte\Compiler\Nodes\StatementNode; use Latte\Compiler\PrintContext; @@ -27,13 +26,10 @@ class InputErrorNode extends StatementNode public static function create(Tag $tag): static { $tag->outputMode = $tag::OutputKeepIndentation; + $tag->expectArguments(); + $node = new static; - if ($tag->parser->isEnd()) { - trigger_error("Missing argument in {inputError} (on line {$tag->position->line})", E_USER_DEPRECATED); - $node->name = new VariableNode('ʟ_input'); - } else { - $node->name = $tag->parser->parseUnquotedStringOrExpression(); - } + $node->name = $tag->parser->parseUnquotedStringOrExpression(); return $node; } @@ -41,7 +37,7 @@ public static function create(Tag $tag): static public function print(PrintContext $context): string { return $context->format( - 'echo %escape(Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global)->getError()) %line;', + 'echo %escape($this->global->forms->item(%node)->getError()) %line;', $this->name, $this->position, ); diff --git a/src/Bridges/FormsLatte/Nodes/InputNode.php b/src/Bridges/FormsLatte/Nodes/InputNode.php index d9f6841eb..be5a4e3b8 100644 --- a/src/Bridges/FormsLatte/Nodes/InputNode.php +++ b/src/Bridges/FormsLatte/Nodes/InputNode.php @@ -48,7 +48,7 @@ public static function create(Tag $tag): static public function print(PrintContext $context): string { return $context->format( - 'echo Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global)->' + 'echo $this->global->forms->item(%node)->' . ($this->part ? ('getControlPart(%node)') : 'getControl()') . ($this->attributes->items ? '->addAttributes(%2.node)' : '') . ' %3.line;', diff --git a/src/Bridges/FormsLatte/Nodes/LabelNode.php b/src/Bridges/FormsLatte/Nodes/LabelNode.php index cf1316c59..82990d9e0 100644 --- a/src/Bridges/FormsLatte/Nodes/LabelNode.php +++ b/src/Bridges/FormsLatte/Nodes/LabelNode.php @@ -63,7 +63,7 @@ public static function create(Tag $tag): \Generator public function print(PrintContext $context): string { return $context->format( - 'echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global)->' + 'echo ($ʟ_label = $this->global->forms->item(%node)->' . ($this->part ? 'getLabelPart(%node)' : 'getLabel()') . ')' . ($this->attributes->items ? '?->addAttributes(%2.node)' : '') diff --git a/src/Bridges/FormsLatte/Runtime.php b/src/Bridges/FormsLatte/Runtime.php index 0de03a92b..d1f55f28a 100644 --- a/src/Bridges/FormsLatte/Runtime.php +++ b/src/Bridges/FormsLatte/Runtime.php @@ -11,23 +11,27 @@ use Latte; use Nette; +use Nette\Forms\Container; use Nette\Forms\Form; use Nette\Utils\Html; /** - * Runtime helpers for Latte v2 & v3. + * Runtime helpers for Latte v3. * @internal */ class Runtime { - use Nette\StaticClass; + /** @var Container[] */ + private array $stack = []; + /** * Renders form begin. */ - public static function renderFormBegin(Form $form, array $attrs, bool $withTags = true): string + public function renderFormBegin(array $attrs, bool $withTags = true): string { + $form = $this->current(); $form->fireRenderEvents(); foreach ($form->getControls() as $control) { $control->setOption('rendered', false); @@ -48,8 +52,9 @@ public static function renderFormBegin(Form $form, array $attrs, bool $withTags /** * Renders form end. */ - public static function renderFormEnd(Form $form, bool $withTags = true): string + public function renderFormEnd(bool $withTags = true): string { + $form = $this->current(); $s = ''; if ($form->isMethod('get')) { foreach (preg_split('#[;&]#', (string) parse_url($form->getElementPrototype()->action, PHP_URL_QUERY), -1, PREG_SPLIT_NO_EMPTY) as $param) { @@ -79,7 +84,7 @@ public static function renderFormEnd(Form $form, bool $withTags = true): string /** * Generates blueprint of form. */ - public static function renderFormPrint(Form $form): void + public function renderFormPrint(Form $form): void { $blueprint = class_exists(Latte\Runtime\Blueprint::class) ? new Latte\Runtime\Blueprint @@ -94,7 +99,7 @@ public static function renderFormPrint(Form $form): void /** * Generates blueprint of form data class. */ - public static function renderFormClassPrint(Form $form): void + public function renderFormClassPrint(Form $form): void { $blueprint = class_exists(Latte\Runtime\Blueprint::class) ? new Latte\Runtime\Blueprint @@ -103,24 +108,35 @@ public static function renderFormClassPrint(Form $form): void $blueprint->printHeader('Form Data Class ' . $form->getName()); $generator = new Nette\Forms\Rendering\DataClassGenerator; $blueprint->printCode($generator->generateCode($form)); - if (PHP_VERSION_ID >= 80000) { - $generator->propertyPromotion = true; - $blueprint->printCode($generator->generateCode($form)); - } + $generator->propertyPromotion = true; + $blueprint->printCode($generator->generateCode($form)); echo $end; } - public static function item($item, $global): object + public function item($item): object { - if (is_object($item)) { - return $item; - } - $form = end($global->formsStack); - if (!$form) { - throw new \LogicException('Form declaration is missing, did you use {form} or
tag?'); - } - return $form[$item]; + return is_object($item) + ? $item + : $this->current()[$item]; + } + + + public function begin(Container $form): void + { + $this->stack[] = $form; + } + + + public function end(): void + { + array_pop($this->stack); + } + + + public function current(): Container + { + return end($this->stack) ?: throw new \LogicException('Form declaration is missing, did you use {form} or tag?'); } } diff --git a/src/Bridges/FormsLatte/Runtime2.php b/src/Bridges/FormsLatte/Runtime2.php new file mode 100644 index 000000000..fd6a038e7 --- /dev/null +++ b/src/Bridges/FormsLatte/Runtime2.php @@ -0,0 +1,111 @@ +fireRenderEvents(); + foreach ($form->getControls() as $control) { + $control->setOption('rendered', false); + } + + $el = $form->getElementPrototype(); + $el->action = (string) $el->action; + $el = clone $el; + if ($form->isMethod('get')) { + $el->action = preg_replace('~\?[^#]*~', '', $el->action, 1); + } + + $el->addAttributes($attrs); + return $withTags ? $el->startTag() : $el->attributes(); + } + + + /** + * Renders form end. + */ + public static function renderFormEnd(Form $form, bool $withTags = true): string + { + $s = ''; + if ($form->isMethod('get')) { + foreach (preg_split('#[;&]#', (string) parse_url($form->getElementPrototype()->action, PHP_URL_QUERY), -1, PREG_SPLIT_NO_EMPTY) as $param) { + $parts = explode('=', $param, 2); + $name = urldecode($parts[0]); + $prefix = explode('[', $name, 2)[0]; + if (!isset($form[$prefix])) { + $s .= Html::el('input', ['type' => 'hidden', 'name' => $name, 'value' => urldecode($parts[1])]); + } + } + } + + foreach ($form->getControls() as $control) { + if ($control->getOption('type') === 'hidden' && !$control->getOption('rendered')) { + $s .= $control->getControl(); + } + } + + if (iterator_count($form->getComponents(true, Nette\Forms\Controls\TextInput::class)) < 2) { + $s .= "\n"; + } + + return $s . ($withTags ? $form->getElementPrototype()->endTag() . "\n" : ''); + } + + + /** + * Generates blueprint of form. + */ + public static function renderFormPrint(Form $form): void + { + $blueprint = class_exists(Latte\Runtime\Blueprint::class) + ? new Latte\Runtime\Blueprint + : new Latte\Essential\Blueprint; + $end = $blueprint->printCanvas(); + $blueprint->printHeader('Form ' . $form->getName()); + $blueprint->printCode((new Nette\Forms\Rendering\LatteRenderer)->render($form), 'latte'); + echo $end; + } + + + /** + * Generates blueprint of form data class. + */ + public static function renderFormClassPrint(Form $form): void + { + $blueprint = class_exists(Latte\Runtime\Blueprint::class) + ? new Latte\Runtime\Blueprint + : new Latte\Essential\Blueprint; + $end = $blueprint->printCanvas(); + $blueprint->printHeader('Form Data Class ' . $form->getName()); + $generator = new Nette\Forms\Rendering\DataClassGenerator; + $blueprint->printCode($generator->generateCode($form)); + $generator->propertyPromotion = true; + $blueprint->printCode($generator->generateCode($form)); + + echo $end; + } +} diff --git a/src/Forms/Container.php b/src/Forms/Container.php index d49d8fab1..0d4782b01 100644 --- a/src/Forms/Container.php +++ b/src/Forms/Container.php @@ -11,6 +11,7 @@ use Nette; use Nette\Utils\ArrayHash; +use Stringable; /** @@ -24,25 +25,22 @@ class Container extends Nette\ComponentModel\Container implements \ArrayAccess { use Nette\ComponentModel\ArrayAccess; - private const Array = 'array'; + public const Array = 'array'; /** * Occurs when the form was validated * @var array */ - public $onValidate = []; + public array $onValidate = []; - /** @var ControlGroup|null */ - protected $currentGroup; + protected ?ControlGroup $currentGroup = null; /** @var callable[] extension methods */ - private static $extMethods = []; + private static array $extMethods = []; - /** @var ?bool */ - private $validated = false; + private ?bool $validated = false; - /** @var ?string */ - private $mappedType; + private ?string $mappedType = null; /********************* data exchange ****************d*g**/ @@ -50,10 +48,8 @@ class Container extends Nette\ComponentModel\Container implements \ArrayAccess /** * Fill-in with default values. - * @param array|object $data - * @return static */ - public function setDefaults($data, bool $erase = false) + public function setDefaults(array|object $data, bool $erase = false): static { $form = $this->getForm(false); if (!$form || !$form->isAnchored() || !$form->isSubmitted()) { @@ -66,20 +62,15 @@ public function setDefaults($data, bool $erase = false) /** * Fill-in with values. - * @param array|object $data - * @return static * @internal */ - public function setValues($data, bool $erase = false) + public function setValues(array|object $data, bool $erase = false): static { if ($data instanceof \Traversable) { $values = iterator_to_array($data); } elseif (is_object($data) || is_array($data) || $data === null) { $values = (array) $data; - - } else { - throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array or object, %s given.', gettype($data))); } foreach ($this->getComponents() as $name => $control) { @@ -91,7 +82,7 @@ public function setValues($data, bool $erase = false) $control->setValue(null); } } elseif ($control instanceof self) { - if (array_key_exists($name, $values)) { + if (isset($values[$name])) { $control->setValues($values[$name], $erase); } elseif ($erase) { @@ -106,11 +97,9 @@ public function setValues($data, bool $erase = false) /** * Returns the values submitted by the form. - * @param string|object|null $returnType 'array' for array * @param Control[]|null $controls - * @return object|array */ - public function getValues($returnType = null, ?array $controls = null) + public function getValues(string|object|bool|null $returnType = null, ?array $controls = null): object|array { $form = $this->getForm(false); if ($form && ($submitter = $form->isSubmitted())) { @@ -126,18 +115,20 @@ public function getValues($returnType = null, ?array $controls = null) } } - $returnType = $returnType === true ? self::Array : $returnType; + if ($returnType === true) { + trigger_error(static::class . '::' . __FUNCTION__ . "(true) is deprecated, use getValues('array').", E_USER_DEPRECATED); + $returnType = self::Array; + } + return $this->getUntrustedValues($returnType, $controls); } /** * Returns the potentially unvalidated values submitted by the form. - * @param string|object|null $returnType 'array' for array * @param Control[]|null $controls - * @return object|array */ - public function getUntrustedValues($returnType = ArrayHash::class, ?array $controls = null) + public function getUntrustedValues(string|object|null $returnType, ?array $controls = null): object|array { if (is_object($returnType)) { $obj = $returnType; @@ -185,12 +176,13 @@ public function getUntrustedValues($returnType = ArrayHash::class, ?array $contr /** @eprecated use getUntrustedValues() */ public function getUnsafeValues($returnType, ?array $controls = null) { + trigger_error(__METHOD__ . '() was renamed to getUntrustedValues()', E_USER_DEPRECATED); return $this->getUntrustedValues($returnType, $controls); } /** @return static */ - public function setMappedType(string $type) + public function setMappedType(string $type): static { $this->mappedType = $type; return $this; @@ -263,8 +255,7 @@ public function getErrors(): array /********************* form building ****************d*g**/ - /** @return static */ - public function setCurrentGroup(?ControlGroup $group = null) + public function setCurrentGroup(?ControlGroup $group = null): static { $this->currentGroup = $group; return $this; @@ -282,14 +273,18 @@ public function getCurrentGroup(): ?ControlGroup /** * Adds the specified component to the IContainer. - * @return static * @throws Nette\InvalidStateException */ public function addComponent( Nette\ComponentModel\IComponent $component, ?string $name, - ?string $insertBefore = null - ) { + ?string $insertBefore = null, + ): static + { + if (!$component instanceof Control && !$component instanceof self) { + throw new Nette\InvalidStateException("Component '$name' of type " . get_debug_type($component) . ' is not intended to be used in the form.'); + } + parent::addComponent($component, $name, $insertBefore); if ($this->currentGroup !== null) { $this->currentGroup->add($component); @@ -322,9 +317,13 @@ public function getForm(bool $throw = true): ?Form /** * Adds single-line text input control to the form. - * @param string|object $label */ - public function addText(string $name, $label = null, ?int $cols = null, ?int $maxLength = null): Controls\TextInput + public function addText( + string $name, + string|Stringable|null $label = null, + ?int $cols = null, + ?int $maxLength = null, + ): Controls\TextInput { return $this[$name] = (new Controls\TextInput($label, $maxLength)) ->setHtmlAttribute('size', $cols); @@ -333,13 +332,12 @@ public function addText(string $name, $label = null, ?int $cols = null, ?int $ma /** * Adds single-line text input control used for sensitive input such as passwords. - * @param string|object $label */ public function addPassword( string $name, - $label = null, + string|Stringable|null $label = null, ?int $cols = null, - ?int $maxLength = null + ?int $maxLength = null, ): Controls\TextInput { return $this[$name] = (new Controls\TextInput($label, $maxLength)) @@ -350,9 +348,13 @@ public function addPassword( /** * Adds multi-line text input control to the form. - * @param string|object $label */ - public function addTextArea(string $name, $label = null, ?int $cols = null, ?int $rows = null): Controls\TextArea + public function addTextArea( + string $name, + string|Stringable|null $label = null, + ?int $cols = null, + ?int $rows = null, + ): Controls\TextArea { return $this[$name] = (new Controls\TextArea($label)) ->setHtmlAttribute('cols', $cols)->setHtmlAttribute('rows', $rows); @@ -361,20 +363,19 @@ public function addTextArea(string $name, $label = null, ?int $cols = null, ?int /** * Adds input for email. - * @param string|object $label */ - public function addEmail(string $name, $label = null): Controls\TextInput - { - return $this[$name] = (new Controls\TextInput($label)) - ->addRule(Form::Email); - } + public function addEmail(string $name, $label = null, ?int $cols = null, ?int $maxLength = null): Controls\TextInput + { + return $this[$name] = (new Controls\TextInput($label, $maxLength)) + ->setHtmlAttribute('size', $cols) + ->addRule(Form::Email); + } /** * Adds input for integer. - * @param string|object $label */ - public function addInteger(string $name, $label = null): Controls\TextInput + public function addInteger(string $name, string|Stringable|null $label = null): Controls\TextInput { return $this[$name] = (new Controls\TextInput($label)) ->setNullable() @@ -384,9 +385,8 @@ public function addInteger(string $name, $label = null): Controls\TextInput /** * Adds control that allows the user to upload files. - * @param string|object $label */ - public function addUpload(string $name, $label = null): Controls\UploadControl + public function addUpload(string $name, string|Stringable|null $label = null): Controls\UploadControl { return $this[$name] = new Controls\UploadControl($label, false); } @@ -394,9 +394,8 @@ public function addUpload(string $name, $label = null): Controls\UploadControl /** * Adds control that allows the user to upload multiple files. - * @param string|object $label */ - public function addMultiUpload(string $name, $label = null): Controls\UploadControl + public function addMultiUpload(string $name, string|Stringable|null $label = null): Controls\UploadControl { return $this[$name] = new Controls\UploadControl($label, true); } @@ -414,9 +413,8 @@ public function addHidden(string $name, $default = null): Controls\HiddenField /** * Adds check box control to the form. - * @param string|object $caption */ - public function addCheckbox(string $name, $caption = null): Controls\Checkbox + public function addCheckbox(string $name, string|Stringable|null $caption = null): Controls\Checkbox { return $this[$name] = new Controls\Checkbox($caption); } @@ -424,9 +422,12 @@ public function addCheckbox(string $name, $caption = null): Controls\Checkbox /** * Adds set of radio button controls to the form. - * @param string|object $label */ - public function addRadioList(string $name, $label = null, ?array $items = null): Controls\RadioList + public function addRadioList( + string $name, + string|Stringable|null $label = null, + ?array $items = null, + ): Controls\RadioList { return $this[$name] = new Controls\RadioList($label, $items); } @@ -434,9 +435,12 @@ public function addRadioList(string $name, $label = null, ?array $items = null): /** * Adds set of checkbox controls to the form. - * @param string|object $label */ - public function addCheckboxList(string $name, $label = null, ?array $items = null): Controls\CheckboxList + public function addCheckboxList( + string $name, + string|Stringable|null $label = null, + ?array $items = null, + ): Controls\CheckboxList { return $this[$name] = new Controls\CheckboxList($label, $items); } @@ -444,9 +448,13 @@ public function addCheckboxList(string $name, $label = null, ?array $items = nul /** * Adds select box control that allows single item selection. - * @param string|object $label */ - public function addSelect(string $name, $label = null, ?array $items = null, ?int $size = null): Controls\SelectBox + public function addSelect( + string $name, + string|Stringable|null $label = null, + ?array $items = null, + ?int $size = null, + ): Controls\SelectBox { return $this[$name] = (new Controls\SelectBox($label, $items)) ->setHtmlAttribute('size', $size > 1 ? $size : null); @@ -455,13 +463,12 @@ public function addSelect(string $name, $label = null, ?array $items = null, ?in /** * Adds select box control that allows multiple item selection. - * @param string|object $label */ public function addMultiSelect( string $name, - $label = null, + string|Stringable|null $label = null, ?array $items = null, - ?int $size = null + ?int $size = null, ): Controls\MultiSelectBox { return $this[$name] = (new Controls\MultiSelectBox($label, $items)) @@ -471,9 +478,8 @@ public function addMultiSelect( /** * Adds button used to submit form. - * @param string|object $caption */ - public function addSubmit(string $name, $caption = null): Controls\SubmitButton + public function addSubmit(string $name, string|Stringable|null $caption = null): Controls\SubmitButton { return $this[$name] = new Controls\SubmitButton($caption); } @@ -481,9 +487,8 @@ public function addSubmit(string $name, $caption = null): Controls\SubmitButton /** * Adds push buttons with no default behavior. - * @param string|object $caption */ - public function addButton(string $name, $caption = null): Controls\Button + public function addButton(string $name, string|Stringable|null $caption = null): Controls\Button { return $this[$name] = new Controls\Button($caption); } @@ -491,8 +496,8 @@ public function addButton(string $name, $caption = null): Controls\Button /** * Adds graphical button used to submit form. - * @param string $src URI of the image - * @param string $alt alternate text for the image + * @param string|null $src URI of the image + * @param string|null $alt alternate text for the image */ public function addImageButton(string $name, ?string $src = null, ?string $alt = null): Controls\ImageButton { @@ -503,15 +508,15 @@ public function addImageButton(string $name, ?string $src = null, ?string $alt = /** @deprecated use addImageButton() */ public function addImage(): Controls\ImageButton { + trigger_error(__METHOD__ . '() was renamed to addImageButton()', E_USER_DEPRECATED); return $this->addImageButton(...func_get_args()); } /** * Adds naming container to the form. - * @param string|int $name */ - public function addContainer($name): self + public function addContainer(string|int $name): self { $control = new self; $control->currentGroup = $this->currentGroup; @@ -526,7 +531,7 @@ public function addContainer($name): self /********************* extension methods ****************d*g**/ - public function __call(string $name, array $args) + public function __call(string $name, array $args): mixed { if (isset(self::$extMethods[$name])) { return (self::$extMethods[$name])($this, ...$args); @@ -538,7 +543,7 @@ public function __call(string $name, array $args) public static function extensionMethod(string $name, /*callable*/ $callback): void { - if (strpos($name, '::') !== false) { // back compatibility + if (str_contains($name, '::')) { // back compatibility [, $name] = explode('::', $name); } diff --git a/src/Forms/Control.php b/src/Forms/Control.php index 36d558b5f..101cc3955 100644 --- a/src/Forms/Control.php +++ b/src/Forms/Control.php @@ -12,21 +12,21 @@ /** * Defines method that must be implemented to allow a component to act like a form control. + * @template T */ interface Control { /** * Sets control's value. - * @param mixed $value - * @return static + * @param T|null $value */ - function setValue($value); + function setValue(mixed $value): static; /** * Returns control's value. - * @return mixed + * @return T|null */ - function getValue(); + function getValue(): mixed; function validate(): void; @@ -40,6 +40,3 @@ function getErrors(): array; */ function isOmitted(): bool; } - - -interface_exists(IControl::class); diff --git a/src/Forms/ControlGroup.php b/src/Forms/ControlGroup.php index a8f35c63d..77df5dc64 100644 --- a/src/Forms/ControlGroup.php +++ b/src/Forms/ControlGroup.php @@ -15,15 +15,13 @@ /** * A user group of form controls. */ -class ControlGroup +final class ControlGroup { use Nette\SmartObject; - /** @var \SplObjectStorage */ - protected $controls; + protected \SplObjectStorage $controls; - /** @var array user options */ - private $options = []; + private array $options = []; public function __construct() @@ -32,8 +30,7 @@ public function __construct() } - /** @return static */ - public function add(...$items) + public function add(...$items): static { foreach ($items as $item) { if ($item instanceof Control) { @@ -47,7 +44,7 @@ public function add(...$items) $this->add(...$item); } else { - $type = is_object($item) ? get_class($item) : gettype($item); + $type = get_debug_type($item); throw new Nette\InvalidArgumentException("Control or Container items expected, $type given."); } } @@ -87,10 +84,8 @@ public function getControls(): array * - 'container' - container as Html object * - 'description' - textual or Nette\HtmlStringable object description * - 'embedNext' - describes how render next group - * - * @return static */ - public function setOption(string $key, $value) + public function setOption(string $key, mixed $value): static { if ($value === null) { unset($this->options[$key]); @@ -105,11 +100,11 @@ public function setOption(string $key, $value) /** * Returns user-specific option. - * @return mixed */ - public function getOption(string $key) + public function getOption(string $key): mixed { if (func_num_args() > 1) { + trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', E_USER_DEPRECATED); $default = func_get_arg(1); } return $this->options[$key] ?? $default ?? null; diff --git a/src/Forms/Controls/BaseControl.php b/src/Forms/Controls/BaseControl.php index 2f9de2a27..004f4cb8d 100644 --- a/src/Forms/Controls/BaseControl.php +++ b/src/Forms/Controls/BaseControl.php @@ -14,6 +14,7 @@ use Nette\Forms\Form; use Nette\Forms\Rules; use Nette\Utils\Html; +use Stringable; /** @@ -21,9 +22,9 @@ * * @property-read Form $form * @property-read string $htmlName - * @property mixed $htmlId + * @property string|bool|null $htmlId * @property mixed $value - * @property string|object $caption + * @property string|Stringable $caption * @property bool $disabled * @property bool $omitted * @property-read Html $control @@ -35,50 +36,44 @@ * @property-read array $errors * @property-read array $options * @property-read string $error + * + * @template T + * @implements Control */ abstract class BaseControl extends Nette\ComponentModel\Component implements Control { - /** @var string */ - public static $idMask = 'frm-%s'; + public static string $idMask = 'frm-%s'; - /** @var mixed current control value */ - protected $value; + /** current control value */ + protected mixed $value = null; - /** @var Html control element template */ - protected $control; + /** control element template */ + protected Html $control; - /** @var Html label element template */ - protected $label; + /** label element template */ + protected Html $label; /** @var bool|bool[] */ protected $disabled = false; /** @var callable[][] extension methods */ - private static $extMethods = []; + private static array $extMethods = []; - /** @var string|object textual caption or label */ - private $caption; + private string|Stringable|null $caption; - /** @var array */ - private $errors = []; + private array $errors = []; - /** @var bool|null */ - private $omitted; + private ?bool $omitted = null; - /** @var Rules */ - private $rules; + private Rules $rules; - /** @var Nette\Localization\Translator|bool|null */ - private $translator = true; // means autodetect + /** true means autodetect */ + private Nette\Localization\Translator|bool|null $translator = true; - /** @var array user options */ - private $options = []; + private array $options = []; - /** - * @param string|object $caption - */ - public function __construct($caption = null) + public function __construct(string|Stringable|null $caption = null) { $this->control = Html::el('input', ['type' => null, 'name' => null]); $this->label = Html::el('label'); @@ -95,18 +90,15 @@ public function __construct($caption = null) /** * Sets textual caption or label. - * @param object|string $caption - * @return static */ - public function setCaption($caption) + public function setCaption(string|Stringable $caption): static { $this->caption = $caption; return $this; } - /** @return object|string */ - public function getCaption() + public function getCaption(): string|Stringable|null { return $this->caption; } @@ -132,9 +124,8 @@ public function loadHttpData(): void /** * Loads HTTP data. - * @return mixed */ - protected function getHttpData($type, ?string $htmlTail = null) + protected function getHttpData($type, ?string $htmlTail = null): mixed { return $this->getForm()->getHttpData($type, $this->getHtmlName() . $htmlTail); } @@ -154,10 +145,9 @@ public function getHtmlName(): string /** * Sets control's value. - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { $this->value = $value; return $this; @@ -166,9 +156,8 @@ public function setValue($value) /** * Returns control's value. - * @return mixed */ - public function getValue() + public function getValue(): mixed { return $this->value; } @@ -186,9 +175,8 @@ public function isFilled(): bool /** * Sets control's default value. - * @return static */ - public function setDefaultValue($value) + public function setDefaultValue($value): static { $form = $this->getForm(false); if ($this->isDisabled() || !$form || !$form->isAnchored() || !$form->isSubmitted()) { @@ -201,10 +189,8 @@ public function setDefaultValue($value) /** * Disables or enables control. - * @param bool $value - * @return static */ - public function setDisabled($value = true) + public function setDisabled(bool $value = true): static { if ($this->disabled = (bool) $value) { $this->setValue(null); @@ -227,9 +213,8 @@ public function isDisabled(): bool /** * Sets whether control value is excluded from $form->getValues() result. - * @return static */ - public function setOmitted(bool $value = true) + public function setOmitted(bool $value = true): static { $this->omitted = $value; return $this; @@ -250,9 +235,8 @@ public function isOmitted(): bool /** * Generates control's HTML element. - * @return Html|string */ - public function getControl() + public function getControl(): Html|string { $this->setOption('rendered', true); $el = clone $this->control; @@ -262,20 +246,19 @@ public function getControl() 'required' => $this->isRequired(), 'disabled' => $this->isDisabled(), 'data-nette-rules' => Nette\Forms\Helpers::exportRules($this->rules) ?: null, + 'data-nette-error' => $this->hasErrors(), ]); } /** * Generates label's HTML element. - * @param string|object $caption - * @return Html|string|null */ - public function getLabel($caption = null) + public function getLabel(string|Stringable|null $caption = null): Html|string|null { $label = clone $this->label; $label->for = $this->getHtmlId(); - $caption = $caption ?? $this->caption; + $caption ??= $this->caption; $translator = $this->getForm()->getTranslator(); $label->setText($translator && !$caption instanceof Nette\HtmlStringable ? $translator->translate($caption) : $caption); return $label; @@ -314,10 +297,8 @@ public function getLabelPrototype(): Html /** * Changes control's HTML id. - * @param string|bool|null $id - * @return static */ - public function setHtmlId($id) + public function setHtmlId(string|bool|null $id): static { $this->control->id = $id; return $this; @@ -326,9 +307,8 @@ public function setHtmlId($id) /** * Returns control's HTML id. - * @return mixed */ - public function getHtmlId() + public function getHtmlId(): string|bool|null { if (!isset($this->control->id)) { $form = $this->getForm(); @@ -344,9 +324,8 @@ public function getHtmlId() /** * Changes control's HTML attribute. - * @return static */ - public function setHtmlAttribute(string $name, $value = true) + public function setHtmlAttribute(string $name, mixed $value = true): static { $this->control->$name = $value; if ( @@ -365,9 +344,8 @@ public function setHtmlAttribute(string $name, $value = true) /** * @deprecated use setHtmlAttribute() - * @return static */ - public function setAttribute(string $name, $value = true) + public function setAttribute(string $name, mixed $value = true): static { return $this->setHtmlAttribute($name, $value); } @@ -378,9 +356,8 @@ public function setAttribute(string $name, $value = true) /** * Sets translate adapter. - * @return static */ - public function setTranslator(?Nette\Localization\Translator $translator) + public function setTranslator(?Nette\Localization\Translator $translator): static { $this->translator = $translator; return $this; @@ -404,9 +381,8 @@ public function getTranslator(): ?Nette\Localization\Translator /** * Returns translated string. - * @return mixed */ - public function translate($value, ...$parameters) + public function translate($value, ...$parameters): mixed { if ($translator = $this->getTranslator()) { $tmp = is_array($value) ? [&$value] : [[&$value]]; @@ -426,11 +402,12 @@ public function translate($value, ...$parameters) /** * Adds a validation rule. - * @param callable|string $validator - * @param string|object $errorMessage - * @return static */ - public function addRule($validator, $errorMessage = null, $arg = null) + public function addRule( + callable|string $validator, + string|Stringable|null $errorMessage = null, + mixed $arg = null, + ): static { $this->rules->addRule($validator, $errorMessage, $arg); return $this; @@ -457,9 +434,8 @@ public function addConditionOn(Control $control, $validator, $value = null): Rul /** * Adds a input filter callback. - * @return static */ - public function addFilter(callable $filter) + public function addFilter(callable $filter): static { $this->getRules()->addFilter($filter); return $this; @@ -474,10 +450,8 @@ public function getRules(): Rules /** * Makes control mandatory. - * @param bool|string|object $value - * @return static */ - public function setRequired($value = true) + public function setRequired(string|Stringable|bool $value = true): static { $this->rules->setRequired($value); return $this; @@ -509,9 +483,8 @@ public function validate(): void /** * Adds error message to the list. - * @param string|object $message */ - public function addError($message, bool $translate = true): void + public function addError(string|Stringable $message, bool $translate = true): void { $this->errors[] = $translate ? $this->translate($message) : $message; } @@ -552,9 +525,8 @@ public function cleanErrors(): void /** * Sets user-specific option. - * @return static */ - public function setOption($key, $value) + public function setOption($key, mixed $value): static { if ($value === null) { unset($this->options[$key]); @@ -568,11 +540,11 @@ public function setOption($key, $value) /** * Returns user-specific option. - * @return mixed */ - public function getOption($key) + public function getOption($key): mixed { if (func_num_args() > 1) { + trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', E_USER_DEPRECATED); $default = func_get_arg(1); } return $this->options[$key] ?? $default ?? null; @@ -591,7 +563,7 @@ public function getOptions(): array /********************* extension methods ****************d*g**/ - public function __call(string $name, array $args) + public function __call(string $name, array $args): mixed { $class = static::class; do { @@ -608,7 +580,7 @@ public function __call(string $name, array $args) public static function extensionMethod(string $name, /*callable*/ $callback): void { - if (strpos($name, '::') !== false) { // back compatibility + if (str_contains($name, '::')) { // back compatibility [, $name] = explode('::', $name); } diff --git a/src/Forms/Controls/Button.php b/src/Forms/Controls/Button.php index b4bd98a61..ccb59384d 100644 --- a/src/Forms/Controls/Button.php +++ b/src/Forms/Controls/Button.php @@ -10,17 +10,16 @@ namespace Nette\Forms\Controls; use Nette\Utils\Html; +use Stringable; /** * Push button control with no default behavior. + * @extends BaseControl */ class Button extends BaseControl { - /** - * @param string|object $caption - */ - public function __construct($caption = null) + public function __construct(string|Stringable|null $caption = null) { parent::__construct($caption); $this->control->type = 'button'; @@ -41,14 +40,13 @@ public function isFilled(): bool /** * Bypasses label generation. */ - public function getLabel($caption = null) + public function getLabel($caption = null): Html|string|null { return null; } - /** @return static */ - public function renderAsButton(bool $state = true) + public function renderAsButton(bool $state = true): static { $this->control->setName($state ? 'button' : 'input'); return $this; @@ -57,9 +55,8 @@ public function renderAsButton(bool $state = true) /** * Generates control's HTML element. - * @param string|object $caption */ - public function getControl($caption = null): Html + public function getControl(string|Stringable|null $caption = null): Html { $this->setOption('rendered', true); $caption = $this->translate($caption ?? $this->getCaption()); diff --git a/src/Forms/Controls/Checkbox.php b/src/Forms/Controls/Checkbox.php index 3a3d27cf4..cc21f2d81 100644 --- a/src/Forms/Controls/Checkbox.php +++ b/src/Forms/Controls/Checkbox.php @@ -11,21 +11,20 @@ use Nette; use Nette\Utils\Html; +use Stringable; /** * Check box control. Allows the user to select a true or false condition. + * @extends BaseControl */ class Checkbox extends BaseControl { - /** @var Html wrapper element template */ - private $container; + /** wrapper element template */ + private Html $container; - /** - * @param string|object $label - */ - public function __construct($label = null) + public function __construct(string|Stringable|null $label = null) { parent::__construct($label); $this->control->type = 'checkbox'; @@ -36,13 +35,12 @@ public function __construct($label = null) /** * Sets control's value. - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { if (!is_scalar($value) && $value !== null) { - throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", gettype($value), $this->name)); + throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", get_debug_type($value), $this->name)); } $this->value = (bool) $value; @@ -65,7 +63,7 @@ public function getControl(): Html /** * Bypasses label generation. */ - public function getLabel($caption = null) + public function getLabel($caption = null): Html|string|null { return null; } @@ -95,6 +93,7 @@ public function getContainerPrototype(): Html /** @deprecated use getContainerPrototype() */ public function getSeparatorPrototype(): Html { + trigger_error(__METHOD__ . '() was renamed to getContainerPrototype()', E_USER_DEPRECATED); return $this->container; } } diff --git a/src/Forms/Controls/CheckboxList.php b/src/Forms/Controls/CheckboxList.php index eadb7a69c..f30418a9a 100644 --- a/src/Forms/Controls/CheckboxList.php +++ b/src/Forms/Controls/CheckboxList.php @@ -11,6 +11,7 @@ use Nette; use Nette\Utils\Html; +use Stringable; /** @@ -22,20 +23,17 @@ */ class CheckboxList extends MultiChoiceControl { - /** @var Html separator element template */ - protected $separator; + /** separator element template */ + protected Html $separator; - /** @var Html container element template */ - protected $container; + /** container element template */ + protected Html $container; - /** @var Html item label template */ - protected $itemLabel; + /** item label template */ + protected Html $itemLabel; - /** - * @param string|object $label - */ - public function __construct($label = null, ?array $items = null) + public function __construct(string|Stringable|null $label = null, ?array $items = null) { parent::__construct($label, $items); $this->control->type = 'checkbox'; @@ -76,8 +74,8 @@ public function getControl(): Html 'data-nette-rules:' => [key($items) => $input->attrs['data-nette-rules']], ]), $this->itemLabel->attrs, - $this->separator - ) + $this->separator, + ), ); } diff --git a/src/Forms/Controls/ChoiceControl.php b/src/Forms/Controls/ChoiceControl.php index 6b17c4cdc..658abb129 100644 --- a/src/Forms/Controls/ChoiceControl.php +++ b/src/Forms/Controls/ChoiceControl.php @@ -17,14 +17,14 @@ * * @property array $items * @property-read mixed $selectedItem + * + * @extends BaseControl */ abstract class ChoiceControl extends BaseControl { - /** @var bool */ - private $checkDefaultValue = true; + private bool $checkDefaultValue = true; - /** @var array */ - private $items = []; + private array $items = []; public function __construct($label = null, ?array $items = null) @@ -50,17 +50,20 @@ public function loadHttpData(): void /** * Sets selected item (by key). * @param string|int|\BackedEnum|null $value - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { if ($value instanceof \BackedEnum) { $value = $value->value; } if ($this->checkDefaultValue && $value !== null && !array_key_exists((string) $value, $this->items)) { - $set = Nette\Utils\Strings::truncate(implode(', ', array_map(function ($s) { return var_export($s, true); }, array_keys($this->items))), 70, '...'); + $set = Nette\Utils\Strings::truncate( + implode(', ', array_map(fn($s) => var_export($s, true), array_keys($this->items))), + 70, + '...', + ); throw new Nette\InvalidArgumentException("Value '$value' is out of allowed set [$set] in field '{$this->name}'."); } @@ -71,9 +74,8 @@ public function setValue($value) /** * Returns selected key. - * @return string|int|null */ - public function getValue() + public function getValue(): mixed { return array_key_exists($this->value, $this->items) ? $this->value @@ -83,9 +85,8 @@ public function getValue() /** * Returns selected key (not checked). - * @return string|int */ - public function getRawValue() + public function getRawValue(): string|int { return $this->value; } @@ -102,9 +103,8 @@ public function isFilled(): bool /** * Sets items from which to choose. - * @return static */ - public function setItems(array $items, bool $useKeys = true) + public function setItems(array $items, bool $useKeys = true): static { $this->items = $useKeys ? $items : array_combine($items, $items); return $this; @@ -122,9 +122,8 @@ public function getItems(): array /** * Returns selected value. - * @return mixed */ - public function getSelectedItem() + public function getSelectedItem(): mixed { $value = $this->getValue(); return $value === null ? null : $this->items[$value]; @@ -133,10 +132,8 @@ public function getSelectedItem() /** * Disables or enables control or items. - * @param bool|array $value - * @return static */ - public function setDisabled($value = true) + public function setDisabled(bool|array $value = true): static { if (!is_array($value)) { return parent::setDisabled($value); @@ -152,8 +149,7 @@ public function setDisabled($value = true) } - /** @return static */ - public function checkDefaultValue(bool $value = true) + public function checkDefaultValue(bool $value = true): static { $this->checkDefaultValue = $value; return $this; diff --git a/src/Forms/Controls/CsrfProtection.php b/src/Forms/Controls/CsrfProtection.php index 70aef3ca4..fd636cfe7 100644 --- a/src/Forms/Controls/CsrfProtection.php +++ b/src/Forms/Controls/CsrfProtection.php @@ -11,24 +11,24 @@ use Nette; use Nette\Application\UI\Presenter; +use Stringable; /** * CSRF protection field. + * @extends BaseControl */ class CsrfProtection extends HiddenField { public const Protection = 'Nette\Forms\Controls\CsrfProtection::validateCsrf'; + + /** @deprecated use CsrfProtection::Protection */ public const PROTECTION = self::Protection; - /** @var Nette\Http\Session|null */ - public $session; + public ?Nette\Http\Session $session = null; - /** - * @param string|object $errorMessage - */ - public function __construct($errorMessage) + public function __construct(string|Stringable|null $errorMessage = null) { parent::__construct(); $this->setOmitted() @@ -52,10 +52,9 @@ public function __construct($errorMessage) /** - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { return $this; } @@ -74,11 +73,11 @@ public function getToken(): string } $session = $this->session->getSection(self::class); - if (!isset($session->token)) { - $session->token = Nette\Utils\Random::generate(); + if (!$session->get('token')) { + $session->set('token', Nette\Utils\Random::generate()); } - return $session->token ^ $this->session->getId(); + return $session->get('token') ^ $this->session->getId(); } diff --git a/src/Forms/Controls/HiddenField.php b/src/Forms/Controls/HiddenField.php index 93b22b979..44ccafa7a 100644 --- a/src/Forms/Controls/HiddenField.php +++ b/src/Forms/Controls/HiddenField.php @@ -10,18 +10,19 @@ namespace Nette\Forms\Controls; use Nette; +use Nette\Utils\Html; +use Stringable; /** * Hidden form control used to store a non-displayed value. + * @extends BaseControl */ class HiddenField extends BaseControl { - /** @var bool */ - private $persistValue; + private bool $persistValue = false; - /** @var bool */ - private $nullable = false; + private bool $nullable = false; public function __construct($persistentValue = null) @@ -29,6 +30,7 @@ public function __construct($persistentValue = null) parent::__construct(); $this->control->type = 'hidden'; $this->setOption('type', 'hidden'); + $this->value = ''; if ($persistentValue !== null) { $this->unmonitor(Nette\Forms\Form::class); $this->persistValue = true; @@ -39,17 +41,16 @@ public function __construct($persistentValue = null) /** * Sets control's value. - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { if ($value === null) { $value = ''; } elseif ($value instanceof \BackedEnum) { $value = $value->value; - } elseif (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) { - throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", gettype($value), $this->name)); + } elseif (!is_scalar($value) && !$value instanceof Stringable) { + throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", get_debug_type($value), $this->name)); } if (!$this->persistValue) { @@ -60,7 +61,7 @@ public function setValue($value) } - public function getValue() + public function getValue(): mixed { return $this->nullable && $this->value === '' ? null : $this->value; } @@ -68,16 +69,15 @@ public function getValue() /** * Sets whether getValue() returns null instead of empty string. - * @return static */ - public function setNullable(bool $value = true) + public function setNullable(bool $value = true): static { $this->nullable = $value; return $this; } - public function getControl(): Nette\Utils\Html + public function getControl(): Html { $this->setOption('rendered', true); $el = clone $this->control; @@ -92,7 +92,7 @@ public function getControl(): Nette\Utils\Html /** * Bypasses label generation. */ - public function getLabel($caption = null) + public function getLabel($caption = null): Html|string|null { return null; } @@ -100,9 +100,8 @@ public function getLabel($caption = null) /** * Adds error message to the list. - * @param string|object $message */ - public function addError($message, bool $translate = true): void + public function addError(string|Stringable $message, bool $translate = true): void { $this->getForm()->addError($message, $translate); } diff --git a/src/Forms/Controls/ImageButton.php b/src/Forms/Controls/ImageButton.php index 035fcbe0b..9711a1860 100644 --- a/src/Forms/Controls/ImageButton.php +++ b/src/Forms/Controls/ImageButton.php @@ -12,6 +12,7 @@ /** * Submittable image button form control. + * @method array|null getValue() */ class ImageButton extends SubmitButton { diff --git a/src/Forms/Controls/MultiChoiceControl.php b/src/Forms/Controls/MultiChoiceControl.php index 7c8bbddda..fed4c5015 100644 --- a/src/Forms/Controls/MultiChoiceControl.php +++ b/src/Forms/Controls/MultiChoiceControl.php @@ -17,14 +17,14 @@ * * @property array $items * @property-read array $selectedItems + * + * @extends BaseControl */ abstract class MultiChoiceControl extends BaseControl { - /** @var bool */ - private $checkDefaultValue = true; + private bool $checkDefaultValue = true; - /** @var array */ - private $items = []; + private array $items = []; public function __construct($label = null, ?array $items = null) @@ -47,23 +47,22 @@ public function loadHttpData(): void /** * Sets selected items (by keys). - * @return static * @internal */ - public function setValue($values) + public function setValue($values): static { if (is_scalar($values) || $values === null) { $values = (array) $values; } elseif (!is_array($values)) { - throw new Nette\InvalidArgumentException(sprintf("Value must be array or null, %s given in field '%s'.", gettype($values), $this->name)); + throw new Nette\InvalidArgumentException(sprintf("Value must be array or null, %s given in field '%s'.", get_debug_type($values), $this->name)); } $flip = []; foreach ($values as $value) { if ($value instanceof \BackedEnum) { $value = $value->value; - } elseif (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) { - throw new Nette\InvalidArgumentException(sprintf("Values must be scalar, %s given in field '%s'.", gettype($value), $this->name)); + } elseif (!is_scalar($value) && !$value instanceof \Stringable) { + throw new Nette\InvalidArgumentException(sprintf("Values must be scalar, %s given in field '%s'.", get_debug_type($value), $this->name)); } $flip[(string) $value] = true; @@ -71,7 +70,11 @@ public function setValue($values) $values = array_keys($flip); if ($this->checkDefaultValue && ($diff = array_diff($values, array_keys($this->items)))) { - $set = Nette\Utils\Strings::truncate(implode(', ', array_map(function ($s) { return var_export($s, true); }, array_keys($this->items))), 70, '...'); + $set = Nette\Utils\Strings::truncate( + implode(', ', array_map(fn($s) => var_export($s, true), array_keys($this->items))), + 70, + '...', + ); $vals = (count($diff) > 1 ? 's' : '') . " '" . implode("', '", $diff) . "'"; throw new Nette\InvalidArgumentException("Value$vals are out of allowed set [$set] in field '{$this->name}'."); } @@ -83,6 +86,7 @@ public function setValue($values) /** * Returns selected keys. + * @return array-key[] */ public function getValue(): array { @@ -110,9 +114,8 @@ public function isFilled(): bool /** * Sets items from which to choose. - * @return static */ - public function setItems(array $items, bool $useKeys = true) + public function setItems(array $items, bool $useKeys = true): static { $this->items = $useKeys ? $items : array_combine($items, $items); return $this; @@ -139,10 +142,8 @@ public function getSelectedItems(): array /** * Disables or enables control or items. - * @param bool|array $value - * @return static */ - public function setDisabled($value = true) + public function setDisabled(bool|array $value = true): static { if (!is_array($value)) { return parent::setDisabled($value); @@ -164,8 +165,7 @@ public function getHtmlName(): string } - /** @return static */ - public function checkDefaultValue(bool $value = true) + public function checkDefaultValue(bool $value = true): static { $this->checkDefaultValue = $value; return $this; diff --git a/src/Forms/Controls/MultiSelectBox.php b/src/Forms/Controls/MultiSelectBox.php index c154de1f4..57b6df6fb 100644 --- a/src/Forms/Controls/MultiSelectBox.php +++ b/src/Forms/Controls/MultiSelectBox.php @@ -17,11 +17,10 @@ */ class MultiSelectBox extends MultiChoiceControl { - /** @var array of option / optgroup */ - private $options = []; + /** of option / optgroup */ + private array $options = []; - /** @var array */ - private $optionAttributes = []; + private array $optionAttributes = []; public function __construct($label = null, ?array $items = null) @@ -33,9 +32,8 @@ public function __construct($label = null, ?array $items = null) /** * Sets options and option groups from which to choose. - * @return static */ - public function setItems(array $items, bool $useKeys = true) + public function setItems(array $items, bool $useKeys = true): static { if (!$useKeys) { $res = []; @@ -70,21 +68,19 @@ public function getControl(): Nette\Utils\Html [ 'disabled:' => is_array($this->disabled) ? $this->disabled : null, ] + $this->optionAttributes, - $this->value + $this->value, )->addAttributes(parent::getControl()->attrs)->multiple(true); } - /** @return static */ - public function addOptionAttributes(array $attributes) + public function addOptionAttributes(array $attributes): static { $this->optionAttributes = $attributes + $this->optionAttributes; return $this; } - /** @return static */ - public function setOptionAttribute(string $name, $value = true) + public function setOptionAttribute(string $name, mixed $value = true): static { $this->optionAttributes[$name] = $value; return $this; diff --git a/src/Forms/Controls/RadioList.php b/src/Forms/Controls/RadioList.php index 5a9282b0b..30be211b1 100644 --- a/src/Forms/Controls/RadioList.php +++ b/src/Forms/Controls/RadioList.php @@ -11,6 +11,7 @@ use Nette; use Nette\Utils\Html; +use Stringable; /** @@ -22,23 +23,19 @@ */ class RadioList extends ChoiceControl { - /** @var bool */ - public $generateId = false; + public bool $generateId = false; - /** @var Html separator element template */ - protected $separator; + /** separator element template */ + protected Html $separator; - /** @var Html container element template */ - protected $container; + /** container element template */ + protected Html $container; - /** @var Html item label template */ - protected $itemLabel; + /** item label template */ + protected Html $itemLabel; - /** - * @param string|object $label - */ - public function __construct($label = null, ?array $items = null) + public function __construct(string|Stringable|null $label = null, ?array $items = null) { parent::__construct($label, $items); $this->control->type = 'radio'; @@ -70,8 +67,8 @@ public function getControl(): Html 'data-nette-rules:' => [key($items) => $input->attrs['data-nette-rules']], ]), ['for:' => $ids] + $this->itemLabel->attrs, - $this->separator - ) + $this->separator, + ), ); } diff --git a/src/Forms/Controls/SelectBox.php b/src/Forms/Controls/SelectBox.php index b935d065d..a561af749 100644 --- a/src/Forms/Controls/SelectBox.php +++ b/src/Forms/Controls/SelectBox.php @@ -10,6 +10,7 @@ namespace Nette\Forms\Controls; use Nette; +use Stringable; /** @@ -19,36 +20,34 @@ class SelectBox extends ChoiceControl { /** validation rule */ public const Valid = ':selectBoxValid'; + + /** @deprecated use SelectBox::Valid */ public const VALID = self::Valid; - /** @var array of option / optgroup */ - private $options = []; + /** of option / optgroup */ + private array $options = []; - /** @var string|object|false */ - private $prompt = false; + private string|Stringable|false $prompt = false; - /** @var array */ - private $optionAttributes = []; + private array $optionAttributes = []; public function __construct($label = null, ?array $items = null) { parent::__construct($label, $items); $this->setOption('type', 'select'); - $this->addCondition(function () { - return $this->prompt === false - && $this->options - && $this->control->size < 2; - })->addRule(Nette\Forms\Form::Filled, Nette\Forms\Validator::$messages[self::Valid]); + $this->addCondition( + fn() => $this->prompt === false + && $this->options + && $this->control->size < 2, + )->addRule(Nette\Forms\Form::Filled, Nette\Forms\Validator::$messages[self::Valid]); } /** * Sets first prompt item in select box. - * @param string|object|false $prompt - * @return static */ - public function setPrompt($prompt) + public function setPrompt(string|Stringable|false $prompt): static { $this->prompt = $prompt; return $this; @@ -57,9 +56,8 @@ public function setPrompt($prompt) /** * Returns first prompt item? - * @return string|object|false */ - public function getPrompt() + public function getPrompt(): string|Stringable|false { return $this->prompt; } @@ -67,9 +65,8 @@ public function getPrompt() /** * Sets options and option groups from which to choose. - * @return static */ - public function setItems(array $items, bool $useKeys = true) + public function setItems(array $items, bool $useKeys = true): static { if (!$useKeys) { $res = []; @@ -104,21 +101,19 @@ public function getControl(): Nette\Utils\Html [ 'disabled:' => is_array($this->disabled) ? $this->disabled : null, ] + $this->optionAttributes, - $this->value + $this->value, )->addAttributes(parent::getControl()->attrs); } - /** @return static */ - public function addOptionAttributes(array $attributes) + public function addOptionAttributes(array $attributes): static { $this->optionAttributes = $attributes + $this->optionAttributes; return $this; } - /** @return static */ - public function setOptionAttribute(string $name, $value = true) + public function setOptionAttribute(string $name, mixed $value = true): static { $this->optionAttributes[$name] = $value; return $this; diff --git a/src/Forms/Controls/SubmitButton.php b/src/Forms/Controls/SubmitButton.php index 2ed47caad..646fb0d2e 100644 --- a/src/Forms/Controls/SubmitButton.php +++ b/src/Forms/Controls/SubmitButton.php @@ -10,6 +10,7 @@ namespace Nette\Forms\Controls; use Nette; +use Stringable; /** @@ -23,19 +24,15 @@ class SubmitButton extends Button implements Nette\Forms\SubmitterControl * Occurs when the button is clicked and form is successfully validated * @var array */ - public $onClick = []; + public array $onClick = []; /** @var array Occurs when the button is clicked and form is not validated */ - public $onInvalidClick = []; + public array $onInvalidClick = []; - /** @var array|null */ - private $validationScope; + private ?array $validationScope = null; - /** - * @param string|object $caption - */ - public function __construct($caption = null) + public function __construct(string|Stringable|null $caption = null) { parent::__construct($caption); $this->control->type = 'submit'; @@ -63,9 +60,8 @@ public function isSubmittedBy(): bool /** * Sets the validation scope. Clicking the button validates only the controls within the specified scope. - * @return static */ - public function setValidationScope(?iterable $scope) + public function setValidationScope(?iterable $scope): static { if ($scope === null) { $this->validationScope = null; diff --git a/src/Forms/Controls/TextArea.php b/src/Forms/Controls/TextArea.php index 160607a60..80dddb7f8 100644 --- a/src/Forms/Controls/TextArea.php +++ b/src/Forms/Controls/TextArea.php @@ -10,6 +10,7 @@ namespace Nette\Forms\Controls; use Nette; +use Stringable; /** @@ -17,10 +18,7 @@ */ class TextArea extends TextBase { - /** - * @param string|object $label - */ - public function __construct($label = null) + public function __construct(string|Stringable|null $label = null) { parent::__construct($label); $this->control->setName('textarea'); diff --git a/src/Forms/Controls/TextBase.php b/src/Forms/Controls/TextBase.php index 5a4cea98c..57d15317c 100644 --- a/src/Forms/Controls/TextBase.php +++ b/src/Forms/Controls/TextBase.php @@ -12,34 +12,33 @@ use Nette; use Nette\Forms\Form; use Nette\Utils\Strings; +use Stringable; /** * Implements the basic functionality common to text input controls. + * @extends BaseControl */ abstract class TextBase extends BaseControl { - /** @var string */ - protected $emptyValue = ''; + protected string $emptyValue = ''; - /** @var mixed unfiltered submitted value */ - protected $rawValue = ''; + /** unfiltered submitted value */ + protected mixed $rawValue = ''; - /** @var bool */ - private $nullable; + private bool $nullable = false; /** * Sets control's value. - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { if ($value === null) { $value = ''; - } elseif (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) { - throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", gettype($value), $this->name)); + } elseif (!is_scalar($value) && !$value instanceof Stringable) { + throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or null, %s given in field '%s'.", get_debug_type($value), $this->name)); } $this->value = $value; @@ -50,9 +49,8 @@ public function setValue($value) /** * Returns control's value. - * @return mixed */ - public function getValue() + public function getValue(): mixed { $value = $this->value === Strings::trim($this->translate($this->emptyValue)) ? '' @@ -63,9 +61,8 @@ public function getValue() /** * Sets whether getValue() returns null instead of empty string. - * @return static */ - public function setNullable(bool $value = true) + public function setNullable(bool $value = true): static { $this->nullable = $value; return $this; @@ -74,9 +71,8 @@ public function setNullable(bool $value = true) /** * Sets the special value which is treated as empty string. - * @return static */ - public function setEmptyValue(string $value) + public function setEmptyValue(string $value): static { $this->emptyValue = $value; return $this; @@ -94,9 +90,8 @@ public function getEmptyValue(): string /** * Sets the maximum number of allowed characters. - * @return static */ - public function setMaxLength(int $length) + public function setMaxLength(int $length): static { $this->control->maxlength = $length; return $this; @@ -126,8 +121,11 @@ protected function getRenderedValue(): ?string } - /** @return static */ - public function addRule($validator, $errorMessage = null, $arg = null) + public function addRule( + callable|string $validator, + string|Stringable|null $errorMessage = null, + mixed $arg = null, + ): static { foreach ($this->getRules() as $rule) { if (!$rule->canExport() && !$rule->branch) { diff --git a/src/Forms/Controls/TextInput.php b/src/Forms/Controls/TextInput.php index 3048ada29..b592d48c5 100644 --- a/src/Forms/Controls/TextInput.php +++ b/src/Forms/Controls/TextInput.php @@ -11,6 +11,7 @@ use Nette; use Nette\Forms\Form; +use Stringable; /** @@ -18,10 +19,7 @@ */ class TextInput extends TextBase { - /** - * @param string|object $label - */ - public function __construct($label = null, ?int $maxLength = null) + public function __construct(string|Stringable|null $label = null, ?int $maxLength = null) { parent::__construct($label); $this->control->maxlength = $maxLength; @@ -37,9 +35,8 @@ public function loadHttpData(): void /** * Changes control's type attribute. - * @return static */ - public function setHtmlType(string $type) + public function setHtmlType(string $type): static { $this->control->type = $type; return $this; @@ -48,9 +45,8 @@ public function setHtmlType(string $type) /** * @deprecated use setHtmlType() - * @return static */ - public function setType(string $type) + public function setType(string $type): static { return $this->setHtmlType($type); } @@ -65,8 +61,11 @@ public function getControl(): Nette\Utils\Html } - /** @return static */ - public function addRule($validator, $errorMessage = null, $arg = null) + public function addRule( + callable|string $validator, + string|Stringable|null $errorMessage = null, + mixed $arg = null, + ): static { foreach ($this->getRules() as $rule) { if (!$rule->canExport() && !$rule->branch) { diff --git a/src/Forms/Controls/UploadControl.php b/src/Forms/Controls/UploadControl.php index 84ce5afd2..28b4539c8 100644 --- a/src/Forms/Controls/UploadControl.php +++ b/src/Forms/Controls/UploadControl.php @@ -14,22 +14,23 @@ use Nette\Forms\Form; use Nette\Http\FileUpload; use Nette\Utils\Arrays; +use Stringable; /** * Text box and browse button that allow users to select a file to upload to the server. + * @extends BaseControl */ class UploadControl extends BaseControl { /** validation rule */ public const Valid = ':uploadControlValid'; + + /** @deprecated use UploadControl::Valid */ public const VALID = self::Valid; - /** - * @param string|object $label - */ - public function __construct($label = null, bool $multiple = false) + public function __construct(string|Stringable|null $label = null, bool $multiple = false) { parent::__construct($label); $this->control->type = 'file'; @@ -39,7 +40,7 @@ public function __construct($label = null, bool $multiple = false) ->addRule([$this, 'isOk'], Forms\Validator::$messages[self::Valid]); $this->addRule(Form::MaxFileSize, null, Forms\Helpers::iniGetSize('upload_max_filesize')); if ($multiple) { - $this->addRule(Form::MaxLength, 'The maximum allowed number of uploaded files is %i', (int) ini_get('max_file_uploads')); + $this->addRule(Form::MaxLength, 'The maximum allowed number of uploaded files is %d', (int) ini_get('max_file_uploads')); } $this->monitor(Form::class, function (Form $form): void { @@ -68,10 +69,9 @@ public function getHtmlName(): string /** - * @return static * @internal */ - public function setValue($value) + public function setValue($value): static { return $this; } @@ -95,17 +95,18 @@ public function isOk(): bool { return $this->value instanceof FileUpload ? $this->value->isOk() - : $this->value && Arrays::every($this->value, function (FileUpload $upload): bool { - return $upload->isOk(); - }); + : $this->value && Arrays::every($this->value, fn(FileUpload $upload): bool => $upload->isOk()); } - /** @return static */ - public function addRule($validator, $errorMessage = null, $arg = null) + public function addRule( + callable|string $validator, + string|Stringable|null $errorMessage = null, + mixed $arg = null, + ): static { if ($validator === Form::Image) { - $this->control->accept = implode(', ', FileUpload::IMAGE_MIME_TYPES); + $this->control->accept = implode(', ', FileUpload::ImageMimeTypes); } elseif ($validator === Form::MimeType) { $this->control->accept = implode(', ', (array) $arg); diff --git a/src/Forms/Form.php b/src/Forms/Form.php index 4299b91db..cae801dcd 100644 --- a/src/Forms/Form.php +++ b/src/Forms/Form.php @@ -12,6 +12,7 @@ use Nette; use Nette\Utils\Arrays; use Nette\Utils\Html; +use Stringable; /** @@ -82,88 +83,147 @@ class Form extends Container implements Nette\HtmlStringable /** @internal protection token ID */ public const ProtectorId = '_token_'; + /** @deprecated use Form::Equal */ public const EQUAL = self::Equal; + + /** @deprecated use Form::IsIn */ public const IS_IN = self::IsIn; + + /** @deprecated use Form::NotEqual */ public const NOT_EQUAL = self::NotEqual; + + /** @deprecated use Form::IsNotIn */ public const IS_NOT_IN = self::IsNotIn; + + /** @deprecated use Form::Filled */ public const FILLED = self::Filled; + + /** @deprecated use Form::Blank */ public const BLANK = self::Blank; + + /** @deprecated use Form::Required */ public const REQUIRED = self::Required; + + /** @deprecated use Form::Valid */ public const VALID = self::Valid; + + /** @deprecated use Form::Submitted */ public const SUBMITTED = self::Submitted; + + /** @deprecated use Form::MinLength */ public const MIN_LENGTH = self::MinLength; + + /** @deprecated use Form::MaxLength */ public const MAX_LENGTH = self::MaxLength; + + /** @deprecated use Form::Length */ public const LENGTH = self::Length; + + /** @deprecated use Form::Email */ public const EMAIL = self::Email; + + /** @deprecated use Form::Pattern */ public const PATTERN = self::Pattern; + + /** @deprecated use Form::PatternCI */ public const PATTERN_ICASE = self::PatternInsensitive; + + /** @deprecated use Form::Integer */ public const INTEGER = self::Integer; + + /** @deprecated use Form::Numeric */ public const NUMERIC = self::Numeric; + + /** @deprecated use Form::Float */ public const FLOAT = self::Float; + + /** @deprecated use Form::Min */ public const MIN = self::Min; + + /** @deprecated use Form::Max */ public const MAX = self::Max; + + /** @deprecated use Form::Range */ public const RANGE = self::Range; + + /** @deprecated use Form::Count */ public const COUNT = self::Count; + + /** @deprecated use Form::MaxFileSize */ public const MAX_FILE_SIZE = self::MaxFileSize; + + /** @deprecated use Form::MimeType */ public const MIME_TYPE = self::MimeType; + + /** @deprecated use Form::Image */ public const IMAGE = self::Image; + + /** @deprecated use Form::MaxPostSize */ public const MAX_POST_SIZE = self::MaxPostSize; + + /** @deprecated use Form::Get */ public const GET = self::Get; + + /** @deprecated use Form::Post */ public const POST = self::Post; + + /** @deprecated use Form::DataText */ public const DATA_TEXT = self::DataText; + + /** @deprecated use Form::DataLine */ public const DATA_LINE = self::DataLine; + + /** @deprecated use Form::DataFile */ public const DATA_FILE = self::DataFile; + + /** @deprecated use Form::DataKeys */ public const DATA_KEYS = self::DataKeys; + + /** @deprecated use Form::TrackerId */ public const TRACKER_ID = self::TrackerId; + + /** @deprecated use Form::ProtectorId */ public const PROTECTOR_ID = self::ProtectorId; /** * Occurs when the form is submitted and successfully validated * @var array */ - public $onSuccess = []; + public array $onSuccess = []; /** @var array Occurs when the form is submitted and is not valid */ - public $onError = []; + public array $onError = []; /** @var array Occurs when the form is submitted */ - public $onSubmit = []; + public array $onSubmit = []; /** @var array Occurs before the form is rendered */ - public $onRender = []; + public array $onRender = []; - /** @internal @var Nette\Http\IRequest used only by standalone form */ - public $httpRequest; + /** @internal used only by standalone form */ + public Nette\Http\IRequest $httpRequest; - /** @var bool */ - protected $crossOrigin = false; + protected bool $crossOrigin = false; - /** @var Nette\Http\IRequest */ - private static $defaultHttpRequest; + private static ?Nette\Http\IRequest $defaultHttpRequest = null; - /** @var SubmitterControl|bool */ - private $submittedBy; + private SubmitterControl|bool $submittedBy; - /** @var array|null */ - private $httpData; + private array $httpData; - /** @var Html element */ - private $element; + /** element */ + private Html $element; - /** @var FormRenderer */ - private $renderer; + private FormRenderer $renderer; - /** @var Nette\Localization\Translator */ - private $translator; + private ?Nette\Localization\Translator $translator = null; /** @var ControlGroup[] */ - private $groups = []; + private array $groups = []; - /** @var array */ - private $errors = []; + private array $errors = []; - /** @var bool */ - private $beforeRenderCalled; + private bool $beforeRenderCalled = false; public function __construct(?string $name = null) @@ -184,9 +244,8 @@ public function __construct(?string $name = null) /** * Returns self. - * @return static */ - public function getForm(bool $throw = true): self + public function getForm(bool $throw = true): static { return $this; } @@ -194,10 +253,8 @@ public function getForm(bool $throw = true): self /** * Sets form's action. - * @param string|object $url - * @return static */ - public function setAction($url) + public function setAction(string|Stringable $url): static { $this->getElementPrototype()->action = $url; return $this; @@ -206,9 +263,8 @@ public function setAction($url) /** * Returns form's action. - * @return mixed */ - public function getAction() + public function getAction(): mixed { return $this->getElementPrototype()->action; } @@ -216,11 +272,10 @@ public function getAction() /** * Sets form's method GET or POST. - * @return static */ - public function setMethod(string $method) + public function setMethod(string $method): static { - if ($this->httpData !== null) { + if (isset($this->httpData)) { throw new Nette\InvalidStateException(__METHOD__ . '() must be called until the form is empty.'); } @@ -249,9 +304,8 @@ public function isMethod(string $method): bool /** * Changes forms's HTML attribute. - * @return static */ - public function setHtmlAttribute(string $name, $value = true) + public function setHtmlAttribute(string $name, mixed $value = true): static { $this->getElementPrototype()->$name = $value; return $this; @@ -274,7 +328,7 @@ public function addProtection(?string $errorMessage = null): Controls\CsrfProtec { $control = new Controls\CsrfProtection($errorMessage); $children = (array) $this->getComponents(); - $first = $children ? (string) key($children) : null; + $first = $children ? (string) array_key_first($children) : null; $this->addComponent($control, self::ProtectorId, $first); return $control; } @@ -282,9 +336,8 @@ public function addProtection(?string $errorMessage = null): Controls\CsrfProtec /** * Adds fieldset group to the form. - * @param string|object $caption */ - public function addGroup($caption = null, bool $setAsCurrent = true): ControlGroup + public function addGroup(string|Stringable|null $caption = null, bool $setAsCurrent = true): ControlGroup { $group = new ControlGroup; $group->setOption('label', $caption); @@ -302,9 +355,8 @@ public function addGroup($caption = null, bool $setAsCurrent = true): ControlGro /** * Removes fieldset group from form. - * @param string|ControlGroup $name */ - public function removeGroup($name): void + public function removeGroup(string|ControlGroup $name): void { if (is_string($name) && isset($this->groups[$name])) { $group = $this->groups[$name]; @@ -337,9 +389,8 @@ public function getGroups(): array /** * Returns the specified group. - * @param string|int $name */ - public function getGroup($name): ?ControlGroup + public function getGroup(string|int $name): ?ControlGroup { return $this->groups[$name] ?? null; } @@ -350,9 +401,8 @@ public function getGroup($name): ?ControlGroup /** * Sets translate adapter. - * @return static */ - public function setTranslator(?Nette\Localization\Translator $translator) + public function setTranslator(?Nette\Localization\Translator $translator): static { $this->translator = $translator; return $this; @@ -382,11 +432,10 @@ public function isAnchored(): bool /** * Tells if the form was submitted. - * @return SubmitterControl|bool submittor control */ - public function isSubmitted() + public function isSubmitted(): SubmitterControl|bool { - if ($this->httpData === null) { + if (!isset($this->httpData)) { $this->getHttpData(); } @@ -405,10 +454,9 @@ public function isSuccess(): bool /** * Sets the submittor control. - * @return static * @internal */ - public function setSubmittedBy(?SubmitterControl $by) + public function setSubmittedBy(?SubmitterControl $by): static { $this->submittedBy = $by ?? false; return $this; @@ -417,11 +465,10 @@ public function setSubmittedBy(?SubmitterControl $by) /** * Returns submitted HTTP data. - * @return mixed */ - public function getHttpData(?int $type = null, ?string $htmlName = null) + public function getHttpData(?int $type = null, ?string $htmlName = null): mixed { - if ($this->httpData === null) { + if (!isset($this->httpData)) { if (!$this->isAnchored()) { throw new Nette\InvalidStateException('Form is not anchored and therefore can not determine whether it was submitted.'); } @@ -505,9 +552,8 @@ private function invokeHandlers(iterable $handlers, $button = null): void /** * Resets form. - * @return static */ - public function reset() + public function reset(): static { $this->setSubmittedBy(null); $this->setValues([], true); @@ -579,9 +625,8 @@ public function validateMaxPostSize(): void /** * Adds global error message. - * @param string|object $message */ - public function addError($message, bool $translate = true): void + public function addError(string|Stringable $message, bool $translate = true): void { if ($translate && $this->translator) { $message = $this->translator->translate($message); @@ -629,7 +674,7 @@ public function getOwnErrors(): array */ public function getElementPrototype(): Html { - if (!$this->element) { + if (!isset($this->element)) { $this->element = Html::el('form'); $this->element->action = ''; // RFC 1808 -> empty uri means 'this' $this->element->method = self::Post; @@ -641,9 +686,8 @@ public function getElementPrototype(): Html /** * Sets form renderer. - * @return static */ - public function setRenderer(?FormRenderer $renderer) + public function setRenderer(?FormRenderer $renderer): static { $this->renderer = $renderer; return $this; @@ -655,7 +699,7 @@ public function setRenderer(?FormRenderer $renderer) */ public function getRenderer(): FormRenderer { - if ($this->renderer === null) { + if (!isset($this->renderer)) { $this->renderer = new Rendering\DefaultFormRenderer; } @@ -693,22 +737,11 @@ public function render(...$args): void /** * Renders form to string. - * @param can throw exceptions? (hidden parameter) */ public function __toString(): string { - try { - $this->fireRenderEvents(); - return $this->getRenderer()->render($this); - - } catch (\Throwable $e) { - if (func_num_args() || PHP_VERSION_ID >= 70400) { - throw $e; - } - - trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); - return ''; - } + $this->fireRenderEvents(); + return $this->getRenderer()->render($this); } @@ -744,7 +777,7 @@ public static function initialize(bool $reinit = false): void if (headers_sent($file, $line)) { throw new Nette\InvalidStateException( 'Create a form or call Nette\Forms\Form::initialize() before the headers are sent to initialize CSRF protection.' - . ($file ? " (output started at $file:$line)" : '') . '. ' + . ($file ? " (output started at $file:$line)" : '') . '. ', ); } @@ -757,7 +790,7 @@ public static function initialize(bool $reinit = false): void private function getHttpRequest(): Nette\Http\IRequest { - if (!$this->httpRequest) { + if (!isset($this->httpRequest)) { self::initialize(); $this->httpRequest = self::$defaultHttpRequest; } diff --git a/src/Forms/FormRenderer.php b/src/Forms/FormRenderer.php index 8db0b7d3a..fdb9eb791 100644 --- a/src/Forms/FormRenderer.php +++ b/src/Forms/FormRenderer.php @@ -20,6 +20,3 @@ interface FormRenderer */ function render(Form $form): string; } - - -interface_exists(IFormRenderer::class); diff --git a/src/Forms/Helpers.php b/src/Forms/Helpers.php index c95da3eaa..576f5fbc0 100644 --- a/src/Forms/Helpers.php +++ b/src/Forms/Helpers.php @@ -17,7 +17,7 @@ /** * Forms helpers. */ -class Helpers +final class Helpers { use Nette\StaticClass; @@ -30,16 +30,19 @@ class Helpers /** * Extracts and sanitizes submitted form data for single control. * @param int $type type Form::DataText, DataLine, DataFile, DataKeys - * @return string|string[] * @internal */ - public static function extractHttpData(array $data, string $htmlName, int $type) + public static function extractHttpData( + array $data, + string $htmlName, + int $type, + ): string|array|Nette\Http\FileUpload|null { $name = explode('[', str_replace(['[]', ']', '.'], ['', '', '_'], $htmlName)); $data = Nette\Utils\Arrays::get($data, $name, null); $itype = $type & ~Form::DataKeys; - if (substr($htmlName, -2) === '[]') { + if (str_ends_with($htmlName, '[]')) { if (!is_array($data)) { return []; } @@ -162,7 +165,7 @@ public static function createInputList( array $items, ?array $inputAttrs = null, ?array $labelAttrs = null, - $wrapper = null + $wrapper = null, ): string { [$inputAttrs, $inputTag] = self::prepareAttrs($inputAttrs, 'input'); @@ -184,7 +187,7 @@ public static function createInputList( $input->value = $value; $res .= ($res === '' && $wrapperEnd === '' ? '' : $wrapper) . $labelTag . $label->attributes() . '>' - . $inputTag . $input->attributes() . (isset(Html::$xhtml) && Html::$xhtml ? ' />' : '>') + . $inputTag . $input->attributes() . '>' . ($caption instanceof Nette\HtmlStringable ? $caption : htmlspecialchars((string) $caption, ENT_NOQUOTES, 'UTF-8')) . '' . $wrapperEnd; @@ -281,7 +284,7 @@ public static function getSingleType($reflection): ?string return $res; } else { throw new Nette\InvalidStateException( - Nette\Utils\Reflection::toString($reflection) . " has unsupported type '$type'." + Nette\Utils\Reflection::toString($reflection) . " has unsupported type '$type'.", ); } } diff --git a/src/Forms/Rendering/DataClassGenerator.php b/src/Forms/Rendering/DataClassGenerator.php index 2c4f5f60f..58ce475fe 100644 --- a/src/Forms/Rendering/DataClassGenerator.php +++ b/src/Forms/Rendering/DataClassGenerator.php @@ -19,19 +19,14 @@ */ final class DataClassGenerator { - /** @var string */ - public $classNameSuffix = 'FormData'; - - /** @var bool */ - public $propertyPromotion = false; - - /** @var bool */ - public $useSmartObject = true; + public string $classNameSuffix = 'FormData'; + public bool $propertyPromotion = false; + public bool $useSmartObject = true; public function generateCode(Form $form, ?string $baseName = null): string { - $baseName = $baseName ?? preg_replace('~Form$~', '', ucwords((string) $form->getName())); + $baseName ??= preg_replace('~Form$~', '', ucwords((string) $form->getName())); return $this->processContainer($form, $baseName); } diff --git a/src/Forms/Rendering/DefaultFormRenderer.php b/src/Forms/Rendering/DefaultFormRenderer.php index 64da5e47c..8939bf587 100644 --- a/src/Forms/Rendering/DefaultFormRenderer.php +++ b/src/Forms/Rendering/DefaultFormRenderer.php @@ -56,8 +56,8 @@ class DefaultFormRenderer implements Nette\Forms\FormRenderer * \--- * \--- * \-- - * @var array of HTML tags */ - public $wrappers = [ + */ + public array $wrappers = [ 'form' => [ 'container' => null, ], @@ -118,11 +118,9 @@ class DefaultFormRenderer implements Nette\Forms\FormRenderer ], ]; - /** @var Nette\Forms\Form */ - protected $form; + protected Nette\Forms\Form $form; - /** @var int */ - protected $counter; + protected int $counter; /** @@ -131,9 +129,7 @@ class DefaultFormRenderer implements Nette\Forms\FormRenderer */ public function render(Nette\Forms\Form $form, ?string $mode = null): string { - if ($this->form !== $form) { - $this->form = $form; - } + $this->form = $form; $s = ''; if (!$mode || $mode === 'begin') { @@ -325,14 +321,9 @@ public function renderBody(): string /** * Renders group of controls. - * @param Nette\Forms\Container|Nette\Forms\ControlGroup $parent */ - public function renderControls($parent): string + public function renderControls(Nette\Forms\Container|Nette\Forms\ControlGroup $parent): string { - if (!($parent instanceof Nette\Forms\Container || $parent instanceof Nette\Forms\ControlGroup)) { - throw new Nette\InvalidArgumentException('Argument must be Nette\Forms\Container or Nette\Forms\ControlGroup instance.'); - } - $container = $this->getWrapper('controls container'); $buttons = null; @@ -516,15 +507,13 @@ public function renderControl(Nette\Forms\Control $control): Html } - /** @return string|Html|null */ - protected function renderLabelElement(Nette\Forms\Control $control) + protected function renderLabelElement(Nette\Forms\Control $control): Html|string|null { return $control->getLabel(); } - /** @return string|Html */ - protected function renderControlElement(Nette\Forms\Control $control) + protected function renderControlElement(Nette\Forms\Control $control): Html|string { return $control->getControl(); } @@ -537,8 +526,7 @@ public function getWrapper(string $name): Html } - /** @return mixed */ - protected function getValue(string $name) + protected function getValue(string $name): mixed { $name = explode(' ', $name); $data = &$this->wrappers[$name[0]][$name[1]]; diff --git a/src/Forms/Rendering/LatteRenderer.php b/src/Forms/Rendering/LatteRenderer.php index b800e9063..2e596f8de 100644 --- a/src/Forms/Rendering/LatteRenderer.php +++ b/src/Forms/Rendering/LatteRenderer.php @@ -11,6 +11,7 @@ use Nette; use Nette\Forms\Form; +use Nette\Utils\Html; /** @@ -33,7 +34,7 @@ protected function receiveHttpData(): ?array public $inner; - public function getLabel($name = null) + public function getLabel($name = null): Html|string|null { return $this->inner->getLabel() ? '{label ' . $this->inner->lookupPath(Form::class) . '/}' @@ -41,7 +42,7 @@ public function getLabel($name = null) } - public function getControl() + public function getControl(): Html|string { return '{input ' . $this->inner->lookupPath(Form::class) . '}'; } @@ -53,7 +54,7 @@ public function isRequired(): bool } - public function getOption($key) + public function getOption($key): mixed { return $key === 'rendered' ? parent::getOption($key) diff --git a/src/Forms/Rule.php b/src/Forms/Rule.php index 1d2fa0344..f75fa6c39 100644 --- a/src/Forms/Rule.php +++ b/src/Forms/Rule.php @@ -10,32 +10,28 @@ namespace Nette\Forms; use Nette; +use Stringable; /** * Single validation rule or condition represented as value object. */ -class Rule +final class Rule { use Nette\SmartObject; - /** @var Control */ - public $control; + public Control $control; - /** @var mixed */ - public $validator; + public mixed $validator; - /** @var mixed */ - public $arg; + public mixed $arg = null; - /** @var bool */ - public $isNegative = false; + public bool $isNegative = false; - /** @var string|null */ - public $message; + public string|Stringable|null $message; - /** @var Rules|null for conditions */ - public $branch; + /** for conditions */ + public ?Rules $branch = null; /** @internal */ diff --git a/src/Forms/Rules.php b/src/Forms/Rules.php index 07434478f..8234793b9 100644 --- a/src/Forms/Rules.php +++ b/src/Forms/Rules.php @@ -10,12 +10,13 @@ namespace Nette\Forms; use Nette; +use Stringable; /** * List of validation & condition rules. */ -class Rules implements \IteratorAggregate +final class Rules implements \IteratorAggregate { use Nette\SmartObject; @@ -24,20 +25,16 @@ class Rules implements \IteratorAggregate Form::Blank => Form::Filled, ]; - /** @var Rule|null */ - private $required; + private ?Rule $required = null; /** @var Rule[] */ - private $rules = []; + private array $rules = []; - /** @var Rules */ - private $parent; + private Rules $parent; - /** @var array */ - private $toggles = []; + private array $toggles = []; - /** @var Control */ - private $control; + private Control $control; public function __construct(Control $control) @@ -48,10 +45,8 @@ public function __construct(Control $control) /** * Makes control mandatory. - * @param string|bool $value - * @return static */ - public function setRequired($value = true) + public function setRequired(string|Stringable|bool $value = true): static { if ($value) { $this->addRule(Form::Filled, $value === true ? null : $value); @@ -74,11 +69,12 @@ public function isRequired(): bool /** * Adds a validation rule for the current control. - * @param callable|string $validator - * @param string|object $errorMessage - * @return static */ - public function addRule($validator, $errorMessage = null, $arg = null) + public function addRule( + callable|string $validator, + string|Stringable|null $errorMessage = null, + mixed $arg = null, + ): static { if ($validator === Form::Valid || $validator === ~Form::Valid) { throw new Nette\InvalidArgumentException('You cannot use Form::Valid in the addRule method.'); @@ -102,10 +98,8 @@ public function addRule($validator, $errorMessage = null, $arg = null) /** * Removes a validation rule for the current control. - * @param callable|string $validator - * @return static */ - public function removeRule($validator) + public function removeRule(callable|string $validator): static { if ($validator === Form::Filled) { $this->required = null; @@ -123,9 +117,8 @@ public function removeRule($validator) /** * Adds a validation condition and returns new branch. - * @return static new branch */ - public function addCondition($validator, $arg = null) + public function addCondition($validator, $arg = null): static { if ($validator === Form::Valid || $validator === ~Form::Valid) { throw new Nette\InvalidArgumentException('You cannot use Form::Valid in the addCondition method.'); @@ -140,9 +133,8 @@ public function addCondition($validator, $arg = null) /** * Adds a validation condition on specified control a returns new branch. - * @return static new branch */ - public function addConditionOn(Control $control, $validator, $arg = null) + public function addConditionOn(Control $control, $validator, $arg = null): static { $rule = new Rule; $rule->control = $control; @@ -159,9 +151,8 @@ public function addConditionOn(Control $control, $validator, $arg = null) /** * Adds a else statement. - * @return static else branch */ - public function elseCondition() + public function elseCondition(): static { $rule = clone end($this->parent->rules); if (isset(self::NegRules[$rule->validator])) { @@ -179,9 +170,8 @@ public function elseCondition() /** * Ends current validation condition. - * @return Rules parent branch */ - public function endCondition(): self + public function endCondition(): static { return $this->parent; } @@ -189,9 +179,8 @@ public function endCondition(): self /** * Adds a filter callback. - * @return static */ - public function addFilter(callable $filter) + public function addFilter(callable $filter): static { $this->rules[] = $rule = new Rule; $rule->control = $this->control; @@ -205,9 +194,8 @@ public function addFilter(callable $filter) /** * Toggles HTML element visibility. - * @return static */ - public function toggle(string $id, bool $hide = true) + public function toggle(string $id, bool $hide = true): static { $this->toggles[$id] = $hide; return $this; @@ -227,13 +215,13 @@ public function getToggleStates(array $toggles = [], bool $success = true, ?bool $toggles[$id] = ($success xor !$hide) || !empty($toggles[$id]); } - $emptyOptional = $emptyOptional ?? (!$this->isRequired() && !$this->control->isFilled()); + $emptyOptional ??= (!$this->isRequired() && !$this->control->isFilled()); foreach ($this as $rule) { if ($rule->branch) { $toggles = $rule->branch->getToggleStates( $toggles, $success && static::validateRule($rule), - $rule->validator === Form::Blank ? false : $emptyOptional + $rule->validator === Form::Blank ? false : $emptyOptional, ); } elseif (!$emptyOptional || $rule->validator === Form::Filled) { $success = $success && static::validateRule($rule); @@ -249,7 +237,7 @@ public function getToggleStates(array $toggles = [], bool $success = true, ?bool */ public function validate(?bool $emptyOptional = null): bool { - $emptyOptional = $emptyOptional ?? (!$this->isRequired() && !$this->control->isFilled()); + $emptyOptional ??= (!$this->isRequired() && !$this->control->isFilled()); foreach ($this as $rule) { if (!$rule->branch && $emptyOptional && $rule->validator !== Form::Filled) { continue; diff --git a/src/Forms/SubmitterControl.php b/src/Forms/SubmitterControl.php index e59f87cda..228745688 100644 --- a/src/Forms/SubmitterControl.php +++ b/src/Forms/SubmitterControl.php @@ -20,6 +20,3 @@ interface SubmitterControl extends Control */ function getValidationScope(): ?array; } - - -interface_exists(ISubmitterControl::class); diff --git a/src/Forms/Validator.php b/src/Forms/Validator.php index e17ebeaf5..af35ff1fe 100644 --- a/src/Forms/Validator.php +++ b/src/Forms/Validator.php @@ -17,12 +17,11 @@ /** * Common validators. */ -class Validator +final class Validator { use Nette\StaticClass; - /** @var array */ - public static $messages = [ + public static array $messages = [ Controls\CsrfProtection::Protection => 'Your session has expired. Please return to the home page and try again.', Form::Equal => 'Please enter %s.', Form::NotEqual => 'This value should not be %s.', @@ -48,10 +47,9 @@ class Validator /** - * @return string|Nette\HtmlStringable * @internal */ - public static function formatMessage(Rule $rule, bool $withValue = true) + public static function formatMessage(Rule $rule, bool $withValue = true): string|Nette\HtmlStringable { $message = $rule->message; if ($message instanceof Nette\HtmlStringable) { @@ -64,7 +62,7 @@ public static function formatMessage(Rule $rule, bool $withValue = true) trigger_error( "Missing validation message for control '{$rule->control->getName()}'" . (is_string($rule->validator) ? " (validator '{$rule->validator}')." : '.'), - E_USER_WARNING + E_USER_WARNING, ); } @@ -181,9 +179,7 @@ public static function validateValid(Controls\BaseControl $control): bool */ public static function validateRange(Control $control, array $range): bool { - $range = array_map(function ($v) { - return $v === '' ? null : $v; - }, $range); + $range = array_map(fn($v) => $v === '' ? null : $v, $range); return Validators::isInRange($control->getValue(), $range); } @@ -208,9 +204,8 @@ public static function validateMax(Control $control, $maximum): bool /** * Count/length validator. Range is array, min and max length pair. - * @param array|int $range */ - public static function validateLength(Control $control, $range): bool + public static function validateLength(Control $control, array|int $range): bool { if (!is_array($range)) { $range = [$range, $range]; diff --git a/src/assets/netteForms.js b/src/assets/netteForms.js index c1b6c7774..d5245a94c 100644 --- a/src/assets/netteForms.js +++ b/src/assets/netteForms.js @@ -307,33 +307,30 @@ * Display modal window. */ Nette.showModal = function(message, onclose) { - var dialog = document.createElement('dialog'), - ua = navigator.userAgentData; - - if (ua && dialog.showModal - && ua.brands.some(function(item) { return item.brand === 'Opera' || (item.brand === 'Chromium' && ua.mobile); }) - ) { - var style = document.createElement('style'); - style.innerText = '.netteFormsModal { text-align: center; margin: auto; border: 2px solid black; padding: 1rem } .netteFormsModal button { padding: .1em 2em }'; - - var button = document.createElement('button'); - button.innerText = 'OK'; - button.onclick = function () { - dialog.remove(); - onclose(); - }; + var dialog = document.createElement('dialog'); - dialog.setAttribute('class', 'netteFormsModal'); - dialog.innerText = message + '\n\n'; - dialog.appendChild(style); - dialog.appendChild(button); - document.body.appendChild(dialog); - dialog.showModal(); + if (!dialog.showModal) { + alert(message); + onclose(); return; } - alert(message); - onclose(); + var style = document.createElement('style'); + style.innerText = '.netteFormsModal { text-align: center; margin: auto; border: 2px solid black; padding: 1rem } .netteFormsModal button { padding: .1em 2em }'; + + var button = document.createElement('button'); + button.innerText = 'OK'; + button.onclick = function () { + dialog.remove(); + onclose(); + }; + + dialog.setAttribute('class', 'netteFormsModal'); + dialog.innerText = message + '\n\n'; + dialog.appendChild(style); + dialog.appendChild(button); + document.body.appendChild(dialog); + dialog.showModal(); }; diff --git a/src/compatibility.php b/src/compatibility.php deleted file mode 100644 index dd9c45ee5..000000000 --- a/src/compatibility.php +++ /dev/null @@ -1,37 +0,0 @@ -addProvider('uiControl', ['myForm' => $form]); Assert::matchFile( __DIR__ . '/expected/FormMacros.button.php', - $latte->compile(__DIR__ . '/templates/forms.button.latte') + $latte->compile(__DIR__ . '/templates/forms.button.latte'), ); Assert::matchFile( __DIR__ . '/expected/FormMacros.button.html', - $latte->renderToString(__DIR__ . '/templates/forms.button.latte') + $latte->renderToString(__DIR__ . '/templates/forms.button.latte'), ); diff --git a/tests/Forms.Latte2/FormMacros.formContainer.phpt b/tests/Forms.Latte2/FormMacros.formContainer.phpt index cb22e4950..a2d93c6e0 100644 --- a/tests/Forms.Latte2/FormMacros.formContainer.phpt +++ b/tests/Forms.Latte2/FormMacros.formContainer.phpt @@ -47,9 +47,9 @@ $latte->addProvider('uiControl', ['myForm' => $form]); Assert::matchFile( __DIR__ . '/expected/FormMacros.formContainer.php', - $latte->compile(__DIR__ . '/templates/forms.formContainer.latte') + $latte->compile(__DIR__ . '/templates/forms.formContainer.latte'), ); Assert::matchFile( __DIR__ . '/expected/FormMacros.formContainer.html', - $latte->renderToString(__DIR__ . '/templates/forms.formContainer.latte') + $latte->renderToString(__DIR__ . '/templates/forms.formContainer.latte'), ); diff --git a/tests/Forms.Latte2/FormMacros.forms.phpt b/tests/Forms.Latte2/FormMacros.forms.phpt index a889bb78b..2b60affa0 100644 --- a/tests/Forms.Latte2/FormMacros.forms.phpt +++ b/tests/Forms.Latte2/FormMacros.forms.phpt @@ -19,13 +19,13 @@ if (version_compare(Latte\Engine::VERSION, '3', '>')) { class MyControl extends Nette\Forms\Controls\BaseControl { - public function getLabel($c = null) + public function getLabel($c = null): string { return ''; } - public function getControl() + public function getControl(): string { return ''; } @@ -53,9 +53,9 @@ $form['username']->addError('error'); Assert::matchFile( __DIR__ . '/expected/FormMacros.forms.php', - $latte->compile(__DIR__ . '/templates/forms.latte') + $latte->compile(__DIR__ . '/templates/forms.latte'), ); Assert::matchFile( __DIR__ . '/expected/FormMacros.forms.html', - $latte->renderToString(__DIR__ . '/templates/forms.latte') + $latte->renderToString(__DIR__ . '/templates/forms.latte'), ); diff --git a/tests/Forms.Latte2/FormMacros.get.phpt b/tests/Forms.Latte2/FormMacros.get.phpt index 35e0d878c..cb74c5d93 100644 --- a/tests/Forms.Latte2/FormMacros.get.phpt +++ b/tests/Forms.Latte2/FormMacros.get.phpt @@ -28,9 +28,9 @@ $latte->addProvider('uiControl', ['myForm' => $form]); Assert::matchFile( __DIR__ . '/expected/FormMacros.get.php', - $latte->compile(__DIR__ . '/templates/forms.get.latte') + $latte->compile(__DIR__ . '/templates/forms.get.latte'), ); Assert::matchFile( __DIR__ . '/expected/FormMacros.get.html', - $latte->renderToString(__DIR__ . '/templates/forms.get.latte') + $latte->renderToString(__DIR__ . '/templates/forms.get.latte'), ); diff --git a/tests/Forms.Latte2/expected/FormMacros.button.php b/tests/Forms.Latte2/expected/FormMacros.button.php index eee0f8d0f..fe3530d94 100644 --- a/tests/Forms.Latte2/expected/FormMacros.button.php +++ b/tests/Forms.Latte2/expected/FormMacros.button.php @@ -2,7 +2,7 @@ %A% $form = $this->global->formsStack[] = $this->global->uiControl["myForm"] /* line 1 */; echo 'global->formsStack), [], false); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), [], false); echo '> global->formsStack)["send"]; @@ -23,7 +23,7 @@ echo LR\Filters::escapeHtmlText($ʟ_input->getCaption()) /* line 8 */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), false) /* line 1 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack), false) /* line 1 */; echo ' '; %A% diff --git a/tests/Forms.Latte2/expected/FormMacros.formContainer.php b/tests/Forms.Latte2/expected/FormMacros.formContainer.php index c0e393ec6..a3cb38470 100644 --- a/tests/Forms.Latte2/expected/FormMacros.formContainer.php +++ b/tests/Forms.Latte2/expected/FormMacros.formContainer.php @@ -1,6 +1,6 @@ global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 1 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 1 */; echo ' @@ -94,6 +94,6 @@
'; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack)); echo "\n"; %A% diff --git a/tests/Forms.Latte2/expected/FormMacros.forms.html b/tests/Forms.Latte2/expected/FormMacros.forms.html index 76564c2c4..317facb39 100644 --- a/tests/Forms.Latte2/expected/FormMacros.forms.html +++ b/tests/Forms.Latte2/expected/FormMacros.forms.html @@ -9,13 +9,13 @@ - + error error
- + error @@ -48,11 +48,11 @@ - + - + @@ -91,19 +91,19 @@
- +
- +
- +
@@ -121,4 +121,4 @@ - + diff --git a/tests/Forms.Latte2/expected/FormMacros.forms.php b/tests/Forms.Latte2/expected/FormMacros.forms.php index ffb93af75..a9b047351 100644 --- a/tests/Forms.Latte2/expected/FormMacros.forms.php +++ b/tests/Forms.Latte2/expected/FormMacros.forms.php @@ -1,6 +1,6 @@ global->formsStack[] = $this->global->uiControl["myForm"], ['id' => 'myForm', 'class'=>"ajax"]) /* line 1 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], ['id' => 'myForm', 'class'=>"ajax"]) /* line 1 */; echo "\n"; $iterations = 0; foreach (['id', 'username', 'select', 'area', 'send'] as $name) /* line 2 */ { @@ -71,17 +71,17 @@ if ($ʟ_label = end($this->global->formsStack)["my"]->getLabel()) echo $ʟ_label; echo end($this->global->formsStack)["my"]->getControl() /* line 23 */; echo "\n"; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack)); echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 27 */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 27 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack)); echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 29 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 29 */; echo "\n"; $iterations = 0; foreach ($form['sex']->items as $key => $label) /* line 31 */ { @@ -199,14 +199,14 @@ $form = $this->global->formsStack[] = $this->global->uiControl["myForm"] /* line 58 */; if (1) /* line 58 */ { echo '
global->formsStack), ['id' => null, 'class' => null], false); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), ['id' => null, 'class' => null], false); echo '> global->formsStack)["username"]; echo $ʟ_input->getControlPart()->attributes() /* line 59 */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), false) /* line 58 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack), false) /* line 58 */; echo ' '; } @@ -216,7 +216,7 @@ $form = $this->global->formsStack[] = $this->global->uiControl["myForm"] /* line 63 */; echo 'global->formsStack), ['class' => null], false); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), ['class' => null], false); echo '> global->formsStack)["username"]; @@ -224,21 +224,21 @@ echo ($ʟ_tmp = array_filter(['nclass'])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line 64 */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), false) /* line 63 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack), false) /* line 63 */; echo ' '; $form = $this->global->formsStack[] = is_object($ʟ_tmp = $this->global->uiControl['myForm']) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp] /* line 68 */; echo 'global->formsStack), [], false); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), [], false); echo '> global->formsStack)["username"]; echo $ʟ_input->getControlPart()->attributes() /* line 69 */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), false) /* line 68 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack), false) /* line 68 */; echo ' @@ -267,7 +267,7 @@ echo $ʟ_input->getControl()->getHtml() /* line 79 */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack)); echo ' diff --git a/tests/Forms.Latte2/expected/FormMacros.get.php b/tests/Forms.Latte2/expected/FormMacros.get.php index 65fc816d8..d3fe8041b 100644 --- a/tests/Forms.Latte2/expected/FormMacros.get.php +++ b/tests/Forms.Latte2/expected/FormMacros.get.php @@ -1,16 +1,16 @@ global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 1 */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin($form = $this->global->formsStack[] = $this->global->uiControl["myForm"], []) /* line 1 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack)); echo ' '; $form = $this->global->formsStack[] = $this->global->uiControl["myForm"] /* line 3 */; echo 'global->formsStack), [], false); + echo Nette\Bridges\FormsLatte\Runtime2::renderFormBegin(end($this->global->formsStack), [], false); echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack), false) /* line 3 */; + echo Nette\Bridges\FormsLatte\Runtime2::renderFormEnd(array_pop($this->global->formsStack), false) /* line 3 */; echo ' '; %A% diff --git a/tests/Forms.Latte3/Runtime.get.phpt b/tests/Forms.Latte3/Runtime.get.phpt index 874cd8c3e..243013172 100644 --- a/tests/Forms.Latte3/Runtime.get.phpt +++ b/tests/Forms.Latte3/Runtime.get.phpt @@ -1,7 +1,5 @@ addText('arg1'); $form->addText('arg2'); $form->setAction('http://example.com/?do=foo-submit&arg0=1&arg1=1&arg2[x]=1#toc'); +$runtime = new Runtime; +$runtime->begin($form); + Assert::same( '
', - Runtime::renderFormBegin($form, []), + $runtime->renderFormBegin([]), ); Assert::match( '
', - Runtime::renderFormEnd($form), + $runtime->renderFormEnd(), ); diff --git a/tests/Forms.Latte3/Runtime.renderFormClassPrint.phpt b/tests/Forms.Latte3/Runtime.renderFormClassPrint.phpt index eee743057..866a24de3 100644 --- a/tests/Forms.Latte3/Runtime.renderFormClassPrint.phpt +++ b/tests/Forms.Latte3/Runtime.renderFormClassPrint.phpt @@ -1,7 +1,5 @@ addText('name')->setRequired(); ob_start(); -Nette\Bridges\FormsLatte\Runtime::renderFormClassPrint($form); +(new Nette\Bridges\FormsLatte\Runtime)->renderFormClassPrint($form); $res = ob_get_clean(); Assert::match( diff --git a/tests/Forms.Latte3/Runtime.renderFormPrint.phpt b/tests/Forms.Latte3/Runtime.renderFormPrint.phpt index 832275444..6616e36dc 100644 --- a/tests/Forms.Latte3/Runtime.renderFormPrint.phpt +++ b/tests/Forms.Latte3/Runtime.renderFormPrint.phpt @@ -1,7 +1,5 @@ addText('name')->setRequired('Enter your name'); $form->addSubmit('submit', 'Send'); ob_start(); -Nette\Bridges\FormsLatte\Runtime::renderFormPrint($form); +(new Nette\Bridges\FormsLatte\Runtime)->renderFormPrint($form); $res = ob_get_clean(); Assert::match( diff --git a/tests/Forms.Latte3/expected/forms.button.php b/tests/Forms.Latte3/expected/forms.button.php index ab94e396a..8af2b21b2 100644 --- a/tests/Forms.Latte3/expected/forms.button.php +++ b/tests/Forms.Latte3/expected/forms.button.php @@ -1,27 +1,27 @@ global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; echo 'global->formsStack), [], false) /* line %d% */; + echo $this->global->forms->renderFormBegin([], false) /* line %d% */; echo '> global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('send'))->getControlPart()->attributes() /* line %d% */; echo '> description of button global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('send'))->getControlPart()->attributes() /* line %d% */; echo '> global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('send'))->getControlPart()->attributes() /* line %d% */; echo '>'; echo LR\Filters::escapeHtmlText($ʟ_input->getCaption()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line %d% */; + echo $this->global->forms->renderFormEnd(false) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); + $this->global->forms->end(); %A% diff --git a/tests/Forms.Latte3/expected/forms.formContainer.php b/tests/Forms.Latte3/expected/forms.formContainer.php index cbe9ad366..6bd65b4e0 100644 --- a/tests/Forms.Latte3/expected/forms.formContainer.php +++ b/tests/Forms.Latte3/expected/forms.formContainer.php @@ -1,45 +1,45 @@ global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, []) /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; + echo $this->global->forms->renderFormBegin([]) /* line %d% */; echo ' '; - $this->global->formsStack[] = $formContainer = Nette\Bridges\FormsLatte\Runtime::item('cont1', $this->global) /* line %d% */; + $this->global->forms->begin($formContainer = $this->global->forms->item('cont1')) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); - $formContainer = end($this->global->formsStack); + $this->global->forms->end(); + $formContainer = $this->global->forms->current(); - $this->global->formsStack[] = $formContainer = Nette\Bridges\FormsLatte\Runtime::item('items', $this->global) /* line %d% */; + $this->global->forms->begin($formContainer = $this->global->forms->item('items')) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); - $formContainer = end($this->global->formsStack); + $this->global->forms->end(); + $formContainer = $this->global->forms->current(); echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('input1', $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('input1')->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input1', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input1')->getControl() /* line %d% */; echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('input2', $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('input2')->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input2', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input2')->getControl() /* line %d% */; echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('input3', $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('input3')->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input3', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input3')->getControl() /* line %d% */; echo '
Checkboxes '; - $this->global->formsStack[] = $formContainer = Nette\Bridges\FormsLatte\Runtime::item('cont2', $this->global) /* line %d% */; + $this->global->forms->begin($formContainer = $this->global->forms->item('cont2')) /* line %d% */; echo '
    '; foreach ($formContainer->controls as $name => $field) /* line %d% */ { echo '
  1. '; - echo Nette\Bridges\FormsLatte\Runtime::item($field, $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item($field)->getControl() /* line %d% */; echo '
  2. '; @@ -47,24 +47,24 @@ echo '
'; - array_pop($this->global->formsStack); - $formContainer = end($this->global->formsStack); + $this->global->forms->end(); + $formContainer = $this->global->forms->current(); echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('input7', $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('input7')->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input7', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input7')->getControl() /* line %d% */; echo '
Items @@ -72,12 +72,12 @@ $items = [1, 2, 3] /* line %d% */; foreach ($items as $item) /* line %d% */ { if (!isset($formContainer[$item])) /* line %d% */ continue; - $this->global->formsStack[] = $formContainer = Nette\Bridges\FormsLatte\Runtime::item($item, $this->global) /* line %d% */; + $this->global->forms->begin($formContainer = $this->global->forms->item($item)) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input')->getControl() /* line %d% */; echo "\n"; - array_pop($this->global->formsStack); - $formContainer = end($this->global->formsStack); + $this->global->forms->end(); + $formContainer = $this->global->forms->current(); } @@ -85,18 +85,19 @@ echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('input8', $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('input8')->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('input8', $this->global)->getControl() /* line %d% */; + echo $this->global->forms->item('input8')->getControl() /* line %d% */; echo '
'; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)) /* line %d% */; -%A% + echo $this->global->forms->renderFormEnd() /* line %d% */; + $this->global->forms->end(); +%A% \ No newline at end of file diff --git a/tests/Forms.Latte3/expected/forms.get.php b/tests/Forms.Latte3/expected/forms.get.php index 06530d61b..0fd2c1eda 100644 --- a/tests/Forms.Latte3/expected/forms.get.php +++ b/tests/Forms.Latte3/expected/forms.get.php @@ -1,19 +1,20 @@ global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, []) /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)) /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; + echo $this->global->forms->renderFormBegin([]) /* line %d% */; + echo $this->global->forms->renderFormEnd() /* line %d% */; + $this->global->forms->end(); echo ' '; - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; echo 'global->formsStack), [], false) /* line %d% */; + echo $this->global->forms->renderFormBegin([], false) /* line %d% */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line %d% */; + echo $this->global->forms->renderFormEnd(false) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); -%A% + $this->global->forms->end(); +%A% \ No newline at end of file diff --git a/tests/Forms.Latte3/expected/forms.html b/tests/Forms.Latte3/expected/forms.html index 485417c52..85a552645 100644 --- a/tests/Forms.Latte3/expected/forms.html +++ b/tests/Forms.Latte3/expected/forms.html @@ -8,12 +8,12 @@ - + error
- + error @@ -43,11 +43,11 @@ - + - + @@ -87,19 +87,19 @@
- +
- +
- +
@@ -118,4 +118,4 @@ - + \ No newline at end of file diff --git a/tests/Forms.Latte3/expected/forms.php b/tests/Forms.Latte3/expected/forms.php index c9551ec81..99e3316af 100644 --- a/tests/Forms.Latte3/expected/forms.php +++ b/tests/Forms.Latte3/expected/forms.php @@ -1,138 +1,140 @@ global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, ['id' => 'myForm', 'class' => 'ajax']) /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; + echo $this->global->forms->renderFormBegin(['id' => 'myForm', 'class' => 'ajax']) /* line %d% */; echo "\n"; foreach (['id', 'username', 'select', 'area', 'send'] as $name) /* line %d% */ { echo ' '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item($name, $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item($name)->getLabel()) /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item($name, $this->global)->getControl()->addAttributes(['title' => 'Hello', 'size' => 10]) /* line %d% */; + echo $this->global->forms->item($name)->getControl()->addAttributes(['title' => 'Hello', 'size' => 10]) /* line %d% */; echo ' '; - echo LR\Filters::escapeHtmlText(Nette\Bridges\FormsLatte\Runtime::item($name, $this->global)->getError()) /* line %d% */; + echo LR\Filters::escapeHtmlText($this->global->forms->item($name)->getError()) /* line %d% */; echo '
'; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item($form[$name], $this->global)->getLabel())?->addAttributes(['title' => 'hello'])?->startTag() /* line %d% */; + echo ($ʟ_label = $this->global->forms->item($form[$name])->getLabel())?->addAttributes(['title' => 'hello'])?->startTag() /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item($form[$name], $this->global)->getControl()->addAttributes(['title' => 'Hello', 'size' => 10]) /* line %d% */; + echo $this->global->forms->item($form[$name])->getControl()->addAttributes(['title' => 'Hello', 'size' => 10]) /* line %d% */; echo ' '; echo $ʟ_label?->endTag() /* line %d% */; echo ' '; - echo LR\Filters::escapeHtmlText(Nette\Bridges\FormsLatte\Runtime::item($form[$name], $this->global)->getError()) /* line %d% */; + echo LR\Filters::escapeHtmlText($this->global->forms->item($form[$name])->getError()) /* line %d% */; echo "\n"; } echo ' '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item($form['username'], $this->global)->getLabel()) /* line %d% */; + echo ($ʟ_label = $this->global->forms->item($form['username'])->getLabel()) /* line %d% */; echo ' global))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello>Name global))->getControlPart()->addAttributes(['value' => null, 'type' => null, 'class' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getControlPart()->addAttributes(['value' => null, 'type' => null, 'class' => null])->attributes() /* line %d% */; echo '> global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item($form['username']))->getLabelPart()->attributes() /* line %d% */; echo '> global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item($form['username']))->getLabelPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item($form['username']))->getControlPart()->attributes() /* line %d% */; echo '> '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('my', $this->global)->getLabel()) /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::item('my', $this->global)->getControl() /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('my')->getLabel()) /* line %d% */; + echo $this->global->forms->item('my')->getControl() /* line %d% */; echo "\n"; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)) /* line %d% */; + echo $this->global->forms->renderFormEnd() /* line %d% */; + $this->global->forms->end(); echo ' '; - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, []) /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)) /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; + echo $this->global->forms->renderFormBegin([]) /* line %d% */; + echo $this->global->forms->renderFormEnd() /* line %d% */; + $this->global->forms->end(); echo ' '; - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form, []) /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; + echo $this->global->forms->renderFormBegin([]) /* line %d% */; echo "\n"; foreach ($form['sex']->items as $key => $label) /* line %d% */ { echo ' '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('sex', $this->global)->getLabelPart($key))?->startTag() /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('sex')->getLabelPart($key))?->startTag() /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('sex', $this->global)->getControlPart($key) /* line %d% */; + echo $this->global->forms->item('sex')->getControlPart($key) /* line %d% */; echo ' '; echo LR\Filters::escapeHtmlText($label) /* line %d% */; echo $ʟ_label?->endTag() /* line %d% */; echo ' global))->getLabelPart($key)->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getLabelPart($key)->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello> global))->getControlPart($key)->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getControlPart($key)->attributes() /* line %d% */; echo '> '; } echo 'global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getLabelPart()->attributes() /* line %d% */; echo '> global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getLabelPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title="hello">'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getControlPart("{$key}")->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item($form['sex']))->getControlPart("{$key}")->attributes() /* line %d% */; echo '> '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('checkbox', $this->global)->getLabelPart(''))?->startTag() /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('checkbox')->getLabelPart(''))?->startTag() /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('checkbox', $this->global)->getControlPart('') /* line %d% */; + echo $this->global->forms->item('checkbox')->getControlPart('') /* line %d% */; echo ' Label'; echo $ʟ_label?->endTag() /* line %d% */; echo ' global))->getLabelPart('')->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getLabelPart('')->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello> global))->getControlPart('')->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getControlPart('')->attributes() /* line %d% */; echo '> global))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello> global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getControlPart()->attributes() /* line %d% */; echo '> global))->getLabelPart('')->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getLabelPart('')->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checkbox'))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' @@ -141,32 +143,32 @@ '; foreach ($form['checklist']->items as $key => $label) /* line %d% */ { echo ' '; - echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item('checklist', $this->global)->getLabelPart($key))?->startTag() /* line %d% */; + echo ($ʟ_label = $this->global->forms->item('checklist')->getLabelPart($key))?->startTag() /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::item('checklist', $this->global)->getControlPart($key) /* line %d% */; + echo $this->global->forms->item('checklist')->getControlPart($key) /* line %d% */; echo ' '; echo LR\Filters::escapeHtmlText($label) /* line %d% */; echo $ʟ_label?->endTag() /* line %d% */; echo ' global))->getLabelPart($key)->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checklist'))->getLabelPart($key)->attributes() /* line %d% */; echo '> global))->getControlPart($key)->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checklist'))->getControlPart($key)->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title=hello> '; } echo 'global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checklist'))->getLabelPart()->attributes() /* line %d% */; echo '> global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checklist'))->getLabelPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('checklist'))->getLabelPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title="hello">'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' @@ -174,62 +176,62 @@ '; if (1) /* line %d% */ { - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; echo 'global->formsStack), ['id' => null, 'class' => null], false) /* line %d% */; + echo $this->global->forms->renderFormBegin(['id' => null, 'class' => null], false) /* line %d% */; echo ' id="myForm" class="ajax"> global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getControlPart()->attributes() /* line %d% */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line %d% */; + echo $this->global->forms->renderFormEnd(false) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); + $this->global->forms->end(); } echo ' '; - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; echo 'global->formsStack), ['class' => null], false) /* line %d% */; + echo $this->global->forms->renderFormBegin(['class' => null], false) /* line %d% */; echo ($ʟ_tmp = array_filter(['nclass'])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line %d% */; echo '> global))->getControlPart()->addAttributes(['class' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getControlPart()->addAttributes(['class' => null])->attributes() /* line %d% */; echo ($ʟ_tmp = array_filter(['nclass'])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line %d% */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line %d% */; + echo $this->global->forms->renderFormEnd(false) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); + $this->global->forms->end(); echo ' '; - $form = $this->global->formsStack[] = is_object($ʟ_tmp = $this->global->uiControl['myForm']) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp] /* line %d% */; + $this->global->forms->begin($form = (is_object($ʟ_tmp = $this->global->uiControl['myForm']) ? $ʟ_tmp : $this->global->uiControl[$ʟ_tmp])) /* line %d% */; echo 'global->formsStack), [], false) /* line %d% */; + echo $this->global->forms->renderFormBegin([], false) /* line %d% */; echo '> global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getControlPart()->attributes() /* line %d% */; echo '> '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line %d% */; + echo $this->global->forms->renderFormEnd(false) /* line %d% */; echo ' '; - array_pop($this->global->formsStack); + $this->global->forms->end(); echo ' global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('select'))->getControlPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getControl()->getHtml() /* line %d% */; echo ' global))->getControlPart()->addAttributes(['title' => null])->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('area'))->getControlPart()->addAttributes(['title' => null])->attributes() /* line %d% */; echo ' title="'; echo LR\Filters::escapeHtmlAttr(10) /* line %d% */; echo '">'; @@ -238,27 +240,29 @@ global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('select'))->getControlPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getControl()->getHtml() /* line %d% */; echo ' '; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(array_pop($this->global->formsStack)) /* line %d% */; + echo $this->global->forms->renderFormEnd() /* line %d% */; + $this->global->forms->end(); echo ' '; - $form = $this->global->formsStack[] = $this->global->uiControl['myForm'] /* line %d% */; + $this->global->forms->begin($form = $this->global->uiControl['myForm']) /* line %d% */; echo ' global))->getLabelPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('sex'))->getLabelPart()->attributes() /* line %d% */; echo '>'; echo $ʟ_input->getLabelPart()->getHtml() /* line %d% */; echo ' global))->getControlPart()->attributes() /* line %d% */; + echo ($ʟ_input = $this->global->forms->item('username'))->getControlPart()->attributes() /* line %d% */; echo '> '; - array_pop($this->global->formsStack) /* line %d% */; -%A% + /* line %d% */; + $this->global->forms->end(); +%A% \ No newline at end of file diff --git a/tests/Forms.Latte3/forms.button.phpt b/tests/Forms.Latte3/forms.button.phpt index bbf035844..136f44bd3 100644 --- a/tests/Forms.Latte3/forms.button.phpt +++ b/tests/Forms.Latte3/forms.button.phpt @@ -1,7 +1,5 @@ My'; } - public function getControl() + public function getControl(): string { return ''; } diff --git a/tests/Forms.Latte3/n-name.form.phpt b/tests/Forms.Latte3/n-name.form.phpt index a97fc17db..dfb182615 100644 --- a/tests/Forms.Latte3/n-name.form.phpt +++ b/tests/Forms.Latte3/n-name.form.phpt @@ -1,7 +1,5 @@ addExtension(new FormsExtension); Assert::match( <<<'XX' %A% - $form = $this->global->formsStack[] = $this->global->uiControl['foo'] /* line 1 */; + $this->global->forms->begin($form = $this->global->uiControl['foo']) /* line 1 */; echo 'global->formsStack), [], false) /* line 1 */; + echo $this->global->forms->renderFormBegin([], false) /* line 1 */; echo '>'; - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line 1 */; + echo $this->global->forms->renderFormEnd(false) /* line 1 */; echo ''; - array_pop($this->global->formsStack); + $this->global->forms->end(); %A% XX, $latte->compile('
'), @@ -37,18 +35,18 @@ Assert::match( Assert::match( <<<'XX' %A% - $form = $this->global->formsStack[] = $this->global->uiControl['foo'] /* line 1 */; + $this->global->forms->begin($form = $this->global->uiControl['foo']) /* line 1 */; $ʟ_tag[0] = ''; if (0) /* line 1 */ { echo '<'; echo $ʟ_tmp = ('form'); $ʟ_tag[0] = '' . $ʟ_tag[0]; - echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin(end($this->global->formsStack), [], false) /* line 1 */; + echo $this->global->forms->renderFormBegin([], false) /* line 1 */; echo '>'; } - echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd(end($this->global->formsStack), false) /* line 1 */; + echo $this->global->forms->renderFormEnd(false) /* line 1 */; echo $ʟ_tag[0]; - array_pop($this->global->formsStack); + $this->global->forms->end(); %A% XX, $latte->compile('
'), diff --git a/tests/Forms.Latte3/n-name.input.phpt b/tests/Forms.Latte3/n-name.input.phpt index 7a1b1c839..e3f09d758 100644 --- a/tests/Forms.Latte3/n-name.input.phpt +++ b/tests/Forms.Latte3/n-name.input.phpt @@ -1,7 +1,5 @@ setLoader(new Latte\Loaders\StringLoader); $latte->addExtension(new FormsExtension); Assert::match( - '%A%echo ($ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global))->getControlPart()->attributes() %A%', + '%A%echo ($ʟ_input = $this->global->forms->item(\'foo\'))->getControlPart()->attributes() %A%', $latte->compile(''), ); Assert::match( - '%A%echo ($ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global))->getControlPart(\'\')->attributes() %A%', + '%A%echo ($ʟ_input = $this->global->forms->item(\'foo\'))->getControlPart(\'\')->attributes() %A%', $latte->compile(''), ); @@ -35,11 +33,11 @@ Assert::exception( ); Assert::match( - '%A%echo ($ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global))->getControlPart(\'x\')->attributes() %A%', + '%A%echo ($ʟ_input = $this->global->forms->item(\'foo\'))->getControlPart(\'x\')->attributes() %A%', $latte->compile(''), ); Assert::match( - '%A%echo ($ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global))->getControlPart(\'x\')->attributes() %A%', + '%A%echo ($ʟ_input = $this->global->forms->item(\'foo\'))->getControlPart(\'x\')->attributes() %A%', $latte->compile(''), ); diff --git a/tests/Forms.Latte3/{input}.phpt b/tests/Forms.Latte3/{input}.phpt index 9a49d02a4..f976a35a7 100644 --- a/tests/Forms.Latte3/{input}.phpt +++ b/tests/Forms.Latte3/{input}.phpt @@ -1,7 +1,5 @@ setLoader(new Latte\Loaders\StringLoader); $latte->addExtension(new FormsExtension); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControl() %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControl() %A%', $latte->compile('{input foo}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControl()->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControl()->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{input foo class => foo}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControl()->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControl()->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{input foo, class => foo}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'\') %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'\') %A%', $latte->compile('{input foo:}'), ); @@ -45,31 +43,31 @@ Assert::exception( ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'\') %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'\') %A%', $latte->compile('{input foo:,}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'\')->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'\')->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{input foo:, class => foo}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'x\') %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'x\') %A%', $latte->compile('{input foo:x}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'x\')->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'x\')->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{input foo:x, class => foo}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'x\') %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'x\') %A%', $latte->compile('{input "foo":"x"}'), ); Assert::match( - '%A%echo Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getControlPart(\'x\') %A%', + '%A%echo $this->global->forms->item(\'foo\')->getControlPart(\'x\') %A%', $latte->compile('{input "foo" : "x"}'), ); diff --git a/tests/Forms.Latte3/{label}.phpt b/tests/Forms.Latte3/{label}.phpt index fdf63a06b..c776c10a0 100644 --- a/tests/Forms.Latte3/{label}.phpt +++ b/tests/Forms.Latte3/{label}.phpt @@ -1,7 +1,5 @@ setLoader(new Latte\Loaders\StringLoader); $latte->addExtension(new FormsExtension); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabel()) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabel()) %A%', $latte->compile('{label foo /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabel())?->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabel())?->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{label foo class => foo /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabel())?->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabel())?->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{label foo, class => foo /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'\')) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'\')) %A%', $latte->compile('{label foo: /}'), ); @@ -45,31 +43,31 @@ Assert::exception( ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'\')) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'\')) %A%', $latte->compile('{label foo:, /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'\'))?->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'\'))?->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{label foo:, class => foo /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'x\')) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'x\')) %A%', $latte->compile('{label foo:x /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'x\'))?->addAttributes([\'class\' => \'foo\']) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'x\'))?->addAttributes([\'class\' => \'foo\']) %A%', $latte->compile('{label foo:x, class => foo /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'x\')) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'x\')) %A%', $latte->compile('{label "foo":"x" /}'), ); Assert::match( - '%A%echo ($ʟ_label = Nette\Bridges\FormsLatte\Runtime::item(\'foo\', $this->global)->getLabelPart(\'x\')) %A%', + '%A%echo ($ʟ_label = $this->global->forms->item(\'foo\')->getLabelPart(\'x\')) %A%', $latte->compile('{label "foo" : "x" /}'), ); diff --git a/tests/Forms/Container.values.ArrayHash.phpt b/tests/Forms/Container.values.ArrayHash.phpt index 02ebea072..8ddcaf525 100644 --- a/tests/Forms/Container.values.ArrayHash.phpt +++ b/tests/Forms/Container.values.ArrayHash.phpt @@ -10,7 +10,7 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = [ 'title' => 'sent title', 'first' => [ @@ -24,6 +24,7 @@ $_POST = [ function createForm(): Form { + ob_start(); Form::initialize(true); $form = new Form; diff --git a/tests/Forms/Container.values.array.phpt b/tests/Forms/Container.values.array.phpt index 417f2259d..c98c7b80e 100644 --- a/tests/Forms/Container.values.array.phpt +++ b/tests/Forms/Container.values.array.phpt @@ -10,7 +10,7 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = [ 'title' => 'sent title', 'first' => [ @@ -24,6 +24,7 @@ $_POST = [ function createForm(): Form { + ob_start(); Form::initialize(true); $form = new Form; @@ -64,11 +65,11 @@ test('setDefaults() + array', function () { 'city' => 'zzz', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); -test('submitted form + getValues(true)', function () { +test('submitted form + getValues(array)', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $form = createForm(); @@ -82,7 +83,7 @@ test('submitted form + getValues(true)', function () { 'city' => 'sent city', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); @@ -104,7 +105,7 @@ test('submitted form + reset()', function () { 'city' => '', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); @@ -130,7 +131,7 @@ test('setValues() + array', function () { 'city' => 'sent city', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); // erase $form->setValues([ @@ -149,7 +150,7 @@ test('setValues() + array', function () { 'city' => '', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); @@ -261,7 +262,7 @@ test('onSuccess test', function () { }); -test('submitted form + setValidationScope() + getValues(true)', function () { +test('submitted form + setValidationScope() + getValues(array)', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST['send'] = ''; @@ -275,11 +276,11 @@ test('submitted form + setValidationScope() + getValues(true)', function () { 'age' => 999, 'second' => [], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); -test('submitted form + setValidationScope() + getValues(true)', function () { +test('submitted form + setValidationScope() + getValues(array)', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST['send'] = ''; @@ -294,5 +295,5 @@ test('submitted form + setValidationScope() + getValues(true)', function () { 'city' => 'sent city', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); diff --git a/tests/Forms/Container.values.mapping-constructor.phpt b/tests/Forms/Container.values.mapping-constructor.phpt index 8c0c8988b..d6b85a45d 100644 --- a/tests/Forms/Container.values.mapping-constructor.phpt +++ b/tests/Forms/Container.values.mapping-constructor.phpt @@ -1,9 +1,5 @@ $value) { - $obj->$key = $value; - } - - return $obj; -} - - -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; -$_POST = [ - 'title' => 'sent title', - 'first' => [ - 'age' => '999', - 'second' => [ - 'city' => 'sent city', - ], - ], -]; - - -function createForm(): Form -{ - Form::initialize(true); - - $form = new Form; - $form->addText('title'); - - $first = $form->addContainer('first'); - $first->addText('name'); - $first->addInteger('age'); - - $second = $first->addContainer('second'); - $second->addText('city'); - return $form; -} - - -test('setDefaults() + object', function () { - $form = createForm(); - Assert::false($form->isSubmitted()); - - $form->setDefaults(hydrate(FormData::class, [ - 'title' => 'xxx', - 'extra' => '50', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'yyy', - 'age' => 30, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => 'zzz', - ]), - ]), - ])); - - Assert::same([ - 'title' => 'xxx', - 'first' => [ - 'name' => 'yyy', - 'age' => 30, - 'second' => [ - 'city' => 'zzz', - ], - ], - ], $form->getValues(true)); -}); - - -test('submitted form + getValues()', function () { - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $form = createForm(); - $form->setMappedType(FormData::class); - - Assert::truthy($form->isSubmitted()); - Assert::equal(hydrate(FormData::class, [ - 'title' => 'sent title', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => '', - 'age' => 999, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => 'sent city', - ]), - ]), - ]), $form->getValues()); -}); - - -test('submitted form + reset()', function () { - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $form = createForm(); - $form->setMappedType(FormData::class); - - Assert::truthy($form->isSubmitted()); - - $form->reset(); - - Assert::false($form->isSubmitted()); - Assert::equal(hydrate(FormData::class, [ - 'title' => '', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => '', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => '', - ]), - ]), - ]), $form->getValues()); -}); - - -test('setValues() + object', function () { - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $form = createForm(); - $form->setMappedType(FormData::class); - - Assert::truthy($form->isSubmitted()); - - $form->setValues(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - // age => null - ]), - ])); - - Assert::equal(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => 'sent city', - ]), - ]), - ]), $form->getValues()); - - // erase - $form->setValues(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - ]), - ]), true); - - Assert::equal(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => '', - ]), - ]), - ]), $form->getValues()); -}); - - -test('getValues(...arguments...)', function () { - $_SERVER['REQUEST_METHOD'] = null; - - $form = createForm(); - - $form->setValues([ - 'title' => 'new1', - 'first' => [ - 'name' => 'new2', - ], - ]); - - Assert::equal(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => '', - ]), - ]), - ]), $form->getValues(FormData::class)); - - $form->setMappedType(FormData::class); - $form['first']->setMappedType(FormFirstLevel::class); - $form['first-second']->setMappedType(FormSecondLevel::class); - - Assert::equal(hydrate(FormData::class, [ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => '', - ]), - ]), - ]), $form->getValues()); - - Assert::equal([ - 'title' => 'new1', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => 'new2', - 'age' => null, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => '', - ]), - ]), - ], $form->getValues(true)); -}); - - -test('onSuccess test', function () { - $_SERVER['REQUEST_METHOD'] = 'POST'; - - $form = createForm(); - $form->setMappedType(FormData::class); - - $form->onSuccess[] = function (Form $form, array $values) { - Assert::same([ - 'title' => 'sent title', - 'first' => [ - 'name' => '', - 'age' => 999, - 'second' => [ - 'city' => 'sent city', - ], - ], - ], $values); - }; - - $form->onSuccess[] = function (Form $form, ArrayHash $values) { - Assert::equal(ArrayHash::from([ - 'title' => 'sent title', - 'first' => ArrayHash::from([ - 'name' => '', - 'age' => 999, - 'second' => ArrayHash::from([ - 'city' => 'sent city', - ]), - ]), - ]), $values); - }; - - $form->onSuccess[] = function (Form $form, $values) { - Assert::equal(hydrate(FormData::class, [ - 'title' => 'sent title', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => '', - 'age' => 999, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => 'sent city', - ]), - ]), - ]), $values); - }; - - $form->onSuccess[] = function (Form $form, FormData $values) { - Assert::equal(hydrate(FormData::class, [ - 'title' => 'sent title', - 'first' => hydrate(FormFirstLevel::class, [ - 'name' => '', - 'age' => 999, - 'second' => hydrate(FormSecondLevel::class, [ - 'city' => 'sent city', - ]), - ]), - ]), $values); - }; - - $ok = false; - $form->onSuccess[] = function () use (&$ok) { - $ok = true; - }; - - $form->fireEvents(); - Assert::true($ok); -}); diff --git a/tests/Forms/Container.values.mapping.phpt b/tests/Forms/Container.values.mapping.phpt index 918a38715..a51c618e0 100644 --- a/tests/Forms/Container.values.mapping.phpt +++ b/tests/Forms/Container.values.mapping.phpt @@ -13,35 +13,29 @@ require __DIR__ . '/../bootstrap.php'; #[AllowDynamicProperties] class FormData { - /** @var string */ - public $title; + public string $title; - /** @var FormFirstLevel */ - public $first; + public FormFirstLevel $first; } class FormFirstLevel { - /** @var string */ - public $name; + public string $name; - /** @var int */ - public $age; + public ?int $age = null; - /** @var FormSecondLevel */ - public $second; + public ?FormSecondLevel $second; } class FormSecondLevel { - /** @var string */ - public $city; + public string $city; } -function hydrate(string $class, array $data) +function hydrate(string $class, array $data): object { $obj = new $class; foreach ($data as $key => $value) { @@ -52,7 +46,7 @@ function hydrate(string $class, array $data) } -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = [ 'title' => 'sent title', 'first' => [ @@ -66,6 +60,7 @@ $_POST = [ function createForm(): Form { + ob_start(); Form::initialize(true); $form = new Form; @@ -90,7 +85,7 @@ test('setDefaults() + object', function () { 'extra' => '50', 'first' => hydrate(FormFirstLevel::class, [ 'name' => 'yyy', - 'age' => '30', + 'age' => 30, 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'zzz', ]), @@ -101,12 +96,12 @@ test('setDefaults() + object', function () { 'title' => 'xxx', 'first' => [ 'name' => 'yyy', - 'age' => '30', + 'age' => 30, 'second' => [ 'city' => 'zzz', ], ], - ], $form->getValues(true)); + ], $form->getValues('array')); }); @@ -119,10 +114,10 @@ test('submitted form + getValues()', function () { Assert::truthy($form->isSubmitted()); Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => '', 'age' => 999, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), @@ -143,10 +138,10 @@ test('submitted form + reset()', function () { Assert::false($form->isSubmitted()); Assert::equal(hydrate(FormData::class, [ 'title' => '', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => '', 'age' => null, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => '', ]), ]), @@ -172,10 +167,10 @@ test('setValues() + object', function () { Assert::equal(hydrate(FormData::class, [ 'title' => 'new1', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => 'new2', 'age' => null, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), @@ -191,10 +186,10 @@ test('setValues() + object', function () { Assert::equal(hydrate(FormData::class, [ 'title' => 'new1', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => 'new2', 'age' => null, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => '', ]), ]), @@ -216,10 +211,10 @@ test('getValues(...arguments...)', function () { Assert::equal(hydrate(FormData::class, [ 'title' => 'new1', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => 'new2', 'age' => null, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => '', ]), ]), @@ -249,7 +244,7 @@ test('getValues(...arguments...)', function () { 'city' => '', ]), ]), - ], $form->getValues(true)); + ], $form->getValues('array')); }); @@ -288,10 +283,10 @@ test('onSuccess test', function () { $form->onSuccess[] = function (Form $form, $values) { Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => '', 'age' => 999, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), @@ -301,10 +296,10 @@ test('onSuccess test', function () { $form->onSuccess[] = function (Form $form, FormData $values) { Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => '', 'age' => 999, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), @@ -329,10 +324,10 @@ test('getValues() + object', function () { Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'name' => '', 'age' => 999, - 'second' => ArrayHash::from([ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), @@ -342,7 +337,7 @@ test('getValues() + object', function () { }); -test('submitted form + setValidationScope() + getValues(true)', function () { +test('submitted form + setValidationScope() + getValues()', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST['send'] = ''; @@ -352,15 +347,15 @@ test('submitted form + setValidationScope() + getValues(true)', function () { Assert::truthy($form->isSubmitted()); Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ 'age' => 999, - 'second' => ArrayHash::from([]), + 'second' => hydrate(FormSecondLevel::class, []), ]), ]), $form->getValues(FormData::class)); }); -test('submitted form + setValidationScope() + getValues(true)', function () { +test('submitted form + setValidationScope() + getValues()', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST['send'] = ''; @@ -370,8 +365,8 @@ test('submitted form + setValidationScope() + getValues(true)', function () { Assert::truthy($form->isSubmitted()); Assert::equal(hydrate(FormData::class, [ 'title' => 'sent title', - 'first' => ArrayHash::from([ - 'second' => ArrayHash::from([ + 'first' => hydrate(FormFirstLevel::class, [ + 'second' => hydrate(FormSecondLevel::class, [ 'city' => 'sent city', ]), ]), diff --git a/tests/Forms/Controls.BaseControl.enum.phpt b/tests/Forms/Controls.BaseControl.enum.phpt new file mode 100644 index 000000000..bee011224 --- /dev/null +++ b/tests/Forms/Controls.BaseControl.enum.phpt @@ -0,0 +1,39 @@ +addText('text'); + $input->setValue(TestEnum::CASE_1->value); + + Assert::true(Validator::validateEqual($input, TestEnum::CASE_1)); + Assert::true(Validator::validateEqual($input, 'case 1')); + Assert::false(Validator::validateEqual($input, TestEnum::CASE_2)); + Assert::false(Validator::validateEqual($input, 1)); +}); diff --git a/tests/Forms/Controls.BaseControl.phpt b/tests/Forms/Controls.BaseControl.phpt index c34b2aa97..4aacf5fdc 100644 --- a/tests/Forms/Controls.BaseControl.phpt +++ b/tests/Forms/Controls.BaseControl.phpt @@ -14,7 +14,8 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { + ob_start(); Form::initialize(true); }); @@ -53,7 +54,6 @@ test('validators', function () { Assert::true(Validator::validateFilled($input)); Assert::true(Validator::validateValid($input)); - Assert::false(Validator::validateLength($input, null)); Assert::false(Validator::validateLength($input, 2)); Assert::true(Validator::validateLength($input, 3)); @@ -89,7 +89,6 @@ test('validators for array', function () { Assert::true(Validator::validateFilled($input)); Assert::true(Validator::validateValid($input)); - Assert::false(Validator::validateLength($input, null)); Assert::false(Validator::validateLength($input, 2)); Assert::true(Validator::validateLength($input, 3)); @@ -132,7 +131,7 @@ test('disabled', function () { test('disabled & submitted', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = ['disabled' => 'submitted value']; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $form = new Form; $form->addText('disabled') diff --git a/tests/Forms/Controls.Button.loadData.phpt b/tests/Forms/Controls.Button.loadData.phpt index 49b3de46a..cc0395c46 100644 --- a/tests/Forms/Controls.Button.loadData.phpt +++ b/tests/Forms/Controls.Button.loadData.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.Checkbox.loadData.phpt b/tests/Forms/Controls.Checkbox.loadData.phpt index 937ef10fe..788189351 100644 --- a/tests/Forms/Controls.Checkbox.loadData.phpt +++ b/tests/Forms/Controls.Checkbox.loadData.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.CheckboxList.loadData.phpt b/tests/Forms/Controls.CheckboxList.loadData.phpt index e606bfa41..ec3a31a1c 100644 --- a/tests/Forms/Controls.CheckboxList.loadData.phpt +++ b/tests/Forms/Controls.CheckboxList.loadData.phpt @@ -15,10 +15,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.ChoiceControl.loadData.phpt b/tests/Forms/Controls.ChoiceControl.loadData.phpt index e0ac8134e..88f0b9cf5 100644 --- a/tests/Forms/Controls.ChoiceControl.loadData.phpt +++ b/tests/Forms/Controls.ChoiceControl.loadData.phpt @@ -19,10 +19,11 @@ class ChoiceControl extends Nette\Forms\Controls\ChoiceControl } -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.CsrfProtection.phpt b/tests/Forms/Controls.CsrfProtection.phpt index f093d2a74..cc35f5920 100644 --- a/tests/Forms/Controls.CsrfProtection.phpt +++ b/tests/Forms/Controls.CsrfProtection.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $form = new Form; diff --git a/tests/Forms/Controls.HiddenField.loadData.phpt b/tests/Forms/Controls.HiddenField.loadData.phpt index dfbf1e3bb..940eb08fe 100644 --- a/tests/Forms/Controls.HiddenField.loadData.phpt +++ b/tests/Forms/Controls.HiddenField.loadData.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); @@ -81,9 +82,7 @@ test('object from string by filter', function () { $_POST = ['text' => (string) $date]; $form = new Form; $input = $form->addHidden('text'); - $input->addFilter(function ($value) { - return $value ? new Nette\Utils\DateTime($value) : $value; - }); + $input->addFilter(fn($value) => $value ? new Nette\Utils\DateTime($value) : $value); Assert::same((string) $date, $input->getValue()); $input->validate(); diff --git a/tests/Forms/Controls.ImageButton.loadData.phpt b/tests/Forms/Controls.ImageButton.loadData.phpt index 976b25acf..de8cf4cd2 100644 --- a/tests/Forms/Controls.ImageButton.loadData.phpt +++ b/tests/Forms/Controls.ImageButton.loadData.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.MultiChoiceControl.loadData.phpt b/tests/Forms/Controls.MultiChoiceControl.loadData.phpt index 6349b9cf6..aae111ada 100644 --- a/tests/Forms/Controls.MultiChoiceControl.loadData.phpt +++ b/tests/Forms/Controls.MultiChoiceControl.loadData.phpt @@ -20,10 +20,11 @@ class MultiChoiceControl extends Nette\Forms\Controls\MultiChoiceControl } -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); @@ -184,11 +185,11 @@ test('setValue() and invalid argument', function () use ($series) { Assert::exception(function () use ($input) { $input->setValue(new stdClass); - }, Nette\InvalidArgumentException::class, "Value must be array or null, object given in field 'select'."); + }, Nette\InvalidArgumentException::class, "Value must be array or null, stdClass given in field 'select'."); Assert::exception(function () use ($input) { $input->setValue([new stdClass]); - }, Nette\InvalidArgumentException::class, "Values must be scalar, object given in field 'select'."); + }, Nette\InvalidArgumentException::class, "Values must be scalar, stdClass given in field 'select'."); }); @@ -201,11 +202,11 @@ test('setValue() and disabled checkDefaultValue()', function () use ($series) { Assert::exception(function () use ($input) { $input->setValue(new stdClass); - }, Nette\InvalidArgumentException::class, "Value must be array or null, object given in field 'select'."); + }, Nette\InvalidArgumentException::class, "Value must be array or null, stdClass given in field 'select'."); Assert::exception(function () use ($input) { $input->setValue([new stdClass]); - }, Nette\InvalidArgumentException::class, "Values must be scalar, object given in field 'select'."); + }, Nette\InvalidArgumentException::class, "Values must be scalar, stdClass given in field 'select'."); }); diff --git a/tests/Forms/Controls.MultiSelectBox.loadData.phpt b/tests/Forms/Controls.MultiSelectBox.loadData.phpt index c5c26c1ab..fc0f054ed 100644 --- a/tests/Forms/Controls.MultiSelectBox.loadData.phpt +++ b/tests/Forms/Controls.MultiSelectBox.loadData.phpt @@ -15,10 +15,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.RadioList.loadData.phpt b/tests/Forms/Controls.RadioList.loadData.phpt index e4bf30153..a5c645333 100644 --- a/tests/Forms/Controls.RadioList.loadData.phpt +++ b/tests/Forms/Controls.RadioList.loadData.phpt @@ -14,10 +14,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.SelectBox.isOk.phpt b/tests/Forms/Controls.SelectBox.isOk.phpt index 8584432a2..a85edefed 100644 --- a/tests/Forms/Controls.SelectBox.isOk.phpt +++ b/tests/Forms/Controls.SelectBox.isOk.phpt @@ -43,7 +43,7 @@ Assert::false($select->isOk()); // error message is processed via Rules $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; Form::initialize(true); Validator::$messages[Nette\Forms\Controls\SelectBox::Valid] = 'SelectBox "%label" must be filled.'; $form = new Form; diff --git a/tests/Forms/Controls.SelectBox.loadData.phpt b/tests/Forms/Controls.SelectBox.loadData.phpt index 36c393e03..97a13b972 100644 --- a/tests/Forms/Controls.SelectBox.loadData.phpt +++ b/tests/Forms/Controls.SelectBox.loadData.phpt @@ -14,10 +14,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Controls.TestBase.validators.phpt b/tests/Forms/Controls.TestBase.validators.phpt index 88395d1dd..0c9e7cc8d 100644 --- a/tests/Forms/Controls.TestBase.validators.phpt +++ b/tests/Forms/Controls.TestBase.validators.phpt @@ -99,7 +99,7 @@ test('', function () { $control = new TextInput; $control->value = new class () { - public $lorem = 'ipsum'; + public string $lorem = 'ipsum'; public function __toString(): string @@ -125,7 +125,7 @@ test('', function () { test('', function () { class MockUploadControl extends UploadControl { - public function setValue($value) + public function setValue($value): static { $this->value = $value; return $this; diff --git a/tests/Forms/Controls.TextBase.loadData.phpt b/tests/Forms/Controls.TextBase.loadData.phpt index 84d86c579..9a46a3a59 100644 --- a/tests/Forms/Controls.TextBase.loadData.phpt +++ b/tests/Forms/Controls.TextBase.loadData.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = $_FILES = []; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); @@ -199,9 +200,7 @@ test('filter in BLANK condition', function () { $form = new Form; $input = $form->addText('text'); $input->addCondition($form::Blank) - ->addFilter(function () use ($input) { - return 'default'; - }); + ->addFilter(fn() => 'default'); Assert::same('', $input->getValue()); $input->validate(); @@ -216,9 +215,7 @@ test('filter in !FILLED condition', function () { $input = $form->addText('text'); $input->addCondition($form::Filled) ->elseCondition() - ->addFilter(function () use ($input) { - return 'default'; - }); + ->addFilter(fn() => 'default'); Assert::same('', $input->getValue()); $input->validate(); diff --git a/tests/Forms/Controls.TextInput.valueObjectValidation.phpt b/tests/Forms/Controls.TextInput.valueObjectValidation.phpt index 5238423b6..2304c7673 100644 --- a/tests/Forms/Controls.TextInput.valueObjectValidation.phpt +++ b/tests/Forms/Controls.TextInput.valueObjectValidation.phpt @@ -15,8 +15,7 @@ require __DIR__ . '/../bootstrap.php'; class ValueObject { - /** @var string */ - private $value; + private string $value; public function __construct(string $value) diff --git a/tests/Forms/Controls.UploadControl.loadData.phpt b/tests/Forms/Controls.UploadControl.loadData.phpt index f8a0bbc1e..73c877511 100644 --- a/tests/Forms/Controls.UploadControl.loadData.phpt +++ b/tests/Forms/Controls.UploadControl.loadData.phpt @@ -16,7 +16,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_FILES = [ 'avatar' => [ diff --git a/tests/Forms/Controls.translate().phpt b/tests/Forms/Controls.translate().phpt index cf1fc2a16..92e1076cb 100644 --- a/tests/Forms/Controls.translate().phpt +++ b/tests/Forms/Controls.translate().phpt @@ -17,7 +17,7 @@ class Translator implements Nette\Localization\ITranslator { public function translate($message, ...$parameters): string { - return is_object($message) ? get_class($message) : $message; + return is_object($message) ? $message::class : $message; } } diff --git a/tests/Forms/DataClassGenerator.phpt b/tests/Forms/DataClassGenerator.phpt index 04d1e9acb..4016394a3 100644 --- a/tests/Forms/DataClassGenerator.phpt +++ b/tests/Forms/DataClassGenerator.phpt @@ -40,7 +40,7 @@ class SignContFormData public ?string $name; } ', - $res + $res, ); $generator->propertyPromotion = true; @@ -68,5 +68,5 @@ class SignContFormData } } ', - $res + $res, ); diff --git a/tests/Forms/Forms.callbackParameters.phpt b/tests/Forms/Forms.callbackParameters.phpt index d3d780338..af919c060 100644 --- a/tests/Forms/Forms.callbackParameters.phpt +++ b/tests/Forms/Forms.callbackParameters.phpt @@ -14,7 +14,7 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST['text'] = 'a'; $_POST['btn'] = 'b'; diff --git a/tests/Forms/Forms.crossOrigin.phpt b/tests/Forms/Forms.crossOrigin.phpt index 14ff4ea65..127f035aa 100644 --- a/tests/Forms/Forms.crossOrigin.phpt +++ b/tests/Forms/Forms.crossOrigin.phpt @@ -13,9 +13,10 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_GET = $_POST = $_FILES = $_COOKIE = []; + ob_start(); Form::initialize(true); }); @@ -27,7 +28,7 @@ test('crossOrigin', function () { test('sameSite', function () { - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $form = new Form; Assert::true($form->isSuccess()); diff --git a/tests/Forms/Forms.getHttpData.get.2.phpt b/tests/Forms/Forms.getHttpData.get.2.phpt index 11443bf13..14efaf66e 100644 --- a/tests/Forms/Forms.getHttpData.get.2.phpt +++ b/tests/Forms/Forms.getHttpData.get.2.phpt @@ -13,7 +13,7 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'GET'; $_GET = $_POST = $_FILES = []; }); @@ -29,5 +29,5 @@ test('', function () { Assert::truthy($form->isSubmitted()); Assert::same(['item'], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); diff --git a/tests/Forms/Forms.getHttpData.get.phpt b/tests/Forms/Forms.getHttpData.get.phpt index 0b3cc8393..c8478e4fb 100644 --- a/tests/Forms/Forms.getHttpData.get.phpt +++ b/tests/Forms/Forms.getHttpData.get.phpt @@ -13,9 +13,10 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'GET'; $_GET = $_POST = $_FILES = []; + ob_start(); Form::initialize(true); }); @@ -28,7 +29,7 @@ test('', function () { Assert::false($form->isSubmitted()); Assert::false($form->isSuccess()); Assert::same([], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); @@ -38,7 +39,7 @@ test('', function () { Assert::false($form->isSubmitted()); Assert::same([], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); @@ -53,6 +54,6 @@ test('', function () { Assert::truthy($form->isSubmitted()); Assert::same([Form::TrackerId => $name], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); Assert::same($name, $form[Form::TrackerId]->getValue()); }); diff --git a/tests/Forms/Forms.getHttpData.post.phpt b/tests/Forms/Forms.getHttpData.post.phpt index ca879b0b7..f8cca7377 100644 --- a/tests/Forms/Forms.getHttpData.post.phpt +++ b/tests/Forms/Forms.getHttpData.post.phpt @@ -14,10 +14,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_GET = $_POST = $_FILES = []; + ob_start(); Form::initialize(true); }); @@ -29,12 +30,12 @@ test('', function () { Assert::truthy($form->isSubmitted()); Assert::true($form->isSuccess()); Assert::same([], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); test('', function () { - unset($_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME]); + unset($_COOKIE[Nette\Http\Helpers::StrictCookieName]); $form = new Form; $form->addSubmit('send', 'Send'); @@ -42,7 +43,7 @@ test('', function () { Assert::false($form->isSubmitted()); Assert::false($form->isSuccess()); Assert::same([], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); @@ -54,7 +55,7 @@ test('', function () { Assert::false($form->isSubmitted()); Assert::false($form->isSuccess()); Assert::same([], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); }); @@ -67,7 +68,7 @@ test('', function () { Assert::truthy($form->isSubmitted()); Assert::same([Form::TrackerId => $name], $form->getHttpData()); - Assert::same([], $form->getValues(true)); + Assert::same([], $form->getValues('array')); Assert::same($name, $form[Form::TrackerId]->getValue()); }); diff --git a/tests/Forms/Forms.isValid.phpt b/tests/Forms/Forms.isValid.phpt index a35f2cf17..f02a15794 100644 --- a/tests/Forms/Forms.isValid.phpt +++ b/tests/Forms/Forms.isValid.phpt @@ -13,9 +13,9 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_GET = $_POST = $_FILES = []; }); diff --git a/tests/Forms/Forms.maxPostSize.phpt b/tests/Forms/Forms.maxPostSize.phpt index 338367444..2190b3f58 100644 --- a/tests/Forms/Forms.maxPostSize.phpt +++ b/tests/Forms/Forms.maxPostSize.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['CONTENT_LENGTH'] = PHP_INT_MAX; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $form = new Form; $form->addHidden('x'); diff --git a/tests/Forms/Forms.no.events.phpt b/tests/Forms/Forms.no.events.phpt index 4946d7dd2..15cae6803 100644 --- a/tests/Forms/Forms.no.events.phpt +++ b/tests/Forms/Forms.no.events.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $_POST = ['send' => 'x']; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Forms.omittedValue.phpt b/tests/Forms/Forms.omittedValue.phpt index 54e952b3a..ae5ed9882 100644 --- a/tests/Forms/Forms.omittedValue.phpt +++ b/tests/Forms/Forms.omittedValue.phpt @@ -20,7 +20,7 @@ $form->addText('input'); $form->addText('omittedInput') ->setOmitted(); -Assert::same(['input' => ''], $form->getValues(true)); +Assert::same(['input' => ''], $form->getValues('array')); Assert::true((new TextInput)->setDisabled()->isOmitted()); diff --git a/tests/Forms/Forms.onClick.phpt b/tests/Forms/Forms.onClick.phpt index 08500f738..cc6828140 100644 --- a/tests/Forms/Forms.onClick.phpt +++ b/tests/Forms/Forms.onClick.phpt @@ -12,7 +12,7 @@ require __DIR__ . '/../bootstrap.php'; test('valid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = ['btn' => '']; $called = []; @@ -42,7 +42,7 @@ test('valid', function () { test('valid -> invalid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = ['btn' => '']; $called = []; @@ -79,7 +79,7 @@ test('valid -> invalid', function () { test('invalid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = ['btn' => '']; $called = []; diff --git a/tests/Forms/Forms.onSuccess.phpt b/tests/Forms/Forms.onSuccess.phpt index 4d9f677ff..bd2153816 100644 --- a/tests/Forms/Forms.onSuccess.phpt +++ b/tests/Forms/Forms.onSuccess.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; test('valid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $called = []; $form = new Form; @@ -38,7 +38,7 @@ test('valid', function () { test('valid -> invalid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $called = []; $form = new Form; @@ -68,7 +68,7 @@ test('valid -> invalid', function () { test('invalid', function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $called = []; $form = new Form; diff --git a/tests/Forms/Forms.renderer.1.expect b/tests/Forms/Forms.renderer.1.expect index 98d298a58..3379e91eb 100644 --- a/tests/Forms/Forms.renderer.1.expect +++ b/tests/Forms/Forms.renderer.1.expect @@ -14,7 +14,7 @@ - + Enter your age @@ -54,14 +54,14 @@ - + Enter your shipping address - + Select your country @@ -81,7 +81,7 @@ - + Reenter your password diff --git a/tests/Forms/Forms.renderer.1.phpt b/tests/Forms/Forms.renderer.1.phpt index e48aa102c..071e1539b 100644 --- a/tests/Forms/Forms.renderer.1.phpt +++ b/tests/Forms/Forms.renderer.1.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = ['name' => 'John Doe ', 'age' => '', 'email' => ' @ ', 'send' => 'on', 'street' => '', 'city' => '', 'country' => 'HU', 'password' => 'xxx', 'password2' => '', 'note' => '', 'submit1' => 'Send', 'userid' => '231']; diff --git a/tests/Forms/Forms.renderer.2.expect b/tests/Forms/Forms.renderer.2.expect index 4fbec753b..4b4872f59 100644 --- a/tests/Forms/Forms.renderer.2.expect +++ b/tests/Forms/Forms.renderer.2.expect @@ -13,14 +13,14 @@
-
• +
Age must be numeric value
-
+
Please select a valid option.
@@ -73,7 +73,7 @@
-
(at least 3 characters) +
(at least 3 characters) The password is too short: it must be at least 3 characters
diff --git a/tests/Forms/Forms.renderer.2.phpt b/tests/Forms/Forms.renderer.2.phpt index 201a2fe88..a62c72913 100644 --- a/tests/Forms/Forms.renderer.2.phpt +++ b/tests/Forms/Forms.renderer.2.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_POST = ['name' => 'John Doe ', 'age' => '9.9', 'email' => '@', 'street' => '', 'city' => 'Troubsko', 'country' => '0', 'password' => 'xx', 'password2' => 'xx', 'note' => '', 'submit1' => 'Send', 'userid' => '231']; diff --git a/tests/Forms/Forms.renderer.3.phpt b/tests/Forms/Forms.renderer.3.phpt index 2dfcbec54..cc22118c7 100644 --- a/tests/Forms/Forms.renderer.3.phpt +++ b/tests/Forms/Forms.renderer.3.phpt @@ -12,7 +12,7 @@ require __DIR__ . '/../bootstrap.php'; $_SERVER['REQUEST_METHOD'] = 'POST'; -$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; +$_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $form = new Nette\Forms\Form; $form->addHidden('userid'); diff --git a/tests/Forms/Forms.renderer.translate.expect b/tests/Forms/Forms.renderer.translate.expect index e1230b986..125b4ac49 100644 --- a/tests/Forms/Forms.renderer.translate.expect +++ b/tests/Forms/Forms.renderer.translate.expect @@ -15,7 +15,7 @@ - + WEAK PASSWORD diff --git a/tests/Forms/Forms.renderer.translate.phpt b/tests/Forms/Forms.renderer.translate.phpt index d1b8b7267..f52da2bc7 100644 --- a/tests/Forms/Forms.renderer.translate.phpt +++ b/tests/Forms/Forms.renderer.translate.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; class Translator implements ITranslator { - public $counter = []; + public array $counter = []; public function translate($message, ...$parameters): string diff --git a/tests/Forms/Forms.submittedBy.phpt b/tests/Forms/Forms.submittedBy.phpt index 02fc60e3d..930d8b7b6 100644 --- a/tests/Forms/Forms.submittedBy.phpt +++ b/tests/Forms/Forms.submittedBy.phpt @@ -13,10 +13,11 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -before(function () { +setUp(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; - $_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1'; + $_COOKIE[Nette\Http\Helpers::StrictCookieName] = '1'; $_GET = $_POST = $_FILES = []; + ob_start(); Form::initialize(true); }); diff --git a/tests/Forms/Helpers.createInputList.phpt b/tests/Forms/Helpers.createInputList.phpt index 129ff988a..afe75c8e8 100644 --- a/tests/Forms/Helpers.createInputList.phpt +++ b/tests/Forms/Helpers.createInputList.phpt @@ -17,24 +17,24 @@ require __DIR__ . '/../bootstrap.php'; test('', function () { Assert::same( '', - Helpers::createInputList([]) + Helpers::createInputList([]), ); Assert::same( '', - Helpers::createInputList(['a']) + Helpers::createInputList(['a']), ); Assert::same( '', - Helpers::createInputList([1]) + Helpers::createInputList([1]), ); Assert::same( '', Helpers::createInputList( - ['a' => 'First', 'b' => 'Second'] - ) + ['a' => 'First', 'b' => 'Second'], + ), ); Assert::same( @@ -42,8 +42,8 @@ test('', function () { Helpers::createInputList( ['a' => 'First', 'b' => 'Second'], ['type' => 'checkbox'], - ['class' => 'button'] - ) + ['class' => 'button'], + ), ); Assert::same( @@ -58,8 +58,8 @@ test('', function () { [ 'class:' => ['a' => ['class1', 'class2']], 'style' => ['color' => 'blue'], - ] - ) + ], + ), ); Assert::same( @@ -68,8 +68,8 @@ test('', function () { ['a' => 'First', 'b' => 'Second'], null, null, - '
' - ) + '
', + ), ); Assert::same( @@ -78,8 +78,8 @@ test('', function () { ['a' => 'First', 'b' => 'Second'], null, null, - Html::el('div') - ) + Html::el('div'), + ), ); Assert::same( @@ -88,7 +88,7 @@ test('', function () { ['a' => 'First', 'b' => 'Second'], null, null, - Html::el(null) - ) + Html::el(null), + ), ); }); diff --git a/tests/Forms/Helpers.createSelectBox.phpt b/tests/Forms/Helpers.createSelectBox.phpt index fe61a3b1f..a9609d092 100644 --- a/tests/Forms/Helpers.createSelectBox.phpt +++ b/tests/Forms/Helpers.createSelectBox.phpt @@ -17,24 +17,24 @@ require __DIR__ . '/../bootstrap.php'; test('', function () { Assert::type( Html::class, - Helpers::createSelectBox([]) + Helpers::createSelectBox([]), ); Assert::same( '', - (string) Helpers::createSelectBox([]) + (string) Helpers::createSelectBox([]), ); Assert::same( '', - (string) Helpers::createSelectBox(['a']) + (string) Helpers::createSelectBox(['a']), ); Assert::same( '', (string) Helpers::createSelectBox( - ['a' => 'First', 'b' => 'Second'] - ) + ['a' => 'First', 'b' => 'Second'], + ), ); Assert::same( @@ -43,8 +43,8 @@ test('', function () { [ 'a' => 'First', 'Group' => ['A', 'B'], - ] - ) + ], + ), ); Assert::same( @@ -53,8 +53,8 @@ test('', function () { [ 'a' => Html::el('', 'Hello')->id('item-a'), 'Group' => [Html::el('', 'World')->id('item-b')], - ] - ) + ], + ), ); Assert::same( @@ -67,16 +67,16 @@ test('', function () { 'title' => 'Hello', 'style' => ['color' => 'blue'], 'a' => 'b', - ] - ) + ], + ), ); Assert::same( '', (string) Helpers::createSelectBox( ['a' => 'First', 'b' => 'Second'], - ['disabled:' => true, 'selected?' => 'b'] - ) + ['disabled:' => true, 'selected?' => 'b'], + ), ); Assert::same( @@ -84,8 +84,8 @@ test('', function () { (string) Helpers::createSelectBox( ['a' => 'First', 'b' => 'Second'], [], - 'b' - ) + 'b', + ), ); Assert::same( @@ -93,8 +93,8 @@ test('', function () { (string) Helpers::createSelectBox( [['a' => 'First'], ['a' => 'First']], [], - 'a' - ) + 'a', + ), ); Assert::same( @@ -102,8 +102,8 @@ test('', function () { (string) Helpers::createSelectBox( ['a' => 'First', 'b' => 'Second'], [], - ['a', 'b'] - ) + ['a', 'b'], + ), ); Assert::same( @@ -111,7 +111,7 @@ test('', function () { (string) Helpers::createSelectBox( [['a' => 'First'], ['a' => 'First']], [], - ['a', 'b'] - ) + ['a', 'b'], + ), ); }); diff --git a/tests/Forms/LatteRenderer.phpt b/tests/Forms/LatteRenderer.phpt index c653be0a0..02068799e 100644 --- a/tests/Forms/LatteRenderer.phpt +++ b/tests/Forms/LatteRenderer.phpt @@ -82,5 +82,5 @@ Assert::match( ', - $res + $res, ); diff --git a/tests/Forms/Rules.valid.phpt b/tests/Forms/Rules.valid.phpt index 82efe3a0b..0c085708d 100644 --- a/tests/Forms/Rules.valid.phpt +++ b/tests/Forms/Rules.valid.phpt @@ -45,9 +45,7 @@ test('', function () { test('', function () { $form = new Form; $form->addText('foo') - ->addFilter(function ($value) { - return str_replace(' ', '', $value); - }) + ->addFilter(fn($value) => str_replace(' ', '', $value)) ->addRule($form::Pattern, 'only numbers', '\d{5}'); $form['foo']->setValue('160 00'); @@ -65,9 +63,7 @@ test('', function () { $foo = $form->addText('foo'); $rules = $foo->getRules(); $rules->addFilter( - function ($value) { - return str_replace(' ', '', $value); - } + fn($value) => str_replace(' ', '', $value), ); $rules->addRule($form::Pattern, 'only numbers', '\d{5}'); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index abb911275..67c2ed86d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -12,21 +12,4 @@ Tester\Environment::setup(); -date_default_timezone_set('Europe/Prague'); - - -function before(?Closure $function = null) -{ - static $val; - if (!func_num_args()) { - return $val ? $val() : null; - } - $val = $function; -} - - -function test(string $title, Closure $function): void -{ - before(); - $function(); -} +Tester\Environment::setupFunctions(); diff --git a/tests/types/ControlsReturnTypeTest.php b/tests/types/ControlsReturnTypeTest.php new file mode 100644 index 000000000..d7ba40882 --- /dev/null +++ b/tests/types/ControlsReturnTypeTest.php @@ -0,0 +1,31 @@ + */ + public function dataFileAsserts(): iterable + { + yield from $this->gatherAssertTypes(__DIR__ . '/data/Controls.getValue().php'); + } + + + /** @dataProvider dataFileAsserts */ + public function testFileAsserts(string $assertType, string $file, mixed ...$args): void + { + $this->assertFileAsserts($assertType, $file, ...$args); + } +} + + +$testCase = new ControlsReturnTypeTest; +$testCase->run(); diff --git a/tests/types/TestCase.php b/tests/types/TestCase.php new file mode 100644 index 000000000..02f87fa4b --- /dev/null +++ b/tests/types/TestCase.php @@ -0,0 +1,28 @@ +addText('Text'); +assertType('string|null', $input->getValue()); + +$input = $form->addPassword('Password'); +assertType('string|null', $input->getValue()); + +$input = $form->addTextArea('TextArea'); +assertType('string|null', $input->getValue()); + +$input = $form->addEmail('Email'); +assertType('string|null', $input->getValue()); + +$input = $form->addInteger('Integer'); +assertType('string|null', $input->getValue()); + +$input = $form->addUpload('Upload'); +assertType('array|Nette\Http\FileUpload|null', $input->getValue()); + +$input = $form->addMultiUpload('MultiUpload'); +assertType('array|Nette\Http\FileUpload|null', $input->getValue()); + +$input = $form->addHidden('Hidden'); +assertType('string|null', $input->getValue()); + +$input = $form->addCheckbox('Checkbox'); +assertType('bool|null', $input->getValue()); + +$input = $form->addRadioList('RadioList'); +assertType('int|string|null', $input->getValue()); + +$input = $form->addCheckboxList('CheckboxList'); +assertType('array<(int|string)>', $input->getValue()); + +$input = $form->addSelect('Select'); +assertType('int|string|null', $input->getValue()); + +$input = $form->addMultiSelect('MultiSelect'); +assertType('array<(int|string)>', $input->getValue()); + +$input = $form->addSubmit('Submit'); +assertType('string|null', $input->getValue()); + +$input = $form->addButton('Button'); +assertType('string|null', $input->getValue()); + +$input = $form->addImageButton('ImageButton'); +assertType('array|null', $input->getValue()); + +$input = $form->addImage('Image'); +assertType('array|null', $input->getValue());