Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
13 / 14
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SortField
92.86% covered (success)
92.86%
13 / 14
83.33% covered (warning)
83.33%
5 / 6
10.04
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 text
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 number
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 date
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 dateTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 position
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Finder;
6
7use Cosray\Collection\Schemas;
8use Cosray\Exception\ParserException;
9
10final readonly class SortField
11{
12    /** @param 'text'|'numeric'|'date'|'timestamptz'|'position' $type */
13    private function __construct(
14        public string $name,
15        public string $type,
16        public ?string $collection = null,
17    ) {
18        if (preg_match('/^[a-zA-Z][a-zA-Z0-9_]*(?:\.[a-zA-Z0-9_-]+)*$/D', $name) !== 1) {
19            throw new ParserException("Invalid sort field '{$name}'");
20        }
21    }
22
23    public static function text(string $name): self
24    {
25        return new self($name, 'text');
26    }
27
28    /** Numbers and decimal strings are compared without losing decimal precision. */
29    public static function number(string $name): self
30    {
31        return new self($name, 'numeric');
32    }
33
34    public static function date(string $name): self
35    {
36        return new self($name, 'date');
37    }
38
39    public static function dateTime(string $name): self
40    {
41        return new self($name, 'timestamptz');
42    }
43
44    /**
45     * The manual order editors arrange in the panel: among the children of
46     * the node's parent, or with a collection (class or handle) at that
47     * collection's top level. Nodes without a position follow the
48     * positioned ones by title, and the uid breaks remaining ties.
49     */
50    public static function position(?string $collection = null): self
51    {
52        if ($collection === null) {
53            return new self('position', 'position');
54        }
55
56        $collection = trim($collection);
57
58        if ($collection === '') {
59            throw new ParserException('A collection position needs a collection');
60        }
61
62        if (class_exists($collection)) {
63            $collection = (string) new Schemas()->of($collection)->handle;
64        }
65
66        return new self('position', 'position', $collection);
67    }
68}