Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Sort
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
2 / 2
13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
8
 order
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Collection;
6
7use Cosray\Exception\RuntimeException;
8use Cosray\Finder\Order;
9use Cosray\Finder\SortField;
10
11final readonly class Sort
12{
13    /** @var non-empty-list<SortField> */
14    public array $fields;
15    public string $direction;
16
17    /**
18     * @param non-empty-list<string|SortField>|null $fields
19     * @param bool $default Whether the listing starts in this order
20     */
21    public function __construct(
22        public string $key,
23        ?array $fields = null,
24        string $direction = 'asc',
25        public bool $default = false,
26    ) {
27        if (preg_match('/^[a-zA-Z][a-zA-Z0-9_-]*$/D', $key) !== 1) {
28            throw new RuntimeException("Invalid collection sort key '{$key}'");
29        }
30        $fields ??= [$key];
31        if ($fields === [] || !array_is_list($fields)) {
32            throw new RuntimeException("Sort '{$key}' needs a non-empty list of fields");
33        }
34        $resolved = [];
35        foreach ($fields as $field) {
36            if (!is_string($field) && !$field instanceof SortField) {
37                throw new RuntimeException("Unsupported field in sort '{$key}'");
38            }
39            $resolved[] = is_string($field) ? SortField::text($field) : $field;
40        }
41        $this->fields = $resolved;
42        $this->direction = new Order($resolved[0], $direction)->direction;
43    }
44
45    /** @return non-empty-list<Order> */
46    public function order(string $direction = ''): array
47    {
48        $direction = $direction === '' ? $this->direction : $direction;
49        $order = [];
50        $unique = false;
51        foreach ($this->fields as $field) {
52            $order[] = new Order($field, $direction);
53            $unique = $unique || in_array($field->name, ['uid', 'id'], true);
54        }
55        if (!$unique) {
56            $order[] = new Order('uid');
57        }
58        return $order;
59    }
60}