Passed
Push — master ( dd435e...1658ca )
by Tomáš
18:05 queued 08:04
created

Range::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 20
ccs 4
cts 4
cp 1
crap 1
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php declare(strict_types = 1);
2
3
namespace Apicart\FQL\Token\Token;
4
5
use DateTimeImmutable;
6
use Apicart\FQL\Value\Token;
7
use InvalidArgumentException;
8
use Apicart\FQL\Tokenizer\Tokenizer;
9
10
final class Range extends Token
11
{
12
13
    public const TYPE_INCLUSIVE = 'inclusive';
14
15
    public const TYPE_EXCLUSIVE = 'exclusive';
16
17
    public const DATE_FORMAT = 'Y-m-d';
18
    public const DATE_REGEX = '/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/';
19
20
    public const DATETIME_FORMAT = 'Y-m-d\TH:i:s\Z';
21
    public const DATETIME_REGEX = '/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3]):([0-5]\d):([0-5]\d)(\.\d{1,9})?Z$/';
22
23
    public const RELATIVE_DATE_SEPARATOR = '|';
24
    public const RELATIVE_DATE_REGEX = '/^(today|week|month|year)(\|(\+|-)?\d+)?$/';
25
    public const RELATIVE_DATE_TODAY = 'today';
26
    public const RELATIVE_DATE_WEEK = 'week';
27
    public const RELATIVE_DATE_MONTH = 'month';
28
    public const RELATIVE_DATE_YEAR = 'year';
29
    public const RELATIVE_DATE_VALUES = [
30
        self::RELATIVE_DATE_TODAY,
31
        self::RELATIVE_DATE_WEEK,
32
        self::RELATIVE_DATE_MONTH,
33
        self::RELATIVE_DATE_YEAR,
34
    ];
35
36
    /**
37
     * @var string
38
     */
39
    private $domain;
40
41
    /**
42
     * @var int|float|string
43
     */
44
    private $startValue;
45
46 23
    /**
47
     * @var int|float|string
48
     */
49
    private $endValue;
50
51
    /**
52
     * @var string|null
53
     */
54
    private $startType;
55 23
56 16
    /**
57 10
     * @var string|null
58
     */
59 10
    private $endType;
60 10
61 10
    /**
62 10
     * @var Flags|null
63 10
     */
64 10
    private $flags;
65
66
67 7
    /**
68
     * @param int|float|string $startValue
69 7
     * @param int|float|string $endValue
70
     */
71
    public function __construct(
72
        string $lexeme,
73
        int $position,
74
        string $domain,
75
        $startValue,
76 6
        $endValue,
77
        ?string $startType,
78 6
        ?string $endType,
79
        ?Flags $flags = null
80
    ) {
81
        $this->ensureValidType($startType);
82
        $this->ensureValidType($endType);
83
        parent::__construct(Tokenizer::TOKEN_TERM, $lexeme, $position);
84
85 5
        $this->domain = $domain;
86
        $this->startValue = $startValue;
87 5
        $this->endValue = $endValue;
88
        $this->startType = $startType;
89
        $this->endType = $endType;
90
        $this->flags = $flags;
91 7
    }
92
93 7
94
    public function getDomain(): string
95
    {
96
        return $this->domain;
97 1
    }
98
99 1
100 1
    /**
101
     * @return int|float|string
102
     */
103 6
    public function getStartValue()
104
    {
105 6
        return $this->startValue;
106
    }
107
108
109 1
    public function getStartDateValue(): ?DateTimeImmutable
110
    {
111 1
        if ($this->isStartInDateFormat()) {
112 1
            return DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $this->getStartValue());
113
        }
114
115 1
        return null;
116
    }
117 1
118
    public function getStartDateTimeValue(): ?DateTimeImmutable
119
    {
120
        if ($this->isStartInDateTimeFormat()) {
121 1
            return DateTimeImmutable::createFromFormat(self::DATETIME_FORMAT, $this->getStartValue());
122
        }
123 1
124
        return null;
125
    }
