diff --git a/.phpstan-baseline.php b/.phpstan-baseline.php new file mode 100644 index 0000000000000000000000000000000000000000..b624e6eeff785959b60c30abe919307f2c243af2 --- /dev/null +++ b/.phpstan-baseline.php @@ -0,0 +1,347 @@ +<?php declare(strict_types = 1); + +$ignoreErrors = []; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:get_type\\(\\) should return string but returns mixed\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:unset_attribute\\(\\) has invalid return type WPDesk\\\\Forms\\\\Field\\\\Traits\\\\HtmlAttributes\\.$#', + 'identifier' => 'return.trait', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:unset_attribute\\(\\) should return WPDesk\\\\Forms\\\\Field\\\\Traits\\\\HtmlAttributes but returns \\$this\\(WPDesk\\\\Forms\\\\Field\\\\BasicField\\)\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'class\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'data\' on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'default_value\' on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'description\' on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'description_tip\' on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'disabled\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? does not exist\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'id\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'label\' on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'multiple\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} in isset\\(\\) does not exist\\.$#', + 'identifier' => 'isset.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'name\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'placeholder\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'readonly\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? does not exist\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'required\' on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} in isset\\(\\) does not exist\\.$#', + 'identifier' => 'isset.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'type\' does not exist on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\}\\.$#', + 'identifier' => 'offsetAccess.notFound', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset string on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept array\\{placeholder\\?\\: string, name\\?\\: string, id\\?\\: string, class\\?\\: array\\<string\\>\\}\\.$#', + 'identifier' => 'assign.propertyType', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept default value of type array\\{\\}\\.$#', + 'identifier' => 'property.defaultValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept non\\-empty\\-array\\<string, array\\<string\\>\\|bool\\|string\\>\\.$#', + 'identifier' => 'assign.propertyType', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Return type \\(array\\<array\\<string\\>\\|bool\\|string\\>\\) of method WPDesk\\\\Forms\\\\Field\\\\BasicField\\:\\:get_attributes\\(\\) should be covariant with return type \\(array\\<string\\>\\) of method WPDesk\\\\Forms\\\\Field\\:\\:get_attributes\\(\\)$#', + 'identifier' => 'method.childReturnType', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/BasicField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'sublabel\' might not exist on array\\{default_value\\: string, possible_values\\?\\: array\\<string\\>, sublabel\\?\\: string, priority\\: int, label\\: string, description\\: string, description_tip\\: string, data\\: array\\<int\\|string\\>\\}\\.$#', + 'identifier' => 'offsetAccess.notFound', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/CheckboxField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$action of class WPDesk\\\\Forms\\\\Validator\\\\NonceValidator constructor expects string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Field/NoOnceField.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\FieldRenderer\\:\\:render_fields\\(\\) has parameter \\$fields_data with no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/FieldRenderer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\FieldRenderer\\:\\:render_fields\\(\\) return type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/FieldRenderer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\:\\:get_normalized_data\\(\\) return type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\:\\:handle_request\\(\\) has parameter \\$request with no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:get_action\\(\\) should return string but returns mixed\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:get_data\\(\\) should return array\\<int\\|string\\> but returns array\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:get_method\\(\\) should return string but returns mixed\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:get_normalized_data\\(\\) return type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:handle_request\\(\\) has parameter \\$request with no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:unset_attribute\\(\\) has invalid return type WPDesk\\\\Forms\\\\Field\\\\Traits\\\\HtmlAttributes\\.$#', + 'identifier' => 'return.trait', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:unset_attribute\\(\\) should return WPDesk\\\\Forms\\\\Field\\\\Traits\\\\HtmlAttributes but returns \\$this\\(WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\)\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'action\' does not exist on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\.$#', + 'identifier' => 'offsetAccess.notFound', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset \'method\' does not exist on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\.$#', + 'identifier' => 'offsetAccess.notFound', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Offset string on array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\} on left side of \\?\\? always exists and is not nullable\\.$#', + 'identifier' => 'nullCoalesce.offset', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#2 \\$value of method WPDesk\\\\Persistence\\\\PersistentContainer\\:\\:set\\(\\) expects array\\|float\\|int\\|string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 2, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept array\\{placeholder\\?\\: string, name\\?\\: string, id\\?\\: string, class\\?\\: array\\<string\\>\\}\\.$#', + 'identifier' => 'assign.propertyType', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept default value of type array\\{\\}\\.$#', + 'identifier' => 'property.defaultValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:\\$attributes \\(array\\{placeholder\\: string, name\\: string, id\\: string, class\\: array\\<string\\>\\}\\) does not accept non\\-empty\\-array\\<string, array\\<string\\>\\|bool\\|string\\>\\.$#', + 'identifier' => 'assign.propertyType', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Form\\\\FormWithFields\\:\\:\\$updated_data type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Form/FormWithFields.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Persistence\\\\FieldPersistenceStrategy\\:\\:load_fields\\(\\) return type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Persistence/FieldPersistenceStrategy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Persistence\\\\FieldPersistenceStrategy\\:\\:persist_fields\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Persistence/FieldPersistenceStrategy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^PHPDoc tag @return with type void is incompatible with native type array\\.$#', + 'identifier' => 'return.phpDocType', + 'count' => 1, + 'path' => __DIR__ . '/src/Persistence/FieldPersistenceStrategy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$value of method WPDesk\\\\Forms\\\\Serializer\\:\\:unserialize\\(\\) expects string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Persistence/FieldPersistenceStrategy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#2 \\$value of method WPDesk\\\\Persistence\\\\PersistentContainer\\:\\:set\\(\\) expects array\\|float\\|int\\|string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Persistence/FieldPersistenceStrategy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Renderer\\\\JsonNormalizedRenderer\\:\\:render_fields\\(\\) has parameter \\$fields_data with no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Renderer/JsonNormalizedRenderer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Renderer\\\\JsonNormalizedRenderer\\:\\:render_fields\\(\\) return type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Renderer/JsonNormalizedRenderer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Sanitizer\\\\CallableSanitizer\\:\\:sanitize\\(\\) should return string but returns mixed\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Sanitizer/CallableSanitizer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$email of function sanitize_email expects string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Sanitizer/EmailSanitizer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, \'sanitize_text_field\' given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Sanitizer/TextFieldSanitizer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$str of function sanitize_text_field expects string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Sanitizer/TextFieldSanitizer.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Method WPDesk\\\\Forms\\\\Validator\\\\ChainValidator\\:\\:get_messages\\(\\) should return array\\<string\\> but returns array\\.$#', + 'identifier' => 'return.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Validator/ChainValidator.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Property WPDesk\\\\Forms\\\\Validator\\\\ChainValidator\\:\\:\\$messages type has no value type specified in iterable type array\\.$#', + 'identifier' => 'missingType.iterableValue', + 'count' => 1, + 'path' => __DIR__ . '/src/Validator/ChainValidator.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#1 \\$nonce of function wp_verify_nonce expects string, mixed given\\.$#', + 'identifier' => 'argument.type', + 'count' => 1, + 'path' => __DIR__ . '/src/Validator/NonceValidator.php', +]; + +return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/changelog.txt b/changelog.txt index c21b67cfeb3a0ea78d21e852f119709f861baebd..bf68f37b287f3b55f69d663661ca549a1f45dfa4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ # Changelog +## [3.3.0] - 2025-04-15 +### Added +- ToggleField class, extends CheckboxField for toggle button functionality. +### Changed +- Declared nullable parameter types (e.g. `?string`, `?Renderer`) to fix PHP 8.4 deprecation warnings about implicitly nullable parameters. + ## [3.2.1] - 2024-10-30 ### Changed - Raised required PHP version to 7.4. diff --git a/composer.json b/composer.json index 92744224c28f499788ba57082ef0ee1d5066f7a2..874f03ffd1d1037ca017511a6365dbc48d244a90 100644 --- a/composer.json +++ b/composer.json @@ -44,6 +44,9 @@ } }, "scripts": { + "phpcs": "phpcs", + "phpstan": "php -d memory_limit=1G vendor/bin/phpstan", + "phpcbf": "phpcbf src", "phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never", "phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage", "phpunit-integration": "phpunit --configuration phpunit-integration.xml --coverage-text --colors=never", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 200d200a6b18db3d5abbcd4e9ee9edbd96924c25..422f90cabdc9d2be2923a706619d4c95590de1a0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,3 +1,5 @@ +includes: + - .phpstan-baseline.php parameters: level: max paths: diff --git a/src/Field.php b/src/Field.php index b932f273f01a7dff40ffeedd12be722d943e0869..14b02592ef679ab0a26d4cbb843433a6fef22d54 100644 --- a/src/Field.php +++ b/src/Field.php @@ -55,7 +55,7 @@ interface Field { */ public function get_attributes( array $except = [] ): array; - public function get_attribute( string $name, string $default = null ): string; + public function get_attribute( string $name, ?string $default = null ): string; public function is_attribute_set( string $name ): bool; diff --git a/src/Field/ToggleField.php b/src/Field/ToggleField.php new file mode 100644 index 0000000000000000000000000000000000000000..79ff440bb27bd98ede1e6fedab22b42d6544c32a --- /dev/null +++ b/src/Field/ToggleField.php @@ -0,0 +1,14 @@ +<?php + +namespace WPDesk\Forms\Field; + +class ToggleField extends CheckboxField { + + public function __construct() { + $this->add_class( 'wpd-toggle-field' ); + } + + public function get_template_name(): string { + return 'input-toggle'; + } +} diff --git a/src/Field/Traits/HtmlAttributes.php b/src/Field/Traits/HtmlAttributes.php index aac835dbaf3389d38cd4477a3e239840138285ce..95a7a421eddb770d860ad39b657df41d6da4ffef 100644 --- a/src/Field/Traits/HtmlAttributes.php +++ b/src/Field/Traits/HtmlAttributes.php @@ -57,7 +57,7 @@ trait HtmlAttributes { return ! empty( $this->attributes[ $name ] ); } - final public function get_attribute( string $name, string $default = null ): string { + final public function get_attribute( string $name, ?string $default = null ): string { if ( is_array( $this->attributes[ $name ] ) ) { // Be aware of coercing - if implode returns string(0) '', then return $default value. return implode( ' ', $this->attributes[ $name ] ) ?: $default ?? ''; diff --git a/src/Persistence/FieldPersistenceStrategy.php b/src/Persistence/FieldPersistenceStrategy.php index 3102f1ce6f69d8f9dc6f790a9a885e92076d3e39..7fa7dcc76587bd2e68d201f29ef34e2dcd276a5c 100644 --- a/src/Persistence/FieldPersistenceStrategy.php +++ b/src/Persistence/FieldPersistenceStrategy.php @@ -43,9 +43,7 @@ class FieldPersistenceStrategy { } else { $data[ $field_key ] = $this->persistence->get( $field_key ); } - } catch ( NotFoundExceptionInterface $not_found ) { - // TODO: Logger - // LoggerFactory::get_logger()->info( "FieldPersistenceStrategy:: Field {$field_key} not found" ); + } catch ( NotFoundExceptionInterface $not_found ) { //phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch } } diff --git a/src/Resolver/DefaultFormFieldResolver.php b/src/Resolver/DefaultFormFieldResolver.php index 4e3077a0cb2b87ef000ac269d3411a9e5a1cf70b..23f5a522011d6ff4a0b92936446c0aeed625051d 100644 --- a/src/Resolver/DefaultFormFieldResolver.php +++ b/src/Resolver/DefaultFormFieldResolver.php @@ -20,7 +20,7 @@ class DefaultFormFieldResolver implements Resolver { $this->dir_resolver = new DirResolver( __DIR__ . '/../../templates' ); } - public function resolve( $name, Renderer $renderer = null ): string { + public function resolve( $name, ?Renderer $renderer = null ): string { return $this->dir_resolver->resolve( $name, $renderer ); } } diff --git a/templates/input-toggle.php b/templates/input-toggle.php new file mode 100644 index 0000000000000000000000000000000000000000..848cdf819581485a2b5eeceb54b648c11bf1d2a8 --- /dev/null +++ b/templates/input-toggle.php @@ -0,0 +1,56 @@ +<?php +/** + * @var \WPDesk\Forms\Field $field + * @var \WPDesk\View\Renderer\Renderer $renderer + * @var string $name_prefix + * @var string $value + * @var string $template_name Real field template. + */ + +?> + +<style> + input[type="checkbox"].wpd-toggle-field { + all:unset; + background: #fff; + border:1px solid #949494; + width:32px; + height: 16px; + position: relative; + cursor: pointer; + border-radius: 200px; + } + input[type="checkbox"].wpd-toggle-field::before { + all:unset; + content: ""; + display: block !important; + height: 14px; + width:14px; + background: #1c1c1c; + border-radius: 100%; + position: absolute; + left: 1px; + top:1px; + transition: 0.25s; + transition-timing-function: ease-out; + } + input[type="checkbox"].wpd-toggle-field:checked { + background: var(--wp-admin-theme-color, #1851e0); + border-color: var(--wp-admin-theme-color, #1851e0); + } + input[type="checkbox"].wpd-toggle-field:checked:before { + left: 17px; + background: #fff; + } + +</style> +<?php +$renderer->output_render( + 'input', + [ + 'field' => $field, + 'renderer' => $renderer, + 'name_prefix' => $name_prefix, + 'value' => $value, + ] +);