Passed
Push — master ( 37753a...ffeb4b )
by Marcin
04:24
created

RequestParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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