Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.92% covered (success)
95.92%
47 / 49
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
CollectionQuery
95.92% covered (success)
95.92%
47 / 49
66.67% covered (warning)
66.67%
4 / 6
19
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 listParams
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 editorParams
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 params
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
6
 openParam
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
6.04
 isInt
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
4.13
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Panel;
6
7final class CollectionQuery
8{
9    private const int DEFAULT_LIMIT = 50;
10
11    /** @param list<string> $open */
12    public function __construct(
13        public readonly string $q = '',
14        public readonly string $sort = '',
15        public readonly string $dir = '',
16        public readonly int $offset = 0,
17        public readonly int $limit = self::DEFAULT_LIMIT,
18        public readonly ?string $parent = null,
19        public readonly string $view = 'list',
20        public readonly array $open = [],
21        public readonly string $defaultView = 'list',
22    ) {}
23
24    /**
25     * @param array<string, mixed> $overrides
26     * @return array<string, mixed>
27     */
28    public function listParams(array $overrides = []): array
29    {
30        return $this->params([
31            'q' => $this->q,
32            'sort' => $this->sort,
33            'dir' => $this->dir,
34            'limit' => $this->limit,
35            'parent' => $this->parent,
36            'view' => $this->view,
37            'open' => $this->open,
38        ], $overrides);
39    }
40
41    /**
42     * @param array<string, mixed> $overrides
43     * @return array<string, mixed>
44     */
45    public function editorParams(array $overrides = []): array
46    {
47        return $this->params([
48            'q' => $this->q,
49            'sort' => $this->sort,
50            'dir' => $this->dir,
51            'offset' => $this->offset,
52            'limit' => $this->limit,
53            'parent' => $this->parent,
54            'view' => $this->view,
55            'open' => $this->open,
56        ], $overrides);
57    }
58
59    /**
60     * @param array<string, mixed> $params
61     * @param array<string, mixed> $overrides
62     * @return array<string, mixed>
63     */
64    private function params(array $params, array $overrides): array
65    {
66        $params = array_merge($params, $overrides);
67
68        if (array_key_exists('open', $params)) {
69            $params['open'] = $this->openParam($params['open']);
70        }
71
72        $params = array_filter(
73            $params,
74            static fn(mixed $value): bool => $value !== null && $value !== '',
75        );
76
77        if (($params['view'] ?? null) === $this->defaultView) {
78            unset($params['view']);
79        }
80
81        if ($this->isInt($params['offset'] ?? null, 0)) {
82            unset($params['offset']);
83        }
84
85        if ($this->isInt($params['limit'] ?? null, self::DEFAULT_LIMIT)) {
86            unset($params['limit']);
87        }
88
89        return $params;
90    }
91
92    private function openParam(mixed $value): string
93    {
94        if (is_string($value)) {
95            return trim($value);
96        }
97
98        if (!is_array($value)) {
99            return '';
100        }
101
102        $open = [];
103
104        foreach ($value as $uid) {
105            $uid = trim((string) $uid);
106
107            if ($uid !== '' && !in_array($uid, $open, true)) {
108                $open[] = $uid;
109            }
110        }
111
112        return implode(',', $open);
113    }
114
115    private function isInt(mixed $value, int $expected): bool
116    {
117        if (is_int($value)) {
118            return $value === $expected;
119        }
120
121        if (!is_string($value) || !preg_match('/^-?[0-9]+$/', $value)) {
122            return false;
123        }
124
125        return (int) $value === $expected;
126    }
127}