-
Notifications
You must be signed in to change notification settings - Fork 75
Support static calls to #[Scope] attribute methods #634
Description
Problem
When a model method has the #[Scope] attribute, Laravel handles static calls via Model::__callStatic() → query() → Builder::__call() → callNamedScope(). So Post::popular() works at runtime.
However, Psalm sees popular() as a real instance method and reports InvalidStaticInvocation before any plugin handler gets a chance to intercept. This is a false positive.
#[Scope]
public function popular(Builder $query): void { ... }
Post::popular(); // ❌ InvalidStaticInvocation — works at runtime
Post::query()->popular(); // ✅ Fixed in #633Legacy scopes (scopeActive → Post::active()) work because active() doesn't exist as a real method — the plugin's existence handler confirms it. #[Scope] methods are different because they exist as real instance methods.
Suggested fix
Implement BeforeAddIssueInterface to suppress InvalidStaticInvocation for #[Scope] methods on Model subclasses. The detection logic already exists in BuilderScopeHandler::hasScopeMethod().
~40 lines in a new handler + registration in Plugin.php + test updates.
Context
Discovered during #633. Currently documented as a known limitation in both CustomQueryBuilderTest.phpt and ModelStaticBuilderMethodsTest.phpt.