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
Awesome Keyboard $88.44 2 Sep 16, 2025, 9:33 AM Sep 21, 2025, 11:05 AM
Budget Mouse $23.45 52 Sep 26, 2025, 1:23 AM Sep 27, 2025, 10:29 PM
Fun Story Collection Book $28.62 88 Oct 1, 2025, 2:10 AM Oct 5, 2025, 8:48 PM
Premium Headphones $279.92 93 Oct 10, 2025, 8:43 PM Oct 16, 2025, 1:39 AM
Zero Gravity Pen $8.15 93 Oct 18, 2025, 3:50 AM Oct 21, 2025, 2:04 PM
Coffee Mug Set $36.50 57 Oct 26, 2025, 3:02 AM Oct 28, 2025, 1:35 PM
Laptop Stand $59.44 78 Oct 31, 2025, 6:57 AM Nov 2, 2025, 7:08 PM
USB-C Cable $8.49 10 Nov 4, 2025, 4:13 PM Nov 7, 2025, 4:07 AM
Desk Organizer $22.71 91 Nov 8, 2025, 6:16 AM Nov 9, 2025, 8:08 PM
Monitor Arm $135.46 20 Nov 9, 2025, 7:15 PM Nov 11, 2025, 8:41 PM

Page 1 of 2, showing 10 record(s) out of 12 total

Try Combined Sort

Current Query Parameters

Array
(
)

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

Send your feedback or bugreport!