Skip to content

Commit a4a6560

Browse files
committed
fix: apply strict code quality standards
- Fix PHPStan level 9 issues: - Update deprecated Form constants (MIN->Min, MAX->Max, RANGE->Range, DATA_TEXT->DataText) - Replace deprecated getSeparatorPrototype() with getContainerPrototype() - Replace deprecated IControl interface with Control - Add typed properties to all classes - Add native type hints to all methods - Fix setValue() contravariance issue in ProtectionFastInput - Fix CodeSniffer issues: - Add array type to $wrappers properties - Add proper PHPDoc annotations - Fix method spacing and ordering - Add exclusion rules for inherited property types - Update phpstan.neon and ruleset.xml with appropriate ignores
1 parent 3f59fbd commit a4a6560

20 files changed

+130
-161
lines changed

phpstan.neon

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ parameters:
99
- src
1010

1111
ignoreErrors:
12-
# It is contravariant, original typehint is not recognized properly
13-
- '#^Parameter \#1 \$value \(string\) of method Contributte\\Forms\\Controls\\ProtectionFastInput\:\:setValue\(\) should be contravariant with parameter \$value \(mixed\) of method Nette\\Forms\\.+\:\:setValue\(\)$#'
12+
# Inherited property from DefaultFormRenderer - we cannot change the base class type
13+
- '#Property .+::\$wrappers type has no value type specified in iterable type array#'
14+
# Type is inferred from union type, validation is for runtime safety
15+
- '#Call to function is_string\(\) with string will always evaluate to true#'

ruleset.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,15 @@
1111
</properties>
1212
</rule>
1313

14+
<!-- Inherited $wrappers property from DefaultFormRenderer cannot have specific type -->
15+
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification">
16+
<exclude-pattern>src/Rendering/*Renderer.php</exclude-pattern>
17+
</rule>
18+
19+
<!-- Test fixtures need superglobals for form simulation -->
20+
<rule ref="SlevomatCodingStandard.Variables.DisallowSuperGlobalVariable">
21+
<exclude-pattern>tests/</exclude-pattern>
22+
</rule>
23+
1424
<exclude-pattern>/tests/tmp</exclude-pattern>
1525
</ruleset>

src/Controls/DateTime/AbstractDateTimeInput.php

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use DateTimeInterface;
99
use Nette\Forms\Controls\BaseControl;
1010
use Nette\Forms\Form;
11-
use Nette\Utils\Arrays;
1211
use Nette\Utils\Html;
1312
use function class_exists;
1413
use function count;
@@ -34,7 +33,7 @@ abstract class AbstractDateTimeInput extends BaseControl
3433

3534
protected string $htmlClass = '';
3635

37-
protected string|object $invalidValueMessage = 'Invalid format';
36+
protected string|\Stringable $invalidValueMessage = 'Invalid format';
3837

3938
/**
4039
* @param string|string[] $format
@@ -52,21 +51,17 @@ public function __construct(?string $label = null, $format = null)
5251
* @param string|string[] $format
5352
* @return static
5453
*/
55-
public function setFormat($format)
54+
public function setFormat(string|array $format): static
5655
{
57-
if (is_string($format)) {
58-
$format = [$format];
59-
}
56+
$formats = is_array($format) ? $format : [$format];
6057

61-
if (!is_array($format) || /** @phpstan-ignore-line */
62-
Arrays::some($format, function ($item) {
63-
return !is_string($item);
64-
})
65-
) {
66-
throw new InvalidArgumentException('Format must be either string or array of strings.');
58+
foreach ($formats as $item) {
59+
if (!is_string($item)) {
60+
throw new InvalidArgumentException('Format must be either string or array of strings.');
61+
}
6762
}
6863

69-
$this->parser->setFormats($format);
64+
$this->parser->setFormats($formats);
7065
return $this;
7166
}
7267

@@ -75,28 +70,25 @@ public function setFormat($format)
7570
* @phpstan-param class-string|callable(DateTimeInterface): mixed $type
7671
* @return static
7772
*/
78-
public function setValueType($type)
73+
public function setValueType(string|callable $type): static
7974
{
8075
$this->valueTransformation = $this->createValueTransformation($type);
8176
return $this;
8277
}
8378

8479
/**
8580
* @template T
86-
* @param string|callable $type
8781
* @phpstan-param class-string<T>|callable(DateTimeInterface): ?T $type
8882
* @return callable(DateTimeInterface): ?T
8983
*/
90-
protected function createValueTransformation($type)
84+
protected function createValueTransformation(string|callable $type): callable
9185
{
9286
if (is_callable($type)) {
9387
return $type;
94-
} elseif (is_string($type)) { /** @phpstan-ignore-line */
95-
if (!class_exists($type) || class_implements($type) === false || !in_array('DateTimeInterface', class_implements($type), true)) {
96-
throw new InvalidArgumentException('Value type must be existing class implementing \DateTimeInterface');
97-
}
98-
} else {
99-
throw new InvalidArgumentException('Value type can be only string with class name or or callback.');
88+
}
89+
90+
if (!class_exists($type) || class_implements($type) === false || !in_array('DateTimeInterface', class_implements($type), true)) {
91+
throw new InvalidArgumentException('Value type must be existing class implementing \DateTimeInterface');
10092
}
10193

10294
if ($type === 'Nette\Utils\DateTime' || (class_parents($type) !== false && in_array('Nette\Utils\DateTime', class_parents($type), true))) {
@@ -111,10 +103,7 @@ protected function createValueTransformation($type)
111103
}
112104
}
113105

114-
/**
115-
* @return mixed
116-
*/
117-
protected function transformValue(?DateTimeImmutable $value)
106+
protected function transformValue(?DateTimeImmutable $value): mixed
118107
{
119108
if ($value === null) {
120109
return null;
@@ -130,7 +119,7 @@ protected function transformValue(?DateTimeImmutable $value)
130119
/**
131120
* @return static
132121
*/
133-
public function addFormat(string $format)
122+
public function addFormat(string $format): static
134123
{
135124
$this->parser->addFormat($format);
136125
return $this;
@@ -190,26 +179,17 @@ public function setDefaultValue($value)
190179
return parent::setDefaultValue($value);
191180
}
192181

193-
/**
194-
* @return mixed
195-
*/
196-
public function getValue()
182+
public function getValue(): mixed
197183
{
198184
return $this->transformValue($this->getValueAsDateTimeImmutable());
199185
}
200186

201-
/**
202-
* @return mixed
203-
*/
204-
public function getRawValue()
187+
public function getRawValue(): mixed
205188
{
206189
return parent::getValue();
207190
}
208191

209-
/**
210-
* @return ?DateTimeImmutable
211-
*/
212-
protected function getValueAsDateTimeImmutable()
192+
protected function getValueAsDateTimeImmutable(): ?DateTimeImmutable
213193
{
214194
if ($this->value === null || $this->value === '') {
215195
return null;
@@ -226,12 +206,10 @@ protected function getValueAsDateTimeImmutable()
226206

227207
/**
228208
* @template T
229-
* @param string|callable $type
230209
* @phpstan-param class-string<T>|callable(DateTimeInterface): ?T $type
231-
* @return mixed
232210
* @phpstan-return ?T
233211
*/
234-
public function getValueAs($type)
212+
public function getValueAs(string|callable $type): mixed
235213
{
236214
$value = $this->getValueAsDateTimeImmutable();
237215
if ($value === null) {
@@ -243,29 +221,26 @@ public function getValueAs($type)
243221
}
244222

245223
/** @phpstan-var ?T */
224+
246225
return $value;
247226
}
248227

249228
/**
250-
* @param string|object $message
251229
* @return static
252230
*/
253-
public function setInvalidValueMessage($message)
231+
public function setInvalidValueMessage(string|\Stringable $message): static
254232
{
255233
$this->invalidValueMessage = $message;
256234
return $this;
257235
}
258236

259237
/**
260-
* @param callable|string $validator
261-
* @param string|object $message
262-
* @param mixed $arg
263238
* @return static
264239
*/
265-
public function addRule($validator, $message = null, $arg = null)
240+
public function addRule(callable|string $validator, string|\Stringable|null $message = null, mixed $arg = null): static
266241
{
267242
switch ($validator) {
268-
case Form::MIN:
243+
case Form::Min:
269244
if (!$arg instanceof DateTimeInterface) {
270245
throw new InvalidArgumentException('Rule parameter expected to be \DateTimeInterface');
271246
}
@@ -275,7 +250,7 @@ public function addRule($validator, $message = null, $arg = null)
275250
$validator = static::class . '::validateMin';
276251
break;
277252

278-
case Form::MAX:
253+
case Form::Max:
279254
if (!$arg instanceof DateTimeInterface) {
280255
throw new InvalidArgumentException('Rule parameter expected to be \DateTimeInterface');
281256
}
@@ -285,7 +260,7 @@ public function addRule($validator, $message = null, $arg = null)
285260
$validator = static::class . '::validateMax';
286261
break;
287262

288-
case Form::RANGE:
263+
case Form::Range:
289264
if (!is_array($arg) || !$arg[0] instanceof DateTimeInterface || !$arg[1] instanceof DateTimeInterface) {
290265
throw new InvalidArgumentException('Rule parameter expected to be 2 item array [min, max] of \DateTimeInterface');
291266
}
@@ -311,7 +286,6 @@ public function getMin(): ?DateTimeInterface
311286
return $this->min;
312287
}
313288

314-
315289
public function getMax(): ?DateTimeInterface
316290
{
317291
return $this->max;

src/Controls/DateTime/DateInput.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ class DateInput extends AbstractDateTimeInput
1717

1818
protected string $htmlClass = 'date-input';
1919

20-
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
20+
public static function register(?string $defaultFormat = null): void
2121
{
22-
$datetime = parent::normalizeDateTime($datetime);
23-
$datetime = $datetime->setTime(0, 0, 0, 0);
24-
return $datetime;
22+
Container::extensionMethod(
23+
'addDate',
24+
fn ($container, $name, $label = null, $format = null, ?DateTimeZone $inputTimezone = null): DateInput => $container[$name] = new DateInput($label, $format ?? $defaultFormat)
25+
);
2526
}
2627

2728
public function getControl(): Html
@@ -34,14 +35,12 @@ public function getControl(): Html
3435
return $control;
3536
}
3637

37-
public static function register(?string $defaultFormat = null): void
38+
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
3839
{
39-
Container::extensionMethod(
40-
'addDate',
41-
function ($container, $name, $label = null, $format = null, ?DateTimeZone $inputTimezone = null) use ($defaultFormat): DateInput {
42-
return $container[$name] = new DateInput($label, $format ?? $defaultFormat);
43-
}
44-
);
40+
$datetime = parent::normalizeDateTime($datetime);
41+
$datetime = $datetime->setTime(0, 0, 0, 0);
42+
43+
return $datetime;
4544
}
4645

4746
}

src/Controls/DateTime/DateTimeInput.php

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,23 @@ class DateTimeInput extends AbstractDateTimeInput
2222
/**
2323
* @param string|string[] $format
2424
*/
25-
public function __construct(?string $label = null, $format = null, ?DateTimeZone $inputTimezone = null)
25+
public function __construct(?string $label = null, string|array|null $format = null, ?DateTimeZone $inputTimezone = null)
2626
{
2727
parent::__construct($label, $format);
28+
2829
$this->parser->setDefaultTimezone($inputTimezone);
2930
$this->inputTimezone = $inputTimezone;
3031
}
3132

32-
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
33+
public static function register(?string $defaultFormat = null): void
3334
{
34-
$datetime = parent::normalizeDateTime($datetime);
35-
if ($this->inputTimezone !== null) {
36-
$datetime = $datetime->setTimezone($this->inputTimezone);
37-
}
38-
39-
return $datetime;
35+
Container::extensionMethod(
36+
'addDateTime',
37+
fn ($container, $name, $label = null, $format = null, ?DateTimeZone $inputTimezone = null): DateTimeInput => $container[$name] = new DateTimeInput($label, $format ?? $defaultFormat, $inputTimezone)
38+
);
4039
}
4140

42-
/**
43-
* @return mixed
44-
*/
45-
public function getValueInTz(?DateTimeZone $timezone = null)
41+
public function getValueInTz(?DateTimeZone $timezone = null): mixed
4642
{
4743
$value = $this->getValueAsDateTimeImmutable();
4844
if ($value === null) {
@@ -54,17 +50,16 @@ public function getValueInTz(?DateTimeZone $timezone = null)
5450
}
5551

5652
$value = $value->setTimezone($timezone);
53+
5754
return $this->transformValue($value);
5855
}
5956

6057
/**
6158
* @template T
62-
* @param string|callable $type
6359
* @phpstan-param class-string<T>|callable(DateTimeInterface): ?T $type
64-
* @return mixed
6560
* @phpstan-return ?T
6661
*/
67-
public function getValueInTzAs($type, ?DateTimeZone $timezone = null)
62+
public function getValueInTzAs(string|callable $type, ?DateTimeZone $timezone = null): mixed
6863
{
6964
$value = $this->getValueAsDateTimeImmutable();
7065
if ($value === null) {
@@ -99,14 +94,14 @@ public function getControl(): Html
9994
return $control;
10095
}
10196

102-
public static function register(?string $defaultFormat = null): void
97+
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
10398
{
104-
Container::extensionMethod(
105-
'addDateTime',
106-
function ($container, $name, $label = null, $format = null, ?DateTimeZone $inputTimezone = null) use ($defaultFormat): DateTimeInput {
107-
return $container[$name] = new DateTimeInput($label, $format ?? $defaultFormat, $inputTimezone);
108-
}
109-
);
99+
$datetime = parent::normalizeDateTime($datetime);
100+
if ($this->inputTimezone !== null) {
101+
$datetime = $datetime->setTimezone($this->inputTimezone);
102+
}
103+
104+
return $datetime;
110105
}
111106

112107
}

src/Controls/DateTime/DateTimeParser.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ public function setDefaultTimezone(?DateTimeZone $timezone): void
6262
$this->defaultTimeZone = $timezone;
6363
}
6464

65-
/**
66-
* @param mixed $value
67-
*/
68-
public function parse($value): ?DateTimeImmutable
65+
public function parse(mixed $value): ?DateTimeImmutable
6966
{
7067
if (!is_string($value) || strlen(trim($value)) === 0) {
7168
return null;

src/Controls/DateTime/TimeInput.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ class TimeInput extends AbstractDateTimeInput
1616

1717
protected string $htmlClass = 'time-input';
1818

19-
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
19+
public static function register(?string $defaultFormat = null): void
2020
{
21-
$datetime = parent::normalizeDateTime($datetime);
22-
$datetime = $datetime->setDate(1970, 1, 1);
23-
return $datetime;
21+
Container::extensionMethod(
22+
'addTime',
23+
fn ($container, $name, $label = null, $format = null): TimeInput => $container[$name] = new TimeInput($label, $format ?? $defaultFormat)
24+
);
2425
}
2526

2627
public function getControl(): Html
@@ -33,14 +34,12 @@ public function getControl(): Html
3334
return $control;
3435
}
3536

36-
public static function register(?string $defaultFormat = null): void
37+
protected function normalizeDateTime(DateTimeInterface $datetime): DateTimeImmutable
3738
{
38-
Container::extensionMethod(
39-
'addTime',
40-
function ($container, $name, $label = null, $format = null) use ($defaultFormat): TimeInput {
41-
return $container[$name] = new TimeInput($label, $format ?? $defaultFormat);
42-
}
43-
);
39+
$datetime = parent::normalizeDateTime($datetime);
40+
$datetime = $datetime->setDate(1970, 1, 1);
41+
42+
return $datetime;
4443
}
4544

4645
}

0 commit comments

Comments
 (0)