Skip to content

Commit effaf31

Browse files
author
Abdalrhman Emad Saad
committed
docs: update docs
1 parent 5fd83f2 commit effaf31

File tree

10 files changed

+479
-681
lines changed

10 files changed

+479
-681
lines changed

docs/.vuepress/config.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default defineUserConfig({
2626
selectLanguageName: "ar",
2727
lastUpdated: true,
2828
contributors: true,
29-
contributorsText: "dasdasd",
29+
// contributorsText: "dasdasd",
3030

3131
navbar: ["/", "/installation"],
3232
sidebar: [
@@ -51,20 +51,20 @@ export default defineUserConfig({
5151
collapsible: true,
5252
children: [
5353
{
54-
text: "Dynamic method",
55-
link: "engines/dynamic-methods",
54+
text: "Invokable",
55+
link: "engines/invokable",
5656
},
5757
{
58-
text: "Tree based",
59-
link: "engines/tree-based",
58+
text: "Tree",
59+
link: "engines/tree",
6060
},
6161
{
6262
text: "Ruleset",
6363
link: "engines/rule-set",
6464
},
6565
{
66-
text: "Closure pipeline",
67-
link: "engines/closure",
66+
text: "Expression",
67+
link: "engines/expression",
6868
},
6969
],
7070
},
@@ -90,10 +90,6 @@ export default defineUserConfig({
9090
text: "Sanitization",
9191
link: "sanitization",
9292
},
93-
{
94-
text: "Configurations",
95-
link: "configurations",
96-
},
9793
],
9894
}),
9995

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Filterable::withRequest($request)
4545
->useEngine('ruleset')
4646
->setAllowedFields(['status', 'title', 'author.name'])
4747
->setRelations(['author'])
48-
->run(Post::query());
48+
->filter(Post::query());
4949
```
5050

5151
## 🧪 Tested & Production-Ready

docs/configurations.md

Lines changed: 0 additions & 204 deletions
This file was deleted.

docs/engines/expression.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# ⚙️ Expression Engine
2+
3+
The **Expression Engine** is a flexible and expressive filtering engine designed to handle both flat and deeply nested filters, including relationships and their attributes.
4+
5+
It is ideal when you want the power of RuleSet-style syntax but also need to filter through relationships and nested relations easily.
6+
7+
---
8+
9+
## 📦 Example Request
10+
11+
```http
12+
GET /posts?filter[status]=pending&filter[author.profile.name][like]=kettasoft
13+
```
14+
15+
This will:
16+
17+
- Filter posts where `status` is `pending`
18+
- AND where the related author's profile `name` contains `kettasoft`
19+
20+
---
21+
22+
## 🛠️ How It Works
23+
24+
- Filters are parsed from the request's `filter` key.
25+
- Each filter can be a:
26+
27+
- Simple key-value pair (e.g., `filter[status]=active`)
28+
- Operator-based pair (e.g., `filter[name][like]=kettasoft`)
29+
- Nested relation filter (e.g., `filter[author.profile.name]=ahmed`)
30+
31+
- The engine determines the filter structure and applies the corresponding query constraints.
32+
33+
---
34+
35+
## 🔧 Default Operator
36+
37+
If a filter doesn't specify an operator, the **default operator** will be used.
38+
This default is configurable in the engine settings.
39+
40+
```php
41+
'default_operator' => '='
42+
```
43+
44+
---
45+
46+
## ✅ Supported Features
47+
48+
- ✅ Flat and nested filters
49+
- ✅ Dot notation for relationships (e.g., `author.profile.name`)
50+
- ✅ Customizable default operator
51+
- ✅ Whitelisting of allowed fields & relations
52+
- ✅ Works well with eager loading and relationship validation
53+
- ✅ Prevents filtering on undefined fields (optional strict mode)
54+
55+
---
56+
57+
## ✅ Allowed Fields & Relations
58+
59+
To avoid unauthorized or unintended access, you can configure the engine to only accept specific fields or relations:
60+
61+
```php
62+
Filterable::create()->useEngine('expression')
63+
->allowdFields(['status'])
64+
->allowRelations([
65+
'author.profile' => ['name'] // specific fields in this relation
66+
])->paginate()
67+
```
68+
69+
In **strict mode**, unsupported fields will be rejected with a validation error.
70+
71+
---
72+
73+
## 📌 Use Case
74+
75+
```php
76+
Post::filter($filters, ExpressionEngine::class)->get();
77+
```
78+
79+
---
80+
81+
## 🧠 Internal Logic (Simplified)
82+
83+
- Parse the `filter` array recursively.
84+
- Detect relationships via dot notation.
85+
- Resolve the relation path and apply `whereHas` queries for related models.
86+
- Build appropriate SQL queries via the Eloquent builder.
87+
- Use the defined or default operator.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
sidebarDepth: 2
33
---
44

5-
# Dynamic Method Engine
5+
# Invokable Engine
66

7-
The **Dynamic Method Engine** provides a powerful way to dynamically map incomming reuqest parameters to corresponding methods in a filter class. This mechanism enables clean, scalable filtering logic and behavior injection without requiring large **switch** or **if-else** blocks.
7+
The **Invokable Engine** provides a powerful way to dynamically map incomming reuqest parameters to corresponding methods in a filter class. This mechanism enables clean, scalable filtering logic and behavior injection without requiring large **switch** or **if-else** blocks.
88

99
---
1010

0 commit comments

Comments
 (0)