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

Eloquent Filtering Laravel Package

indexzer0/eloquent-filtering

Define allowed filters on your Eloquent models and apply them from simple arrays or request data—no custom query logic. Supports complex, type-based filtering for APIs and dashboards on Laravel 10+ / PHP 8.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require indexzer0/eloquent-filtering
    php artisan eloquent-filtering:install
    
  2. Implement IsFilterable in your model:

    use IndexZer0\EloquentFiltering\Contracts\IsFilterable;
    use IndexZer0\EloquentFiltering\Traits\Filterable;
    
    class Product extends Model implements IsFilterable
    {
        use Filterable;
    
        public function allowedFilters(): AllowedFilterList
        {
            return Filter::only(
                Filter::field('name', [FilterType::EQUAL])
            );
        }
    }
    
  3. First API request usage:

    $products = Product::filter([
        [
            'target' => 'name',
            'type'   => '$eq',
            'value'  => 'TV'
        ]
    ])->get();
    

Where to Look First

  • Model definition: Check allowedFilters() method for filter configurations.
  • Request payload: Inspect incoming HTTP requests for filter arrays.
  • Documentation: Refer to available filters for supported operations.

Implementation Patterns

Common Workflows

  1. API Controller Integration:

    public function index(Request $request)
    {
        $filters = $request->input('filters', []);
        $products = Product::filter($filters)->paginate(10);
        return response()->json($products);
    }
    
  2. Dynamic Filtering with Relationships:

    public function allowedFilters(): AllowedFilterList
    {
        return Filter::only(
            Filter::field('name', [FilterType::EQUAL]),
            Filter::field('category.name', [FilterType::EQUAL]) // Nested relationship
        );
    }
    
  3. Combining Filters with Conditions:

    $filters = [
        [
            'type' => '$or',
            'filters' => [
                ['target' => 'name', 'type' => '$eq', 'value' => 'TV'],
                ['target' => 'price', 'type' => '$gt', 'value' => 100]
            ]
        ]
    ];
    
  4. Validation Layer:

    use IndexZer0\EloquentFiltering\Validation\FilterValidator;
    
    public function index(Request $request)
    {
        $validator = FilterValidator::make($request->input('filters'));
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }
        // Proceed with filtering
    }
    

Integration Tips

  • Form Requests: Use Laravel's FormRequest to validate and sanitize filter inputs.
  • Caching: Cache filtered results if queries are expensive:
    $products = Cache::remember("products_{$filterHash}", now()->addHours(1), function () use ($filters) {
        return Product::filter($filters)->get();
    });
    
  • Testing: Mock filter inputs in tests:
    $this->get('/products?filters[0][target]=name&filters[0][type]=$eq&filters[0][value]=TV');
    

Gotchas and Tips

Pitfalls

  1. Performance:

    • Avoid complex nested filters on large datasets without proper indexing.
    • Use ->select() to limit columns if full model hydration isn't needed.
  2. JSON Path Wildcards:

    • Ensure database supports JSON functions (e.g., json_length) for JSON path filters.
    • Test with ->toSql() to verify generated queries.
  3. Sorting Limitation:

    • Sorting is in early stages; prefer manual ->orderBy() for critical projects.
  4. Condition Filters:

    • $or/$and are always allowed but may require explicit definition for clarity.

Debugging

  • Query Inspection:
    $query = Product::filter($filters);
    dd($query->toSql(), $query->getBindings());
    
  • Validation Errors: Check FilterValidator for unsupported filter types or targets.

Extension Points

  1. Custom Filter Types:

    Filter::custom('custom_filter', function ($query, $value) {
        return $query->where('column', 'like', "%{$value}%");
    });
    
  2. Filter Modifiers: Extend FilterModifier to add logic like case-insensitive matching:

    Filter::field('name', [FilterType::EQUAL])
        ->modifyWith('lowercase', fn ($value) => strtolower($value));
    
  3. Global Filter Configuration: Override defaults in config/eloquent-filtering.php:

    'default_modifiers' => [
        'trim' => fn ($value) => trim($value),
    ],
    

Pro Tips

  • Document Filter Schema: Use OpenAPI/Swagger to define expected filter structures.
  • Filter Groups: Organize filters by feature (e.g., Filter::group('search', ...)).
  • Soft Deletes: Ensure allowedFilters() includes soft-deleted columns if needed:
    Filter::field('deleted_at', [FilterType::EQUAL])->when(fn () => auth()->check());
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope