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

Laravel Global Scope Laravel Package

sofa/laravel-global-scope

Deprecated: Laravel 5.2+ changed global scopes, so this package is no longer valid. For Laravel 5.0–5.1, it provides an abstract Eloquent GlobalScope to define scopes via apply() and makes removing scopes from queries easier.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require sofa/laravel-global-scope:0.1@dev
    

    (Note: This package is outdated for Laravel 5.2+ but remains useful for legacy projects.)

  2. Define a Global Scope: Extend the provided Sofa\Eloquent\GlobalScope abstract class and implement the apply() method:

    namespace App\Scopes;
    
    use Sofa\Eloquent\GlobalScope;
    
    class PublishedScope extends GlobalScope
    {
        public function apply($builder)
        {
            $builder->where('published_at', '<=', now());
        }
    }
    
  3. Register the Scope: Attach the scope to your model in the boot() method:

    namespace App\Models;
    
    use App\Scopes\PublishedScope;
    use Sofa\Eloquent\GlobalScope as BaseGlobalScope;
    
    class Post extends Model
    {
        protected static function boot()
        {
            parent::boot();
            static::addGlobalScope(new PublishedScope());
        }
    }
    
  4. First Use Case: Query the model—all results will automatically apply the scope:

    $posts = Post::all(); // Only returns published posts
    

Implementation Patterns

Usage Patterns

  1. Conditional Scopes: Implement logic to conditionally apply scopes (e.g., based on user roles):

    public function apply($builder)
    {
        if (auth()->user()->isAdmin()) {
            return; // Skip scope for admins
        }
        $builder->where('is_active', true);
    }
    
  2. Dynamic Constraints: Use helper methods to encapsulate reusable query logic:

    public function apply($builder)
    {
        $this->scopeActive($builder);
    }
    
    protected function scopeActive($builder)
    {
        $builder->where('active', true);
    }
    
  3. Macro Integration: Extend Eloquent’s query builder with macros for cleaner syntax:

    public function apply($builder)
    {
        $builder->macro('published', function($builder) {
            return $builder->where('published_at', '<=', now());
        });
    }
    
  4. Scope Removal: Temporarily disable the scope using withoutGlobalScopes():

    $allPosts = Post::withoutGlobalScopes()->get(); // Bypasses all global scopes
    
  5. Model-Specific Scopes: Group scopes by model (e.g., UserScope, PostScope) in a Scopes directory for organization.

Workflows

  • Development: Use withoutGlobalScopes() in tests to isolate query logic:

    $this->assertCount(10, Post::withoutGlobalScopes()->get());
    
  • Production: Leverage scopes for default query constraints (e.g., soft deletes, tenant isolation).

  • APIs: Apply scopes dynamically based on request data (e.g., ?include=archived).

Integration Tips

  • Soft Deletes: Combine with Laravel’s built-in SoftDeletes trait for unified soft-delete logic:

    class Post extends Model
    {
        use SoftDeletes;
        protected $dates = ['deleted_at', 'published_at'];
    
        protected static function boot()
        {
            parent::boot();
            static::addGlobalScope(new PublishedScope());
        }
    }
    
  • Tenancy: Use scopes for multi-tenant applications (e.g., TenantScope):

    class TenantScope extends GlobalScope
    {
        public function apply($builder)
        {
            $builder->where('tenant_id', auth()->user()->tenant_id);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Laravel 5.2+ Incompatibility: Native global scopes in Laravel 5.2+ replace this package’s need. Avoid using it in new projects.

  2. Scope Order: Scopes are applied in the order they are registered. Reorder with addGlobalScope() or withoutGlobalScopes():

    // Wrong: Scopes may override each other unexpectedly.
    static::addGlobalScope(new ScopeA());
    static::addGlobalScope(new ScopeB());
    
    // Better: Explicitly control order.
    
  3. Performance: Overly complex apply() methods can bloat queries. Test with DB::enableQueryLog():

    DB::enableQueryLog();
    Post::all();
    dd(DB::getQueryLog());
    
  4. Caching: Global scopes affect cached queries. Clear caches after modifying scopes:

    php artisan cache:clear
    php artisan view:clear
    

Debugging

  • Query Inspection: Use toSql() and getBindings() to debug scope logic:

    $query = Post::query();
    dd($query->toSql(), $query->getBindings());
    
  • Scope Isolation: Test scopes in isolation with withoutGlobalScopes():

    $query = Post::withoutGlobalScopes()->where(...);
    

Config Quirks

  • No Built-in Config: The package has no configuration file. All logic is in the apply() method.

  • Namespace Conflicts: Ensure your GlobalScope class is namespaced to avoid collisions with Laravel’s native GlobalScope.

Extension Points

  1. Custom Scope Logic: Extend the abstract class to add pre/post-apply hooks:

    abstract class CustomGlobalScope extends GlobalScope
    {
        protected function beforeApply($builder) {}
        protected function afterApply($builder) {}
    }
    
  2. Scope Metadata: Add metadata (e.g., priority, description) to scopes:

    class PublishedScope extends GlobalScope
    {
        public static $priority = 10;
        public static $description = 'Filters unpublished posts';
    }
    
  3. Dynamic Scope Registration: Register scopes dynamically based on environment or user context:

    if (app()->environment('staging')) {
        static::addGlobalScope(new StagingScope());
    }
    
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.
amashukov/lnd-client-php
althinect/enum-permission
andydefer/laravel-actions
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor