SortUriManager::getAppliedSorts()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace BenTools\OpenCubes\Component\Sort;
4
5
use BenTools\OpenCubes\Component\Pager\PagerUriManager;
6
use BenTools\OpenCubes\Component\Pager\PagerUriManagerInterface;
7
use BenTools\OpenCubes\Component\Sort\Model\Sort;
8
use BenTools\OpenCubes\OptionsTrait;
9
use Psr\Http\Message\UriInterface;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
use function BenTools\QueryString\query_string;
12
13
final class SortUriManager implements SortUriManagerInterface
14
{
15
    use OptionsTrait;
16
17
    public const OPT_SORT_QUERY_PARAM = 'query_param';
18
19
    /**
20
     * @var PagerUriManagerInterface
21
     */
22
    private $pagerUriManager;
23
24
    /**
25
     * SortUriManager constructor.
26
     * @param array                         $options
27
     * @param PagerUriManagerInterface|null $pagerUriManager
28
     */
29
    public function __construct(array $options = [], PagerUriManagerInterface $pagerUriManager = null)
30
    {
31
        $optionsResolver = new OptionsResolver();
32
        $optionsResolver->setDefaults([
33
            self::OPT_SORT_QUERY_PARAM => 'sort'
34
        ]);
35
36
        $this->options = $optionsResolver->resolve($options);
37
        $this->pagerUriManager = $pagerUriManager ?? new PagerUriManager();
38
    }
39
40
    /**
41
     * @inheritDoc
42
     */
43
    public function getAppliedSorts(UriInterface $uri): array
44
    {
45
        $qs = query_string($uri);
46
47
        $sorts = $qs->getParam($this->getOption(self::OPT_SORT_QUERY_PARAM));
48
49
        if (!is_array($sorts)) {
50
            return [];
51
        }
52
53
        return $this->normalizeSorts((array) $sorts);
54
    }
55
56
    /**
57
     * @param UriInterface $uri
58
     * @param array        $sorts
59
     * @return UriInterface
60
     * @throws \InvalidArgumentException
61
     * @throws \Symfony\Component\OptionsResolver\Exception\NoSuchOptionException
62
     */
63
    public function buildSortUri(UriInterface $uri, array $sorts): UriInterface
64
    {
65
66
        $normalizedSorts = [];
67
68
        foreach ($sorts as $key => $value) {
69
            if ($value instanceof Sort) {
70
                $normalizedSorts[$value->getField()] = $value->getDirection();
71
            } else {
72
                $normalizedSorts[$key] = $value;
73
            }
74
        }
75
76
        // Reset to 1st page after sorting
77
        $uri = $this->pagerUriManager->buildPageUri($uri, 1);
78
        $qs = query_string($uri);
79
        $qs = [] === $sorts ? $qs->withoutParam($this->getOption(self::OPT_SORT_QUERY_PARAM)) : $qs->withParam($this->getOption(self::OPT_SORT_QUERY_PARAM), $normalizedSorts);
80
81
        return $uri->withQuery((string) $qs);
82
    }
83
84
    /**
85
     * @param array $sorts
86
     * @return array
87
     */
88
    private function normalizeSorts(array $sorts): array
89
    {
90
        return array_map(function (string $direction) {
91
            switch ($direction) {
92
                case '':
93
                    return null;
94
                case 'asc':
95
                case 'ASC':
96
                    return 'asc';
97
                case 'desc':
98
                case 'DESC':
99
                    return 'desc';
100
            }
101
102
            return strtolower($direction);
103
        }, $sorts);
104
    }
105
}
106