Passed
Push — master ( 8e3856...c9645e )
by Marcin
03:52
created

RequestParser::getQueryParam()   B

Complexity

Conditions 9
Paths 7

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 9.0197

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 26
c 0
b 0
f 0
ccs 15
cts 16
cp 0.9375
rs 8.0555
cc 9
nc 7
nop 3
crap 9.0197
1
<?php
2
/**
3
 * Created by Marcin.
4
 * Date: 16.06.2018
5
 * Time: 13:45
6
 */
7
declare(strict_types=1);
8
9
namespace mrcnpdlk\Lib\UrlSearchParser;
10
11
12
use mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter;
13
use mrcnpdlk\Lib\UrlSearchParser\Criteria\Sort;
14
use mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException;
15
16
class RequestParser
17
{
18
    public const SORT_IDENTIFIER   = 'sort';
19
    public const FILTER_IDENTIFIER = 'filter';
20
21
    public const LIMIT_IDENTIFIER  = 'limit';
22
    public const OFFSET_IDENTIFIER = 'offset';
23
    public const PAGE_IDENTIFIER   = 'page';
24
    public const PHRASE_IDENTIFIER = 'phrase';
25
26
27
    private $queryParams = [];
28
    /**
29
     * @var \mrcnpdlk\Lib\UrlSearchParser\Criteria\Sort
30
     */
31
    private $sort;
32
    /**
33
     * @var \mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter
34
     */
35
    private $filter;
36
    /**
37
     * @var integer|null
38
     */
39
    private $limit;
40
    /**
41
     * @var integer|null
42
     */
43
    private $page;
44
    /**
45
     * @var integer|null
46
     */
47
    private $offset;
48
    /**
49
     * @var string|null
50
     */
51
    private $phrase;
52
53
    /**
54
     * RequestParser constructor.
55
     *
56
     * @param string $query
57
     *
58
     * @throws \mrcnpdlk\Lib\UrlSearchParser\Exception
59
     * @throws \mrcnpdlk\Lib\UrlSearchParser\Exception\EmptyParamException
60
     * @throws \mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException
61
     */
62 16
    public function __construct(string $query)
63
    {
64 16
        $this->parse($query);
65 7
    }
66
67
    /**
68
     * @return \mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter
69
     */
70 2
    public function getFilter(): Filter
71
    {
72 2
        return $this->filter;
73
    }
74
75
    /**
76
     * @param int|null $default
77
     *
78
     * @return int|null
79
     */
80 2
    public function getLimit(int $default = null): ?int
81
    {
82 2
        return $this->limit ?? $default;
83
    }
84
85
    /**
86
     * @param int|null $default
87
     *
88
     * @return int|null
89
     */
90 2
    public function getOffset(int $default = null): ?int
91
    {
92 2
        return $this->offset ?? $default;
93
    }
94
95
    /**
96
     * @param int|null $default
97
     *
98
     * @return int|null
99
     */
100 2
    public function getPage(int $default = null): ?int
101
    {
102 2
        return $this->page ?? $default;
103
    }
104
105
    /**
106
     * @return null|string
107
     */
108 2
    public function getPhrase(): ?string
109
    {
110 2
        return $this->phrase;
111
    }
112
113
    /**
114
     * @param string      $param
115
     * @param string|null $type If NULL return value AS IS
116
     * @param mixed|null  $default
117
     *
118
     * @return mixed|null
119
     */
120 16
    public function getQueryParam(string $param, string $type = null, $default = null)
121
    {
122 16
        if (isset($this->queryParams[$param])) {
123 16
            if ($type !== null) {
124 15
                $type = strtolower($type);
125 15
                if (!\in_array($type, ['boolean', 'bool', 'integer', 'int', 'float', 'double', 'string', 'array'])) {
126 1
                    throw new \InvalidArgumentException(sprintf('Unsupported type [%s]', $type));
127
                }
128
129 14
                $var = $this->queryParams[$param];
130
131 14
                if ($type === 'array' && \is_string($var)) {
132 2
                    $var = explode(',', $var);
133 13
                } elseif ($type === 'string' && \is_array($var)) {
134 1
                    $var = implode(',', $var);
135 13
                } elseif (!settype($var, strtolower($type))) {
136
                    throw new \RuntimeException(sprintf('Cannot set type [%s]', $type));
137
                }
138
139 14
                return $var;
140
            }
141
142 1
            return $this->queryParams[$param];
143
        }
144
145 14
        return $default ?? null;
146
    }
147
148
    /**
149
     * @return \mrcnpdlk\Lib\UrlSearchParser\Criteria\Sort
150
     */
151 2
    public function getSort(): Sort
152
    {
153 2
        return $this->sort;
154
    }
155
156
    /**
157
     * @param string $param
158
     *
159
     * @return $this
160
     */
161 1
    public function removeQueryParam(string $param)
162
    {
163 1
        unset($this->queryParams[$param]);
164
165 1
        return $this;
166
    }
167
168
    /**
169
     * @param string $query
170
     *
171
     * @throws \mrcnpdlk\Lib\UrlSearchParser\Exception\EmptyParamException
172
     * @throws \mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException
173
     */
174 16
    private function parse(string $query): void
175
    {
176 16
        parse_str($query, $this->queryParams);
177
178 16
        $this->sort   = new Sort($this->getQueryParam(self::SORT_IDENTIFIER, 'string'));
179 14
        $this->filter = new Filter($this->getQueryParam(self::FILTER_IDENTIFIER, 'array', []));
180 10
        $this->limit  = $this->getQueryParam('limit', 'int');
181 10
        if (null !== $this->limit && $this->limit < 0) {
182 1
            throw new InvalidParamException('Limit value cannot be lower than 0');
183
        }
184 9
        $this->offset = $this->getQueryParam('offset', 'int');
185 9
        if (null !== $this->offset && $this->offset < 0) {
186 1
            throw new InvalidParamException('Offset value cannot be lower than 0');
187
        }
188 8
        $this->page = $this->getQueryParam('page', 'int');
189 8
        if (null !== $this->page && $this->page < 0) {
190 1
            throw new InvalidParamException('Page value cannot be lower than 0');
191
        }
192 7
        $this->phrase = $this->getQueryParam('phrase', 'string');
193 7
    }
194
}
195