Skip to content

Commit 6929dc3

Browse files
authored
Merge pull request #12 from kettasoft/2.2.0
Add Sorting Feature to Filterable
2 parents 285d65d + 81ec485 commit 6929dc3

File tree

9 files changed

+1717
-1
lines changed

9 files changed

+1717
-1
lines changed

config/filterable.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,117 @@
7272
*/
7373
'default_engine' => 'invokable',
7474

75+
/*
76+
|--------------------------------------------------------------------------
77+
| Sorting
78+
|--------------------------------------------------------------------------
79+
|
80+
| Configure the sorting behavior for filterable queries.
81+
| You can control which fields are allowed, define default sorting,
82+
| set aliases (presets), and customize how multiple sorts are handled.
83+
|
84+
*/
85+
'sorting' => [
86+
87+
/*
88+
|--------------------------------------------------------------------------
89+
| Default Request Key
90+
|--------------------------------------------------------------------------
91+
|
92+
| The query string key to look for filter inputs automatically from requests.
93+
| Example: /posts?sort=-created_at,name
94+
|
95+
*/
96+
'sort_key' => 'sort',
97+
98+
/*
99+
|--------------------------------------------------------------------------
100+
| Allowed Fields
101+
|--------------------------------------------------------------------------
102+
|
103+
| Define which fields are allowed for sorting.
104+
| Example: ['id', 'name', 'created_at']
105+
|
106+
*/
107+
'allowed' => [],
108+
109+
/*
110+
|--------------------------------------------------------------------------
111+
| Default Sorting
112+
|--------------------------------------------------------------------------
113+
|
114+
| Define a default sorting order if none is provided by the request.
115+
| Format: ['field', 'direction']
116+
| Example: ['created_at', 'desc']
117+
|
118+
*/
119+
'default' => null,
120+
121+
/*
122+
|--------------------------------------------------------------------------
123+
| Aliases
124+
|--------------------------------------------------------------------------
125+
|
126+
| Define shortcuts (aliases) for common sorting orders.
127+
| Example:
128+
| 'aliases' => [
129+
| 'recent' => [['created_at', 'desc']],
130+
| 'popular' => [['views', 'desc'], ['likes', 'desc']],
131+
| ],
132+
|
133+
*/
134+
'aliases' => [],
135+
136+
/*
137+
|--------------------------------------------------------------------------
138+
| Multi-Sorting
139+
|--------------------------------------------------------------------------
140+
|
141+
| Enable or disable multiple sorting fields in the same request.
142+
|
143+
*/
144+
'multi_sort' => true,
145+
146+
/*
147+
|--------------------------------------------------------------------------
148+
| Delimiter
149+
|--------------------------------------------------------------------------
150+
|
151+
| The delimiter used to separate multiple sorting fields in a request.
152+
| Example: ?sort=name,-created_at
153+
| With delimiter = ',' → "name,-created_at"
154+
|
155+
*/
156+
'delimiter' => ',',
157+
158+
/*
159+
|--------------------------------------------------------------------------
160+
| Direction Map
161+
|--------------------------------------------------------------------------
162+
|
163+
| Define how sorting directions are interpreted.
164+
| Example:
165+
| '-' prefix means descending, no prefix = ascending.
166+
|
167+
*/
168+
'direction_map' => [
169+
'asc' => 'asc',
170+
'desc' => 'desc',
171+
'prefix' => '-', // "-field" = desc
172+
],
173+
174+
/*
175+
|--------------------------------------------------------------------------
176+
| Nulls Position
177+
|--------------------------------------------------------------------------
178+
|
179+
| Decide how to handle NULL values in sorting.
180+
| Supported: 'first', 'last', or null (database default).
181+
|
182+
*/
183+
'nulls_position' => null,
184+
],
185+
75186
/*
76187
|--------------------------------------------------------------------------
77188
| Filter Engines

docs/.vuepress/config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,20 @@ export default defineUserConfig({
117117
text: "Payload",
118118
link: "api/payload",
119119
},
120+
{
121+
text: "Sorter",
122+
link: "api/sorter",
123+
},
120124
],
121125
},
122126
{
123127
text: "Profiler",
124128
link: "profiler",
125129
},
130+
{
131+
text: "Sorting",
132+
link: "sorting",
133+
},
126134
{
127135
text: "Authorization",
128136
link: "authorization",

docs/api/sorter.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Sorter
2+
3+
The **Sorter** class provides functionality to manage and apply sorting rules to Eloquent queries.
4+
It simplifies the process of sorting models by accepting parameters like field names, directions, aliases, and default sorting. You can also customize the sorting behavior, including handling nulls and multi-field sorting.
5+
6+
---
7+
8+
### Overview
9+
10+
The **Sorter** class allows developers to configure sorting behavior on Eloquent queries based on user input. You can define allowed sortable fields, set default sorting, create sorting aliases (presets), and customize sorting behaviors such as handling null values and multi-field sorting.
11+
12+
```php
13+
$sorter = new Sorter($request);
14+
$sorter->allow(['title', 'created_at'])
15+
->setSortKey('sort')
16+
->setDelimiter(',')
17+
->setNullsPosition('last')
18+
->apply($query);
19+
```
20+
21+
---
22+
23+
### Properties
24+
25+
| Property | Type | Description |
26+
| ------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------ |
27+
| `$allowed` | `array<int, string>` | List of allowed fields for sorting. |
28+
| `$default` | `array{0: string, 1: string} or null` | Default sorting field and direction (e.g., `['created_at', 'desc']`). |
29+
| `$aliases` | `array<string, array<int, array{0: string, 1: string}>>` | Aliases for sorting presets (e.g., `['recent' => [['created_at', 'desc']]]`). |
30+
| `$map` | `array<string, string>` | Field mapping for input to database columns (e.g., `['name' => 'full_name']`). |
31+
| `$config` | `\Illuminate\Support\Collection` | Configuration settings for the sorter. |
32+
| `$sortKey` | `string` | The key used for sorting in the request (e.g., `sort`). |
33+
| `$delimiter` | `string` | Delimiter used for multi-field sorting (e.g., `,`). |
34+
35+
---
36+
37+
### Public Methods
38+
39+
---
40+
41+
#### `__construct(Request $request, array|null $config = null)`
42+
43+
Creates a new Sorter instance. Optionally accepts a configuration array.
44+
45+
```php
46+
$sorter = new Sorter($request, $config);
47+
```
48+
49+
---
50+
51+
#### `static make(Request $request, array|null $config = null): self`
52+
53+
Static factory method to create a new Sorter instance.
54+
55+
```php
56+
$sorter = Sorter::make($request);
57+
```
58+
59+
---
60+
61+
#### `map(array $fields): self`
62+
63+
Maps input fields to database columns.
64+
65+
```php
66+
$sorter->map(['name' => 'full_name']);
67+
```
68+
69+
---
70+
71+
#### `getFieldMapping(string $field): string`
72+
73+
Gets the mapped database column for a given input field.
74+
75+
```php
76+
$column = $sorter->getFieldMapping('name');
77+
```
78+
79+
---
80+
81+
#### `allow(array $fields): self`
82+
83+
Defines which fields are allowed for sorting.
84+
85+
```php
86+
$sorter->allow(['title', 'created_at']);
87+
```
88+
89+
---
90+
91+
#### `allowAll(): self`
92+
93+
Allows sorting on all fields (use with caution, may expose sensitive fields).
94+
95+
```php
96+
$sorter->allowAll();
97+
```
98+
99+
---
100+
101+
#### `default(string $field, string $direction = 'asc'): self`
102+
103+
Defines a default sorting field and direction.
104+
105+
```php
106+
$sorter->default('created_at', 'desc');
107+
```
108+
109+
---
110+
111+
#### `defaults(array{0: string, 1: string} $defaults): self`
112+
113+
Defines default sorting using an array.
114+
115+
```php
116+
$sorter->defaults(['created_at', 'desc']);
117+
```
118+
119+
---
120+
121+
#### `alias(string $name, array $sorting): self`
122+
123+
Defines a sorting alias (preset).
124+
125+
```php
126+
$sorter->alias('popular', [['views', 'desc'], ['likes', 'desc']]);
127+
```
128+
129+
---
130+
131+
#### `aliases(array<string, array<int, array{0: string, 1: string}>> $aliases): self`
132+
133+
Defines multiple sorting aliases (presets).
134+
135+
```php
136+
$sorter->aliases([
137+
'popular' => [['views', 'desc'], ['likes', 'desc']],
138+
'recent' => [['created_at', 'desc']],
139+
]);
140+
```
141+
142+
---
143+
144+
#### `setSortKey(string $key): self`
145+
146+
Sets the key used for sorting in the request.
147+
148+
```php
149+
$sorter->setSortKey('order');
150+
```
151+
152+
---
153+
154+
#### `setDelimiter(string $delimiter): self`
155+
156+
Sets the delimiter used for multi-field sorting.
157+
158+
```php
159+
$sorter->setDelimiter(',');
160+
```
161+
162+
---
163+
164+
#### `setNullsPosition(string|null $position = null): self`
165+
166+
Sets the position of null values in sorting.
167+
168+
- Accepts: `'first'`, `'last'`, or `null` for default DB behavior.
169+
170+
```php
171+
$sorter->setNullsPosition('first');
172+
```
173+
174+
---
175+
176+
#### `apply(Builder $query): Builder`
177+
178+
Applies the sorting rules to the given Eloquent query.
179+
180+
```php
181+
$sorter->apply($query);
182+
```
183+
184+
---
185+
186+
### Example Usage
187+
188+
```php
189+
$sorter = Sorter::make($request);
190+
191+
$sorter->allow(['title', 'created_at'])
192+
->setSortKey('sort')
193+
->setDelimiter(',')
194+
->setNullsPosition('last');
195+
196+
$query = $sorter->apply(Post::query());
197+
```
198+
199+
---
200+
201+
### Summary
202+
203+
- **`Sorter`** manages the sorting logic for Eloquent queries.
204+
- It allows you to define which fields are sortable, set default sorting, and create sorting aliases.
205+
- Customizable features include sorting with multi-fields, null value handling, and request-based sorting keys.

0 commit comments

Comments
 (0)