From ebe5af210aaecccb375b9ccedb65605f50488b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BA=D0=BE=D0=B2?= Date: Thu, 15 Jan 2026 16:14:25 +0400 Subject: [PATCH 1/5] configs + deps --- .github/workflows/rector-cs.yml | 28 +++++++++++ .github/workflows/rector.yml | 24 ---------- .gitignore | 4 ++ .php-cs-fixer.dist.php | 40 ++++++++++++++++ .styleci.yml | 85 --------------------------------- composer.json | 1 + 6 files changed, 73 insertions(+), 109 deletions(-) create mode 100644 .github/workflows/rector-cs.yml delete mode 100644 .github/workflows/rector.yml create mode 100644 .php-cs-fixer.dist.php delete mode 100644 .styleci.yml diff --git a/.github/workflows/rector-cs.yml b/.github/workflows/rector-cs.yml new file mode 100644 index 000000000..03b7c75cc --- /dev/null +++ b/.github/workflows/rector-cs.yml @@ -0,0 +1,28 @@ +name: Rector + PHP CS Fixer + +on: + pull_request_target: + paths: + - 'config/**' + - 'src/**' + - 'tests/**' + - '.github/workflows/rector-cs.yml' + - 'composer.json' + - 'rector.php' + - '.php-cs-fixer.dist.php' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rector: + uses: yiisoft/actions/.github/workflows/rector-cs.yml@master + secrets: + token: ${{ secrets.YIISOFT_GITHUB_TOKEN }} + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + php: '8.1' diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml deleted file mode 100644 index 5d6931d51..000000000 --- a/.github/workflows/rector.yml +++ /dev/null @@ -1,24 +0,0 @@ -on: - pull_request_target: - paths-ignore: - - 'docs/**' - - 'README.md' - - 'CHANGELOG.md' - - '.gitignore' - - '.gitattributes' - - 'infection.json.dist' - - 'psalm.xml' - -name: rector - -jobs: - rector: - uses: yiisoft/actions/.github/workflows/rector.yml@master - secrets: - token: ${{ secrets.YIISOFT_GITHUB_TOKEN }} - with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - os: >- - ['ubuntu-latest'] - php: >- - ['8.4'] diff --git a/.gitignore b/.gitignore index b37074da3..9ecba9a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,7 @@ phpunit.phar /phpunit.xml # phpunit cache /.phpunit.cache/ + +# PHP CS Fixer +/.php-cs-fixer.cache +/.php-cs-fixer.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 000000000..0d7313cb2 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,40 @@ +in([ + __DIR__ . '/config', + __DIR__ . '/src', + __DIR__ . '/tests', +]); + +// TODO: Update the configuration after raising the minimum PHP version +return (new Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PER-CS2.0' => true, + 'nullable_type_declaration' => true, + 'operator_linebreak' => true, + 'ordered_types' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'single_class_element_per_statement' => true, + 'types_spaces' => true, + 'no_unused_imports' => true, + 'ordered_class_elements' => true, + 'class_attributes_separation' => ['elements' => ['method' => 'one']], + 'declare_strict_types' => true, + 'native_function_invocation' => true, + 'native_constant_invocation' => true, + 'fully_qualified_strict_types' => [ + 'import_symbols' => true + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ], + ]) + ->setFinder($finder); + diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 1ab379b46..000000000 --- a/.styleci.yml +++ /dev/null @@ -1,85 +0,0 @@ -preset: psr12 -risky: true - -version: 8.1 - -finder: - exclude: - - docs - - vendor - -enabled: - - alpha_ordered_traits - - array_indentation - - array_push - - combine_consecutive_issets - - combine_consecutive_unsets - - combine_nested_dirname - - declare_strict_types - - dir_constant - - fully_qualified_strict_types - - function_to_constant - - hash_to_slash_comment - - is_null - - logical_operators - - magic_constant_casing - - magic_method_casing - - method_separation - - modernize_types_casting - - native_function_casing - - native_function_type_declaration_casing - - no_alias_functions - - no_empty_comment - - no_empty_phpdoc - - no_empty_statement - - no_extra_block_blank_lines - - no_short_bool_cast - - no_superfluous_elseif - - no_unneeded_control_parentheses - - no_unneeded_curly_braces - - no_unneeded_final_method - - no_unset_cast - - no_unused_imports - - no_unused_lambda_imports - - no_useless_else - - no_useless_return - - normalize_index_brace - - php_unit_dedicate_assert - - php_unit_dedicate_assert_internal_type - - php_unit_expectation - - php_unit_mock - - php_unit_mock_short_will_return - - php_unit_namespaced - - php_unit_no_expectation_annotation - - phpdoc_no_empty_return - - phpdoc_no_useless_inheritdoc - - phpdoc_order - - phpdoc_property - - phpdoc_scalar - - phpdoc_singular_inheritdoc - - phpdoc_trim - - phpdoc_trim_consecutive_blank_line_separation - - phpdoc_type_to_var - - phpdoc_types - - phpdoc_types_order - - print_to_echo - - regular_callable_call - - return_assignment - - self_accessor - - self_static_accessor - - set_type_to_cast - - short_array_syntax - - short_list_syntax - - simplified_if_return - - single_quote - - standardize_not_equals - - ternary_to_null_coalescing - - trailing_comma_in_multiline_array - - unalign_double_arrow - - unalign_equals - - empty_loop_body_braces - - integer_literal_case - - union_type_without_spaces - -disabled: - - function_declaration diff --git a/composer.json b/composer.json index 877af8d12..3452758b3 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "yiisoft/widget": "^2.2" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.56", "infection/infection": "^0.26.21 || ^0.29.14", "maglnet/composer-require-checker": "^4.7.1", "phpunit/phpunit": "^10.5.45", From 54a07a8a873b00474c0bf0e61f49351764aecc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BA=D0=BE=D0=B2?= Date: Thu, 15 Jan 2026 16:15:44 +0400 Subject: [PATCH 2/5] fix CS --- src/Field/Base/BaseField.php | 10 ++---- src/Field/Base/ButtonField.php | 4 +-- src/Field/Base/DateTimeInputField.php | 8 ++--- .../InputDataWithCustomNameAndValueTrait.php | 18 +++++------ src/Field/Base/InputField.php | 6 ++-- src/Field/Base/PartsField.php | 22 +++++++------ src/Field/Checkbox.php | 32 +++++++++---------- src/Field/CheckboxList.php | 2 +- src/Field/Color.php | 4 +-- src/Field/Email.php | 4 +-- src/Field/ErrorSummary.php | 3 ++ src/Field/File.php | 4 +-- src/Field/Image.php | 4 +-- src/Field/Number.php | 4 +-- src/Field/Part/Error.php | 4 ++- src/Field/Part/Hint.php | 2 +- src/Field/Part/Label.php | 2 +- src/Field/Password.php | 4 +-- src/Field/RadioList.php | 5 ++- src/Field/Range.php | 4 +-- src/Field/Select.php | 10 +++--- src/Field/Telephone.php | 4 +-- src/Field/Text.php | 4 +-- src/Field/Textarea.php | 7 ++-- src/Field/Url.php | 4 +-- src/PureField/FieldFactory.php | 3 +- src/PureField/InputData.php | 3 +- src/Theme/Theme.php | 2 ++ tests/ConfigTest.php | 4 ++- tests/Field/Base/BaseFieldTest.php | 2 +- tests/Field/Base/ButtonFieldTest.php | 2 +- tests/Field/Base/DateTimeInputFieldTest.php | 4 +-- tests/Field/Base/FieldContentTraitTest.php | 2 ++ tests/Field/Base/InputFieldTest.php | 4 +-- tests/Field/Base/PartsFieldTest.php | 6 ++-- tests/Field/ButtonTest.php | 2 +- tests/Field/CheckboxListTest.php | 6 ++-- tests/Field/CheckboxTest.php | 8 ++--- tests/Field/ColorTest.php | 7 ++-- tests/Field/EmailTest.php | 4 +-- tests/Field/ErrorSummaryTest.php | 10 +++--- tests/Field/FieldsetTest.php | 4 +-- tests/Field/FileTest.php | 16 +++++----- tests/Field/ImageTest.php | 2 +- tests/Field/NumberTest.php | 4 +-- tests/Field/Part/ErrorTest.php | 30 ++++++++--------- tests/Field/PasswordTest.php | 24 +++++++------- tests/Field/RadioListTest.php | 10 +++--- tests/Field/RangeTest.php | 14 ++++---- tests/Field/ResetButtonTest.php | 2 +- tests/Field/SelectTest.php | 8 ++--- tests/Field/SubmitButtonTest.php | 10 +++--- tests/Field/TelephoneTest.php | 24 +++++++------- tests/Field/TextTest.php | 16 +++++----- tests/Field/TextareaTest.php | 30 ++++++++--------- tests/Field/UrlTest.php | 6 ++-- tests/Support/StringableObject.php | 5 ++- tests/Support/StubBaseField.php | 3 +- tests/Support/StubInputField.php | 2 +- tests/Support/StubValidationRulesEnricher.php | 3 +- tests/Theme/ThemeTest.php | 4 +-- 61 files changed, 234 insertions(+), 227 deletions(-) diff --git a/src/Field/Base/BaseField.php b/src/Field/Base/BaseField.php index 36cedadd3..53bc266c5 100644 --- a/src/Field/Base/BaseField.php +++ b/src/Field/Base/BaseField.php @@ -67,7 +67,7 @@ final public function containerId(?string $id): static final public function containerClass(?string ...$class): static { $new = clone $this; - $new->containerAttributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->containerAttributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } @@ -127,9 +127,7 @@ final public function render(): string return $result; } - protected function beforeRender(): void - { - } + protected function beforeRender(): void {} abstract protected function generateContent(): ?string; @@ -143,9 +141,7 @@ protected function generateEndContent(): string return ''; } - protected function prepareContainerAttributes(array &$attributes): void - { - } + protected function prepareContainerAttributes(array &$attributes): void {} final protected static function getThemeConfig(?string $theme): array { diff --git a/src/Field/Base/ButtonField.php b/src/Field/Base/ButtonField.php index 021e8bdb2..847e5c2c7 100644 --- a/src/Field/Base/ButtonField.php +++ b/src/Field/Base/ButtonField.php @@ -58,7 +58,7 @@ final public function buttonId(?string $id): static final public function buttonClass(?string ...$class): static { $new = clone $this; - $new->buttonAttributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->buttonAttributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } @@ -92,7 +92,7 @@ final public function name(?string $name): self final public function ariaDescribedBy(?string ...$value): static { $new = clone $this; - $new->buttonAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->buttonAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } diff --git a/src/Field/Base/DateTimeInputField.php b/src/Field/Base/DateTimeInputField.php index e02ce2f82..e0aee0ee8 100644 --- a/src/Field/Base/DateTimeInputField.php +++ b/src/Field/Base/DateTimeInputField.php @@ -48,7 +48,7 @@ final public function min(?string $value): static final public function ariaDescribedBy(?string ...$value): static { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -157,15 +157,15 @@ final protected function generateInput(): string $value = $this->formatDateTime($value); } elseif (!is_string($value) && $value !== null) { throw new InvalidArgumentException( - (new ReflectionClass($this))->getShortName() . - ' field requires a string or null value.' + (new ReflectionClass($this))->getShortName() + . ' field requires a string or null value.', ); } /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::input($this->getInputType(), $this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/Base/InputData/InputDataWithCustomNameAndValueTrait.php b/src/Field/Base/InputData/InputDataWithCustomNameAndValueTrait.php index d69045885..525fe0dcc 100644 --- a/src/Field/Base/InputData/InputDataWithCustomNameAndValueTrait.php +++ b/src/Field/Base/InputData/InputDataWithCustomNameAndValueTrait.php @@ -31,15 +31,6 @@ final public function inputData(InputDataInterface $inputData): static return $new; } - final protected function getInputData(): InputDataInterface - { - if ($this->inputData === null) { - $this->inputData = new InputData(); - } - - return $this->inputData; - } - final public function name(?string $name): static { $new = clone $this; @@ -66,6 +57,15 @@ final public function prepareValue(?callable $callback): static return $new; } + final protected function getInputData(): InputDataInterface + { + if ($this->inputData === null) { + $this->inputData = new InputData(); + } + + return $this->inputData; + } + final protected function getName(): ?string { return $this->useCustomName diff --git a/src/Field/Base/InputField.php b/src/Field/Base/InputField.php index 474ba2653..edf06ea0f 100644 --- a/src/Field/Base/InputField.php +++ b/src/Field/Base/InputField.php @@ -69,7 +69,7 @@ final public function addInputAttributes(array $attributes): static final public function inputClass(?string ...$class): static { $new = clone $this; - $new->inputAttributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->inputAttributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } @@ -96,9 +96,7 @@ final protected function getInputAttributes(): array return $attributes; } - protected function prepareInputAttributes(array &$attributes): void - { - } + protected function prepareInputAttributes(array &$attributes): void {} final protected function prepareIdInInputAttributes(array &$attributes): void { diff --git a/src/Field/Base/PartsField.php b/src/Field/Base/PartsField.php index 06f348593..ecdc4207d 100644 --- a/src/Field/Base/PartsField.php +++ b/src/Field/Base/PartsField.php @@ -12,6 +12,8 @@ use Yiisoft\Html\Html; use function in_array; +use function is_array; +use function is_string; abstract class PartsField extends BaseField { @@ -25,12 +27,6 @@ abstract class PartsField extends BaseField '{error}', ]; - /** - * @var string[]|Stringable[] - * @psalm-var array - */ - private array $extraTokens = []; - protected string $templateBegin = "{label}\n{input}"; protected string $templateEnd = "{input}\n{hint}\n{error}"; protected string $template = "{label}\n{input}\n{hint}\n{error}"; @@ -46,6 +42,12 @@ abstract class PartsField extends BaseField protected string|Stringable $beforeInput = ''; protected string|Stringable $afterInput = ''; + /** + * @var string[]|Stringable[] + * @psalm-var array + */ + private array $extraTokens = []; + private bool $replaceLabelAttributes = false; private bool $replaceLabelClass = false; private array $labelAttributes = []; @@ -71,7 +73,7 @@ final public function tokens(array $tokens): static sprintf( 'Token should be string. %s given.', get_debug_type($token), - ) + ), ); } @@ -80,7 +82,7 @@ final public function tokens(array $tokens): static sprintf( 'Token value should be string or Stringable. %s given.', get_debug_type($value), - ) + ), ); } @@ -165,7 +167,7 @@ final public function addInputContainerAttributes(array $attributes): static final public function inputContainerClass(?string ...$class): static { $new = clone $this; - $new->inputContainerAttributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->inputContainerAttributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } @@ -610,7 +612,7 @@ private function validateToken(string $token): void sprintf( 'Token name "%s" is built-in.', $token, - ) + ), ); } } diff --git a/src/Field/Checkbox.php b/src/Field/Checkbox.php index 1824bce7f..f6cc9b839 100644 --- a/src/Field/Checkbox.php +++ b/src/Field/Checkbox.php @@ -40,7 +40,7 @@ final class Checkbox extends InputField implements ValidationClassInterface public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -156,7 +156,7 @@ public function inputLabelId(?string $id): self public function inputLabelClass(?string ...$class): self { $new = clone $this; - $new->inputLabelAttributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->inputLabelAttributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } @@ -231,7 +231,7 @@ protected function generateInput(): string && $value !== null ) { throw new InvalidArgumentException( - 'Checkbox widget requires a string, Stringable, numeric, bool or null value.' + 'Checkbox widget requires a string, Stringable, numeric, bool or null value.', ); } @@ -277,19 +277,6 @@ protected function shouldHideLabel(): bool return $this->getLabelPlacement() !== CheckboxLabelPlacement::DEFAULT; } - private function prepareCheckboxValue(mixed $value): ?string - { - if ($value === null) { - return null; - } - - if (is_bool($value)) { - return $value ? '1' : '0'; - } - - return (string) $value; - } - protected function prepareContainerAttributes(array &$attributes): void { $this->addValidationClassToAttributes( @@ -308,6 +295,19 @@ protected function prepareInputAttributes(array &$attributes): void ); } + private function prepareCheckboxValue(mixed $value): ?string + { + if ($value === null) { + return null; + } + + if (is_bool($value)) { + return $value ? '1' : '0'; + } + + return (string) $value; + } + private function getLabelPlacement(): CheckboxLabelPlacement { // If default value, use deprecated `enclosedByLabel` property diff --git a/src/Field/CheckboxList.php b/src/Field/CheckboxList.php index bc384cf43..40c1a98e2 100644 --- a/src/Field/CheckboxList.php +++ b/src/Field/CheckboxList.php @@ -204,7 +204,7 @@ protected function generateInput(): string $value ??= []; if (!is_iterable($value)) { throw new InvalidArgumentException( - '"CheckboxList" field requires iterable or null value.' + '"CheckboxList" field requires iterable or null value.', ); } /** @psalm-var iterable $value */ diff --git a/src/Field/Color.php b/src/Field/Color.php index 65b6f0d86..6ac295700 100644 --- a/src/Field/Color.php +++ b/src/Field/Color.php @@ -71,7 +71,7 @@ public function required(bool $value = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -145,7 +145,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::input('color', $this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/Email.php b/src/Field/Email.php index 2f2c47f8b..6ed2d0e8e 100644 --- a/src/Field/Email.php +++ b/src/Field/Email.php @@ -144,7 +144,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -218,7 +218,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::input('email', $this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/ErrorSummary.php b/src/Field/ErrorSummary.php index a7feb99f3..423fdb1b4 100644 --- a/src/Field/ErrorSummary.php +++ b/src/Field/ErrorSummary.php @@ -10,6 +10,9 @@ use Yiisoft\Html\Tag\CustomTag; use function in_array; +use function array_slice; + +use const ARRAY_FILTER_USE_KEY; /** * @psalm-type Errors = array> diff --git a/src/Field/File.php b/src/Field/File.php index 699418270..927839bb6 100644 --- a/src/Field/File.php +++ b/src/Field/File.php @@ -86,7 +86,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -165,7 +165,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); $tag = Html::file($this->getName(), attributes: $inputAttributes); diff --git a/src/Field/Image.php b/src/Field/Image.php index 70d334940..04bd8171a 100644 --- a/src/Field/Image.php +++ b/src/Field/Image.php @@ -85,7 +85,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -143,7 +143,7 @@ protected function generateInput(): string { return Html::input( type: 'image', - attributes: $this->inputAttributes + attributes: $this->inputAttributes, )->render(); } } diff --git a/src/Field/Number.php b/src/Field/Number.php index 406dc3f18..6e0b619a3 100644 --- a/src/Field/Number.php +++ b/src/Field/Number.php @@ -105,7 +105,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -179,7 +179,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::input('number', $this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/Part/Error.php b/src/Field/Part/Error.php index a593c15a5..029dc07ae 100644 --- a/src/Field/Part/Error.php +++ b/src/Field/Part/Error.php @@ -12,6 +12,8 @@ use Yiisoft\Html\Tag\CustomTag; use Yiisoft\Widget\Widget; +use function count; + /** * Represent a field validation error (if there are several errors, the first one is used). If field is no validation * error, field part will be hidden. @@ -129,7 +131,7 @@ public function addClass(?string ...$class): self public function class(?string ...$class): self { $new = clone $this; - $new->attributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->attributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } diff --git a/src/Field/Part/Hint.php b/src/Field/Part/Hint.php index f7f49c118..78370e533 100644 --- a/src/Field/Part/Hint.php +++ b/src/Field/Part/Hint.php @@ -78,7 +78,7 @@ public function id(?string $id): self public function class(?string ...$class): self { $new = clone $this; - $new->attributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->attributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } diff --git a/src/Field/Part/Label.php b/src/Field/Part/Label.php index e6edcd2db..b3320ce9c 100644 --- a/src/Field/Part/Label.php +++ b/src/Field/Part/Label.php @@ -62,7 +62,7 @@ public function id(?string $id): self public function class(?string ...$class): self { $new = clone $this; - $new->attributes['class'] = array_filter($class, static fn ($c) => $c !== null); + $new->attributes['class'] = array_filter($class, static fn($c) => $c !== null); return $new; } diff --git a/src/Field/Password.php b/src/Field/Password.php index 4ae1abca8..43fda8d22 100644 --- a/src/Field/Password.php +++ b/src/Field/Password.php @@ -121,7 +121,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -209,7 +209,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::passwordInput($this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/RadioList.php b/src/Field/RadioList.php index 2255c1ea2..9c87bd888 100644 --- a/src/Field/RadioList.php +++ b/src/Field/RadioList.php @@ -18,6 +18,9 @@ use Yiisoft\Html\Widget\RadioList\RadioItem; use Yiisoft\Html\Widget\RadioList\RadioList as RadioListWidget; +use function is_bool; +use function is_string; + /** * @see RadioListWidget */ @@ -206,7 +209,7 @@ protected function generateInput(): string && $value !== null ) { throw new InvalidArgumentException( - '"RadioList" field requires a string, Stringable, numeric, bool or null value.' + '"RadioList" field requires a string, Stringable, numeric, bool or null value.', ); } /** @psalm-var Stringable|scalar $value */ diff --git a/src/Field/Range.php b/src/Field/Range.php index 3add16025..646f7c7d5 100644 --- a/src/Field/Range.php +++ b/src/Field/Range.php @@ -101,7 +101,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -207,7 +207,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); $tag = Html::range($this->getName(), $value, $inputAttributes); diff --git a/src/Field/Select.php b/src/Field/Select.php index 79a6ba40d..8fb24eb34 100644 --- a/src/Field/Select.php +++ b/src/Field/Select.php @@ -92,7 +92,7 @@ public function optionsData( array $data, bool $encode = true, array $optionsAttributes = [], - array $groupsAttributes = [] + array $groupsAttributes = [], ): self { $new = clone $this; $new->select = $this->select->optionsData($data, $encode, $optionsAttributes, $groupsAttributes); @@ -119,7 +119,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -259,7 +259,7 @@ protected function generateInput(): string $value ??= []; if (!is_iterable($value)) { throw new InvalidArgumentException( - 'Select field with multiple option requires iterable or null value.' + 'Select field with multiple option requires iterable or null value.', ); } } else { @@ -270,7 +270,7 @@ protected function generateInput(): string && $value !== null ) { throw new InvalidArgumentException( - 'Non-multiple select field requires a string, Stringable, numeric, bool, backed enumeration or null value.' + 'Non-multiple select field requires a string, Stringable, numeric, bool, backed enumeration or null value.', ); } $value = $value === null ? [] : [$value]; @@ -279,7 +279,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $selectAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); /** @psalm-var iterable $value */ diff --git a/src/Field/Telephone.php b/src/Field/Telephone.php index 2590c7c2a..5ab2cd2bd 100644 --- a/src/Field/Telephone.php +++ b/src/Field/Telephone.php @@ -116,7 +116,7 @@ public function disabled(bool $disabled = true): self public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -204,7 +204,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::input('tel', $this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/Text.php b/src/Field/Text.php index f5013c06a..79e5532e4 100644 --- a/src/Field/Text.php +++ b/src/Field/Text.php @@ -36,7 +36,7 @@ final class Text extends InputField implements EnrichFromValidationRulesInterfac public function ariaDescribedBy(?string ...$value): self { $new = clone $this; - $new->inputAttributes['aria-describedby'] = array_filter($value, static fn (?string $v): bool => $v !== null); + $new->inputAttributes['aria-describedby'] = array_filter($value, static fn(?string $v): bool => $v !== null); return $new; } @@ -220,7 +220,7 @@ protected function generateInput(): string /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */ $inputAttributes = array_merge( $this->enrichment['inputAttributes'] ?? [], - $this->getInputAttributes() + $this->getInputAttributes(), ); return Html::textInput($this->getName(), $value, $inputAttributes)->render(); diff --git a/src/Field/Textarea.php b/src/Field/Textarea.php index cd3b9ad76..683af8a17 100644 --- a/src/Field/Textarea.php +++ b/src/Field/Textarea.php @@ -16,6 +16,7 @@ use Yiisoft\Html\Html; use function is_string; +use function is_array; /** * Represents `', - $result + $result, ); } @@ -138,7 +138,7 @@ public function testMinlength(): void $this->assertSame( '', - $result + $result, ); } @@ -153,7 +153,7 @@ public function testDirname(): void $this->assertSame( '', - $result + $result, ); } @@ -168,7 +168,7 @@ public function testReadonly(): void $this->assertSame( '', - $result + $result, ); } @@ -183,7 +183,7 @@ public function testRequired(): void $this->assertSame( '', - $result + $result, ); } @@ -198,7 +198,7 @@ public function testDisabled(): void $this->assertSame( '', - $result + $result, ); } @@ -251,7 +251,7 @@ public function testAriaLabel(): void $this->assertSame( '', - $result + $result, ); } @@ -266,7 +266,7 @@ public function testAutofocus(): void $this->assertSame( '', - $result + $result, ); } @@ -281,7 +281,7 @@ public function testTabIndex(): void $this->assertSame( '', - $result + $result, ); } @@ -296,7 +296,7 @@ public function testCols(): void $this->assertSame( '', - $result + $result, ); } @@ -311,7 +311,7 @@ public function testRows(): void $this->assertSame( '', - $result + $result, ); } @@ -326,7 +326,7 @@ public function testWrap(): void $this->assertSame( '', - $result + $result, ); } @@ -336,7 +336,7 @@ public function testInvalidValue(): void $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( - 'Textarea field requires a string, a stringable object, an array of strings or null value.' + 'Textarea field requires a string, a stringable object, an array of strings or null value.', ); $widget->render(); } @@ -348,7 +348,7 @@ public function testEnrichFromValidationRulesEnabled(): void ->validationRulesEnricher( new StubValidationRulesEnricher([ 'inputAttributes' => ['data-test' => 1], - ]) + ]), ) ->render(); @@ -412,7 +412,7 @@ public function testEnrichFromValidationRulesDisabled(): void ->validationRulesEnricher( new StubValidationRulesEnricher([ 'inputAttributes' => ['data-test' => 1], - ]) + ]), ) ->render(); diff --git a/tests/Field/UrlTest.php b/tests/Field/UrlTest.php index d58139061..e8b9bd68d 100644 --- a/tests/Field/UrlTest.php +++ b/tests/Field/UrlTest.php @@ -76,7 +76,7 @@ public static function dataBase(): array new InputData( name: 'site', value: '', - placeholder: 'test' + placeholder: 'test', ), ], ]; @@ -338,7 +338,7 @@ public function testEnrichFromValidationRulesEnabled(): void ->validationRulesEnricher( new StubValidationRulesEnricher([ 'inputAttributes' => ['data-test' => 1], - ]) + ]), ) ->render(); @@ -402,7 +402,7 @@ public function testEnrichFromValidationRulesDisabled(): void ->validationRulesEnricher( new StubValidationRulesEnricher([ 'inputAttributes' => ['data-test' => 1], - ]) + ]), ) ->render(); diff --git a/tests/Support/StringableObject.php b/tests/Support/StringableObject.php index 331a17cf8..ca6aa6963 100644 --- a/tests/Support/StringableObject.php +++ b/tests/Support/StringableObject.php @@ -9,9 +9,8 @@ final class StringableObject implements Stringable { public function __construct( - private string $string - ) { - } + private string $string, + ) {} public function __toString(): string { diff --git a/tests/Support/StubBaseField.php b/tests/Support/StubBaseField.php index 3f1601164..1aa27095a 100644 --- a/tests/Support/StubBaseField.php +++ b/tests/Support/StubBaseField.php @@ -14,8 +14,7 @@ public function __construct( private ?string $endContent = null, private ?string $beforeRenderBeginContent = null, private ?string $beforeRenderEndContent = null, - ) { - } + ) {} protected function beforeRender(): void { diff --git a/tests/Support/StubInputField.php b/tests/Support/StubInputField.php index 577920c47..be61fea45 100644 --- a/tests/Support/StubInputField.php +++ b/tests/Support/StubInputField.php @@ -20,7 +20,7 @@ protected function generateInput(): string return Html::textInput( $this->getName(), (string) $this->getValue(), - $this->getInputAttributes() + $this->getInputAttributes(), )->render(); } } diff --git a/tests/Support/StubValidationRulesEnricher.php b/tests/Support/StubValidationRulesEnricher.php index 46c82e8cd..a860be3a4 100644 --- a/tests/Support/StubValidationRulesEnricher.php +++ b/tests/Support/StubValidationRulesEnricher.php @@ -11,8 +11,7 @@ final class StubValidationRulesEnricher implements ValidationRulesEnricherInterf { public function __construct( private ?array $result, - ) { - } + ) {} public function process(BaseField $field, mixed $rules): ?array { diff --git a/tests/Theme/ThemeTest.php b/tests/Theme/ThemeTest.php index 425352990..628b3bfdc 100644 --- a/tests/Theme/ThemeTest.php +++ b/tests/Theme/ThemeTest.php @@ -563,7 +563,7 @@ public function testTextWithCustomTheme(): void
HTML, - $result + $result, ); } @@ -784,7 +784,7 @@ public function testNotExistTheme(): void HTML, - $html + $html, ); } From 5bf9a94a14d3be7e2ff6953e86e603a0175712c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BA=D0=BE=D0=B2?= Date: Thu, 15 Jan 2026 16:16:35 +0400 Subject: [PATCH 3/5] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62062d14e..670cbfa52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.5.2 under development -- no changes in this release. +- Enh #384: Explicitly import classes, functions, and constants in "use" section (@mspirkov) ## 1.5.1 December 23, 2025 From 16a06c7d06713fb51bc5e8b396274487f64d0e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BA=D0=BE=D0=B2?= Date: Thu, 15 Jan 2026 16:16:58 +0400 Subject: [PATCH 4/5] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 670cbfa52..7d65202db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.5.2 under development -- Enh #384: Explicitly import classes, functions, and constants in "use" section (@mspirkov) +- Enh #384: Explicitly import functions and constants in "use" section (@mspirkov) ## 1.5.1 December 23, 2025 From de2150c605acd332616785416a0880cf2d10df2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BA=D0=BE=D0=B2?= Date: Fri, 16 Jan 2026 10:29:24 +0400 Subject: [PATCH 5/5] update PHP CS Fixer --- .php-cs-fixer.dist.php | 11 +++-------- composer.json | 2 +- src/Field/Base/PartsField.php | 1 + 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 0d7313cb2..7571f3048 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,6 +4,7 @@ use PhpCsFixer\Config; use PhpCsFixer\Finder; +use PhpCsFixer\Runner\Parallel\ParallelConfigFactory; $finder = (new Finder())->in([ __DIR__ . '/config', @@ -11,16 +12,11 @@ __DIR__ . '/tests', ]); -// TODO: Update the configuration after raising the minimum PHP version return (new Config()) ->setRiskyAllowed(true) + ->setParallelConfig(ParallelConfigFactory::detect()) ->setRules([ - '@PER-CS2.0' => true, - 'nullable_type_declaration' => true, - 'operator_linebreak' => true, - 'ordered_types' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'single_class_element_per_statement' => true, - 'types_spaces' => true, + '@PER-CS3.0' => true, 'no_unused_imports' => true, 'ordered_class_elements' => true, 'class_attributes_separation' => ['elements' => ['method' => 'one']], @@ -37,4 +33,3 @@ ], ]) ->setFinder($finder); - diff --git a/composer.json b/composer.json index 7d670d0fb..a1609b84b 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "yiisoft/widget": "^2.2" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.56", + "friendsofphp/php-cs-fixer": "^3.92", "bamarni/composer-bin-plugin": "^1.8.3", "maglnet/composer-require-checker": "^4.7.1", "phpunit/phpunit": "^10.5.45", diff --git a/src/Field/Base/PartsField.php b/src/Field/Base/PartsField.php index ecdc4207d..f49c037f5 100644 --- a/src/Field/Base/PartsField.php +++ b/src/Field/Base/PartsField.php @@ -14,6 +14,7 @@ use function in_array; use function is_array; use function is_string; +use function sprintf; abstract class PartsField extends BaseField {