Filterable
Home
📦 Installation
GitHub
Home
📦 Installation
GitHub
  • Home
  • Introduction
  • Installation
  • How It Works
  • Engines

    • Invokable
    • Tree
    • Ruleset
    • Expression
  • Features

    • Header-Driven Filter Mode
  • Authorization
  • Validation
  • Sanitization

⚙️ Expression Engine

The Expression Engine is a flexible and expressive filtering engine designed to handle both flat and deeply nested filters, including relationships and their attributes.

It is ideal when you want the power of RuleSet-style syntax but also need to filter through relationships and nested relations easily.


📦 Example Request

GET /posts?filter[status]=pending&filter[author.profile.name][like]=kettasoft

This will:

  • Filter posts where status is pending
  • AND where the related author's profile name contains kettasoft

🛠️ How It Works

  • Filters are parsed from the request's filter key.

  • Each filter can be a:

    • Simple key-value pair (e.g., filter[status]=active)
    • Operator-based pair (e.g., filter[name][like]=kettasoft)
    • Nested relation filter (e.g., filter[author.profile.name]=ahmed)
  • The engine determines the filter structure and applies the corresponding query constraints.


🔧 Default Operator

If a filter doesn't specify an operator, the default operator will be used.
This default is configurable in the engine settings.

'default_operator' => '='

✅ Supported Features

  • ✅ Flat and nested filters
  • ✅ Dot notation for relationships (e.g., author.profile.name)
  • ✅ Customizable default operator
  • ✅ Whitelisting of allowed fields & relations
  • ✅ Works well with eager loading and relationship validation
  • ✅ Prevents filtering on undefined fields (optional strict mode)

✅ Allowed Fields & Relations

To avoid unauthorized or unintended access, you can configure the engine to only accept specific fields or relations:

Filterable::create()->useEngine('expression')
  ->allowdFields(['status'])
  ->allowRelations([
    'author.profile' => ['name'] // specific fields in this relation
  ])->paginate()

In strict mode, unsupported fields will be rejected with a validation error.


📌 Use Case

Post::filter($filters, ExpressionEngine::class)->get();

🧠 Internal Logic (Simplified)

  • Parse the filter array recursively.
  • Detect relationships via dot notation.
  • Resolve the relation path and apply whereHas queries for related models.
  • Build appropriate SQL queries via the Eloquent builder.
  • Use the defined or default operator.
Edit this page
Last Updated:
Contributors: Abdalrhman Emad Saad
Prev
Ruleset