Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Plugin Laravel Laravel Package

psalm/plugin-laravel

Laravel Psalm plugin for deep static analysis plus taint-based security scanning. Detects SQL injection, XSS, SSRF, shell injection, path traversal, and open redirects by tracking user input through Laravel code without running it.

View on GitHub
Deep Wiki
Context7

title: PublicModelScope parent: Custom Issues nav_order: 8

PublicModelScope

A public #[Scope]-attributed Eloquent query scope. Laravel's convention is protected. Enabled by default; see How to disable.

Why it matters

A public #[Scope] is a runtime hazard, not just a convention slip. A static call such as Post::published() fatals, because PHP resolves the accessible non-static method before __callStatic can forward it to the query builder (see #634 and vimeo/psalm#11876). Keeping it protected leaves the static call routed to the builder.

Reported as an error at project error levels 1 to 4, the range most analysis-serious codebases use; downgraded at looser levels (5 to 8). A scope whose visibility is forced by a contract (an interface method, a parent override, or an abstract trait method) is not reported, since it cannot be narrowed.

Legacy scopeXxx() scopes are not reported at all: public is Laravel's documented idiom for them, and their $builder->active() dispatch is unaffected by visibility, so there is nothing to flag. Only the #[Scope] form, whose static call is a genuine runtime fatal, is checked.

Example

class Post extends Model
{
    #[Scope]
    protected function published(Builder $query): Builder // public here would be reported
    {
        return $query->whereNotNull('published_at');
    }
}

How to fix

Change public to protected. Call sites are unaffected.

How to disable

<issueHandlers>
    <PluginIssue name="PublicModelScope" errorLevel="suppress" />
</issueHandlers>

private is intentionally not flagged; a private #[Scope] is rejected by Laravel and surfaces elsewhere.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony