PHPStan readable macros plugin screenshot
No dark mode support
No multilingual support
Supports v5.x

PHPStan readable macros

Community

PHPStan and Larastan understand macros registered on Filament components.

Tags: Developer Tool
Supported versions:
5.x 4.x 3.x
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Happenv sp. z o.o. avatar Author: Happenv sp. z o.o.

Documentation

Filament PHPStan Macros

Latest Version Tests PHPStan Quality Total Downloads License

A PHPStan extension that makes PHPStan and Larastan understand macros registered on Filament components — TextInput, TextColumn, TextEntry, Grid, Action and everything else built on Filament's Macroable.

Filament ships its own macro trait, Filament\Support\Concerns\Macroable, instead of Laravel's Illuminate\Support\Traits\Macroable. Larastan only knows Laravel's trait, so every Filament macro call is an "undefined method" — and, as shown below, ignoring that error switches off analysis of everything chained after the macro.

// A service provider
Field::macro('translatableLabel', function (string $key): Field {
    /** @var Field $this */
    return $this->label(__("fields.{$key}"));
});

// Anywhere in the app
TextInput::make('title')->translatableLabel('title')->maxLength(100);

#Why it matters: everything after the macro goes dark

Without this package PHPStan reports every macro call as Call to an undefined method. The usual fix is an ignoreErrors entry — and that hides far more than the macro: the macro's result is unknown, so every method chained after it is no longer checked at all.

TextInput::make('title')
    ->translatableLabel('title')      // the macro — its error is ignored
    ->copyable(copyMessage: 42)       // wrong argument type
    ->maxLenght(100);                 // typo
Analysis (level 8) Reported
without this package, macro error in ignoreErrors nothing — both bugs pass
with this package Parameter $copyMessage of method TextInput::copyable() expects Closure|string|null, 42 given.
Call to an undefined method TextInput::maxLenght().

At level 9 and above the ignored macro only turns into Cannot call method copyable() on mixed for every following call — noise that tends to get ignored as well, with the same result. With this package the macro is a typed method, so the whole chain is analysed like any other Filament code.

#Key features

  • The code after a macro is checked again. No more ignoreErrors for macros — which silently switched off analysis of everything chained after them.
  • Macros become real methods for PHPStan. Parameters and return type are read from the registered closure, so a wrong argument or a misused result is reported like for any native method.
  • Fluent chains keep their type. A macro typed to return one of the caller's ancestors (e.g. Field when called on TextInput) returns static, so subclass-only methods after it are still known.
  • Filament's own lookup rules. A macro registered on the class itself wins over one registered on a parent, exactly as Filament resolves it at runtime.
  • Any callable. Closures, invokable objects and array callables registered with macro() or mixin() are all understood.
  • Zero configuration. With phpstan/extension-installer the extension registers itself; no Filament dependency is added to your production install.
  • Filament 3, 4 and 5. Tested against every major on PHP 8.3 – 8.5, with the lowest and the newest installable PHPStan 2.x.

#Requirements

Package Versions
PHP 8.3 – 8.5
PHPStan 2.1+
Filament 3, 4, 5

Macros are read from Filament at analysis time, so they must be registered when PHPStan runs. Larastan does that for you: it boots your Laravel application, which runs the service providers that register them.

#Installation

Install the package as a development dependency:

composer require --dev happenv-com/filament-phpstan-macros

With phpstan/extension-installer (Larastan setups usually have it) there is nothing else to do. Otherwise include the extension in your phpstan.neon:

includes:
    - vendor/happenv-com/filament-phpstan-macros/extension.neon

#Usage

Register macros as usual — typically in a service provider's boot() — and type the closure: its parameter and return types are what PHPStan will use.

use Filament\Forms\Components\Field;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Columns\Column;
use Filament\Tables\Columns\TextColumn;

// Fluent: typed to return an ancestor, so the chain keeps the caller's type.
Column::macro('sortableAndSearchable', function (): Column {
    /** @var Column $this */
    return $this->sortable()->searchable();
});

// Returning a value: kept as declared.
Field::macro('translationKey', function (): string {
    /** @var Field $this */
    return "fields.{$this->getName()}";
});

TextColumn::make('name')->sortableAndSearchable()->limit(50); // still a TextColumn: limit() is known
TextInput::make('title')->translationKey();                    // string

#Without Larastan

Register the macros before analysis with a bootstrap file:

parameters:
    bootstrapFiles:
        - phpstan-macros.php   # calls TextInput::macro(...) and friends

#Good to know

  • A closure without a return type is analysed as returning mixed, just like with Larastan's macros — add the return type.
  • Macros are exposed as instance methods. Calling a Filament macro statically (TextInput::myMacro()) is still reported.
  • Only Filament's Macroable is handled here; Laravel's Macroable (collections, requests, Eloquent builders, …) stays Larastan's job, so both work side by side.

#Development

composer test     # PHPStan test cases: unit tests and type inference on tests/Types/data
composer phpstan  # static analysis of the package itself (level max)
composer cs       # fix code style: composer normalize, Rector, Pint
composer ci       # everything CI checks, locally

The macros the type-inference tests analyse are registered in tests/bootstrap.php; add a case there and an assertType() to tests/Types/data/macros.php.

#Upgrading

Breaking changes and how to migrate are described in UPGRADING for every major version.

#Changelog

See CHANGELOG and GitHub releases for what has changed recently.

#Contributing

See CONTRIBUTING for details.

#Security vulnerabilities

Please review our security policy on how to report security vulnerabilities.

#Credits

#License

The MIT License (MIT). See License File for more information.


Happenv

The author

Happenv sp. z o.o. avatar Author: Happenv sp. z o.o.

Happenv is a software development company specializing in e-commerce solutions, logistics systems, and Order Management Systems (OMS). We design, build, and maintain scalable business applications that help companies streamline operations, automate workflows, and improve customer experiences. Our expertise includes custom development, system integrations, and long-term support of solutions built with Laravel and Filament, delivering reliable and efficient platforms tailored to modern commerce and logistics needs.

Plugins
9

From the same author