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    /** @param array<string, mixed> $overrides */
25    public function listParams(array $overrides = []): array
26    {
27        return $this->params([
28            'q' => $this->q,
29            'sort' => $this->sort,
30            'dir' => $this->dir,
31            'limit' => $this->limit,
32            'parent' => $this->parent,
33            'view' => $this->view,
34            'open' => $this->open,
35        ], $overrides);
36    }
37
38    /** @param array<string, mixed> $overrides */
39    public function editorParams(array $overrides = []): array
40    {
41        return $this->params([
42            'q' => $this->q,
43            'sort' => $this->sort,
44            'dir' => $this->dir,
45            'offset' => $this->offset,
46            'limit' => $this->limit,
47            'parent' => $this->parent,
48            'view' => $this->view,
49            'open' => $this->open,
50        ], $overrides);
51    }
52
53    /**
54     * @param array<string, mixed> $params
55     * @param array<string, mixed> $overrides
56     * @return array<string, mixed>
57     */
58    private function params(array $params, array $overrides): array
59    {
60        $params = array_merge($params, $overrides);
61
62        if (array_key_exists('open', $params)) {
63            $params['open'] = $this->openParam($params['open']);
64        }
65
66        $params = array_filter(
67            $params,
68            static fn(mixed $value): bool => $value !== null && $value !== '',
69        );
70
71        if (($params['view'] ?? null) === $this->defaultView) {
72            unset($params['view']);
73        }
74
75        if ($this->isInt($params['offset'] ?? null, 0)) {
76            unset($params['offset']);
77        }
78
79        if ($this->isInt($params['limit'] ?? null, self::DEFAULT_LIMIT)) {
80            unset($params['limit']);
81        }
82
83        return $params;
84    }
85
86    private function openParam(mixed $value): string
87    {
88        if (is_string($value)) {
89            return trim($value);
90        }
91
92        if (!is_array($value)) {
93            return '';
94        }
95
96        $open = [];
97
98        foreach ($value as $uid) {
99            $uid = trim((string) $uid);
100
101            if ($uid !== '' && !in_array($uid, $open, true)) {
102                $open[] = $uid;
103            }
104        }
105
106        return implode(',', $open);
107    }
108
109    private function isInt(mixed $value, int $expected): bool
110    {
111        if (is_int($value)) {
112            return $value === $expected;
113        }
114
115        if (!is_string($value) || !preg_match('/^-?[0-9]+$/', $value)) {
116            return false;
117        }
118
119        return (int) $value === $expected;
120    }
121}