Statická analýza kódu po aktualizaci knihoven na Nette 3 při lvl 5+ hlásí chyby

Spock
Člen | 8
+
0
-

Statická analýza kódu (https://github.com/…hpstan-nette) hlásí:

pro

	$form = new Form();
	...
	$form->addText('address', 'Ulice a číslo popisné:*')
			->setOption('id', 'address')
			->setOption('class', 'font-weight-bold')
			**->addConditionOn($form['transportRequest'], $form::EQUAL, true)**
			->addRule($form::FILLED, 'Zadejte vaší ulici a číslo popisné');

Chybu (možná souvisí s chybou viz níže):

Parameter #1 $control of method Nette\Forms\Controls\BaseControl::addConditionOn() expects
         Nette\Forms\IControl, Nette\ComponentModel\IComponent given.

a

pro form v komponentě (extends \Nette\Application\UI\Control)

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

Chybu:

Array (array<(callable(Nette\Forms\Form, array): void)|(callable(Nette\Forms\Form,
         Nette\Forms\ArrayHash): void)>) does not accept
         array($this(App\Components\Newsletter\NewsletterForm), 'processForm').

Nápady, proč tak najednou? (Nette/Utils mam nově na 3.0)
A jak to má být správně?

Pavel Janda
Člen | 977
+
+4
-

@Spock

1,

$transportRequestControl = $form->add.......;

$form->addText('address', 'Ulice a číslo popisné:*')
        ->setOption('id', 'address')
        ->setOption('class', 'font-weight-bold')
        **->addConditionOn($transportRequestControl, $form::EQUAL, true)**
        ->addRule($form::FILLED, 'Zadejte vaší ulici a číslo popisné');

Je tomu tak proto, že $form[‚cokoliv‘] vrací dle definice IComponent, kdežto první parametr metody addConditionOn přijímá striktněji IControl. Stačí, když tam prdneš ten formulářový prvek tak, jak jsem to zmínil výše..

2,

Mohl bys ukázat tu metodu processForm?

Spock
Člen | 8
+
0
-

ad1) Super, fachá dobře (pro ostatní konkrétněji):

		$transportRequestControl = $form->addCheckbox('transportRequest', 'Chci nabídku na dopravu (v případě vlastní dopravy odškrtněte)');
		$transportRequestControl->addCondition($form::EQUAL, true)
			->toggle('address')
			->toggle('city')
			->toggle('zip')
			->toggle('weNeedInformation')
			->toggle('deliveryPhone')
			->toggle('deliveryNote');

		$form->addText('address', 'Ulice a číslo popisné:*')
			->setOption('id', 'address')
			->setOption('class', 'font-weight-bold')
			->addConditionOn($transportRequestControl, $form::EQUAL, true)
			->addRule($form::FILLED, 'Zadejte vaší ulici a číslo popisné');

2,

Mohl bys ukázat tu metodu processForm?

	public function processForm($form)
	{
		$values = $form->getValues();

		if ($values->spamControl) {

			...

			$this->onSave($this);
		} else {
			$this->flashMessage('Objednávka/poptávka nebyla odeslána - blokováno antispamem', 'danger');
		}
	}

Editoval Spock (28. 5. 2019 9:25)

Pavel Janda
Člen | 977
+
+2
-

@Spock Zkus toto:

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

Editoval Pavel Janda (28. 5. 2019 15:05)

CZechBoY
Člen | 3608
+
0
-

pravda, s jednim parametrem ten phpdoc nepočítá :(
https://github.com/…rms/Form.php#L85

zkusim zjistit jestli se to dá nějak fixnout

Editoval CZechBoY (28. 5. 2019 12:17)

Pavel Janda
Člen | 977
+
0
-

@CZechBoY To je podle mě v pořádku. Když strict types tak strict types.. ale chápu, že jen 1 parametr by mohli lidé někdy preferovat.

Editoval Pavel Janda (28. 5. 2019 15:04)

CZechBoY
Člen | 3608
+
0
-

@PavelJanda Taky to používám s jednim parametrem na jednom projektu, akorát jsem ho ještě neupdatnul na nový nette :D

Spock
Člen | 8
+
0
-

Druhý parametr by asi nevadil, jen aby pak do budoucna nebyl deprecated. :-)

Nicméně to stejně háže:

 Line   app/Components/Checkout/CheckoutForm.php
------ ------------------------------------------------------------------------------------
 177    Array (array<(callable(Nette\Forms\Form, array): void)|(callable(Nette\Forms\Form,
        Nette\Forms\ArrayHash): void)>) does not accept
        array($this(App\Components\Checkout\CheckoutForm), 'processForm').
use Nette\Forms\Form;
use Nette\Utils\ArrayHash;

		...

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

		return $form;
	}

	public function processForm(Form $form, ArrayHash $values): void
	{
		//$values = $form->getValues();

		if ($values->spamControl) {

			...

Pokud použiji dle docu Nette\Forms\ArrayHash:

	public function processForm(Form $form, \Nette\Forms\ArrayHash $values): void

Hodí to prozměnu:

 Line   app/Components/Checkout/CheckoutForm.php
------ ---------------------------------------------------------------------------------------------
 181    Parameter $values of method App\Components\Checkout\CheckoutForm::processForm() has invalid
        typehint type Nette\Forms\ArrayHash.
 185    Access to property $spamControl on an unknown class Nette\Forms\ArrayHash.
 ...    Access to property ............ on an unknown class Nette\Forms\ArrayHash.
 ...    Access to property ............ on an unknown class Nette\Forms\ArrayHash.
 ...    Access to property ............ on an unknown class Nette\Forms\ArrayHash.
 ...

Tzn krom povinného parametru tam bude chyba zřejmě v use v Forms/Form.php, kde chybí:

use Nette\Utils\ArrayHash;

Je to tak? Může to někdo opravit?
A případně udělat druhý parametr volitelný?

CZechBoY
Člen | 3608
+
0
-

lol tak to se tam dostal dobrej bug :-)
posles PR?

jiri.pudil
Nette Blogger | 1032
+
0
-

https://github.com/…rms/pull/223

A když už jsme u toho, půjde tam připsat něco, co by přidalo podporu vlastních mapped types?

class MappedValues {
	public string $name;
}

$form = new Nette\Forms\Form();
$form–>addText('name', 'Name');
$form->setMappedType(MappedValues::class);
$form->onSuccess[] = function (Form $form, MappedValues $values) {};
Array (array<(callable(Nette\Forms\Form, array): void)|(callable(Nette\Forms\Form, Nette\Utils\ArrayHash): void)>) does not accept Closure(Nette\Forms\Form, MappedValues): void.

Experimentoval jsem s callable(Form, object) nebo s class MappedValues extends ArrayHash, ale nedošel jsem k ničemu funkčnímu.

https://github.com/…s/issues/224

Editoval jiri.pudil (29. 5. 2019 12:13)