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 Model Filter Laravel Package

lacodix/laravel-model-filter

Filter, search, and sort Eloquent models with reusable filter classes and query-string support. Includes built-in types (string, date, number, enum), relation/nested relation filtering, custom complex logic, and filter visualisation.

View on GitHub
Deep Wiki
Context7

Getting Started

This package, Laravel Model Filter, simplifies filtering Eloquent models with a fluent, chainable API. To start, install via Composer:

composer require lacodix/laravel-model-filter

Publish the config (optional):

php artisan vendor:publish --provider="Lacodix\LaravelModelFilter\LaravelModelFilterServiceProvider"

Basic usage:

use Lacodix\LaravelModelFilter\Filter;

$filtered = Model::filter(Filter::where('active', true)->orWhere('name', 'like', '%test%'));

For the new belongstomanytimeframe feature (v4.4.1+), initialize with:

$filtered = Model::filter(Filter::belongstomanytimeframe('posts', 'created_at', 'week'));

Implementation Patterns

Core Filtering Workflows

  1. Basic Filtering:
    $filter = Filter::where('status', 'published');
    Model::filter($filter);
    
  2. Complex Conditions:
    $filter = Filter::where('price', '>', 100)
        ->where('category', 'in', ['electronics', 'books'])
        ->orWhere('is_featured', true);
    
  3. Relationship Filtering:
    $filter = Filter::whereHas('author', fn($q) => $q->where('active', true));
    

New: Timeframe-Based BelongsToMany Filtering (v4.4.1)

Use the belongstomanytimeframe method to filter pivot relationships by time ranges (e.g., day, week, month):

// Filter posts created in the last week for a user
$filter = Filter::belongstomanytimeframe('posts', 'created_at', 'week');
User::filter($filter)->get();

Supported Modes:

  • day, week, month, quarter, year, or custom Carbon intervals.

Integration Tips

  • API Controllers: Combine with Laravel’s API resources for filtered responses:
    return UserResource::collection(User::filter($filter)->get());
    
  • Admin Panels: Use with Nova, Filament, or Backpack for dynamic table filtering.
  • Caching: Cache filtered results if queries are expensive:
    Cache::remember("filtered_{$filter->hash()}", now()->addHours(1), fn() =>
        Model::filter($filter)->get()
    );
    

Gotchas and Tips

Pitfalls

  1. Timezone Awareness: Timeframe filters (e.g., belongstomanytimeframe) use the system timezone by default. Explicitly set timezone in queries if needed:
    $filter->setTimezone('America/New_York');
    
  2. Pivot Table Ambiguity: For belongstomanytimeframe, ensure the pivot table’s timestamp column (e.g., created_at) matches the field name in the method call. Misalignment throws SyntaxError.
  3. Performance: Avoid deep nesting of whereHas/orWhereHas with timeframe filters—use raw SQL or subqueries for complex cases:
    $filter->whereRaw('EXISTS (
        SELECT 1 FROM post_user WHERE users.id = user_id
        AND posts.created_at > NOW() - INTERVAL 1 WEEK
    )');
    

Debugging

  • Filter Hashing: Use $filter->hash() to debug cached or repeated queries. Identical filters produce the same hash.
  • Query Logging: Enable Laravel’s query logging to inspect generated SQL:
    \DB::enableQueryLog();
    Model::filter($filter)->get();
    dd(\DB::getQueryLog());
    

Extension Points

  1. Custom Timeframe Modes: Extend the timeframe logic by publishing the config and adding a custom mode:
    // config/laravel-model-filter.php
    'timeframes' => [
        'custom' => 'custom_interval',
    ],
    
    Then implement custom_interval in a service provider.
  2. Dynamic Field Mapping: Override the default pivot table column mapping via the setPivotColumns() method:
    $filter->belongstomanytimeframe('posts', 'published_at', 'month')
        ->setPivotColumns(['user_id', 'post_id', 'custom_timestamp']);
    
  3. Macros: Add reusable filter logic via Eloquent macros:
    Model::macro('filterByRole', function ($role) {
        return $this->filter(Filter::whereHas('roles', fn($q) => $q->where('name', $role)));
    });
    

Config Quirks

  • Default Timezone: Set in config/laravel-model-filter.php:
    'timezone' => 'UTC',
    
  • Strict Mode: Enable to throw exceptions on invalid filter syntax:
    'strict' => env('FILTER_STRICT', false),
    

Pro Tips

  • Soft Deletes: Combine with withTrashed() for inclusive filtering:
    Model::withTrashed()->filter($filter)->get();
    
  • Dynamic Filter Building: Use request input to build filters dynamically:
    $filter = Filter::buildFromRequest(request()->all());
    
  • Testing: Mock filters in tests:
    $filter = \Mockery::mock(Filter::class);
    $filter->shouldReceive('apply')->andReturn($query);
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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