diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 23b27d08..dc3a0407 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -79,7 +79,7 @@ jobs: run: composer install --prefer-dist --no-progress --no-suggest - name: Coding Guideline - run: .build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./ + run: composer project:cgl code-quality: runs-on: ubuntu-latest @@ -87,15 +87,11 @@ jobs: - php-linting strategy: matrix: - include: - - php-version: '8.2' - typo3-version: '^13.4' - - php-version: '8.3' - typo3-version: '^13.4' - - php-version: '8.4' - typo3-version: '^13.4' - - php-version: '8.5' - typo3-version: '^13.4' + php-version: + - 8.2 + - 8.3 + - 8.4 + - 8.5 steps: - uses: actions/checkout@v4 @@ -112,41 +108,35 @@ jobs: && composer install --no-progress --no-ansi --no-interaction - name: Code Quality (by PHPStan) - run: .build/bin/phpstan analyse -c Build/phpstan.neon + run: composer project:phpstan - tests-phpunit: + tests-unit-and-functional: runs-on: ubuntu-latest needs: - coding-guideline - code-quality + strategy: + matrix: + php-version: + - 8.2 + - 8.3 + - 8.4 + - 8.5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v17 + - name: Install PHP + uses: shivammathur/setup-php@v2 with: - nix_path: nixpkgs=channel:nixos-unstable - - - name: Run Unit Tests PHP8.2 - run: nix-shell --arg phpVersion \"php82\" --pure --run project-test-unit - - - name: Run Unit Tests PHP8.3 - run: nix-shell --arg phpVersion \"php83\" --pure --run project-test-unit - - - name: Run Unit Tests PHP8.4 - run: nix-shell --arg phpVersion \"php84\" --pure --run project-test-unit - - - name: Run Unit Tests PHP8.5 - run: nix-shell --arg phpVersion \"php85\" --pure --run project-test-unit - - - name: Run Functional Tests PHP8.2 - run: nix-shell --arg phpVersion \"php82\" --pure --run project-test-functional + php-version: "${{ matrix.php-version }}" + tools: composer:v2 - - name: Run Functional Tests PHP8.3 - run: nix-shell --arg phpVersion \"php83\" --pure --run project-test-functional + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest - - name: Run Functional Tests PHP8.4 - run: nix-shell --arg phpVersion \"php84\" --pure --run project-test-functional + - name: Run unit tests + run: composer project:test:unit - - name: Run Functional Tests PHP8.5 - run: nix-shell --arg phpVersion \"php85\" --pure --run project-test-functional + - name: Run functional tests + run: export typo3DatabaseDriver=pdo_sqlite && composer project:test:functional diff --git a/Build/.php-cs-fixer.dist.php b/Build/.php-cs-fixer.dist.php index 58818f6f..aecc017b 100644 --- a/Build/.php-cs-fixer.dist.php +++ b/Build/.php-cs-fixer.dist.php @@ -2,62 +2,497 @@ declare(strict_types=1); -if (PHP_SAPI !== 'cli') { - die('This script supports command line usage only. Please check your command.'); +use ErickSkrauch\PhpCsFixer\Fixer\Whitespace\BlankLineBeforeReturnFixer; +use ErickSkrauch\PhpCsFixer\Fixer\Whitespace\MultilineIfStatementBracesFixer; +use ErickSkrauch\PhpCsFixer\Fixers as ErickSkrauchFixersAlias; +use PhpCsFixer\Config; +use PhpCsFixer\Finder; +use PhpCsFixer\Fixer\Alias\MbStrFunctionsFixer; +use PhpCsFixer\Fixer\Alias\ModernizeStrposFixer; +use PhpCsFixer\Fixer\Alias\NoAliasFunctionsFixer; +use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer; +use PhpCsFixer\Fixer\ArrayNotation\NoMultilineWhitespaceAroundDoubleArrowFixer; +use PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer; +use PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceInEmptyArrayFixer; +use PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer; +use PhpCsFixer\Fixer\ArrayNotation\ReturnToYieldFromFixer; +use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer; +use PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer; +use PhpCsFixer\Fixer\ArrayNotation\YieldFromArrayToYieldsFixer; +use PhpCsFixer\Fixer\AttributeNotation\AttributeBlockNoSpacesFixer; +use PhpCsFixer\Fixer\AttributeNotation\AttributeEmptyParenthesesFixer; +use PhpCsFixer\Fixer\AttributeNotation\OrderedAttributesFixer; +use PhpCsFixer\Fixer\Basic\NoMultipleStatementsPerLineFixer; +use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer; +use PhpCsFixer\Fixer\Basic\NonPrintableCharacterFixer; +use PhpCsFixer\Fixer\Basic\NumericLiteralSeparatorFixer; +use PhpCsFixer\Fixer\Casing\ClassReferenceNameCasingFixer; +use PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer; +use PhpCsFixer\Fixer\Casing\NativeTypeDeclarationCasingFixer; +use PhpCsFixer\Fixer\CastNotation\CastSpacesFixer; +use PhpCsFixer\Fixer\CastNotation\ModernizeTypesCastingFixer; +use PhpCsFixer\Fixer\CastNotation\NoUnsetCastFixer; +use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer; +use PhpCsFixer\Fixer\ClassNotation\NoNullPropertyInitializationFixer; +use PhpCsFixer\Fixer\ClassNotation\NoRedundantReadonlyPropertyFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedTraitsFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedTypesFixer; +use PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer; +use PhpCsFixer\Fixer\ClassNotation\StaticPrivateMethodFixer; +use PhpCsFixer\Fixer\ClassNotation\StringableForToStringFixer; +use PhpCsFixer\Fixer\Comment\HeaderCommentFixer; +use PhpCsFixer\Fixer\Comment\MultilineCommentOpeningClosingFixer; +use PhpCsFixer\Fixer\Comment\NoEmptyCommentFixer; +use PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer; +use PhpCsFixer\Fixer\ControlStructure\NoSuperfluousElseifFixer; +use PhpCsFixer\Fixer\ControlStructure\NoUnneededBracesFixer; +use PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer; +use PhpCsFixer\Fixer\ControlStructure\NoUselessElseFixer; +use PhpCsFixer\Fixer\ControlStructure\SimplifiedIfReturnFixer; +use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer; +use PhpCsFixer\Fixer\FunctionNotation\DateTimeCreateFromFormatCallFixer; +use PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer; +use PhpCsFixer\Fixer\FunctionNotation\MultilinePromotedPropertiesFixer; +use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer; +use PhpCsFixer\Fixer\FunctionNotation\NoUselessPrintfFixer; +use PhpCsFixer\Fixer\FunctionNotation\NoUselessSprintfFixer; +use PhpCsFixer\Fixer\FunctionNotation\NullableTypeDeclarationForDefaultNullValueFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToParamTypeFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToPropertyTypeFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToReturnTypeFixer; +use PhpCsFixer\Fixer\FunctionNotation\RegularCallableCallFixer; +use PhpCsFixer\Fixer\FunctionNotation\StaticLambdaFixer; +use PhpCsFixer\Fixer\FunctionNotation\VoidReturnFixer; +use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer; +use PhpCsFixer\Fixer\Import\GlobalNamespaceImportFixer; +use PhpCsFixer\Fixer\Import\NoUnneededImportAliasFixer; +use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer; +use PhpCsFixer\Fixer\Import\OrderedImportsFixer; +use PhpCsFixer\Fixer\LanguageConstruct\ClassKeywordFixer; +use PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveIssetsFixer; +use PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveUnsetsFixer; +use PhpCsFixer\Fixer\LanguageConstruct\NullableTypeDeclarationFixer; +use PhpCsFixer\Fixer\LanguageConstruct\SingleSpaceAroundConstructFixer; +use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer; +use PhpCsFixer\Fixer\NamespaceNotation\BlankLinesBeforeNamespaceFixer; +use PhpCsFixer\Fixer\Naming\NoHomoglyphNamesFixer; +use PhpCsFixer\Fixer\Operator\ConcatSpaceFixer; +use PhpCsFixer\Fixer\Operator\IncrementStyleFixer; +use PhpCsFixer\Fixer\Operator\LongToShorthandOperatorFixer; +use PhpCsFixer\Fixer\Operator\NewWithParenthesesFixer; +use PhpCsFixer\Fixer\Operator\NoUselessConcatOperatorFixer; +use PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer; +use PhpCsFixer\Fixer\Operator\OperatorLinebreakFixer; +use PhpCsFixer\Fixer\Operator\StandardizeIncrementFixer; +use PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer; +use PhpCsFixer\Fixer\Operator\TernaryToElvisOperatorFixer; +use PhpCsFixer\Fixer\Operator\TernaryToNullCoalescingFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitDataProviderMethodOrderFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitDataProviderReturnTypeFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitDataProviderStaticFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertInternalTypeFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitFqcnAnnotationFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitMethodCasingFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitMockFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitMockShortWillReturnFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitNamespacedFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitNoExpectationAnnotationFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitSetUpTearDownVisibilityFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestAnnotationFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer; +use PhpCsFixer\Fixer\Phpdoc\NoBlankLinesAfterPhpdocFixer; +use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer; +use PhpCsFixer\Fixer\Phpdoc\NoSuperfluousPhpdocTagsFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocAlignFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocLineSpanFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocNoAccessFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocNoDuplicateTypesFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocOrderByValueFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocOrderFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocParamOrderFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocScalarFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocSeparationFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocToCommentFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimConsecutiveBlankLineSeparationFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesOrderFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocVarAnnotationCorrectOrderFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocVarWithoutNameFixer; +use PhpCsFixer\Fixer\ReturnNotation\NoUselessReturnFixer; +use PhpCsFixer\Fixer\ReturnNotation\ReturnAssignmentFixer; +use PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer; +use PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer; +use PhpCsFixer\Fixer\Semicolon\NoSinglelineWhitespaceBeforeSemicolonsFixer; +use PhpCsFixer\Fixer\Semicolon\SemicolonAfterInstructionFixer; +use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer; +use PhpCsFixer\Fixer\StringNotation\NoTrailingWhitespaceInStringFixer; +use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer; +use PhpCsFixer\Fixer\StringNotation\StringImplicitBackslashesFixer; +use PhpCsFixer\Fixer\StringNotation\StringLengthToEmptyFixer; +use PhpCsFixer\Fixer\Whitespace\ArrayIndentationFixer; +use PhpCsFixer\Fixer\Whitespace\CompactNullableTypeDeclarationFixer; +use PhpCsFixer\Fixer\Whitespace\MethodChainingIndentationFixer; +use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer; +use PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer; +use PhpCsFixer\Fixer\Whitespace\StatementIndentationFixer; +use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer; +use PhpCsFixer\Fixer\Whitespace\TypesSpacesFixer; +use PhpCsFixer\Preg; +use PhpCsFixer\Runner\Parallel\ParallelConfigFactory; +use PhpCsFixerCustomFixers\Fixer\CommentSurroundedBySpacesFixer; +use PhpCsFixerCustomFixers\Fixer\MultilineCommentOpeningClosingAloneFixer; +use PhpCsFixerCustomFixers\Fixer\NoCommentedOutCodeFixer; +use PhpCsFixerCustomFixers\Fixer\NoUselessDirnameCallFixer; +use PhpCsFixerCustomFixers\Fixer\NoUselessParenthesisFixer; +use PhpCsFixerCustomFixers\Fixer\NoUselessStrlenFixer; +use PhpCsFixerCustomFixers\Fixer\PhpdocNoIncorrectVarAnnotationFixer; +use PhpCsFixerCustomFixers\Fixer\PhpdocNoSuperfluousParamFixer; +use PhpCsFixerCustomFixers\Fixer\PhpdocParamTypeFixer; +use PhpCsFixerCustomFixers\Fixer\PhpdocTypesCommaSpacesFixer; +use PhpCsFixerCustomFixers\Fixer\PhpdocTypesTrimFixer; +use PhpCsFixerCustomFixers\Fixer\PromotedConstructorPropertyFixer; +use PhpCsFixerCustomFixers\Fixer\SingleSpaceAfterStatementFixer; +use PhpCsFixerCustomFixers\Fixer\SingleSpaceBeforeStatementFixer; +use PhpCsFixerCustomFixers\Fixers as PhpCsFixerCustomFixersAlias; + +/** + * Transforms a given class to php-cs-fixer rule name. + * That way we can use auto completion, phpstan, etc. + * + * @param class-string $className + * @param bool $keepVendor Set to true for custom fixers. + */ +function transform(string $className, bool $keepVendor = false): string +{ + $nameParts = explode('\\', $className); + $name = mb_substr(end($nameParts), 0, -mb_strlen('Fixer')); + $name = mb_strtolower(Preg::replace( + '/(?setParallelConfig(ParallelConfigFactory::detect()) + ->setRiskyAllowed(true) ->setFinder( - (new PhpCsFixer\Finder()) + (new Finder()) + ->ignoreDotFiles(false) ->ignoreVCSIgnored(true) ->in(__DIR__ . '/../') + ->exclude( + [ + '.build/', + 'var/', + ] + ) ) - ->setRiskyAllowed(true) + ->registerCustomFixers(new PhpCsFixerCustomFixersAlias()) + ->registerCustomFixers(new ErickSkrauchFixersAlias()) ->setRules([ - '@DoctrineAnnotation' => true, - '@PER-CS' => true, - 'array_syntax' => ['syntax' => 'short'], - 'cast_spaces' => ['space' => 'none'], - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'none'], - 'declare_parentheses' => true, - 'dir_constant' => true, - 'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], - 'modernize_strpos' => true, - 'modernize_types_casting' => true, - 'native_function_casing' => true, - 'no_alias_functions' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_blank_lines' => true, - 'no_leading_namespace_whitespace' => true, - 'no_null_property_initialization' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_superfluous_elseif' => true, - 'no_trailing_comma_in_singleline' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_nullsafe_operator' => true, - 'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'], - 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], - 'php_unit_mock_short_will_return' => true, - 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_package' => true, - 'phpdoc_scalar' => true, - 'phpdoc_trim' => true, - 'phpdoc_types' => true, - 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'return_type_declaration' => ['space_before' => 'none'], - 'single_quote' => true, - 'single_space_around_construct' => true, - 'single_line_comment_style' => ['comment_types' => ['hash']], - 'trailing_comma_in_multiline' => ['elements' => ['arrays']], - 'type_declaration_spaces' => true, - 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], - 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], - ]); + '@PSR12' => true, + transform(ArrayIndentationFixer::class) => true, + transform(ArraySyntaxFixer::class) => [ + 'syntax' => 'short', + ], + transform(AttributeBlockNoSpacesFixer::class) => true, + transform(AttributeEmptyParenthesesFixer::class) => true, + transform(BlankLinesBeforeNamespaceFixer::class) => true, + transform(CastSpacesFixer::class) => true, + transform(ClassAttributesSeparationFixer::class) => [ + 'elements' => [ + 'const' => 'one', + 'method' => 'one', + 'property' => 'one', + 'trait_import' => 'one', + ], + ], + transform(ClassKeywordFixer::class) => true, + transform(ClassReferenceNameCasingFixer::class) => true, + transform(CombineConsecutiveIssetsFixer::class) => true, + transform(CombineConsecutiveUnsetsFixer::class) => true, + transform(CompactNullableTypeDeclarationFixer::class) => true, + transform(ConcatSpaceFixer::class) => [ + 'spacing' => 'one', + ], + transform(DateTimeCreateFromFormatCallFixer::class) => true, + transform(DeclareStrictTypesFixer::class) => true, + transform(FullyQualifiedStrictTypesFixer::class) => [ + 'import_symbols' => true, + 'leading_backslash_in_global_namespace' => true, + ], + transform(GlobalNamespaceImportFixer::class) => true, + transform(HeaderCommentFixer::class) => [ + 'header' => '', + ], + transform(IncrementStyleFixer::class) => [ + 'style' => 'post', + ], + transform(ListSyntaxFixer::class) => true, + transform(LongToShorthandOperatorFixer::class) => true, + transform(MbStrFunctionsFixer::class) => true, + transform(MethodArgumentSpaceFixer::class) => [ + 'on_multiline' => 'ensure_fully_multiline', + 'attribute_placement' => 'standalone', + ], + transform(MethodChainingIndentationFixer::class) => true, + transform(ModernizeStrposFixer::class) => [ + 'modernize_stripos' => true, + ], + transform(ModernizeTypesCastingFixer::class) => true, + transform(MultilineCommentOpeningClosingFixer::class) => true, + transform(MultilinePromotedPropertiesFixer::class) => true, + transform(MultilineWhitespaceBeforeSemicolonsFixer::class) => [ + 'strategy' => 'new_line_for_chained_calls', + ], + transform(NativeFunctionCasingFixer::class) => true, + transform(NativeTypeDeclarationCasingFixer::class) => true, + transform(NewWithParenthesesFixer::class) => [ + 'anonymous_class' => false, + 'named_class' => true, + ], + transform(NoAliasFunctionsFixer::class) => true, + transform(NoBlankLinesAfterPhpdocFixer::class) => true, + transform(NoEmptyCommentFixer::class) => true, + transform(NoEmptyPhpdocFixer::class) => true, + transform(NoEmptyStatementFixer::class) => true, + transform(NoExtraBlankLinesFixer::class) => [ + 'tokens' => [ + 'attribute', + 'break', + 'case', + 'continue', + 'curly_brace_block', + 'default', + 'extra', + 'parenthesis_brace_block', + 'return', + 'square_brace_block', + 'switch', + 'throw', + 'use', + ], + ], + transform(NoHomoglyphNamesFixer::class) => true, + transform(NoMultilineWhitespaceAroundDoubleArrowFixer::class) => true, + transform(NoMultipleStatementsPerLineFixer::class) => true, + transform(NoNullPropertyInitializationFixer::class) => true, + transform(NoRedundantReadonlyPropertyFixer::class) => true, + transform(NoSinglelineWhitespaceBeforeSemicolonsFixer::class) => true, + transform(NoSpacesAroundOffsetFixer::class) => true, + transform(NoSuperfluousElseifFixer::class) => true, + transform(NoSuperfluousPhpdocTagsFixer::class) => [ + 'allow_mixed' => true, + ], + transform(NoTrailingCommaInSinglelineFixer::class) => true, + transform(NoTrailingWhitespaceInStringFixer::class) => true, + transform(NoUnneededBracesFixer::class) => true, + transform(NoUnneededControlParenthesesFixer::class) => true, + transform(NoUnneededImportAliasFixer::class) => true, + transform(NoUnreachableDefaultArgumentValueFixer::class) => true, + transform(NoUnsetCastFixer::class) => true, + transform(NoUnusedImportsFixer::class) => true, + transform(NoUselessConcatOperatorFixer::class) => true, + transform(NoUselessElseFixer::class) => true, + transform(NoUselessPrintfFixer::class) => true, + transform(NoUselessReturnFixer::class) => true, + transform(NoUselessSprintfFixer::class) => true, + transform(NoWhitespaceBeforeCommaInArrayFixer::class) => true, + transform(NoWhitespaceInEmptyArrayFixer::class) => true, + transform(NonPrintableCharacterFixer::class) => true, + transform(NormalizeIndexBraceFixer::class) => true, + transform(NullableTypeDeclarationFixer::class) => true, + transform(NullableTypeDeclarationForDefaultNullValueFixer::class) => true, + transform(NumericLiteralSeparatorFixer::class) => [ + 'strategy' => NumericLiteralSeparatorFixer::STRATEGY_NO_SEPARATOR, + ], + transform(ObjectOperatorWithoutWhitespaceFixer::class) => true, + transform(OperatorLinebreakFixer::class) => [ + 'position' => 'beginning', ], + transform(OrderedAttributesFixer::class) => [ + 'order' => [ + 'alpha', + ], + ], + transform(OrderedClassElementsFixer::class) => [ + 'order' => [ + 'use_trait', + 'case', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public', + 'property_protected', + 'property_private', + 'construct', + 'destruct', + 'magic', + 'phpunit', + 'method_public', + 'method_protected', + 'method_private', + ], + 'case_sensitive' => true, + ], + transform(OrderedImportsFixer::class) => [ + 'sort_algorithm' => 'alpha', + 'case_sensitive' => true, + 'imports_order' => [ + 'class', + 'const', + 'function', + ], + ], + transform(OrderedInterfacesFixer::class) => [ + 'case_sensitive' => true, + ], + transform(OrderedTraitsFixer::class) => [ + 'case_sensitive' => true, + ], + transform(OrderedTypesFixer::class) => [ + 'case_sensitive' => true, + ], + transform(PhpUnitConstructFixer::class) => true, + transform(PhpUnitDataProviderMethodOrderFixer::class) => true, + transform(PhpUnitDataProviderReturnTypeFixer::class) => true, + transform(PhpUnitDataProviderStaticFixer::class) => [ + 'force' => true, + ], + transform(PhpUnitDedicateAssertFixer::class) => true, + transform(PhpUnitDedicateAssertInternalTypeFixer::class) => true, + transform(PhpUnitFqcnAnnotationFixer::class) => true, + transform(PhpUnitMethodCasingFixer::class) => true, + transform(PhpUnitMockFixer::class) => true, + transform(PhpUnitMockShortWillReturnFixer::class) => true, + transform(PhpUnitNamespacedFixer::class) => true, + transform(PhpUnitNoExpectationAnnotationFixer::class) => true, + transform(PhpUnitSetUpTearDownVisibilityFixer::class) => true, + transform(PhpUnitTestAnnotationFixer::class) => [ + 'style' => 'annotation', + ], + transform(PhpUnitTestCaseStaticMethodCallsFixer::class) => [ + 'call_type' => 'self', + // TODO: phpunit/phpunit:11.0 Update this configuration to match actual PHPUnit version + 'target' => '10.0', + ], + transform(PhpdocAlignFixer::class) => [ + 'align' => 'left', + ], + transform(PhpdocIndentFixer::class) => true, + transform(PhpdocLineSpanFixer::class) => true, + transform(PhpdocNoAccessFixer::class) => true, + transform(PhpdocNoDuplicateTypesFixer::class) => true, + transform(PhpdocOrderByValueFixer::class) => [ + 'annotations' => [ + 'covers', 'throws', + ], + ], + transform(PhpdocOrderFixer::class) => true, + transform(PhpdocParamOrderFixer::class) => true, + transform(PhpdocScalarFixer::class) => [ + 'types' => [ + 'boolean', + 'callback', + 'double', + 'integer', + 'never-return', + 'never-returns', + 'no-return', + 'real', + 'str', + ], + ], + transform(PhpdocSeparationFixer::class) => [ + 'groups' => [ + ['see'], + ['throw'], + ['param'], + ['return'], + ], + ], + transform(PhpdocToCommentFixer::class) => true, + transform(PhpdocToParamTypeFixer::class) => true, + transform(PhpdocToPropertyTypeFixer::class) => true, + transform(PhpdocToReturnTypeFixer::class) => true, + transform(PhpdocTrimConsecutiveBlankLineSeparationFixer::class) => true, + transform(PhpdocTrimFixer::class) => true, + transform(PhpdocTypesFixer::class) => true, + transform(PhpdocTypesOrderFixer::class) => [ + 'case_sensitive' => true, + ], + transform(PhpdocVarAnnotationCorrectOrderFixer::class) => true, + transform(PhpdocVarWithoutNameFixer::class) => true, + transform(RegularCallableCallFixer::class) => true, + transform(ReturnAssignmentFixer::class) => true, + transform(ReturnToYieldFromFixer::class) => true, + transform(SelfAccessorFixer::class) => true, + transform(SemicolonAfterInstructionFixer::class) => true, + transform(SimplifiedIfReturnFixer::class) => true, + transform(SingleLineCommentStyleFixer::class) => true, + transform(SingleQuoteFixer::class) => true, + transform(SingleSpaceAroundConstructFixer::class) => true, + transform(StandardizeIncrementFixer::class) => true, + transform(StatementIndentationFixer::class) => true, + transform(StaticLambdaFixer::class) => true, + transform(StaticPrivateMethodFixer::class) => true, + transform(StringableForToStringFixer::class) => true, + transform(StringImplicitBackslashesFixer::class) => [ + 'single_quoted' => 'ignore', + ], + transform(StringLengthToEmptyFixer::class) => true, + transform(TernaryOperatorSpacesFixer::class) => true, + transform(TernaryToElvisOperatorFixer::class) => true, + transform(TernaryToNullCoalescingFixer::class) => true, + transform(TrailingCommaInMultilineFixer::class) => true, + transform(TrimArraySpacesFixer::class) => true, + transform(TypeDeclarationSpacesFixer::class) => [ + 'elements' => [ + 'constant', + 'function', + 'property', + ], + ], + transform(TypesSpacesFixer::class) => true, + transform(VoidReturnFixer::class) => true, + transform(WhitespaceAfterCommaInArrayFixer::class) => [ + 'ensure_single_space' => true, + ], + transform(YieldFromArrayToYieldsFixer::class) => true, + + // Part of PhpCsFixerCustomFixers + CommentSurroundedBySpacesFixer::name() => true, + MultilineCommentOpeningClosingAloneFixer::name() => true, + NoCommentedOutCodeFixer::name() => true, + NoUselessDirnameCallFixer::name() => true, + NoUselessParenthesisFixer::name() => true, + NoUselessStrlenFixer::name() => true, + PhpdocNoIncorrectVarAnnotationFixer::name() => true, + PhpdocNoSuperfluousParamFixer::name() => true, + PhpdocParamTypeFixer::name() => true, + PhpdocTypesCommaSpacesFixer::name() => true, + PhpdocTypesTrimFixer::name() => true, + // Doesn't work with some Codeception files due to miss match with underlying TYPO3 classes. + // PromotedConstructorPropertyFixer::name() => true, + SingleSpaceAfterStatementFixer::name() => [ + 'allow_linebreak' => true, + ], + SingleSpaceBeforeStatementFixer::name() => true, + + // Part of ErickSkrauch\PhpCsFixer + transform(BlankLineBeforeReturnFixer::class, true) => true, + transform(MultilineIfStatementBracesFixer::class, true) => true, + ]) +; diff --git a/Build/UnitTests.xml b/Build/UnitTests.xml deleted file mode 100644 index 9825de0b..00000000 --- a/Build/UnitTests.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - ../Tests/Unit/ - - - - - ../Classes/ - - - ../Classes/Widgets - - - diff --git a/Build/UnitTestsBootstrap.php b/Build/UnitTestsBootstrap.php index d2cd5570..bcae7efe 100644 --- a/Build/UnitTestsBootstrap.php +++ b/Build/UnitTestsBootstrap.php @@ -1,5 +1,20 @@ defineSitePath(); - $requestType = \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE | \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI; + $requestType = SystemEnvironmentBuilder::REQUESTTYPE_BE | SystemEnvironmentBuilder::REQUESTTYPE_CLI; \TYPO3\TestingFramework\Core\SystemEnvironmentBuilder::run(0, $requestType); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3conf/ext'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/assets'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/tests'); - $testbase->createDirectory(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/typo3temp/var/transient'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3conf/ext'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/assets'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/tests'); + $testbase->createDirectory(Environment::getPublicPath() . '/typo3temp/var/transient'); // Retrieve an instance of class loader and inject to core bootstrap $classLoader = require $testbase->getPackagesPath() . '/autoload.php'; - \TYPO3\CMS\Core\Core\Bootstrap::initializeClassLoader($classLoader); + Bootstrap::initializeClassLoader($classLoader); // Initialize default TYPO3_CONF_VARS - $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager(); + $configurationManager = new ConfigurationManager(); $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration(); - $cache = new \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend( + $cache = new PhpFrontend( 'core', - new \TYPO3\CMS\Core\Cache\Backend\NullBackend('production', []) + new NullBackend('production', []) ); // Set all packages to active - if (interface_exists(\TYPO3\CMS\Core\Package\Cache\PackageCacheInterface::class)) { - $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager(\TYPO3\CMS\Core\Package\UnitTestPackageManager::class, \TYPO3\CMS\Core\Core\Bootstrap::createPackageCache($cache)); + if (interface_exists(PackageCacheInterface::class)) { + $packageManager = Bootstrap::createPackageManager(UnitTestPackageManager::class, Bootstrap::createPackageCache($cache)); } else { // v10 compatibility layer // @deprecated Will be removed when v10 compat is dropped from testing-framework - $packageManager = \TYPO3\CMS\Core\Core\Bootstrap::createPackageManager(\TYPO3\CMS\Core\Package\UnitTestPackageManager::class, $cache); + $packageManager = Bootstrap::createPackageManager(UnitTestPackageManager::class, $cache); } - \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager); - \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::setPackageManager($packageManager); + GeneralUtility::setSingletonInstance(PackageManager::class, $packageManager); + ExtensionManagementUtility::setPackageManager($packageManager); $testbase->dumpClassLoadingInformation(); - \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances(); + GeneralUtility::purgeInstances(); })(); diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index 3cfb689d..626acd8d 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -1,21 +1,5473 @@ parameters: ignoreErrors: - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Service\\\\PaymentMethodsServiceInterface\\:\\:getConfigurationsForType\\(\\)\\.$#" + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SiteSets\\AbstractConfigurationLoader\:\:getConfigurationsForType\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SiteSets\\AbstractConfigurationLoader\:\:getCountryCodeFromPreset\(\) has parameter \$configuration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SiteSets\\AbstractConfigurationLoader\:\:getServices\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SiteSets\\AbstractConfigurationLoader\:\:getTypeZonesPluginSettings\(\) has parameter \$zoneSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SiteSets\\AbstractConfigurationLoader\:\:getTypeZonesPluginSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\SpecialOptionsLoaderInterface\:\:getSpecialOptions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/SpecialOptionsLoaderInterface.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getConfigurationsForType\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getCountryCodeFromPreset\(\) has parameter \$configuration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getServices\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getServices\(\) has parameter \$services with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getServices\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getTypeZonesPluginSettings\(\) has parameter \$zoneSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:getTypeZonesPluginSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Parameter \#1 \$serviceKey of method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceFactory\:\:getService\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Parameter \#2 \$serviceConfig of method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceFactory\:\:getService\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Property Extcode\\Cart\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoader\:\:\$configurations type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\PaymentMethodsLoader\:\:getPaymentMethods\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/PaymentMethodsLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\ShippingMethodsLoader\:\:getShippingMethods\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/ShippingMethodsLoader.php + + - + message: '#^Method Extcode\\Cart\\Configuration\\Loader\\TypoScript\\SpecialOptionsLoader\:\:getSpecialOptions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/SpecialOptionsLoader.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Parameter \#1 \$taxClassKey of method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactoryInterface\:\:getTaxClass\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Parameter \#2 \$array of function array_key_exists expects array, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Parameter \#2 \$taxClassValue of method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactoryInterface\:\:getTaxClass\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Property Extcode\\Cart\\Configuration\\Loader\\TypoScript\\TaxClassLoader\:\:\$settings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Configuration/Loader/TypoScript/TaxClassLoader.php + + - + message: '#^Parameter \#3 \$view of class Extcode\\Cart\\Event\\View\\ModifyViewEvent constructor expects TYPO3Fluid\\Fluid\\View\\ViewInterface, TYPO3\\CMS\\Core\\View\\ViewInterface given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/ActionController.php + + - + message: '#^Cannot call method getPagePermsClause\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/ActionController.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Controller/Backend/ActionController.php + + - + message: '#^Parameter \#2 \$perms_clause of static method TYPO3\\CMS\\Backend\\Utility\\BackendUtility\:\:readPageAccess\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/ActionController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Backend\\ActionController\:\:\$pluginSettings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/ActionController.php + + - + message: '#^Binary operation "\." between ''attachment;…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot call method getContents\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot call method getName\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot call method getOriginalResource\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot call method getSize\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot call method toArray\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Parameter \#1 \$array of function end expects array\|object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Parameter \#1 \$content of method Psr\\Http\\Message\\StreamFactoryInterface\:\:createStream\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/DocumentController.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Binary operation "\." between ''LLL\:EXT\:cart…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''columns'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''config'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''group'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''icon'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''items'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''label'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''link'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''showLabel'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''status'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''title'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''tx_cart_domain_model_order_payment'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''tx_cart_domain_model_order_shipping'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Cannot access offset ''value'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:dispatchModifyButtonBarEvent\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:getLanguageService\(\) should return TYPO3\\CMS\\Core\\Localization\\LanguageService but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:getPaymentStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:getShippingStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:setDocHeader\(\) has parameter \$buttons with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$href of method TYPO3\\CMS\\Backend\\Template\\Components\\Buttons\\LinkButton\:\:setHref\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$identifier of method TYPO3\\CMS\\Core\\Imaging\\IconFactory\:\:getIcon\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$key of static method TYPO3\\CMS\\Extbase\\Utility\\LocalizationUtility\:\:translate\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$queryResult of class TYPO3\\CMS\\Extbase\\Pagination\\QueryResultPaginator constructor expects TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface, array\|TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$showLabelText of method TYPO3\\CMS\\Backend\\Template\\Components\\Buttons\\AbstractButton\:\:setShowLabelText\(\) expects bool, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#3 \$buttonGroup of method TYPO3\\CMS\\Backend\\Template\\Components\\ButtonBar\:\:addButton\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 2 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:\$searchArguments \(array\) does not accept mixed\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Backend\\Order\\OrderController\:\:\$searchArguments type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Backend/Order/OrderController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/PaymentController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Backend/Order/ShippingController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:restoreCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Cart\\ActionController\:\:\$configurations type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Cart\\ActionController\:\:\$payments type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Cart\\ActionController\:\:\$shippings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Cart\\ActionController\:\:\$specials type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ActionController.php + + - + message: '#^Binary operation "\." between ''billing_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 2 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Binary operation "\." between ''shipping_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 2 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 8 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Cannot access offset ''shippingSameAsBilling'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Cannot access offset ''steps'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 4 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 4 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Cannot call method getId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Cannot call method isPreset\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Parameter \#1 \$cartSettings of method Extcode\\Cart\\Utility\\CartUtility\:\:updateCountry\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Parameter \#1 \$payment of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setPayment\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Parameter \#1 \$shipping of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setShipping\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Cart/CountryController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Cannot call method getCode\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Cannot call method isUseable\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Parameter \#1 \$className of static method TYPO3\\CMS\\Core\\Utility\\GeneralUtility\:\:makeInstance\(\) expects class\-string\, string given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Parameter \#1 \$coupon of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:addCoupon\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\CartCouponInterface, object given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Parameter \#1 \$couponCode of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:removeCoupon\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 8 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Unable to resolve the template type T in call to static method TYPO3\\CMS\\Core\\Utility\\GeneralUtility\:\:makeInstance\(\)$#' + identifier: argument.templateType + count: 1 + path: ../Classes/Controller/Cart/CouponController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/CurrencyController.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/CurrencyController.php + + - + message: '#^Cannot call method getPageType\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/CurrencyController.php + + - + message: '#^Parameter \#1 \$cartSettings of method Extcode\\Cart\\Utility\\CurrencyUtility\:\:updateCurrency\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CurrencyController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CurrencyController.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Binary operation "\." between ''billing_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 2 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Binary operation "\." between ''shipping_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 2 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''fields'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''options'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible count: 1 path: ../Classes/Controller/Cart/OrderController.php - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Domain\\\\Model\\\\Cart\\\\CartCouponInterface\\:\\:getTaxClass\\(\\)\\.$#" + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 6 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''redirects'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''success'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''url'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''validator'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset int on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot call method getId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 2 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Cart\\OrderController\:\:setDynamicValidation\(\) has parameter \$validatorConf with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Parameter \#1 \$uri of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:redirectToUri\(\) expects Psr\\Http\\Message\\UriInterface\|string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Parameter \#1 \$validatorType of method TYPO3\\CMS\\Extbase\\Validation\\ValidatorResolver\:\:createValidator\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Parameter \#2 \$propertyName of method Extcode\\Cart\\Controller\\Cart\\OrderController\:\:setDynamicValidation\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Parameter \#2 \$validator of method TYPO3\\CMS\\Extbase\\Validation\\Validator\\AbstractGenericObjectValidator\:\:addPropertyValidator\(\) expects TYPO3\\CMS\\Extbase\\Validation\\Validator\\ValidatorInterface, TYPO3\\CMS\\Extbase\\Validation\\Validator\\ValidatorInterface\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Parameter \#2 \$validatorOptions of method TYPO3\\CMS\\Extbase\\Validation\\ValidatorResolver\:\:createValidator\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/OrderController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/PaymentController.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/PaymentController.php + + - + message: '#^Cannot call method getPageType\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/PaymentController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/PaymentController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/PaymentController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot call method getPageType\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot call method getQuantity\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot call method getSeverity\(\) on TYPO3\\CMS\\Core\\Messaging\\FlashMessage\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot call method toArray\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Cart\\ProductController\:\:addProductsToCart\(\) has parameter \$products with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Cart\\ProductController\:\:getChangedProducts\(\) has parameter \$products with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Cart\\ProductController\:\:getChangedProducts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Method Extcode\\Cart\\Controller\\Cart\\ProductController\:\:getErrorWithHighestSeverity\(\) should return TYPO3\\CMS\\Core\\Messaging\\FlashMessage but returns TYPO3\\CMS\\Core\\Messaging\\FlashMessage\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#1 \$cartProducts of method Extcode\\Cart\\Controller\\Cart\\ProductController\:\:responseForAddAction\(\) expects array\, array given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#1 \$json of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:jsonResponse\(\) expects string\|null, string\|false given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#1 \$productId of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:removeProductById\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Parameter \#2 \$product of class Extcode\\Cart\\Event\\CheckProductAvailabilityEvent constructor expects Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: array.invalidKey + count: 2 + path: ../Classes/Controller/Cart/ProductController.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Cart/ShippingController.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/ShippingController.php + + - + message: '#^Cannot call method getPageType\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Cart/ShippingController.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ShippingController.php + + - + message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/ShippingController.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''columns'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''config'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''items'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''label'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''status'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''tx_cart_domain_model_order_payment'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''tx_cart_domain_model_order_shipping'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot access offset ''value'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Cannot call method getUid\(\) on Extcode\\Cart\\Domain\\Model\\FrontendUser\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Parameter \#1 \$key of static method TYPO3\\CMS\\Extbase\\Utility\\LocalizationUtility\:\:translate\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 2 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Order\\OrderController\:\:\$pluginSettings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Property Extcode\\Cart\\Controller\\Order\\OrderController\:\:\$searchArguments type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Controller/Order/OrderController.php + + - + message: '#^Binary operation "\." between ''tx_cart\.add_to_cart…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 4 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Binary operation "\." between non\-falsy\-string and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 2 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot access offset ''cart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot access offset ''jsonResponseForPageTypes'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method addProduct\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method getCount\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method getGross\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method getNet\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot call method getPageType\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:addProductsToCart\(\) has parameter \$products with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:getFormValues\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:getStatusMessageBody\(\) has parameter \$formValues with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:getStatusMessageBody\(\) has parameter \$status with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:getStatusMessageTitle\(\) has parameter \$formValues with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:getStatusMessageTitle\(\) has parameter \$status with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#1 \$cart of method Extcode\\Cart\\Utility\\CartUtility\:\:updateService\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#1 \$content of method TYPO3\\CMS\\Core\\Http\\StreamFactory\:\:createStream\(\) expects string, string\|false given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:restoreCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#2 \$cart of class Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent constructor expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#2 \$cart of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Parameter \#2 \$haystack of function in_array expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisher\:\:\$configurations type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisher.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisherInterface\:\:getProductFromForm\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisherInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Finisher\\Form\\AddToCartFinisherInterface\:\:getProductFromForm\(\) has parameter \$formValues with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Finisher/Form/AddToCartFinisherInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\DatabaseWriter\:\:jsonEncodeWithThrowable\(\) has parameter \$dataToEncode with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/DatabaseWriter.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:__construct\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:error\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:getArguments\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:info\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:notice\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\Log\:\:warning\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/Log.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:__construct\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:error\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:getArguments\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:info\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:notice\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Model\\LogInterface\:\:warning\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Model/LogInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Repository\\LogRepository\:\:findAllByIdentifier\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Repository/LogRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Log\\Repository\\LogRepository\:\:insert\(\) has parameter \$fieldValues with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Log/Repository/LogRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\:\:getCart\(\) should return Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart.php + + - + message: '#^Parameter \#1 \$data of function unserialize expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart.php + + - + message: '#^Cannot call method getGross\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/AbstractCartCoupon.php + + - + message: '#^Binary operation "\+" between mixed and int results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Binary operation "\+\=" between \(float\|int\) and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Binary operation "\+\=" between float and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 2 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method addBeVariants\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method changeQuantity\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method changeVariantsQuantity\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method getBeVariants\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method getGross\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method getId\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method getNet\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method getQuantity\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method removeBeVariants\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method setQuantity\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Cannot call method toArray\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:addBeVariants\(\) has parameter \$newVariants with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:changeVariantsQuantity\(\) has parameter \$variantQuantityArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:getBeVariantById\(\) should return Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\|null but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:getBeVariants\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:getParentPrice\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:getPriceCalculated\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:removeBeVariants\(\) has parameter \$beVariantsArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Parameter \#1 \$newBeVariant of method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:addBeVariant\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: array.invalidKey + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant\:\:\$beVariants type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\:\:addBeVariants\(\) has parameter \$newVariants with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariantInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\:\:changeVariantsQuantity\(\) has parameter \$variantQuantityArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariantInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\:\:getBeVariants\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariantInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\:\:removeBeVariants\(\) has parameter \$beVariantsArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariantInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/BeVariantInterface.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\*" between \-1 and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\+\=" between \(float\|int\) and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 3 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\+\=" between mixed and float results in an error\.$#' + identifier: assignOp.invalid + count: 2 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\+\=" between mixed and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 2 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\-\=" between mixed and float results in an error\.$#' + identifier: assignOp.invalid + count: 2 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Binary operation "\-\=" between mixed and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Cannot access offset ''tax'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Cannot access offset ''taxClassId'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 6 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:__construct\(\) has parameter \$taxClasses with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:changeProductsQuantity\(\) has parameter \$productQuantityArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getCouponTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getCoupons\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getDiscountTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getServiceTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getSpecials\(\) should return array\ but returns array\\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getSubtotalTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getTaxClass\(\) should return Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getTaxClasses\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:getTotalTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:removeProduct\(\) has parameter \$productVariantIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:removeProductByIds\(\) has parameter \$products with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:toJson\(\) should return string but returns string\|false\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Parameter \#1 \$key of function array_key_exists expects int\|string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Parameter \#1 \$newQuantity of method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:changeQuantity\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Parameter \#1 \$variantsArray of method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:removeBeVariants\(\) expects array\, array given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Parameter \#2 \$productVariantIds of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:removeProduct\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 7 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:\$taxes type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Cart.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\CartCouponFix\:\:getTranslatedDiscount\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponFix.php + + - + message: '#^Binary operation "\*" between mixed and float results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Binary operation "\-\=" between float and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Cannot call method getGross\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Cannot call method getTaxes\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\CartCouponPercentage\:\:getTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\CartCouponPercentage\:\:getTranslatedDiscount\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/CartCouponPercentage.php + + - + message: '#^Binary operation "\*" between float and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 4 + path: ../Classes/Domain/Model/Cart/Extra.php + + - + message: '#^Cannot call method getCart\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 4 + path: ../Classes/Domain/Model/Cart/Extra.php + + - + message: '#^Cannot call method getTaxClass\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 10 + path: ../Classes/Domain/Model/Cart/Extra.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Extra\:\:getTax\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Extra.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Extra\:\:getTaxClassDistributionOverCart\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Extra.php + + - + message: '#^Cannot access offset ''sku'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Cannot access offset ''title'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Cannot access offset ''value'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\FeVariant\:\:__construct\(\) has parameter \$variantData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\FeVariant\:\:getVariantData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Parameter \#1 \$string of function sha1 expects string, string\|false given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariant.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\FeVariantFactory\:\:create\(\) has parameter \$variantData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariantFactory.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\FeVariantFactoryInterface\:\:create\(\) has parameter \$variantData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariantFactoryInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\FeVariantInterface\:\:getVariantData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/FeVariantInterface.php + + - + message: '#^Cannot access offset ''price'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Cannot access offset ''quantity'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Cannot call method removeProduct\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Cannot call method setQuantity\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:changeQuantities\(\) has parameter \$newQuantities with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:changeVariantsQuantity\(\) has parameter \$variantQuantity with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:getQuantityDiscountPrice\(\) should return float but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:getQuantityDiscounts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:getTranslatedPrice\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:setQuantityDiscounts\(\) has parameter \$quantityDiscounts with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:toJson\(\) should return string but returns string\|false\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Cart\\Product\:\:\$quantityDiscounts type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:changeQuantities\(\) has parameter \$newQuantities with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ProductInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:changeVariantsQuantity\(\) has parameter \$variantQuantity with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ProductInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:getQuantityDiscounts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ProductInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:setQuantityDiscounts\(\) has parameter \$quantityDiscounts with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ProductInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ProductInterface.php + + - + message: '#^Cannot access offset ''from'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Cannot access offset ''until'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Cannot call method getCalc\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Cannot cast mixed to float\.$#' + identifier: cast.double + count: 7 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 7 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:__construct\(\) has parameter \$config with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getConfig\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getExtra\(\) should return Extcode\\Cart\\Domain\\Model\\Cart\\Extra but returns Extcode\\Cart\\Domain\\Model\\Cart\\Extra\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getGross\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getName\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getNet\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getProcessOrderCreateEvent\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getProvider\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getStatus\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getTax\(\) should return float but returns float\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getTaxClass\(\) should return Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass but returns Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Parameter \#1 \$extraType of method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:getConditionValueFromCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Parameter \#1 \$price of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:translatePrice\(\) expects float\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Parameter \#6 \$extraType of class Extcode\\Cart\\Domain\\Model\\Cart\\Extra constructor expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/Service.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceFactory\:\:getService\(\) has parameter \$serviceConfig with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceFactory.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\:\:__construct\(\) has parameter \$config with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\:\:getConfig\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\:\:getTaxes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\:\:setCart\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\:\:setPreset\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Classes/Domain/Model/Cart/ServiceInterface.php + + - + message: '#^Cannot cast mixed to float\.$#' + identifier: cast.double + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactory.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactory\:\:getTaxClass\(\) has parameter \$taxClassValue with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactory.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactory\:\:isValidTaxClassConfig\(\) has parameter \$value with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactory.php + + - + message: '#^Parameter \#2 \$value of class Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass constructor expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactory.php + + - + message: '#^Parameter \#4 \$title of class Extcode\\Cart\\Domain\\Model\\Cart\\TaxClass constructor expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactory.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactoryInterface\:\:getTaxClass\(\) has parameter \$taxClassValue with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Cart/TaxClassFactoryInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:getAdditional\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:getAdditional\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:getItem\(\) should return Extcode\\Cart\\Domain\\Model\\Order\\Item\|null but returns Extcode\\Cart\\Domain\\Model\\Order\\Item\|TYPO3\\CMS\\Extbase\\Persistence\\Generic\\LazyLoadingProxy\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:setAdditional\(\) has parameter \$additional with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Order\\AbstractAddress\:\:\$additional \(string\) does not accept string\|false\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Domain/Model/Order/AbstractAddress.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:getItem\(\) should return Extcode\\Cart\\Domain\\Model\\Order\\Item\|null but returns Extcode\\Cart\\Domain\\Model\\Order\\Item\|TYPO3\\CMS\\Extbase\\Persistence\\Generic\\LazyLoadingProxy\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/AbstractService.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AbstractService.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface\:\:getAdditional\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AddressInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface\:\:setAdditional\(\) has parameter \$additional with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AddressInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/AddressInterface.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Discount\:\:getItem\(\) should return Extcode\\Cart\\Domain\\Model\\Order\\Item\|null but returns Extcode\\Cart\\Domain\\Model\\Order\\Item\|TYPO3\\CMS\\Extbase\\Persistence\\Generic\\LazyLoadingProxy\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Discount.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:addTotalTax\(\) has parameter \$tax with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:getAdditional\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:getAdditional\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:removeTotalTax\(\) has parameter \$tax with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:setAdditional\(\) has parameter \$additional with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Parameter \#1 \$object of method TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\\:\:attach\(\) expects Extcode\\Cart\\Domain\\Model\\Order\\Tax, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Parameter \#1 \$object of method TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\\:\:detach\(\) expects Extcode\\Cart\\Domain\\Model\\Order\\Tax, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:\$additional \(string\) does not accept string\|false\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Domain/Model/Order/Item.php + + - + message: '#^Cannot call method attach\(\) on TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Order/Payment.php + + - + message: '#^Cannot call method detach\(\) on TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Domain/Model/Order/Payment.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Payment\:\:getTransactions\(\) should return TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\ but returns TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\\|null\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Payment.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Payment\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/Payment.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:getAdditional\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:getAdditional\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:getItem\(\) should return Extcode\\Cart\\Domain\\Model\\Order\\Item\|null but returns Extcode\\Cart\\Domain\\Model\\Order\\Item\|TYPO3\\CMS\\Extbase\\Persistence\\Generic\\LazyLoadingProxy\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:setAdditional\(\) has parameter \$additional with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/Product.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:\$additional \(string\) does not accept string\|false\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Domain/Model/Order/Product.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\ProductAdditional\:\:getAdditional\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/ProductAdditional.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\ProductAdditional\:\:getAdditional\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/ProductAdditional.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\ProductAdditional\:\:setAdditional\(\) has parameter \$additional with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/ProductAdditional.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Order\\ProductAdditional\:\:\$additional \(string\) does not accept string\|false\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Domain/Model/Order/ProductAdditional.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\TaxClass\:\:toArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Model/Order/TaxClass.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Model\\Order\\Transaction\:\:getTxnId\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Domain/Model/Order/Transaction.php + + - + message: '#^Property Extcode\\Cart\\Domain\\Model\\Order\\Transaction\:\:\$txnId has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Classes/Domain/Model/Order/Transaction.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\CartRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/CartRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\CouponRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/CouponRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\FrontendUserGroupRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/FrontendUserGroupRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\FrontendUserRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/FrontendUserRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\BillingAddressRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/BillingAddressRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\DiscountRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/DiscountRepository.php + + - + message: '#^Binary operation "\." between ''%%'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 3 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 4 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:findAll\(\) has parameter \$searchArguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:findAll\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:findAll\(\) return type has no value type specified in iterable type array\|TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:findAll\(\) return type with generic interface TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface does not specify its types\: TKey, TValue$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:getFilterConstraints\(\) has parameter \$query with generic interface TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:getFilterConstraints\(\) has parameter \$searchArguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ItemRepository\:\:getFilterConstraints\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Parameter \#1 \.\.\.\$constraints of method TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface\\:\:logicalAnd\(\) expects TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Qom\\ConstraintInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Parameter \#2 \$operand of method TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface\\:\:like\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Domain/Repository/Order/ItemRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\PaymentRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/PaymentRepository.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 2 + path: ../Classes/Domain/Repository/Order/ProductAdditionalRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\ProductAdditionalRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ProductAdditionalRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductAdditionalRepository\:\:findAllByAdditionalType\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductAdditionalRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductAdditionalRepository\:\:findAllByAdditionalType\(\) return type with generic interface TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface does not specify its types\: TKey, TValue$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ProductAdditionalRepository.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 2 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:findAll\(\) has parameter \$searchArguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:findAll\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:findAll\(\) return type has no value type specified in iterable type array\|TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:findAll\(\) return type with generic interface TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface does not specify its types\: TKey, TValue$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:getFilterConstraints\(\) has parameter \$query with generic interface TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:getFilterConstraints\(\) has parameter \$searchArguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Method Extcode\\Cart\\Domain\\Repository\\Order\\ProductRepository\:\:getFilterConstraints\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Parameter \#1 \.\.\.\$constraints of method TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface\\:\:logicalAnd\(\) expects TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Qom\\ConstraintInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Repository/Order/ProductRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\ShippingAddressRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ShippingAddressRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\ShippingRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/ShippingRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\TaxClassRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/TaxClassRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\TaxRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/TaxRepository.php + + - + message: '#^Class Extcode\\Cart\\Domain\\Repository\\Order\\TransactionRepository extends generic class TYPO3\\CMS\\Extbase\\Persistence\\Repository but does not specify its types\: T$#' + identifier: missingType.generics + count: 1 + path: ../Classes/Domain/Repository/Order/TransactionRepository.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Cannot access offset ''name'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Cannot access offset ''size'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Cannot access offset ''tmp_name'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Cannot access offset ''type'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Cannot access offset 0 on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 4 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Parameter \#1 \$object of method Extcode\\Cart\\Domain\\Validator\\OrderItemValidator\:\:getPropertyValue\(\) expects object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Parameter \#2 \$validators of method Extcode\\Cart\\Domain\\Validator\\OrderItemValidator\:\:checkProperty\(\) expects Traversable\, iterable\&SplObjectStorage given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Property TYPO3\\CMS\\Extbase\\Validation\\Validator\\AbstractGenericObjectValidator\:\:\$propertyValidators \(array\&SplObjectStorage\>\) does not accept array\&SplObjectStorage\)\|SplObjectStorage\\>\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Domain/Validator/OrderItemValidator.php + + - + message: '#^Method Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Cart/UpdateCurrencyEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Cart/UpdateCurrencyEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEventInterface\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Cart/UpdateCurrencyEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEventInterface\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Cart/UpdateCurrencyEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\CheckProductAvailabilityEvent\:\:getQuantity\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Classes/Event/CheckProductAvailabilityEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\CheckProductAvailabilityEventInterface\:\:__construct\(\) has parameter \$quantity with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Event/CheckProductAvailabilityEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\CheckProductAvailabilityEventInterface\:\:getQuantity\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Classes/Event/CheckProductAvailabilityEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:__construct\(\) has parameter \$formValues with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:getCartProducts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:getErrors\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:getFormValues\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:setCartProducts\(\) has parameter \$cartProducts with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:setErrors\(\) has parameter \$errors with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:\$cartProducts \(array\\) does not accept array\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Form\\AddToCartFinisherEvent\:\:\$errors type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Form/AddToCartFinisherEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Mail\\AttachmentEvent\:\:getAttachments\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Event/Mail/AttachmentEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Mail\\AttachmentEvent\:\:\$attachments type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Mail/AttachmentEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\CreateEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/CreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\CreateEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/CreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\CreateEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/CreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\EventInterface\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/EventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\EventInterface\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/EventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\FinishEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/FinishEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\FinishEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/FinishEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\FinishEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/FinishEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:getOnlyGenerateNumberOfType\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:setOnlyGenerateNumberOfType\(\) has parameter \$onlyGenerateNumberOfType with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Order\\NumberGeneratorEvent\:\:\$onlyGenerateNumberOfType type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEventInterface\:\:getOnlyGenerateNumberOfType\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\NumberGeneratorEventInterface\:\:setOnlyGenerateNumberOfType\(\) has parameter \$onlyGenerateNumberOfType with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/NumberGeneratorEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PaymentEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PaymentEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PaymentEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PaymentEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PaymentEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PaymentEvent.php + + - + message: '#^Cannot access offset ''order'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:getTaxClasses\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:setTaxClasses\(\) has parameter \$taxClasses with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Order\\PersistOrderEvent\:\:\$taxClasses type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEventInterface\:\:getTaxClasses\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEventInterface\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\PersistOrderEventInterface\:\:setTaxClasses\(\) has parameter \$taxClasses with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/PersistOrderEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\StockEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/StockEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\StockEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/StockEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Order\\StockEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Order/StockEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\ProcessOrderCreateEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/ProcessOrderCreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\ProcessOrderCreateEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/ProcessOrderCreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\ProcessOrderCreateEvent\:\:setSettings\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/ProcessOrderCreateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\RetrieveProductsFromRequestEvent\:\:getProducts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/RetrieveProductsFromRequestEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\RetrieveProductsFromRequestEvent\:\:setErrors\(\) has parameter \$errors with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/RetrieveProductsFromRequestEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\RetrieveProductsFromRequestEvent\:\:\$errors \(array\\) does not accept array\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Event/RetrieveProductsFromRequestEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\RetrieveProductsFromRequestEventInterface\:\:getErrors\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/RetrieveProductsFromRequestEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\RetrieveProductsFromRequestEventInterface\:\:getProducts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/RetrieveProductsFromRequestEventInterface.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:__construct\(\) has parameter \$searchArguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:getButtons\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:getSearchArguments\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:setButtons\(\) has parameter \$buttons with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Property Extcode\\Cart\\Event\\Template\\Components\\ModifyButtonBarEvent\:\:\$buttons type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyButtonBarEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyModuleTemplateEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyModuleTemplateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\Template\\Components\\ModifyModuleTemplateEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/Template/Components/ModifyModuleTemplateEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\View\\ModifyViewEvent\:\:__construct\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/View/ModifyViewEvent.php + + - + message: '#^Method Extcode\\Cart\\Event\\View\\ModifyViewEvent\:\:getSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Event/View/ModifyViewEvent.php + + - + message: '#^Parameter \#1 \$billingCountry of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setBillingCountry\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCountry.php + + - + message: '#^Parameter \#1 \$shippingCountry of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setShippingCountry\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCountry.php + + - + message: '#^Cannot access offset ''sign'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Cannot access offset ''translation'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Cannot access offset int\\|int\<1, max\> on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Cannot cast mixed to float\.$#' + identifier: cast.double + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Method Extcode\\Cart\\EventListener\\Cart\\UpdateCurrency\:\:getCurrencyConfigId\(\) has parameter \$currencyOptions with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Parameter \#1 \$currencyCode of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setCurrencyCode\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Parameter \#1 \$currencyCode of method Extcode\\Cart\\EventListener\\Cart\\UpdateCurrency\:\:getCurrencyConfigId\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Parameter \#1 \$currencySign of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setCurrencySign\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Parameter \#2 \$currencyOptions of method Extcode\\Cart\\EventListener\\Cart\\UpdateCurrency\:\:getCurrencyConfigId\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Cart/UpdateCurrency.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Call to an undefined method object\:\:getOriginalResource\(\)\.$#' + identifier: method.notFound + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Cannot access offset ''attachDocuments'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Cannot access offset string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Cannot call method getForLocalProcessing\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Parameter \#1 \$attachment of method Extcode\\Cart\\Event\\Mail\\AttachmentEvent\:\:addAttachment\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Parameter \#1 \$filename of function is_file expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Property Extcode\\Cart\\EventListener\\Mail\\AttachmentFromOrderItem\:\:\$settings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromOrderItem.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromTypoScript.php + + - + message: '#^Cannot access offset ''attachments'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromTypoScript.php + + - + message: '#^Cannot access offset string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromTypoScript.php + + - + message: '#^Parameter \#1 \$fileName of static method TYPO3\\CMS\\Core\\Utility\\GeneralUtility\:\:getFileAbsFileName\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromTypoScript.php + + - + message: '#^Property Extcode\\Cart\\EventListener\\Mail\\AttachmentFromTypoScript\:\:\$settings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Mail/AttachmentFromTypoScript.php + + - + message: '#^Binary operation "\+" between mixed and 1 results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/EventListener/Order/Create/Number.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/EventListener/Order/Create/Number.php + + - + message: '#^Method Extcode\\Cart\\EventListener\\Order\\Create\\Number\:\:__construct\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Order/Create/Number.php + + - + message: '#^Parameter \#1 \$format of function sprintf expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/Number.php + + - + message: '#^Parameter \#1 \$orderId of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setOrderId\(\) expects int, int\<1, max\>\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/OrderNumber.php + + - + message: '#^Parameter \#1 \$orderNumber of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setOrderNumber\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/OrderNumber.php + + - + message: '#^Cannot call method getCode\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method getGross\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method getNet\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method getTax\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method getTaxClass\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method getTitle\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot call method isUseable\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php + + - + message: '#^Cannot access offset ''currency'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Cannot access offset ''currencySign'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Cannot access offset ''format'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Parameter \#1 \$currency of method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:setCurrency\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Parameter \#1 \$feUser of method Extcode\\Cart\\Domain\\Model\\Order\\Item\:\:setFeUser\(\) expects Extcode\\Cart\\Domain\\Model\\FrontendUser, TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Parameter \#1 \$uid of method TYPO3\\CMS\\Extbase\\Persistence\\Repository\\:\:findByUid\(\) expects int, array\|bool\|int\|string given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Cannot call method getGross\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getName\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getNet\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getStatus\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getTax\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Cannot call method getTaxClass\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Parameter \#1 \$note of method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:setNote\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Parameter \#1 \$object_or_class of function method_exists expects object\|string, Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Parameter \#1 \$taxClass of method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:setTaxClass\(\) expects Extcode\\Cart\\Domain\\Model\\Order\\TaxClass, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\|Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:getCompleteSku\(\)\.$#' + identifier: method.notFound + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface\|Extcode\\Cart\\Domain\\Model\\Cart\\ProductInterface\:\:getParent\(\)\.$#' + identifier: method.notFound + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Cannot call method getBeVariants\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Method Extcode\\Cart\\EventListener\\Order\\Create\\PersistOrder\\Products\:\:addProductAdditional\(\) has parameter \$feVariant with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' + identifier: argument.type + count: 4 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Parameter \#1 \$taxClass of method Extcode\\Cart\\Domain\\Model\\Order\\Product\:\:setTaxClass\(\) expects Extcode\\Cart\\Domain\\Model\\Order\\TaxClass, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Parameter \#1 \$variant of method Extcode\\Cart\\EventListener\\Order\\Create\\PersistOrder\\Products\:\:addBeVariant\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Parameter \#1 \$variant of method Extcode\\Cart\\EventListener\\Order\\Create\\PersistOrder\\Products\:\:addVariantsOfVariant\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\BeVariantInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Parameter \#3 \$feVariant of method Extcode\\Cart\\EventListener\\Order\\Create\\PersistOrder\\Products\:\:addProductAdditional\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Property Extcode\\Cart\\EventListener\\Order\\Create\\PersistOrder\\Products\:\:\$taxClasses type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Products.php + + - + message: '#^Cannot call method getGross\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getName\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getNet\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getStatus\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getTax\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Cannot call method getTaxClass\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Parameter \#1 \$note of method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:setNote\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Parameter \#1 \$object_or_class of function method_exists expects object\|string, Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Parameter \#1 \$taxClass of method Extcode\\Cart\\Domain\\Model\\Order\\AbstractService\:\:setTaxClass\(\) expects Extcode\\Cart\\Domain\\Model\\Order\\TaxClass, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php + + - + message: '#^Binary operation "\." between ''billing_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Binary operation "\." between ''shipping_address_'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot access offset ''cart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot access offset ''preventClearCart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot access offset int on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot call method getId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Finish/ClearCart.php + + - + message: '#^Cannot call method getServiceId\(\) on Extcode\\Cart\\Domain\\Model\\Order\\Payment\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Order/Finish/Email.php + + - + message: '#^Parameter \#1 \$object_or_class of function method_exists expects object\|string, Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/EventListener/Order/Finish/Email.php + + - + message: '#^Cannot call method current\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/EventListener/Template/Components/ModifyButtonBar.php + + - + message: '#^Method Extcode\\Cart\\EventListener\\Template\\Components\\ModifyButtonBar\:\:getDocumentButtons\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/EventListener/Template/Components/ModifyButtonBar.php + + - + message: '#^Cannot access an offset on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Cannot access offset ''itemsProcFuncConfig'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Cannot access offset ''name'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Cannot access offset ''persistenceIdentifier'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\FormDefinitions\:\:getFormSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\FormDefinitions\:\:getItems\(\) has parameter \$config with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Method TYPO3\\CMS\\Form\\Mvc\\Persistence\\FormPersistenceManagerInterface\:\:listForms\(\) invoked with 1 parameter, 2 required\.$#' + identifier: arguments.count + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Parameter \#1 \$persistenceIdentifier of method TYPO3\\CMS\\Form\\Mvc\\Persistence\\FormPersistenceManagerInterface\:\:load\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Parameter \#3 \$request of method TYPO3\\CMS\\Form\\Mvc\\Persistence\\FormPersistenceManagerInterface\:\:load\(\) expects Psr\\Http\\Message\\ServerRequestInterface\|null, array given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/FormDefinitions.php + + - + message: '#^Cannot access offset ''colPos'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset ''extKey'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset ''pid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset ''pluginName'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset 0 on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset 1 on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 2 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:getLanguageService\(\) should return TYPO3\\CMS\\Core\\Localization\\LanguageService but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:getPageId\(\) should return int but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:reduceTemplateLayouts\(\) has parameter \$templateLayouts with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:reduceTemplateLayouts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:user_templateLayout\(\) has parameter \$config with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Offset ''pid'' might not exist on array\|null\.$#' + identifier: offsetAccess.notFound + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#1 \$array of function array_push expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#1 \$input of method TYPO3\\CMS\\Core\\Localization\\LanguageService\:\:sL\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#1 \$pid of method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:getPageId\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#2 \$currentColPos of method Extcode\\Cart\\Hooks\\ItemsProcFunc\:\:reduceTemplateLayouts\(\) expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#2 \$extKey of method Extcode\\Cart\\Utility\\TemplateLayout\:\:getAvailableTemplateLayouts\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#2 \$string of static method TYPO3\\CMS\\Core\\Utility\\GeneralUtility\:\:intExplode\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Parameter \#3 \$pluginName of method Extcode\\Cart\\Utility\\TemplateLayout\:\:getAvailableTemplateLayouts\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Hooks/ItemsProcFunc.php + + - + message: '#^Cannot access offset ''bccAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''buyer'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 10 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''ccAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailBccAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailCcAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailFromAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailFromName'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailReplyToAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''emailToAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''fromAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''fromName'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''replyToAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''seller'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 10 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot access offset ''toAddress'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Cannot call method getStatus\(\) on Extcode\\Cart\\Domain\\Model\\Order\\Payment\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$buyerEmailBcc of method Extcode\\Cart\\Service\\MailHandler\:\:setBuyerEmailBcc\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$buyerEmailCc of method Extcode\\Cart\\Service\\MailHandler\:\:setBuyerEmailCc\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$buyerEmailReplyTo of method Extcode\\Cart\\Service\\MailHandler\:\:setBuyerEmailReplyTo\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$email of method Extcode\\Cart\\Service\\MailHandler\:\:setBuyerEmailFrom\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$email of method Extcode\\Cart\\Service\\MailHandler\:\:setSellerEmailFrom\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$email of method Extcode\\Cart\\Service\\MailHandler\:\:setSellerEmailTo\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$name of method Extcode\\Cart\\Service\\MailHandler\:\:setBuyerEmailName\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$name of method Extcode\\Cart\\Service\\MailHandler\:\:setSellerEmailName\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$sellerEmailBcc of method Extcode\\Cart\\Service\\MailHandler\:\:setSellerEmailBcc\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Parameter \#1 \$sellerEmailCc of method Extcode\\Cart\\Service\\MailHandler\:\:setSellerEmailCc\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Property Extcode\\Cart\\Service\\MailHandler\:\:\$pluginSettings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/MailHandler.php + + - + message: '#^Method Extcode\\Cart\\Service\\OrderItemCleanupService\:\:deleteRecordsFromTable\(\) has parameter \$recordUids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/OrderItemCleanupService.php + + - + message: '#^Method Extcode\\Cart\\Service\\OrderItemCleanupService\:\:getRecordUidsToDelete\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/OrderItemCleanupService.php + + - + message: '#^Parameter \#1 \$keys of function array_fill_keys expects an array of values castable to string, array given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Service/OrderItemCleanupService.php + + - + message: '#^Binary operation "\." between mixed and string results in an error\.$#' + identifier: binaryOp.invalid + count: 5 + path: ../Classes/Service/SessionHandler.php + + - + message: '#^Cannot call method getAttribute\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Service/SessionHandler.php + + - + message: '#^Property Extcode\\Cart\\Service\\SessionHandler\:\:\$frontendUserAuthentication \(TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication\) does not accept mixed\.$#' + identifier: assign.propertyType + count: 1 + path: ../Classes/Service/SessionHandler.php + + - + message: '#^Property Extcode\\Cart\\Service\\SessionHandler\:\:\$prefixKey has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Classes/Service/SessionHandler.php + + - + message: '#^Cannot access offset ''cart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''code'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''countries'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''currencies'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''isNetCart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''options'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''preset'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset mixed on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot call method getFallBackId\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot call method getId\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot call method isAvailable\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot call method setCart\(\) on Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot cast mixed to float\.$#' + identifier: cast.double + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CartUtility\:\:getNewCart\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CartUtility\:\:getServiceById\(\) has parameter \$services with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CartUtility\:\:updateCountry\(\) has parameter \$cartSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CartUtility\:\:updateCountry\(\) has parameter \$pluginSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$billingCountry of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setBillingCountry\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$cart of class Extcode\\Cart\\Event\\Cart\\UpdateCountryEvent constructor expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$countryCode of method Extcode\\Cart\\Configuration\\Loader\\TaxClassLoaderInterface\:\:getTaxClasses\(\) expects string\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:restoreCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$payment of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setPayment\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$shipping of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setShipping\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\ServiceInterface, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#1 \$shippingCountry of method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\:\:setShippingCountry\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Parameter \#2 \$serviceId of method Extcode\\Cart\\Utility\\CartUtility\:\:getServiceById\(\) expects int, int\|null given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Utility/CartUtility.php + + - + message: '#^Cannot access offset ''currencies'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CurrencyUtility\:\:updateCurrency\(\) has parameter \$cartSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Method Extcode\\Cart\\Utility\\CurrencyUtility\:\:updateCurrency\(\) has parameter \$pluginSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Parameter \#1 \$cart of class Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEvent constructor expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:restoreCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Parameter \#1 \$key of method Extcode\\Cart\\Service\\SessionHandler\:\:writeCart\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Parameter \#3 \$settings of class Extcode\\Cart\\Event\\Cart\\UpdateCurrencyEvent constructor expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/CurrencyUtility.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/Utility/EvalPrice.php + + - + message: '#^Method Extcode\\Cart\\Utility\\EvalPrice\:\:evaluateFieldValue\(\) has parameter \$is_in with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Utility/EvalPrice.php + + - + message: '#^Method Extcode\\Cart\\Utility\\EvalPrice\:\:evaluateFieldValue\(\) has parameter \$set with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Utility/EvalPrice.php + + - + message: '#^Method Extcode\\Cart\\Utility\\EvalPrice\:\:evaluateFieldValue\(\) has parameter \$value with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/Utility/EvalPrice.php + + - + message: '#^Method Extcode\\Cart\\Utility\\EvalPrice\:\:evaluateFieldValue\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Utility/EvalPrice.php + + - + message: '#^Cannot access offset ''EXT'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Cannot access offset ''templateLayouts'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Cannot access offset ''templateLayouts\.'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Cannot access offset non\-falsy\-string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Cannot access offset string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Method Extcode\\Cart\\Utility\\TemplateLayout\:\:getAvailableTemplateLayouts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Method Extcode\\Cart\\Utility\\TemplateLayout\:\:getTemplateLayoutsFromTsConfig\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Parameter \#2 \$string of static method TYPO3\\CMS\\Core\\Utility\\GeneralUtility\:\:trimExplode\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Utility/TemplateLayout.php + + - + message: '#^Binary operation "\." between ''\$GLOBALS\[\\''BE_USER\\''\]…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Utility/Typo3GlobalsUtility.php + + - + message: '#^Binary operation "\." between ''\$GLOBALS\[\\''TYPO3…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Utility/Typo3GlobalsUtility.php + + - + message: '#^Binary operation "\." between ''\$site was not of…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Utility/Typo3GlobalsUtility.php + + - + message: '#^Method Extcode\\Cart\\ViewHelpers\\AdditionalJsonViewHelper\:\:getValue\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/ViewHelpers/AdditionalJsonViewHelper.php + + - + message: '#^Method Extcode\\Cart\\ViewHelpers\\AdditionalJsonViewHelper\:\:getValue\(\) should return string but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/ViewHelpers/AdditionalJsonViewHelper.php + + - + message: '#^Parameter \#1 \$data of method Extcode\\Cart\\ViewHelpers\\AdditionalJsonViewHelper\:\:getValue\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/ViewHelpers/AdditionalJsonViewHelper.php + + - + message: '#^Parameter \#2 \$key of method Extcode\\Cart\\ViewHelpers\\AdditionalJsonViewHelper\:\:getValue\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/AdditionalJsonViewHelper.php + + - + message: '#^Parameter \#2 \$delim of static method TYPO3\\CMS\\Core\\Utility\\CsvUtility\:\:csvValues\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/CsvHeaderViewHelper.php + + - + message: '#^Parameter \#3 \$quote of static method TYPO3\\CMS\\Core\\Utility\\CsvUtility\:\:csvValues\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/CsvHeaderViewHelper.php + + - + message: '#^Cannot call method format\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getBillingAddress\(\) on mixed\.$#' + identifier: method.nonObject + count: 4 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getFirstName\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getInvoiceDate\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getInvoiceNumber\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getLastName\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getOrderDate\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getOrderNumber\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getSalutation\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Cannot call method getTitle\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Parameter \#1 \$row of static method TYPO3\\CMS\\Core\\Utility\\CsvUtility\:\:csvValues\(\) expects array\, array\ given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Parameter \#2 \$delim of static method TYPO3\\CMS\\Core\\Utility\\CsvUtility\:\:csvValues\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Parameter \#3 \$quote of static method TYPO3\\CMS\\Core\\Utility\\CsvUtility\:\:csvValues\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/CsvValuesViewHelper.php + + - + message: '#^Binary operation "\." between ''\['' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/ViewHelpers/FieldNameViewHelper.php + + - + message: '#^Cannot call method getId\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/FieldNameViewHelper.php + + - + message: '#^Parameter \#1 \$variant of method Extcode\\Cart\\ViewHelpers\\FieldNameViewHelper\:\:getVariantFieldName\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\BeVariant, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/FieldNameViewHelper.php + + - + message: '#^Cannot call method isAvailable\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php + + - + message: '#^Binary operation "\." between mixed and ''''\|'' '' results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Binary operation "\." between string and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Binary operation "/\=" between float and mixed results in an error\.$#' + identifier: assignOp.invalid + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Cannot access offset ''currency'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Cannot access offset ''format'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Cannot call method get\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Cannot cast mixed to float\.$#' + identifier: cast.double + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Parameter \#2 \$decimals of function number_format expects int, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Parameter \#3 \$decimal_separator of function number_format expects string\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Parameter \#4 \$thousands_separator of function number_format expects string\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Format/CurrencyViewHelper.php + + - + message: '#^Call to method sanitize\(\) of deprecated class TYPO3\\CMS\\Frontend\\Resource\\FilePathSanitizer\.$#' + identifier: method.deprecatedClass + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Cannot access property \$tmpl on mixed\.$#' + identifier: property.nonObject + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Cannot access property \$tt_track on mixed\.$#' + identifier: property.nonObject + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 3 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Parameter \#1 \$file of method TYPO3\\CMS\\Core\\Page\\PageRenderer\:\:addCssFile\(\) expects string\|TYPO3\\CMS\\Core\\SystemResource\\Type\\StaticResourceInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Parameter \#1 \$file of method TYPO3\\CMS\\Core\\Page\\PageRenderer\:\:addJsFile\(\) expects string\|TYPO3\\CMS\\Core\\SystemResource\\Type\\StaticResourceInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Parameter \#1 \$request of static method TYPO3\\CMS\\Core\\Http\\ApplicationType\:\:fromRequest\(\) expects Psr\\Http\\Message\\ServerRequestInterface, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Parameter \$filePathSanitizer of method Extcode\\Cart\\ViewHelpers\\IncludeFileViewHelper\:\:__construct\(\) has typehint with deprecated class TYPO3\\CMS\\Frontend\\Resource\\FilePathSanitizer\.$#' + identifier: parameter.deprecatedClass + count: 1 + path: ../Classes/ViewHelpers/IncludeFileViewHelper.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset ''classes'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset ''columns'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset ''mapOnProperty'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset ''mapping'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset ''tableName'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Cannot access offset mixed on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Method Extcode\\Cart\\ViewHelpers\\MapModelPropertiesToTableColumnsViewHelper\:\:render\(\) should return array\ but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Parameter \#1 \$object of static method TYPO3\\CMS\\Extbase\\Reflection\\ObjectAccess\:\:getGettableProperties\(\) expects object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php + + - + message: '#^Parameter \#1 \$property of method TYPO3\\CMS\\Core\\MetaTag\\MetaTagManagerInterface\:\:addProperty\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/MetaTagViewHelper.php + + - + message: '#^Parameter \#1 \$property of method TYPO3\\CMS\\Core\\MetaTag\\MetaTagManagerRegistry\:\:getManagerForProperty\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/MetaTagViewHelper.php + + - + message: '#^Parameter \#2 \$content of method TYPO3\\CMS\\Core\\MetaTag\\MetaTagManagerInterface\:\:addProperty\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/MetaTagViewHelper.php + + - + message: '#^Strict comparison using \!\=\= between '''' and '''' will always evaluate to false\.$#' + identifier: notIdentical.alwaysFalse + count: 1 + path: ../Classes/ViewHelpers/TitleTagViewHelper.php + + - + message: '#^Variable \$arguments on left side of \?\? is never defined\.$#' + identifier: nullCoalesce.variable + count: 1 + path: ../Classes/ViewHelpers/TitleTagViewHelper.php + + - + message: '#^Cannot access offset string on array\\|Traversable\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Cannot call method add\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Cannot call method exists\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Cannot call method get\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Cannot call method remove\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Method Extcode\\Cart\\ViewHelpers\\Traversable\\ExtractViewHelper\:\:extractByKey\(\) has parameter \$iterator with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Parameter \#2 \$key of method Extcode\\Cart\\ViewHelpers\\Traversable\\ExtractViewHelper\:\:extractByKey\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Cannot call method exists\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Cannot call method get\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 2 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Parameter \#1 \$subject of static method TYPO3\\CMS\\Extbase\\Reflection\\ObjectAccess\:\:getProperty\(\) expects array\|object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Parameter \#1 \$subject of static method TYPO3\\CMS\\Extbase\\Reflection\\ObjectAccess\:\:getPropertyPath\(\) expects array\|object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Variable/GetViewHelper.php + + - + message: '#^Cannot call method add\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Cannot call method exists\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Cannot call method get\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Cannot call method remove\(\) on TYPO3Fluid\\Fluid\\Core\\Variables\\VariableProviderInterface\|null\.$#' + identifier: method.nonObject + count: 2 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 3 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Parameter \#1 \$subject of static method TYPO3\\CMS\\Extbase\\Reflection\\ObjectAccess\:\:setProperty\(\) expects array\|object, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/ViewHelpers/Variable/SetViewHelper.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\PaymentPaidShippingOpen\:\:__construct\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/PaymentPaidShippingOpen.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\PaymentPaidShippingOpen\:\:getOptions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/PaymentPaidShippingOpen.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrderItemsProvider\:\:__construct\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrderItemsProvider\:\:getItems\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Parameter \#1 \$fieldName of method TYPO3\\CMS\\Core\\Database\\Query\\QueryBuilder\:\:orderBy\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Parameter \#1 \$maxResults of method TYPO3\\CMS\\Core\\Database\\Query\\QueryBuilder\:\:setMaxResults\(\) expects int\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Parameter \#2 \$order of method TYPO3\\CMS\\Core\\Database\\Query\\QueryBuilder\:\:orderBy\(\) expects string\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Property Extcode\\Cart\\Widgets\\Provider\\OrderItemsProvider\:\:\$options type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrderItemsProvider.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrdersPerDayProvider\:\:__construct\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrdersPerDayProvider\:\:calculateData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrdersPerDayProvider\:\:getChartData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\OrdersPerDayProvider\:\:getOrderItemsInPeriod\(\) should return int but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Parameter \#1 \$fieldName of method TYPO3\\CMS\\Core\\Database\\Query\\Expression\\ExpressionBuilder\:\:gte\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Parameter \#1 \$fieldName of method TYPO3\\CMS\\Core\\Database\\Query\\Expression\\ExpressionBuilder\:\:lte\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Parameter \#1 \$user of method TYPO3\\CMS\\Core\\Localization\\LanguageServiceFactory\:\:createFromUserPreferences\(\) expects TYPO3\\CMS\\Core\\Authentication\\AbstractUserAuthentication\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Property Extcode\\Cart\\Widgets\\Provider\\OrdersPerDayProvider\:\:\$options type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/OrdersPerDayProvider.php + + - + message: '#^Binary operation "\." between ''tx_cart_domain…'' and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\TurnoverPerDayProvider\:\:__construct\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\TurnoverPerDayProvider\:\:calculateData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\TurnoverPerDayProvider\:\:getChartData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Method Extcode\\Cart\\Widgets\\Provider\\TurnoverPerDayProvider\:\:getOrderItemsInPeriod\(\) should return float but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Parameter \#1 \$fieldName of method TYPO3\\CMS\\Core\\Database\\Query\\Expression\\ExpressionBuilder\:\:gte\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Parameter \#1 \$fieldName of method TYPO3\\CMS\\Core\\Database\\Query\\Expression\\ExpressionBuilder\:\:lte\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Parameter \#1 \$user of method TYPO3\\CMS\\Core\\Localization\\LanguageServiceFactory\:\:createFromUserPreferences\(\) expects TYPO3\\CMS\\Core\\Authentication\\AbstractUserAuthentication\|null, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Property Extcode\\Cart\\Widgets\\Provider\\TurnoverPerDayProvider\:\:\$options type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Widgets/Provider/TurnoverPerDayProvider.php + + - + message: '#^Cannot access offset ''1'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''pages'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''types'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Parameter \#1 \$original of static method TYPO3\\CMS\\Core\\Utility\\ArrayUtility\:\:mergeRecursiveWithOverrule\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot call method create\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Functional/Command/AbstractCommandTestCase.php + + - + message: '#^Cannot access offset ''deleted'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 33 + path: ../Tests/Functional/Command/OrderItemCleanupCommandTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Functional\\Command\\OrderItemCleanupCommandTest\:\:wrongCutOffDateDataProvider\(\) return type has no value type specified in iterable type iterable\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Functional/Command/OrderItemCleanupCommandTest.php + + - + message: '#^Parameter \#1 \$command of class Symfony\\Component\\Console\\Tester\\CommandTester constructor expects \(callable\(\)\: mixed\)\|Symfony\\Component\\Console\\Command\\Command, mixed given\.$#' + identifier: argument.type + count: 6 + path: ../Tests/Functional/Command/OrderItemCleanupCommandTest.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php + + - + message: '#^Cannot access constant class on mixed\.$#' + identifier: classConstant.nonObject + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php + + - + message: '#^Cannot call method getListenersForEvent\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php + + - + message: '#^Cannot access constant class on mixed\.$#' + identifier: classConstant.nonObject + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php + + - + message: '#^Cannot call method getListenersForEvent\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Configuration\\Loader\\TypoScript\\AbstractConfigurationLoaderTest\:\:createSubject\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Configuration/Loader/TypoScript/AbstractConfigurationLoaderTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Configuration\\Loader\\TypoScript\\TaxClassLoaderTest\:\:createSubject\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Configuration/Loader/TypoScript/TaxClassLoaderTest.php + + - + message: '#^Cannot call method getMessage\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Cannot call method getSeverity\(\) on mixed\.$#' + identifier: method.nonObject count: 2 - path: ../Classes/Domain/Model/Cart/Cart.php + path: ../Tests/Unit/Controller/ProductControllerTest.php - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Domain\\\\Model\\\\Cart\\\\CartCouponInterface\\:\\:setCart\\(\\)\\.$#" + message: '#^Cannot call method getTitle\(\) on mixed\.$#' + identifier: method.nonObject count: 1 - path: ../Classes/Domain/Model/Cart/Cart.php + path: ../Tests/Unit/Controller/ProductControllerTest.php - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Service\\\\PaymentMethodsServiceInterface\\:\\:getConfigurationsForType\\(\\)\\.$#" + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Controller\\ProductControllerTest\:\:getHighestSeverity\(\) has parameter \$errors with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 - path: ../Classes/EventListener/Order/Finish/ClearCart.php + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Controller\\ProductControllerTest\:\:getHighestSeverityDataProvider\(\) return type has no value type specified in iterable type iterable\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Controller\\ProductControllerTest\:\:getLastHighestSeverity\(\) has parameter \$errors with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Controller\\ProductControllerTest\:\:getLastHighestSeverityDataProvider\(\) return type has no value type specified in iterable type iterable\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject\:\:method\(\)\.$#' + identifier: method.notFound + count: 4 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\CartCouponFixTest\:\:createCartMock\(\) has parameter \$methods with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php + + - + message: '#^Parameter \#1 \$cart of method Extcode\\Cart\\Domain\\Model\\Cart\\AbstractCartCoupon\:\:setCart\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject given\.$#' + identifier: argument.type + count: 4 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject\:\:method\(\)\.$#' + identifier: method.notFound + count: 12 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\CartCouponPercentageTest\:\:createCartMock\(\) has parameter \$methods with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php + + - + message: '#^Parameter \#1 \$cart of method Extcode\\Cart\\Domain\\Model\\Cart\\AbstractCartCoupon\:\:setCart\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject given\.$#' + identifier: argument.type + count: 9 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php + + - + message: '#^Parameter \#1 \$array of function array_diff_assoc expects an array of values castable to string, array given\.$#' + identifier: argument.type + count: 2 + path: ../Tests/Unit/Domain/Model/Cart/CartTest.php + + - + message: '#^Parameter \#2 \$arrays of function array_diff_assoc expects an array of values castable to string, array given\.$#' + identifier: argument.type + count: 2 + path: ../Tests/Unit/Domain/Model/Cart/CartTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\CartTest\:\:\$taxClasses type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/CartTest.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject\:\:addProduct\(\)\.$#' + identifier: method.notFound + count: 2 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Call to an undefined method Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject\:\:method\(\)\.$#' + identifier: method.notFound + count: 12 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\ServiceTest\:\:createCartMock\(\) has parameter \$methods with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Parameter \#1 \$cart of method Extcode\\Cart\\Domain\\Model\\Cart\\Service\:\:setCart\(\) expects Extcode\\Cart\\Domain\\Model\\Cart\\Cart, Extcode\\Cart\\Domain\\Model\\Cart\\Cart\|PHPUnit\\Framework\\MockObject\\MockObject given\.$#' + identifier: argument.type + count: 14 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\ServiceTest\:\:\$config type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Cart\\ServiceTest\:\:\$taxClasses type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php + + - + message: '#^Parameter \#1 \$transactions of method Extcode\\Cart\\Domain\\Model\\Order\\Payment\:\:setTransactions\(\) expects TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\, TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage\ given\.$#' + identifier: argument.type + count: 1 + path: ../Tests/Unit/Domain/Model/Order/PaymentTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\CategoryTraitStub\:\:getCategories\(\) return type with generic class TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage does not specify its types\: TEntity$#' + identifier: missingType.generics + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitStub.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\CategoryTraitStub\:\:setCategories\(\) has parameter \$categories with generic class TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage but does not specify its types\: TEntity$#' + identifier: missingType.generics + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitStub.php + + - + message: '#^Cannot call method count\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitTest.php + + - + message: '#^Cannot call method getCategories\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitTest.php + + - + message: '#^Cannot call method getCategory\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitTest.php + + - + message: '#^Cannot call method setCategory\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\CategoryTraitTest\:\:\$trait has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Tests/Unit/Domain/Model/Product/CategoryTraitTest.php + + - + message: '#^Binary operation "/" between 1\.0 and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Binary operation "/" between float and mixed results in an error\.$#' + identifier: binaryOp.invalid + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Cannot access offset string on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitStub\:\:getMeasureUnits\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitStub\:\:setMeasureUnits\(\) has parameter \$measureUnits with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Parameter \#2 \$array of function array_key_exists expects array, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitStub\:\:\$measureUnits type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitStub.php + + - + message: '#^Cannot call method getBasePriceMeasureUnit\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getIsMeasureUnitCompatibility\(\) on mixed\.$#' + identifier: method.nonObject + count: 4 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getMeasureUnitFactor\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getMeasureUnits\(\) on mixed\.$#' + identifier: method.nonObject + count: 5 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getPriceMeasure\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getPriceMeasureUnit\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method setBasePriceMeasureUnit\(\) on mixed\.$#' + identifier: method.nonObject + count: 5 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method setMeasureUnits\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method setPriceMeasure\(\) on mixed\.$#' + identifier: method.nonObject + count: 3 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method setPriceMeasureUnit\(\) on mixed\.$#' + identifier: method.nonObject + count: 4 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice\(\) has parameter \$calculatedBasePrice with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice\(\) has parameter \$factor with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice\(\) has parameter \$priceMeasure with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice\(\) has parameter \$sourceMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice\(\) has parameter \$targetMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit\(\) has parameter \$calculatedBasePrice with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit\(\) has parameter \$factor with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit\(\) has parameter \$priceMeasure with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit\(\) has parameter \$sourceMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit\(\) has parameter \$targetMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor\(\) has parameter \$calculatedBasePrice with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor\(\) has parameter \$factor with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor\(\) has parameter \$priceMeasure with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor\(\) has parameter \$sourceMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor\(\) has parameter \$targetMeasureUnit with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:measureUnitsProvider\(\) return type has no value type specified in iterable type iterable\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\MeasureTraitTest\:\:\$trait has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Tests/Unit/Domain/Model/Product/MeasureTraitTest.php + + - + message: '#^Cannot call method getServiceAttribute1\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method getServiceAttribute2\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method getServiceAttribute3\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method setServiceAttribute1\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method setServiceAttribute2\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method setServiceAttribute3\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\ServiceAttributeTraitTest\:\:\$trait has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Tests/Unit/Domain/Model/Product/ServiceAttributeTraitTest.php + + - + message: '#^Cannot call method getStock\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/StockTraitTest.php + + - + message: '#^Cannot call method isHandleStock\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/StockTraitTest.php + + - + message: '#^Cannot call method setIsHandleStock\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/StockTraitTest.php + + - + message: '#^Cannot call method setStock\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/StockTraitTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\StockTraitTest\:\:\$trait has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Tests/Unit/Domain/Model/Product/StockTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\TagTraitStub\:\:getTags\(\) return type with generic class TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage does not specify its types\: TEntity$#' + identifier: missingType.generics + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitStub.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\TagTraitStub\:\:setTags\(\) has parameter \$tags with generic class TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage but does not specify its types\: TEntity$#' + identifier: missingType.generics + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitStub.php + + - + message: '#^Cannot call method addTag\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Cannot call method attach\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Cannot call method count\(\) on mixed\.$#' + identifier: method.nonObject + count: 4 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Cannot call method getTags\(\) on mixed\.$#' + identifier: method.nonObject + count: 8 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Cannot call method removeTag\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Cannot call method setTags\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Property Extcode\\Cart\\Tests\\Unit\\Domain\\Model\\Product\\TagTraitTest\:\:\$trait has no type specified\.$#' + identifier: missingType.property + count: 1 + path: ../Tests/Unit/Domain/Model/Product/TagTraitTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Validation\\Validator\\EmptyValidatorTest\:\:getValidator\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Validation\\Validator\\EmptyValidatorTest\:\:getValidator\(\) should return TYPO3\\CMS\\Extbase\\Validation\\Validator\\ValidatorInterface but returns object\.$#' + identifier: return.type + count: 1 + path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Validation\\Validator\\EmptyValidatorTest\:\:validatorOptions\(\) has parameter \$options with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php + + - + message: '#^Parameter \#1 \$className of method PHPUnit\\Framework\\TestCase\:\:getMockBuilder\(\) expects class\-string\, string given\.$#' + identifier: argument.type + count: 1 + path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php + + - + message: '#^Unable to resolve the template type T in call to method PHPUnit\\Framework\\TestCase\:\:getMockBuilder\(\)$#' + identifier: argument.templateType + count: 1 + path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php diff --git a/Build/phpstan.neon b/Build/phpstan.neon index 13c67700..f582a280 100644 --- a/Build/phpstan.neon +++ b/Build/phpstan.neon @@ -1,10 +1,35 @@ includes: - - phpstan-baseline.neon + - 'phpstan-baseline.neon' + parameters: - level: 4 + level: 'max' + paths: - ../Classes - ../Configuration - ../Tests - - ../ext_emconf.php - ../ext_localconf.php + + disallowedFunctionCalls: + - + function: + - 'var_dump()' + - 'xdebug_break()' + message: 'Do not add debugging' + - + function: 'header()' + message: 'Use API instead' + + disallowedStaticCalls: + - + method: 'TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump()' + message: 'Do not add debugging' + + disallowedSuperglobals: + - + superglobal: + - '$_GET' + - '$_POST' + - '$_FILES' + - '$_SERVER' + message: 'Use API instead' diff --git a/Build/FunctionalTests.xml b/Build/phpunit.xml.dist similarity index 88% rename from Build/FunctionalTests.xml rename to Build/phpunit.xml.dist index c381bae5..d6e33ac2 100644 --- a/Build/FunctionalTests.xml +++ b/Build/phpunit.xml.dist @@ -18,9 +18,12 @@ > - + ../Tests/Functional/ + + ../Tests/Unit/ + diff --git a/Classes/Command/OrderItemCleanupCommand.php b/Classes/Command/OrderItemCleanupCommand.php index d58a49e5..b5e24830 100644 --- a/Classes/Command/OrderItemCleanupCommand.php +++ b/Classes/Command/OrderItemCleanupCommand.php @@ -27,7 +27,7 @@ public function __construct( parent::__construct(); } - protected function configure() + protected function configure(): void { $this->setDescription('Will remove all old orders'); $this->addArgument( @@ -41,7 +41,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $cutOffDate = $input->getArgument('cutOffDate'); - if (is_string($cutOffDate) === false || $this->isCutOffDateValid($cutOffDate) === false) { + if (is_string($cutOffDate) === false || self::isCutOffDateValid($cutOffDate) === false) { $output->writeln('The cutOffDate argument must follow the pattern YYYY-MM-DD.'); return Command::FAILURE; @@ -58,7 +58,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } - private function isCutOffDateValid(string $cutOffDate): bool + private static function isCutOffDateValid(string $cutOffDate): bool { $pattern = '/^\d{4}-\d{2}-\d{2}$/'; diff --git a/Classes/Constants.php b/Classes/Configuration/Constants.php similarity index 93% rename from Classes/Constants.php rename to Classes/Configuration/Constants.php index 2a5efc76..0364cb08 100644 --- a/Classes/Constants.php +++ b/Classes/Configuration/Constants.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart; +namespace Extcode\Cart\Configuration; /* * This file is part of the package extcode/cart @@ -19,5 +19,6 @@ class Constants public const DOKTYPE_CART_CART = 181; public const LANGUAGE_PATH = 'LLL:EXT:cart/Resources/Private/Language/locallang.xlf'; + public const LANGUAGE_BE_PATH = 'LLL:EXT:cart/Resources/Private/Language/locallang_be.xlf'; } diff --git a/Classes/Service/CurrencyTranslationService.php b/Classes/Configuration/Loader/CurrencyTranslationLoader.php similarity index 78% rename from Classes/Service/CurrencyTranslationService.php rename to Classes/Configuration/Loader/CurrencyTranslationLoader.php index 526392f6..529eccb5 100644 --- a/Classes/Service/CurrencyTranslationService.php +++ b/Classes/Configuration/Loader/CurrencyTranslationLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -11,7 +11,7 @@ * LICENSE file that was distributed with this source code. */ -class CurrencyTranslationService implements CurrencyTranslationServiceInterface +class CurrencyTranslationLoader implements CurrencyTranslationLoaderInterface { public function translatePrice(float $factor, ?float $price = null): ?float { diff --git a/Classes/Service/CurrencyTranslationServiceInterface.php b/Classes/Configuration/Loader/CurrencyTranslationLoaderInterface.php similarity index 83% rename from Classes/Service/CurrencyTranslationServiceInterface.php rename to Classes/Configuration/Loader/CurrencyTranslationLoaderInterface.php index f1ee3fe2..a236a7fb 100644 --- a/Classes/Service/CurrencyTranslationServiceInterface.php +++ b/Classes/Configuration/Loader/CurrencyTranslationLoaderInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -14,7 +14,7 @@ /** * @internal This class is marked internal and is not considered part of the public API. The interface will change in the next major version (v12.0.0). */ -interface CurrencyTranslationServiceInterface +interface CurrencyTranslationLoaderInterface { public function translatePrice(float $factor, ?float $price = null): ?float; } diff --git a/Classes/Service/PaymentMethodsServiceInterface.php b/Classes/Configuration/Loader/PaymentMethodsLoaderInterface.php similarity index 83% rename from Classes/Service/PaymentMethodsServiceInterface.php rename to Classes/Configuration/Loader/PaymentMethodsLoaderInterface.php index 64a59fea..cc892c44 100644 --- a/Classes/Service/PaymentMethodsServiceInterface.php +++ b/Classes/Configuration/Loader/PaymentMethodsLoaderInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -14,7 +14,7 @@ use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Cart\ServiceInterface; -interface PaymentMethodsServiceInterface +interface PaymentMethodsLoaderInterface { /** * @return ServiceInterface[] diff --git a/Classes/Service/ShippingMethodsServiceInterface.php b/Classes/Configuration/Loader/ShippingMethodsLoaderInterface.php similarity index 83% rename from Classes/Service/ShippingMethodsServiceInterface.php rename to Classes/Configuration/Loader/ShippingMethodsLoaderInterface.php index 882c0b09..f6cc33dd 100644 --- a/Classes/Service/ShippingMethodsServiceInterface.php +++ b/Classes/Configuration/Loader/ShippingMethodsLoaderInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -14,7 +14,7 @@ use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Cart\ServiceInterface; -interface ShippingMethodsServiceInterface +interface ShippingMethodsLoaderInterface { /** * @return ServiceInterface[] diff --git a/Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php b/Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php new file mode 100644 index 00000000..eb33e167 --- /dev/null +++ b/Classes/Configuration/Loader/SiteSets/AbstractConfigurationLoader.php @@ -0,0 +1,136 @@ +site = Typo3GlobalsUtility::getSiteFromTypo3Request(); + } + + /** + * @param array $services + * + * @return array + */ + public function getServices(?array $configurations, array $services, Cart $cart): array + { + if (is_array($configurations['options'] ?? null) === false) { + return $services; + } + + foreach ($configurations['options'] as $serviceKey => $serviceConfig) { + if (is_numeric($serviceKey) === false + || is_array($serviceConfig) === false + ) { + continue; + } + + $service = $this->serviceFactory->getService( + (int) $serviceKey, + $serviceConfig, + $configurations['preset'] == $serviceKey + ); + $service->setCart($cart); + + $services[$serviceKey] = $service; + } + + return $services; + } + + public function getConfigurationsForType(string $configurationType, ?string $country = null): ?array + { + $configurations = $this->site->getSettings()->getAll(); + if (is_array($configurations['extcode']) === false + || is_array($configurations['extcode'][$configurationType]) === false + ) { + return null; + } + + $configuration = $configurations['extcode'][$configurationType]; + + if (is_null($country)) { + $country = self::getCountryCodeFromPreset($configuration); + } + if (is_null($country)) { + return null; + } + + if (is_array($configuration['countries']) + && is_array($configuration['countries'][$country]) + ) { + return $configuration['countries'][$country]; + } + + if (!empty($configuration['zones']) + && is_array($configuration['zones']) + ) { + $zoneSetting = $this->getTypeZonesPluginSettings($configuration['zones'], $country); + if (!empty($zoneSetting)) { + return $zoneSetting; + } + } + + return $configuration; + } + + protected function getTypeZonesPluginSettings(array $zoneSettings, string $country): array + { + foreach ($zoneSettings as $zoneSetting) { + if (is_array($zoneSetting) === false + || is_string($zoneSetting['countries']) === false + ) { + continue; + } + $countriesInZones = GeneralUtility::trimExplode(',', $zoneSetting['countries'], true); + + if (in_array($country, $countriesInZones)) { + return $zoneSetting; + } + } + + return []; + } + + private static function getCountryCodeFromPreset(array $configuration): ?string + { + if (is_array($configuration['settings']) === false + || is_array($configuration['settings']['countries']) === false + || is_numeric($configuration['settings']['countries']['preset']) === false + ) { + return null; + } + + $preset = (int) $configuration['settings']['countries']['preset']; + + if (is_array($configuration['settings']['countries']['options']) === false + || is_array($configuration['settings']['countries']['options'][$preset]) === false + || is_string($configuration['settings']['countries']['options'][$preset]['code']) === false + ) { + return null; + } + + return $configuration['settings']['countries']['options'][$preset]['code']; + } +} diff --git a/Classes/Configuration/Loader/SiteSets/PaymentMethodsLoader.php b/Classes/Configuration/Loader/SiteSets/PaymentMethodsLoader.php new file mode 100644 index 00000000..99bb143f --- /dev/null +++ b/Classes/Configuration/Loader/SiteSets/PaymentMethodsLoader.php @@ -0,0 +1,27 @@ +getConfigurationsForType('cart-payments', $cart->getBillingCountry()); + + return $this->getServices($configurations, $services, $cart); + } +} diff --git a/Classes/Configuration/Loader/SiteSets/ShippingMethodsLoader.php b/Classes/Configuration/Loader/SiteSets/ShippingMethodsLoader.php new file mode 100644 index 00000000..79d758f3 --- /dev/null +++ b/Classes/Configuration/Loader/SiteSets/ShippingMethodsLoader.php @@ -0,0 +1,27 @@ +getConfigurationsForType('cart-shippings', $cart->getBillingCountry()); + + return $this->getServices($configurations, $services, $cart); + } +} diff --git a/Classes/Configuration/Loader/SiteSets/TaxClassLoader.php b/Classes/Configuration/Loader/SiteSets/TaxClassLoader.php new file mode 100644 index 00000000..d358437f --- /dev/null +++ b/Classes/Configuration/Loader/SiteSets/TaxClassLoader.php @@ -0,0 +1,72 @@ +site = Typo3GlobalsUtility::getSiteFromTypo3Request(); + } + + /** + * @return TaxClass[] + */ + public function getTaxClasses(?string $countryCode = null): array + { + $taxClasses = []; + + $configuration = $this->site->getSettings()->getAll(); + if (is_array($configuration['extcode']) === false + || is_array($configuration['extcode']['taxclasses']) === false + ) { + return []; + } + + $taxClassSettings = $configuration['extcode']['taxclasses']; + if ( + is_string($countryCode) + && array_key_exists($countryCode, $taxClassSettings) + && is_array($taxClassSettings[$countryCode]) + ) { + $taxClassSettings = $taxClassSettings[$countryCode]; + } elseif ( + array_key_exists('fallback', $taxClassSettings) + && is_array($taxClassSettings['fallback']) + ) { + $taxClassSettings = $taxClassSettings['fallback']; + } + + foreach ($taxClassSettings as $taxClassKey => $taxClassValue) { + if (is_array($taxClassValue) === false) { + continue; + } + $taxClass = $this->taxClassFactory->getTaxClass($taxClassKey, $taxClassValue); + + if ($taxClass instanceof TaxClassInterface) { + $taxClasses[$taxClassKey] = $taxClass; + } + } + + return $taxClasses; + } +} diff --git a/Classes/Service/SpecialOptionsServiceInterface.php b/Classes/Configuration/Loader/SpecialOptionsLoaderInterface.php similarity index 79% rename from Classes/Service/SpecialOptionsServiceInterface.php rename to Classes/Configuration/Loader/SpecialOptionsLoaderInterface.php index 7adb4e9a..fd5cf0dd 100644 --- a/Classes/Service/SpecialOptionsServiceInterface.php +++ b/Classes/Configuration/Loader/SpecialOptionsLoaderInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -13,7 +13,7 @@ use Extcode\Cart\Domain\Model\Cart\Cart; -interface SpecialOptionsServiceInterface +interface SpecialOptionsLoaderInterface { public function getSpecialOptions(Cart $cart): array; } diff --git a/Classes/Service/TaxClassServiceInterface.php b/Classes/Configuration/Loader/TaxClassLoaderInterface.php similarity index 82% rename from Classes/Service/TaxClassServiceInterface.php rename to Classes/Configuration/Loader/TaxClassLoaderInterface.php index beb280c6..cd1024e4 100644 --- a/Classes/Service/TaxClassServiceInterface.php +++ b/Classes/Configuration/Loader/TaxClassLoaderInterface.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader; /* * This file is part of the package extcode/cart. @@ -13,7 +13,7 @@ use Extcode\Cart\Domain\Model\Cart\TaxClass; -interface TaxClassServiceInterface +interface TaxClassLoaderInterface { /** * @return TaxClass[] diff --git a/Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php b/Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php new file mode 100644 index 00000000..7c32ac95 --- /dev/null +++ b/Classes/Configuration/Loader/TypoScript/AbstractConfigurationLoader.php @@ -0,0 +1,122 @@ +configurations = $this->configurationManager->getConfiguration( + ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, + 'Cart' + ); + } + + public function getServices(?array $configurations, array $services, Cart $cart): array + { + if (empty($configurations['options'])) { + return $services; + } + + foreach ($configurations['options'] as $serviceKey => $serviceConfig) { + $service = $this->serviceFactory->getService($serviceKey, $serviceConfig, $configurations['preset'] == $serviceKey); + $service->setCart($cart); + + $services[$serviceKey] = $service; + } + + return $services; + } + + public function getConfigurationsForType(string $configurationType, ?string $country = null): ?array + { + if (is_array($this->configurations[$configurationType]) === false + ) { + return null; + } + + $configuration = $this->configurations[$configurationType]; + + if (is_null($country)) { + $country = self::getCountryCodeFromPreset($configuration); + } + if (is_null($country)) { + return null; + } + + if (!empty($configuration['countries']) + && is_array($configuration['countries']) + && is_array($configuration['countries'][$country]) + ) { + return $configuration['countries'][$country]; + } + + if (!empty($configuration['zones']) + && is_array($configuration['zones']) + ) { + $zoneSetting = $this->getTypeZonesPluginSettings($configuration['zones'], $country); + if (!empty($zoneSetting)) { + return $zoneSetting; + } + } + + return $configuration; + } + + protected function getTypeZonesPluginSettings(array $zoneSettings, string $country): array + { + foreach ($zoneSettings as $zoneSetting) { + if (is_array($zoneSetting) === false + || is_string($zoneSetting['countries']) === false + ) { + continue; + } + $countriesInZones = GeneralUtility::trimExplode(',', $zoneSetting['countries'], true); + + if (in_array($country, $countriesInZones)) { + return $zoneSetting; + } + } + + return []; + } + + private static function getCountryCodeFromPreset(array $configuration): ?string + { + if (is_array($configuration['settings']) === false + || is_array($configuration['settings']['countries']) === false + || is_numeric($configuration['settings']['countries']['preset']) === false + ) { + return null; + } + + $preset = (int) $configuration['settings']['countries']['preset']; + + if (is_array($configuration['settings']['countries']['options']) === false + || is_array($configuration['settings']['countries']['options'][$preset]) === false + || is_string($configuration['settings']['countries']['options'][$preset]['code']) === false + ) { + return null; + } + + return $configuration['settings']['countries']['options'][$preset]['code']; + } +} diff --git a/Classes/Service/PaymentMethodsFromTypoScriptService.php b/Classes/Configuration/Loader/TypoScript/PaymentMethodsLoader.php similarity index 68% rename from Classes/Service/PaymentMethodsFromTypoScriptService.php rename to Classes/Configuration/Loader/TypoScript/PaymentMethodsLoader.php index c083fa24..b926f801 100644 --- a/Classes/Service/PaymentMethodsFromTypoScriptService.php +++ b/Classes/Configuration/Loader/TypoScript/PaymentMethodsLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader\TypoScript; /* * This file is part of the package extcode/cart. @@ -11,9 +11,10 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface; use Extcode\Cart\Domain\Model\Cart\Cart; -class PaymentMethodsFromTypoScriptService extends AbstractConfigurationFromTypoScriptService implements PaymentMethodsServiceInterface +final readonly class PaymentMethodsLoader extends AbstractConfigurationLoader implements PaymentMethodsLoaderInterface { public function getPaymentMethods(Cart $cart): array { diff --git a/Classes/Service/ShippingMethodsFromTypoScriptService.php b/Classes/Configuration/Loader/TypoScript/ShippingMethodsLoader.php similarity index 68% rename from Classes/Service/ShippingMethodsFromTypoScriptService.php rename to Classes/Configuration/Loader/TypoScript/ShippingMethodsLoader.php index 31b579e7..26525abd 100644 --- a/Classes/Service/ShippingMethodsFromTypoScriptService.php +++ b/Classes/Configuration/Loader/TypoScript/ShippingMethodsLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader\TypoScript; /* * This file is part of the package extcode/cart. @@ -11,9 +11,10 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\ShippingMethodsLoaderInterface; use Extcode\Cart\Domain\Model\Cart\Cart; -class ShippingMethodsFromTypoScriptService extends AbstractConfigurationFromTypoScriptService implements ShippingMethodsServiceInterface +final readonly class ShippingMethodsLoader extends AbstractConfigurationLoader implements ShippingMethodsLoaderInterface { public function getShippingMethods(Cart $cart): array { diff --git a/Classes/Service/SpecialOptionsFromTypoScriptService.php b/Classes/Configuration/Loader/TypoScript/SpecialOptionsLoader.php similarity index 68% rename from Classes/Service/SpecialOptionsFromTypoScriptService.php rename to Classes/Configuration/Loader/TypoScript/SpecialOptionsLoader.php index 53256181..e255e182 100644 --- a/Classes/Service/SpecialOptionsFromTypoScriptService.php +++ b/Classes/Configuration/Loader/TypoScript/SpecialOptionsLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader\TypoScript; /* * This file is part of the package extcode/cart. @@ -11,9 +11,10 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\SpecialOptionsLoaderInterface; use Extcode\Cart\Domain\Model\Cart\Cart; -class SpecialOptionsFromTypoScriptService extends AbstractConfigurationFromTypoScriptService implements SpecialOptionsServiceInterface +final readonly class SpecialOptionsLoader extends AbstractConfigurationLoader implements SpecialOptionsLoaderInterface { public function getSpecialOptions(Cart $cart): array { diff --git a/Classes/Service/TaxClassService.php b/Classes/Configuration/Loader/TypoScript/TaxClassLoader.php similarity index 76% rename from Classes/Service/TaxClassService.php rename to Classes/Configuration/Loader/TypoScript/TaxClassLoader.php index a1615a45..6fc34111 100644 --- a/Classes/Service/TaxClassService.php +++ b/Classes/Configuration/Loader/TypoScript/TaxClassLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Extcode\Cart\Service; +namespace Extcode\Cart\Configuration\Loader\TypoScript; /* * This file is part of the package extcode/cart. @@ -11,18 +11,19 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\TaxClassLoaderInterface; use Extcode\Cart\Domain\Model\Cart\TaxClass; use Extcode\Cart\Domain\Model\Cart\TaxClassFactoryInterface; use Extcode\Cart\Domain\Model\Cart\TaxClassInterface; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; -final class TaxClassService implements TaxClassServiceInterface +final readonly class TaxClassLoader implements TaxClassLoaderInterface { private array $settings; public function __construct( - private readonly ConfigurationManagerInterface $configurationManager, - private readonly TaxClassFactoryInterface $taxClassFactory + private ConfigurationManagerInterface $configurationManager, + private TaxClassFactoryInterface $taxClassFactory ) { $this->settings = $this->configurationManager->getConfiguration( ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, @@ -39,9 +40,9 @@ public function getTaxClasses(?string $countryCode = null): array $taxClassSettings = $this->settings['taxClasses']; if ( - is_null($countryCode) === false - && array_key_exists($countryCode, $taxClassSettings) - && is_array($taxClassSettings[$countryCode]) + is_string($countryCode) + && array_key_exists($countryCode, $taxClassSettings) + && is_array($taxClassSettings[$countryCode]) ) { $taxClassSettings = $taxClassSettings[$countryCode]; } elseif ( diff --git a/Classes/Controller/Backend/ActionController.php b/Classes/Controller/Backend/ActionController.php index 75ab8d30..5005078c 100644 --- a/Classes/Controller/Backend/ActionController.php +++ b/Classes/Controller/Backend/ActionController.php @@ -12,13 +12,18 @@ */ use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManager; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; class ActionController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController { protected array $pluginSettings = []; + public function __construct( + protected ConfigurationManagerInterface $configurationManager + ) { + } + protected function initializeAction(): void { $this->pluginSettings @@ -26,16 +31,14 @@ protected function initializeAction(): void ConfigurationManager::CONFIGURATION_TYPE_FRAMEWORK ); - $pageId = (int)($this->request->getQueryParams()['id'] ?? 1); + $pageId = (int) ($this->request->getQueryParams()['id'] ?? 1); BackendUtility::readPageAccess( $pageId, $GLOBALS['BE_USER']->getPagePermsClause(1) ); - $configurationManager = GeneralUtility::makeInstance( - ConfigurationManager::class - ); + $configurationManager = $this->configurationManager; $frameworkConf = $configurationManager->getConfiguration( diff --git a/Classes/Controller/Backend/Order/DocumentController.php b/Classes/Controller/Backend/Order/DocumentController.php index 3df52aa9..bbe55be1 100644 --- a/Classes/Controller/Backend/Order/DocumentController.php +++ b/Classes/Controller/Backend/Order/DocumentController.php @@ -18,7 +18,6 @@ use Extcode\Cart\Event\Order\NumberGeneratorEvent; use Extcode\CartPdf\Service\PdfService; use Psr\Http\Message\ResponseInterface; -use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; @@ -29,7 +28,8 @@ class DocumentController extends ActionController public function __construct( protected readonly PersistenceManager $persistenceManager, protected readonly ItemRepository $itemRepository - ) {} + ) { + } public function createAction(Item $orderItem, string $pdfType): ResponseInterface { @@ -80,12 +80,13 @@ public function downloadAction(Item $orderItem, string $pdfType): ResponseInterf ->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->withHeader('Content-Description', 'File Transfer') ->withHeader('Content-Disposition', 'attachment; filename="' . $originalPdf->getName() . '"') - ->withHeader('Content-Length', (string)$originalPdf->getSize()) + ->withHeader('Content-Length', (string) $originalPdf->getSize()) ->withHeader('Content-Transfer-Encoding', 'binary') ->withHeader('Content-Type', 'application/pdf') ->withHeader('Expires', '0') ->withHeader('Pragma', 'public') - ->withBody($this->streamFactory->createStream($originalPdf->getContents())); + ->withBody($this->streamFactory->createStream($originalPdf->getContents())) + ; } return $this->htmlResponse(); diff --git a/Classes/Controller/Backend/Order/OrderController.php b/Classes/Controller/Backend/Order/OrderController.php index 15cefc8b..2985cb6a 100644 --- a/Classes/Controller/Backend/Order/OrderController.php +++ b/Classes/Controller/Backend/Order/OrderController.php @@ -10,7 +10,6 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ - use Extcode\Cart\Controller\Backend\ActionController; use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Order\Item; @@ -20,6 +19,7 @@ use Extcode\Cart\Event\Template\Components\ModifyModuleTemplateEvent; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Backend\Template\Components\ButtonBar; +use TYPO3\CMS\Backend\Template\Components\ComponentFactory; use TYPO3\CMS\Backend\Template\ModuleTemplate; use TYPO3\CMS\Backend\Template\ModuleTemplateFactory; use TYPO3\CMS\Core\Imaging\IconFactory; @@ -33,30 +33,24 @@ use TYPO3\CMS\Extbase\Pagination\QueryResultPaginator; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; +use stdClass; class OrderController extends ActionController { private const LANG_FILE = 'LLL:EXT:cart/Resources/Private/Language/locallang.xlf:'; - private ModuleTemplate $moduleTemplate; - protected array $searchArguments = []; + private ModuleTemplate $moduleTemplate; + public function __construct( protected readonly ModuleTemplateFactory $moduleTemplateFactory, protected readonly IconFactory $iconFactory, protected readonly PersistenceManager $persistenceManager, protected readonly ItemRepository $itemRepository, - private readonly PageRenderer $pageRenderer - ) {} - - protected function initializeAction(): void - { - parent::initializeAction(); - - if ($this->request->hasArgument('search')) { - $this->searchArguments = $this->request->getArgument('search'); - } + private readonly PageRenderer $pageRenderer, + private readonly ComponentFactory $componentFactory + ) { } public function listAction(int $currentPage = 1): ResponseInterface @@ -69,7 +63,7 @@ public function listAction(int $currentPage = 1): ResponseInterface $this->moduleTemplate->assign('settings', $this->settings); $this->moduleTemplate->assign('searchArguments', $this->searchArguments); - $itemsPerPage = (isset($this->settings['itemsPerPage']) && is_numeric($this->settings['itemsPerPage'])) ? (int)$this->settings['itemsPerPage'] : 20; + $itemsPerPage = (isset($this->settings['itemsPerPage']) && is_numeric($this->settings['itemsPerPage'])) ? (int) $this->settings['itemsPerPage'] : 20; $orderItems = $this->itemRepository->findAll($this->searchArguments); $arrayPaginator = new QueryResultPaginator( @@ -155,7 +149,8 @@ public function exportAction(): ResponseInterface ->withAddedHeader('Content-Type', 'text/' . $format) ->withAddedHeader('Content-Description', 'File transfer') ->withAddedHeader('Content-Disposition', 'attachment; filename="' . $filename . '"') - ->withBody($this->streamFactory->createStream($this->view->render())); + ->withBody($this->streamFactory->createStream($this->view->render())) + ; } public function generateNumberAction(Item $orderItem, string $numberType): ResponseInterface @@ -193,7 +188,7 @@ public function getPaymentStatus(): array { $paymentStatusArray = []; - $paymentStatus = new \stdClass(); + $paymentStatus = new stdClass(); $paymentStatus->key = ''; $paymentStatus->value = LocalizationUtility::translate( 'tx_cart_domain_model_order_payment.status.all', @@ -203,7 +198,7 @@ public function getPaymentStatus(): array $entries = ['open', 'pending', 'paid', 'canceled']; foreach ($entries as $entry) { - $paymentStatus = new \stdClass(); + $paymentStatus = new stdClass(); $paymentStatus->key = $entry; $paymentStatus->value = LocalizationUtility::translate( 'tx_cart_domain_model_order_payment.status.' . $entry, @@ -211,6 +206,7 @@ public function getPaymentStatus(): array ); $paymentStatusArray[] = $paymentStatus; } + return $paymentStatusArray; } @@ -218,7 +214,7 @@ public function getShippingStatus(): array { $shippingStatusArray = []; - $shippingStatus = new \stdClass(); + $shippingStatus = new stdClass(); $shippingStatus->key = ''; $shippingStatus->value = LocalizationUtility::translate( 'tx_cart_domain_model_order_shipping.status.all', @@ -228,7 +224,7 @@ public function getShippingStatus(): array $entries = ['open', 'on_hold', 'in_process', 'shipped']; foreach ($entries as $entry) { - $shippingStatus = new \stdClass(); + $shippingStatus = new stdClass(); $shippingStatus->key = $entry; $shippingStatus->value = LocalizationUtility::translate( 'tx_cart_domain_model_order_shipping.status.' . $entry, @@ -236,9 +232,19 @@ public function getShippingStatus(): array ); $shippingStatusArray[] = $shippingStatus; } + return $shippingStatusArray; } + protected function initializeAction(): void + { + parent::initializeAction(); + + if ($this->request->hasArgument('search')) { + $this->searchArguments = $this->request->getArgument('search'); + } + } + protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; @@ -275,13 +281,14 @@ private function setDocHeader(array $buttons): void foreach ($buttons as $button) { $title = $this->getLanguageService()->sL(self::LANG_FILE . $button['title']); - $icon = $this->iconFactory->getIcon($button['icon'], IconSize::SMALL->value); + $icon = $this->iconFactory->getIcon($button['icon'], IconSize::SMALL); - $viewButton = $buttonBar->makeLinkButton() + $viewButton = $this->componentFactory->createLinkButton() ->setHref($button['link']) ->setTitle($title) ->setShowLabelText($button['showLabel']) - ->setIcon($icon); + ->setIcon($icon) + ; $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, $button['group']); } } diff --git a/Classes/Controller/Backend/Order/PaymentController.php b/Classes/Controller/Backend/Order/PaymentController.php index 76dc559c..15a64d7f 100644 --- a/Classes/Controller/Backend/Order/PaymentController.php +++ b/Classes/Controller/Backend/Order/PaymentController.php @@ -12,21 +12,36 @@ */ use Extcode\Cart\Controller\Backend\ActionController; +use Extcode\Cart\Domain\Log\LogServiceInterface; +use Extcode\Cart\Domain\Log\Model\Log; use Extcode\Cart\Domain\Model\Order\Payment; use Extcode\Cart\Domain\Repository\Order\PaymentRepository; use Extcode\Cart\Event\Order\UpdateServiceEvent; +use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; class PaymentController extends ActionController { public function __construct( - protected PaymentRepository $paymentRepository - ) {} + private readonly PaymentRepository $paymentRepository, + private readonly LogServiceInterface $logService, + ) { + } public function updateAction(Payment $payment): ResponseInterface { $this->paymentRepository->update($payment); + $this->logService->write( + Log::info( + self::getOrderItemUid($payment), + 'updatePayment', + 'Payment was set to ' . $payment->getStatus() . '.', + [ + 'time' => time(), + ] + ) + ); $event = new UpdateServiceEvent($payment); $this->eventDispatcher->dispatch($event); @@ -40,4 +55,15 @@ public function updateAction(Payment $payment): ResponseInterface return $this->redirect('show', 'Backend\Order\Order', null, ['orderItem' => $payment->getItem()]); } + + private static function getOrderItemUid(Payment $payment): int + { + $orderItemUid = $payment->getItem()?->getUid(); + + if (is_null($orderItemUid)) { + throw new InvalidArgumentException('Method should only called for persisted orders.', 1774715307); + } + + return $orderItemUid; + } } diff --git a/Classes/Controller/Backend/Order/ShippingController.php b/Classes/Controller/Backend/Order/ShippingController.php index f2cfed3e..c39a8512 100644 --- a/Classes/Controller/Backend/Order/ShippingController.php +++ b/Classes/Controller/Backend/Order/ShippingController.php @@ -12,21 +12,36 @@ */ use Extcode\Cart\Controller\Backend\ActionController; +use Extcode\Cart\Domain\Log\LogServiceInterface; +use Extcode\Cart\Domain\Log\Model\Log; use Extcode\Cart\Domain\Model\Order\Shipping; use Extcode\Cart\Domain\Repository\Order\ShippingRepository; use Extcode\Cart\Event\Order\UpdateServiceEvent; +use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; class ShippingController extends ActionController { public function __construct( - protected ShippingRepository $shippingRepository - ) {} + private readonly ShippingRepository $shippingRepository, + private readonly LogServiceInterface $logService, + ) { + } public function updateAction(Shipping $shipping): ResponseInterface { $this->shippingRepository->update($shipping); + $this->logService->write( + Log::info( + self::getOrderItemUid($shipping), + 'updateShipping', + 'Shipping was set to ' . $shipping->getStatus() . '.', + [ + 'time' => time(), + ] + ) + ); $event = new UpdateServiceEvent($shipping); $this->eventDispatcher->dispatch($event); @@ -40,4 +55,15 @@ public function updateAction(Shipping $shipping): ResponseInterface return $this->redirect('show', 'Backend\Order\Order', null, ['orderItem' => $shipping->getItem()]); } + + private static function getOrderItemUid(Shipping $shipping): int + { + $orderItemUid = $shipping->getItem()?->getUid(); + + if (is_null($orderItemUid)) { + throw new InvalidArgumentException('Method should only called for persisted orders.', 1774715307); + } + + return $orderItemUid; + } } diff --git a/Classes/Controller/Cart/ActionController.php b/Classes/Controller/Cart/ActionController.php index fdf54a7a..a0d7a753 100644 --- a/Classes/Controller/Cart/ActionController.php +++ b/Classes/Controller/Cart/ActionController.php @@ -11,11 +11,11 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface; +use Extcode\Cart\Configuration\Loader\ShippingMethodsLoaderInterface; +use Extcode\Cart\Configuration\Loader\SpecialOptionsLoaderInterface; use Extcode\Cart\Domain\Model\Cart\Cart; -use Extcode\Cart\Service\PaymentMethodsServiceInterface; use Extcode\Cart\Service\SessionHandler; -use Extcode\Cart\Service\ShippingMethodsServiceInterface; -use Extcode\Cart\Service\SpecialOptionsServiceInterface; use Extcode\Cart\Utility\CartUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManager; @@ -25,16 +25,20 @@ abstract class ActionController extends \Extcode\Cart\Controller\ActionControlle protected CartUtility $cartUtility; - protected PaymentMethodsServiceInterface $paymentMethodsService; - protected ShippingMethodsServiceInterface $shippingMethodsService; - protected SpecialOptionsServiceInterface $specialOptionsService; + protected PaymentMethodsLoaderInterface $paymentMethodsLoader; + + protected ShippingMethodsLoaderInterface $shippingMethodsLoader; + + protected SpecialOptionsLoaderInterface $specialOptionsLoader; protected array $configurations; protected Cart $cart; protected array $payments = []; + protected array $shippings = []; + protected array $specials = []; public function injectSessionHandler(SessionHandler $sessionHandler): void @@ -47,19 +51,19 @@ public function injectCartUtility(CartUtility $cartUtility): void $this->cartUtility = $cartUtility; } - public function injectPaymentMethodsService(PaymentMethodsServiceInterface $paymentMethodsService): void + public function injectPaymentMethodsService(PaymentMethodsLoaderInterface $paymentMethodsLoader): void { - $this->paymentMethodsService = $paymentMethodsService; + $this->paymentMethodsLoader = $paymentMethodsLoader; } - public function injectShippingMethodsService(ShippingMethodsServiceInterface $shippingMethodsService): void + public function injectShippingMethodsService(ShippingMethodsLoaderInterface $shippingMethodsLoader): void { - $this->shippingMethodsService = $shippingMethodsService; + $this->shippingMethodsLoader = $shippingMethodsLoader; } - public function injectSpecialOptionsService(SpecialOptionsServiceInterface $specialOptionsService): void + public function injectSpecialOptionsService(SpecialOptionsLoaderInterface $specialOptionsLoader): void { - $this->specialOptionsService = $specialOptionsService; + $this->specialOptionsLoader = $specialOptionsLoader; } public function initializeAction(): void @@ -68,14 +72,7 @@ public function initializeAction(): void ConfigurationManager::CONFIGURATION_TYPE_FRAMEWORK ); - $this->settings['addToCartByAjax'] = isset($this->settings['addToCartByAjax']) ? (int)$this->settings['addToCartByAjax'] : 0; - } - - protected function parseServices(): void - { - $this->payments = $this->paymentMethodsService->getPaymentMethods($this->cart); - $this->shippings = $this->shippingMethodsService->getShippingMethods($this->cart); - $this->specials = $this->specialOptionsService->getSpecialOptions($this->cart); + $this->settings['addToCartByAjax'] = isset($this->settings['addToCartByAjax']) ? (int) $this->settings['addToCartByAjax'] : 0; } public function parseServicesAndAssignToView(): void @@ -91,6 +88,13 @@ public function parseServicesAndAssignToView(): void ); } + protected function parseServices(): void + { + $this->payments = $this->paymentMethodsLoader->getPaymentMethods($this->cart); + $this->shippings = $this->shippingMethodsLoader->getShippingMethods($this->cart); + $this->specials = $this->specialOptionsLoader->getSpecialOptions($this->cart); + } + protected function restoreSession(): void { $cart = $this->sessionHandler->restoreCart($this->settings['cart']['pid']); diff --git a/Classes/Controller/Cart/CartController.php b/Classes/Controller/Cart/CartController.php index de0e7a34..385f8bb8 100755 --- a/Classes/Controller/Cart/CartController.php +++ b/Classes/Controller/Cart/CartController.php @@ -11,11 +11,13 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Extcode\Cart\Domain\Model\Order\BillingAddress; use Extcode\Cart\Domain\Model\Order\Item; use Extcode\Cart\Domain\Model\Order\ShippingAddress; use Extcode\Cart\Event\Cart\BeforeShowCartEvent; use Extcode\Cart\Event\CheckProductAvailabilityEvent; +use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters; @@ -24,8 +26,8 @@ class CartController extends ActionController { public function showAction( ?Item $orderItem = null, - ?BillingAddress $billingAddress = null, - ?ShippingAddress $shippingAddress = null + ?AddressInterface $billingAddress = null, + ?AddressInterface $shippingAddress = null ): ResponseInterface { $this->restoreSession(); @@ -60,7 +62,7 @@ public function showAction( $originalRequestOrderItem = $extbaseAttribute->getOriginalRequest()->getArgument('orderItem'); if (isset($originalRequestOrderItem['shippingSameAsBilling'])) { - $this->cart->setShippingSameAsBilling((bool)$originalRequestOrderItem['shippingSameAsBilling']); + $this->cart->setShippingSameAsBilling((bool) $originalRequestOrderItem['shippingSameAsBilling']); $this->sessionHandler->writeCart($this->settings['cart']['pid'], $this->cart); } } @@ -69,7 +71,12 @@ public function showAction( $this->sessionHandler->writeCart($this->settings['cart']['pid'], $this->cart); } - $beforeShowCartEvent = new BeforeShowCartEvent($this->cart, $orderItem, $billingAddress, $shippingAddress); + $beforeShowCartEvent = new BeforeShowCartEvent( + $this->cart, + $orderItem, + $billingAddress, + $shippingAddress + ); $this->eventDispatcher->dispatch($beforeShowCartEvent); $orderItem = $beforeShowCartEvent->getOrderItem(); @@ -91,7 +98,7 @@ public function showAction( $currentStep = null; if ($this->request->hasArgument('step')) { - $currentStep = (int)$this->request->getArgument('step'); + $currentStep = (int) $this->request->getArgument('step'); } $currentStepHasError = false; @@ -117,7 +124,6 @@ public function showAction( $this->dispatchModifyViewEvent(); return $this->htmlResponse($this->view->render($template)); - } public function clearAction(): ResponseInterface @@ -152,7 +158,7 @@ public function updateAction(): ResponseInterface if (is_array($quantity)) { $cartProduct->changeQuantities($quantity); } else { - $cartProduct->changeQuantity((int)$quantity); + $cartProduct->changeQuantity((int) $quantity); } } else { foreach ($checkAvailabilityEvent->getMessages() as $message) { @@ -177,7 +183,7 @@ public function updateAction(): ResponseInterface private function getTemplateForShowAction(): string { - $steps = (int)($this->settings['cart']['steps'] ?? 1); + $steps = (int) ($this->settings['cart']['steps'] ?? 1); if ($steps === 1) { return 'Show'; @@ -185,11 +191,11 @@ private function getTemplateForShowAction(): string $currentStep = 1; if ($this->request->hasArgument('step')) { - $currentStep = (int)$this->request->getArgument('step') ?: 1; + $currentStep = (int) $this->request->getArgument('step') ?: 1; } if ($currentStep > $steps) { - throw new \InvalidArgumentException(); + throw new InvalidArgumentException(); } if ($currentStep < $steps) { diff --git a/Classes/Controller/Cart/CountryController.php b/Classes/Controller/Cart/CountryController.php index 6c03cb26..fc29e21e 100644 --- a/Classes/Controller/Cart/CountryController.php +++ b/Classes/Controller/Cart/CountryController.php @@ -4,7 +4,7 @@ namespace Extcode\Cart\Controller\Cart; -use Extcode\Cart\Service\TaxClassServiceInterface; +use Extcode\Cart\Configuration\Loader\TaxClassLoaderInterface; use Psr\Http\Message\ResponseInterface; /* @@ -16,18 +16,23 @@ class CountryController extends ActionController { public function __construct( - protected TaxClassServiceInterface $taxClassService - ) {} + protected TaxClassLoaderInterface $taxClassLoader + ) { + } public function updateAction(): ResponseInterface { - //ToDo check country is allowed by TypoScript + // ToDo check country is allowed by TypoScript - $this->cartUtility->updateCountry($this->settings['cart'], $this->configurations, $this->request); + $this->cartUtility->updateCountry( + $this->settings['cart'], + $this->configurations, + $this->request + ); $this->restoreSession(); - $taxClasses = $this->taxClassService->getTaxClasses($this->cart->getBillingCountry()); + $taxClasses = $this->taxClassLoader->getTaxClasses($this->cart->getBillingCountry()); $this->cart->setTaxClasses($taxClasses); $this->cart->reCalc(); diff --git a/Classes/Controller/Cart/CouponController.php b/Classes/Controller/Cart/CouponController.php index b17c2283..db77314a 100644 --- a/Classes/Controller/Cart/CouponController.php +++ b/Classes/Controller/Cart/CouponController.php @@ -23,7 +23,8 @@ class CouponController extends ActionController { public function __construct( protected CouponRepository $couponRepository - ) {} + ) { + } public function addAction(): ResponseInterface { diff --git a/Classes/Controller/Cart/CurrencyController.php b/Classes/Controller/Cart/CurrencyController.php index a0868958..f0c92b2b 100644 --- a/Classes/Controller/Cart/CurrencyController.php +++ b/Classes/Controller/Cart/CurrencyController.php @@ -16,15 +16,21 @@ class CurrencyController extends ActionController { public const AJAX_CART_TYPE_NUM = '2278001'; + public const AJAX_CURRENCY_TYPE_NUM = '2278003'; public function __construct( protected CurrencyUtility $currencyUtility - ) {} + ) { + } public function updateAction(): ResponseInterface { - $this->currencyUtility->updateCurrency($this->settings['cart'], $this->configurations, $this->request); + $this->currencyUtility->updateCurrency( + $this->settings['cart'], + $this->configurations, + $this->request + ); $this->restoreSession(); diff --git a/Classes/Controller/Cart/OrderController.php b/Classes/Controller/Cart/OrderController.php index fb01571d..77ba5b2a 100644 --- a/Classes/Controller/Cart/OrderController.php +++ b/Classes/Controller/Cart/OrderController.php @@ -10,6 +10,7 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ + use Extcode\Cart\Domain\Model\Order\BillingAddress; use Extcode\Cart\Domain\Model\Order\Item; use Extcode\Cart\Domain\Model\Order\ShippingAddress; @@ -21,26 +22,15 @@ use Extcode\Cart\Event\Order\StockEvent; use Extcode\Cart\Event\ProcessOrderCheckStockEvent; use Extcode\Cart\Validation\Validator\EmptyValidator; -use Psr\EventDispatcher\StoppableEventInterface; use Psr\Http\Message\ResponseInterface; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Annotation\IgnoreValidation; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; use TYPO3\CMS\Extbase\Validation\Validator\AbstractGenericObjectValidator; use TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator; use TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator; -use TYPO3\CMS\Extbase\Validation\ValidatorResolver; class OrderController extends ActionController { - protected function getErrorFlashMessage(): bool|string - { - return LocalizationUtility::translate( - 'tx_cart.error.validation', - 'Cart' - ) ?? false; - } - public function initializeCreateAction(): void { foreach (['orderItem', 'billingAddress', 'shippingAddress'] as $argumentName) { @@ -51,7 +41,8 @@ public function initializeCreateAction(): void $this->arguments->getArgument($argumentName) ->getPropertyMappingConfiguration() - ->setTargetTypeForSubProperty('additional', 'array'); + ->setTargetTypeForSubProperty('additional', 'array') + ; } } @@ -63,21 +54,27 @@ public function createAction( ): ResponseInterface { $this->restoreSession(); - if (!is_null($billingAddress)) { + if ($billingAddress instanceof BillingAddress) { $this->sessionHandler->writeAddress('billing_address_' . $this->settings['cart']['pid'], $billingAddress); } else { $billingAddress = $this->sessionHandler->restoreAddress('billing_address_' . $this->settings['cart']['pid']); } - if (!is_null($shippingAddress)) { + if ($shippingAddress instanceof ShippingAddress) { $this->sessionHandler->writeAddress('shipping_address_' . $this->settings['cart']['pid'], $shippingAddress); } else { $shippingAddress = $this->sessionHandler->restoreAddress('shipping_address_' . $this->settings['cart']['pid']); - if (!$shippingAddress) { - $shippingAddress = new ShippingAddress(); - } } - if (is_null($orderItem) || is_null($billingAddress) || $this->cart->getCount() === 0) { + if (($orderItem instanceof Item) === false + || ($billingAddress instanceof BillingAddress) === false + || $this->cart->getCount() === 0 + ) { + return $this->redirect('show', 'Cart\Cart'); + } + + if ($orderItem->isShippingSameAsBilling() === false + && ($shippingAddress instanceof ShippingAddress) === false + ) { return $this->redirect('show', 'Cart\Cart'); } @@ -95,10 +92,10 @@ public function createAction( return $this->redirect('show', 'Cart\Cart'); } - $orderItem->setCartPid((int)$this->settings['cart']['pid']); + $orderItem->setCartPid($this->getCartPidFromSettings()); // add billing and shipping address to order - $storagePid = (int)$this->settings['order']['pid']; + $storagePid = $this->getOrderPidFromSettings(); $billingAddress->setPid($storagePid); $orderItem->setBillingAddress($billingAddress); @@ -106,6 +103,9 @@ public function createAction( $shippingAddress = null; $orderItem->removeShippingAddress(); } else { + if (($shippingAddress instanceof ShippingAddress) === false) { + $shippingAddress = new ShippingAddress(); + } $shippingAddress->setPid($storagePid); $orderItem->setShippingAddress($shippingAddress); } @@ -122,10 +122,14 @@ public function createAction( $this->view->assign('orderItem', $orderItem); $paymentId = $this->cart->getPayment()->getId(); - $paymentSettings = $this->paymentMethodsService->getConfigurationsForType('payments', $this->cart->getBillingCountry()); + $paymentSettings = $this->paymentMethodsLoader->getPaymentMethods($this->cart); if (isset($paymentSettings['options'][$paymentId]['redirects']['success']['url'])) { - $this->redirectToUri($paymentSettings['options'][$paymentId]['redirects']['success']['url'], 0, 200); + return $this->redirectToUri( + $paymentSettings['options'][$paymentId]['redirects']['success']['url'], + null, + 200 + ); } $this->dispatchModifyViewEvent(); @@ -162,6 +166,14 @@ public function setDynamicValidationsForArgument(string $argumentName): void } } + protected function getErrorFlashMessage(): bool|string + { + return LocalizationUtility::translate( + 'tx_cart.error.validation', + 'Cart' + ) ?? false; + } + /** * Sets the dynamic validation rules. */ @@ -171,9 +183,7 @@ protected function setDynamicValidation( array $validatorConf ): void { // build custom validation chain - $validatorResolver = GeneralUtility::makeInstance( - ValidatorResolver::class - ); + $validatorResolver = $this->validatorResolver; if ($validatorConf['validator'] === 'Empty') { $validatorConf['validator'] = EmptyValidator::class; @@ -209,39 +219,55 @@ protected function dispatchOrderCreateEvents(Item $orderItem): bool { $createEvent = new CreateEvent($this->cart, $orderItem, $this->configurations); $this->eventDispatcher->dispatch($createEvent); - if ($createEvent instanceof StoppableEventInterface && $createEvent->isPropagationStopped()) { + if ($createEvent->isPropagationStopped()) { return true; } $onlyGenerateNumberOfType = []; if (!empty($this->configurations['autoGenerateNumbers'])) { - $onlyGenerateNumberOfType = array_map('trim', explode(',', (string)$this->configurations['autoGenerateNumbers'])); + $onlyGenerateNumberOfType = array_map(trim(...), explode(',', (string) $this->configurations['autoGenerateNumbers'])); } $generateNumbersEvent = new NumberGeneratorEvent($this->cart, $orderItem, $this->configurations); $generateNumbersEvent->setOnlyGenerateNumberOfType($onlyGenerateNumberOfType); $this->eventDispatcher->dispatch($generateNumbersEvent); - if ($generateNumbersEvent instanceof StoppableEventInterface && $generateNumbersEvent->isPropagationStopped()) { + if ($generateNumbersEvent->isPropagationStopped()) { return true; } $stockEvent = new StockEvent($this->cart, $orderItem, $this->configurations); $this->eventDispatcher->dispatch($stockEvent); - if ($stockEvent instanceof StoppableEventInterface && $stockEvent->isPropagationStopped()) { + if ($stockEvent->isPropagationStopped()) { return true; } $paymentEvent = new PaymentEvent($this->cart, $orderItem, $this->configurations); $this->eventDispatcher->dispatch($paymentEvent); - if ($paymentEvent instanceof StoppableEventInterface && $paymentEvent->isPropagationStopped()) { + if ($paymentEvent->isPropagationStopped()) { return true; } $finishEvent = new FinishEvent($this->cart, $orderItem, $this->configurations); $this->eventDispatcher->dispatch($finishEvent); - if ($finishEvent instanceof StoppableEventInterface && $finishEvent->isPropagationStopped()) { - return true; + + return (bool) ($finishEvent->isPropagationStopped()); + } + + /** + * @return int<0, max> + */ + private function getOrderPidFromSettings(): int + { + $orderPid = (int) ($this->settings['order']['pid'] ?? 0); + + if ($orderPid < 0) { + $orderPid = 0; } - return false; + return $orderPid; + } + + private function getCartPidFromSettings(): int + { + return (int) $this->settings['cart']['pid']; } } diff --git a/Classes/Controller/Cart/PaymentController.php b/Classes/Controller/Cart/PaymentController.php index c16ec2dc..14a8c381 100644 --- a/Classes/Controller/Cart/PaymentController.php +++ b/Classes/Controller/Cart/PaymentController.php @@ -23,14 +23,14 @@ public function updateAction(int $paymentId): ResponseInterface { $this->updatePaymentInSession($paymentId); - if ($this->isAjaxRequest()) { + if (self::isAjaxRequest()) { return $this->renderHtmlResponse(); } return $this->redirect('show', 'Cart\Cart'); } - private function isAjaxRequest(): bool + private static function isAjaxRequest(): bool { $pageType = $GLOBALS['TYPO3_REQUEST']->getAttribute('routing')->getPageType(); @@ -51,7 +51,7 @@ private function updatePaymentInSession(int $paymentId): void { $this->restoreSession(); - $payments = $this->paymentMethodsService->getPaymentMethods($this->cart); + $payments = $this->paymentMethodsLoader->getPaymentMethods($this->cart); $payment = $payments[$paymentId] ?? null; if (is_null($payment) || $payment->isAvailable() === false) { diff --git a/Classes/Controller/Cart/ProductController.php b/Classes/Controller/Cart/ProductController.php index b93dc4b5..448204ab 100644 --- a/Classes/Controller/Cart/ProductController.php +++ b/Classes/Controller/Cart/ProductController.php @@ -11,6 +11,7 @@ * LICENSE file that was distributed with this source code. */ +use Exception; use Extcode\Cart\Domain\Model\Cart\Product; use Extcode\Cart\Event\CheckProductAvailabilityEvent; use Extcode\Cart\Event\RetrieveProductsFromRequestEvent; @@ -27,7 +28,7 @@ public function addAction(): ResponseInterface { if (!$this->request->hasArgument('productType')) { // TODO: add own Exception - throw new \Exception('productType is needed'); + throw new Exception('productType is needed', 5200281451); } $this->restoreSession(); @@ -154,7 +155,7 @@ private function responseForAddAction(array $cartProducts, int $quantity): Respo */ private function responseForAddActionWithErrors(array $errors): ResponseInterface { - $errorWithHighestSeverity = $this->getErrorWithHighestSeverity($errors); + $errorWithHighestSeverity = self::getErrorWithHighestSeverity($errors); $pageType = $GLOBALS['TYPO3_REQUEST']->getAttribute('routing')->getPageType(); if ($pageType === self::AJAX_CART_TYPE_NUM) { @@ -183,7 +184,7 @@ private function responseForAddActionWithErrors(array $errors): ResponseInterfac /** * @param FlashMessage[] $errors */ - private function getErrorWithHighestSeverity(array $errors): FlashMessage + private static function getErrorWithHighestSeverity(array $errors): FlashMessage { $errorToReturn = array_shift($errors); diff --git a/Classes/Controller/Cart/ShippingController.php b/Classes/Controller/Cart/ShippingController.php index 4690a1b7..7bbdcda0 100644 --- a/Classes/Controller/Cart/ShippingController.php +++ b/Classes/Controller/Cart/ShippingController.php @@ -23,14 +23,14 @@ public function updateAction(int $shippingId): ResponseInterface { $this->updateShippingInSession($shippingId); - if ($this->isAjaxRequest()) { + if (self::isAjaxRequest()) { return $this->renderHtmlResponse(); } return $this->redirect('show', 'Cart\Cart'); } - private function isAjaxRequest(): bool + private static function isAjaxRequest(): bool { $pageType = $GLOBALS['TYPO3_REQUEST']->getAttribute('routing')->getPageType(); @@ -51,7 +51,7 @@ private function updateShippingInSession(int $shippingId): void { $this->restoreSession(); - $shippings = $this->shippingMethodsService->getShippingMethods($this->cart); + $shippings = $this->shippingMethodsLoader->getShippingMethods($this->cart); $shipping = $shippings[$shippingId] ?? null; if (is_null($shipping) || $shipping->isAvailable() === false) { diff --git a/Classes/Controller/Order/OrderController.php b/Classes/Controller/Order/OrderController.php index bd3316b7..0d4a223e 100644 --- a/Classes/Controller/Order/OrderController.php +++ b/Classes/Controller/Order/OrderController.php @@ -27,19 +27,13 @@ class OrderController extends ActionController { protected array $searchArguments = []; + protected array $pluginSettings; public function __construct( private readonly Context $context, protected ItemRepository $itemRepository - ) {} - - protected function initializeAction(): void - { - $this->pluginSettings - = $this->configurationManager->getConfiguration( - ConfigurationManager::CONFIGURATION_TYPE_FRAMEWORK - ); + ) { } public function listAction(int $currentPage = 1): ResponseInterface @@ -49,7 +43,7 @@ public function listAction(int $currentPage = 1): ResponseInterface $feUserUid = $this->context->getPropertyFromAspect('frontend.user', 'id'); $orderItems = $this->itemRepository->findBy(['feUser' => $feUserUid]); - $itemsPerPage = (isset($this->settings['itemsPerPage']) && is_numeric($this->settings['itemsPerPage'])) ? (int)$this->settings['itemsPerPage'] : 20; + $itemsPerPage = (isset($this->settings['itemsPerPage']) && is_numeric($this->settings['itemsPerPage'])) ? (int) $this->settings['itemsPerPage'] : 20; $arrayPaginator = new QueryResultPaginator( $orderItems, @@ -81,6 +75,7 @@ public function showAction(Item $orderItem): ResponseInterface '', ContextualFeedbackSeverity::ERROR ); + return $this->redirect('list'); } @@ -113,4 +108,12 @@ public function showAction(Item $orderItem): ResponseInterface return $this->htmlResponse(); } + + protected function initializeAction(): void + { + $this->pluginSettings + = $this->configurationManager->getConfiguration( + ConfigurationManager::CONFIGURATION_TYPE_FRAMEWORK + ); + } } diff --git a/Classes/Domain/Finisher/Form/AddToCartFinisher.php b/Classes/Domain/Finisher/Form/AddToCartFinisher.php index 864c68b3..fcb848c0 100644 --- a/Classes/Domain/Finisher/Form/AddToCartFinisher.php +++ b/Classes/Domain/Finisher/Form/AddToCartFinisher.php @@ -37,7 +37,9 @@ public function __construct( protected ConfigurationManagerInterface $configurationManager, protected SessionHandler $sessionHandler, protected CartUtility $cartUtility, - protected EventDispatcherInterface $eventDispatcher + protected EventDispatcherInterface $eventDispatcher, + private readonly ExtensionService $extensionService, + private readonly FlashMessageService $flashMessageService ) { $this->configurations = $this->configurationManager->getConfiguration( ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, @@ -79,7 +81,7 @@ protected function executeInternal(): ?string $severity = ContextualFeedbackSeverity::OK; $pageType = $GLOBALS['TYPO3_REQUEST']->getAttribute('routing')->getPageType(); - if (in_array((int)$pageType, $this->configurations['settings']['jsonResponseForPageTypes'])) { + if (in_array((int) $pageType, $this->configurations['settings']['jsonResponseForPageTypes'])) { $payload = [ 'status' => $status, 'added' => $quantity, @@ -96,21 +98,22 @@ protected function executeInternal(): ?string $response = $this->finisherContext->getFormRuntime()->getResponse() ->withAddedHeader('Content-Type', 'application/json; charset=utf-8') ->withBody($stream) - ->withStatus((int)$status); + ->withStatus((int) $status) + ; - /** @see \TYPO3\CMS\Form\Domain\Finishers\RedirectFinisher::redirectToUri */ + // @see \TYPO3\CMS\Form\Domain\Finishers\RedirectFinisher::redirectToUri throw new PropagateResponseException($response, 1655984985); } $flashMessage = GeneralUtility::makeInstance( FlashMessage::class, - (string)$messageBody, - (string)$messageTitle, + (string) $messageBody, + (string) $messageTitle, $severity, true ); - $extensionService = GeneralUtility::makeInstance(ExtensionService::class); - $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); + $extensionService = $this->extensionService; + $flashMessageService = $this->flashMessageService; // todo: this value has to be taken from the request directly in the future $pluginNamespace = $extensionService->getPluginNamespace( @@ -136,6 +139,7 @@ protected function getHoneypotIdentifier(): string return $renderable->getIdentifier(); } } + return ''; } @@ -149,6 +153,7 @@ protected function addProductsToCart(array $products): int $this->cart->addProduct($product); } } + return $quantity; } @@ -164,6 +169,7 @@ protected function getStatusMessageBody(array $formValues, $status = '200'): ?st 'Cart' ); } + return $messageBody; } @@ -179,6 +185,7 @@ protected function getStatusMessageTitle(array $formValues, $status = '200'): ?s 'Cart' ); } + return $messageTitle; } } diff --git a/Classes/Domain/Log/DatabaseWriter.php b/Classes/Domain/Log/DatabaseWriter.php new file mode 100644 index 00000000..863d2711 --- /dev/null +++ b/Classes/Domain/Log/DatabaseWriter.php @@ -0,0 +1,58 @@ +getData(); + + $log = $recordData['log'] ?? null; + if (($log instanceof LogInterface) === false) { + return $this; + } + unset($recordData['log']); + + $fieldValues = [ + 'log_level' => $log->getLogLevel()->value, + 'item' => $log->getOrderItemId(), + 'type' => $log->getType(), + 'message' => $log->getMessage(), + 'arguments' => $this->jsonEncodeWithThrowable($log->getArguments()), + 'request_id' => $record->getRequestId(), + 'time_micro' => $record->getCreated(), + 'level' => $record->getLevel(), + 'data' => $this->jsonEncodeWithThrowable($recordData), + ]; + + $logRepository = GeneralUtility::makeInstance(LogRepository::class); + $logRepository->insert($fieldValues); + + return $this; + } + + public function jsonEncodeWithThrowable(array $dataToEncode): string + { + $data = ''; + if (!empty($dataToEncode)) { + // Fold an exception into the message, and string-ify it into recordData so it can be jsonified. + if (isset($dataToEncode['exception']) && $dataToEncode['exception'] instanceof Throwable) { + $dataToEncode['exception'] = (string) $dataToEncode['exception']; + } + $data = '- ' . json_encode($dataToEncode); + } + + return $data; + } +} diff --git a/Classes/Domain/Log/LogService.php b/Classes/Domain/Log/LogService.php new file mode 100644 index 00000000..71959c60 --- /dev/null +++ b/Classes/Domain/Log/LogService.php @@ -0,0 +1,28 @@ +logger->log( + $log->getLogLevel()->value, + $log->getMessage(), + [ + 'log' => $log, + ] + ); + } +} diff --git a/Classes/Domain/Log/LogServiceInterface.php b/Classes/Domain/Log/LogServiceInterface.php new file mode 100644 index 00000000..9d45842e --- /dev/null +++ b/Classes/Domain/Log/LogServiceInterface.php @@ -0,0 +1,12 @@ +logLevel; + } + + public function getOrderItemId(): int + { + return $this->orderItemId; + } + + public function getType(): string + { + return $this->type; + } + + public function getMessage(): string + { + return $this->message; + } + + public function getArguments(): array + { + return $this->arguments; + } +} diff --git a/Classes/Domain/Log/Model/LogInterface.php b/Classes/Domain/Log/Model/LogInterface.php new file mode 100644 index 00000000..bb4ce8a8 --- /dev/null +++ b/Classes/Domain/Log/Model/LogInterface.php @@ -0,0 +1,54 @@ +queryBuilder = $connectionPool + ->getQueryBuilderForTable(self::TABLE_NAME) + ; + } + + public function insert( + array $fieldValues, + ): void { + // for cleanup of table + $fieldValues['crdate'] = time(); + + $queryBuilder = clone $this->queryBuilder; + $queryBuilder + ->insert(self::TABLE_NAME) + ->values($fieldValues) + ->executeStatement() + ; + } + + public function findAllByIdentifier( + string $identifier, + ): array { + $queryBuilder = clone $this->queryBuilder; + $queryBuilder + ->select('*') + ->from(self::TABLE_NAME) + ->where( + $queryBuilder->expr()->eq( + 'identifier', + $queryBuilder->createNamedParameter($identifier) + ) + ) + ; + + return $queryBuilder + ->executeQuery() + ->fetchAllAssociative() + ; + } +} diff --git a/Classes/Domain/Model/Cart/AbstractCartCoupon.php b/Classes/Domain/Model/Cart/AbstractCartCoupon.php index 1aa937eb..7035f8b9 100644 --- a/Classes/Domain/Model/Cart/AbstractCartCoupon.php +++ b/Classes/Domain/Model/Cart/AbstractCartCoupon.php @@ -25,8 +25,6 @@ abstract class AbstractCartCoupon implements CartCouponInterface protected bool $isCombinable = false; - protected bool $isRelativeDiscount = false; - public function setCart(Cart $cart): void { $this->cart = $cart; @@ -42,11 +40,6 @@ public function getCode(): string return $this->code; } - public function getCouponType(): string - { - return $this->couponType; - } - public function getCartMinPrice(): float { return $this->cartMinPrice; @@ -57,11 +50,6 @@ public function isCombinable(): bool return $this->isCombinable; } - public function isRelativeDiscount(): bool - { - return $this->isRelativeDiscount; - } - public function isUseable(): bool { return $this->cartMinPrice <= $this->cart->getGross(); diff --git a/Classes/Domain/Model/Cart/AdditionalDataTrait.php b/Classes/Domain/Model/Cart/AdditionalDataTrait.php index 13e113ad..c03502a3 100644 --- a/Classes/Domain/Model/Cart/AdditionalDataTrait.php +++ b/Classes/Domain/Model/Cart/AdditionalDataTrait.php @@ -41,7 +41,7 @@ public function unsetAdditionals(): void public function getAdditional(string $key): mixed { - return $this->additionals[$key]; + return $this->additionals[$key] ?? null; } public function setAdditional(string $key, mixed $value): void diff --git a/Classes/Domain/Model/Cart/BeVariant.php b/Classes/Domain/Model/Cart/BeVariant.php index 98748db6..777119e2 100644 --- a/Classes/Domain/Model/Cart/BeVariant.php +++ b/Classes/Domain/Model/Cart/BeVariant.php @@ -4,6 +4,8 @@ namespace Extcode\Cart\Domain\Model\Cart; +use InvalidArgumentException; + /* * This file is part of the package extcode/cart. * @@ -125,11 +127,9 @@ public function getTitle(): string public function getCompleteTitle(): string { - $title = ''; - if ($this->parent instanceof BeVariantInterface) { $title = $this->parent->getCompleteTitle(); - } elseif ($this->parent instanceof ProductInterface) { + } else { $title = $this->parent->getTitle(); } @@ -203,9 +203,10 @@ public function getDiscount(): float public function getSpecialPriceDiscount(): float { $discount = 0.0; - if (($this->price != 0.0) && ($this->specialPrice)) { + if (($this->price != 0.0) && $this->specialPrice) { $discount = (($this->price - $this->specialPrice) / $this->price) * 100; } + return $discount; } @@ -215,10 +216,8 @@ public function getPriceCalculated(): float if ($this->parent instanceof BeVariantInterface) { $parentPrice = $this->parent->getBestPrice(); - } elseif ($this->parent instanceof ProductInterface) { - $parentPrice = $this->parent->getBestPrice($this->getQuantity()); } else { - $parentPrice = 0.0; + $parentPrice = $this->parent->getBestPrice($this->getQuantity()); } if ($this->priceCalcMethod === 0) { @@ -240,7 +239,7 @@ public function getPriceCalculated(): float return $parentPrice + (($price / 100) * $parentPrice); } - throw new \InvalidArgumentException('Unkonwn price calc method', 1711969492); + throw new InvalidArgumentException('Unkonwn price calc method', 1711969492); } public function getBestPriceCalculated(): float @@ -295,11 +294,9 @@ public function getSku(): string public function getCompleteSku(): string { - $sku = ''; - if ($this->parent instanceof BeVariantInterface) { $sku = $this->parent->getCompleteSku(); - } elseif ($this->parent instanceof ProductInterface) { + } else { $sku = $this->parent->getSku(); } @@ -419,10 +416,7 @@ public function getBeVariantById(int $beVariantId): ?BeVariantInterface return $this->beVariants[$beVariantId] ?? null; } - /** - * @return bool|int - */ - public function removeBeVariants(array $beVariantsArray) + public function removeBeVariants(array $beVariantsArray): bool|int { foreach ($beVariantsArray as $beVariantId => $value) { $beVariant = $this->beVariants[$beVariantId]; @@ -433,7 +427,6 @@ public function removeBeVariants(array $beVariantsArray) if (!$beVariant->getBeVariants()) { unset($this->beVariants[$beVariantId]); } - } else { unset($this->beVariants[$beVariantId]); } @@ -446,6 +439,44 @@ public function removeBeVariants(array $beVariantsArray) return true; } + public function getMin(): int + { + return $this->min; + } + + public function setMin(int $min): void + { + if ($min < 0 || $min > $this->max) { + throw new InvalidArgumentException(); + } + + $this->min = $min; + } + + public function getMax(): int + { + return $this->max; + } + + public function setMax(int $max): void + { + if ($max < 0 || $max < $this->min) { + throw new InvalidArgumentException(); + } + + $this->max = $max; + } + + public function getStock(): int + { + return $this->stock; + } + + public function setStock(int $stock): void + { + $this->stock = $stock; + } + protected function calcGross(): void { if ($this->isNetPrice() === false) { @@ -472,7 +503,7 @@ protected function calcTax(): void $this->tax = ($this->gross / (1 + $this->getTaxClass()->getCalc())) * ($this->getTaxClass()->getCalc()); } else { $this->calcNet(); - $this->tax = ($this->net * $this->getTaxClass()->getCalc()); + $this->tax = $this->net * $this->getTaxClass()->getCalc(); } } @@ -518,42 +549,4 @@ protected function reCalc(): void $this->calcGross(); } } - - public function getMin(): int - { - return $this->min; - } - - public function setMin(int $min): void - { - if ($min < 0 || $min > $this->max) { - throw new \InvalidArgumentException(); - } - - $this->min = $min; - } - - public function getMax(): int - { - return $this->max; - } - - public function setMax(int $max): void - { - if ($max < 0 || $max < $this->min) { - throw new \InvalidArgumentException(); - } - - $this->max = $max; - } - - public function getStock(): int - { - return $this->stock; - } - - public function setStock(int $stock): void - { - $this->stock = $stock; - } } diff --git a/Classes/Domain/Model/Cart/BeVariantInterface.php b/Classes/Domain/Model/Cart/BeVariantInterface.php index ff295f69..b3ae9abb 100644 --- a/Classes/Domain/Model/Cart/BeVariantInterface.php +++ b/Classes/Domain/Model/Cart/BeVariantInterface.php @@ -15,9 +15,9 @@ interface BeVariantInterface extends MinimalInterface { public function toArray(): array; - public function getParent(): BeVariantInterface|ProductInterface; + public function getParent(): ProductInterface|self; - public function setParent(BeVariantInterface|ProductInterface $parent): void; + public function setParent(ProductInterface|self $parent): void; public function getProduct(): ProductInterface; @@ -77,10 +77,7 @@ public function getBeVariants(): array; public function getBeVariantById(int $beVariantId): ?self; - /** - * @return bool|int - */ - public function removeBeVariants(array $beVariantsArray); + public function removeBeVariants(array $beVariantsArray): bool|int; public function getMin(): int; diff --git a/Classes/Domain/Model/Cart/Cart.php b/Classes/Domain/Model/Cart/Cart.php index e635b3aa..b7300715 100644 --- a/Classes/Domain/Model/Cart/Cart.php +++ b/Classes/Domain/Model/Cart/Cart.php @@ -11,15 +11,15 @@ * LICENSE file that was distributed with this source code. */ -use Extcode\Cart\Service\CurrencyTranslationServiceInterface; +use Extcode\Cart\Configuration\Loader\CurrencyTranslationLoaderInterface; +use InvalidArgumentException; +use LogicException; use TYPO3\CMS\Core\Utility\GeneralUtility; class Cart implements AdditionalDataInterface { use AdditionalDataTrait; - private ?CurrencyTranslationServiceInterface $currencyTranslationService = null; - protected float $net; protected float $gross; @@ -29,7 +29,7 @@ class Cart implements AdditionalDataInterface protected int $count; /** - * @var Product[] + * @var ProductInterface[] */ protected array $products = []; @@ -71,6 +71,8 @@ class Cart implements AdditionalDataInterface protected string $shippingCountry = ''; + private ?CurrencyTranslationLoaderInterface $currencyTranslationLoader = null; + public function __construct( protected array $taxClasses, protected bool $isNetCart = false, @@ -78,7 +80,7 @@ public function __construct( protected string $currencySign = '€', protected float $currencyTranslation = 1.00 ) { - $this->currencyTranslationService = GeneralUtility::makeInstance(CurrencyTranslationServiceInterface::class); + $this->currencyTranslationLoader = GeneralUtility::makeInstance(CurrencyTranslationLoaderInterface::class); $this->net = 0.0; $this->gross = 0.0; @@ -126,7 +128,9 @@ public function __sleep(): array ]; } - public function __wakeup() {} + public function __wakeup(): void + { + } /** * @return TaxClass[] @@ -168,12 +172,13 @@ public function isNetCart(): bool /** * Sets Order Number if no Order Number is given else throws an exception - * @throws \LogicException + * + * @throws LogicException */ public function setOrderNumber(string $orderNumber): void { - if (($this->orderNumber) && ($this->orderNumber !== $orderNumber)) { - throw new \LogicException( + if ($this->orderNumber && ($this->orderNumber !== $orderNumber)) { + throw new LogicException( 'You can not redeclare the order number of your cart.', 1413969668 ); @@ -201,12 +206,12 @@ public function getOrderNumber(): string /** * Sets Invoice Number if no Invoice Number is given else throws an exception * - * @throws \LogicException + * @throws LogicException */ public function setInvoiceNumber(string $invoiceNumber): void { - if (($this->invoiceNumber) && ($this->invoiceNumber !== $invoiceNumber)) { - throw new \LogicException( + if ($this->invoiceNumber && ($this->invoiceNumber !== $invoiceNumber)) { + throw new LogicException( 'You can not redeclare the invoice number of your cart.', 1413969712 ); @@ -484,21 +489,18 @@ public function getServiceGross(): float } /** - * @return Product[] + * @return ProductInterface[] */ public function getProducts(): array { return $this->products; } - public function getProductById(string $productId): ?Product + public function getProductById(string $productId): ?ProductInterface { return $this->products[$productId] ?? null; } - /** - * @return array - */ public function toArray(): array { $cartArray = [ @@ -541,27 +543,12 @@ public function toJson(): string /** * Return Coupons - * - * @return array */ public function getCoupons(): array { return $this->coupons; } - protected function areCouponsCombinable(): bool - { - if ($this->coupons) { - foreach ($this->coupons as $coupon) { - if (!$coupon->isCombinable()) { - return false; - } - } - } - - return true; - } - /** * @todo replace return type with enum */ @@ -656,16 +643,12 @@ public function getCouponTaxes(): array public function getDiscountGross(): float { - $gross = -1 * $this->getCouponGross(); - - return $gross; + return -1 * $this->getCouponGross(); } public function getDiscountNet(): float { - $net = -1 * $this->getCouponNet(); - - return $net; + return -1 * $this->getCouponNet(); } /** @@ -673,12 +656,12 @@ public function getDiscountNet(): float */ public function getDiscountTaxes(): array { - $taxes = array_map(fn($value) => -1 * $value, $this->getCouponTaxes()); + $taxes = array_map(static fn ($value) => -1 * $value, $this->getCouponTaxes()); return $taxes; } - public function addProduct(Product $newProduct): void + public function addProduct(ProductInterface $newProduct): void { $id = $newProduct->getId(); @@ -695,7 +678,7 @@ public function addProduct(Product $newProduct): void } } - public function changeProduct(Product $product, Product $newProduct): void + public function changeProduct(ProductInterface $product, ProductInterface $newProduct): void { $newQuantity = $product->getQuantity() + $newProduct->getQuantity(); @@ -716,7 +699,7 @@ public function changeProduct(Product $product, Product $newProduct): void $this->addNet($product->getNet()); $this->addTax($product->getTax(), $product->getTaxClass()); - //update all service attributes + // update all service attributes $this->updateServiceAttributes(); } @@ -725,38 +708,36 @@ public function changeProductsQuantity(array $productQuantityArray): void foreach ($productQuantityArray as $productPuid => $quantity) { $product = $this->products[$productPuid]; - if ($product instanceof Product) { - if (is_array($quantity)) { + if (is_array($quantity)) { + $this->subCount($product->getQuantity()); + $this->subGross($product->getGross()); + $this->subNet($product->getNet()); + $this->subTax($product->getTax(), $product->getTaxClass()); + + $product->changeVariantsQuantity($quantity); + + $this->addCount($product->getQuantity()); + $this->addGross($product->getGross()); + $this->addNet($product->getNet()); + $this->addTax($product->getTax(), $product->getTaxClass()); + } else { + // only run, if quantity was realy changed + if ($product->getQuantity() != $quantity) { $this->subCount($product->getQuantity()); $this->subGross($product->getGross()); $this->subNet($product->getNet()); $this->subTax($product->getTax(), $product->getTaxClass()); - $product->changeVariantsQuantity($quantity); + $product->changeQuantity($quantity); $this->addCount($product->getQuantity()); $this->addGross($product->getGross()); $this->addNet($product->getNet()); $this->addTax($product->getTax(), $product->getTaxClass()); - } else { - // only run, if quantity was realy changed - if ($product->getQuantity() != $quantity) { - $this->subCount($product->getQuantity()); - $this->subGross($product->getGross()); - $this->subNet($product->getNet()); - $this->subTax($product->getTax(), $product->getTaxClass()); - - $product->changeQuantity($quantity); - - $this->addCount($product->getQuantity()); - $this->addGross($product->getGross()); - $this->addNet($product->getNet()); - $this->addTax($product->getTax(), $product->getTaxClass()); - } } } - //update all service attributes + // update all service attributes $this->updateServiceAttributes(); } } @@ -765,6 +746,10 @@ public function removeProductByIds(array $products): bool { $productId = key($products); + if (is_string($productId) === false) { + throw new InvalidArgumentException('Key has to be a string.', 1774447534); + } + if (!isset($this->products[$productId])) { return false; } @@ -789,9 +774,9 @@ public function removeProductById(string $productId): bool return true; } - public function removeProduct(Product $product, array $productVariantIds = []): bool + public function removeProduct(ProductInterface $product, array $productVariantIds = []): bool { - if (is_array($productVariantIds) && !empty($productVariantIds)) { + if (!empty($productVariantIds)) { $product->removeBeVariants($productVariantIds); if (!$product->getBeVariants()) { @@ -811,49 +796,6 @@ public function removeProduct(Product $product, array $productVariantIds = []): return true; } - protected function addServiceAttributes(Product $newProduct): void - { - if ($this->maxServiceAttr1 < $newProduct->getServiceAttribute1()) { - $this->maxServiceAttr1 = $newProduct->getServiceAttribute1(); - } - if ($this->maxServiceAttr2 < $newProduct->getServiceAttribute2()) { - $this->maxServiceAttr2 = $newProduct->getServiceAttribute2(); - } - if ($this->maxServiceAttr3 < $newProduct->getServiceAttribute3()) { - $this->maxServiceAttr3 = $newProduct->getServiceAttribute3(); - } - - $this->sumServiceAttr1 += $newProduct->getServiceAttribute1() * $newProduct->getQuantity(); - $this->sumServiceAttr2 += $newProduct->getServiceAttribute2() * $newProduct->getQuantity(); - $this->sumServiceAttr3 += $newProduct->getServiceAttribute3() * $newProduct->getQuantity(); - } - - protected function updateServiceAttributes(): void - { - $this->maxServiceAttr1 = 0.0; - $this->maxServiceAttr2 = 0.0; - $this->maxServiceAttr3 = 0.0; - $this->sumServiceAttr1 = 0.0; - $this->sumServiceAttr2 = 0.0; - $this->sumServiceAttr3 = 0.0; - - foreach ($this->products as $key => $product) { - if ($this->maxServiceAttr1 < $product->getServiceAttribute1()) { - $this->maxServiceAttr1 = $product->getServiceAttribute1(); - } - if ($this->maxServiceAttr2 < $product->getServiceAttribute2()) { - $this->maxServiceAttr2 = $product->getServiceAttribute2(); - } - if ($this->maxServiceAttr3 < $product->getServiceAttribute3()) { - $this->maxServiceAttr3 = $product->getServiceAttribute3(); - } - - $this->sumServiceAttr1 += $product->getServiceAttribute1() * $product->getQuantity(); - $this->sumServiceAttr2 += $product->getServiceAttribute2() * $product->getQuantity(); - $this->sumServiceAttr3 += $product->getServiceAttribute3() * $product->getQuantity(); - } - } - public function getMaxServiceAttribute1(): float { return $this->maxServiceAttr1; @@ -902,54 +844,6 @@ public function changeSpecials(array $specials): void $this->specials = $specials; } - protected function calcAll(): void - { - $this->calcCount(); - $this->calcGross(); - $this->calcTax(); - $this->calcNet(); - } - - protected function calcCount(): void - { - $this->count = 0; - if ($this->products) { - foreach ($this->products as $product) { - $this->addCount($product->getQuantity()); - } - } - } - - protected function calcGross(): void - { - $this->gross = 0.0; - if ($this->products) { - foreach ($this->products as $product) { - $this->addGross($product->getGross()); - } - } - } - - protected function calcNet(): void - { - $this->net = 0.0; - if ($this->products) { - foreach ($this->products as $product) { - $this->addNet($product->getNet()); - } - } - } - - protected function calcTax(): void - { - $this->taxes = []; - if ($this->products) { - foreach ($this->products as $product) { - $this->addTax($product->getTax(), $product->getTaxClass()); - } - } - } - public function reCalc(): void { $this->calcCount(); @@ -1088,10 +982,114 @@ public function setCurrencySign(string $currencySign): void public function translatePrice(?float $price = null): ?float { - if (is_null($this->currencyTranslationService)) { - $this->currencyTranslationService = GeneralUtility::makeInstance(CurrencyTranslationServiceInterface::class); + if (is_null($this->currencyTranslationLoader)) { + $this->currencyTranslationLoader = GeneralUtility::makeInstance(CurrencyTranslationLoaderInterface::class); } - return $this->currencyTranslationService->translatePrice($this->getCurrencyTranslation(), $price); + return $this->currencyTranslationLoader->translatePrice($this->getCurrencyTranslation(), $price); + } + + protected function areCouponsCombinable(): bool + { + if ($this->coupons) { + foreach ($this->coupons as $coupon) { + if (!$coupon->isCombinable()) { + return false; + } + } + } + + return true; + } + + protected function addServiceAttributes(ProductInterface $newProduct): void + { + if ($this->maxServiceAttr1 < $newProduct->getServiceAttribute1()) { + $this->maxServiceAttr1 = $newProduct->getServiceAttribute1(); + } + if ($this->maxServiceAttr2 < $newProduct->getServiceAttribute2()) { + $this->maxServiceAttr2 = $newProduct->getServiceAttribute2(); + } + if ($this->maxServiceAttr3 < $newProduct->getServiceAttribute3()) { + $this->maxServiceAttr3 = $newProduct->getServiceAttribute3(); + } + + $this->sumServiceAttr1 += $newProduct->getServiceAttribute1() * $newProduct->getQuantity(); + $this->sumServiceAttr2 += $newProduct->getServiceAttribute2() * $newProduct->getQuantity(); + $this->sumServiceAttr3 += $newProduct->getServiceAttribute3() * $newProduct->getQuantity(); + } + + protected function updateServiceAttributes(): void + { + $this->maxServiceAttr1 = 0.0; + $this->maxServiceAttr2 = 0.0; + $this->maxServiceAttr3 = 0.0; + $this->sumServiceAttr1 = 0.0; + $this->sumServiceAttr2 = 0.0; + $this->sumServiceAttr3 = 0.0; + + foreach ($this->products as $key => $product) { + if ($this->maxServiceAttr1 < $product->getServiceAttribute1()) { + $this->maxServiceAttr1 = $product->getServiceAttribute1(); + } + if ($this->maxServiceAttr2 < $product->getServiceAttribute2()) { + $this->maxServiceAttr2 = $product->getServiceAttribute2(); + } + if ($this->maxServiceAttr3 < $product->getServiceAttribute3()) { + $this->maxServiceAttr3 = $product->getServiceAttribute3(); + } + + $this->sumServiceAttr1 += $product->getServiceAttribute1() * $product->getQuantity(); + $this->sumServiceAttr2 += $product->getServiceAttribute2() * $product->getQuantity(); + $this->sumServiceAttr3 += $product->getServiceAttribute3() * $product->getQuantity(); + } + } + + protected function calcAll(): void + { + $this->calcCount(); + $this->calcGross(); + $this->calcTax(); + $this->calcNet(); + } + + protected function calcCount(): void + { + $this->count = 0; + if ($this->products) { + foreach ($this->products as $product) { + $this->addCount($product->getQuantity()); + } + } + } + + protected function calcGross(): void + { + $this->gross = 0.0; + if ($this->products) { + foreach ($this->products as $product) { + $this->addGross($product->getGross()); + } + } + } + + protected function calcNet(): void + { + $this->net = 0.0; + if ($this->products) { + foreach ($this->products as $product) { + $this->addNet($product->getNet()); + } + } + } + + protected function calcTax(): void + { + $this->taxes = []; + if ($this->products) { + foreach ($this->products as $product) { + $this->addTax($product->getTax(), $product->getTaxClass()); + } + } } } diff --git a/Classes/Domain/Model/Cart/CartCouponInterface.php b/Classes/Domain/Model/Cart/CartCouponInterface.php index f1d0681a..3e9c3c7d 100644 --- a/Classes/Domain/Model/Cart/CartCouponInterface.php +++ b/Classes/Domain/Model/Cart/CartCouponInterface.php @@ -13,16 +13,14 @@ interface CartCouponInterface { - /** - * Returns the coupon title. - */ public function getTitle(): string; - /** - * Returns the coupon code. - */ public function getCode(): string; + public function getTaxClass(): TaxClass; + + public function setCart(Cart $cart): void; + /** * Returns true if a coupon can be combined with other coupons. */ diff --git a/Classes/Domain/Model/Cart/Extra.php b/Classes/Domain/Model/Cart/Extra.php index a77d604d..523cd456 100644 --- a/Classes/Domain/Model/Cart/Extra.php +++ b/Classes/Domain/Model/Cart/Extra.php @@ -63,11 +63,7 @@ public function getCondition(): float public function leq(float $condition): bool { - if ($condition < $this->condition) { - return false; - } - - return true; + return ! ($condition < $this->condition); } public function getPrice(): float @@ -114,6 +110,7 @@ public function getTaxForTaxClass(TaxClass $taxClass): float if ($this->service->getTaxClass()->getId() === -2) { $taxClassDistribution = $this->getTaxClassDistributionOverCart(); $factor = $taxClass->getCalc(); + return ($this->net * $taxClassDistribution[$taxClass->getId()]) * $factor; } } else { @@ -124,6 +121,7 @@ public function getTaxForTaxClass(TaxClass $taxClass): float if ($this->service->getTaxClass()->getId() === -2) { $taxClassDistribution = $this->getTaxClassDistributionOverCart(); $factor = $taxClass->getCalc(); + return ($this->gross * $taxClassDistribution[$taxClass->getId()]) / (1 + $factor) * $factor; } } @@ -150,7 +148,7 @@ protected function calcTax(): void { if ($this->isNetPrice) { if ($this->service->getTaxClass()->getId() > 0) { - $this->tax = ($this->net * $this->taxClass->getCalc()); + $this->tax = $this->net * $this->taxClass->getCalc(); } elseif ($this->service->getTaxClass()->getId() === -2) { $tax = 0.0; foreach ($this->getTaxClassDistributionOverCart() as $taxClassId => $taxClassDistribution) { @@ -187,7 +185,7 @@ protected function getTaxClassDistributionOverCart(): array $total = array_sum($taxClassDistribution); - return array_map(fn($gross) => $gross / $total, $taxClassDistribution); + return array_map(static fn ($gross) => $gross / $total, $taxClassDistribution); } protected function calcNet(): void diff --git a/Classes/Domain/Model/Cart/FeVariant.php b/Classes/Domain/Model/Cart/FeVariant.php index bc202f2d..e8a8045c 100644 --- a/Classes/Domain/Model/Cart/FeVariant.php +++ b/Classes/Domain/Model/Cart/FeVariant.php @@ -25,7 +25,8 @@ final class FeVariant implements FeVariantInterface public function __construct( protected array $variantData = [] - ) {} + ) { + } public function getId(): string { @@ -51,8 +52,11 @@ public function getTitle(): string { $titleArr = []; foreach ($this->variantData as $variant) { - $titleArr[] = $variant['title']; + if (is_string($variant['title'])) { + $titleArr[] = $variant['title']; + } } + return implode($this->titleGlue, $titleArr); } @@ -60,8 +64,11 @@ public function getSku(): string { $skuArr = []; foreach ($this->variantData as $variant) { - $skuArr[] = $variant['sku']; + if (is_string($variant['sku'])) { + $skuArr[] = $variant['sku']; + } } + return implode($this->skuGlue, $skuArr); } @@ -69,8 +76,11 @@ public function getValue(): string { $valueArr = []; foreach ($this->variantData as $variant) { - $valueArr[] = $variant['value']; + if (is_string($variant['value'])) { + $valueArr[] = $variant['value']; + } } + return implode($this->valueGlue, $valueArr); } } diff --git a/Classes/Domain/Model/Cart/Product.php b/Classes/Domain/Model/Cart/Product.php index 58d9a08b..31b2833c 100644 --- a/Classes/Domain/Model/Cart/Product.php +++ b/Classes/Domain/Model/Cart/Product.php @@ -4,6 +4,8 @@ namespace Extcode\Cart\Domain\Model\Cart; +use InvalidArgumentException; + /* * This file is part of the package extcode/cart. * @@ -148,8 +150,8 @@ public function changeVariantsQuantity(array $variantQuantity): void foreach ($variantQuantity as $variantId => $quantity) { $variant = $this->beVariants[$variantId]; - if (ctype_digit((string)$quantity)) { - $quantity = (int)$quantity; + if (ctype_digit((string) $quantity)) { + $quantity = (int) $quantity; $variant->changeQuantity($quantity); } elseif (is_array($quantity)) { $variant->changeVariantsQuantity($quantity); @@ -240,15 +242,6 @@ public function getId(): string return $this->getTableProductId(); } - protected function getTableProductId(): string - { - $tableProductId = $this->getProductType() . '_' . $this->getProductId(); - if ($this->getFeVariant()) { - $tableProductId .= '_' . $this->getFeVariant()->getId(); - } - return $tableProductId; - } - public function getPrice(): float { return $this->price; @@ -312,7 +305,7 @@ public function setQuantityDiscounts(array $quantityDiscounts): void /** * Returns Best Price (min of Price and Special Price) */ - public function getBestPrice(?int $quantity = null): ?float + public function getBestPrice(?int $quantity = null): float { $bestPrice = $this->getQuantityDiscountPrice($quantity); @@ -329,9 +322,7 @@ public function getBestPrice(?int $quantity = null): ?float */ public function getDiscount(): float { - $discount = $this->getTranslatedPrice() - $this->getBestPrice(); - - return $discount; + return $this->getTranslatedPrice() - $this->getBestPrice(); } /** @@ -343,6 +334,7 @@ public function getSpecialPriceDiscount(): float if (($this->getTranslatedPrice() != 0.0) && ($this->getTranslatedSpecialPrice())) { $discount = (($this->getTranslatedPrice() - $this->getTranslatedSpecialPrice()) / $this->getTranslatedPrice()) * 100; } + return $discount; } @@ -376,12 +368,12 @@ public function changeQuantity(int $newQuantity): void public function changeQuantities(array $newQuantities): void { foreach ($newQuantities as $newQuantityKey => $newQuantityValue) { - $newQuantityKey = (string)$newQuantityKey; - $newQuantityValue = (int)$newQuantityValue; + $newQuantityKey = (string) $newQuantityKey; + $newQuantityValue = (int) $newQuantityValue; if ($newQuantityValue === 0) { - $this->removeVariantById((string)$newQuantityKey); + $this->removeVariantById((string) $newQuantityKey); } else { - $this->getBeVariantById((string)$newQuantityKey)->setQuantity($newQuantityValue); + $this->getBeVariantById((string) $newQuantityKey)->setQuantity($newQuantityValue); $this->reCalc(); } } @@ -414,6 +406,7 @@ public function getGross(): float $this->calcGross(); $gross = $this->gross; } + return $gross; } @@ -424,6 +417,7 @@ public function getNet(): float $this->calcNet(); $net = $this->net; } + return $net; } @@ -434,13 +428,11 @@ public function getTax(): float $this->calcTax(); $tax = $this->tax; } + return $tax; } - /** - * @return mixed - */ - public function getError() + public function getError(): mixed { return $this->error; } @@ -523,6 +515,76 @@ public function toJson(): string return json_encode($this->toArray()); } + public function getMinNumberInCart(): int + { + return $this->minNumberInCart; + } + + public function setMinNumberInCart(int $minNumberInCart): void + { + if ($minNumberInCart < 0 + || ($this->maxNumberInCart > 0 && $minNumberInCart > $this->maxNumberInCart) + ) { + throw new InvalidArgumentException(); + } + + $this->minNumberInCart = $minNumberInCart; + } + + public function getMaxNumberInCart(): int + { + return $this->maxNumberInCart; + } + + public function setMaxNumberInCart(int $maxNumberInCart): void + { + if ($maxNumberInCart < 0 || $maxNumberInCart < $this->minNumberInCart) { + throw new InvalidArgumentException(); + } + + $this->maxNumberInCart = $maxNumberInCart; + } + + public function getStock(): int + { + return $this->stock; + } + + public function setStock(int $stock): void + { + $this->stock = $stock; + } + + public function isHandleStock(): bool + { + return $this->handleStock; + } + + public function setHandleStock(bool $handleStock): void + { + $this->handleStock = $handleStock; + } + + public function isHandleStockInVariants(): bool + { + return $this->handleStockInVariants; + } + + public function setHandleStockInVariants(bool $handleStockInVariants): void + { + $this->handleStockInVariants = $handleStockInVariants; + } + + protected function getTableProductId(): string + { + $tableProductId = $this->getProductType() . '_' . $this->getProductId(); + if ($this->getFeVariant()) { + $tableProductId .= '_' . $this->getFeVariant()->getId(); + } + + return $tableProductId; + } + protected function calcGross(): void { if ($this->isNetPrice == false) { @@ -554,7 +616,7 @@ protected function calcTax(): void if ($this->isNetPrice == false) { $this->tax = ($this->gross / (1 + $this->getTaxClass()->getCalc())) * ($this->getTaxClass()->getCalc()); } else { - $this->tax = ($this->net * $this->getTaxClass()->getCalc()); + $this->tax = $this->net * $this->getTaxClass()->getCalc(); } } @@ -601,64 +663,4 @@ protected function reCalc(): void $this->calcTax(); $this->calcNet(); } - - public function getMinNumberInCart(): int - { - return $this->minNumberInCart; - } - - public function setMinNumberInCart(int $minNumberInCart): void - { - if ($minNumberInCart < 0 - || ($this->maxNumberInCart > 0 && $minNumberInCart > $this->maxNumberInCart) - ) { - throw new \InvalidArgumentException(); - } - - $this->minNumberInCart = $minNumberInCart; - } - - public function getMaxNumberInCart(): int - { - return $this->maxNumberInCart; - } - - public function setMaxNumberInCart(int $maxNumberInCart): void - { - if ($maxNumberInCart < 0 || $maxNumberInCart < $this->minNumberInCart) { - throw new \InvalidArgumentException(); - } - - $this->maxNumberInCart = $maxNumberInCart; - } - - public function getStock(): int - { - return $this->stock; - } - - public function setStock(int $stock): void - { - $this->stock = $stock; - } - - public function isHandleStock(): bool - { - return $this->handleStock; - } - - public function setHandleStock(bool $handleStock): void - { - $this->handleStock = $handleStock; - } - - public function isHandleStockInVariants(): bool - { - return $this->handleStockInVariants; - } - - public function setHandleStockInVariants(bool $handleStockInVariants): void - { - $this->handleStockInVariants = $handleStockInVariants; - } } diff --git a/Classes/Domain/Model/Cart/ProductInterface.php b/Classes/Domain/Model/Cart/ProductInterface.php index 0c636308..65c212de 100644 --- a/Classes/Domain/Model/Cart/ProductInterface.php +++ b/Classes/Domain/Model/Cart/ProductInterface.php @@ -105,10 +105,7 @@ public function getNet(): float; public function getTax(): float; - /** - * @return mixed - */ - public function getError(); + public function getError(): mixed; public function isVirtualProduct(): bool; diff --git a/Classes/Domain/Model/Cart/Service.php b/Classes/Domain/Model/Cart/Service.php index ab39b10c..dda84b5e 100644 --- a/Classes/Domain/Model/Cart/Service.php +++ b/Classes/Domain/Model/Cart/Service.php @@ -20,7 +20,8 @@ class Service implements ServiceInterface public function __construct( protected int $id, protected array $config = [] - ) {} + ) { + } public function getId(): int { @@ -133,7 +134,7 @@ public function getTaxes(): array $taxValue = $this->cart->translatePrice($extraTax); if ($extra->getExtraType() === 'each') { - $taxValue = $this->cart->getCount() * $taxValue; + $taxValue *= $this->cart->getCount(); } $taxes[] = [ @@ -150,11 +151,11 @@ public function getTaxClass(): TaxClass { $taxClass = null; - if ((int)$this->config['taxClassId'] > 0) { - return $this->cart->getTaxClass((int)$this->config['taxClassId']); + if ((int) $this->config['taxClassId'] > 0) { + return $this->cart->getTaxClass((int) $this->config['taxClassId']); } - if ((int)$this->config['taxClassId'] === -1) { + if ((int) $this->config['taxClassId'] === -1) { // assign lowest TaxClass foreach ($this->cart->getTaxClasses() as $cartTaxClass) { if ($taxClass === null || $taxClass->getCalc() > $cartTaxClass->getCalc()) { @@ -169,7 +170,7 @@ public function getTaxClass(): TaxClass } } - if ((int)$this->config['taxClassId'] === -2) { + if ((int) $this->config['taxClassId'] === -2) { $taxClass = new TaxClass( $this->id = -2, '0', @@ -196,18 +197,23 @@ public function getFallBackId(): ?int if (!isset($this->config['fallBackId'])) { return null; } - return (int)$this->config['fallBackId']; + + return (int) $this->config['fallBackId']; } public function isAvailable(): bool { if (isset($this->config['available'])) { - $availableFrom = $this->config['available']['from']; - if (isset($availableFrom) && $this->cart->getGross() < (float)$availableFrom) { + if (isset($this->config['available']['from']) + && is_numeric($this->config['available']['from']) + && $this->cart->getGross() < (float) $this->config['available']['from'] + ) { return false; } - $availableUntil = $this->config['available']['until']; - if (isset($availableUntil) && $this->cart->getGross() > (float)$availableUntil) { + if (isset($this->config['available']['until']) + && is_numeric($this->config['available']['until']) + && $this->cart->getGross() > (float) $this->config['available']['until'] + ) { return false; } } @@ -217,20 +223,15 @@ public function isAvailable(): bool public function isFree(): bool { - $freeFrom = $this->config['free']['from'] ?? null; $freeUntil = $this->config['free']['until'] ?? null; if ($freeFrom || $freeUntil) { - if ($freeFrom && $this->cart->getGross() < (float)$freeFrom) { - return false; - } - - if ($freeUntil && $this->cart->getGross() > (float)$freeUntil) { + if ($freeFrom && $this->cart->getGross() < (float) $freeFrom) { return false; } - return true; + return ! ($freeUntil && $this->cart->getGross() > (float) $freeUntil); } return false; @@ -238,12 +239,12 @@ public function isFree(): bool public function isBuyerEmailDisabled(): bool { - return (int)($this->config['preventBuyerEmail'] ?? 0) === 1; + return (int) ($this->config['preventBuyerEmail'] ?? 0) === 1; } public function isSellerEmailDisabled(): bool { - return (int)($this->config['preventSellerEmail'] ?? 0) === 1; + return (int) ($this->config['preventSellerEmail'] ?? 0) === 1; } protected function getExtra(): Extra @@ -267,7 +268,7 @@ protected function getExtra(): Extra return new Extra( 0, 0, - (float)$this->config['extra']['extra'], + (float) $this->config['extra']['extra'], $this->getTaxClass(), $this->cart->isNetCart(), $extraType, @@ -280,11 +281,11 @@ protected function getExtra(): Extra $extra = null; foreach ($this->config['extra'] as $extraKey => $extraValue) { - if (is_array($extraValue) && ((float)$extraValue['value'] <= (float)$conditionValue)) { + if (is_array($extraValue) && ((float) $extraValue['value'] <= (float) $conditionValue)) { $extra = new Extra( $extraKey, - (float)$extraValue['value'], - (float)$extraValue['extra'], + (float) $extraValue['value'], + (float) $extraValue['extra'], $this->getTaxClass(), $this->cart->isNetCart(), $extraType, @@ -299,7 +300,7 @@ protected function getExtra(): Extra return new Extra( 0, 0, - (float)$this->config['extra'], + (float) $this->config['extra'], $this->getTaxClass(), $this->cart->isNetCart(), '', @@ -307,10 +308,7 @@ protected function getExtra(): Extra ); } - /** - * @return float|int|null - */ - protected function getConditionValueFromCart(string $extraType) + protected function getConditionValueFromCart(string $extraType): null|float|int { return match ($extraType) { 'by_price' => $this->cart->getGross(), diff --git a/Classes/Domain/Model/Cart/TaxClass.php b/Classes/Domain/Model/Cart/TaxClass.php index 0cc0d897..38bf0b60 100644 --- a/Classes/Domain/Model/Cart/TaxClass.php +++ b/Classes/Domain/Model/Cart/TaxClass.php @@ -18,7 +18,8 @@ public function __construct( private string $value, private float $calc, private string $title - ) {} + ) { + } public function getId(): int { diff --git a/Classes/Domain/Model/Cart/TaxClassFactory.php b/Classes/Domain/Model/Cart/TaxClassFactory.php index e9f8573c..caae78cb 100644 --- a/Classes/Domain/Model/Cart/TaxClassFactory.php +++ b/Classes/Domain/Model/Cart/TaxClassFactory.php @@ -17,7 +17,8 @@ { public function __construct( private LoggerInterface $logger - ) {} + ) { + } public function getTaxClass(int $taxClassKey, array $taxClassValue): ?TaxClass { @@ -25,7 +26,7 @@ public function getTaxClass(int $taxClassKey, array $taxClassValue): ?TaxClass return new TaxClass( $taxClassKey, $taxClassValue['value'], - (float)$taxClassValue['calc'], + (float) $taxClassValue['calc'], $taxClassValue['name'] ); } diff --git a/Classes/Domain/Model/Coupon.php b/Classes/Domain/Model/Coupon.php index 6c305e8e..be474e60 100644 --- a/Classes/Domain/Model/Coupon.php +++ b/Classes/Domain/Model/Coupon.php @@ -33,7 +33,8 @@ public function __construct( protected string $couponType, protected float $discount, protected int $taxClassId - ) {} + ) { + } public function getTitle(): string { @@ -105,7 +106,7 @@ public function getNumberUsed(): int */ public function incNumberUsed(): void { - $this->numberUsed += 1; + $this->numberUsed++; } public function setNumberUsed(int $numberUsed): void diff --git a/Classes/Domain/Model/Order/AbstractAddress.php b/Classes/Domain/Model/Order/AbstractAddress.php index 8906247b..7f34295c 100755 --- a/Classes/Domain/Model/Order/AbstractAddress.php +++ b/Classes/Domain/Model/Order/AbstractAddress.php @@ -11,14 +11,14 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; +use TYPO3\CMS\Extbase\Attribute\ORM\Lazy; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy; -abstract class AbstractAddress extends AbstractEntity +abstract class AbstractAddress extends AbstractEntity implements AddressInterface { #[Lazy] - protected LazyLoadingProxy|Item|null $item = null; + protected null|Item|LazyLoadingProxy $item = null; protected string $title = ''; diff --git a/Classes/Domain/Model/Order/AbstractService.php b/Classes/Domain/Model/Order/AbstractService.php index 52afb128..dea67bff 100644 --- a/Classes/Domain/Model/Order/AbstractService.php +++ b/Classes/Domain/Model/Order/AbstractService.php @@ -11,25 +11,25 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; -use TYPO3\CMS\Extbase\Annotation\Validate; +use TYPO3\CMS\Extbase\Attribute\ORM\Lazy; +use TYPO3\CMS\Extbase\Attribute\Validate; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy; abstract class AbstractService extends AbstractEntity { #[Lazy] - protected LazyLoadingProxy|Item|null $item = null; + protected null|Item|LazyLoadingProxy $item = null; protected string $serviceCountry = ''; - #[Validate(['validator' => 'NotEmpty'])] - protected ?int $serviceId = null; + #[Validate(validator: 'NotEmpty')] + protected int $serviceId; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $name = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $status = 'open'; protected float $net = 0.0; @@ -38,7 +38,7 @@ abstract class AbstractService extends AbstractEntity protected ?TaxClass $taxClass = null; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $tax = 0.0; protected string $note = ''; @@ -90,7 +90,7 @@ public function setServiceCountry(string $serviceCountry): void $this->serviceCountry = $serviceCountry; } - public function getServiceId(): ?int + public function getServiceId(): int { return $this->serviceId; } diff --git a/Classes/Domain/Model/Order/AddressInterface.php b/Classes/Domain/Model/Order/AddressInterface.php new file mode 100644 index 00000000..a7b6e260 --- /dev/null +++ b/Classes/Domain/Model/Order/AddressInterface.php @@ -0,0 +1,92 @@ + 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $title, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $code, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $gross, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $net, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected TaxClass $taxClass, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $tax - ) {} + ) { + } public function getItem(): ?Item { diff --git a/Classes/Domain/Model/Order/Item.php b/Classes/Domain/Model/Order/Item.php index fc432306..7525bbcb 100644 --- a/Classes/Domain/Model/Order/Item.php +++ b/Classes/Domain/Model/Order/Item.php @@ -11,9 +11,10 @@ * LICENSE file that was distributed with this source code. */ +use DateTime; use Extcode\Cart\Domain\Model\FrontendUser; use Extcode\Cart\Property\Exception\ResetPropertyException; -use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; +use TYPO3\CMS\Extbase\Attribute\ORM\Lazy; use TYPO3\CMS\Extbase\Domain\Model\FileReference; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; @@ -26,15 +27,15 @@ class Item extends AbstractEntity protected string $orderNumber = ''; - protected ?\DateTime $orderDate = null; + protected ?DateTime $orderDate = null; protected string $invoiceNumber = ''; - protected ?\DateTime $invoiceDate = null; + protected ?DateTime $invoiceDate = null; protected string $deliveryNumber = ''; - protected ?\DateTime $deliveryDate = null; + protected ?DateTime $deliveryDate = null; protected bool $shippingSameAsBilling = false; @@ -112,7 +113,7 @@ class Item extends AbstractEntity */ protected ObjectStorage $deliveryPdfs; - protected \DateTime $crdate; + protected DateTime $crdate; protected bool $acceptTermsAndConditions = false; @@ -127,18 +128,6 @@ public function __construct() $this->initStorageObjects(); } - protected function initStorageObjects(): void - { - $this->products = new ObjectStorage(); - $this->discounts = new ObjectStorage(); - $this->taxClass = new ObjectStorage(); - $this->tax = new ObjectStorage(); - $this->totalTax = new ObjectStorage(); - $this->orderPdfs = new ObjectStorage(); - $this->invoicePdfs = new ObjectStorage(); - $this->deliveryPdfs = new ObjectStorage(); - } - public function setCartPid(int $cartPid): void { $this->cartPid = $cartPid; @@ -176,15 +165,16 @@ public function setOrderNumber(string $orderNumber): string throw new ResetPropertyException('Could not reset orderNumber', 1395306283); } } + return $this->orderNumber; } - public function getOrderDate(): ?\DateTime + public function getOrderDate(): ?DateTime { return $this->orderDate; } - public function setOrderDate(\DateTime $orderDate): void + public function setOrderDate(DateTime $orderDate): void { $this->orderDate = $orderDate; } @@ -206,15 +196,16 @@ public function setInvoiceNumber(string $invoiceNumber): string throw new ResetPropertyException('Could not reset invoiceNumber', 1395307266); } } + return $this->invoiceNumber; } - public function getInvoiceDate(): ?\DateTime + public function getInvoiceDate(): ?DateTime { return $this->invoiceDate; } - public function setInvoiceDate(\DateTime $invoiceDate): void + public function setInvoiceDate(DateTime $invoiceDate): void { $this->invoiceDate = $invoiceDate; } @@ -236,15 +227,16 @@ public function setDeliveryNumber(string $deliveryNumber): string throw new ResetPropertyException('Could not reset deliveryNumber', 1475061197); } } + return $this->deliveryNumber; } - public function getDeliveryDate(): ?\DateTime + public function getDeliveryDate(): ?DateTime { return $this->deliveryDate; } - public function setDeliveryDate(\DateTime $deliveryDate): void + public function setDeliveryDate(DateTime $deliveryDate): void { $this->deliveryDate = $deliveryDate; } @@ -612,12 +604,12 @@ public function setTotalTax(ObjectStorage $taxes): void $this->totalTax = $taxes; } - public function getCrdate(): ?\DateTime + public function getCrdate(): ?DateTime { return $this->crdate; } - public function setCrdate(\DateTime $crdate): void + public function setCrdate(DateTime $crdate): void { $this->crdate = $crdate; } @@ -675,4 +667,16 @@ public function setAdditional(array $additional): void { $this->additional = json_encode($additional); } + + protected function initStorageObjects(): void + { + $this->products = new ObjectStorage(); + $this->discounts = new ObjectStorage(); + $this->taxClass = new ObjectStorage(); + $this->tax = new ObjectStorage(); + $this->totalTax = new ObjectStorage(); + $this->orderPdfs = new ObjectStorage(); + $this->invoicePdfs = new ObjectStorage(); + $this->deliveryPdfs = new ObjectStorage(); + } } diff --git a/Classes/Domain/Model/Order/Payment.php b/Classes/Domain/Model/Order/Payment.php index eabff708..744f5264 100644 --- a/Classes/Domain/Model/Order/Payment.php +++ b/Classes/Domain/Model/Order/Payment.php @@ -11,7 +11,7 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; +use TYPO3\CMS\Extbase\Attribute\ORM\Lazy; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; class Payment extends AbstractService diff --git a/Classes/Domain/Model/Order/Product.php b/Classes/Domain/Model/Order/Product.php index 2d860ab7..f1129c94 100644 --- a/Classes/Domain/Model/Order/Product.php +++ b/Classes/Domain/Model/Order/Product.php @@ -11,8 +11,8 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; -use TYPO3\CMS\Extbase\Annotation\Validate; +use TYPO3\CMS\Extbase\Attribute\ORM\Lazy; +use TYPO3\CMS\Extbase\Attribute\Validate; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; @@ -20,37 +20,37 @@ class Product extends AbstractEntity { #[Lazy] - protected LazyLoadingProxy|Item $item; + protected Item|LazyLoadingProxy $item; protected int $productId = 0; protected string $productType = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $sku = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $title = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected int $count = 0; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $price = 0.0; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $discount = 0.0; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $gross = 0.0; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $net = 0.0; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected TaxClass $taxClass; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $tax = 0.0; protected string $additionalData = ''; @@ -70,11 +70,6 @@ public function __construct() $this->initStorageObjects(); } - protected function initStorageObjects(): void - { - $this->productAdditional = new ObjectStorage(); - } - public function getItem(): ?Item { if ($this->item instanceof LazyLoadingProxy) { @@ -243,4 +238,9 @@ public function setAdditional(array $additional): void { $this->additional = json_encode($additional); } + + protected function initStorageObjects(): void + { + $this->productAdditional = new ObjectStorage(); + } } diff --git a/Classes/Domain/Model/Order/ProductAdditional.php b/Classes/Domain/Model/Order/ProductAdditional.php index 78da1047..1304b55e 100644 --- a/Classes/Domain/Model/Order/ProductAdditional.php +++ b/Classes/Domain/Model/Order/ProductAdditional.php @@ -24,7 +24,8 @@ public function __construct( protected string $additionalKey, protected string $additionalValue, protected string $additionalData = '' - ) {} + ) { + } public function getAdditionalType(): string { diff --git a/Classes/Domain/Model/Order/Shipping.php b/Classes/Domain/Model/Order/Shipping.php index 39eadc9a..ea07b0bb 100644 --- a/Classes/Domain/Model/Order/Shipping.php +++ b/Classes/Domain/Model/Order/Shipping.php @@ -11,4 +11,6 @@ * LICENSE file that was distributed with this source code. */ -class Shipping extends AbstractService {} +class Shipping extends AbstractService +{ +} diff --git a/Classes/Domain/Model/Order/ShippingAddress.php b/Classes/Domain/Model/Order/ShippingAddress.php index f2061a70..d299e3c6 100644 --- a/Classes/Domain/Model/Order/ShippingAddress.php +++ b/Classes/Domain/Model/Order/ShippingAddress.php @@ -11,4 +11,6 @@ * LICENSE file that was distributed with this source code. */ -class ShippingAddress extends AbstractAddress {} +class ShippingAddress extends AbstractAddress +{ +} diff --git a/Classes/Domain/Model/Order/Tax.php b/Classes/Domain/Model/Order/Tax.php index 02091102..8ec52b21 100644 --- a/Classes/Domain/Model/Order/Tax.php +++ b/Classes/Domain/Model/Order/Tax.php @@ -11,17 +11,18 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\Validate; +use TYPO3\CMS\Extbase\Attribute\Validate; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; class Tax extends AbstractEntity { public function __construct( - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $tax, - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected TaxClass $taxClass - ) {} + ) { + } public function getTax(): float { diff --git a/Classes/Domain/Model/Order/TaxClass.php b/Classes/Domain/Model/Order/TaxClass.php index 87cbc680..8c41a88b 100644 --- a/Classes/Domain/Model/Order/TaxClass.php +++ b/Classes/Domain/Model/Order/TaxClass.php @@ -11,18 +11,18 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\Validate; +use TYPO3\CMS\Extbase\Attribute\Validate; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; class TaxClass extends AbstractEntity { - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $title = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $value = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected float $calc = 0.0; public function toArray(): array diff --git a/Classes/Domain/Model/Product/AbstractProduct.php b/Classes/Domain/Model/Product/AbstractProduct.php index 2787693d..4c403b08 100644 --- a/Classes/Domain/Model/Product/AbstractProduct.php +++ b/Classes/Domain/Model/Product/AbstractProduct.php @@ -10,15 +10,15 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Extbase\Annotation\Validate; +use TYPO3\CMS\Extbase\Attribute\Validate; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; abstract class AbstractProduct extends AbstractEntity { - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $sku = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[Validate(validator: 'NotEmpty')] protected string $title = ''; protected string $teaser = ''; diff --git a/Classes/Domain/Model/Product/CategoryTrait.php b/Classes/Domain/Model/Product/CategoryTrait.php index cc0df96b..88dd1ca0 100644 --- a/Classes/Domain/Model/Product/CategoryTrait.php +++ b/Classes/Domain/Model/Product/CategoryTrait.php @@ -14,7 +14,7 @@ use TYPO3\CMS\Extbase\Domain\Model\Category; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; -trait CategoryTrait +trait CategoryTrait // @phpstan-ignore trait.unused (provided for product extensions) { protected ?Category $category = null; diff --git a/Classes/Domain/Model/Product/FileAndImageTrait.php b/Classes/Domain/Model/Product/FileAndImageTrait.php index b5447e49..ff5ae5ba 100644 --- a/Classes/Domain/Model/Product/FileAndImageTrait.php +++ b/Classes/Domain/Model/Product/FileAndImageTrait.php @@ -13,7 +13,7 @@ use TYPO3\CMS\Extbase\Domain\Model\FileReference; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; -trait FileAndImageTrait +trait FileAndImageTrait // @phpstan-ignore trait.unused (provided for product extensions) { /** * @var ObjectStorage diff --git a/Classes/Domain/Model/Product/MeasureTrait.php b/Classes/Domain/Model/Product/MeasureTrait.php index fb1931f7..7697c321 100644 --- a/Classes/Domain/Model/Product/MeasureTrait.php +++ b/Classes/Domain/Model/Product/MeasureTrait.php @@ -1,5 +1,7 @@ measureUnits as $measureUnitGroup) { if ( - isset($measureUnitGroup[$this->priceMeasureUnit]) - && isset($measureUnitGroup[$this->basePriceMeasureUnit]) + isset($measureUnitGroup[$this->priceMeasureUnit], $measureUnitGroup[$this->basePriceMeasureUnit]) ) { return true; } @@ -105,10 +106,10 @@ public function getMeasureUnitFactor(): float foreach ($this->measureUnits as $measureUnit) { if (array_key_exists($this->priceMeasureUnit, $measureUnit)) { - $factor = $factor / ($this->priceMeasure / $measureUnit[$this->priceMeasureUnit]); + $factor /= ($this->priceMeasure / $measureUnit[$this->priceMeasureUnit]); } if (array_key_exists($this->basePriceMeasureUnit, $measureUnit)) { - $factor = $factor * (1.0 / $measureUnit[$this->basePriceMeasureUnit]); + $factor *= (1.0 / $measureUnit[$this->basePriceMeasureUnit]); } } diff --git a/Classes/Domain/Model/Product/ServiceAttributeTrait.php b/Classes/Domain/Model/Product/ServiceAttributeTrait.php index cf1face1..ab931e1b 100644 --- a/Classes/Domain/Model/Product/ServiceAttributeTrait.php +++ b/Classes/Domain/Model/Product/ServiceAttributeTrait.php @@ -1,5 +1,7 @@ diff --git a/Classes/Domain/Model/Tag.php b/Classes/Domain/Model/Tag.php index fe0b6bac..786447ce 100644 --- a/Classes/Domain/Model/Tag.php +++ b/Classes/Domain/Model/Tag.php @@ -15,7 +15,10 @@ class Tag extends AbstractEntity { - public function __construct(protected string $title) {} + public function __construct( + protected string $title + ) { + } public function getTitle(): string { diff --git a/Classes/Domain/Repository/CartRepository.php b/Classes/Domain/Repository/CartRepository.php index 537f0e7f..6b55cf70 100644 --- a/Classes/Domain/Repository/CartRepository.php +++ b/Classes/Domain/Repository/CartRepository.php @@ -13,4 +13,6 @@ use TYPO3\CMS\Extbase\Persistence\Repository; -class CartRepository extends Repository {} +class CartRepository extends Repository +{ +} diff --git a/Classes/Domain/Repository/CouponRepository.php b/Classes/Domain/Repository/CouponRepository.php index 2449bd19..619f89d9 100644 --- a/Classes/Domain/Repository/CouponRepository.php +++ b/Classes/Domain/Repository/CouponRepository.php @@ -13,4 +13,6 @@ use TYPO3\CMS\Extbase\Persistence\Repository; -class CouponRepository extends Repository {} +class CouponRepository extends Repository +{ +} diff --git a/Classes/Domain/Repository/FrontendUserGroupRepository.php b/Classes/Domain/Repository/FrontendUserGroupRepository.php index d62df719..d75e68a8 100644 --- a/Classes/Domain/Repository/FrontendUserGroupRepository.php +++ b/Classes/Domain/Repository/FrontendUserGroupRepository.php @@ -13,4 +13,6 @@ use TYPO3\CMS\Extbase\Persistence\Repository; -class FrontendUserGroupRepository extends Repository {} +class FrontendUserGroupRepository extends Repository +{ +} diff --git a/Classes/Domain/Repository/FrontendUserRepository.php b/Classes/Domain/Repository/FrontendUserRepository.php index 467b1097..8c4edc87 100644 --- a/Classes/Domain/Repository/FrontendUserRepository.php +++ b/Classes/Domain/Repository/FrontendUserRepository.php @@ -13,4 +13,6 @@ use TYPO3\CMS\Extbase\Persistence\Repository; -class FrontendUserRepository extends Repository {} +class FrontendUserRepository extends Repository +{ +} diff --git a/Classes/Domain/Repository/Order/BillingAddressRepository.php b/Classes/Domain/Repository/Order/BillingAddressRepository.php index e97812ce..b048447e 100644 --- a/Classes/Domain/Repository/Order/BillingAddressRepository.php +++ b/Classes/Domain/Repository/Order/BillingAddressRepository.php @@ -1,5 +1,7 @@ createQuery(); @@ -82,19 +82,19 @@ protected function getFilterConstraints(array $searchArguments, QueryInterface $ $and[] = $query->like('orderNumber', $value); break; case 'orderDateStart': - $and[] = $query->greaterThan('orderDate', strtotime((string)$value)); + $and[] = $query->greaterThan('orderDate', strtotime((string) $value)); break; case 'orderDateEnd': - $and[] = $query->lessThan('orderDate', strtotime((string)$value) + 86400); + $and[] = $query->lessThan('orderDate', strtotime((string) $value) + 86400); break; case 'invoiceNumber': $and[] = $query->like('invoiceNumber', $value); break; case 'invoiceDateStart': - $and[] = $query->greaterThan('invoiceDate', strtotime((string)$value)); + $and[] = $query->greaterThan('invoiceDate', strtotime((string) $value)); break; case 'invoiceDateEnd': - $and[] = $query->lessThan('invoiceDate', strtotime((string)$value) + 86400); + $and[] = $query->lessThan('invoiceDate', strtotime((string) $value) + 86400); break; case 'paymentStatus': if ($value !== 'all') { diff --git a/Classes/Domain/Repository/Order/PaymentRepository.php b/Classes/Domain/Repository/Order/PaymentRepository.php index e26131d4..3bc01d1f 100644 --- a/Classes/Domain/Repository/Order/PaymentRepository.php +++ b/Classes/Domain/Repository/Order/PaymentRepository.php @@ -1,5 +1,7 @@ $value) { + foreach ((array) $arguments['filter'] as $field => $value) { if ($field === 'start' && !empty($value)) { - $and[] = $query->greaterThan('crdate', strtotime((string)$value)); + $and[] = $query->greaterThan('crdate', strtotime((string) $value)); } elseif ($field === 'stop' && !empty($value)) { - $and[] = $query->lessThan('crdate', strtotime((string)$value)); + $and[] = $query->lessThan('crdate', strtotime((string) $value)); } } } - $constraint = $query->logicalAnd($and); + $constraint = $query->logicalAnd(...$and); $query->matching($constraint); return $query->execute(); diff --git a/Classes/Domain/Repository/Order/ProductRepository.php b/Classes/Domain/Repository/Order/ProductRepository.php index 05f81e25..8d0a7884 100644 --- a/Classes/Domain/Repository/Order/ProductRepository.php +++ b/Classes/Domain/Repository/Order/ProductRepository.php @@ -1,5 +1,7 @@ createQuery(); @@ -38,11 +38,11 @@ protected function getFilterConstraints(array $searchArguments, QueryInterface $ $and = []; if (isset($searchArguments['filter'])) { - foreach ((array)$searchArguments['filter'] as $field => $value) { + foreach ((array) $searchArguments['filter'] as $field => $value) { if ($field == 'start' && !empty($value)) { - $and[] = $query->greaterThan('crdate', strtotime((string)$value)); + $and[] = $query->greaterThan('crdate', strtotime((string) $value)); } elseif ($field == 'stop' && !empty($value)) { - $and[] = $query->lessThan('crdate', strtotime((string)$value)); + $and[] = $query->lessThan('crdate', strtotime((string) $value)); } } } diff --git a/Classes/Domain/Repository/Order/ShippingAddressRepository.php b/Classes/Domain/Repository/Order/ShippingAddressRepository.php index 53fa7676..e360b576 100644 --- a/Classes/Domain/Repository/Order/ShippingAddressRepository.php +++ b/Classes/Domain/Repository/Order/ShippingAddressRepository.php @@ -1,5 +1,7 @@ result; } + /** + * Adds the given validator for validation of the specified property. + */ + public function addPropertyValidator(string $propertyName, ValidatorInterface $validator): void + { + if (!isset($this->propertyValidators[$propertyName])) { + $this->propertyValidators[$propertyName] = new SplObjectStorage(); + } + $this->propertyValidators[$propertyName]->offsetSet($validator); + } + + public function countPropertyValidators(): int + { + $count = 0; + foreach ($this->propertyValidators as $propertyValidators) { + $count += $propertyValidators->count(); + } + + return $count; + } + /** * Load the property value to be used for validation. * In case the object is a doctrine proxy, we need to load the real instance first. @@ -61,7 +86,7 @@ protected function getPropertyValue(object $object, string $propertyName): mixed * Checks if the specified property of the given object is valid, and adds * found errors to the $messages object. */ - protected function checkProperty(mixed $value, \Traversable $validators, string $propertyName): void + protected function checkProperty(mixed $value, Traversable $validators, string $propertyName): void { $result = null; foreach ($validators as $validator) { @@ -69,7 +94,7 @@ protected function checkProperty(mixed $value, \Traversable $validators, string $validator->setValidatedInstancesContainer($this->validatedInstancesContainer); } - /** + /* * File upload validation. * * If a $_FILES array is found in the request data, @@ -77,10 +102,7 @@ protected function checkProperty(mixed $value, \Traversable $validators, string * single file. */ if ( - isset($value[0]['name']) - && isset($value[0]['type']) - && isset($value[0]['tmp_name']) - && isset($value[0]['size']) + isset($value[0]['name'], $value[0]['type'], $value[0]['tmp_name'], $value[0]['size']) ) { foreach ($value as $file) { $currentResult = $validator->validate($file); @@ -119,37 +141,17 @@ protected function isValid(mixed $object): void } } - /** - * Adds the given validator for validation of the specified property. - */ - public function addPropertyValidator(string $propertyName, ValidatorInterface $validator): void - { - if (!isset($this->propertyValidators[$propertyName])) { - $this->propertyValidators[$propertyName] = new \SplObjectStorage(); - } - $this->propertyValidators[$propertyName]->attach($validator); - } - protected function isValidatedAlready(object $object): bool { if ($this->validatedInstancesContainer === null) { - $this->validatedInstancesContainer = new \SplObjectStorage(); + $this->validatedInstancesContainer = new SplObjectStorage(); } - if ($this->validatedInstancesContainer->contains($object)) { + if ($this->validatedInstancesContainer->offsetExists($object)) { return true; } - $this->validatedInstancesContainer->attach($object); + $this->validatedInstancesContainer->offsetSet($object); return false; } - - public function countPropertyValidators(): int - { - $count = 0; - foreach ($this->propertyValidators as $propertyValidators) { - $count += $propertyValidators->count(); - } - return $count; - } } diff --git a/Classes/Event/Cart/BeforeShowCartEvent.php b/Classes/Event/Cart/BeforeShowCartEvent.php index 88bc36d9..43ee1e73 100644 --- a/Classes/Event/Cart/BeforeShowCartEvent.php +++ b/Classes/Event/Cart/BeforeShowCartEvent.php @@ -12,9 +12,8 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; -use Extcode\Cart\Domain\Model\Order\BillingAddress; +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Extcode\Cart\Domain\Model\Order\Item; -use Extcode\Cart\Domain\Model\Order\ShippingAddress; use Psr\EventDispatcher\StoppableEventInterface; final class BeforeShowCartEvent implements StoppableEventInterface @@ -24,9 +23,10 @@ final class BeforeShowCartEvent implements StoppableEventInterface public function __construct( private Cart $cart, private ?Item $orderItem = null, - private ?BillingAddress $billingAddress = null, - private ?ShippingAddress $shippingAddress = null - ) {} + private ?AddressInterface $billingAddress = null, + private ?AddressInterface $shippingAddress = null + ) { + } public function getCart(): Cart { @@ -48,22 +48,22 @@ public function setOrderItem(Item $orderItem): void $this->orderItem = $orderItem; } - public function getBillingAddress(): ?BillingAddress + public function getBillingAddress(): ?AddressInterface { return $this->billingAddress; } - public function setBillingAddress(BillingAddress $billingAddress): void + public function setBillingAddress(AddressInterface $billingAddress): void { $this->billingAddress = $billingAddress; } - public function getShippingAddress(): ?ShippingAddress + public function getShippingAddress(): ?AddressInterface { return $this->shippingAddress; } - public function setShippingAddress(ShippingAddress $shippingAddress): void + public function setShippingAddress(AddressInterface $shippingAddress): void { $this->shippingAddress = $shippingAddress; } diff --git a/Classes/Event/Cart/UpdateCountryEvent.php b/Classes/Event/Cart/UpdateCountryEvent.php index 92bb889b..0a53ba21 100644 --- a/Classes/Event/Cart/UpdateCountryEvent.php +++ b/Classes/Event/Cart/UpdateCountryEvent.php @@ -12,21 +12,22 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; final readonly class UpdateCountryEvent implements UpdateCountryEventInterface { public function __construct( private Cart $cart, - private Request $request - ) {} + private RequestInterface $request + ) { + } public function getCart(): Cart { return $this->cart; } - public function getRequest(): Request + public function getRequest(): RequestInterface { return $this->request; } diff --git a/Classes/Event/Cart/UpdateCountryEventInterface.php b/Classes/Event/Cart/UpdateCountryEventInterface.php index 3fca882c..281d2495 100644 --- a/Classes/Event/Cart/UpdateCountryEventInterface.php +++ b/Classes/Event/Cart/UpdateCountryEventInterface.php @@ -1,15 +1,17 @@ cart; } - public function getRequest(): Request + public function getRequest(): RequestInterface { return $this->request; } diff --git a/Classes/Event/Cart/UpdateCurrencyEventInterface.php b/Classes/Event/Cart/UpdateCurrencyEventInterface.php index df64be90..ae79751a 100644 --- a/Classes/Event/Cart/UpdateCurrencyEventInterface.php +++ b/Classes/Event/Cart/UpdateCurrencyEventInterface.php @@ -1,17 +1,19 @@ cart; } - public function getProduct(): Product + public function getProduct(): ProductInterface { return $this->product; } diff --git a/Classes/Event/CheckProductAvailabilityEventInterface.php b/Classes/Event/CheckProductAvailabilityEventInterface.php index b57bdaef..7ae61422 100644 --- a/Classes/Event/CheckProductAvailabilityEventInterface.php +++ b/Classes/Event/CheckProductAvailabilityEventInterface.php @@ -12,16 +12,21 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; -use Extcode\Cart\Domain\Model\Cart\Product; +use Extcode\Cart\Domain\Model\Cart\ProductInterface; use TYPO3\CMS\Core\Messaging\FlashMessage; interface CheckProductAvailabilityEventInterface { - public function __construct(Cart $cart, Product $product, $quantity, string $mode = 'update'); + public function __construct( + Cart $cart, + ProductInterface $product, + $quantity, + string $mode = 'update' + ); public function getCart(): Cart; - public function getProduct(): Product; + public function getProduct(): ProductInterface; public function getQuantity(); diff --git a/Classes/Event/Form/AddToCartFinisherEvent.php b/Classes/Event/Form/AddToCartFinisherEvent.php index 2df34ff1..8dcf8ec5 100644 --- a/Classes/Event/Form/AddToCartFinisherEvent.php +++ b/Classes/Event/Form/AddToCartFinisherEvent.php @@ -1,5 +1,7 @@ settings = $settings; } + /** + * @return int<0, max> + */ public function getStoragePid(): int { - if (!isset($this->settings['settings']['order']['pid'])) { - return 0; + $orderPid = (int) ($this->settings['settings']['order']['pid'] ?? 0); + + if ($orderPid < 0) { + $orderPid = 0; } - return (int)$this->settings['settings']['order']['pid']; + return $orderPid; } public function setPropagationStopped(bool $isPropagationStopped): void diff --git a/Classes/Event/Order/StockEvent.php b/Classes/Event/Order/StockEvent.php index 46ad18d5..b9d0cef1 100644 --- a/Classes/Event/Order/StockEvent.php +++ b/Classes/Event/Order/StockEvent.php @@ -23,7 +23,8 @@ public function __construct( private readonly Cart $cart, private readonly OrderItem $orderItem, private array $settings = [] - ) {} + ) { + } public function getCart(): Cart { diff --git a/Classes/Event/Order/UpdateServiceEvent.php b/Classes/Event/Order/UpdateServiceEvent.php index e72f2769..4331f7c8 100644 --- a/Classes/Event/Order/UpdateServiceEvent.php +++ b/Classes/Event/Order/UpdateServiceEvent.php @@ -20,7 +20,8 @@ final class UpdateServiceEvent implements StoppableEventInterface public function __construct( private readonly AbstractService $service - ) {} + ) { + } public function getService(): AbstractService { diff --git a/Classes/Event/ProcessOrderCheckStockEvent.php b/Classes/Event/ProcessOrderCheckStockEvent.php index 6a86fb4a..414efb11 100644 --- a/Classes/Event/ProcessOrderCheckStockEvent.php +++ b/Classes/Event/ProcessOrderCheckStockEvent.php @@ -16,16 +16,17 @@ final class ProcessOrderCheckStockEvent { - private bool $everyProductAvailable = true; - /** * @var FlashMessage[] */ protected array $insufficientStockMessages = []; + private bool $everyProductAvailable = true; + public function __construct( private readonly Cart $cart - ) {} + ) { + } public function getCart(): Cart { diff --git a/Classes/Event/ProcessOrderCreateEvent.php b/Classes/Event/ProcessOrderCreateEvent.php index 51567958..5b5b5ac7 100644 --- a/Classes/Event/ProcessOrderCreateEvent.php +++ b/Classes/Event/ProcessOrderCreateEvent.php @@ -20,7 +20,8 @@ public function __construct( private readonly Cart $cart, private readonly OrderItem $orderItem, private array $settings = [] - ) {} + ) { + } public function getCart(): Cart { diff --git a/Classes/Event/ProcessOrderCreateEventInterface.php b/Classes/Event/ProcessOrderCreateEventInterface.php index 644daef9..14ab0afd 100644 --- a/Classes/Event/ProcessOrderCreateEventInterface.php +++ b/Classes/Event/ProcessOrderCreateEventInterface.php @@ -13,4 +13,6 @@ use Extcode\Cart\Event\Order\EventInterface; -interface ProcessOrderCreateEventInterface extends EventInterface {} +interface ProcessOrderCreateEventInterface extends EventInterface +{ +} diff --git a/Classes/Event/RetrieveProductsFromRequestEvent.php b/Classes/Event/RetrieveProductsFromRequestEvent.php index b296b4b6..75131321 100644 --- a/Classes/Event/RetrieveProductsFromRequestEvent.php +++ b/Classes/Event/RetrieveProductsFromRequestEvent.php @@ -14,7 +14,7 @@ use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Cart\Product; use TYPO3\CMS\Core\Messaging\FlashMessage; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; final class RetrieveProductsFromRequestEvent implements RetrieveProductsFromRequestEventInterface { @@ -31,16 +31,17 @@ final class RetrieveProductsFromRequestEvent implements RetrieveProductsFromRequ private array $products = []; public function __construct( - private readonly Request $request, + private readonly RequestInterface $request, private readonly Cart $cart - ) {} + ) { + } public function getCart(): Cart { return $this->cart; } - public function getRequest(): Request + public function getRequest(): RequestInterface { return $this->request; } diff --git a/Classes/Event/RetrieveProductsFromRequestEventInterface.php b/Classes/Event/RetrieveProductsFromRequestEventInterface.php index 210e0075..7424af71 100644 --- a/Classes/Event/RetrieveProductsFromRequestEventInterface.php +++ b/Classes/Event/RetrieveProductsFromRequestEventInterface.php @@ -13,15 +13,15 @@ use Extcode\Cart\Domain\Model\Cart\Cart; use Psr\EventDispatcher\StoppableEventInterface; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; interface RetrieveProductsFromRequestEventInterface extends StoppableEventInterface { - public function __construct(Request $request, Cart $cart); + public function __construct(RequestInterface $request, Cart $cart); public function getCart(): Cart; - public function getRequest(): Request; + public function getRequest(): RequestInterface; public function getProducts(): array; diff --git a/Classes/Event/Session/AfterRestoreAddressEvent.php b/Classes/Event/Session/AfterRestoreAddressEvent.php index bac93f87..418a0c4b 100644 --- a/Classes/Event/Session/AfterRestoreAddressEvent.php +++ b/Classes/Event/Session/AfterRestoreAddressEvent.php @@ -11,21 +11,24 @@ * LICENSE file that was distributed with this source code. */ -use Extcode\Cart\Domain\Model\Order\AbstractAddress; +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Psr\EventDispatcher\StoppableEventInterface; final class AfterRestoreAddressEvent implements StoppableEventInterface { private bool $isPropagationStopped = false; - public function __construct(private AbstractAddress $address) {} + public function __construct( + private AddressInterface $address + ) { + } - public function getAddress(): AbstractAddress + public function getAddress(): AddressInterface { return $this->address; } - public function setCart(AbstractAddress $address): void + public function setCart(AddressInterface $address): void { $this->address = $address; } diff --git a/Classes/Event/Session/AfterRestoreCartEvent.php b/Classes/Event/Session/AfterRestoreCartEvent.php index 74b4321b..8b9e39cc 100644 --- a/Classes/Event/Session/AfterRestoreCartEvent.php +++ b/Classes/Event/Session/AfterRestoreCartEvent.php @@ -18,7 +18,10 @@ final class AfterRestoreCartEvent implements StoppableEventInterface { private bool $isPropagationStopped = false; - public function __construct(private Cart $cart) {} + public function __construct( + private Cart $cart + ) { + } public function getCart(): Cart { diff --git a/Classes/Event/Session/BeforeWriteAddressEvent.php b/Classes/Event/Session/BeforeWriteAddressEvent.php index 13972bb4..66fb2e20 100644 --- a/Classes/Event/Session/BeforeWriteAddressEvent.php +++ b/Classes/Event/Session/BeforeWriteAddressEvent.php @@ -11,21 +11,24 @@ * LICENSE file that was distributed with this source code. */ -use Extcode\Cart\Domain\Model\Order\AbstractAddress; +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Psr\EventDispatcher\StoppableEventInterface; final class BeforeWriteAddressEvent implements StoppableEventInterface { private bool $isPropagationStopped = false; - public function __construct(private AbstractAddress $address) {} + public function __construct( + private AddressInterface $address + ) { + } - public function getAddress(): AbstractAddress + public function getAddress(): AddressInterface { return $this->address; } - public function setCart(AbstractAddress $address): void + public function setCart(AddressInterface $address): void { $this->address = $address; } diff --git a/Classes/Event/Session/BeforeWriteCartEvent.php b/Classes/Event/Session/BeforeWriteCartEvent.php index 3f3bd955..a2a3545a 100644 --- a/Classes/Event/Session/BeforeWriteCartEvent.php +++ b/Classes/Event/Session/BeforeWriteCartEvent.php @@ -18,7 +18,10 @@ final class BeforeWriteCartEvent implements StoppableEventInterface { private bool $isPropagationStopped = false; - public function __construct(private Cart $cart) {} + public function __construct( + private Cart $cart + ) { + } public function getCart(): Cart { diff --git a/Classes/Event/Template/Components/ModifyButtonBarEvent.php b/Classes/Event/Template/Components/ModifyButtonBarEvent.php index f024b383..9dddf3fa 100644 --- a/Classes/Event/Template/Components/ModifyButtonBarEvent.php +++ b/Classes/Event/Template/Components/ModifyButtonBarEvent.php @@ -23,7 +23,8 @@ public function __construct( private readonly array $settings, private readonly array $searchArguments, private readonly ?Item $orderItem = null, - ) {} + ) { + } public function getRequest(): RequestInterface { diff --git a/Classes/Event/Template/Components/ModifyModuleTemplateEvent.php b/Classes/Event/Template/Components/ModifyModuleTemplateEvent.php index e88fe160..97908d19 100644 --- a/Classes/Event/Template/Components/ModifyModuleTemplateEvent.php +++ b/Classes/Event/Template/Components/ModifyModuleTemplateEvent.php @@ -20,7 +20,8 @@ public function __construct( private readonly RequestInterface $request, private readonly array $settings, private readonly ModuleTemplate $moduleTemplate, - ) {} + ) { + } public function getRequest(): RequestInterface { diff --git a/Classes/Event/View/ModifyViewEvent.php b/Classes/Event/View/ModifyViewEvent.php index 1d2a00f1..b1430dff 100644 --- a/Classes/Event/View/ModifyViewEvent.php +++ b/Classes/Event/View/ModifyViewEvent.php @@ -20,7 +20,8 @@ public function __construct( private readonly RequestInterface $request, private readonly array $settings, private readonly ViewInterface $view, - ) {} + ) { + } public function getRequest(): RequestInterface { diff --git a/Classes/EventListener/Cart/UpdateCurrency.php b/Classes/EventListener/Cart/UpdateCurrency.php index d661eb1f..86b182a1 100644 --- a/Classes/EventListener/Cart/UpdateCurrency.php +++ b/Classes/EventListener/Cart/UpdateCurrency.php @@ -36,7 +36,7 @@ public function __invoke(UpdateCurrencyEvent $event): void ); $cart->setCurrencyTranslation( - (float)($settings['options'][$currencyConfigId]['translation']) + (float) ($settings['options'][$currencyConfigId]['translation']) ); } @@ -45,10 +45,10 @@ public function __invoke(UpdateCurrencyEvent $event): void protected function getCurrencyConfigId(string $currencyCode, array $currencyOptions): int { - if (strlen($currencyCode) === 3) { + if (mb_strlen($currencyCode) === 3) { foreach ($currencyOptions as $currencyOptionId => $currencyOption) { if (is_array($currencyOption) && $currencyOption['code'] === $currencyCode) { - return (int)$currencyOptionId; + return (int) $currencyOptionId; } } } diff --git a/Classes/EventListener/Mail/AttachmentFromOrderItem.php b/Classes/EventListener/Mail/AttachmentFromOrderItem.php index 235404d2..1a9c89f6 100644 --- a/Classes/EventListener/Mail/AttachmentFromOrderItem.php +++ b/Classes/EventListener/Mail/AttachmentFromOrderItem.php @@ -44,7 +44,7 @@ public function __invoke(AttachmentEvent $event): void if ($pdfData !== '1' && $pdfData !== 'true') { continue; } - $getter = 'get' . ucfirst((string)$pdfType) . 'Pdfs'; + $getter = 'get' . ucfirst((string) $pdfType) . 'Pdfs'; $pdfs = $orderItem->$getter(); if ($pdfs && ($pdfs instanceof ObjectStorage)) { $documents = $pdfs->toArray(); diff --git a/Classes/EventListener/Order/Create/DeliveryNumber.php b/Classes/EventListener/Order/Create/DeliveryNumber.php index b81b9c56..67f21868 100644 --- a/Classes/EventListener/Order/Create/DeliveryNumber.php +++ b/Classes/EventListener/Order/Create/DeliveryNumber.php @@ -11,15 +11,11 @@ * LICENSE file that was distributed with this source code. */ +use DateTime; use Extcode\Cart\Event\Order\NumberGeneratorEventInterface; class DeliveryNumber extends Number { - protected function getRegistryName(NumberGeneratorEventInterface $event): string - { - return 'lastDelivery' . '_' . $event->getOrderItem()->getCartPid(); - } - public function __invoke(NumberGeneratorEventInterface $event): void { $onlyGenerateNumberOfType = $event->getOnlyGenerateNumberOfType(); @@ -30,10 +26,15 @@ public function __invoke(NumberGeneratorEventInterface $event): void $orderItem = $event->getOrderItem(); $orderItem->setDeliveryNumber($this->generateNumber($event)); - $orderItem->setDeliveryDate(new \DateTime()); + $orderItem->setDeliveryDate(new DateTime()); $this->orderItemRepository->update($orderItem); $this->persistenceManager->persistAll(); } + + protected function getRegistryName(NumberGeneratorEventInterface $event): string + { + return 'lastDelivery_' . $event->getOrderItem()->getCartPid(); + } } diff --git a/Classes/EventListener/Order/Create/InvoiceNumber.php b/Classes/EventListener/Order/Create/InvoiceNumber.php index a6dfcd7b..a7d35da4 100644 --- a/Classes/EventListener/Order/Create/InvoiceNumber.php +++ b/Classes/EventListener/Order/Create/InvoiceNumber.php @@ -11,15 +11,11 @@ * LICENSE file that was distributed with this source code. */ +use DateTime; use Extcode\Cart\Event\Order\NumberGeneratorEventInterface; class InvoiceNumber extends Number { - protected function getRegistryName(NumberGeneratorEventInterface $event): string - { - return 'lastInvoice' . '_' . $event->getOrderItem()->getCartPid(); - } - public function __invoke(NumberGeneratorEventInterface $event): void { $onlyGenerateNumberOfType = $event->getOnlyGenerateNumberOfType(); @@ -30,10 +26,15 @@ public function __invoke(NumberGeneratorEventInterface $event): void $orderItem = $event->getOrderItem(); $orderItem->setInvoiceNumber($this->generateNumber($event)); - $orderItem->setInvoiceDate(new \DateTime()); + $orderItem->setInvoiceDate(new DateTime()); $this->orderItemRepository->update($orderItem); $this->persistenceManager->persistAll(); } + + protected function getRegistryName(NumberGeneratorEventInterface $event): string + { + return 'lastInvoice_' . $event->getOrderItem()->getCartPid(); + } } diff --git a/Classes/EventListener/Order/Create/Number.php b/Classes/EventListener/Order/Create/Number.php index ba1727c4..e3f8d07c 100644 --- a/Classes/EventListener/Order/Create/Number.php +++ b/Classes/EventListener/Order/Create/Number.php @@ -19,26 +19,17 @@ abstract class Number { - protected PersistenceManager $persistenceManager; - - protected OrderItemRepository $orderItemRepository; - - protected array $options; - - abstract protected function getRegistryName(NumberGeneratorEventInterface $event): string; - - abstract public function __invoke(NumberGeneratorEventInterface $event): void; - public function __construct( - PersistenceManager $persistenceManager, - OrderItemRepository $orderItemRepository, - array $options = [] + protected PersistenceManager $persistenceManager, + protected OrderItemRepository $orderItemRepository, + protected array $options = [] ) { - $this->persistenceManager = $persistenceManager; - $this->orderItemRepository = $orderItemRepository; - $this->options = $options; } + abstract public function __invoke(NumberGeneratorEventInterface $event): void; + + abstract protected function getRegistryName(NumberGeneratorEventInterface $event): string; + protected function generateNumber(NumberGeneratorEventInterface $event): string { $registry = GeneralUtility::makeInstance(Registry::class); @@ -48,12 +39,13 @@ protected function generateNumber(NumberGeneratorEventInterface $event): string $registry->set('tx_cart', $this->getRegistryName($event), $numberInRegistry); $format = $this->options['format'] ?? '%d'; - $numberInRegistryWithOffset = $numberInRegistry + (int)($this->options['offset'] ?? 0); + $numberInRegistryWithOffset = $numberInRegistry + (int) ($this->options['offset'] ?? 0); + $number = sprintf($format, $numberInRegistryWithOffset); return implode('', [ - $this->options['prefix'] ?? '', - sprintf($format, $numberInRegistryWithOffset), - $this->options['suffix'] ?? '', + is_string($this->options['prefix']) ? $this->options['prefix'] : '', + $number, + is_string($this->options['suffix']) ? $this->options['suffix'] : '', ]); } } diff --git a/Classes/EventListener/Order/Create/Order.php b/Classes/EventListener/Order/Create/Order.php index ef6549c4..5504641d 100644 --- a/Classes/EventListener/Order/Create/Order.php +++ b/Classes/EventListener/Order/Create/Order.php @@ -21,7 +21,8 @@ class Order public function __construct( private readonly EventDispatcherInterface $eventDispatcher, private readonly PersistenceManager $persistenceManager - ) {} + ) { + } public function __invoke(EventInterface $event): void { diff --git a/Classes/EventListener/Order/Create/OrderNumber.php b/Classes/EventListener/Order/Create/OrderNumber.php index b7eb6f4e..d29d56ff 100644 --- a/Classes/EventListener/Order/Create/OrderNumber.php +++ b/Classes/EventListener/Order/Create/OrderNumber.php @@ -11,15 +11,11 @@ * LICENSE file that was distributed with this source code. */ +use DateTime; use Extcode\Cart\Event\Order\NumberGeneratorEventInterface; class OrderNumber extends Number { - protected function getRegistryName(NumberGeneratorEventInterface $event): string - { - return 'lastOrder' . '_' . $event->getOrderItem()->getCartPid(); - } - public function __invoke(NumberGeneratorEventInterface $event): void { $onlyGenerateNumberOfType = $event->getOnlyGenerateNumberOfType(); @@ -31,7 +27,7 @@ public function __invoke(NumberGeneratorEventInterface $event): void $orderItem = $event->getOrderItem(); $orderItem->setOrderNumber($this->generateNumber($event)); - $orderItem->setOrderDate(new \DateTime()); + $orderItem->setOrderDate(new DateTime()); $this->orderItemRepository->update($orderItem); @@ -40,4 +36,9 @@ public function __invoke(NumberGeneratorEventInterface $event): void $cart->setOrderId($orderItem->getUid()); $cart->setOrderNumber($orderItem->getOrderNumber()); } + + protected function getRegistryName(NumberGeneratorEventInterface $event): string + { + return 'lastOrder_' . $event->getOrderItem()->getCartPid(); + } } diff --git a/Classes/EventListener/Order/Create/PersistOrder/Coupons.php b/Classes/EventListener/Order/Create/PersistOrder/Coupons.php index 698afe1e..7940acc8 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Coupons.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Coupons.php @@ -27,7 +27,8 @@ public function __construct( private readonly ItemRepository $itemRepository, private readonly DiscountRepository $discountRepository, private readonly CouponRepository $couponRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { diff --git a/Classes/EventListener/Order/Create/PersistOrder/Item.php b/Classes/EventListener/Order/Create/PersistOrder/Item.php index 7b245c32..84adb2e1 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Item.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Item.php @@ -17,7 +17,6 @@ use Extcode\Cart\Domain\Repository\Order\ShippingAddressRepository; use Extcode\Cart\Event\Order\PersistOrderEvent; use TYPO3\CMS\Core\Context\Context; -use TYPO3\CMS\Core\Context\UserAspect; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; @@ -27,8 +26,10 @@ public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ItemRepository $itemRepository, private readonly BillingAddressRepository $billingAddressRepository, - private readonly ShippingAddressRepository $shippingAddressRepository - ) {} + private readonly ShippingAddressRepository $shippingAddressRepository, + private readonly Context $context + ) { + } public function __invoke(PersistOrderEvent $event): void { @@ -39,12 +40,9 @@ public function __invoke(PersistOrderEvent $event): void $orderItem->setPid($storagePid); - $userAspect = GeneralUtility::makeInstance(Context::class)->getAspect('frontend.user'); + $userAspect = $this->context->getAspect('frontend.user'); - if ( - $userAspect instanceof UserAspect - && $userAspect->isLoggedIn() - ) { + if ($userAspect->isLoggedIn()) { $frontendUserRepository = GeneralUtility::makeInstance( FrontendUserRepository::class ); @@ -63,8 +61,10 @@ public function __invoke(PersistOrderEvent $event): void $orderItem->setTotalGross($cart->getTotalGross()); $orderItem->setTotalNet($cart->getTotalNet()); - /* In multistep checkout the setting `shippingSameAsBilling` might get lost for the orderItem, - but it does not get lost for the cart as the cart is stored between every step in the session */ + /* + * In multistep checkout the setting `shippingSameAsBilling` might get lost for the orderItem, + but it does not get lost for the cart as the cart is stored between every step in the session + */ $orderItem->setShippingSameAsBilling($cart->isShippingSameAsBilling()); if ($orderItem->isShippingSameAsBilling()) { $orderItem->removeShippingAddress(); diff --git a/Classes/EventListener/Order/Create/PersistOrder/Payment.php b/Classes/EventListener/Order/Create/PersistOrder/Payment.php index 3453a65e..3a0d0669 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Payment.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Payment.php @@ -23,7 +23,8 @@ public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ItemRepository $itemRepository, private readonly PaymentRepository $paymentRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { diff --git a/Classes/EventListener/Order/Create/PersistOrder/Products.php b/Classes/EventListener/Order/Create/PersistOrder/Products.php index 200dba2d..3d9abfbe 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Products.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Products.php @@ -26,17 +26,18 @@ class Products { - private Item $orderItem; - protected array $taxClasses; + private Item $orderItem; + private int $storagePid; public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ProductRepository $productRepository, private readonly ProductAdditionalRepository $productAdditionalRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { @@ -132,7 +133,7 @@ protected function addProductAdditional( protected function addVariantsOfVariant(BeVariantInterface $variant, int $level): void { - $level += 1; + $level++; foreach ($variant->getBeVariants() as $variantInner) { if ($variantInner->getBeVariants()) { diff --git a/Classes/EventListener/Order/Create/PersistOrder/Shipping.php b/Classes/EventListener/Order/Create/PersistOrder/Shipping.php index c3707997..f753d4f9 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Shipping.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Shipping.php @@ -23,7 +23,8 @@ public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ItemRepository $itemRepository, private readonly ShippingRepository $shippingRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { diff --git a/Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php b/Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php index 1821f037..d1593887 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php +++ b/Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php @@ -24,7 +24,8 @@ public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ItemRepository $itemRepository, private readonly TaxClassRepository $taxClassRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { diff --git a/Classes/EventListener/Order/Create/PersistOrder/Taxes.php b/Classes/EventListener/Order/Create/PersistOrder/Taxes.php index 449386dc..7d9301ad 100644 --- a/Classes/EventListener/Order/Create/PersistOrder/Taxes.php +++ b/Classes/EventListener/Order/Create/PersistOrder/Taxes.php @@ -25,7 +25,8 @@ public function __construct( private readonly PersistenceManager $persistenceManager, private readonly ItemRepository $itemRepository, private readonly TaxRepository $taxRepository - ) {} + ) { + } public function __invoke(PersistOrderEvent $event): void { diff --git a/Classes/EventListener/Order/Finish/ClearCart.php b/Classes/EventListener/Order/Finish/ClearCart.php index 88fbd26b..0ec596b5 100644 --- a/Classes/EventListener/Order/Finish/ClearCart.php +++ b/Classes/EventListener/Order/Finish/ClearCart.php @@ -11,10 +11,10 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface; use Extcode\Cart\Domain\Model\Order\BillingAddress; use Extcode\Cart\Domain\Model\Order\ShippingAddress; use Extcode\Cart\Event\Order\EventInterface; -use Extcode\Cart\Service\PaymentMethodsServiceInterface; use Extcode\Cart\Service\SessionHandler; use Extcode\Cart\Utility\CartUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -23,9 +23,10 @@ class ClearCart { public function __construct( protected readonly CartUtility $cartUtility, - protected readonly PaymentMethodsServiceInterface $paymentMethodsService, + protected readonly PaymentMethodsLoaderInterface $paymentMethodsLoader, protected readonly SessionHandler $sessionHandler - ) {} + ) { + } public function __invoke(EventInterface $event): void { @@ -33,9 +34,9 @@ public function __invoke(EventInterface $event): void $settings = $event->getSettings(); $paymentId = $cart->getPayment()->getId(); - $paymentSettings = $this->paymentMethodsService->getConfigurationsForType('payments', $cart->getBillingCountry()); + $paymentSettings = $this->paymentMethodsLoader->getPaymentMethods($cart); - if ((int)($paymentSettings['options'][$paymentId]['preventClearCart'] ?? 0) != 1) { + if ((int) ($paymentSettings['options'][$paymentId]['preventClearCart'] ?? 0) != 1) { $cartPid = $settings['settings']['cart']['pid']; $this->sessionHandler->writeCart( diff --git a/Classes/EventListener/Order/Finish/Email.php b/Classes/EventListener/Order/Finish/Email.php index e8dcc94b..07f9ff52 100644 --- a/Classes/EventListener/Order/Finish/Email.php +++ b/Classes/EventListener/Order/Finish/Email.php @@ -11,36 +11,37 @@ * LICENSE file that was distributed with this source code. */ +use Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface; use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Order\Item; use Extcode\Cart\Event\Order\EventInterface; use Extcode\Cart\Service\MailHandler; -use Extcode\Cart\Service\PaymentMethodsServiceInterface; class Email { public function __construct( - private readonly PaymentMethodsServiceInterface $paymentMethodsService, + private readonly PaymentMethodsLoaderInterface $paymentMethodsLoader, private readonly MailHandler $mailHandler, - ) {} + ) { + } public function __invoke(EventInterface $event): void { $orderItem = $event->getOrderItem(); - $paymentMethods = $this->paymentMethodsService->getPaymentMethods($event->getCart()); + $paymentMethods = $this->paymentMethodsLoader->getPaymentMethods($event->getCart()); $paymentId = $orderItem->getPayment()->getServiceId(); $paymentMethod = $paymentMethods[$paymentId] ?? null; if ( method_exists($paymentMethod, 'isBuyerEmailDisabled') === false - || (method_exists($paymentMethod, 'isBuyerEmailDisabled') && $paymentMethod->isBuyerEmailDisabled() === false) + || $paymentMethod->isBuyerEmailDisabled() === false ) { $this->sendBuyerMail($orderItem, $event->getCart()); } if ( method_exists($paymentMethod, 'isSellerEmailDisabled') === false - || (method_exists($paymentMethod, 'isSellerEmailDisabled') && $paymentMethod->isSellerEmailDisabled() === false) + || $paymentMethod->isSellerEmailDisabled() === false ) { $this->sendSellerMail($orderItem, $event->getCart()); } diff --git a/Classes/EventListener/Order/Update/LogServiceUpdate.php b/Classes/EventListener/Order/Update/LogServiceUpdate.php index cdc993a4..30aaeaad 100644 --- a/Classes/EventListener/Order/Update/LogServiceUpdate.php +++ b/Classes/EventListener/Order/Update/LogServiceUpdate.php @@ -18,7 +18,8 @@ class LogServiceUpdate { public function __construct( private readonly LoggerInterface $logger - ) {} + ) { + } public function __invoke(UpdateServiceEvent $event): void { diff --git a/Classes/EventListener/Template/Components/ModifyButtonBar.php b/Classes/EventListener/Template/Components/ModifyButtonBar.php index ed6b3dad..14bd0805 100644 --- a/Classes/EventListener/Template/Components/ModifyButtonBar.php +++ b/Classes/EventListener/Template/Components/ModifyButtonBar.php @@ -1,5 +1,7 @@ setButtons( array_merge( $event->getButtons(), - [ 'action-export-csv' => [ + ['action-export-csv' => [ 'link' => $this->uriBuilder->reset()->setRequest($event->getRequest()) ->setArguments(['searchArguments' => $event->getSearchArguments()]) ->setFormat('csv') @@ -51,12 +54,12 @@ private function modifyListActionButtons(ModifyButtonBarEvent $event) ); } - private function modifyShowActionButtons(ModifyButtonBarEvent $event) + private function modifyShowActionButtons(ModifyButtonBarEvent $event): void { $event->setButtons( array_merge( $event->getButtons(), - [ 'action-close' => [ + ['action-close' => [ 'link' => $this->uriBuilder->reset()->setRequest($event->getRequest()) ->uriFor( 'list' diff --git a/Classes/Hooks/FormDefinitions.php b/Classes/Hooks/FormDefinitions.php index da453df6..c8d9c66c 100644 --- a/Classes/Hooks/FormDefinitions.php +++ b/Classes/Hooks/FormDefinitions.php @@ -1,5 +1,7 @@ $layout) { if (is_array($layout[0])) { - if (isset($layout[0]['allowedColPos']) && \str_ends_with((string)$layout[1], '.')) { - $layoutKey = substr((string)$layout[1], 0, -1); + if (isset($layout[0]['allowedColPos']) && \str_ends_with((string) $layout[1], '.')) { + $layoutKey = mb_substr((string) $layout[1], 0, -1); $restrictions[$layoutKey] = GeneralUtility::intExplode(',', $layout[0]['allowedColPos'], true); } } else { @@ -87,6 +89,7 @@ protected function getPageId(int $pid): int } $row = BackendUtilityCore::getRecord('tt_content', abs($pid), 'uid,pid'); + return $row['pid']; } diff --git a/Classes/PageTitle/PageTitleProvider.php b/Classes/PageTitle/PageTitleProvider.php index bd10c8ca..93f9d73c 100644 --- a/Classes/PageTitle/PageTitleProvider.php +++ b/Classes/PageTitle/PageTitleProvider.php @@ -2,13 +2,6 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\PageTitle; use TYPO3\CMS\Core\PageTitle\AbstractPageTitleProvider; diff --git a/Classes/Property/Exception/ResetPropertyException.php b/Classes/Property/Exception/ResetPropertyException.php index a7da9af1..06c41c5e 100644 --- a/Classes/Property/Exception/ResetPropertyException.php +++ b/Classes/Property/Exception/ResetPropertyException.php @@ -1,5 +1,7 @@ configurations = $this->configurationManager->getConfiguration( - ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, - 'Cart' - ); - } - - public function getServices(?array $configurations, array $services, Cart $cart): array - { - if (empty($configurations['options'])) { - return $services; - } - - foreach ($configurations['options'] as $serviceKey => $serviceConfig) { - $service = $this->serviceFactory->getService($serviceKey, $serviceConfig, $configurations['preset'] == $serviceKey); - $service->setCart($cart); - - $services[$serviceKey] = $service; - } - - return $services; - } - - public function getConfigurationsForType(string $configurationType, ?string $country = null): ?array - { - if (!isset($this->configurations[$configurationType])) { - return null; - } - - $configuration = $this->configurations[$configurationType]; - - if (is_null($country)) { - if (isset($configuration['settings']['countries']['options'][$configuration['settings']['countries']['preset']]['code'])) { - $country = $configuration['settings']['countries']['options'][$configuration['settings']['countries']['preset']]['code']; - } - } - - if (isset($country)) { - if ( - !empty($configuration['countries']) - && !empty($configuration['countries'][$country]) - && is_array($configuration['countries'][$country]) - ) { - return $configuration['countries'][$country]; - } - - if (!empty($configuration['zones']) && is_array($configuration['zones'])) { - $zoneSetting = $this->getTypeZonesPluginSettings($configuration['zones'], $country); - if (!empty($zoneSetting)) { - return $zoneSetting; - } - } - - return $configuration; - } - - return null; - } - - protected function getTypeZonesPluginSettings(array $zoneSettings, string $country): array - { - foreach ($zoneSettings as $zoneSetting) { - $countriesInZones = GeneralUtility::trimExplode(',', $zoneSetting['countries'], true); - - if (in_array($country, $countriesInZones)) { - return $zoneSetting; - } - } - - return []; - } -} diff --git a/Classes/Service/MailHandler.php b/Classes/Service/MailHandler.php index 9bd4c96a..ea47d013 100644 --- a/Classes/Service/MailHandler.php +++ b/Classes/Service/MailHandler.php @@ -1,5 +1,7 @@ setPluginSettings(); } @@ -292,7 +309,10 @@ public function getSellerEmailBcc(): string */ public function sendBuyerMail(Item $orderItem): void { - if (empty($this->getBuyerEmailFrom()) || empty($orderItem->getBillingAddress()->getEmail())) { + if (empty($this->getBuyerEmailFrom()) + || ($orderItem->getBillingAddress() instanceof AddressInterface) === false + || empty($orderItem->getBillingAddress()->getEmail()) + ) { return; } @@ -306,9 +326,10 @@ public function sendBuyerMail(Item $orderItem): void ->from($fromAddress) ->setTemplate('Mail/' . ucfirst($status) . '/Buyer') ->format(FluidEmail::FORMAT_HTML) - ->assign('settings', $this->pluginSettings['settings']) + ->assign('settings', $this->pluginSettings['settings'] ?? []) ->assign('cart', $this->cart) - ->assign('orderItem', $orderItem); + ->assign('orderItem', $orderItem) + ; if ($this->getBuyerEmailCc()) { $cc = explode(',', $this->getBuyerEmailCc()); @@ -324,11 +345,35 @@ public function sendBuyerMail(Item $orderItem): void $this->addAttachments('buyer', $orderItem, $email); - if ($GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) { + if (($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface) { $email->setRequest($GLOBALS['TYPO3_REQUEST']); } - $this->mailer->send($email); + try { + $this->mailer->send($email); + $this->logService->write( + Log::info( + self::getOrderItemUid($orderItem), + 'sendBuyerMail', + 'Mail was send to buyer.', + [ + 'time' => time(), + ] + ) + ); + } catch (Exception $e) { + $this->logService->write( + Log::error( + self::getOrderItemUid($orderItem), + 'sendBuyerMail', + 'Mail could not send to buyer.', + [ + 'time' => time(), + 'exception' => $e->__toString(), + ] + ) + ); + } } /** @@ -336,6 +381,9 @@ public function sendBuyerMail(Item $orderItem): void */ public function sendSellerMail(Item $orderItem): void { + if (is_null($orderItem->getUid())) { + throw new InvalidArgumentException('Method should only called for persisted orders.', 1774715307); + } $sellerEmailTo = $this->getSellerEmailTo(); if (empty($this->getSellerEmailFrom()) || empty($sellerEmailTo)) { return; @@ -352,11 +400,14 @@ public function sendSellerMail(Item $orderItem): void ->from($fromAddress) ->setTemplate('Mail/' . ucfirst($status) . '/Seller') ->format(FluidEmail::FORMAT_HTML) - ->assign('settings', $this->pluginSettings['settings']) + ->assign('settings', $this->pluginSettings['settings'] ?? []) ->assign('cart', $this->cart) - ->assign('orderItem', $orderItem); + ->assign('orderItem', $orderItem) + ; - if ($orderItem->getBillingAddress()->getEmail()) { + if (($orderItem->getBillingAddress() instanceof AddressInterface) + && $orderItem->getBillingAddress()->getEmail() + ) { $email->replyTo($orderItem->getBillingAddress()->getEmail()); } if ($this->getSellerEmailCc()) { @@ -370,11 +421,35 @@ public function sendSellerMail(Item $orderItem): void $this->addAttachments('seller', $orderItem, $email); - if ($GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) { + if (($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface) { $email->setRequest($GLOBALS['TYPO3_REQUEST']); } - $this->mailer->send($email); + try { + $this->mailer->send($email); + $this->logService->write( + Log::info( + self::getOrderItemUid($orderItem), + 'sendSellerMail', + 'Mail was send to seller.', + [ + 'time' => time(), + ] + ) + ); + } catch (Exception $e) { + $this->logService->write( + Log::error( + self::getOrderItemUid($orderItem), + 'sendSellerMail', + 'Mail could not send to seller.', + [ + 'time' => time(), + 'exception' => $e->__toString(), + ] + ) + ); + } } public function addAttachments(string $type, Item $orderItem, FluidEmail $email): void @@ -388,8 +463,30 @@ public function addAttachments(string $type, Item $orderItem, FluidEmail $email) foreach ($attachments as $attachment) { if (file_exists($attachment)) { $email->attachFromPath($attachment); + } else { + $this->logService->write( + Log::warning( + self::getOrderItemUid($orderItem), + 'addAttachments', + 'Mail could add attachment ' . $attachment . ' to mail.', + [ + 'time' => time(), + ] + ) + ); } } } } + + private static function getOrderItemUid(Item $orderItem): int + { + $orderItemUid = $orderItem->getUid(); + + if (is_null($orderItemUid)) { + throw new InvalidArgumentException('Method should only called for persisted orders.', 1774715307); + } + + return $orderItemUid; + } } diff --git a/Classes/Service/OrderItemCleanupService.php b/Classes/Service/OrderItemCleanupService.php index e6e95059..7c1cb102 100644 --- a/Classes/Service/OrderItemCleanupService.php +++ b/Classes/Service/OrderItemCleanupService.php @@ -14,21 +14,22 @@ use DateTimeImmutable; use Extcode\Cart\Utility\Typo3GlobalsUtility; use RuntimeException; +use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; -use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\Utility\GeneralUtility; final readonly class OrderItemCleanupService { public function __construct( private ConnectionPool $connectionPool, - ) {} + ) { + } public function run(DateTimeImmutable $cutOffDate): void { - $this->deleteRecordsFromTable( + self::deleteRecordsFromTable( 'tx_cart_domain_model_order_item', $this->getRecordUidsToDelete( 'tx_cart_domain_model_order_item', @@ -43,7 +44,8 @@ private function getRecordUidsToDelete(string $tableName, DateTimeImmutable $cut $queryBuilder ->getRestrictions() ->removeAll() - ->add(GeneralUtility::makeInstance(DeletedRestriction::class)); + ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) + ; return $queryBuilder ->select('uid') @@ -55,10 +57,11 @@ private function getRecordUidsToDelete(string $tableName, DateTimeImmutable $cut ), ) ->executeQuery() - ->fetchFirstColumn(); + ->fetchFirstColumn() + ; } - private function deleteRecordsFromTable(string $tableName, array $recordUids): void + private static function deleteRecordsFromTable(string $tableName, array $recordUids): void { $dataHandler = GeneralUtility::makeInstance(DataHandler::class); $dataHandler->start( @@ -74,7 +77,7 @@ private function deleteRecordsFromTable(string $tableName, array $recordUids): v if ($dataHandler->errorLog !== []) { throw new RuntimeException( - 'Could not properly delete records for table: ' . $tableName . ', got the following errors: ' . implode(', ', $dataHandler->errorLog), + 'Could not properly delete records for table: ' . $tableName . ', got the following errors: ' . implode(', ', array_filter($dataHandler->errorLog, is_string(...))), 1751526777 ); } diff --git a/Classes/Service/SessionHandler.php b/Classes/Service/SessionHandler.php index 804c7d01..987fce6a 100644 --- a/Classes/Service/SessionHandler.php +++ b/Classes/Service/SessionHandler.php @@ -1,5 +1,7 @@ eventDispatcher->dispatch($afterRestoreCartEvent); + return $cart; } } @@ -72,17 +76,18 @@ public function clearCart(string $key): void } /** - * restore an AbstractAddress object from session + * restore an AddressInterface object from session */ - public function restoreAddress(string $key): ?AbstractAddress + public function restoreAddress(string $key): ?AddressInterface { $sessionData = $this->frontendUserAuthentication->getKey('ses', $this->prefixKey . $key); if (is_string($sessionData)) { $address = unserialize($sessionData); - if ($address instanceof AbstractAddress) { + if ($address instanceof AddressInterface) { $afterRestoreAddressEvent = new AfterRestoreAddressEvent($address); $this->eventDispatcher->dispatch($afterRestoreAddressEvent); + return $address; } } @@ -91,9 +96,9 @@ public function restoreAddress(string $key): ?AbstractAddress } /** - * writes an AbstractAddress object to session + * writes an AddressInterface object to session */ - public function writeAddress(string $key, AbstractAddress $address): void + public function writeAddress(string $key, AddressInterface $address): void { $beforeWriteAddressEvent = new BeforeWriteAddressEvent($address); $this->eventDispatcher->dispatch($beforeWriteAddressEvent); diff --git a/Classes/Updates/ExtcodeCartCTypeMigration.php b/Classes/Updates/ExtcodeCartCTypeMigration.php new file mode 100644 index 00000000..e43fa680 --- /dev/null +++ b/Classes/Updates/ExtcodeCartCTypeMigration.php @@ -0,0 +1,36 @@ + 'cart_cart', + ]; + } +} diff --git a/Classes/Updates/ListTypeToCTypeUpdate.php b/Classes/Updates/ListTypeToCTypeUpdate.php index 2f046f3a..e65e9055 100644 --- a/Classes/Updates/ListTypeToCTypeUpdate.php +++ b/Classes/Updates/ListTypeToCTypeUpdate.php @@ -1,9 +1,8 @@ 'cart_cart', - 'cart_currency' => 'cart_currency', - 'cart_minicart' => 'cart_minicart', - 'cart_order' => 'cart_order', - ]; - } - public function getTitle(): string { return 'Update cart list_type to CType.'; @@ -34,4 +26,14 @@ public function getDescription(): string { return 'Update all cart list_type plugin to CType.'; } + + protected function getListTypeToCTypeMapping(): array + { + return [ + 'cart_cart' => 'cart_cart', + 'cart_currency' => 'cart_currency', + 'cart_minicart' => 'cart_minicart', + 'cart_order' => 'cart_order', + ]; + } } diff --git a/Classes/Utility/CartUtility.php b/Classes/Utility/CartUtility.php index a9881f6e..f260be8f 100644 --- a/Classes/Utility/CartUtility.php +++ b/Classes/Utility/CartUtility.php @@ -1,5 +1,7 @@ sessionHandler->restoreCart($cartSettings['pid']); - $event = new UpdateCountryEvent($cart, $request); + $event = new UpdateCountryEvent( + $cart, + $request + ); $this->eventDispatcher->dispatch($event); $this->sessionHandler->writeCart($cartSettings['pid'], $event->getCart()); @@ -54,7 +64,7 @@ public function updateService(Cart $cart): void { $cart->getPayment()->setCart($cart); if (!$cart->getPayment()->isAvailable()) { - $payments = $this->paymentMethodsService->getPaymentMethods($cart); + $payments = $this->paymentMethodsLoader->getPaymentMethods($cart); $fallBackId = $cart->getPayment()->getFallBackId(); if ($fallBackId) { $payment = $this->getServiceById($payments, $fallBackId); @@ -64,7 +74,7 @@ public function updateService(Cart $cart): void $cart->getShipping()->setCart($cart); if (!$cart->getShipping()->isAvailable()) { - $shippings = $this->shippingMethodsService->getShippingMethods($cart); + $shippings = $this->shippingMethodsLoader->getShippingMethods($cart); $fallBackId = $cart->getShipping()->getFallBackId(); if ($fallBackId) { $shipping = $this->getServiceById($shippings, $fallBackId); @@ -79,7 +89,7 @@ public function updateService(Cart $cart): void public function getNewCart(array $configurations): Cart { $isNetCartTypoScriptInput = $configurations['settings']['cart']['isNetCart']; - $isNetCart = ($isNetCartTypoScriptInput === '1' || $isNetCartTypoScriptInput === 'true'); + $isNetCart = $isNetCartTypoScriptInput === '1' || $isNetCartTypoScriptInput === 'true'; $preset = $configurations['settings']['currencies']['preset']; if ($configurations['settings']['currencies']['options'][$preset]) { @@ -87,7 +97,7 @@ public function getNewCart(array $configurations): Cart } if (!isset($currency) || !is_array($currency) || !isset($currency['code']) || !isset($currency['sign']) || !isset($currency['translation'])) { - throw new \InvalidArgumentException('Add propper currency TypoScript configuration.'); + throw new InvalidArgumentException('Add propper currency TypoScript configuration.', 5910386141); } // TODO: Throw exception if no currency setting is available or make an default because creating a new cart need @@ -95,7 +105,7 @@ public function getNewCart(array $configurations): Cart $defaultCountry = $configurations['settings']['countries']['options'][$configurations['settings']['countries']['preset']]['code']; - $taxClasses = $this->taxClassService->getTaxClasses($defaultCountry); + $taxClasses = $this->taxClassLoader->getTaxClasses($defaultCountry); $cart = GeneralUtility::makeInstance( Cart::class, @@ -103,7 +113,7 @@ public function getNewCart(array $configurations): Cart $isNetCart, $currency['code'], $currency['sign'], - (float)$currency['translation'] + (float) $currency['translation'] ); if ($defaultCountry) { @@ -120,7 +130,7 @@ public function getNewCart(array $configurations): Cart protected function setShipping(Cart $cart): void { - $shippings = $this->shippingMethodsService->getShippingMethods($cart); + $shippings = $this->shippingMethodsLoader->getShippingMethods($cart); foreach ($shippings as $shipping) { if ($shipping->isPreset()) { @@ -136,7 +146,7 @@ protected function setShipping(Cart $cart): void protected function setPayment(Cart $cart): void { - $payments = $this->paymentMethodsService->getPaymentMethods($cart); + $payments = $this->paymentMethodsLoader->getPaymentMethods($cart); foreach ($payments as $payment) { if ($payment->isPreset()) { diff --git a/Classes/Utility/CurrencyUtility.php b/Classes/Utility/CurrencyUtility.php index a92b9f10..c40c4fad 100644 --- a/Classes/Utility/CurrencyUtility.php +++ b/Classes/Utility/CurrencyUtility.php @@ -1,5 +1,7 @@ sessionHandler->restoreCart($cartSettings['pid']); - $event = new UpdateCurrencyEvent($cart, $request, $pluginSettings['settings']['currencies']); + $event = new UpdateCurrencyEvent( + $cart, + $request, + $pluginSettings['settings']['currencies'] + ); $this->eventDispatcher->dispatch($event); $this->sessionHandler->writeCart($cartSettings['pid'], $event->getCart()); diff --git a/Classes/Utility/EvalPrice.php b/Classes/Utility/EvalPrice.php index ea7e9015..ad0718a1 100644 --- a/Classes/Utility/EvalPrice.php +++ b/Classes/Utility/EvalPrice.php @@ -1,5 +1,7 @@ getTemplateLayoutsFromTsConfig($pageUid, $extKey, $pluginName) as $templateKey => $title) { - if (\str_starts_with((string)$title, '--div--')) { + if (\str_starts_with((string) $title, '--div--')) { $optGroupParts = GeneralUtility::trimExplode(',', $title, true, 2); $title = $optGroupParts[1]; $templateKey = $optGroupParts[0]; @@ -61,8 +63,7 @@ protected function getTemplateLayoutsFromTsConfig(int $pageUid, string $extKey, if (!empty($pluginName)) { $pluginName .= '.'; - if (isset($pagesTsConfig[$extKey]['templateLayouts.']) - && isset($pagesTsConfig[$extKey]['templateLayouts.'][$pluginName]) + if (isset($pagesTsConfig[$extKey]['templateLayouts.'], $pagesTsConfig[$extKey]['templateLayouts.'][$pluginName]) && is_array($pagesTsConfig[$extKey]['templateLayouts.'][$pluginName]) ) { $templateLayouts = $pagesTsConfig[$extKey]['templateLayouts.'][$pluginName]; @@ -74,6 +75,7 @@ protected function getTemplateLayoutsFromTsConfig(int $pageUid, string $extKey, $templateLayouts = $pagesTsConfig[$extKey]['templateLayouts.']; } } + return $templateLayouts; } } diff --git a/Classes/Utility/Typo3GlobalsUtility.php b/Classes/Utility/Typo3GlobalsUtility.php index 251966d3..a6cd0da8 100644 --- a/Classes/Utility/Typo3GlobalsUtility.php +++ b/Classes/Utility/Typo3GlobalsUtility.php @@ -11,8 +11,10 @@ * LICENSE file that was distributed with this source code. */ -use TypeError; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\Site\Entity\Site; +use TypeError; final readonly class Typo3GlobalsUtility { @@ -20,10 +22,34 @@ public static function getTypo3BackendUser(): BackendUserAuthentication { $user = $GLOBALS['BE_USER'] ?? null; - if (!$user instanceof BackendUserAuthentication) { - throw new TypeError('Globals BE_USER was not of type BackendUserAuthentication, got: ' . $user, 1769004660); + if (($user instanceof BackendUserAuthentication) === false) { + throw new TypeError('$GLOBALS[\'BE_USER\'] was not of type BackendUserAuthentication, got: ' . $user, 1769004660); } return $user; } + + public static function getTypo3Request(): ServerRequestInterface + { + $request = $GLOBALS['TYPO3_REQUEST'] ?? null; + + if (($request instanceof ServerRequestInterface) === false) { + throw new TypeError('$GLOBALS[\'TYPO3_REQUEST\'] was not of type ServerRequestInterface, got: ' . $request, 1776420280); + } + + return $request; + } + + public static function getSiteFromTypo3Request(): Site + { + $request = self::getTypo3Request(); + + $site = $request->getAttribute('site'); + + if (($site instanceof Site) === false) { + throw new TypeError('$site was not of type Site, got: ' . $site, 1776450259); + } + + return $site; + } } diff --git a/Classes/Validation/Validator/EmptyValidator.php b/Classes/Validation/Validator/EmptyValidator.php index 3f992295..e246e4c9 100644 --- a/Classes/Validation/Validator/EmptyValidator.php +++ b/Classes/Validation/Validator/EmptyValidator.php @@ -1,5 +1,7 @@ addError( $this->translateErrorMessage( @@ -59,7 +62,11 @@ public function isValid(mixed $value): void ), 1500493650 ); - } elseif (is_object($value) && $value instanceof \Countable && $value->count() != 0) { + } elseif ( + is_object($value) + && $value instanceof Countable + && $value->count() != 0 + ) { $this->addError( $this->translateErrorMessage( 'validator.empty.notempty', @@ -71,3 +78,6 @@ public function isValid(mixed $value): void } } } + +// keep compatibility for $acceptsEmptyValues property definition of parent class +// @php-cs-fixer-ignore phpdoc_to_property_type diff --git a/Classes/ViewHelpers/AdditionalJsonViewHelper.php b/Classes/ViewHelpers/AdditionalJsonViewHelper.php index 973ab9b2..de1b3500 100644 --- a/Classes/ViewHelpers/AdditionalJsonViewHelper.php +++ b/Classes/ViewHelpers/AdditionalJsonViewHelper.php @@ -1,5 +1,7 @@ arguments['delim']; $quote = $this->arguments['quote']; @@ -66,3 +66,6 @@ public function render() return CsvUtility::csvValues($orderItemArr, $delim, $quote); } } + +// keep compatibility for $escapeOutput property definition of parent class +// @php-cs-fixer-ignore phpdoc_to_property_type diff --git a/Classes/ViewHelpers/CsvValuesViewHelper.php b/Classes/ViewHelpers/CsvValuesViewHelper.php index 7488debb..3e20e61e 100644 --- a/Classes/ViewHelpers/CsvValuesViewHelper.php +++ b/Classes/ViewHelpers/CsvValuesViewHelper.php @@ -1,5 +1,7 @@ arguments['orderItem']; $delim = $this->arguments['delim']; @@ -74,3 +74,6 @@ public function render() return CsvUtility::csvValues($orderItemArr, $delim, $quote); } } + +// keep compatibility for $escapeOutput property definition of parent class +// @php-cs-fixer-ignore phpdoc_to_property_type diff --git a/Classes/ViewHelpers/FieldNameViewHelper.php b/Classes/ViewHelpers/FieldNameViewHelper.php index b4593272..8280f3f4 100644 --- a/Classes/ViewHelpers/FieldNameViewHelper.php +++ b/Classes/ViewHelpers/FieldNameViewHelper.php @@ -1,5 +1,7 @@ registerArgument( 'service', ServiceInterface::class, @@ -38,15 +41,11 @@ public function initializeArguments(): void ); } - /** - * @param array|null $arguments - * @return bool - * @api - */ - protected static function evaluateCondition($arguments = null) + public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool { $service = $arguments['service']; $price = $arguments['price']; - return (bool)$service->isAvailable($price); + + return (bool) $service->isAvailable($price); } } diff --git a/Classes/ViewHelpers/Format/CurrencyViewHelper.php b/Classes/ViewHelpers/Format/CurrencyViewHelper.php index 2f33f79f..a16382a1 100644 --- a/Classes/ViewHelpers/Format/CurrencyViewHelper.php +++ b/Classes/ViewHelpers/Format/CurrencyViewHelper.php @@ -1,5 +1,7 @@ 0.0) { - $floatToFormat = $floatToFormat / $currencyTranslation; + $floatToFormat /= $currencyTranslation; } $output = number_format($floatToFormat, $decimals, $decimalSeparator, $thousandsSeparator); @@ -157,6 +160,10 @@ public function render(): string $output = $output . $currencySeparator . $currencySign; } } + return $output; } } + +// keep compatibility for $escapeOutput property definition of parent class +// @php-cs-fixer-ignore phpdoc_to_property_type diff --git a/Classes/ViewHelpers/Format/NothingViewHelper.php b/Classes/ViewHelpers/Format/NothingViewHelper.php index 9db9ccb9..1f8962f5 100644 --- a/Classes/ViewHelpers/Format/NothingViewHelper.php +++ b/Classes/ViewHelpers/Format/NothingViewHelper.php @@ -1,5 +1,7 @@ renderChildren(); } } + +// keep compatibility for $escapeOutput property definition of parent class +// @php-cs-fixer-ignore phpdoc_to_property_type diff --git a/Classes/ViewHelpers/IncludeFileViewHelper.php b/Classes/ViewHelpers/IncludeFileViewHelper.php index 3b83421f..e134aa05 100644 --- a/Classes/ViewHelpers/IncludeFileViewHelper.php +++ b/Classes/ViewHelpers/IncludeFileViewHelper.php @@ -1,5 +1,7 @@ arguments['path']; $compress = $this->arguments['compress']; - $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); + $pageRenderer = $this->pageRenderer; if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend()) { try { - $path = GeneralUtility::makeInstance(FilePathSanitizer::class)->sanitize((string)$path); + $path = $this->filePathSanitizer->sanitize((string) $path); } catch (InvalidFileNameException) { $path = null; - } catch (InvalidPathException|FileDoesNotExistException|InvalidFileException $e) { + } catch (FileDoesNotExistException|InvalidFileException|InvalidPathException $e) { $path = null; if ($GLOBALS['TSFE']->tmpl->tt_track) { - GeneralUtility::makeInstance(TimeTracker::class)->setTSlogMessage($e->getMessage(), 3); + $this->timeTracker->setTSlogMessage($e->getMessage(), LogLevel::ERROR); } } } - if (strtolower(substr((string)$path, -3)) === '.js') { + if (mb_strtolower(mb_substr((string) $path, -3)) === '.js') { $pageRenderer->addJsFile($path, null, $compress); - } elseif (strtolower(substr((string)$path, -4)) === '.css') { + } elseif (mb_strtolower(mb_substr((string) $path, -4)) === '.css') { $pageRenderer->addCssFile($path, 'stylesheet', 'all', '', $compress); } } diff --git a/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php b/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php index 744a5877..5ab6b9ec 100644 --- a/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php +++ b/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php @@ -1,5 +1,7 @@ configuration['persistence']['classes'][$class]['mapping']['columns'] as $tableColumn => $modelPropertyData) { $modelProperty = $modelPropertyData['mapOnProperty']; + if (is_string($modelProperty) === false) { + continue; + } $mapping[$modelProperty] = $tableColumn; } $data = ObjectAccess::getGettableProperties($data); foreach ($data as $key => $value) { - if (isset($mapping[$key])) { + if (isset($mapping[$key]) && is_string($mapping[$key])) { unset($data[$key]); - $data[$mapping[$key]] = $value; + $data[(string) $mapping[$key]] = $value; } } return $data; } + return $data; } } diff --git a/Classes/ViewHelpers/MetaTagViewHelper.php b/Classes/ViewHelpers/MetaTagViewHelper.php index 01c91e6e..fb3d4588 100644 --- a/Classes/ViewHelpers/MetaTagViewHelper.php +++ b/Classes/ViewHelpers/MetaTagViewHelper.php @@ -1,5 +1,7 @@ registerArgument( @@ -46,8 +52,9 @@ public function initializeArguments(): void public function render(): void { - $metaTagManager = GeneralUtility::makeInstance(MetaTagManagerRegistry::class) - ->getManagerForProperty($this->arguments['property']); + $metaTagManager = $this->metaTagManagerRegistry + ->getManagerForProperty($this->arguments['property']) + ; $metaTagManager->addProperty( $this->arguments['property'], $this->arguments['content'] diff --git a/Classes/ViewHelpers/TitleTagViewHelper.php b/Classes/ViewHelpers/TitleTagViewHelper.php index a4f56815..b882fe81 100644 --- a/Classes/ViewHelpers/TitleTagViewHelper.php +++ b/Classes/ViewHelpers/TitleTagViewHelper.php @@ -2,42 +2,37 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\ViewHelpers; use Extcode\Cart\PageTitle\PageTitleProvider; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; /** * ViewHelper to render the page title */ class TitleTagViewHelper extends AbstractViewHelper { - use CompileWithRenderStatic; + public function __construct( + private readonly PageTitleProvider $pageTitleProvider, + ) { + } public function initializeArguments(): void { parent::initializeArguments(); - $this->registerArgument('pageTitle', 'String', 'The page title'); + + $this->registerArgument( + 'pageTitle', + 'string', + 'The page title' + ); } - public static function renderStatic( - array $arguments, - \Closure $renderChildrenClosure, - RenderingContextInterface $renderingContext - ): void { + public function render(): void + { $pageTitle = $arguments['pageTitle'] ?? ''; if ($pageTitle !== '') { - GeneralUtility::makeInstance(PageTitleProvider::class)->setTitle($pageTitle); + $this->pageTitleProvider->setTitle($pageTitle); } } } diff --git a/Classes/ViewHelpers/Traversable/ExtractViewHelper.php b/Classes/ViewHelpers/Traversable/ExtractViewHelper.php index e75daa7b..bc8baf7d 100644 --- a/Classes/ViewHelpers/Traversable/ExtractViewHelper.php +++ b/Classes/ViewHelpers/Traversable/ExtractViewHelper.php @@ -1,5 +1,7 @@ registerArgument( 'content', - \Traversable::class, + 'array', 'Content', false ); @@ -37,10 +41,7 @@ public function initializeArguments(): void ); } - /** - * @return array - */ - public function render() + public function render(): mixed { $key = $this->arguments['key']; $content = $this->arguments['content']; @@ -51,7 +52,7 @@ public function render() try { $result = $this->extractByKey($content, $key); - } catch (\Exception) { + } catch (Exception) { $result = []; } @@ -66,6 +67,7 @@ public function render() if (isset($backup) === true) { $this->templateVariableContainer->add($this->arguments['as'], $backup); } + return $content; } @@ -75,12 +77,12 @@ public function render() /** * Extract by key * - * @throws \Exception + * @throws Exception */ public function extractByKey($iterator, string $key): mixed { - if ((is_array($iterator) === false) && ($iterator instanceof \Traversable === false)) { - throw new \Exception('Traversable object or array expected but received ' . gettype($iterator), 1361532490); + if ((is_array($iterator) === false) && ($iterator instanceof Traversable === false)) { + throw new Exception('Traversable object or array expected but received ' . gettype($iterator), 1361532490); } return $iterator[$key]; diff --git a/Classes/ViewHelpers/Variable/GetViewHelper.php b/Classes/ViewHelpers/Variable/GetViewHelper.php index edd4e532..c78117d1 100644 --- a/Classes/ViewHelpers/Variable/GetViewHelper.php +++ b/Classes/ViewHelpers/Variable/GetViewHelper.php @@ -1,5 +1,7 @@ arguments['name']; $useRawKeys = $this->arguments['useRawKeys']; - if (!str_contains((string)$name, '.')) { + if (!str_contains((string) $name, '.')) { if ($this->templateVariableContainer->exists($name) === true) { return $this->templateVariableContainer->get($name); } } else { - $segments = explode('.', (string)$name); + $segments = explode('.', (string) $name); $templateVariableRootName = $lastSegment = array_shift($segments); if ($this->templateVariableContainer->exists($templateVariableRootName) === true) { $templateVariableRoot = $this->templateVariableContainer->get($templateVariableRootName); @@ -94,7 +95,7 @@ public function render() $value = $templateVariableRoot; foreach ($segments as $segment) { if (ctype_digit($segment) === true) { - $segment = (int)$segment; + $segment = (int) $segment; $index = 0; // Note: this loop approach is not a stupid solution. If you doubt this, // attempt to feth a number at a numeric index from ObjectStorage ;) @@ -103,18 +104,20 @@ public function render() $value = $possibleValue; break; } - ++$index; + $index++; } continue; } $value = ObjectAccess::getProperty($value, $segment); } + return $value; - } catch (\Exception) { + } catch (Exception) { return null; } } } + return null; } } diff --git a/Classes/ViewHelpers/Variable/SetViewHelper.php b/Classes/ViewHelpers/Variable/SetViewHelper.php index a4a526fb..7b5affcb 100644 --- a/Classes/ViewHelpers/Variable/SetViewHelper.php +++ b/Classes/ViewHelpers/Variable/SetViewHelper.php @@ -1,5 +1,7 @@ renderChildren(); } - if (!str_contains((string)$name, '.')) { + if (!str_contains((string) $name, '.')) { if ($this->templateVariableContainer->exists($name) === true) { $this->templateVariableContainer->remove($name); } $this->templateVariableContainer->add($name, $value); - } elseif (substr_count((string)$name, '.') === 1) { - $parts = explode('.', (string)$name); + } elseif (mb_substr_count((string) $name, '.') === 1) { + $parts = explode('.', (string) $name); $objectName = array_shift($parts); $path = implode('.', $parts); if ($this->templateVariableContainer->exists($objectName) === false) { @@ -103,10 +106,11 @@ public function render() // Note: re-insert the variable to ensure unreferenced values like arrays also get updated $this->templateVariableContainer->remove($objectName); $this->templateVariableContainer->add($objectName, $object); - } catch (\Exception) { + } catch (Exception) { return null; } } + return null; } } diff --git a/Classes/Widgets/PaymentPaidShippingOpen.php b/Classes/Widgets/PaymentPaidShippingOpen.php index 81990dc1..c5ae1a87 100644 --- a/Classes/Widgets/PaymentPaidShippingOpen.php +++ b/Classes/Widgets/PaymentPaidShippingOpen.php @@ -17,19 +17,20 @@ use TYPO3\CMS\Dashboard\Widgets\RequestAwareWidgetInterface; use TYPO3\CMS\Dashboard\Widgets\WidgetConfigurationInterface; use TYPO3\CMS\Dashboard\Widgets\WidgetInterface; -use TYPO3\CMS\Fluid\View\StandaloneView; -class PaymentPaidShippingOpen implements WidgetInterface, RequestAwareWidgetInterface +class PaymentPaidShippingOpen implements RequestAwareWidgetInterface, WidgetInterface { private ServerRequestInterface $request; - private StandaloneView|ViewInterface $view; + + private ViewInterface $view; public function __construct( private readonly WidgetConfigurationInterface $configuration, private readonly ListDataProviderInterface $dataProvider, private readonly BackendViewFactory $backendViewFactory, private readonly array $options = [] - ) {} + ) { + } public function setRequest(ServerRequestInterface $request): void { @@ -48,6 +49,7 @@ public function renderWidgetContent(): string return $this->view->render('Widget/CartPaymentPaidShippingOpen'); } + public function getOptions(): array { return $this->options; diff --git a/Classes/Widgets/Provider/OrderItemsProvider.php b/Classes/Widgets/Provider/OrderItemsProvider.php index 38fdea4f..deec9d8e 100644 --- a/Classes/Widgets/Provider/OrderItemsProvider.php +++ b/Classes/Widgets/Provider/OrderItemsProvider.php @@ -2,13 +2,6 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\Widgets\Provider; use TYPO3\CMS\Core\Database\Connection; @@ -33,9 +26,6 @@ public function __construct( ); } - /** - * @return array - */ public function getItems(): array { $constraints = []; @@ -51,7 +41,8 @@ public function getItems(): array ) ->from('tx_cart_domain_model_order_item') ->orderBy($this->options['order_by'], $this->options['order_order']) - ->setMaxResults($this->options['limit']); + ->setMaxResults($this->options['limit']) + ; $this->queryBuilder ->leftJoin( @@ -63,7 +54,8 @@ public function getItems(): array $this->queryBuilder->quoteIdentifier('payment.item') ) ) - ->addSelect('payment.name AS payment_name', 'payment.status AS payment_status'); + ->addSelect('payment.name AS payment_name', 'payment.status AS payment_status') + ; if (is_array($this->options['filter']) && is_array($this->options['filter']['payment']) && !empty($this->options['filter']['payment']['status'])) { $constraints[] = $this->queryBuilder->expr()->eq( @@ -85,11 +77,13 @@ public function getItems(): array $this->queryBuilder->quoteIdentifier('shipping.item') ) ) - ->addSelect('shipping.name AS shipping_name', 'shipping.status AS shipping_status'); + ->addSelect('shipping.name AS shipping_name', 'shipping.status AS shipping_status') + ; if (is_array($this->options['filter']) && is_array($this->options['filter']['shipping']) - && !empty($this->options['filter']['shipping']['status'])) { + && !empty($this->options['filter']['shipping']['status']) + ) { $constraints[] = $this->queryBuilder->expr()->eq( 'shipping.status', $this->queryBuilder->createNamedParameter( diff --git a/Classes/Widgets/Provider/OrdersPerDayProvider.php b/Classes/Widgets/Provider/OrdersPerDayProvider.php index d810e81f..ee250114 100644 --- a/Classes/Widgets/Provider/OrdersPerDayProvider.php +++ b/Classes/Widgets/Provider/OrdersPerDayProvider.php @@ -2,16 +2,9 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\Widgets\Provider; -use Extcode\Cart\Constants; +use Extcode\Cart\Configuration\Constants; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Localization\LanguageService; @@ -23,6 +16,7 @@ class OrdersPerDayProvider implements ChartDataProviderInterface { private readonly LanguageService $languageService; + private array $options; public function __construct( @@ -75,9 +69,25 @@ public function getChartData(): array ]; } + public function getOrderItemsInPeriod(int $start, int $end): int + { + $constraints = [ + $this->queryBuilder->expr()->gte($this->options['fieldName'], $start), + $this->queryBuilder->expr()->lte($this->options['fieldName'], $end), + ]; + + $this->queryBuilder + ->count('*') + ->from('tx_cart_domain_model_order_item') + ->where(... $constraints) + ; + + return $this->queryBuilder->executeQuery()->fetchOne(); + } + private function calculateData(): array { - $days = (int)$this->options['days']; + $days = (int) $this->options['days']; $labels = []; $data = []; @@ -103,22 +113,4 @@ private function calculateData(): array $data, ]; } - - public function getOrderItemsInPeriod(int $start, int $end): int - { - $constraints = [ - $this->queryBuilder->expr()->gte($this->options['fieldName'], $start), - $this->queryBuilder->expr()->lte($this->options['fieldName'], $end), - ]; - - $this->queryBuilder - ->count('*') - ->from('tx_cart_domain_model_order_item'); - - if ($constraints !== []) { - $this->queryBuilder->where(... $constraints); - } - - return $this->queryBuilder->executeQuery()->fetchOne(); - } } diff --git a/Classes/Widgets/Provider/TurnoverPerDayProvider.php b/Classes/Widgets/Provider/TurnoverPerDayProvider.php index 9b69ae34..ee13e873 100644 --- a/Classes/Widgets/Provider/TurnoverPerDayProvider.php +++ b/Classes/Widgets/Provider/TurnoverPerDayProvider.php @@ -2,16 +2,9 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\Widgets\Provider; -use Extcode\Cart\Constants; +use Extcode\Cart\Configuration\Constants; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Localization\LanguageServiceFactory; @@ -22,6 +15,7 @@ class TurnoverPerDayProvider implements ChartDataProviderInterface { private readonly LanguageService $languageService; + private array $options; public function __construct( @@ -55,9 +49,27 @@ public function getChartData(): array ]; } + public function getOrderItemsInPeriod(int $start, int $end): float + { + $constraints = [ + $this->queryBuilder->expr()->gte($this->options['fieldName'], $start), + $this->queryBuilder->expr()->lte($this->options['fieldName'], $end), + ]; + + $this->queryBuilder + ->selectLiteral( + $this->queryBuilder->expr()->sum('tx_cart_domain_model_order_item.' . $this->options['sum'], 'turnover') + ) + ->from('tx_cart_domain_model_order_item') + ->where(... $constraints) + ; + + return $this->queryBuilder->executeQuery()->fetchOne() ?? 0; + } + private function calculateData(): array { - $days = (int)$this->options['days']; + $days = (int) $this->options['days']; $labels = []; $data = []; @@ -83,24 +95,4 @@ private function calculateData(): array $data, ]; } - - public function getOrderItemsInPeriod(int $start, int $end): float - { - $constraints = [ - $this->queryBuilder->expr()->gte($this->options['fieldName'], $start), - $this->queryBuilder->expr()->lte($this->options['fieldName'], $end), - ]; - - $this->queryBuilder - ->selectLiteral( - $this->queryBuilder->expr()->sum('tx_cart_domain_model_order_item.' . $this->options['sum'], 'turnover') - ) - ->from('tx_cart_domain_model_order_item'); - - if ($constraints !== []) { - $this->queryBuilder->where(... $constraints); - } - - return $this->queryBuilder->executeQuery()->fetchOne() ?? 0; - } } diff --git a/Configuration/Backend/Modules.php b/Configuration/Backend/Modules.php index 59a4f200..4f30cb9d 100644 --- a/Configuration/Backend/Modules.php +++ b/Configuration/Backend/Modules.php @@ -9,9 +9,7 @@ $_LLL_be = 'LLL:EXT:cart/Resources/Private/Language/locallang_be.xlf:'; -/** - * Definitions for modules provided by EXT:cart - */ +// Definitions for modules provided by EXT:cart return [ 'cart_cart_main' => [ 'access' => '', diff --git a/Configuration/Backend/Provider/OrdersPerDayProvider.php b/Configuration/Backend/Provider/OrdersPerDayProvider.php index 1596fb5b..7828fdc5 100644 --- a/Configuration/Backend/Provider/OrdersPerDayProvider.php +++ b/Configuration/Backend/Provider/OrdersPerDayProvider.php @@ -8,7 +8,7 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Reference; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('extcode.cart.provider.orders_per_day') @@ -23,5 +23,6 @@ 'status' => 'open', ], ], - ]); + ]) + ; }; diff --git a/Configuration/Backend/Provider/PaymentPaidShippingOpenProvider.php b/Configuration/Backend/Provider/PaymentPaidShippingOpenProvider.php index 4fa269e1..e1a33304 100644 --- a/Configuration/Backend/Provider/PaymentPaidShippingOpenProvider.php +++ b/Configuration/Backend/Provider/PaymentPaidShippingOpenProvider.php @@ -8,7 +8,7 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Reference; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('extcode.cart.provider.payment_paid_shipping_open') @@ -23,5 +23,6 @@ 'status' => 'open', ], ], - ]); + ]) + ; }; diff --git a/Configuration/Backend/Provider/TurnoverPerDayProvider.php b/Configuration/Backend/Provider/TurnoverPerDayProvider.php index b82b63be..cfc6b8db 100644 --- a/Configuration/Backend/Provider/TurnoverPerDayProvider.php +++ b/Configuration/Backend/Provider/TurnoverPerDayProvider.php @@ -8,7 +8,7 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Reference; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('extcode.cart.provider.turnover_per_day') @@ -16,5 +16,6 @@ ->arg('$queryBuilder', new Reference('querybuilder.tx_cart_domain_model_order_item')) ->arg('$options', [ 'sum' => 'total_gross', - ]); + ]) + ; }; diff --git a/Configuration/Backend/Widgets/OrdersPerDayWidget.php b/Configuration/Backend/Widgets/OrdersPerDayWidget.php index da2c39b1..04ac2393 100644 --- a/Configuration/Backend/Widgets/OrdersPerDayWidget.php +++ b/Configuration/Backend/Widgets/OrdersPerDayWidget.php @@ -9,7 +9,7 @@ use TYPO3\CMS\Backend\View\BackendViewFactory; use TYPO3\CMS\Dashboard\Widgets\BarChartWidget; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('dashboard.widget.extcode.cart.orders_per_day') @@ -24,5 +24,6 @@ 'iconIdentifier' => 'content-widget-chart-bar', 'height' => 'medium', 'width' => 'medium', - ]); + ]) + ; }; diff --git a/Configuration/Backend/Widgets/PaymentPaidShippingOpenWidget.php b/Configuration/Backend/Widgets/PaymentPaidShippingOpenWidget.php index 2de2712f..17193ac7 100644 --- a/Configuration/Backend/Widgets/PaymentPaidShippingOpenWidget.php +++ b/Configuration/Backend/Widgets/PaymentPaidShippingOpenWidget.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Reference; use TYPO3\CMS\Backend\View\BackendViewFactory; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('dashboard.widget.extcode.cart.payment_paid_shipping_open') @@ -24,5 +24,6 @@ 'iconIdentifier' => 'content-widget-list', 'height' => 'large', 'width' => 'medium', - ]); + ]) + ; }; diff --git a/Configuration/Backend/Widgets/TurnoverPerDayWidget.php b/Configuration/Backend/Widgets/TurnoverPerDayWidget.php index e5114482..00f7c6fc 100644 --- a/Configuration/Backend/Widgets/TurnoverPerDayWidget.php +++ b/Configuration/Backend/Widgets/TurnoverPerDayWidget.php @@ -9,7 +9,7 @@ use TYPO3\CMS\Backend\View\BackendViewFactory; use TYPO3\CMS\Dashboard\Widgets\BarChartWidget; -return function (ContainerConfigurator $configurator) { +return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); $services->set('dashboard.widget.extcode.cart.turnover_per_day') @@ -24,5 +24,6 @@ 'iconIdentifier' => 'content-widget-chart-bar', 'height' => 'medium', 'width' => 'medium', - ]); + ]) + ; }; diff --git a/Configuration/Icons.php b/Configuration/Icons.php index 5a0afe74..950fecae 100644 --- a/Configuration/Icons.php +++ b/Configuration/Icons.php @@ -1,28 +1,32 @@ [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/apps_pagetree_folder_cart_coupons.svg', ], 'apps-pagetree-folder-cart-orders' => [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/apps_pagetree_folder_cart_orders.svg', ], 'apps-pagetree-page-cart-cart' => [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/apps_pagetree_page_cart_cart.svg', ], 'ext-cart-wizard-icon' => [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/cart_plugin_wizard.svg', ], 'ext-cart-module' => [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/module.svg', ], 'ext-cart-module-order' => [ - 'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, + 'provider' => SvgIconProvider::class, 'source' => 'EXT:cart/Resources/Public/Icons/module_orders.svg', ], ]; diff --git a/Configuration/JavaScriptModules.php b/Configuration/JavaScriptModules.php index f576aaaa..ac4873a7 100644 --- a/Configuration/JavaScriptModules.php +++ b/Configuration/JavaScriptModules.php @@ -1,5 +1,7 @@ ['backend'], 'imports' => [ diff --git a/Configuration/Services.php b/Configuration/Services.php index 7579a4ec..3841a171 100644 --- a/Configuration/Services.php +++ b/Configuration/Services.php @@ -4,11 +4,15 @@ namespace Extcode\Cart\Configuration; +use Extcode\Cart\Hooks\ItemsProcFunc; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use TYPO3\CMS\Dashboard\Widgets\BarChartWidget; +use TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManager; +use TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManager; -return function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder) { - if ($containerBuilder->hasDefinition('TYPO3\CMS\Dashboard\Widgets\BarChartWidget')) { +return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void { + if ($containerBuilder->hasDefinition(BarChartWidget::class)) { $containerConfigurator->import('Backend/Provider/PaymentPaidShippingOpenProvider.php'); $containerConfigurator->import('Backend/Widgets/PaymentPaidShippingOpenWidget.php'); @@ -20,14 +24,16 @@ } if ( - $containerBuilder->hasDefinition('TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManager') - && $containerBuilder->hasDefinition('TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManager') + $containerBuilder->hasDefinition(ConfigurationManager::class) + && $containerBuilder->hasDefinition(FormPersistenceManager::class) ) { $services = $containerConfigurator->services(); - $services->set('Extcode\Cart\Hooks\ItemsProcFunc') - ->public(); + $services->set(ItemsProcFunc::class) + ->public() + ; } + $containerConfigurator->import('Services/Configuration.php'); $containerConfigurator->import('Services/ConsoleCommands.php'); }; diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 36b69b7c..9d796d79 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -138,22 +138,6 @@ services: identifier: 'cart--order--update--log-service-update' event: Extcode\Cart\Event\Order\UpdateServiceEvent - Extcode\Cart\Service\CurrencyTranslationServiceInterface: - alias: Extcode\Cart\Service\CurrencyTranslationService - public: true - - Extcode\Cart\Service\PaymentMethodsFromTypoScriptService: - public: true - - Extcode\Cart\Service\ShippingMethodsFromTypoScriptService: - public: true - - Extcode\Cart\Service\SpecialOptionsFromTypoScriptService: - public: true - - Extcode\Cart\Service\TaxClassService: - public: true - querybuilder.tx_cart_domain_model_order_item: class: 'TYPO3\CMS\Core\Database\Query\QueryBuilder' factory: diff --git a/Configuration/Services/Configuration.php b/Configuration/Services/Configuration.php new file mode 100644 index 00000000..7c7a1324 --- /dev/null +++ b/Configuration/Services/Configuration.php @@ -0,0 +1,86 @@ +services() + ; + + $services + ->alias( + CurrencyTranslationLoaderInterface::class, + CurrencyTranslationLoader::class + ) + ; + + $services + ->alias( + PaymentMethodsLoaderInterface::class, + TypoScriptPaymentMethodsLoader::class + ) + ; + + $services + ->set(SiteSetsPaymentMethodsLoader::class) + ->public() + ; + + $services + ->set(TypoScriptPaymentMethodsLoader::class) + ->public() + ; + + $services + ->alias( + ShippingMethodsLoaderInterface::class, + TypoScriptShippingMethodsLoader::class + ) + ; + + $services + ->set(SiteSetsShippingMethodsLoader::class) + ->public() + ; + + $services + ->set(TypoScriptShippingMethodsLoader::class) + ->public() + ; + + $services + ->set(SpecialOptionsLoader::class) + ->public() + ; + + $services + ->alias( + TaxClassLoaderInterface::class, + TypoScriptTaxClassLoader::class + ) + ; + + $services + ->set(SiteSetsTaxClassLoader::class) + ->public() + ; + + $services + ->set(TypoScriptTaxClassLoader::class) + ->public() + ; +}; diff --git a/Configuration/Services/ConsoleCommands.php b/Configuration/Services/ConsoleCommands.php index f26b752b..23d3dcef 100644 --- a/Configuration/Services/ConsoleCommands.php +++ b/Configuration/Services/ConsoleCommands.php @@ -5,7 +5,7 @@ use Extcode\Cart\Command\OrderItemCleanupCommand; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -return static function (ContainerConfigurator $containerConfigurator) { +return static function (ContainerConfigurator $containerConfigurator): void { $services = $containerConfigurator ->services() ->defaults() diff --git a/Configuration/Sets/Payments/config.yaml b/Configuration/Sets/Payments/config.yaml new file mode 100644 index 00000000..be79c0c2 --- /dev/null +++ b/Configuration/Sets/Payments/config.yaml @@ -0,0 +1,2 @@ +name: extcode/cart-payments +label: 'Cart Payment: Vorkasse' diff --git a/Configuration/Sets/Payments/settings.yaml b/Configuration/Sets/Payments/settings.yaml new file mode 100644 index 00000000..46b2f776 --- /dev/null +++ b/Configuration/Sets/Payments/settings.yaml @@ -0,0 +1,13 @@ +extcode: + cart-payments: + countries: + de: + preset: 1 + options: + 1: + title: 'Vorkasse' + extra: 0.0 + taxClassId: 1 + status: 'open' + at: .de + ch: .de diff --git a/Configuration/Sets/Shippings/config.yaml b/Configuration/Sets/Shippings/config.yaml new file mode 100644 index 00000000..6f60d14d --- /dev/null +++ b/Configuration/Sets/Shippings/config.yaml @@ -0,0 +1,2 @@ +name: extcode/cart-shippings +label: 'Cart Shippings: Standard' diff --git a/Configuration/Sets/Shippings/settings.yaml b/Configuration/Sets/Shippings/settings.yaml new file mode 100644 index 00000000..b5d12f37 --- /dev/null +++ b/Configuration/Sets/Shippings/settings.yaml @@ -0,0 +1,13 @@ +extcode: + cart-shippings: + countries: + de: + preset: 1 + options: + 1: + title: 'Standard' + extra: 7.95 + taxClassId: 1 + status: 'open' + at: .de + ch: .de \ No newline at end of file diff --git a/Configuration/Sets/TaxClass/config.yaml b/Configuration/Sets/TaxClass/config.yaml new file mode 100644 index 00000000..2f543aad --- /dev/null +++ b/Configuration/Sets/TaxClass/config.yaml @@ -0,0 +1,2 @@ +name: extcode/cart-taxclasses +label: 'Cart Tax Classes' diff --git a/Configuration/Sets/TaxClass/settings.yaml b/Configuration/Sets/TaxClass/settings.yaml new file mode 100644 index 00000000..7ebb7ac9 --- /dev/null +++ b/Configuration/Sets/TaxClass/settings.yaml @@ -0,0 +1,14 @@ +extcode: + cart-taxclasses: + 1: + value: 19 + calc: 0.19 + name: 'normal' + 2: + value: 7 + calc: 0.07 + name: 'reduced' + 3: + value: 0 + calc: 0.00 + name: 'free' diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php index 1b367ba8..6e09eb02 100644 --- a/Configuration/TCA/Overrides/pages.php +++ b/Configuration/TCA/Overrides/pages.php @@ -1,27 +1,59 @@ $_LLL_db . 'pages.doktype.181', - 'value' => 181, - 'icon' => 'apps-pagetree-page-cart-cart', - ]; - $GLOBALS['TCA']['pages']['columns']['module']['config']['items'][] = [ - 'label' => $_LLL_db . 'tcarecords-pages-contains.cart_coupons', - 'value' => 'coupons', - 'icon' => 'apps-pagetree-folder-cart-coupons', - ]; - $GLOBALS['TCA']['pages']['columns']['module']['config']['items'][] = [ - 'label' => $_LLL_db . 'tcarecords-pages-contains.cart_orders', - 'value' => 'orders', - 'icon' => 'apps-pagetree-folder-cart-orders', - ]; - - $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][181] = 'apps-pagetree-page-cart-cart'; - $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes']['contains-coupons'] = 'apps-pagetree-folder-cart-coupons'; - $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes']['contains-orders'] = 'apps-pagetree-folder-cart-orders'; -}); + ArrayUtility::mergeRecursiveWithOverrule( + $GLOBALS['TCA']['pages'], + [ + 'columns' => [ + 'doktype' => [ + 'config' => [ + 'items' => [ + 1776199422 => [ + 'label' => $_LLL_db . 'pages.doktype.' . Constants::DOKTYPE_CART_CART, + 'value' => Constants::DOKTYPE_CART_CART, + 'icon' => 'apps-pagetree-page-cart-cart', + 'group' => 'default', + ], + ], + ], + ], + 'module' => [ + 'config' => [ + 'items' => [ + 1776199535 => [ + 'label' => $_LLL_db . 'tcarecords-pages-contains.cart_coupons', + 'value' => 'coupons', + 'icon' => 'apps-pagetree-folder-cart-coupons', + ], + 1776199573 => [ + 'label' => $_LLL_db . 'tcarecords-pages-contains.cart_orders', + 'value' => 'orders', + 'icon' => 'apps-pagetree-folder-cart-orders', + ], + ], + ], + ], + ], + 'ctrl' => [ + 'typeicon_classes' => [ + Constants::DOKTYPE_CART_CART => 'apps-pagetree-page-cart-cart', + 'contains-coupons' => 'apps-pagetree-folder-cart-coupons', + 'contains-orders' => 'apps-pagetree-folder-cart-orders', + ], + ], + 'types' => [ + Constants::DOKTYPE_CART_CART => $GLOBALS['TCA']['pages']['types'][(string) PageRepository::DOKTYPE_DEFAULT], + ], + ] + ); +})(); diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php index 846a4ff4..f561a2d9 100644 --- a/Configuration/TCA/Overrides/sys_template.php +++ b/Configuration/TCA/Overrides/sys_template.php @@ -1,13 +1,15 @@ $pluginConfig) { - $pluginSignature = 'cart_' . strtolower($pluginName); + $pluginSignature = 'cart_' . mb_strtolower($pluginName); + + $flexFormPath = 'EXT:cart/Configuration/FlexForms/' . $pluginName . 'Plugin.xml'; + if (file_exists(GeneralUtility::getFileAbsFileName($flexFormPath))) { + $flexFormPath = 'FILE:' . $flexFormPath; + } else { + $flexFormPath = ''; + } ExtensionUtility::registerPlugin( 'Cart', $pluginName, $_LLL_db . 'tx_cart.plugin.' . $pluginSignature, $pluginConfig['iconIdentifier'], - 'cart' + 'cart', + $_LLL_db . 'tx_cart.plugin.' . $pluginSignature . '.description', + $flexFormPath ); - - $flexFormPath = 'EXT:cart/Configuration/FlexForms/' . $pluginName . 'Plugin.xml'; - if (file_exists(GeneralUtility::getFileAbsFileName($flexFormPath))) { - ExtensionManagementUtility::addPiFlexFormValue( - '*', - 'FILE:' . $flexFormPath, - $pluginSignature - ); - // Add the FlexForm to the show item list - ExtensionManagementUtility::addToAllTCAtypes( - 'tt_content', - '--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.plugin, pi_flexform', - $pluginSignature, - 'after:palette:headers' - ); - } } -}); +})(); diff --git a/Configuration/TCA/tx_cart_domain_model_cart.php b/Configuration/TCA/tx_cart_domain_model_cart.php index 244445fd..25f79f01 100644 --- a/Configuration/TCA/tx_cart_domain_model_cart.php +++ b/Configuration/TCA/tx_cart_domain_model_cart.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => '', ], 'types' => [ '1' => [ - 'showitem' - => 'pid, f_hash, s_hash, fe_user, was_ordered, order_item, serialized_cart', + 'showitem' => 'pid, f_hash, s_hash, fe_user, was_ordered, order_item, serialized_cart', ], ], 'palettes' => [ diff --git a/Configuration/TCA/tx_cart_domain_model_coupon.php b/Configuration/TCA/tx_cart_domain_model_coupon.php index 5f01fa5a..a8641e8e 100644 --- a/Configuration/TCA/tx_cart_domain_model_coupon.php +++ b/Configuration/TCA/tx_cart_domain_model_coupon.php @@ -1,5 +1,7 @@ 'starttime', 'endtime' => 'endtime', ], - 'searchFields' => 'title', 'iconfile' => 'EXT:cart/Resources/Public/Icons/tx_cart_domain_model_coupon.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_address.php b/Configuration/TCA/tx_cart_domain_model_order_address.php index ab92024d..4a9b9b5b 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_address.php +++ b/Configuration/TCA/tx_cart_domain_model_order_address.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'first_name, last_name, street, zip, city', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Address.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_discount.php b/Configuration/TCA/tx_cart_domain_model_order_discount.php index 6cb12d0f..cc238adc 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_discount.php +++ b/Configuration/TCA/tx_cart_domain_model_order_discount.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'title', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Discount.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_item.php b/Configuration/TCA/tx_cart_domain_model_order_item.php index 43b5fb10..ae823619 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_item.php +++ b/Configuration/TCA/tx_cart_domain_model_order_item.php @@ -1,5 +1,7 @@ 't3_origuid', 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'order_number, invoice_number', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Item.svg', ], 'types' => [ '1' => [ - 'showitem' - => 'pid, fe_user, + 'showitem' => 'pid, fe_user, --palette--;' . $_LLL . ':tx_cart_domain_model_order_item.palettes.numbers;numbers, --palette--;' . $_LLL . ':tx_cart_domain_model_order_item.palettes.addresses;addresses, --palette--;' . $_LLL . ':tx_cart_domain_model_order_item.palettes.price;price, diff --git a/Configuration/TCA/tx_cart_domain_model_order_payment.php b/Configuration/TCA/tx_cart_domain_model_order_payment.php index e8e0e091..e277bf11 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_payment.php +++ b/Configuration/TCA/tx_cart_domain_model_order_payment.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'name,value,calc,sum,', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Payment.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_product.php b/Configuration/TCA/tx_cart_domain_model_order_product.php index ca16e8b2..17b67282 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_product.php +++ b/Configuration/TCA/tx_cart_domain_model_order_product.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'sku,title', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Product.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_productadditional.php b/Configuration/TCA/tx_cart_domain_model_order_productadditional.php index 2dfe85ec..c27f54fa 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_productadditional.php +++ b/Configuration/TCA/tx_cart_domain_model_order_productadditional.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'additional_type,additional_key,additional_value', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/ProductAdditional.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_shipping.php b/Configuration/TCA/tx_cart_domain_model_order_shipping.php index b92882e7..940e012e 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_shipping.php +++ b/Configuration/TCA/tx_cart_domain_model_order_shipping.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'name,value,calc,sum,', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Shipping.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_tax.php b/Configuration/TCA/tx_cart_domain_model_order_tax.php index d2c26eb2..57c14d73 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_tax.php +++ b/Configuration/TCA/tx_cart_domain_model_order_tax.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => '', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Tax.svg', 'type' => 'record_type', ], diff --git a/Configuration/TCA/tx_cart_domain_model_order_taxclass.php b/Configuration/TCA/tx_cart_domain_model_order_taxclass.php index ab9cac32..c77685f7 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_taxclass.php +++ b/Configuration/TCA/tx_cart_domain_model_order_taxclass.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'title,value,calc', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/TaxClass.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_order_transaction.php b/Configuration/TCA/tx_cart_domain_model_order_transaction.php index 54bce6b7..f641afab 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_transaction.php +++ b/Configuration/TCA/tx_cart_domain_model_order_transaction.php @@ -1,5 +1,7 @@ true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'txn_id', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Transaction.svg', ], 'hideTable' => 1, diff --git a/Configuration/TCA/tx_cart_domain_model_tag.php b/Configuration/TCA/tx_cart_domain_model_tag.php index 2dd64191..8396661b 100644 --- a/Configuration/TCA/tx_cart_domain_model_tag.php +++ b/Configuration/TCA/tx_cart_domain_model_tag.php @@ -1,5 +1,7 @@ 'starttime', 'endtime' => 'endtime', ], - 'searchFields' => 'title', 'iconfile' => 'EXT:cart/Resources/Public/Icons/tx_cart_domain_model_tag.svg', ], 'hideTable' => 1, diff --git a/Configuration/TypoScript/Payments/setup.typoscript b/Configuration/TypoScript/Payments/setup.typoscript new file mode 100644 index 00000000..f5fbaa01 --- /dev/null +++ b/Configuration/TypoScript/Payments/setup.typoscript @@ -0,0 +1,19 @@ +plugin.tx_cart { + payments { + countries { + de { + preset = 1 + options { + 1 { + title = Vorkasse + extra = 0.00 + taxClassId = 1 + status = open + } + } + } + at < .de + ch < .de + } + } +} diff --git a/Configuration/TypoScript/Settings/countries.typoscript b/Configuration/TypoScript/Settings/countries.typoscript new file mode 100644 index 00000000..27aa7c24 --- /dev/null +++ b/Configuration/TypoScript/Settings/countries.typoscript @@ -0,0 +1,21 @@ +plugin.tx_cart { + settings { + countries { + preset = 1 + options { + 1 { + code = de + label = Deutschland + } + 2 { + code = at + label = Österreich + } + 3 { + code = ch + label = Schweiz + } + } + } + } +} diff --git a/Configuration/TypoScript/Settings/currencies.typoscript b/Configuration/TypoScript/Settings/currencies.typoscript new file mode 100644 index 00000000..d2a81d9b --- /dev/null +++ b/Configuration/TypoScript/Settings/currencies.typoscript @@ -0,0 +1,23 @@ +plugin.tx_cart { + settings { + currencies { + preset = 1 + options { + 1 { + code = EUR + sign = € + translation = 1.00 + } + } + } + + format.currency { + currencySign = {$plugin.tx_cart.settings.format.currency.currencySign} + decimalSeparator = {$plugin.tx_cart.settings.format.currency.decimalSeparator} + thousandsSeparator = {$plugin.tx_cart.settings.format.currency.thousandsSeparator} + prependCurrency = {$plugin.tx_cart.settings.format.currency.prependCurrency} + separateCurrency = {$plugin.tx_cart.settings.format.currency.separateCurrency} + decimals = {$plugin.tx_cart.settings.format.currency.decimals} + } + } +} diff --git a/Configuration/TypoScript/Settings/validation.typoscript b/Configuration/TypoScript/Settings/validation.typoscript new file mode 100644 index 00000000..2b118736 --- /dev/null +++ b/Configuration/TypoScript/Settings/validation.typoscript @@ -0,0 +1,237 @@ +plugin.tx_cart { + settings { + validation { + orderItem { + fields { + acceptTermsAndConditions { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.options.is} + } + acceptRevocationInstruction { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.options.is} + } + acceptPrivacyPolicy { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.options.is} + } + } + } + billingAddress { + fields { + salutation { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.salutation.validator} + } + title { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.title.validator} + } + firstName { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.firstName.validator} + } + lastName { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.lastName.validator} + } + email { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.email.validator} + } + phone { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.phone.validator} + } + fax { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.fax.validator} + } + company { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.company.validator} + } + taxIdentificationNumber { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.taxIdentificationNumber.validator} + } + street { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.street.validator} + } + streetNumber { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.streetNumber.validator} + } + addition { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.addition.validator} + } + zip { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.zip.validator} + } + city { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.city.validator} + } + country { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.country.validator} + } + } + } + shippingAddress { + fields { + salutation { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.salutation.validator} + } + title { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.title.validator} + } + firstName { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.firstName.validator} + } + lastName { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.lastName.validator} + } + email { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.email.validator} + } + phone { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.phone.validator} + } + fax { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.fax.validator} + } + company { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.company.validator} + } + taxIdentificationNumber { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.taxIdentificationNumber.validator} + } + street { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.street.validator} + } + streetNumber { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.streetNumber.validator} + } + addition { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.addition.validator} + } + zip { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.zip.validator} + } + city { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.city.validator} + } + country { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.country.validator} + } + } + } + } + + validation { + orderItem { + fields { + acceptTermsAndConditions { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.options.is} + } + acceptRevocationInstruction { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.options.is} + } + acceptPrivacyPolicy { + validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.validator} + options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.options.is} + } + } + } + billingAddress { + fields { + salutation { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.salutation.validator} + } + title { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.title.validator} + } + firstName { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.firstName.validator} + } + lastName { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.lastName.validator} + } + email { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.email.validator} + } + phone { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.phone.validator} + } + fax { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.fax.validator} + } + company { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.company.validator} + } + taxIdentificationNumber { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.taxIdentificationNumber.validator} + } + street { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.street.validator} + } + streetNumber { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.streetNumber.validator} + } + addition { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.addition.validator} + } + zip { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.zip.validator} + } + city { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.city.validator} + } + country { + validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.country.validator} + } + } + } + shippingAddress { + fields { + salutation { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.salutation.validator} + } + title { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.title.validator} + } + firstName { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.firstName.validator} + } + lastName { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.lastName.validator} + } + email { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.email.validator} + } + phone { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.phone.validator} + } + fax { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.fax.validator} + } + company { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.company.validator} + } + taxIdentificationNumber { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.taxIdentificationNumber.validator} + } + street { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.street.validator} + } + streetNumber { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.streetNumber.validator} + } + addition { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.addition.validator} + } + zip { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.zip.validator} + } + city { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.city.validator} + } + country { + validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.country.validator} + } + } + } + } + } +} diff --git a/Configuration/TypoScript/Shippings/setup.typoscript b/Configuration/TypoScript/Shippings/setup.typoscript new file mode 100644 index 00000000..e3f58c4e --- /dev/null +++ b/Configuration/TypoScript/Shippings/setup.typoscript @@ -0,0 +1,19 @@ +plugin.tx_cart { + shippings { + countries { + de { + preset = 1 + options { + 1 { + title = Standard + extra = 0.00 + taxClassId = 1 + status = open + } + } + } + at < .de + ch < .de + } + } +} diff --git a/Configuration/TypoScript/TaxClasses/setup.typoscript b/Configuration/TypoScript/TaxClasses/setup.typoscript new file mode 100644 index 00000000..08d7c6d9 --- /dev/null +++ b/Configuration/TypoScript/TaxClasses/setup.typoscript @@ -0,0 +1,19 @@ +plugin.tx_cart { + taxClasses { + 1 { + value = {$plugin.tx_cart.taxClasses.1.value} + calc = {$plugin.tx_cart.taxClasses.1.calc} + name = {$plugin.tx_cart.taxClasses.1.name} + } + 2 { + value = {$plugin.tx_cart.taxClasses.2.value} + calc = {$plugin.tx_cart.taxClasses.2.calc} + name = {$plugin.tx_cart.taxClasses.2.name} + } + 3 { + value = {$plugin.tx_cart.taxClasses.3.value} + calc = {$plugin.tx_cart.taxClasses.3.calc} + name = {$plugin.tx_cart.taxClasses.3.name} + } + } +} diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript index addd23b0..c83f7456 100755 --- a/Configuration/TypoScript/setup.typoscript +++ b/Configuration/TypoScript/setup.typoscript @@ -71,44 +71,6 @@ plugin.tx_cart { addToCartByAjax = {$plugin.tx_cart.settings.addToCartByAjax} } - countries { - preset = 1 - options { - 1 { - code = de - label = Deutschland - } - 2 { - code = at - label = Österreich - } - 3 { - code = ch - label = Schweiz - } - } - } - - currencies { - preset = 1 - options { - 1 { - code = EUR - sign = € - translation = 1.00 - } - } - } - - format.currency { - currencySign = {$plugin.tx_cart.settings.format.currency.currencySign} - decimalSeparator = {$plugin.tx_cart.settings.format.currency.decimalSeparator} - thousandsSeparator = {$plugin.tx_cart.settings.format.currency.thousandsSeparator} - prependCurrency = {$plugin.tx_cart.settings.format.currency.prependCurrency} - separateCurrency = {$plugin.tx_cart.settings.format.currency.separateCurrency} - decimals = {$plugin.tx_cart.settings.format.currency.decimals} - } - showAction { media { image { @@ -155,180 +117,14 @@ plugin.tx_cart { } } } - - validation { - orderItem { - fields { - acceptTermsAndConditions { - validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.validator} - options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptTermsAndConditions.options.is} - } - acceptRevocationInstruction { - validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.validator} - options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptRevocationInstruction.options.is} - } - acceptPrivacyPolicy { - validator = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.validator} - options.is = {$plugin.tx_cart.settings.validation.orderItem.fields.acceptPrivacyPolicy.options.is} - } - } - } - billingAddress { - fields { - salutation { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.salutation.validator} - } - title { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.title.validator} - } - firstName { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.firstName.validator} - } - lastName { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.lastName.validator} - } - email { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.email.validator} - } - phone { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.phone.validator} - } - fax { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.fax.validator} - } - company { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.company.validator} - } - taxIdentificationNumber { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.taxIdentificationNumber.validator} - } - street { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.street.validator} - } - streetNumber { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.streetNumber.validator} - } - addition { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.addition.validator} - } - zip { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.zip.validator} - } - city { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.city.validator} - } - country { - validator = {$plugin.tx_cart.settings.validation.billingAddress.fields.country.validator} - } - } - } - shippingAddress { - fields { - salutation { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.salutation.validator} - } - title { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.title.validator} - } - firstName { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.firstName.validator} - } - lastName { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.lastName.validator} - } - email { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.email.validator} - } - phone { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.phone.validator} - } - fax { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.fax.validator} - } - company { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.company.validator} - } - taxIdentificationNumber { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.taxIdentificationNumber.validator} - } - street { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.street.validator} - } - streetNumber { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.streetNumber.validator} - } - addition { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.addition.validator} - } - zip { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.zip.validator} - } - city { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.city.validator} - } - country { - validator = {$plugin.tx_cart.settings.validation.shippingAddress.fields.country.validator} - } - } - } - } - } - - taxClasses { - 1 { - value = {$plugin.tx_cart.taxClasses.1.value} - calc = {$plugin.tx_cart.taxClasses.1.calc} - name = {$plugin.tx_cart.taxClasses.1.name} - } - 2 { - value = {$plugin.tx_cart.taxClasses.2.value} - calc = {$plugin.tx_cart.taxClasses.2.calc} - name = {$plugin.tx_cart.taxClasses.2.name} - } - 3 { - value = {$plugin.tx_cart.taxClasses.3.value} - calc = {$plugin.tx_cart.taxClasses.3.calc} - name = {$plugin.tx_cart.taxClasses.3.name} - } - } - - shippings { - countries { - de { - preset = 1 - options { - 1 { - title = Standard - extra = 0.00 - taxClassId = 1 - status = open - } - } - } - at < .de - ch < .de - } - } - - payments { - countries { - de { - preset = 1 - options { - 1 { - title = Vorkasse - extra = 0.00 - taxClassId = 1 - status = open - } - } - } - at < .de - ch < .de - } } } +@import 'EXT:cart/Configuration/TypoScript/Settings/*.typoscript' +@import 'EXT:cart/Configuration/TypoScript/TaxClasses/setup.typoscript' +@import 'EXT:cart/Configuration/TypoScript/Payments/setup.typoscript +@import 'EXT:cart/Configuration/TypoScript/Shippings/setup.typoscript + # use this lib to add custom information or content elements to your email template temp.cartMailContentElement = RECORDS diff --git a/Documentation/Changelog/12.0/Breaking-756-AddSiteSetConfigurationLoader.rst b/Documentation/Changelog/12.0/Breaking-756-AddSiteSetConfigurationLoader.rst new file mode 100644 index 00000000..6fa4cbfb --- /dev/null +++ b/Documentation/Changelog/12.0/Breaking-756-AddSiteSetConfigurationLoader.rst @@ -0,0 +1,46 @@ +.. include:: ../../Includes.rst.txt + +================================================== +Breaking: #756 - Add Site Set Configuration Loader +================================================== + +See `Issue 756 `__ + +Description +=========== + +Regarding to the new feature configuring cart by site sets the +code was restructured and the services to load configurations +moved to `Configuration/Loader`. + +The interfaces was moved form `Service` to `Configuration`: + +`Classes/Service/CurrencyTranslationServiceInterface.php` => `Classes/Configuration/Loader/CurrencyTranslationLoaderInterface.php` +`Classes/Service/TaxClassServiceInterface.php` => `Classes/Configuration/Loader/TaxClassLoaderInterface.php` +`Classes/Service/PaymentMethodsServiceInterface.php` => `Classes/Configuration/Loader/PaymentMethodsLoaderInterface.php` +`Classes/Service/ShippingMethodsServiceInterface.php` => `Classes/Configuration/Loader/ShippingMethodsLoaderInterface.php` +`Classes/Service/SpecialOptionsServiceInterface.php` => `Classes/Configuration/Loader/SpecialOptionsLoaderInterface.php` + +The classes was moved form `Service` to `Configuration` or `Configuration/TypoScript`: + +`Classes/Service/CurrencyTranslationService.php` => `Classes/Configuration/Loader/CurrencyTranslationLoader.php` +`Classes/Service/PaymentMethodsFromTypoScriptService.php` => `Classes/Configuration/Loader/TypoScript/PaymentMethodsLoader.php` +`Classes/Service/ShippingMethodsFromTypoScriptService.php` => `Classes/Configuration/Loader/TypoScript/ShippingMethodsLoader.php` +`Classes/Service/SpecialOptionsFromTypoScriptService.php` => `Classes/Configuration/Loader/TypoScript/SpecialOptionsLoader.php` +`Classes/Service/TaxClassService.php` => `Classes/Configuration/Loader/TypoScript/TaxClassLoader.php` + +Affected Installations +====================== + +All installations implementing one of the service interfaces or extending one of the +services. + +Migration +========= + +Use interfaces from new namespace. + +.. CAUTION:: + All configuration loaders are now final. If your own configuration loader only extends the + service, you have to copy the code from the final configuration loader class and add your + changes in your own class. Add or update an alias to your own configuration loader class. diff --git a/Documentation/Changelog/12.0/Feature-752-AddLogForOrders.rst b/Documentation/Changelog/12.0/Feature-752-AddLogForOrders.rst new file mode 100644 index 00000000..cc2e5d72 --- /dev/null +++ b/Documentation/Changelog/12.0/Feature-752-AddLogForOrders.rst @@ -0,0 +1,21 @@ +.. include:: ../../Includes.rst.txt + +=========================================== +Feature: #752 - Add LogInterface for orders +=========================================== + +See `Issue 752 `__ + +Description +=========== + +Currently there is no logging for an order. An editor can +change the shipping status, but nobody knows, when this is +happend. + +Impact +====== + +No direct impact. + +.. index:: API diff --git a/Documentation/Changelog/12.0/Feature-756-AddSiteSetConfigurationLoader.rst b/Documentation/Changelog/12.0/Feature-756-AddSiteSetConfigurationLoader.rst new file mode 100644 index 00000000..21ab8ee0 --- /dev/null +++ b/Documentation/Changelog/12.0/Feature-756-AddSiteSetConfigurationLoader.rst @@ -0,0 +1,41 @@ +.. include:: ../../Includes.rst.txt + +================================================= +Feature: #756 - Add Site Set Configuration Loader +================================================= + +See `Issue 756 `__ + +Description +=========== + +If you want to switch to the Site Sets configuration loader, +you have to alias the new classes. + +You can decide to move some configuration to Site Sets and +leave others in TypoScript + +.. code-block:: php + + $services + ->alias( + \Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface::class, + \Extcode\Cart\Configuration\Loader\SiteSets\PaymentMethodsLoader::class + ) + ; + +.. code-block:: yaml + + services: + Extcode\Cart\Configuration\Loader\PaymentMethodsLoaderInterface: + alias: Extcode\Cart\Configuration\Loader\SiteSets\PaymentMethodsLoader + +.. NOTE:: + Not all configurations can be moved to Site Sets with the 12.0.0 release. + Others will follow in the near future with a minor release. + +Impact +====== + +No direct impact. + diff --git a/Documentation/Changelog/12.0/Index.rst b/Documentation/Changelog/12.0/Index.rst new file mode 100644 index 00000000..f71bf7c3 --- /dev/null +++ b/Documentation/Changelog/12.0/Index.rst @@ -0,0 +1,30 @@ +.. include:: ../../Includes.rst.txt + +12.0 Changes +============ + +**Table of contents** + +.. contents:: + :local: + :depth: 1 + +Breaking +-------- + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :glob: + + Breaking-* + +Features +-------- + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :glob: + + Feature-* diff --git a/Documentation/Changelog/Index.rst b/Documentation/Changelog/Index.rst index f4c73d9d..bc90b960 100644 --- a/Documentation/Changelog/Index.rst +++ b/Documentation/Changelog/Index.rst @@ -10,6 +10,7 @@ ChangeLog :maxdepth: 5 :titlesonly: + 12.0/Index 11.7/Index 11.3/Index 11.1/Index diff --git a/Documentation/Introduction/Index.rst b/Documentation/Introduction/Index.rst index 20694a56..49eb4266 100644 --- a/Documentation/Introduction/Index.rst +++ b/Documentation/Introduction/Index.rst @@ -86,13 +86,6 @@ Examples of websites which use this extension as e-commerce solution. `www.liebman-design-import.com `__ -.. figure:: ../Images/Examples/weingut-isele.de.png - :width: 640 - :alt: Cart of Weingut Isele - :class: with-shadow - - `www.weingut-isele.de `__ - **Table of contents** .. toctree:: @@ -101,4 +94,3 @@ Examples of websites which use this extension as e-commerce solution. Support/Index Sponsoring/Index - NoteOfThanks/Index diff --git a/Documentation/Introduction/NoteOfThanks/Index.rst b/Documentation/Introduction/NoteOfThanks/Index.rst deleted file mode 100644 index 0d5e7181..00000000 --- a/Documentation/Introduction/NoteOfThanks/Index.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. include:: ../../Includes.rst.txt - -============== -Note of thanks -============== - -A big thank you goes `Tritum GmbH `__ for the many hours I was allowed to work on Cart. - -In particular, I would like to thank Björn. He always has an open ear. He contributed his opinion to many questions -and decisions. Without him, Cart would not be what it is today. - -Another thanks goes to the testers for their feedback and understanding when I made changes to the data model again and -again. - -A big thank you also goes out to all the supporters on github. diff --git a/Documentation/Introduction/Sponsoring/Index.rst b/Documentation/Introduction/Sponsoring/Index.rst index a2fce503..78671a83 100644 --- a/Documentation/Introduction/Sponsoring/Index.rst +++ b/Documentation/Introduction/Sponsoring/Index.rst @@ -9,8 +9,5 @@ If there is a feature that has not yet been implemented in Cart, you can contact There is also the possibility to support the further development independently of new functions. * Ask for an invoice. -* `GitHub Sponsors `_ * `paypal.me `_ -Sponsors --------- diff --git a/Documentation/guides.xml b/Documentation/guides.xml index 3ce88ac9..3ed5ce12 100644 --- a/Documentation/guides.xml +++ b/Documentation/guides.xml @@ -11,9 +11,9 @@ interlink-shortcode="extcode/cart" /> diff --git a/README.md b/README.md index aee99e82..603ce5fd 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,11 @@ Sometimes minor versions also result in minor adjustments to own templates or co | Cart | TYPO3 | PHP | Support/Development | |--------|------------|-----------|--------------------------------------| -| 11.x.x | 13.4 | 8.2 - 8.5 | Features, Bugfixes, Security Updates | -| 10.x.x | 12.4 | 8.1 - 8.5 | Bugfixes, Security Updates | -| 9.x.x | 12.4 | 8.1 - 8.4 | Security Updates | -| 8.x.x | 10.4, 11.5 | 7.2+ | Security Updates | +| 12.x.x | 14.3 | 8.2 - 8.5 | Features, Bugfixes, Security Updates | +| 11.x.x | 13.4 | 8.2 - 8.5 | Bugfixes, Security Updates | +| 10.x.x | 12.4 | 8.1 - 8.5 | Security Updates | +| 9.x.x | 12.4 | 8.1 - 8.4 | | +| 8.x.x | 10.4, 11.5 | 7.2+ | | | 7.x.x | 10.4 | 7.2 - 7.4 | | | 6.x.x | 9.5 | 7.2 - 7.4 | | | 5.x.x | 8.7 | 7.0 - 7.4 | | @@ -79,7 +80,6 @@ News uses **semantic versioning** which basically means for you, that ## 4. Sponsoring * Ask for an invoice. -* [GitHub Sponsors](https://github.com/sponsors/extcode) * [PayPal.Me](https://paypal.me/extcart) [1]: https://docs.typo3.org/typo3cms/extensions/cart/ diff --git a/Tests/Fixtures/BackendUser.php b/Tests/Fixtures/BackendUser.php new file mode 100644 index 00000000..6578a28c --- /dev/null +++ b/Tests/Fixtures/BackendUser.php @@ -0,0 +1,15 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '0', + 'username' => 'admin', + 'password' => '$1$tCrlLajZ$C0sikFQQ3SWaFAZ1Me0Z/1', + 'admin' => 1, + ], + ], +]; diff --git a/Tests/Fixtures/BaseDatabase.php b/Tests/Fixtures/BaseDatabase.php index 8b7f86d4..03b4bac8 100644 --- a/Tests/Fixtures/BaseDatabase.php +++ b/Tests/Fixtures/BaseDatabase.php @@ -16,5 +16,23 @@ 'deleted' => '0', 'is_siteroot' => '1', ], + 100 => [ + 'uid' => '101', + 'pid' => '0', + 'title' => 'Shop', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/shop-folder', + 'sorting' => '128', + 'deleted' => '0', + ], + 104 => [ + 'uid' => '105', + 'pid' => '101', + 'title' => 'Orders', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/orders-folder', + 'sorting' => '128', + 'deleted' => '0', + ], ], ]; diff --git a/Tests/Functional/Command/AbstractCommandTestCase.php b/Tests/Functional/Command/AbstractCommandTestCase.php index 99953e37..21d184be 100644 --- a/Tests/Functional/Command/AbstractCommandTestCase.php +++ b/Tests/Functional/Command/AbstractCommandTestCase.php @@ -11,12 +11,16 @@ * LICENSE file that was distributed with this source code. */ -use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use Codappix\Typo3PhpDatasets\TestingFramework; use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; abstract class AbstractCommandTestCase extends FunctionalTestCase { + use TestingFramework; + + private const FORM_PROTECTION_SESSION_TOKEN = 'testtoken'; + protected function setUp(): void { $this->testExtensionsToLoad = [ @@ -25,28 +29,27 @@ protected function setUp(): void $this->coreExtensionsToLoad = [ 'typo3/cms-beuser', + 'typo3/cms-core', ]; $this->pathsToLinkInTestInstance['typo3conf/ext/cart/Tests/Functional/Fixtures/Import/Sites/'] = 'typo3conf/sites'; parent::setUp(); - $backendUser = self::createStub(BackendUserAuthentication::class); - $backendUser->method('isAdmin')->willReturn(true); - $backendUser->method('recordEditAccessInternals')->willReturn(true); - $backendUser->workspace = 0; - $backendUser->user = [ - 'uid' => 1, - 'admin' => true, - ]; - $GLOBALS['BE_USER'] = $backendUser; + $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BaseDatabase.php'); + $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BackendUser.php'); + + $this->setUpBackendUser(1) + ->getSession() + ->set('formProtectionSessionToken', self::FORM_PROTECTION_SESSION_TOKEN) + ; + $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('en'); } protected function tearDown(): void { unset( - $GLOBALS['BE_USER'], $GLOBALS['LANG'] ); diff --git a/Tests/Functional/Command/OrderItemCleanupCommandTest.php b/Tests/Functional/Command/OrderItemCleanupCommandTest.php index d6c95fcd..75db2c9c 100644 --- a/Tests/Functional/Command/OrderItemCleanupCommandTest.php +++ b/Tests/Functional/Command/OrderItemCleanupCommandTest.php @@ -33,16 +33,16 @@ public function doesNotDeletesRecordsCreatedAfterCutOffDate(): void (new PhpDataSet())->import([ 'tx_cart_domain_model_order_item' => [ [ - 'crdate' => (int)(new DateTimeImmutable('2026-01-21'))->format('U'), + 'crdate' => (new DateTimeImmutable('2026-01-21'))->format('U'), ], [ - 'crdate' => (int)(new DateTimeImmutable('2025-01-21'))->format('U'), + 'crdate' => (new DateTimeImmutable('2025-01-21'))->format('U'), ], [ - 'crdate' => (int)(new DateTimeImmutable('2025-01-02'))->format('U'), + 'crdate' => (new DateTimeImmutable('2025-01-02'))->format('U'), ], [ - 'crdate' => (int)(new DateTimeImmutable('2025-01-01'))->format('U'), + 'crdate' => (new DateTimeImmutable('2025-01-01'))->format('U'), ], ], ]); @@ -67,10 +67,10 @@ public function deletesRecordsCreatedBeforeCutOffDate(): void (new PhpDataSet())->import([ 'tx_cart_domain_model_order_item' => [ [ - 'crdate' => (int)(new DateTimeImmutable('2024-12-31'))->format('U'), + 'crdate' => (new DateTimeImmutable('2024-12-31'))->format('U'), ], [ - 'crdate' => (int)(new DateTimeImmutable('2024-10-12'))->format('U'), + 'crdate' => (new DateTimeImmutable('2024-10-12'))->format('U'), ], ], ]); @@ -94,62 +94,62 @@ public function deletesRelatedRecordsCreatedBeforeCutOffDate(): void (new PhpDataSet())->import([ 'tx_cart_domain_model_order_item' => [ [ - 'uid' => 10, - 'products' => 2, - 'billing_address' => 1, - 'shipping_address' => 1, - 'payment' => 1, - 'shipping' => 1, - 'tax_class' => 3, - 'crdate' => (int)(new DateTimeImmutable('2024-12-31'))->format('U'), + 'uid' => '10', + 'products' => '2', + 'billing_address' => '1', + 'shipping_address' => '1', + 'payment' => '1', + 'shipping' => '1', + 'tax_class' => '3', + 'crdate' => (new DateTimeImmutable('2024-12-31'))->format('U'), ], ], 'tx_cart_domain_model_order_product' => [ [ - 'uid' => 1, - 'item' => 10, + 'uid' => '1', + 'item' => '10', ], [ - 'uid' => 2, - 'item' => 10, + 'uid' => '2', + 'item' => '10', ], ], 'tx_cart_domain_model_order_address' => [ [ - 'uid' => 100, - 'item' => 10, + 'uid' => '100', + 'item' => '10', 'record_type' => '\\' . BillingAddress::class, ], [ - 'uid' => 101, - 'item' => 10, + 'uid' => '101', + 'item' => '10', 'record_type' => '\\' . ShippingAddress::class, ], ], 'tx_cart_domain_model_order_payment' => [ [ - 'uid' => 30, - 'item' => 10, + 'uid' => '30', + 'item' => '10', ], ], 'tx_cart_domain_model_order_shipping' => [ [ - 'uid' => 30, - 'item' => 10, + 'uid' => '30', + 'item' => '10', ], ], 'tx_cart_domain_model_order_taxclass' => [ [ - 'uid' => 30, - 'item' => 10, + 'uid' => '30', + 'item' => '10', ], [ - 'uid' => 31, - 'item' => 10, + 'uid' => '31', + 'item' => '10', ], [ - 'uid' => 32, - 'item' => 10, + 'uid' => '32', + 'item' => '10', ], ], ]); @@ -186,78 +186,78 @@ public function doesNotDeletesNotRelatedRecordsCreatedBeforeCutOffDate(): void (new PhpDataSet())->import([ 'tx_cart_domain_model_order_item' => [ [ - 'uid' => 10, - 'products' => 2, - 'billing_address' => 1, - 'shipping_address' => 1, - 'payment' => 1, - 'shipping' => 1, - 'tax_class' => 3, - 'crdate' => (int)(new DateTimeImmutable('2024-12-31'))->format('U'), + 'uid' => '10', + 'products' => '2', + 'billing_address' => '1', + 'shipping_address' => '1', + 'payment' => '1', + 'shipping' => '1', + 'tax_class' => '3', + 'crdate' => (new DateTimeImmutable('2024-12-31'))->format('U'), ], ], 'tx_cart_domain_model_order_product' => [ [ - 'uid' => 1, - 'item' => 9, + 'uid' => '1', + 'item' => '9', ], [ - 'uid' => 2, - 'item' => 11, + 'uid' => '2', + 'item' => '11', ], ], 'tx_cart_domain_model_order_address' => [ [ - 'item' => 9, + 'item' => '9', 'record_type' => '\\' . BillingAddress::class, ], [ - 'item' => 9, + 'item' => '9', 'record_type' => '\\' . ShippingAddress::class, ], [ - 'item' => 11, + 'item' => '11', 'record_type' => '\\' . BillingAddress::class, ], [ - 'item' => 11, + 'item' => '11', 'record_type' => '\\' . ShippingAddress::class, ], ], 'tx_cart_domain_model_order_payment' => [ [ - 'item' => 9, + 'item' => '9', ], [ - 'item' => 11, + 'item' => '11', ], ], 'tx_cart_domain_model_order_shipping' => [ [ - 'item' => 9, + 'item' => '9', ], [ - 'item' => 11, + 'item' => '11', ], ], 'tx_cart_domain_model_order_taxclass' => [ [ - 'item' => 9, + 'item' => '9', ], [ - 'item' => 9, + 'item' => '9', ], [ - 'item' => 9, + 'item' => '9', ], [ - 'item' => 11, + 'item' => '11', ], [ - 'item' => 11, + 'item' => '11', ], [ - 'item' => 11, + 'item' => '11', ], ], ]); @@ -324,14 +324,14 @@ public function wrongCutOffDateFormatTerminatesTheCommandWithErrorMessage( ); } - public static function wrongCutOffDateDataProvider() + public static function wrongCutOffDateDataProvider(): iterable { - yield [ '01-01-2025' ]; - yield [ '01.01.2025' ]; - yield [ '01. Jan. 2025' ]; - yield [ 'first day of month' ]; - yield [ '1767265200' ]; - yield [ 'Thu Jan 01 2026 11:00:00 GMT+0000' ]; - yield [ 1 ]; + yield ['01-01-2025']; + yield ['01.01.2025']; + yield ['01. Jan. 2025']; + yield ['first day of month']; + yield ['1767265200']; + yield ['Thu Jan 01 2026 11:00:00 GMT+0000']; + yield [1]; } } diff --git a/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php b/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php index e7037257..8442521c 100644 --- a/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php +++ b/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php @@ -1,5 +1,7 @@ testExtensionsToLoad[] = 'extcode/cart'; - $this->testExtensionsToLoad[] = 'typo3conf/ext/cart/Tests/Fixtures/cart_example'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + 'typo3conf/ext/cart/Tests/Fixtures/cart_example', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest()) - ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE); + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE) + ; $this->importPHPDataSet(__DIR__ . '/../../../Fixtures/BaseDatabase.php'); } diff --git a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php index 2f971431..1090b5fb 100644 --- a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php +++ b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php @@ -1,5 +1,7 @@ testExtensionsToLoad[] = 'extcode/cart'; - $this->testExtensionsToLoad[] = 'typo3conf/ext/cart/Tests/Fixtures/cart_example'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + 'typo3conf/ext/cart/Tests/Fixtures/cart_example', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest()) - ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE); + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE) + ; $this->importPHPDataSet(__DIR__ . '/../../../Fixtures/BaseDatabase.php'); } @@ -72,7 +83,7 @@ public function filesFromTypoScriptAddedToAttachmentList(): void ], ]; - $reflection = new \ReflectionClass($attachmentFromTypoScriot); + $reflection = new ReflectionClass($attachmentFromTypoScriot); $reflection_property = $reflection->getProperty('settings'); $reflection_property->setValue($attachmentFromTypoScriot, $settings); @@ -80,7 +91,7 @@ public function filesFromTypoScriptAddedToAttachmentList(): void $attachments = $attachmentEvent->getAttachments(); - self::assertSame(2, count($attachments)); + self::assertCount(2, $attachments); self::assertContains(GeneralUtility::getFileAbsFileName('EXT:cart_example/Resources/Public/Files/Extension.pdf'), $attachments); self::assertContains(GeneralUtility::getFileAbsFileName('EXT:cart_example/Resources/Public/Icons/Extension.svg'), $attachments); } diff --git a/Tests/Functional/Service/MailHandlerTest.php b/Tests/Functional/Service/MailHandlerTest.php new file mode 100644 index 00000000..49193f61 --- /dev/null +++ b/Tests/Functional/Service/MailHandlerTest.php @@ -0,0 +1,392 @@ +testExtensionsToLoad = [ + 'extcode/cart', + 'typo3conf/ext/cart/Tests/Fixtures/cart_example', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; + + $this->configurationToUseInTestInstance = [ + 'LOG' => [ + 'Extcode' => [ + 'Cart' => [ + 'Tests' => [ + 'writerConfiguration' => [ + LogLevel::INFO => [ + DatabaseWriter::class => [], + ], + ], + ], + ], + ], + ], + ]; + + parent::setUp(); + + $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BaseDatabase.php'); + } + + #[Test] + public function logSucessAfterEmailToBuyerWasSend(): void + { + $mockBuilder = $this->getMockBuilderForMailHandlerClass(); + $mockBuilder->onlyMethods( + [ + 'getBuyerEmailFrom', + 'getBuyerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getBuyerEmailFrom')->willReturn('buyerEmailFrom@example.com'); + $mailHandler->method('getBuyerEmailName')->willReturn('Buyer Email Name'); + + $mailHandler->sendBuyerMail( + self::createStubForOrderItem() + ); + + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries + ); + self::assertIsArray($logEntries[0]); + + self::assertArrayIsEqualToArrayIgnoringListOfKeys( + [ + 'log_level' => 'info', + 'item' => 142, + 'type' => 'sendBuyerMail', + 'message' => 'Mail was send to buyer.', + 'level' => 'info', + ], + $logEntries[0], + [ + 'uid', + 'request_id', + 'crdate', + 'time_micro', + 'data', + 'arguments', + ] + ); + + self::assertIsString( + $logEntries[0]['arguments'] + ); + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments + ); + self::assertArrayHasKey( + 'time', + $arguments + ); + } + + #[Test] + public function logErrorIfEmailToBuyerCouldNotSend(): void + { + $mockBuilder = $this->getMockBuilderForMailHandlerClass(mailerThrowException: true); + $mockBuilder->onlyMethods( + [ + 'getBuyerEmailFrom', + 'getBuyerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getBuyerEmailFrom')->willReturn('buyerEmailFrom@example.com'); + $mailHandler->method('getBuyerEmailName')->willReturn('Buyer Email Name'); + + $mailHandler->sendBuyerMail( + self::createStubForOrderItem() + ); + + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries + ); + self::assertIsArray($logEntries[0]); + + self::assertArrayIsEqualToArrayIgnoringListOfKeys( + [ + 'log_level' => 'error', + 'item' => 142, + 'type' => 'sendBuyerMail', + 'message' => 'Mail could not send to buyer.', + 'level' => 'error', + ], + $logEntries[0], + [ + 'uid', + 'request_id', + 'crdate', + 'time_micro', + 'data', + 'arguments', + ] + ); + + self::assertIsString( + $logEntries[0]['arguments'] + ); + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments + ); + self::assertArrayHasKey( + 'time', + $arguments + ); + self::assertArrayHasKey( + 'exception', + $arguments + ); + self::assertIsString( + $arguments['exception'] + ); + self::assertStringStartsWith( + 'Exception in ', + $arguments['exception'] + ); + self::assertStringContainsString( + '/cart/Tests/Functional/Service/MailHandlerTest.php', + $arguments['exception'] + ); + } + + #[Test] + public function logSucessAfterEmailToSellerWasSend(): void + { + $mockBuilder = $this->getMockBuilderForMailHandlerClass(); + $mockBuilder->onlyMethods( + [ + 'getSellerEmailTo', + 'getSellerEmailFrom', + 'getSellerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getSellerEmailTo')->willReturn('sellerEmailTo@example.com'); + $mailHandler->method('getSellerEmailFrom')->willReturn('sellerEmailFrom@example.com'); + $mailHandler->method('getSellerEmailName')->willReturn('Seller Email Name'); + + $mailHandler->sendSellerMail( + self::createStubForOrderItem() + ); + + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries + ); + self::assertIsArray($logEntries[0]); + + self::assertArrayIsEqualToArrayIgnoringListOfKeys( + [ + 'log_level' => 'info', + 'item' => 142, + 'type' => 'sendSellerMail', + 'message' => 'Mail was send to seller.', + 'level' => 'info', + ], + $logEntries[0], + [ + 'uid', + 'request_id', + 'crdate', + 'time_micro', + 'data', + 'arguments', + ] + ); + + self::assertIsString( + $logEntries[0]['arguments'] + ); + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments + ); + self::assertArrayHasKey( + 'time', + $arguments + ); + } + + #[Test] + public function logErrorIfEmailToSellerCouldNotSend(): void + { + $mockBuilder = $this->getMockBuilderForMailHandlerClass(mailerThrowException: true); + $mockBuilder->onlyMethods( + [ + 'getSellerEmailTo', + 'getSellerEmailFrom', + 'getSellerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getSellerEmailTo')->willReturn('sellerEmailTo@example.com'); + $mailHandler->method('getSellerEmailFrom')->willReturn('sellerEmailFrom@example.com'); + $mailHandler->method('getSellerEmailName')->willReturn('Seller Email Name'); + + $mailHandler->sendSellerMail( + self::createStubForOrderItem() + ); + + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries + ); + self::assertIsArray($logEntries[0]); + + self::assertArrayIsEqualToArrayIgnoringListOfKeys( + [ + 'log_level' => 'error', + 'item' => 142, + 'type' => 'sendSellerMail', + 'message' => 'Mail could not send to seller.', + 'level' => 'error', + ], + $logEntries[0], + [ + 'uid', + 'request_id', + 'crdate', + 'time_micro', + 'data', + 'arguments', + ] + ); + + self::assertIsString( + $logEntries[0]['arguments'] + ); + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments + ); + self::assertArrayHasKey( + 'time', + $arguments + ); + self::assertArrayHasKey( + 'exception', + $arguments + ); + self::assertIsString( + $arguments['exception'] + ); + self::assertStringStartsWith( + 'Exception in ', + $arguments['exception'] + ); + self::assertStringContainsString( + '/cart/Tests/Functional/Service/MailHandlerTest.php', + $arguments['exception'] + ); + } + + /** + * @return MockBuilder + */ + private function getMockBuilderForMailHandlerClass(bool $mailerThrowException = false): MockBuilder + { + $configurationManager = self::createStub(ConfigurationManagerInterface::class); + + $eventDispatcher = self::createStub(EventDispatcherInterface::class); + + $mailer = self::createStub(MailerInterface::class); + if ($mailerThrowException) { + $mailer->method('send')->willThrowException(new Exception()); + } + + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(self::class); + $logService = GeneralUtility::makeInstance( + LogService::class, + $logger, + ); + + $mockBuilder = $this->getMockBuilder(MailHandler::class); + $mockBuilder->setConstructorArgs( + [ + $configurationManager, + $eventDispatcher, + $mailer, + $logService, + ] + ); + + return $mockBuilder; + } + + private static function createStubForOrderItem(): OrderItem&Stub + { + $billingAddress = self::createStub(BillingAddress::class); + $billingAddress->method('getEmail')->willReturn('billingAddress@example.com'); + + $payment = self::createStub(Payment::class); + $payment->method('getStatus')->willReturn('open'); + + $orderItem = self::createStub(OrderItem::class); + $orderItem->method('getBillingAddress')->willReturn($billingAddress); + $orderItem->method('getPayment')->willReturn($payment); + $orderItem->method('getUid')->willReturn(142); + + return $orderItem; + } +} diff --git a/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php b/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php index fce4bbd8..9216366e 100644 --- a/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php @@ -23,9 +23,16 @@ final class CsvHeaderViewHelperTest extends FunctionalTestCase { use TestingFramework; - public function setUp(): void + protected function setUp(): void { - $this->testExtensionsToLoad[] = 'extcode/cart'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); } @@ -34,7 +41,7 @@ public function setUp(): void public function headerExportsToCsvLine(): void { $template = __DIR__ . '/Fixtures/CsvHeader.html'; - $view = $this->getView($template); + $view = self::getView($template); $content = $view->render(); self::assertSame( @@ -47,7 +54,7 @@ public function headerExportsToCsvLine(): void public function headerExportsToCsvLineWithDifferentDelimAndQuote(): void { $template = __DIR__ . '/Fixtures/CsvHeaderWithDifferentDelimAndQuote.html'; - $view = $this->getView($template); + $view = self::getView($template); $content = $view->render(); self::assertSame( @@ -56,7 +63,7 @@ public function headerExportsToCsvLineWithDifferentDelimAndQuote(): void ); } - private function getView(string $template): ViewInterface + private static function getView(string $template): ViewInterface { $viewFactory = GeneralUtility::makeInstance(ViewFactoryInterface::class); return $viewFactory->create(new ViewFactoryData(null, null, null, $template)); diff --git a/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php b/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php index 9ccb78f9..f1bc408d 100644 --- a/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php @@ -27,9 +27,16 @@ final class CsvValuesViewHelperTest extends FunctionalTestCase private ItemRepository $itemRepository; - public function setUp(): void + protected function setUp(): void { - $this->testExtensionsToLoad[] = 'extcode/cart'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); @@ -49,7 +56,7 @@ public function orderWithEmptyOrderDataWithEmptyAddressDataExportsToCsvLine(): v $orderItem = $this->itemRepository->findByUid(10); $template = __DIR__ . '/Fixtures/CsvValues.html'; - $view = $this->getView($template); + $view = self::getView($template); $view->assign('orderItem', $orderItem); $content = $view->render(); @@ -65,7 +72,7 @@ public function orderWithOrderDataAndWithAddressExportsToCsvLine(): void $orderItem = $this->itemRepository->findByUid(11); $template = __DIR__ . '/Fixtures/CsvValues.html'; - $view = $this->getView($template); + $view = self::getView($template); $view->assign('orderItem', $orderItem); $content = $view->render(); @@ -81,7 +88,7 @@ public function orderWithOrderDataAndWithAddressExportsToCsvLineWithDifferentDel $orderItem = $this->itemRepository->findByUid(11); $template = __DIR__ . '/Fixtures/CsvValuesWithDifferentDelimAndQuote.html'; - $view = $this->getView($template); + $view = self::getView($template); $view->assign('orderItem', $orderItem); $content = $view->render(); @@ -97,7 +104,7 @@ public function orderWithOrderDataAndWithoutAddressExportsToCsvLine(): void $orderItem = $this->itemRepository->findByUid(12); $template = __DIR__ . '/Fixtures/CsvValues.html'; - $view = $this->getView($template); + $view = self::getView($template); $view->assign('orderItem', $orderItem); $content = $view->render(); @@ -107,7 +114,7 @@ public function orderWithOrderDataAndWithoutAddressExportsToCsvLine(): void ); } - private function getView(string $template): ViewInterface + private static function getView(string $template): ViewInterface { $viewFactory = GeneralUtility::makeInstance(ViewFactoryInterface::class); return $viewFactory->create(new ViewFactoryData(null, null, null, $template)); diff --git a/Tests/ObjectAccess.php b/Tests/ObjectAccess.php new file mode 100644 index 00000000..136206cc --- /dev/null +++ b/Tests/ObjectAccess.php @@ -0,0 +1,29 @@ +setValue($instance, $value); + } + + public static function getProperty(object $instance, string $propertyName): mixed + { + $reflection = new ReflectionProperty($instance::class, $propertyName); + return $reflection->getValue($instance); + } +} diff --git a/Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php b/Tests/Unit/Configuration/Loader/TypoScript/AbstractConfigurationLoaderTest.php similarity index 88% rename from Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php rename to Tests/Unit/Configuration/Loader/TypoScript/AbstractConfigurationLoaderTest.php index 25a0c5eb..c43844e9 100644 --- a/Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php +++ b/Tests/Unit/Configuration/Loader/TypoScript/AbstractConfigurationLoaderTest.php @@ -1,6 +1,8 @@ createSubject($configurations); + $paymentMethodsService = self::createSubject($configurations); $parsedData = $paymentMethodsService->getConfigurationsForType($type, $country); @@ -86,9 +88,9 @@ public function getTypePluginSettingsReturnsTypeCountrySettings(): void $parsedData ); - self::assertEquals( + self::assertCount( 2, - count($parsedData) + $parsedData ); self::assertEquals( @@ -159,7 +161,7 @@ public function getTypeZonePluginSettingsReturnsTypeZoneSettings(): void ], ]; - $paymentMethodsService = $this->createSubject($configurations); + $paymentMethodsService = self::createSubject($configurations); $parsedData = $paymentMethodsService->getConfigurationsForType($type, $country); @@ -167,9 +169,9 @@ public function getTypeZonePluginSettingsReturnsTypeZoneSettings(): void $parsedData ); - self::assertEquals( + self::assertCount( 3, - count($parsedData) + $parsedData ); self::assertEquals( @@ -178,11 +180,15 @@ public function getTypeZonePluginSettingsReturnsTypeZoneSettings(): void ); } - private function createSubject(array $configurations) + private static function createSubject(array $configurations): AbstractConfigurationLoader { $configurationManager = self::createStub(ConfigurationManagerInterface::class); $configurationManager->method('getConfiguration')->willReturn($configurations); - return new class ($configurationManager, new ServiceFactory()) extends AbstractConfigurationFromTypoScriptService {}; + return new TestConfigurationLoader($configurationManager, new ServiceFactory()); } } + +readonly class TestConfigurationLoader extends AbstractConfigurationLoader +{ +} diff --git a/Tests/Unit/Service/TaxClassServiceTest.php b/Tests/Unit/Configuration/Loader/TypoScript/TaxClassLoaderTest.php similarity index 87% rename from Tests/Unit/Service/TaxClassServiceTest.php rename to Tests/Unit/Configuration/Loader/TypoScript/TaxClassLoaderTest.php index 80996f99..bfbb58b9 100644 --- a/Tests/Unit/Service/TaxClassServiceTest.php +++ b/Tests/Unit/Configuration/Loader/TypoScript/TaxClassLoaderTest.php @@ -1,6 +1,8 @@ createSubject($settings)->getTaxClasses($countryCode); + $taxClasses = self::createSubject($settings)->getTaxClasses($countryCode); - self::assertIsArray( - $taxClasses - ); - - self::assertEquals( + self::assertCount( 3, - count($taxClasses) + $taxClasses ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses @@ -113,18 +113,16 @@ public function parsingTaxClassesFromTypoScriptWithCountryCodeReturnsCountrySpec $countryCode = 'AT'; - $taxClasses = $this->createSubject($settings)->getTaxClasses($countryCode); - - self::assertIsArray( - $taxClasses - ); + $taxClasses = self::createSubject($settings)->getTaxClasses($countryCode); - self::assertEquals( + self::assertCount( 3, - count($taxClasses) + $taxClasses ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses @@ -197,18 +195,16 @@ public function parsingTaxClassesFromTypoScriptWithNotConfiguredCountryCodeRetur $countryCode = 'CH'; - $taxClasses = $this->createSubject($settings)->getTaxClasses($countryCode); + $taxClasses = self::createSubject($settings)->getTaxClasses($countryCode); - self::assertIsArray( - $taxClasses - ); - - self::assertEquals( + self::assertCount( 3, - count($taxClasses) + $taxClasses ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses @@ -233,7 +229,7 @@ public function parsingTaxClassesFromTypoScriptWithIntegerZeroAsCalcIsValid(): v ], ]; - $taxClasses = $this->createSubject($settings)->getTaxClasses(); + $taxClasses = self::createSubject($settings)->getTaxClasses(); self::assertEquals( $taxClasses[1]->getCalc(), @@ -241,12 +237,12 @@ public function parsingTaxClassesFromTypoScriptWithIntegerZeroAsCalcIsValid(): v ); } - private function createSubject(array $settings): TaxClassService + private static function createSubject(array $settings): TaxClassLoader { $configurationManager = self::createStub(ConfigurationManagerInterface::class); $configurationManager->method('getConfiguration')->willReturn($settings); - return new TaxClassService( + return new TaxClassLoader( $configurationManager, new TaxClassFactory( self::createStub(LoggerInterface::class) diff --git a/Tests/Unit/ConstantsTest.php b/Tests/Unit/ConstantsTest.php index 8b62ae99..4cd3dc84 100644 --- a/Tests/Unit/ConstantsTest.php +++ b/Tests/Unit/ConstantsTest.php @@ -2,16 +2,9 @@ declare(strict_types=1); -/* - * This file is part of the package extcode/cart. - * - * For the full copyright and license information, please read the - * LICENSE file that was distributed with this source code. - */ - namespace Extcode\Cart\Tests\Unit; -use Extcode\Cart\Constants; +use Extcode\Cart\Configuration\Constants; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; diff --git a/Tests/Unit/Controller/ProductControllerTest.php b/Tests/Unit/Controller/ProductControllerTest.php index b1b5f5b0..fa856c0d 100644 --- a/Tests/Unit/Controller/ProductControllerTest.php +++ b/Tests/Unit/Controller/ProductControllerTest.php @@ -1,5 +1,7 @@ getMethod('getErrorWithHighestSeverity'); $error = $method->invoke($productController, $errors); @@ -38,7 +40,7 @@ public function getHighestSeverity(array $errors, ContextualFeedbackSeverity $ex ); } - public static function getHighestSeverityDataProvider(): Traversable + public static function getHighestSeverityDataProvider(): iterable { yield [ 'errors' => [ @@ -113,7 +115,7 @@ public function getLastHighestSeverity(array $errors, ContextualFeedbackSeverity { $productController = GeneralUtility::makeInstance(ProductController::class); - $reflection = new \ReflectionClass(ProductController::class); + $reflection = new ReflectionClass(ProductController::class); $method = $reflection->getMethod('getErrorWithHighestSeverity'); $error = $method->invoke($productController, $errors); @@ -133,7 +135,7 @@ public function getLastHighestSeverity(array $errors, ContextualFeedbackSeverity ); } - public static function getLastHighestSeverityDataProvider(): Traversable + public static function getLastHighestSeverityDataProvider(): iterable { yield [ 'errors' => [ @@ -199,5 +201,4 @@ public static function getLastHighestSeverityDataProvider(): Traversable 'expectedMessage' => 'ERROR 2', ]; } - } diff --git a/Tests/Unit/Domain/Model/Cart/BeVariantTest.php b/Tests/Unit/Domain/Model/Cart/BeVariantTest.php index b1a267e3..eab8991c 100644 --- a/Tests/Unit/Domain/Model/Cart/BeVariantTest.php +++ b/Tests/Unit/Domain/Model/Cart/BeVariantTest.php @@ -1,5 +1,7 @@ expectException(\TypeError::class); - - $this->beVariantFactory->create( - 1, - $this->product, - null, - 'test-variant-sku', - 0, - 1.0, - 1 - ); - } - - #[Test] - public function constructWithoutSkuThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->beVariantFactory->create( - 1, - $this->product, - 'Test Variant', - null, - 0, - 1.0, - 1 - ); - } - - #[Test] - public function constructWithoutQuantityThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->beVariantFactory->create( - 1, - $this->product, - 'Test Variant', - 'test-variant-sku', - 0, - 1.0, - null - ); - } - #[Test] public function getMinReturnsInitialValueMin(): void { @@ -252,7 +205,7 @@ public function setMinIfMinIsLesserThanMax(): void #[Test] public function throwsInvalidArgumentExceptionIfMinIsGreaterThanMax(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $min = 2; $max = 1; @@ -264,7 +217,7 @@ public function throwsInvalidArgumentExceptionIfMinIsGreaterThanMax(): void #[Test] public function throwsInvalidArgumentExceptionIfMinIsNegativ(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $min = -1; $max = 1; @@ -288,7 +241,7 @@ public function setMaxIfMaxIsEqualToMin(): void $min = 1; $max = 1; - //sets max before because $min and $max are 0 by default + // sets max before because $min and $max are 0 by default $this->beVariant->setMax($max); $this->beVariant->setMin($min); @@ -306,7 +259,7 @@ public function setMaxIfMaxIsGreaterThanMin(): void $min = 1; $max = 2; - //sets max before because $min and $max are 0 by default + // sets max before because $min and $max are 0 by default $this->beVariant->setMax($min); $this->beVariant->setMin($min); @@ -321,12 +274,12 @@ public function setMaxIfMaxIsGreaterThanMin(): void #[Test] public function throwsInvalidArgumentExceptionIfMaxIsLesserThanMin(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $min = 2; $max = 1; - //sets max before because $min and $max are 0 by default + // sets max before because $min and $max are 0 by default $this->beVariant->setMax($min); $this->beVariant->setMin($min); @@ -337,156 +290,17 @@ public function throwsInvalidArgumentExceptionIfMaxIsLesserThanMin(): void public function getParentPriceReturnsProductPriceForCalculationMethodZero(): void { self::markTestSkipped(); - // self::assertSame( - // 10.00, - // $this->beVariant->getParentPrice() - // ); } #[Test] public function getParentPriceReturnsZeroPriceForCalculationMethodOne(): void { self::markTestSkipped(); - // $this->beVariant->setPriceCalcMethod(1); - // self::assertSame( - // 0.00, - // $this->beVariant->getParentPrice() - // ); } #[Test] public function getParentPriceRespectsTheQuantityDiscountsOfProductsForEachVariant(): void { self::markTestSkipped(); - // $quantityDiscounts = [ - // [ - // 'quantity' => 3, - // 'price' => 7.00, - // ], - // [ - // 'quantity' => 4, - // 'price' => 6.00, - // ], - // [ - // 'quantity' => 5, - // 'price' => 5.00, - // ], - // [ - // 'quantity' => 6, - // 'price' => 4.00, - // ], - // [ - // 'quantity' => 7, - // 'price' => 3.00, - // ], - // [ - // 'quantity' => 8, - // 'price' => 2.50, - // ], - // ]; - // - // $this->product->setQuantityDiscounts($quantityDiscounts); - // - // $title = 'Test Variant'; - // $sku = 'test-variant-sku'; - // $priceCalcMethod = 0; - // $price = 1.00; - // - // $beVariant1 = $this->beVariantFactory->create( - // '1', - // $this->product, - // $title, - // $sku, - // $priceCalcMethod, - // $price, - // 1 - // ); - // $this->product->addBeVariant($beVariant1); - // - // $beVariant2 = $this->beVariantFactory->create( - // '2', - // $this->product, - // $title, - // $sku, - // $priceCalcMethod, - // $price, - // 3 - // ); - // $this->product->addBeVariant($beVariant2); - // - // $beVariant3 = $this->beVariantFactory->create( - // '3', - // $this->product, - // $title, - // $sku, - // $priceCalcMethod, - // $price, - // 4 - // ); - // $this->product->addBeVariant($beVariant3); - // - // self::assertSame( - // 10.00, - // $beVariant1->getParentPrice() - // ); - // - // self::assertSame( - // 7.00, - // $beVariant2->getParentPrice() - // ); - // - // self::assertSame( - // 6.00, - // $beVariant3->getParentPrice() - // ); - } - - /** - * Creates a mock object which allows for calling protected methods and access of protected properties. - * - * Note: This method has no native return types on purpose, but only PHPDoc return type annotations. - * The reason is that the combination of "union types with generics in PHPDoc" and "a subset of those types as - * native types, but without the generics" tends to confuse PhpStorm's static type analysis (which we want to avoid). - * - * @template T of object - * @param class-string $originalClassName name of class to create the mock object of - * @param string[]|null $methods name of the methods to mock, null for "mock no methods" - * @param array $arguments arguments to pass to constructor - * @param string $mockClassName the class name to use for the mock class - * @param bool $callOriginalConstructor whether to call the constructor - * @param bool $callOriginalClone whether to call the __clone method - * @param bool $callAutoload whether to call any autoload function - * - * @return MockObject&AccessibleObjectInterface&T a mock of `$originalClassName` with access methods added - * - * @throws \InvalidArgumentException - */ - protected function getAccessibleMock( - string $originalClassName, - ?array $methods = [], - array $arguments = [], - string $mockClassName = '', - bool $callOriginalConstructor = true, - bool $callOriginalClone = true, - bool $callAutoload = true - ) { - $mockBuilder = $this->getMockBuilder($this->buildAccessibleProxy($originalClassName)) - ->onlyMethods($methods) - ->setConstructorArgs($arguments) - ->setMockClassName($mockClassName); - - if (!$callOriginalConstructor) { - $mockBuilder->disableOriginalConstructor(); - } - - if (!$callOriginalClone) { - $mockBuilder->disableOriginalClone(); - } - - if (!$callAutoload) { - $mockBuilder->disableAutoload(); - } - - return $mockBuilder->getMock(); } } diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php index f8b570a7..288e2928 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php @@ -1,5 +1,7 @@ taxClass = new TaxClass(1, '19 %', 0.19, 'normal'); @@ -58,81 +60,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructCouponWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponFix( - null, - $this->code, - $this->couponType, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutCodeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponFix( - $this->title, - null, - $this->couponType, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutCouponTypeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponFix( - $this->title, - $this->code, - null, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutDiscountThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponFix( - $this->title, - $this->code, - $this->couponType, - null, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutTaxClassThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponFix( - $this->title, - $this->code, - $this->couponType, - $this->discount, - null, - $this->cartMinPrice - ); - } - #[Test] public function isCombinableInitiallyReturnsFalse(): void { @@ -313,13 +240,14 @@ public function isUsableReturnsFalseIfCartMinPriceIsGreaterToGivenPrice(): void private function createCartMock(array $methods = ['getGross']): Cart|MockObject { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([[$this->taxClass]]) - ->getMock(); + ->getMock() + ; } } diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php index 1c5dfea7..5b41f999 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php @@ -1,5 +1,7 @@ taxClass = new TaxClass(1, '19 %', 0.19, 'normal'); @@ -58,81 +60,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructCouponWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponPercentage( - null, - $this->code, - $this->couponType, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutCodeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponPercentage( - $this->title, - null, - $this->couponType, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutCouponTypeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponPercentage( - $this->title, - $this->code, - null, - $this->discount, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutDiscountThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponPercentage( - $this->title, - $this->code, - $this->couponType, - null, - $this->taxClass, - $this->cartMinPrice - ); - } - - #[Test] - public function constructCouponWithoutTaxClassThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new CartCouponPercentage( - $this->title, - $this->code, - $this->couponType, - $this->discount, - null, - $this->cartMinPrice - ); - } - #[Test] public function isCombinableInitiallyReturnsFalse(): void { @@ -343,13 +270,14 @@ public function isUsableReturnsFalseIfCartMinPriceIsGreaterToGivenPrice(): void private function createCartMock(array $methods = ['getGross']): Cart|MockObject { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([[$this->taxClass]]) - ->getMock(); + ->getMock() + ; } } diff --git a/Tests/Unit/Domain/Model/Cart/CartTest.php b/Tests/Unit/Domain/Model/Cart/CartTest.php index eccb7fdd..94143af1 100644 --- a/Tests/Unit/Domain/Model/Cart/CartTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartTest.php @@ -1,5 +1,7 @@ netCart = $this->createCart(true); } - public function tearDown(): void + protected function tearDown(): void { - unset($this->grossCart); - unset($this->netCart); - - unset($this->taxClasses); - - unset($this->normalTaxClass); - unset($this->reducedTaxClass); - unset($this->freeTaxClass); - parent::tearDown(); } @@ -265,7 +259,7 @@ public function resetDifferentOrderNumberThrowsException(): void $this->grossCart->setOrderNumber('ValidOrderNumber'); $this->expectException( - 'LogicException' + LogicException::class ); $this->expectExceptionMessage( 'You can not redeclare the order number of your cart.' @@ -328,7 +322,7 @@ public function resetDifferentInvoiceNumberThrowsException(): void $this->grossCart->setInvoiceNumber('ValidInvoiceNumber'); $this->expectException( - 'LogicException' + LogicException::class ); $this->expectExceptionMessage( 'You can not redeclare the invoice number of your cart.', @@ -1198,23 +1192,6 @@ public function getCouponGrossReturnsAllCouponsGrossSum(): void ); } - protected function addFirstProductToCarts(): void - { - $product = $this->productFactory->create( - 'simple', - 1, - 'SKU', - 'First Product', - 10.00, - $this->normalTaxClass, - 1, - false - ); - - $this->grossCart->addProduct($product); - $this->netCart->addProduct($product); - } - #[Test] public function getCouponGrossReturnsCouponsGrossSumOfCouponsWhenCartMinPriceWasReached(): void { @@ -1338,13 +1315,14 @@ public function getSubtotalGrossReturnsSubtotalGross(): void $couponGross = 10.00; GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); $cart = $this->getMockBuilder(Cart::class) ->onlyMethods(['getCouponGross', 'getCurrencyTranslation']) ->setConstructorArgs([$this->taxClasses]) - ->getMock(); + ->getMock() + ; $cart->method('getCouponGross')->willReturn($couponGross); $cart->method('getCurrencyTranslation')->willReturn(1.00); @@ -1375,13 +1353,14 @@ public function getSubtotalNetReturnsSubtotalNet(): void $couponNet = $couponGross / 1.19; GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); $cart = $this->getMockBuilder(Cart::class) ->onlyMethods(['getCouponNet', 'getCurrencyTranslation']) ->setConstructorArgs([$this->taxClasses]) - ->getMock(); + ->getMock() + ; $cart->method('getCouponNet')->willReturn($couponNet); $cart->method('getCurrencyTranslation')->willReturn(1.00); @@ -1423,8 +1402,8 @@ public function getCurrencyCodeInitiallyReturnsString(): void public function constructorSetsCurrencyCode(): void { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); $cart = new Cart( $this->taxClasses, @@ -1476,8 +1455,8 @@ public function getCurrencySignInitiallyReturnsString(): void public function constructorSetsCurrencySign(): void { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); $cart = new Cart( $this->taxClasses, @@ -1529,8 +1508,8 @@ public function getCurrencyTranslationInitiallyReturnsFloat(): void public function constructorSetsCurrencyTranslation(): void { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); $cart = new Cart( $this->taxClasses, @@ -1604,11 +1583,28 @@ public function translatePriceReturnsCorrectPrice(): void ); } + protected function addFirstProductToCarts(): void + { + $product = $this->productFactory->create( + 'simple', + 1, + 'SKU', + 'First Product', + 10.00, + $this->normalTaxClass, + 1, + false + ); + + $this->grossCart->addProduct($product); + $this->netCart->addProduct($product); + } + private function createCart(bool $isNetCart): Cart { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); return new Cart($this->taxClasses, $isNetCart); diff --git a/Tests/Unit/Domain/Model/Cart/ProductTest.php b/Tests/Unit/Domain/Model/Cart/ProductTest.php index c8edf292..b9a90674 100644 --- a/Tests/Unit/Domain/Model/Cart/ProductTest.php +++ b/Tests/Unit/Domain/Model/Cart/ProductTest.php @@ -1,5 +1,7 @@ product, - $this->productType, - $this->productId, - $this->title, - $this->sku, - $this->price, - $this->quantity, - $this->taxClass - ); - parent::tearDown(); } - #[Test] - public function constructCartProductWithoutProductTypeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - null, - $this->productId, - $this->sku, - $this->title, - $this->price, - $this->taxClass, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutProductIdThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - null, - $this->sku, - $this->title, - $this->price, - $this->taxClass, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutSkuThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - $this->productId, - null, - $this->title, - $this->price, - $this->taxClass, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - $this->productId, - $this->sku, - null, - $this->price, - $this->taxClass, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutPriceThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - $this->productId, - $this->sku, - $this->title, - null, - $this->taxClass, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutTaxClassThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - $this->productId, - $this->sku, - $this->title, - $this->price, - null, - $this->quantity - ); - } - - #[Test] - public function constructCartProductWithoutQuantityThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productFactory->create( - $this->productType, - $this->productId, - $this->sku, - $this->title, - $this->price, - $this->taxClass, - null - ); - } - #[Test] public function getCartProductTypeReturnsProductTypeSetByConstructor(): void { diff --git a/Tests/Unit/Domain/Model/Cart/ServiceTest.php b/Tests/Unit/Domain/Model/Cart/ServiceTest.php index 2b8751db..dc4ab9aa 100644 --- a/Tests/Unit/Domain/Model/Cart/ServiceTest.php +++ b/Tests/Unit/Domain/Model/Cart/ServiceTest.php @@ -1,5 +1,7 @@ normalTaxClass = new TaxClass(1, '19 %', 0.19, 'Normal'); $this->reducedTaxClass = new TaxClass(2, '7 %', 0.07, 'Reduced'); @@ -348,6 +350,7 @@ public function isFreeWithCartGrossAboveRangeReturnsFalse(): void $service->isFree() ); } + #[Test] public function taxClassIdsGreaterZeroReturnsTaxClass(): void { @@ -468,13 +471,14 @@ public function forTaxClassIdMinusTwoReturnsPseudoTaxClassWithIdMinusTwo(): void private function createCartMock(array $methods = ['getGross']): Cart|MockObject { GeneralUtility::addInstance( - CurrencyTranslationServiceInterface::class, - new CurrencyTranslationService() + CurrencyTranslationLoaderInterface::class, + new CurrencyTranslationLoader() ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([$this->taxClasses]) - ->getMock(); + ->getMock() + ; } } diff --git a/Tests/Unit/Domain/Model/Cart/TaxClassTest.php b/Tests/Unit/Domain/Model/Cart/TaxClassTest.php index 2d646eef..afa79f3a 100644 --- a/Tests/Unit/Domain/Model/Cart/TaxClassTest.php +++ b/Tests/Unit/Domain/Model/Cart/TaxClassTest.php @@ -1,5 +1,7 @@ id = 1; $this->value = '19 %%'; @@ -44,16 +46,8 @@ public function setUp(): void parent::setUp(); } - public function tearDown(): void + protected function tearDown(): void { - unset( - $this->id, - $this->value, - $this->calc, - $this->title, - $this->fixture - ); - parent::tearDown(); } diff --git a/Tests/Unit/Domain/Model/CouponTest.php b/Tests/Unit/Domain/Model/CouponTest.php index 453033ef..42165ea9 100644 --- a/Tests/Unit/Domain/Model/CouponTest.php +++ b/Tests/Unit/Domain/Model/CouponTest.php @@ -1,5 +1,7 @@ title = 'Coupon'; $this->code = 'coupon'; @@ -48,76 +50,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructCouponWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new Coupon( - null, - $this->code, - $this->couponType, - $this->discount, - $this->taxClassId - ); - } - - #[Test] - public function constructCouponWithoutCodeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new Coupon( - $this->title, - null, - $this->couponType, - $this->discount, - $this->taxClassId - ); - } - - #[Test] - public function constructCouponWithoutCouponTypeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new Coupon( - $this->title, - $this->code, - null, - $this->discount, - $this->taxClassId - ); - } - - #[Test] - public function constructCouponWithoutDiscountThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new Coupon( - $this->title, - $this->code, - $this->couponType, - null, - $this->taxClassId - ); - } - - #[Test] - public function constructCouponWithoutTaxClassIdThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->coupon = new Coupon( - $this->title, - $this->code, - $this->couponType, - $this->discount, - null - ); - } - #[Test] public function getTitleInitiallyReturnsTitleSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Domain/Model/Order/AbstractAddressTest.php b/Tests/Unit/Domain/Model/Order/AbstractAddressTest.php index 5f5183ec..44b8f1ed 100644 --- a/Tests/Unit/Domain/Model/Order/AbstractAddressTest.php +++ b/Tests/Unit/Domain/Model/Order/AbstractAddressTest.php @@ -1,5 +1,7 @@ address = $this->getMockForAbstractClass(AbstractAddress::class); + $this->address = new class extends AbstractAddress {}; parent::setUp(); } @@ -579,9 +577,6 @@ public function setFaxSetsFax(): void #[Test] public function getAdditionalInitiallyReturnsEmptyArray(): void { - self::assertIsArray( - $this->address->getAdditional() - ); self::assertEmpty( $this->address->getAdditional() ); @@ -609,74 +604,13 @@ public function additionalIsInternallyJsonString(): void 'additional' => true, ]; - /** @var AccessibleObjectInterface&MockObject&AbstractAddress $address */ - $address = $this->getAccessibleMock( - AbstractAddress::class, - [], - [], - '', - false - ); - - self::assertSame( - '', - $address->_get('additional') - ); + $this->address->setAdditional($additional); - $address->setAdditional($additional); + $additionalPropertyValue = ObjectAccess::getProperty($this->address, 'additional'); self::assertSame( json_encode($additional), - $address->_get('additional') - ); - } - - /** - * Creates a mock object which allows for calling protected methods and access of protected properties. - * - * Note: This method has no native return types on purpose, but only PHPDoc return type annotations. - * The reason is that the combination of "union types with generics in PHPDoc" and "a subset of those types as - * native types, but without the generics" tends to confuse PhpStorm's static type analysis (which we want to avoid). - * - * @template T of object - * @param class-string $originalClassName name of class to create the mock object of - * @param string[]|null $methods name of the methods to mock, null for "mock no methods" - * @param array $arguments arguments to pass to constructor - * @param string $mockClassName the class name to use for the mock class - * @param bool $callOriginalConstructor whether to call the constructor - * @param bool $callOriginalClone whether to call the __clone method - * @param bool $callAutoload whether to call any autoload function - * - * @return MockObject&AccessibleObjectInterface - * - * @throws \InvalidArgumentException - */ - protected function getAccessibleMock( - string $originalClassName, - ?array $methods = [], - array $arguments = [], - string $mockClassName = '', - bool $callOriginalConstructor = true, - bool $callOriginalClone = true, - bool $callAutoload = true - ): MockObject { - $mockBuilder = $this->getMockBuilder($this->buildAccessibleProxy($originalClassName)) - ->addMethods($methods) - ->setConstructorArgs($arguments) - ->setMockClassName($mockClassName); - - if (!$callOriginalConstructor) { - $mockBuilder->disableOriginalConstructor(); - } - - if (!$callOriginalClone) { - $mockBuilder->disableOriginalClone(); - } - - if (!$callAutoload) { - $mockBuilder->disableAutoload(); - } - - return $mockBuilder->getMock(); + $additionalPropertyValue + ); } } diff --git a/Tests/Unit/Domain/Model/Order/AbstractServiceTest.php b/Tests/Unit/Domain/Model/Order/AbstractServiceTest.php index 69fbdbe5..dedb84ac 100644 --- a/Tests/Unit/Domain/Model/Order/AbstractServiceTest.php +++ b/Tests/Unit/Domain/Model/Order/AbstractServiceTest.php @@ -1,5 +1,7 @@ service = $this->getMockForAbstractClass(AbstractService::class); + $this->service = new class extends AbstractService {}; parent::setUp(); } @@ -70,7 +72,7 @@ public function toArrayReturnsArray(): void $this->service->toArray() ); - //with taxClass + // with taxClass $this->service->setTaxClass($taxClass); $serviceArr['taxClass'] = $taxClass->toArray(); diff --git a/Tests/Unit/Domain/Model/Order/DiscountTest.php b/Tests/Unit/Domain/Model/Order/DiscountTest.php index 0df8791f..de5f2436 100644 --- a/Tests/Unit/Domain/Model/Order/DiscountTest.php +++ b/Tests/Unit/Domain/Model/Order/DiscountTest.php @@ -1,5 +1,7 @@ taxClass = new TaxClass(1, '19 %', 0.19, 'normal'); @@ -54,96 +56,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructDiscountWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - null, - $this->code, - $this->gross, - $this->net, - $this->taxClass, - $this->tax - ); - } - - #[Test] - public function constructDiscountWithoutCodeThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - $this->title, - null, - $this->gross, - $this->net, - $this->taxClass, - $this->tax - ); - } - - #[Test] - public function constructDiscountWithoutGrossThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - $this->title, - $this->code, - null, - $this->net, - $this->taxClass, - $this->tax - ); - } - - #[Test] - public function constructDiscountWithoutNetThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - $this->title, - $this->code, - $this->gross, - null, - $this->taxClass, - $this->tax - ); - } - - #[Test] - public function constructDiscountWithoutTaxClassThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - $this->title, - $this->code, - $this->gross, - $this->net, - null, - $this->tax - ); - } - - #[Test] - public function constructDiscountWithoutTaxThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Discount( - $this->title, - $this->code, - $this->gross, - $this->net, - $this->taxClass, - null - ); - } - #[Test] public function getTitleInitiallyReturnsTitleSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Domain/Model/Order/ItemTest.php b/Tests/Unit/Domain/Model/Order/ItemTest.php index e89e807b..4a912b68 100644 --- a/Tests/Unit/Domain/Model/Order/ItemTest.php +++ b/Tests/Unit/Domain/Model/Order/ItemTest.php @@ -1,5 +1,7 @@ item = new Item(); diff --git a/Tests/Unit/Domain/Model/Order/PaymentTest.php b/Tests/Unit/Domain/Model/Order/PaymentTest.php index f8079898..1fe47ba7 100644 --- a/Tests/Unit/Domain/Model/Order/PaymentTest.php +++ b/Tests/Unit/Domain/Model/Order/PaymentTest.php @@ -1,5 +1,7 @@ payment = new Payment(); @@ -33,6 +35,7 @@ public function toArrayReturnsArray(): void { $provider = 'test_provider'; + $this->payment->setServiceId(1); $this->payment->setProvider($provider); $result = $this->payment->toArray(); diff --git a/Tests/Unit/Domain/Model/Order/ProductAdditionalTest.php b/Tests/Unit/Domain/Model/Order/ProductAdditionalTest.php index 47c2901f..c5a6965e 100644 --- a/Tests/Unit/Domain/Model/Order/ProductAdditionalTest.php +++ b/Tests/Unit/Domain/Model/Order/ProductAdditionalTest.php @@ -1,5 +1,7 @@ additionalType = 'additional-type'; $this->additionalKey = 'additional-key'; @@ -40,42 +42,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructProductAdditionalWithoutAdditionalTypeThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productAdditional = new ProductAdditional( - null, - $this->additionalKey, - $this->additionalValue - ); - } - - #[Test] - public function constructProductAdditionalWithoutAdditionalKeyThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productAdditional = new ProductAdditional( - $this->additionalType, - null, - $this->additionalValue - ); - } - - #[Test] - public function constructProductAdditionalWithoutAdditionalValueThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->productAdditional = new ProductAdditional( - $this->additionalType, - $this->additionalKey, - null - ); - } - #[Test] public function getAdditionalTypeInitiallyReturnsAdditionalTypeSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Domain/Model/Order/ProductTest.php b/Tests/Unit/Domain/Model/Order/ProductTest.php index 9fe63561..eef619f6 100644 --- a/Tests/Unit/Domain/Model/Order/ProductTest.php +++ b/Tests/Unit/Domain/Model/Order/ProductTest.php @@ -1,5 +1,7 @@ sku = 'sku'; $this->title = 'title'; diff --git a/Tests/Unit/Domain/Model/Order/ShippingTest.php b/Tests/Unit/Domain/Model/Order/ShippingTest.php index 0deb9db5..610b6bd3 100644 --- a/Tests/Unit/Domain/Model/Order/ShippingTest.php +++ b/Tests/Unit/Domain/Model/Order/ShippingTest.php @@ -1,5 +1,7 @@ shipping = new Shipping(); diff --git a/Tests/Unit/Domain/Model/Order/TaxClassTest.php b/Tests/Unit/Domain/Model/Order/TaxClassTest.php index c82a29f0..4817edd1 100644 --- a/Tests/Unit/Domain/Model/Order/TaxClassTest.php +++ b/Tests/Unit/Domain/Model/Order/TaxClassTest.php @@ -1,5 +1,7 @@ title = 'normal'; $this->value = '19 %'; diff --git a/Tests/Unit/Domain/Model/Order/TaxTest.php b/Tests/Unit/Domain/Model/Order/TaxTest.php index 98d82242..bfeab767 100644 --- a/Tests/Unit/Domain/Model/Order/TaxTest.php +++ b/Tests/Unit/Domain/Model/Order/TaxTest.php @@ -1,5 +1,7 @@ taxClass = new TaxClass(); $this->taxClass->setTitle('normal'); @@ -41,28 +43,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructTaxWithoutTaxThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Tax( - null, - $this->taxClass - ); - } - - #[Test] - public function constructTaxWithoutTaxClassThrowsException(): void - { - $this->expectException(\TypeError::class); - - new Tax( - $this->tax, - null - ); - } - #[Test] public function getTaxInitiallyReturnsTaxSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Domain/Model/Order/TransactionTest.php b/Tests/Unit/Domain/Model/Order/TransactionTest.php index 12f12d35..353cdec6 100644 --- a/Tests/Unit/Domain/Model/Order/TransactionTest.php +++ b/Tests/Unit/Domain/Model/Order/TransactionTest.php @@ -1,5 +1,7 @@ transaction = new Transaction(); diff --git a/Tests/Unit/Domain/Model/Product/AbstractProductTest.php b/Tests/Unit/Domain/Model/Product/AbstractProductTest.php index 3e6d68ef..d6b34952 100644 --- a/Tests/Unit/Domain/Model/Product/AbstractProductTest.php +++ b/Tests/Unit/Domain/Model/Product/AbstractProductTest.php @@ -1,5 +1,7 @@ product = $this->getMockForAbstractClass( - AbstractProduct::class - ); + $this->product = new class extends AbstractProduct {}; } #[Test] diff --git a/Tests/Unit/Domain/Model/Product/CategoryTraitStub.php b/Tests/Unit/Domain/Model/Product/CategoryTraitStub.php new file mode 100644 index 00000000..5f1b8c8e --- /dev/null +++ b/Tests/Unit/Domain/Model/Product/CategoryTraitStub.php @@ -0,0 +1,19 @@ +trait = $this->getObjectForTrait(CategoryTrait::class); + $this->trait = new CategoryTraitStub(); } #[Test] diff --git a/Tests/Unit/Domain/Model/Product/MeasureTraitStub.php b/Tests/Unit/Domain/Model/Product/MeasureTraitStub.php new file mode 100644 index 00000000..b235a202 --- /dev/null +++ b/Tests/Unit/Domain/Model/Product/MeasureTraitStub.php @@ -0,0 +1,19 @@ +trait = $this->getObjectForTrait(MeasureTrait::class); + $this->trait = new MeasureTraitStub(); } #[Test] @@ -158,31 +158,9 @@ public function getIsMeasureUnitCompatibilityAndNotSetBasePriceMeasureUnitsRetru ); } - /** - * Measurement Units Provider - * - * @return array - */ - public static function measureUnitsProvider() - { - return [ - ['mg', 'kg', 1000000.0, 1000.0, 1000.0], - ['g', 'kg', 1000.0, 1000.0, 1.0], - ['kg', 'kg', 1.0, 1000.0, 0.001], - ['ml', 'l', 1000.0, 1000.0, 1.0], - ['cl', 'l', 100.0, 1000.0, 0.1], - ['l', 'l', 1.0, 1000.0, 0.001], - ['cbm', 'l', 0.001, 1.0, 0.001], - ['mm', 'm', 1000.0, 1000.0, 1.0], - ['cm', 'm', 100.0, 1000.0, 0.1], - ['m', 'm', 1.0, 2.0, 0.5], - ['km', 'm', 0.001, 2.0, 0.0005], - ['m2', 'm2', 1.0, 20.0, 0.05], - ]; - } - /** * @test + * * @dataProvider measureUnitsProvider */ public function getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit( @@ -202,6 +180,7 @@ public function getIsMeasureUnitCompatibilityRetrunsTrueOnSameTypeOfMeasureUnit( /** * @test + * * @dataProvider measureUnitsProvider */ public function getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureUnitReturnsFactor( @@ -223,6 +202,7 @@ public function getMeasureUnitFactorForGivenPriceMeasureUnitAndBasePriceMeasureU /** * @test + * * @dataProvider measureUnitsProvider */ public function getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasureUnitRetrunsPrice( @@ -241,4 +221,25 @@ public function getCalculatedBasePriceForGivenPriceMeasureUnitAndBasePriceMeasur $this->trait->getMeasureUnitFactor() ); } + + /** + * Measurement Units Provider + * + * @return array + */ + public static function measureUnitsProvider(): iterable + { + yield ['mg', 'kg', 1000000.0, 1000.0, 1000.0]; + yield ['g', 'kg', 1000.0, 1000.0, 1.0]; + yield ['kg', 'kg', 1.0, 1000.0, 0.001]; + yield ['ml', 'l', 1000.0, 1000.0, 1.0]; + yield ['cl', 'l', 100.0, 1000.0, 0.1]; + yield ['l', 'l', 1.0, 1000.0, 0.001]; + yield ['cbm', 'l', 0.001, 1.0, 0.001]; + yield ['mm', 'm', 1000.0, 1000.0, 1.0]; + yield ['cm', 'm', 100.0, 1000.0, 0.1]; + yield ['m', 'm', 1.0, 2.0, 0.5]; + yield ['km', 'm', 0.001, 2.0, 0.0005]; + yield ['m2', 'm2', 1.0, 20.0, 0.05]; + } } diff --git a/Tests/Unit/Domain/Model/Product/ServiceAttributeTraitStub.php b/Tests/Unit/Domain/Model/Product/ServiceAttributeTraitStub.php new file mode 100644 index 00000000..22e05e0c --- /dev/null +++ b/Tests/Unit/Domain/Model/Product/ServiceAttributeTraitStub.php @@ -0,0 +1,19 @@ +trait = $this->getObjectForTrait(ServiceAttributeTrait::class); + $this->trait = new ServiceAttributeTraitStub(); } #[Test] diff --git a/Tests/Unit/Domain/Model/Product/StockTraitStub.php b/Tests/Unit/Domain/Model/Product/StockTraitStub.php new file mode 100644 index 00000000..28c07b11 --- /dev/null +++ b/Tests/Unit/Domain/Model/Product/StockTraitStub.php @@ -0,0 +1,19 @@ +trait = $this->getObjectForTrait(StockTrait::class); + $this->trait = new StockTraitStub(); } #[Test] diff --git a/Tests/Unit/Domain/Model/Product/TagTraitStub.php b/Tests/Unit/Domain/Model/Product/TagTraitStub.php new file mode 100644 index 00000000..19dc4a5e --- /dev/null +++ b/Tests/Unit/Domain/Model/Product/TagTraitStub.php @@ -0,0 +1,19 @@ +trait = $this->getObjectForTrait(TagTrait::class); + $this->trait = new TagTraitStub(); } #[Test] diff --git a/Tests/Unit/Domain/Model/TagTest.php b/Tests/Unit/Domain/Model/TagTest.php index 89a36a46..38d5aafe 100644 --- a/Tests/Unit/Domain/Model/TagTest.php +++ b/Tests/Unit/Domain/Model/TagTest.php @@ -1,5 +1,7 @@ title = 'Title'; @@ -32,16 +34,6 @@ public function setUp(): void parent::setUp(); } - #[Test] - public function constructCouponWithoutTitleThrowsException(): void - { - $this->expectException(\TypeError::class); - - $this->tag = new Tag( - null - ); - } - #[Test] public function getTitleInitiallyReturnsTitleSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Validation/Validator/EmptyValidatorTest.php b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php index 5ced1c1a..365c3236 100644 --- a/Tests/Unit/Validation/Validator/EmptyValidatorTest.php +++ b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php @@ -1,5 +1,7 @@ validatorClassName($options); - } - - /** - * @param array $options - */ - protected function validatorOptions(array $options): void - { - $this->validator = $this->getValidator($options); - } - - public function setUp(): void + protected function setUp(): void { - /** @var MockObject&EmptyValidator $validator */ + /** @var EmptyValidator&MockObject $validator */ $validator = $this->getMockBuilder($this->validatorClassName) ->onlyMethods(['translateErrorMessage']) - ->getMock(); + ->getMock() + ; $this->validator = $validator; @@ -79,7 +68,7 @@ public function emptyValidatorReturnsNoErrorForANullValue(): void #[Test] public function emptyValidatorCreatesTheCorrectErrorForAnEmptySubject(): void { - self::assertEquals(1, count($this->validator->validate('a not empty string')->getErrors())); + self::assertCount(1, $this->validator->validate('a not empty string')->getErrors()); } #[Test] @@ -92,14 +81,24 @@ public function emptyValidatorWorksForArrays(): void #[Test] public function emptyValidatorWorksForCountableObjects(): void { - self::assertFalse($this->validator->validate(new \SplObjectStorage())->hasErrors()); + self::assertFalse($this->validator->validate(new SplObjectStorage())->hasErrors()); } #[Test] public function emptyValidatorWorksForEmptyCountableObjects(): void { - $countableObject = new \SplObjectStorage(); - $countableObject->offsetSet(new \stdClass()); + $countableObject = new SplObjectStorage(); + $countableObject->offsetSet(new stdClass()); self::assertTrue($this->validator->validate($countableObject)->hasErrors()); } + + protected function getValidator(array $options = []): ValidatorInterface + { + return new $this->validatorClassName($options); + } + + protected function validatorOptions(array $options): void + { + $this->validator = $this->getValidator($options); + } } diff --git a/composer.json b/composer.json index 6e30a450..8e3bfce7 100644 --- a/composer.json +++ b/composer.json @@ -38,9 +38,12 @@ "allow-plugins": { "typo3/class-alias-loader": true, "typo3/cms-composer-installers": true, - "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": true - } + "phpstan/extension-installer": true + }, + "lock": false, + "sort-packages": true }, + "version": "12.0.0", "extra": { "typo3/cms": { "extension-key": "cart", @@ -51,63 +54,38 @@ "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "ext-json": "*", "ext-openssl": "*", - "typo3/cms-core": "^13.4", - "typo3/cms-extbase": "^13.4", - "typo3/cms-fluid": "^13.4" + "typo3/cms-core": "^14.3", + "typo3/cms-extbase": "^14.3", + "typo3/cms-fluid": "^14.3", + "typo3/cms-frontend": "^14.3" }, "require-dev": { - "codappix/typo3-php-datasets": "^2.0", - "friendsofphp/php-cs-fixer": "^3.64", - "phpstan/phpstan": "^1.12", - "ssch/typo3-rector": "^2.9", - "typo3/cms-beuser": "^13.4", - "typo3/cms-dashboard": "^13.4", - "typo3/cms-form": "^13.4", - "typo3/testing-framework": "^8.2" + "codappix/typo3-php-datasets": "^2.1", + "erickskrauch/php-cs-fixer-custom-fixers": "*", + "friendsofphp/php-cs-fixer": "^3.95", + "kubawerlos/php-cs-fixer-custom-fixers": "*", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "spaze/phpstan-disallowed-calls": "^4.7", + "staabm/phpstan-todo-by": "^0.3", + "typo3/cms-beuser": "^14.3", + "typo3/cms-dashboard": "^14.3", + "typo3/cms-form": "^14.3", + "typo3/testing-framework": "^9.5", + "ssch/typo3-rector": "^3.11" }, "scripts": { - "test:cgl": [ - ".build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --using-cache=no --path-mode=intersection ./" - ], - "test:cgl:dry-run": [ - ".build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./" - ], - "test:php:lint": [ - "find *.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l" - ], - "test:php:unit": [ - ".build/bin/phpunit -c Build/UnitTests.xml" - ], - "test:php:functional": [ - "typo3DatabaseDriver=\"pdo_sqlite\" .build/bin/phpunit -c Build/FunctionalTests.xml" - ], - "test:phpstan:analyse": [ - ".build/bin/phpstan analyse -c Build/phpstan.neon --memory-limit 256M" - ], - "test:rector:process": [ - ".build/bin/rector process *" - ], - "test:rector:process:dry-run": [ - ".build/bin/rector process * --dry-run" - ], - "test:typoscript:lint": [ - ".build/bin/typoscript-lint -c Build/typoscriptlint.yaml Configuration" - ], - "test:php": [ - "@test:php:lint", - "@test:php:unit", - "@test:php:functional" - ], - "test:all": [ - "@test:phpstan:analyse", - "@test:rector:process", - "@test:cgl", - "@test:typoscript:lint", - "@test:php" - ] + "project:cgl": "php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --diff --using-cache=no", + "project:cgl:fix": "php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php --using-cache=no", + "project:lint:php": "find ./*.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l", + "project:phpstan": "phpstan analyse -c Build/phpstan.neon --memory-limit 256M", + "project:test:unit": "phpunit -c Build/phpunit.xml.dist --testsuite unit --display-warnings --display-deprecations --display-errors --display-notices", + "project:test:functional": "phpunit -c Build/phpunit.xml.dist --testsuite functional --display-warnings --display-deprecations --display-errors" }, "suggest": { - "typo3/cms-dashboard": "^13.4", - "typo3/cms-form": "^13.4" + "typo3/cms-dashboard": "^14.3", + "typo3/cms-form": "^14.3" } } diff --git a/ext_emconf.php b/ext_emconf.php deleted file mode 100644 index a71cd715..00000000 --- a/ext_emconf.php +++ /dev/null @@ -1,22 +0,0 @@ - 'Cart', - 'description' => 'Shopping Cart(s) for TYPO3', - 'category' => 'plugin', - 'version' => '11.7.2', - 'state' => 'stable', - 'author' => 'Daniel Gohlke', - 'author_email' => 'ext@extco.de', - 'author_company' => 'extco.de UG (haftungsbeschränkt)', - 'constraints' => [ - 'depends' => [ - 'php' => '8.2.0-8.5.99', - 'typo3' => '13.4.0-13.4.99', - 'extbase' => '13.4.0-13.4.99', - 'fluid' => '13.4.0-13.4.99', - ], - 'conflicts' => [], - 'suggests' => [], - ], -]; diff --git a/ext_localconf.php b/ext_localconf.php index 24086288..670647b3 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,5 +1,7 @@ 'show', - CurrencyController::class => 'update', - ], - [ - CartPreviewController::class => 'show', - CurrencyController::class => 'update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT -); +(static function (string $extKey): void { + if (is_array($GLOBALS['TYPO3_CONF_VARS'] ?? null) === false) { + throw new \Exception('$GLOBALS[\'TYPO3_CONF_VARS\'] is not an array', 1774601240); + } -ExtensionUtility::configurePlugin( - 'Cart', - 'Cart', - [ - CartController::class => 'show, clear, update', - CountryController::class => 'update', - CouponController::class => 'add, remove', - CurrencyController::class => 'update', - OrderController::class => 'show, create', - PaymentController::class => 'update', - ProductController::class => 'add, remove', - ShippingController::class => 'update', - ], - [ - CartController::class => 'show, clear, update', - CountryController::class => 'update', - CouponController::class => 'add, remove', - CurrencyController::class => 'update', - OrderController::class => 'show, create', - PaymentController::class => 'update', - ProductController::class => 'add, remove', - ShippingController::class => 'update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT -); + ArrayUtility::mergeRecursiveWithOverrule( + $GLOBALS['TYPO3_CONF_VARS'], + [ + 'LOG' => [ + 'Extcode' => [ + 'Cart' => [ + 'Domain' => [ + 'Log' => [ + 'LogService' => [ + 'writerConfiguration' => [ + LogLevel::INFO => [ + DatabaseWriter::class => [], + ], + ], + ], + ], + ], + ], + ], + ], + // view paths for TYPO3 Mail API + 'MAIL' => [ + 'templateRootPaths' => [ + '1588829280' => 'EXT:cart/Resources/Private/Templates/', + ], + 'partialRootPaths' => [ + '1588829280' => 'EXT:cart/Resources/Private/Partials/', + ], + ], + 'SYS' => [ + 'fluid' => [ + 'namespaces' => [ + 'cart' => [ + 1 => 'Extcode\\Cart\\ViewHelpers', + ], + ], + ], + ], + ] + ); -ExtensionUtility::configurePlugin( - 'Cart', - 'Currency', - [ - CurrencyController::class => 'edit, update', - ], - [ - CurrencyController::class => 'edit, update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT -); + // configure plugins + ExtensionUtility::configurePlugin( + 'Cart', + 'MiniCart', + [ + CartPreviewController::class => 'show', + CurrencyController::class => 'update', + ], + [ + CartPreviewController::class => 'show', + CurrencyController::class => 'update', + ] + ); -ExtensionUtility::configurePlugin( - 'Cart', - 'Order', - [ - \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', - ], - [ - \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT -); + ExtensionUtility::configurePlugin( + 'Cart', + 'Cart', + [ + CartController::class => 'show, clear, update', + CountryController::class => 'update', + CouponController::class => 'add, remove', + CurrencyController::class => 'update', + OrderController::class => 'show, create', + PaymentController::class => 'update', + ProductController::class => 'add, remove', + ShippingController::class => 'update', + ], + [ + CartController::class => 'show, clear, update', + CountryController::class => 'update', + CouponController::class => 'add, remove', + CurrencyController::class => 'update', + OrderController::class => 'show, create', + PaymentController::class => 'update', + ProductController::class => 'add, remove', + ShippingController::class => 'update', + ] + ); -// register "cart:" namespace -$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['cart'][] = 'Extcode\\Cart\\ViewHelpers'; + ExtensionUtility::configurePlugin( + 'Cart', + 'Currency', + [ + CurrencyController::class => 'edit, update', + ], + [ + CurrencyController::class => 'edit, update', + ] + ); -// view paths for TYPO3 Mail API -$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths']['1588829280'] = 'EXT:cart/Resources/Private/Templates/'; -$GLOBALS['TYPO3_CONF_VARS']['MAIL']['partialRootPaths']['1588829280'] = 'EXT:cart/Resources/Private/Partials/'; + ExtensionUtility::configurePlugin( + 'Cart', + 'Order', + [ + \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', + ], + [ + \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', + ] + ); +})('cart'); diff --git a/ext_tables.sql b/ext_tables.sql index acc70928..53c843d9 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -23,10 +23,10 @@ CREATE TABLE tx_cart_domain_model_order_item ( currency_code varchar(255) DEFAULT '' NOT NULL, currency_sign varchar(255) DEFAULT '' NOT NULL, currency_translation varchar(255) DEFAULT '' NOT NULL, - gross double(11,2) DEFAULT '0.00' NOT NULL, - net double(11,2) DEFAULT '0.00' NOT NULL, - total_gross double(11,2) DEFAULT '0.00' NOT NULL, - total_net double(11,2) DEFAULT '0.00' NOT NULL, + gross decimal(17,5) DEFAULT '0.00' NOT NULL, + net decimal(17,5) DEFAULT '0.00' NOT NULL, + total_gross decimal(17,5) DEFAULT '0.00' NOT NULL, + total_net decimal(17,5) DEFAULT '0.00' NOT NULL, tax int(11) unsigned DEFAULT '0' NOT NULL, total_tax int(11) unsigned DEFAULT '0' NOT NULL, @@ -81,7 +81,7 @@ CREATE TABLE tx_cart_domain_model_order_taxclass ( title varchar(255) DEFAULT '' NOT NULL, value varchar(255) DEFAULT '' NOT NULL, - calc double(11,2) DEFAULT '0.00' NOT NULL, + calc decimal(17,5) DEFAULT '0.00' NOT NULL, INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); @@ -93,7 +93,7 @@ CREATE TABLE tx_cart_domain_model_order_tax ( item int(11) unsigned DEFAULT '0' NOT NULL, record_type varchar(255) DEFAULT '' NOT NULL, - tax double(11,2) DEFAULT '0.00' NOT NULL, + tax decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class int(11) unsigned DEFAULT '0' NOT NULL, INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), @@ -111,11 +111,11 @@ CREATE TABLE tx_cart_domain_model_order_product ( sku varchar(255) DEFAULT '' NOT NULL, title varchar(255) DEFAULT '' NOT NULL, count int(11) DEFAULT '0' NOT NULL, - price double(11,2) DEFAULT '0.00' NOT NULL, - discount double(11,2) DEFAULT '0.00' NOT NULL, - gross double(11,2) DEFAULT '0.00' NOT NULL, - net double(11,2) DEFAULT '0.00' NOT NULL, - tax double(11,2) DEFAULT '0.00' NOT NULL, + price decimal(17,5) DEFAULT '0.00' NOT NULL, + discount decimal(17,5) DEFAULT '0.00' NOT NULL, + gross decimal(17,5) DEFAULT '0.00' NOT NULL, + net decimal(17,5) DEFAULT '0.00' NOT NULL, + tax decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class int(11) unsigned DEFAULT '0' NOT NULL, additional text, @@ -134,10 +134,10 @@ CREATE TABLE tx_cart_domain_model_order_discount ( title varchar(255) DEFAULT '' NOT NULL, code varchar(255) DEFAULT '' NOT NULL, - gross double(11,2) DEFAULT '0.00' NOT NULL, - net double(11,2) DEFAULT '0.00' NOT NULL, + gross decimal(17,5) DEFAULT '0.00' NOT NULL, + net decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class_id int(11) unsigned DEFAULT '1' NOT NULL, - tax double(11,2) DEFAULT '0.00' NOT NULL, + tax decimal(17,5) DEFAULT '0.00' NOT NULL, INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); @@ -169,9 +169,9 @@ CREATE TABLE tx_cart_domain_model_order_shipping ( service_id int(11) DEFAULT '0' NOT NULL, name varchar(255) DEFAULT '' NOT NULL, status varchar(255) DEFAULT '0' NOT NULL, - gross double(11,2) DEFAULT '0.00' NOT NULL, - net double(11,2) DEFAULT '0.00' NOT NULL, - tax double(11,2) DEFAULT '0.00' NOT NULL, + gross decimal(17,5) DEFAULT '0.00' NOT NULL, + net decimal(17,5) DEFAULT '0.00' NOT NULL, + tax decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class int(11) unsigned DEFAULT '0' NOT NULL, note text, @@ -190,9 +190,9 @@ CREATE TABLE tx_cart_domain_model_order_payment ( name varchar(255) DEFAULT '' NOT NULL, provider varchar(255) DEFAULT '' NOT NULL, status varchar(255) DEFAULT '0' NOT NULL, - gross double(11,2) DEFAULT '0.00' NOT NULL, - net double(11,2) DEFAULT '0.00' NOT NULL, - tax double(11,2) DEFAULT '0.00' NOT NULL, + gross decimal(17,5) DEFAULT '0.00' NOT NULL, + net decimal(17,5) DEFAULT '0.00' NOT NULL, + tax decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class int(11) unsigned DEFAULT '0' NOT NULL, note text, @@ -225,9 +225,9 @@ CREATE TABLE tx_cart_domain_model_coupon ( title varchar(255) DEFAULT '' NOT NULL, code varchar(255) DEFAULT '' NOT NULL, coupon_type varchar(255) DEFAULT 'cartdiscount' NOT NULL, - discount double(11,2) DEFAULT '0.00' NOT NULL, + discount decimal(17,5) DEFAULT '0.00' NOT NULL, tax_class_id int(11) unsigned DEFAULT '1' NOT NULL, - cart_min_price double(11,2) DEFAULT '0.00' NOT NULL, + cart_min_price decimal(17,5) DEFAULT '0.00' NOT NULL, is_combinable tinyint(4) unsigned DEFAULT '0' NOT NULL, is_relative_discount tinyint(4) unsigned DEFAULT '0' NOT NULL, handle_available tinyint(4) unsigned DEFAULT '0' NOT NULL, @@ -237,6 +237,27 @@ CREATE TABLE tx_cart_domain_model_coupon ( INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); +# +# Table structure for table 'tx_cart_domain_model_order_log' +# +CREATE TABLE tx_cart_domain_model_order_log ( + uid int(11) NOT NULL auto_increment, + item int(11) DEFAULT '0' NOT NULL, + type varchar(255) DEFAULT '' NOT NULL, + + request_id varchar(13) DEFAULT '' NOT NULL, + crdate int(11) DEFAULT '0' NOT NULL, + time_micro float DEFAULT '0' NOT NULL, + log_level varchar(10) DEFAULT 'info' NOT NULL, + level varchar(10) DEFAULT 'info' NOT NULL, + message text, + data text, + + arguments mediumtext, + + PRIMARY KEY (uid), +); + # # Table structure for table 'tx_cart_domain_model_cart' # @@ -269,3 +290,4 @@ CREATE TABLE tx_cart_domain_model_tag ( INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); + diff --git a/rector.php b/rector.php index 2c72b1d6..1ac2c13a 100644 --- a/rector.php +++ b/rector.php @@ -7,7 +7,6 @@ use Rector\PostRector\Rector\NameImportingPostRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; use Rector\ValueObject\PhpVersion; -use Ssch\TYPO3Rector\CodeQuality\General\ConvertImplicitVariablesToExplicitGlobalsRector; use Ssch\TYPO3Rector\CodeQuality\General\ExtEmConfRector; use Ssch\TYPO3Rector\CodeQuality\General\InjectMethodToConstructorInjectionRector; use Ssch\TYPO3Rector\Configuration\Typo3Option; @@ -20,7 +19,6 @@ __DIR__ . '/Classes', __DIR__ . '/Configuration', __DIR__ . '/Tests', - __DIR__ . '/ext_emconf.php', __DIR__ . '/ext_localconf.php', ]) // uncomment to reach your current PHP version @@ -29,7 +27,7 @@ ->withSets([ Typo3SetList::CODE_QUALITY, Typo3SetList::GENERAL, - Typo3LevelSetList::UP_TO_TYPO3_13, + Typo3LevelSetList::UP_TO_TYPO3_14, ]) // To have a better analysis from PHPStan, we teach it here some more things ->withPHPStanConfigs([ @@ -37,7 +35,6 @@ ]) ->withRules([ AddVoidReturnTypeWhereNoReturnRector::class, - ConvertImplicitVariablesToExplicitGlobalsRector::class, ]) ->withConfiguredRule(ExtEmConfRector::class, [ ExtEmConfRector::PHP_VERSION_CONSTRAINT => '8.2.0-8.4.99', diff --git a/shell.nix b/shell.nix index c0a30c3b..4ab74c62 100644 --- a/shell.nix +++ b/shell.nix @@ -19,8 +19,8 @@ let projectInstall = pkgs.writeShellApplication { name = "project-install"; runtimeInputs = [ - php composer + php ]; text = '' composer update --prefer-dist --no-progress @@ -31,11 +31,12 @@ let name = "project-cgl"; runtimeInputs = [ + composer php ]; text = '' - ./.build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --diff + composer project:cgl ''; }; @@ -43,23 +44,25 @@ let name = "project-cgl-fix"; runtimeInputs = [ + composer php ]; text = '' - ./.build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php + composer project:cgl:fix ''; }; - projectLint = pkgs.writeShellApplication { - name = "project-lint"; + projectLintPhp = pkgs.writeShellApplication { + name = "project-lint-php"; runtimeInputs = [ + composer php ]; text = '' - find ./*.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l + composer project:lint:php ''; }; @@ -67,35 +70,38 @@ let name = "project-phpstan"; runtimeInputs = [ + composer php ]; text = '' - ./.build/bin/phpstan analyse -c Build/phpstan.neon --memory-limit 256M + composer project:phpstan ''; }; projectTestUnit = pkgs.writeShellApplication { name = "project-test-unit"; runtimeInputs = [ + composer php projectInstall ]; text = '' project-install - .build/bin/phpunit -c Build/UnitTests.xml --display-deprecations --display-warnings + composer project:test:unit ''; }; projectTestFunctional = pkgs.writeShellApplication { name = "project-test-functional"; runtimeInputs = [ + composer php projectInstall ]; text = '' project-install - .build/bin/phpunit -c Build/FunctionalTests.xml --display-deprecations --display-warnings + composer project:test:functional ''; }; @@ -105,10 +111,9 @@ in pkgs.mkShell { php composer projectInstall - projectPhpstan projectCgl projectCglFix - projectLint + projectLintPhp projectPhpstan projectTestUnit projectTestFunctional