phpstan-nette icon indicating copy to clipboard operation
phpstan-nette copied to clipboard

Form events errors

Open martenb opened this issue 4 years ago • 3 comments

Hi, i have problems with latest nette/forms and phpstan 1.0.. i will describe it on presenter, but same errors are in control...

<?php declare(strict_types = 1);

namespace App\Presenters;

use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nette\Utils\ArrayHash;

final class HomepagePresenter extends Presenter
{

	protected function createCompomentForm(): Form
	{
		$form = new Form();
		$form->onSuccess[] = function (Form $form, ArrayHash $values): void {

		};
		$form->onSuccess[] = [$this, 'formOnSuccess'];

		return $form;
	}

	public function formOnSuccess(Form $form, ArrayHash $values): void
	{

	}

}
 ------ ---------------------------------------------------------------------------------
  Line   Presenters/HomepagePresenter.php
 ------ ---------------------------------------------------------------------------------
  15     Array (array<callable(Nette\Application\UI\Form, mixed): void>) does not accept
         Closure(Nette\Application\UI\Form, Nette\Utils\ArrayHash): void.
  18     Array (array<callable(Nette\Application\UI\Form, mixed): void>) does not accept
         array{$this(App\Presenters\HomepagePresenter), 'formOnSuccess'}.
 ------ ---------------------------------------------------------------------------------

martenb avatar Nov 03 '21 06:11 martenb

Given the types from the stub: https://github.com/phpstan/phpstan-nette/blob/f4654b27b107241e052755ec187a0b1964541ba6/stubs/Forms/Form.stub#L8-L9

	/** @var array<callable(static, mixed): void> */
	public $onSuccess;

this is expected behaviour by PHPStan. Because you're narrowing down the type of the second parameter from mixed to ArrayHash.

I understand that Nette contains some magic (https://github.com/nette/forms/blob/0f0c770db65ce2a18fc766b8b718b53e081ac8e2/src/Forms/Form.php#L424-L442) that will prevent this bug from happening. But PHPStan currently doesn't have the facilities to describe this behaviour, so feel free to just ignore the error: https://phpstan.org/user-guide/ignoring-errors

ondrejmirtes avatar Nov 03 '21 13:11 ondrejmirtes

I just noticed this with Container::onValidate – the property is expected to contain array<callable(static, T): void|callable(static, array): void|callable(T): void|callable(array): void> where T can be any object type but that is not expressible in PHPStan type language since containers like arrays are invariant in their item template types.

Would changing the stubs to just array<callable> and adding specific rules as a replacement be acceptable?

Comparison of the various type signatures: https://phpstan.org/r/a8969a90-ac6f-47f6-b11f-8df10e8f7e95

jtojnar avatar Feb 24 '23 10:02 jtojnar

@martenb I solved this with a custom Form class:

/** @property array<callable(self, \Nette\Utils\ArrayHash $values): void> $onSuccess */
class Form extends \Nette\Application\UI\Form
{}

uestla avatar Mar 03 '23 10:03 uestla