Skip to content

[2.x] PHPStan fails in extensions depending on flarum/tags: Flarum\Gdpr\Events\Erased not found #5194

Open

Description

@imorland

Current Behavior

Since flarum/tags 2.0.1, PHPStan fails in any extension that depends on flarum/tags but doesn't have flarum/gdpr installed:

 -1     Class Flarum\Gdpr\Events\Erased not found.
        🪪  class.notFound
 [ERROR] Found 1 error

#5158 added this to extensions/tags/extend.php:

->whenExtensionEnabled('flarum-gdpr', fn () => [
    (new Extend\Event())
        ->listen(\Flarum\Gdpr\Events\Erased::class, Listener\RefreshLastPostedDiscussionsAfterErasure::class),
]),

It's fine at runtime, since the closure only runs when GDPR is enabled. But flarum/phpstan analyses the dependency's extend.php, and the ::class reference fails when flarum/gdpr isn't installed. extensions/messages/extend.php uses the same pattern, so extensions depending on flarum/messages are affected too.

Steps to Reproduce

  1. Take an extension that requires flarum/tags and runs composer analyse:phpstan (e.g. fof/categories).
  2. composer update flarum/tags to get v2.0.1.
  3. Run PHPStan.

Expected Behavior

Optional integrations in a bundled extension's extend.php shouldn't break static analysis for extensions that depend on it.

Possible Solution

  • Reference the event by string in tags and messages ('Flarum\Gdpr\Events\Erased'). Extend\Event::listen() accepts a class name string, and PHPStan won't try to resolve it.
  • Or handle classes referenced inside whenExtensionEnabled() closures in flarum/phpstan.

Workaround for now: add flarum/gdpr to the extension's require-dev.

Additional Context

Found on FriendsOfFlarum/categories#10.

Activity

  1. self-assigned this
    on Oct 14, 2026
  2. added this to the 2.1 milestone on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions