Skip to content

Commit e38eb36

Browse files
authored
Doc/Enhance Eloquent Criteria Parser documentation with pagination support details (#9)
1 parent f7dcf7c commit e38eb36

File tree

2 files changed

+107
-19
lines changed

2 files changed

+107
-19
lines changed

src/Infrastructure/Laravel/Persistence/Contracts/IlluminateCriteriaParser.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface IlluminateCriteriaParser
2222
* - 'builder': Query builder with filters, ordering, and pagination applied
2323
* - 'total': Total count before pagination
2424
* - 'page': Page value object from criteria
25+
* - 'currentPage': Current page number (1-indexed)
2526
*
2627
* @return array{builder: Builder, total: int, page: Page, currentPage: int}
2728
*/

wiki/Eloquent-Criteria-Parser.md

Lines changed: 106 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
11
# Eloquent Criteria Parser
22

3-
Using the Eloquent Criteria Parser is quite simple. Just instantiate the class, next, pass a Criteria instance to
4-
the `applyCriteria()` method along with a `EloquentQueryBuilder` instance:
3+
The Eloquent Criteria Parser translates domain Criteria objects into Eloquent query builders with pagination support.
4+
5+
## Basic Usage
6+
7+
Instantiate the parser and pass a Criteria instance along with an `EloquentQueryBuilder`:
58

69
```php
710
$parser = new EloquentCriteriaParser();
8-
$query = $parser->applyCriteria(User::query(), $criteria);
11+
$result = $parser->applyCriteria(User::query(), $criteria);
912
```
1013

11-
The returned `EloquentQueryBuilder` has the criteria applied. You just need to call the `get` method to fetch the data
12-
from the database.
14+
The `applyCriteria()` method returns an array containing:
15+
16+
- `builder`: EloquentQueryBuilder with filters, ordering, and pagination applied
17+
- `total`: Total count of records before pagination
18+
- `page`: Page value object from the criteria
19+
- `currentPage`: Current page number (1-indexed)
1320

1421
```php
15-
$users = $query->get();
22+
$items = $result['builder']->get();
23+
$total = $result['total'];
24+
$currentPage = $result['currentPage'];
1625
```
1726

18-
Alternatively, you can pass an array of strings to map the attributes between the domain and the database.
27+
## Attribute Mapping
28+
29+
Map domain attributes to database columns by passing an array to the constructor:
1930

2031
```php
2132
$parser = new EloquentCriteriaParser([
2233
'domain-attribute' => 'database-attribute',
2334
]);
2435
```
2536

26-
For example,
27-
given the following table:
37+
### Example
38+
39+
Given this users table:
2840

2941
```php
3042
$this->builder->create('users', function (Blueprint $table) {
@@ -37,7 +49,7 @@ $this->builder->create('users', function (Blueprint $table) {
3749
});
3850
```
3951

40-
You may use the following configuration to use `name` and `surname` instead of `first_name` and `last_name`:
52+
Use `name` and `surname` in your domain instead of `first_name` and `last_name`:
4153

4254
```php
4355
$parser = new EloquentCriteriaParser([
@@ -46,19 +58,94 @@ $parser = new EloquentCriteriaParser([
4658
]);
4759
```
4860

49-
A criteria search will be something like this:
61+
## Repository Implementation with PaginatedCollection
62+
63+
The recommended pattern is to use `PaginatedCollection` in your repositories:
64+
65+
```php
66+
use ComplexHeart\Domain\Criteria\Contracts\PaginatedResult;
67+
use ComplexHeart\Infrastructure\Laravel\Pagination\PaginatedCollection;
68+
69+
class UsersEloquentRepository implements UserRepository
70+
{
71+
private IlluminateCriteriaParser $criteriaParser;
72+
73+
public function __construct()
74+
{
75+
$this->criteriaParser = new EloquentCriteriaParser([
76+
'name' => 'first_name',
77+
'surname' => 'last_name'
78+
]);
79+
}
80+
81+
public function match(Criteria $criteria): PaginatedResult
82+
{
83+
$result = $this->criteriaParser->applyCriteria(User::query(), $criteria);
84+
85+
$items = $result['builder']
86+
->get()
87+
->map(fn($row) => UserEntity::fromSource($row))
88+
->toArray();
89+
90+
return PaginatedCollection::paginate(
91+
items: $items,
92+
total: $result['total'],
93+
perPage: $result['page']->limit(),
94+
currentPage: $result['currentPage'],
95+
);
96+
}
97+
}
98+
```
99+
100+
## PaginatedCollection
101+
102+
`PaginatedCollection` extends Laravel's `Collection` and implements the `PaginatedResult` interface from php-criteria.
103+
104+
### Collection Methods Support
105+
106+
You can use all Laravel Collection methods:
107+
108+
```php
109+
$result = $repository->match($criteria);
110+
111+
// Standard Collection methods
112+
$names = $result->map(fn($user) => $user->name)->toArray();
113+
$emails = $result->pluck('email')->toArray();
114+
$filtered = $result->filter(fn($user) => $user->isActive);
115+
```
116+
117+
### Pagination Metadata
118+
119+
Access pagination information through these methods:
120+
121+
```php
122+
$result->items(); // Get current page items as array
123+
$result->total(); // Total records across all pages
124+
$result->perPage(); // Items per page
125+
$result->currentPage(); // Current page number (1-indexed)
126+
$result->lastPage(); // Last page number
127+
$result->hasMorePages(); // Check if more pages exist
128+
$result->isEmpty(); // Check if current page is empty
129+
$result->isNotEmpty(); // Check if current page has items
130+
$result->count(); // Count items on current page
131+
```
132+
133+
### Example Usage
50134

51135
```php
52136
$criteria = Criteria::default()
53137
->withFilterGroup(FilterGroup::create()
54-
->addFilterEqual('name', 'Vicent'));
138+
->addFilterEqual('name', 'Vincent'))
139+
->withPageNumber(1, 25);
55140

56-
$builder = User::query();
141+
$result = $repository->match($criteria);
57142

58-
$parser = new EloquentCriteriaParser();
59-
$users = $parser
60-
->applyCriteria($builder, $criteria)
61-
->get();
62-
```
143+
if ($result->isNotEmpty()) {
144+
echo "Page {$result->currentPage()} of {$result->lastPage()}";
145+
echo "Showing {$result->count()} of {$result->total()} users";
63146

64-
This is useful to expose different attributes from different interfaces as HTTP, or CLI.
147+
foreach ($result as $user) {
148+
echo $user->name;
149+
}
150+
}
151+
```

0 commit comments

Comments
 (0)