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

Saring Laravel Package

laraditz/saring

Saring is a simple Eloquent model filtering package for Laravel and Lumen. Add the Filterable trait to models, create per-model filter classes (e.g., UserFilter), optionally whitelist filterable fields, and call Model::filter($request->all()).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laraditz/saring
    
  2. Apply Trait: Add Filterable trait to your Eloquent model:

    use Laraditz\Saring\Filterable;
    
    class User extends Model
    {
        use Filterable;
    }
    
  3. Create Filter Class: Generate a filter class in App/Filters (e.g., UserFilter for User model):

    php artisan make:filter UserFilter
    

    (Note: The package doesn’t include a built-in Artisan command, so manually create the file.)

  4. Define Filters: Implement filter methods in UserFilter:

    namespace App\Filters;
    
    use Laraditz\Saring\Filter;
    
    class UserFilter extends Filter
    {
        public function name($value)
        {
            $this->where('name', 'LIKE', "%$value%");
        }
    }
    
  5. First Use Case: Apply filters via query builder:

    $users = User::filter(request()->all())->get();
    

    Or chain filters explicitly:

    $users = User::filter(new UserFilter)->name('John')->get();
    

Implementation Patterns

Core Workflows

  1. Request-Based Filtering: Use filter() with request input to dynamically apply filters:

    $results = Model::filter(request()->query)->get();
    

    (Assumes request keys match filter method names.)

  2. Explicit Filter Chaining: Chain filters programmatically for reusable logic:

    $activeUsers = User::filter(new UserFilter)
        ->active(true)
        ->name('Admin')
        ->get();
    
  3. Nested/Complex Filters: Combine conditions with logical operators:

    public function search($query)
    {
        $this->where(function ($q) use ($query) {
            $q->where('name', 'LIKE', "%$query%")
              ->orWhere('email', 'LIKE', "%$query%");
        });
    }
    
  4. API Resource Integration: Use in API controllers to return filtered data:

    public function index(Request $request)
    {
        return UserResource::collection(
            User::filter($request->query)->paginate()
        );
    }
    

Integration Tips

  • Validation: Validate filter inputs before applying them (e.g., using Laravel’s Validator):

    $validated = Validator::make(request()->all(), [
        'name' => 'sometimes|string|max:255',
    ])->validate();
    User::filter($validated)->get();
    
  • Caching Filters: Cache frequent filter combinations (e.g., for dashboards):

    $cached = Cache::remember('filtered_users', now()->addHours(1), function () {
        return User::filter(request()->query)->get();
    });
    
  • Filter Groups: Organize filters by context (e.g., AdminUserFilter, PublicUserFilter) and switch dynamically:

    $filter = auth()->user()->isAdmin() ? new AdminUserFilter : new PublicUserFilter;
    User::filter($filter)->get();
    
  • Lumen Compatibility: Use Input facade instead of request():

    $users = User::filter(Input::all())->get();
    

Gotchas and Tips

Pitfalls

  1. Case Sensitivity: Filter method names must match request keys exactly (e.g., name vs. Name). Fix: Normalize keys in middleware or use snake_case consistently.

  2. Missing Filter Classes: Forgetting to create the filter class (e.g., UserFilter) will throw:

    Class 'App\Filters\UserFilter' not found
    

    Fix: Ensure the class exists in App/Filters and follows <Model>Filter naming.

  3. SQL Injection Risks: Directly interpolating user input (e.g., $this->where('name', $value)) is unsafe. Fix: Use parameter binding:

    $this->where('name', 'LIKE', "%$value%"); // Safe if $value is sanitized
    
  4. Overwriting Query: Chaining filter() multiple times overwrites previous filters. Fix: Use explicit filter instances:

    // Bad: Overwrites
    User::filter(request()->query)->filter(request()->query);
    
    // Good: Chains
    User::filter(new UserFilter)->name('John')->email('test@example.com');
    
  5. Performance with Large Datasets: Complex filters (e.g., nested orWhere) can slow queries. Fix: Add database indexes or use select() to limit columns:

    User::select(['id', 'name'])->filter(...)->get();
    

Debugging

  • Log Filtered Queries: Use Laravel’s query logging to inspect generated SQL:

    DB::enableQueryLog();
    User::filter(request()->query)->get();
    dd(DB::getQueryLog());
    
  • Validate Filter Logic: Test filters in isolation:

    $filter = new UserFilter;
    $filter->name('Test');
    dd($filter->getQuery()); // Inspect the query builder
    

Extension Points

  1. Custom Filter Logic: Extend the Filter class to add reusable methods:

    namespace App\Filters;
    
    use Laraditz\Saring\Filter;
    
    class BaseFilter extends Filter
    {
        public function isActive($value)
        {
            $this->where('active', $value);
        }
    }
    
  2. Dynamic Filter Loading: Auto-load filters based on model events (e.g., booted):

    class User extends Model
    {
        use Filterable;
    
        protected static function booted()
        {
            static::addGlobalScope(new FilterScope);
        }
    }
    
  3. Filter Events: Listen for filter application (e.g., log or modify queries):

    event(new Filtering($model, $filter));
    

    (Requires custom event handling.)

  4. Filterable Attributes: Restrict filterable columns via $filterable property:

    class UserFilter extends Filter
    {
        protected $filterable = ['name', 'email']; // Only allow these
    }
    
  5. Localization: Support multi-language filters by translating values:

    public function name($value)
    {
        $translated = __($value); // Example: Translate 'Admin' to 'Administrator'
        $this->where('name', 'LIKE', "%$translated%");
    }
    
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.
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
sandermuller/package-boost-php
sandermuller/boost-core
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle