phpstan / phpstan-nette

Nette Framework class reflection extension for PHPStan & framework-specific rules
MIT License
100 stars 35 forks source link

Resolving BaseControl in presenter #102

Closed rootpd closed 1 year ago

rootpd commented 2 years ago

Hi,

(first of all great work with the tool; kudos)

I'm trying to meet level 2 requirements on our Nette project. In presenter we're working with Nette Form components.

The issue I'm facing is, that PHPstan doesn't recognize my form elements as BaseControl even when I think it already should.

I read https://github.com/phpstan/phpstan-nette/issues/27#issuecomment-412445961 and I got an impression, that @ondrejmirtes wanted form elements to always be a BaseControl. I can also see https://github.com/phpstan/phpstan-nette/blob/1.1.x/src/Type/Nette/FormsBaseControlDynamicReturnTypeExtension.php which seems like the thing that should handle it.

Am I just wrong here and the assumption is incorrect?

This is what I execute:

php vendor/bin/phpstan analyse --level=2 --memory-limit=1G app tests extensions
 368/368 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ -------------------------------------------------------------------------- 
  Line   extensions/mailer-module/src/Presenters/GeneratorPresenter.php            
 ------ -------------------------------------------------------------------------- 
  134    Call to an undefined method Nette\ComponentModel\IComponent::setValue().  
 ------ -------------------------------------------------------------------------- 

 ------ -------------------------------------------------------------------------- 
  Line   extensions/mailer-module/src/Presenters/ListPresenter.php                 
 ------ -------------------------------------------------------------------------- 
  419    Call to an undefined method Nette\ComponentModel\IComponent::setValue().  
  422    Call to an undefined method Nette\ComponentModel\IComponent::getValue().  
  424    Call to an undefined method Nette\ComponentModel\IComponent::getValue().  
  429    Call to an undefined method Nette\ComponentModel\IComponent::setItems().  
 ------ -------------------------------------------------------------------------- 

This is the simplified GeneratorPresenter:

<?php
declare(strict_types=1);

use Nette\Application\UI\Form;
use Remp\MailerModule\Forms\SourceTemplateFormFactory;

final class GeneratorPresenter extends BasePresenter
{
    public function createComponentMailSourceTemplateForm(): Form
    {
        $form = $this->sourceTemplateFormFactory->create(isset($this->params['id']) ? (int)$this->params['id'] : null);
        return $form;
    }

    public function handleRenderSorting($sorting): void
    {
        /** @var Form $form */
        $form = $this['mailSourceTemplateForm'];
        $form['sorting']->setValue($sorting); // <<<-------- THIS IS WHAT PHPSTAN COMPLAINS ABOUT
        //...
    }
}

Am I wrong thinking, that if PHPstan knows that the $form is of type Form, and the sorting is a form element, that it is not just IComponent, but a BaseControl?

Thanks a lot for the clarification.

lulco commented 1 year ago

It could be BaseControl, Form\Container or any other IComponent, if (let's say) 90% of your fields are BaseControl, you can create your own stub, where you override this: https://github.com/phpstan/phpstan-nette/blob/1.1.x/stubs/Forms/Container.stub#L11

rootpd commented 1 year ago

@lulco Thanks a lot, this is exactly what I needed! :)

github-actions[bot] commented 1 year ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.