Skip to content

Keep getValues() extension for nette/forms 2.x PHPDoc ArrayHash|array - #228

Open
hubipe wants to merge 1 commit into
phpstan:2.0.xfrom
hubipe:fix-getvalues-nette-forms-2
Open

hubipe wants to merge 1 commit into
phpstan:2.0.xfrom
hubipe:fix-getvalues-nette-forms-2

Conversation

@hubipe

@hubipe hubipe commented Oct 12, 2026

Copy link
Copy Markdown

#224 skips FormContainerValuesDynamicReturnTypeExtension when the PHPDoc @return of getValues() is not a supertype of object|array, assuming that

nette/forms before 3.2.9 has either no @return or @return object|array, so its users keep the current behaviour.

That holds for nette/forms 3.0 – 3.2.8, but nette/forms 2.3 and 2.4 (still allowed by "conflict": {"nette/forms": "<2.3.0"}) declare @return Nette\Utils\ArrayHash|array. Since 2.0.13 their users get array|Nette\Utils\ArrayHash for every getValues() call, including getValues(true).

This PR keeps the extension also when the PHPDoc type is exactly ArrayHash|array (checked as mutual supertypes, so a narrower override such as CustomValues|array<string, string> keeps its own PHPDoc). getUntrustedValues() doesn't exist in nette/forms 2.x, so FormContainerUntrustedValuesDynamicReturnTypeExtension is left as is.

Tests

nette/forms 2.x can't be installed next to the ^3.0 dev dependencies, so the new data file FormContainerArrayHashOrArrayValues.php overrides getValues() in a Form subclass with the nette/forms 2.x PHPDoc. It also has a subclass with a narrower @return to check that this PHPDoc is still respected.

  • Without the fix, the 4 nette/forms 2.x assertions fail with got type array|Nette\Utils\ArrayHash.
  • make lint, make tests, make phpstan and make cs pass (nette/forms 3.3.0, PHPStan 2.3.1). The type tests also pass with --prefer-lowest (nette/forms 3.2.8, PHPStan 2.2.3).
  • Also verified on a real project with nette/forms v2.4.11: getValues(TRUE) → array<string, mixed>, getValues() → Nette\Utils\ArrayHash.

nette/forms 2.3 and 2.4 describe the return type of
Container::getValues() as @return Nette\Utils\ArrayHash|array, which is
not more precise than what the extension infers either. Since 2.0.13
the extension was skipped for it and every getValues() call was typed
as array|ArrayHash, including getValues(true).

Claude-Session: https://claude.ai/code/session_01FBu2xVRvxJ4rGqBf4Mjrhy
@ondrejmirtes

Copy link
Copy Markdown
Member

Hi, why are you still using nette/forms 2.x? This has been unmaintained since around 2018...

@hubipe

hubipe commented Oct 12, 2026

Copy link
Copy Markdown
Author

@ondrejmirtes Fair point, and we know it's old. nette/forms 2.4 is part of a larger in-house projects portfolio built on the whole Nette 2.4 stack (application, DI, Latte 2.4, Kdyby Doctrine/Translation/Events/Console, nextras/forms…). Upgrading forms alone isn't possible, so moving to Nette 3 means migrating the whole platform, which we can't do right now. (We've just upgraded all of the projects in the porfolio from PHP 7.1 to 7.4, and starting process on upgrading even further to PHP 8 and Nette 3, but it is just at the beginning.)

I opened the PR because phpstan-nette still declares support for nette/forms 2.3+ ("conflict": {"nette/forms": "<2.3.0"}), and #224 changed the behaviour for those versions. If you'd rather not support 2.x anymore, raising the conflict to <3.0 would be fine with us too. That way the supported range is explicit, and we'll stay on 2.0.12 or keep a small extension of our own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants