Combined Sort Pagination
Including "SortableFieldsBuilder" functionality and Paginator defaulting.
CakePHP 5.3 Feature
Combined Sort allows you to include the sort direction (ASC/DESC) directly in the sort parameter key.
Instead of separate sort and direction parameters, you can use sort=column-asc or sort=column-desc.
Example URLs:
/sandbox/cake-examples/paginate-combined-sort?sort=title-asc- Sort by title ascending/sandbox/cake-examples/paginate-combined-sort?sort=price-desc- Sort by price descending/sandbox/cake-examples/paginate-combined-sort?sort=expensive-desc- Custom multi-column sort, locked (price DESC, then created DESC)/sandbox/cake-examples/paginate-combined-sort?sort=availability-asc- Custom multi-column sort, unlocked (price ASC, then stock ASC)
| Title | Price / Expensive | Stock / Availability | Created | Modified |
|---|---|---|---|---|
| Webcam HD | $117.34 | 42 | Nov 12, 2025, 8:50 AM | Nov 13, 2025, 1:26 PM |
| Wireless Charger | $23.57 | 53 | Nov 14, 2025, 12:31 AM | Nov 15, 2025, 6:59 AM |
Try Combined Sort
Current Query Parameters
Array
(
[page] => 2
)
SQL ORDER BY
No sorting applied
Implementation
// Controller - Using SortableFieldsBuilder (CakePHP 5.3)
$this->paginate = [
'sortableFields' => function ($builder) {
return $builder
->add('title') // Allows: title-asc, title-desc
// Lock price to ascending only (for demo purposes)
->add('price', SortField::asc('price', locked: true))
->add('stock') // Allows: stock-asc, stock-desc
->add('created') // Allows: created-asc, created-desc
->add('modified', SortField::desc('modified')) // Defaults to DESC
// Custom multi-column sort: expensive items first (DESC only, locked)
->add('expensive', SortField::desc('price', locked: true), SortField::desc('created', locked: true))
// Custom multi-column sort: availability (price + stock, not locked, can toggle)
->add('availability', 'price', 'stock');
},
'limit' => 10,
'maxLimit' => 10, // Enforce maximum limit
];
// Key Features Demonstrated:
// - Combined sort format: field-direction (e.g., title-asc)
// - Locked direction: price always sorts ASC, expensive always sorts DESC
// - Default direction: modified defaults to DESC (most recent first)
// - Multi-column custom sort (locked): 'expensive' sorts by price DESC, then created DESC
// - Multi-column custom sort (unlocked): 'availability' sorts by price, then stock (toggleable)
// - Pagination limit enforcement via maxLimit

