diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index e3b794fa..5496b394 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -41,6 +41,10 @@ jobs: if: success() || matrix.allow_failure run: phpcs -wps --colors + - name: PHPStan + uses: php-actions/phpstan@v3 + if: success() || matrix.allow_failure + test: name: Unit tests with php ${{ matrix.php }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..85d4cd5d --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,871 @@ +parameters: + ignoreErrors: + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:__construct\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:addValue\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:create\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:escapeValue\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:escapeValue\\(\\) should return string but returns string\\|null\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:getValue\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:removeValue\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Method ipl\\\\Html\\\\Attribute\\:\\:setValue\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Parameter \\#1 \\$value of static method ipl\\\\Html\\\\Attribute\\:\\:escapeValue\\(\\) expects array\\|string, array\\|bool\\|string\\|null given\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Property ipl\\\\Html\\\\Attribute\\:\\:\\$value type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attribute.php + + - + message: "#^Class ipl\\\\Html\\\\Attributes implements generic interface ArrayAccess but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Class ipl\\\\Html\\\\Attributes implements generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:__construct\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:add\\(\\) has parameter \\$attribute with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:add\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:getIterator\\(\\) return type with generic class ArrayIterator does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:remove\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:set\\(\\) has parameter \\$attribute with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:set\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\Attributes\\:\\:wantAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Parameter \\#1 \\$value of method ipl\\\\Html\\\\Attribute\\:\\:addValue\\(\\) expects array\\|string, array\\|bool\\|string\\|null given\\.$#" + count: 3 + path: src/Attributes.php + + - + message: "#^Parameter \\#2 \\$value of method ipl\\\\Html\\\\Attributes\\:\\:set\\(\\) expects array\\|bool\\|string\\|null, mixed given\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Parameter \\#2 \\$value of static method ipl\\\\Html\\\\Attribute\\:\\:create\\(\\) expects array\\|bool\\|string\\|null, bool\\|float\\|int\\|string given\\.$#" + count: 1 + path: src/Attributes.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:addAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:addAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\|ipl\\\\Html\\\\Attributes\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:getDefaultAttributes\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:removeAttribute\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:setAttribute\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\BaseHtmlElement\\:\\:setAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Property ipl\\\\Html\\\\BaseHtmlElement\\:\\:\\$defaultAttributes type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Property ipl\\\\Html\\\\BaseHtmlElement\\:\\:\\$voidElements type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/BaseHtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\Contract\\\\FormElement\\:\\:addAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/Contract/FormElement.php + + - + message: "#^Method ipl\\\\Html\\\\Contract\\\\FormElement\\:\\:getMessages\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Contract/FormElement.php + + - + message: "#^Method ipl\\\\Html\\\\Contract\\\\FormElementDecorator\\:\\:decorate\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Contract/FormElementDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\Contract\\\\ValueCandidates\\:\\:getValueCandidates\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Contract/ValueCandidates.php + + - + message: "#^Method ipl\\\\Html\\\\Contract\\\\ValueCandidates\\:\\:setValueCandidates\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Contract/ValueCandidates.php + + - + message: "#^Method ipl\\\\Html\\\\Error\\:\\:getPhpTypeName\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Error.php + + - + message: "#^Method ipl\\\\Html\\\\Error\\:\\:getPhpTypeName\\(\\) has parameter \\$any with no type specified\\.$#" + count: 1 + path: src/Error.php + + - + message: "#^Method ipl\\\\Html\\\\Error\\:\\:renderErrorMessage\\(\\) has parameter \\$message with no type specified\\.$#" + count: 1 + path: src/Error.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string\\)\\: Unexpected token \"\\\\n \\* \", expected variable at offset 24$#" + count: 1 + path: src/Error.php + + - + message: "#^Cannot call method hasBeenPressed\\(\\) on ipl\\\\Html\\\\Contract\\\\FormSubmitElement\\|null\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:getValues\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:onElementRegistered\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:onError\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:onSuccess\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:populate\\(\\) has parameter \\$values with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:removeElement\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:setRequest\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\Form\\:\\:setRequest\\(\\) has parameter \\$request with no type specified\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Parameter \\#1 \\$attributes of method ipl\\\\Html\\\\Contract\\\\FormElement\\:\\:addAttributes\\(\\) expects iterable, mixed given\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Parameter \\#1 \\.\\.\\.\\$arrays of function array_merge_recursive expects array, array\\|object\\|null given\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Parameter \\#3 \\$postfix of method ipl\\\\Html\\\\Form\\:\\:addPluginLoader\\(\\) expects string, string\\|null given\\.$#" + count: 2 + path: src/Form.php + + - + message: "#^Property ipl\\\\Html\\\\Form\\:\\:\\$defaultElementDecorator \\(ipl\\\\Html\\\\Contract\\\\FormElementDecorator\\|null\\) does not accept ipl\\\\Html\\\\Contract\\\\FormElementDecorator\\|ipl\\\\Html\\\\FormDecorator\\\\DecoratorInterface\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Property ipl\\\\Html\\\\Form\\:\\:\\$populatedValues type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Property ipl\\\\Html\\\\Form\\:\\:\\$submitButton \\(ipl\\\\Html\\\\Contract\\\\FormSubmitElement\\) does not accept null\\.$#" + count: 1 + path: src/Form.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\CallbackDecorator\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/CallbackDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\CallbackDecorator\\:\\:decorate\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/CallbackDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:dt\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:renderDescription\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:renderErrors\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:renderLabel\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Property ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:\\$dd has no type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Property ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:\\$dt has no type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Property ipl\\\\Html\\\\FormDecorator\\\\DdDtDecorator\\:\\:\\$ready has no type specified\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$wrapper \\(ipl\\\\Html\\\\Contract\\\\Wrappable\\) does not accept null\\.$#" + count: 1 + path: src/FormDecorator/DdDtDecorator.php + + - + message: "#^Binary operation \"\\.\" between 'desc_' and array\\|bool\\|string\\|null results in an error\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Call to an undefined method ipl\\\\Html\\\\Contract\\\\FormElement\\:\\:ensureAssembled\\(\\)\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:assembleDescription\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:assembleElement\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:assembleErrors\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:assembleLabel\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Method ipl\\\\Html\\\\FormDecorator\\\\DivDecorator\\:\\:decorate\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormDecorator/DivDecorator.php + + - + message: "#^Cannot access offset 'name' on mixed\\.$#" + count: 2 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:addValidators\\(\\) has parameter \\$validators with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:getValueCandidates\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:getValueOfNameAttribute\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:isValid\\(\\) should return bool but returns bool\\|null\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:registerCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:registerValueCallback\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:setValidators\\(\\) has parameter \\$validators with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:setValueCandidates\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Parameter \\#1 \\$attributes of method ipl\\\\Html\\\\BaseHtmlElement\\:\\:addAttributes\\(\\) expects array\\|ipl\\\\Html\\\\Attributes, mixed given\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\BaseFormElement\\:\\:\\$valueCandidates type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Trying to invoke mixed but it's not a callable\\.$#" + count: 1 + path: src/FormElement/BaseFormElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\CheckboxElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/CheckboxElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:getValue\\(\\) has parameter \\$default with no type specified\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:getValue\\(\\) has parameter \\$name with no type specified\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:getValues\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:onElementRegistered\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:populate\\(\\) has parameter \\$values with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Parameter \\#1 \\$attributes of method ipl\\\\Html\\\\Contract\\\\FormElement\\:\\:addAttributes\\(\\) expects iterable, mixed given\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Parameter \\#1 \\$values of method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:populate\\(\\) expects iterable, mixed given\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Parameter \\#3 \\$postfix of method ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:addPluginLoader\\(\\) expects string, string\\|null given\\.$#" + count: 2 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:\\$defaultElementDecorator \\(ipl\\\\Html\\\\Contract\\\\FormElementDecorator\\|null\\) does not accept ipl\\\\Html\\\\Contract\\\\FormElementDecorator\\|ipl\\\\Html\\\\FormDecorator\\\\DecoratorInterface\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\FieldsetElement\\:\\:\\$populatedValues type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/FieldsetElement.php + + - + message: "#^Cannot access offset 0 on mixed\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FileElement\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\FileElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Only iterables can be unpacked, array\\\\|Psr\\\\Http\\\\Message\\\\UploadedFileInterface\\>\\|Psr\\\\Http\\\\Message\\\\UploadedFileInterface given in argument \\#1\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Parameter \\#1 \\$content of static method ipl\\\\Html\\\\Text\\:\\:create\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Parameter \\#1 \\$name of method ipl\\\\Html\\\\FormElement\\\\FileElement\\:\\:getFilePath\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\FileElement\\:\\:\\$files \\(array\\\\) does not accept array\\\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\FileElement\\:\\:\\$filesToRemove \\(array\\\\) does not accept array\\.$#" + count: 1 + path: src/FormElement/FileElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\InputElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/InputElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\LocalDateTimeElement\\:\\:\\$defaultAttributes type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/LocalDateTimeElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\PasswordElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/PasswordElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\RadioElement\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/RadioElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\RadioElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/RadioElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\RadioElement\\:\\:setDisabledOptions\\(\\) has parameter \\$disabledOptions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/RadioElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\RadioElement\\:\\:setOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/RadioElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\RadioElement\\:\\:\\$disabledOptions type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/RadioElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\RadioOption\\:\\:getLabelCssClass\\(\\) should return array\\\\|string but returns mixed\\.$#" + count: 1 + path: src/FormElement/RadioOption.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:getValue\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:getValue\\(\\) should return array\\|string\\|null but returns mixed\\.$#" + count: 2 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:makeOption\\(\\) has parameter \\$label with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:setDisabledOptions\\(\\) has parameter \\$disabledOptions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:setOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:\\$disabledOptions type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\SelectElement\\:\\:\\$value type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SelectElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SelectOption\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/SelectOption.php + + - + message: "#^Method ipl\\\\Html\\\\FormElement\\\\SubmitButtonElement\\:\\:registerAttributeCallbacks\\(\\) has no return type specified\\.$#" + count: 1 + path: src/FormElement/SubmitButtonElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\SubmitButtonElement\\:\\:\\$defaultAttributes type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/FormElement/SubmitButtonElement.php + + - + message: "#^Property ipl\\\\Html\\\\FormElement\\\\SubmitElement\\:\\:\\$buttonLabel has no type specified\\.$#" + count: 1 + path: src/FormElement/SubmitElement.php + + - + message: "#^Method ipl\\\\Html\\\\FormattedString\\:\\:__construct\\(\\) has parameter \\$args with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/FormattedString.php + + - + message: "#^Parameter \\#2 \\$values of function vsprintf expects array\\, array\\ given\\.$#" + count: 1 + path: src/FormattedString.php + + - + message: "#^Property ipl\\\\Html\\\\FormattedString\\:\\:\\$args \\(array\\\\) does not accept array\\\\.$#" + count: 1 + path: src/FormattedString.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:__callStatic\\(\\) has parameter \\$arguments with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:escapeForHtml\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:escapeForHtml\\(\\) has parameter \\$content with no type specified\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:renderError\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:renderError\\(\\) has parameter \\$error with no type specified\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Method ipl\\\\Html\\\\Html\\:\\:wrapEach\\(\\) has parameter \\$list with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Parameter \\#1 \\$attributes of static method ipl\\\\Html\\\\Attributes\\:\\:wantAttributes\\(\\) expects array\\|ipl\\\\Html\\\\Attributes\\|null, mixed given\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Parameter \\#1 \\$content of class ipl\\\\Html\\\\Text constructor expects string, mixed given\\.$#" + count: 1 + path: src/Html.php + + - + message: "#^Access to an undefined property ipl\\\\Html\\\\Contract\\\\Wrappable\\:\\:\\$renderedBy\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Call to an undefined method ipl\\\\Html\\\\Contract\\\\Wrappable\\:\\:contains\\(\\)\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Call to an undefined method ipl\\\\Html\\\\Contract\\\\Wrappable\\:\\:renderWrappedDocument\\(\\)\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Call to an undefined method ipl\\\\Html\\\\Contract\\\\Wrappable\\:\\:wrappedBy\\(\\)\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:addIndexedContent\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:addObjectPosition\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:addObjectPosition\\(\\) has parameter \\$pos with no type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:assemble\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:getContent\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:incrementIndexKeys\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Method ipl\\\\Html\\\\HtmlDocument\\:\\:reIndexContent\\(\\) has no return type specified\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$contentIndex type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$renderedBy \\(ipl\\\\Html\\\\HtmlDocument\\) does not accept ipl\\\\Html\\\\Contract\\\\Wrappable\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$renderedBy \\(ipl\\\\Html\\\\HtmlDocument\\) does not accept null\\.$#" + count: 2 + path: src/HtmlDocument.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$renderedBy \\(ipl\\\\Html\\\\HtmlDocument\\) in isset\\(\\) is not nullable\\.$#" + count: 2 + path: src/HtmlDocument.php + + - + message: "#^Property ipl\\\\Html\\\\HtmlDocument\\:\\:\\$wrapped \\(ipl\\\\Html\\\\Contract\\\\Wrappable\\) does not accept null\\.$#" + count: 1 + path: src/HtmlDocument.php + + - + message: "#^Parameter \\#1 \\$attributes of static method ipl\\\\Html\\\\Attributes\\:\\:wantAttributes\\(\\) expects array\\|ipl\\\\Html\\\\Attributes\\|null, mixed given\\.$#" + count: 1 + path: src/HtmlElement.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:row\\(\\) has parameter \\$row with no type specified\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:td\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:td\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:th\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:th\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:tr\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\Table\\:\\:tr\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$body \\(ipl\\\\Html\\\\HtmlElement\\) does not accept ipl\\\\Html\\\\BaseHtmlElement\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$body \\(ipl\\\\Html\\\\HtmlElement\\) does not accept null\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$caption \\(ipl\\\\Html\\\\HtmlElement\\) does not accept ipl\\\\Html\\\\BaseHtmlElement\\.$#" + count: 2 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$footer \\(ipl\\\\Html\\\\HtmlElement\\) does not accept ipl\\\\Html\\\\BaseHtmlElement\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$header \\(ipl\\\\Html\\\\HtmlElement\\) does not accept ipl\\\\Html\\\\BaseHtmlElement\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Property ipl\\\\Html\\\\Table\\:\\:\\$header \\(ipl\\\\Html\\\\HtmlElement\\) does not accept null\\.$#" + count: 1 + path: src/Table.php + + - + message: "#^Method ipl\\\\Html\\\\TemplateString\\:\\:__construct\\(\\) has parameter \\$args with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/TemplateString.php + + - + message: "#^Property ipl\\\\Html\\\\TemplateString\\:\\:\\$templateArgs type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/TemplateString.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..b0402357 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,24 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: max + + checkFunctionNameCase: true + checkInternalClassCaseSensitivity: true + treatPhpDocTypesAsCertain: false + + paths: + - src + + scanDirectories: + - vendor + + ignoreErrors: + - + messages: + - '#Unsafe usage of new static\(\)#' + - '#. but return statement is missing#' + reportUnmatched: false + + - '#Parameter \#2 \$haystack of function in_array expects array.#' # SelectElement::getValues() returns array attribute `multiple` is set to `true` diff --git a/src/Error.php b/src/Error.php index a4ab2531..316d237b 100644 --- a/src/Error.php +++ b/src/Error.php @@ -29,9 +29,6 @@ public static function show($error) if ($error instanceof Throwable) { // PHP 7+ $msg = static::createMessageForException($error); - } elseif ($error instanceof Exception) { - // PHP 5.x - $msg = static::createMessageForException($error); } elseif (is_string($error)) { $msg = $error; } else { @@ -40,7 +37,7 @@ public static function show($error) } $result = static::renderErrorMessage($msg); - if (static::showTraces()) { + if (static::showTraces() && $error instanceof Throwable) { $result->addHtml(Html::tag('pre', $error->getTraceAsString())); } @@ -84,7 +81,7 @@ public static function getPhpTypeName($any) */ protected static function createMessageForException($exception) { - $file = preg_split('/[\/\\\]/', $exception->getFile(), -1, PREG_SPLIT_NO_EMPTY); + $file = preg_split('/[\/\\\]/', $exception->getFile(), -1, PREG_SPLIT_NO_EMPTY) ?: []; $file = array_pop($file); return sprintf( '%s (%s:%d)', diff --git a/src/Form.php b/src/Form.php index dc18a5a6..a7360c7d 100644 --- a/src/Form.php +++ b/src/Form.php @@ -355,6 +355,8 @@ public function remove(ValidHtml $elementOrHtml) } $this->removeElement($elementOrHtml); + + return $this; } protected function onError() diff --git a/src/FormDecorator/DdDtDecorator.php b/src/FormDecorator/DdDtDecorator.php index 1b58ff80..9cfec205 100644 --- a/src/FormDecorator/DdDtDecorator.php +++ b/src/FormDecorator/DdDtDecorator.php @@ -51,7 +51,7 @@ public function getAttributes() $attributes = parent::getAttributes(); if ($this->wrappedElement->hasBeenValidated() && ! $this->wrappedElement->isValid()) { - $classes = $attributes->get('class'); + $classes = $attributes->get('class')->getValue(); if ( empty($classes) || (is_array($classes) && ! in_array('errors', $classes)) diff --git a/src/FormElement/FileElement.php b/src/FormElement/FileElement.php index 854d7d05..12f4217d 100644 --- a/src/FormElement/FileElement.php +++ b/src/FormElement/FileElement.php @@ -12,7 +12,6 @@ use ipl\I18n\Translation; use ipl\Validator\FileValidator; use ipl\Validator\ValidatorChain; -use ipl\Web\Widget\Icon; use Psr\Http\Message\UploadedFileInterface; use ipl\Html\Common\MultipleAttribute; @@ -94,7 +93,7 @@ public function getValueAttribute() public function getNameAttribute() { - $name = parent::getNameAttribute(); + $name = $this->getName(); return $this->isMultiple() ? ($name . '[]') : $name; } @@ -197,10 +196,10 @@ protected function loadFiles(): array } else { $this->files[$name] = new UploadedFile( $filePath, - filesize($filePath), + filesize($filePath) ?: null, 0, $name, - mime_content_type($filePath) + mime_content_type($filePath) ?: null ); } } @@ -374,7 +373,7 @@ protected function assemble() $doc = new HtmlDocument(); if ($this->hasFiles()) { foreach ($this->files as $file) { - $doc->addHtml(new HiddenElement('chosen_file_' . $this->getNameAttribute(), [ + $doc->addHtml(new HiddenElement('chosen_file_' . $this->getValueOfNameAttribute(), [ 'value' => $file->getClientFilename() ])); } @@ -394,7 +393,7 @@ public function renderUnwrapped() $uploadedFiles->addHtml(new HtmlElement( 'li', null, - (new ButtonElement('remove_file_' . $this->getNameAttribute(), Attributes::create([ + (new ButtonElement('remove_file_' . $this->getValueOfNameAttribute(), Attributes::create([ 'type' => 'submit', 'formnovalidate' => true, 'class' => 'remove-uploaded-file', @@ -403,7 +402,7 @@ public function renderUnwrapped() ])))->addHtml(new HtmlElement( 'span', null, - new Icon('remove'), + new HtmlElement('i', Attributes::create(['class' => ['icon', 'fa', 'fa-xmark']])), Text::create($file->getClientFilename()) )) )); diff --git a/src/FormElement/FormElements.php b/src/FormElement/FormElements.php index fa415a9b..6d363fd6 100644 --- a/src/FormElement/FormElements.php +++ b/src/FormElement/FormElements.php @@ -363,7 +363,7 @@ public function clearPopulatedValue($name) /** * Add all elements from the given element collection * - * @param Form|SubFormElement $form + * @param Form $form * * @return $this */ @@ -495,7 +495,7 @@ public function remove(ValidHtml $elementOrHtml) } } - parent::remove($elementOrHtml); + return parent::remove($elementOrHtml); } /** diff --git a/src/FormElement/LocalDateTimeElement.php b/src/FormElement/LocalDateTimeElement.php index 839da886..a628b57b 100644 --- a/src/FormElement/LocalDateTimeElement.php +++ b/src/FormElement/LocalDateTimeElement.php @@ -25,7 +25,7 @@ public function setValue($value) // In Chrome, if the seconds are set to 00, DateTime::createFromFormat() returns false. // Create DateTime without seconds in format if ($value === false) { - $format = substr(static::FORMAT, 0, strrpos(static::FORMAT, ':')); + $format = substr(static::FORMAT, 0, strrpos(static::FORMAT, ':') ?: null); $value = DateTime::createFromFormat($format, $originalVal); } diff --git a/src/HtmlDocument.php b/src/HtmlDocument.php index eb471e47..e4e977e7 100644 --- a/src/HtmlDocument.php +++ b/src/HtmlDocument.php @@ -173,7 +173,7 @@ public function insertAfter(ValidHtml $newNode, ValidHtml $existingNode): self throw new InvalidArgumentException('The content does not contain the $existingNode'); } - array_splice($this->content, $index + 1, 0, [$newNode]); + array_splice($this->content, (int) $index + 1, 0, [$newNode]); $this->reIndexContent(); @@ -195,7 +195,7 @@ public function insertBefore(ValidHtml $newNode, ValidHtml $existingNode): self throw new InvalidArgumentException('The content does not contain the $existingNode'); } - array_splice($this->content, $index, 0, [$newNode]); + array_splice($this->content, (int) $index, 0, [$newNode]); $this->reIndexContent(); diff --git a/src/TemplateString.php b/src/TemplateString.php index 611ea121..b1e01c0f 100644 --- a/src/TemplateString.php +++ b/src/TemplateString.php @@ -49,7 +49,7 @@ public function __construct($format, $args = null) /** * Parse template strings * - * @param null $for template name + * @param ?string $for template name * @return HtmlDocument * @throws Exception in case of missing template argument or unbounded open or close templates */