Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,6 @@ parameters:
message: '#^Parameter \#1 \$returnType of method Nette\\Forms\\Container::(getValues|getUntrustedValues)\(\) expects#'
path: src/Forms/Container.php

- # Complex template type T cannot be fully tracked through getValues delegation
message: '#^Method Nette\\Forms\\Container::getValues\(\) should return#'
path: src/Forms/Container.php
count: 1

-
message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
Expand Down
2 changes: 1 addition & 1 deletion src/Bridges/FormsDI/FormsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FormsExtension extends Nette\DI\CompilerExtension
public function __construct()
{
$this->config = new class {
/** @var string[] */
/** @var array<string, string> */
public array $messages = [];
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/Bridges/FormsLatte/Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
class Runtime
{
/** @var Container[] */
/** @var list<Container> */
private array $stack = [];

/** @var list<?string> parallel to $stack; non-null element = id of a detached form */
Expand All @@ -28,7 +28,7 @@ class Runtime
/** @var list<bool> parallel to $stack; true = scope the template's $form variable was bound to */
private array $formBindings = [];

/** @var Nette\Forms\Repeater[] */
/** @var list<Nette\Forms\Repeater> */
private array $repeaters = [];


Expand Down
12 changes: 7 additions & 5 deletions src/Forms/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
* @property-read string $name
* @property ArrayHash<mixed> $values
* @property-read \Iterator $controls
* @property-read \Iterator<string,Control> $controls
* @property-read ?Form $form
* @implements \ArrayAccess<string|int, Nette\ComponentModel\IComponent>
*/
Expand Down Expand Up @@ -118,7 +118,7 @@ public function setValues(array|object $values, bool $erase = false, bool $onlyD
* @template T of object
* @param class-string<T>|T|'array'|null $returnType
* @param ?list<Control|self> $controls
* @return ($returnType is class-string<T>|T ? T : ($returnType is 'array' ? mixed[] : ArrayHash<mixed>))
* @return ($returnType is 'array' ? array<int|string, mixed> : ($returnType is class-string<T>|T ? T : ArrayHash<mixed>))
*/
public function getValues(string|object|null $returnType = null, ?array $controls = null): object|array
{
Expand Down Expand Up @@ -154,7 +154,7 @@ public function getValues(string|object|null $returnType = null, ?array $control
* @template T of object
* @param class-string<T>|T|'array'|null $returnType
* @param ?list<Control|self> $controls
* @return ($returnType is class-string<T>|T ? T : ($returnType is 'array' ? mixed[] : ArrayHash<mixed>))
* @return ($returnType is 'array' ? array<int|string, mixed> : ($returnType is class-string<T>|T ? T : ArrayHash<mixed>))
*/
public function getUntrustedValues(string|object|null $returnType = null, ?array $controls = null): object|array
{
Expand Down Expand Up @@ -356,13 +356,15 @@ public function addComponent(

/**
* Iterates over all form controls including nested. Keys are control names and are not unique across containers.
* @return iterable<Control>
* @return iterable<string, Control>
*/
public function getControls(): iterable
{
foreach ($this->getComponentTree() as $component) {
if ($component instanceof Control) {
yield $component->getName() => $component;
$name = $component->getName();
assert($name !== null);
yield $name => $component;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/Controls/BaseControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* @property-read Html $labelPrototype
* @property bool $required
* @property-deprecated bool $filled
* @property-read string[] $errors
* @property-read list<string|Stringable> $errors
* @property-deprecated array<string,mixed> $options
* @property-read string $error
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/Controls/UploadControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function setValue(mixed $value): static

/**
* Returns the uploaded file(s), a dummy FileUpload(null) when nothing was uploaded, or null when nullable is set.
* @return FileUpload|FileUpload[]|null
* @return FileUpload|list<FileUpload>|null
*/
public function getValue(): FileUpload|array|null
{
Expand Down
4 changes: 2 additions & 2 deletions src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
* by default the form reads its own HTTP request (standalone usage), inside Nette Application
* use Nette\Application\UI\Form, other sources are set via setSubmissionSource().
*
* @property-read string[] $errors
* @property-read array<string|Stringable> $ownErrors
* @property-read list<string|Stringable> $errors
* @property-read list<string|Stringable> $ownErrors
* @property-read Html $elementPrototype
* @property-deprecated FormRenderer $renderer
* @property-deprecated string $action
Expand Down
28 changes: 26 additions & 2 deletions tests/types/forms-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ class FormDto
function testFormContainerGetValues(Container $container): void
{
assertType('Nette\Utils\ArrayHash<mixed>', $container->getValues());
assertType('array|array<mixed>', $container->getValues('array'));
assertType('array<int|string, mixed>', $container->getValues('array'));
assertType('array<int|string, mixed>', $container->getValues(Container::Array));
assertType(FormDto::class, $container->getValues(FormDto::class));
assertType('array<int|string, mixed>|Nette\Utils\ArrayHash<mixed>', $container->getValues(rand() ? 'array' : null));
assertType('array<int|string, mixed>|FormDto', $container->getValues(rand() ? 'array' : FormDto::class));
}


function testFormContainerGetUntrustedValues(Container $container): void
{
assertType('Nette\Utils\ArrayHash<mixed>', $container->getUntrustedValues());
assertType('array|array<mixed>', $container->getUntrustedValues('array'));
assertType('array<int|string, mixed>', $container->getUntrustedValues('array'));
assertType(FormDto::class, $container->getUntrustedValues(FormDto::class));
}

Expand Down Expand Up @@ -64,3 +67,24 @@ function testFormGetSubmittedData(Form $form, Nette\Forms\Container $container):
assertType('array<mixed>', $form->getSubmittedData());
assertType('array<mixed>', $container->getSubmittedData());
}


function testFormContainerControls(Container $container): void
{
assertType('Iterator<string, Nette\Forms\Control>', $container->controls);
assertType('iterable<string, Nette\Forms\Control>', $container->getControls());
}


function testFormErrors(Form $form, Nette\Forms\Controls\TextInput $input): void
{
assertType('list<string|Stringable>', $form->errors);
assertType('list<string|Stringable>', $form->ownErrors);
assertType('list<string|Stringable>', $input->errors);
}


function testUploadControlGetValue(Nette\Forms\Controls\UploadControl $upload): void
{
assertType('list<Nette\Http\FileUpload>|Nette\Http\FileUpload|null', $upload->getValue());
}
Loading