skip to Main Content

We recently started using PHPStan 1.10 at level 6 in a Laravel 10 PHP 8.2 project.
It reports a few remaining issues in the following model that I would like to fix.

class ArticlePrice extends Model
{

    protected $fillable = ['cost_type_id', 'type', 'type_id', 'amount'];

    /**
     * @var array<string> $with
     */
    protected $with = ['types'];

    /**
     * @return MorphTo
     */
    public function types(): MorphTo
    {
        return $this->morphTo('types', 'type', 'type_id');
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        if ($this->types) {
            return $this->type === Article::class ? $this->types->vdm_code : $this->types->name;
        }

        return '';
    }
}

For the types() MorphTo it reports:

phpstan: Method AppModelsEnvironmentCostTypeArticlePrice::types() 
return type with generic class IlluminateDatabaseEloquentRelationsMorphTo 
does not specify its types: TRelatedModel, TChildModel

But if I change it into MorphTo<Model, Article|Category> which reflects the actually models it could return at this point it complains about:

phpstan: Method AppModelsEnvironmentCostTypeArticlePrice::types() should return
 IlluminateDatabaseEloquentRelationsMorphTo<IlluminateDatabaseEloquentModel,
 AppModelsShopArticle|AppModelsShopCategory> 
but returns IlluminateDatabaseEloquentRelationsMorphTo<IlluminateDatabaseEloquentModel,
 AppModelsEnvironmentCostTypeArticlePrice>.

which is weird to me, since we are in ArticlePrice, this seems nonsensical to me.
It has the exact same complaint when I do <Model, Model> instead.

The other issue is that it does not understand the content of $types:

phpstan: Access to an undefined property IlluminateDatabaseEloquentModel::$name.
phpstan: Access to an undefined property IlluminateDatabaseEloquentModel::$vdm_code.

I hoped fixing the morphTo issue would fix this as well, since vdm_code and name are documented properties of their models. But I fear this would not work, so this might need a different way of fixing the issue.

In short, how can I get PHPStan to understand how my polymorphic relation works, and how do I get it to recognise properties of the polymorphic related models?

2

Answers


  1. Chosen as BEST ANSWER

    I fixed the problem with $types with a workaround by adding this to the class level docblock:

    * @property-read Article|Category|null $types
    

    This makes sure PHPStan understands the types $types can be, and the properties it can have.

    Only downside is now, I can't run ide-helper:models on this model, this would undo it.

    And this is the way I fixed the issue with the MorphTo, though its not a satisfactory solution to me. Since to me it feels like this gives the wrong information about the relation about the possible return types. It does get rid of the PHPStan issue, but I rather have be able to give the correct information.

    * @return MorphTo<Model, ArticlePrice>
    

  2. Are you using Larastan? Enabling that extension fixes a lot of issues when analysing Laravel apps with PHPStan.

    If this issue persists then it’s just a feature request / bug report you should open in Larastan.

    1. To make it understand the correct return type of morphTo method.
    2. To make it understand the types property type.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search