Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
CollectionUrls
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
13 / 13
16
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 path
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 collection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 back
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 expand
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 collapse
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 children
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 showInTree
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 edit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 bulk
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 position
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 url
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Panel;
6
7final class CollectionUrls
8{
9    public function __construct(
10        private readonly string $panelPath,
11        private readonly string $slug,
12        public readonly CollectionQuery $query,
13    ) {}
14
15    public function path(): string
16    {
17        return $this->panelPath . '/collection/' . rawurlencode($this->slug);
18    }
19
20    /** @param array<string, mixed> $overrides */
21    public function collection(array $overrides = []): string
22    {
23        return $this->url($this->path(), $this->query->listParams($overrides));
24    }
25
26    /** @param array<string, mixed> $overrides */
27    public function back(array $overrides = []): string
28    {
29        return $this->url($this->path(), $this->query->editorParams($overrides));
30    }
31
32    public function expand(string $uid): string
33    {
34        $open = $this->query->open;
35
36        if (!in_array($uid, $open, true)) {
37            $open[] = $uid;
38        }
39
40        return $this->collection([
41            'view' => 'tree',
42            'open' => $open,
43        ]);
44    }
45
46    /** @param list<string> $descendants */
47    public function collapse(string $uid, array $descendants = []): string
48    {
49        $closed = array_fill_keys(array_merge([$uid], $descendants), true);
50        $open = array_values(array_filter(
51            $this->query->open,
52            static fn(string $openUid): bool => !isset($closed[$openUid]),
53        ));
54
55        return $this->collection([
56            'view' => 'tree',
57            'open' => $open,
58        ]);
59    }
60
61    public function children(string $uid): string
62    {
63        return $this->collection([
64            'parent' => $uid,
65            'view' => '',
66            'open' => '',
67            'offset' => '',
68        ]);
69    }
70
71    public function showInTree(string $uid): string
72    {
73        $open = $this->query->open;
74
75        if (!in_array($uid, $open, true)) {
76            $open[] = $uid;
77        }
78
79        return $this->collection([
80            'parent' => '',
81            'view' => 'tree',
82            'open' => $open,
83            'offset' => '',
84        ]);
85    }
86
87    public function edit(string $uid): string
88    {
89        return new NodeUrls($this->panelPath, 'collection:' . $this->slug, $this->query)->edit($uid);
90    }
91
92    /**
93     * Bulk-action endpoint, carrying the full listing query (offset
94     * included) so the response can redirect back to the same view.
95     */
96    public function bulk(string $action): string
97    {
98        $path = $this->path() . '/bulk/' . rawurlencode($action);
99
100        return $this->url($path, $this->query->editorParams());
101    }
102
103    /** Reorder endpoint, carrying the listing query like `bulk()`. */
104    public function position(): string
105    {
106        return $this->url($this->path() . '/position', $this->query->editorParams());
107    }
108
109    public function create(string $type, ?string $parent = null): string
110    {
111        return new NodeUrls($this->panelPath, 'collection:' . $this->slug, $this->query)
112            ->create($type, $parent ?? $this->query->parent);
113    }
114
115    /** @param array<string, mixed> $params */
116    private function url(string $path, array $params): string
117    {
118        $query = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
119
120        return $query === '' ? $path : $path . '?' . $query;
121    }
122}