Passed
Push — master ( 6d5c7d...f7244e )
by Tomáš
09:21
created

Range::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

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

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