126
127 1
    public function getStartRelativeDateValue(): ?array
128
    {
129 1
        return $this->parseRelativeDateValue($this->getStartValue());
130
    }
131
132
133 1
    /**
134
     * @return int|float|string
135 1
     */
136
    public function getEndValue()
137
    {
138
        return $this->endValue;
139 23
    }
140
141 23
    public function getEndDateValue(): ?DateTimeImmutable
142 13
    {
143
        if ($this->isEndInDateFormat()) {
144 16
            return DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $this->getEndValue());
145
        }
146
147
        return null;
148
    }
149
150
    public function getEndDateTimeValue(): ?DateTimeImmutable
151
    {
152
        if ($this->isEndInDateTimeFormat()) {
153
            return DateTimeImmutable::createFromFormat(self::DATETIME_FORMAT, $this->getEndValue());
154
        }
155
156
        return null;
157
    }
158
159
    public function getEndRelativeDateValue(): ?array
160
    {
161
        return $this->parseRelativeDateValue($this->getEndValue());
162
    }
163
164
165
    public function getStartType(): ?string
166
    {
167
        return $this->startType;
168
    }
169
170
171
    public function setStartType(?string $startType): void
172
    {
173
        $this->startType = $startType;
174
    }
175
176
177
    public function getEndType(): ?string
178
    {
179
        return $this->endType;
180
    }
181
182
183
    public function setEndType(?string $endType): void
184
    {
185
        $this->endType = $endType;
186
    }
187
188
189
    public function getStartSign(): string
190
    {
191
        return $this->getStartType() === Range::TYPE_INCLUSIVE ? '>=' : '>';
192
    }
193
194
195
    public function getEndSign(): string
196
    {
197
        return $this->getEndType() === Range::TYPE_INCLUSIVE ? '<=' : '<';
198
    }
199
200
201
    public function isStartDefined(): bool
202
    {
203
        return $this->getStartValue() !== '*';
204
    }
205
206
207
    public function isEndDefined(): bool
208
    {
209
        return $this->getEndValue() !== '*';
210
    }
211
212
213
    public function getFlags(): ?Flags
214
    {
215
        return $this->flags;
216
    }
217
218
    public function isStartInDateFormat(): bool
219
    {
220
        return preg_match(self::DATE_REGEX, $this->getStartValue()) === 1;
221
    }
222
223
    public function isStartInDateTimeFormat(): bool
224
    {
225
        return preg_match(self::DATETIME_REGEX, $this->getStartValue()) === 1;
226
    }
227
228
    public function isStartInRelativeDateFormat(): bool
229
    {
230
        return preg_match(self::RELATIVE_DATE_REGEX, $this->getStartValue()) === 1;
231
    }
232
233
    public function isEndInDateFormat(): bool
234
    {
235
        return preg_match(self::DATE_REGEX, $this->getEndValue()) === 1;
236
    }
237
238
    public function isEndInDateTimeFormat(): bool
239
    {
240
        return preg_match(self::DATETIME_REGEX, $this->getEndValue()) === 1;
241
    }
242
243
    public function isEndInRelativeDateFormat(): bool
244
    {
245
        return preg_match(self::RELATIVE_DATE_REGEX, $this->getEndValue()) === 1;
246
    }
247
248
    public function parseRelativeDateValue(string $value): ?array
249
    {
250
        if (preg_match(self::RELATIVE_DATE_REGEX, $value) === 1) {
251
            $parts = explode(self::RELATIVE_DATE_SEPARATOR, $value);
252
            $base = $parts[0];
253
            $offset = isset($parts[1]) ? (int) $parts[1] : 0;
254
255
            return ['base' => $base, 'offset' => $offset];
256
        }
257
258
        return null;
259
    }
260
261
    private function ensureValidType(?string $type): void
262
    {
263
        if (! in_array($type, [self::TYPE_EXCLUSIVE, self::TYPE_INCLUSIVE], true)) {
264
            throw new InvalidArgumentException(sprintf('Invalid range type: %s', $type));
265
        }
266
    }
267
268
}
269