From cc5813a7d8cd8e81d968a178530cc6941b609721 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 4 Mar 2025 22:14:36 +0100 Subject: [PATCH 01/14] [TASK] Add TYPO3 v14 support --- Build/UnitTests.xml | 33 - Build/UnitTestsBootstrap.php | 46 +- Build/phpstan-baseline.neon | 5622 ++++++++++++++++- Build/phpstan.neon | 30 +- .../{FunctionalTests.xml => phpunit.xml.dist} | 5 +- .../Controller/Backend/ActionController.php | 9 +- .../Backend/Order/DocumentController.php | 1 - .../Backend/Order/OrderController.php | 9 +- Classes/Controller/Cart/CartController.php | 12 +- Classes/Controller/Cart/CountryController.php | 6 +- .../Controller/Cart/CurrencyController.php | 6 +- Classes/Controller/Cart/OrderController.php | 34 +- Classes/Controller/Cart/ProductController.php | 2 +- .../Finisher/Form/AddToCartFinisher.php | 8 +- .../Domain/Model/Cart/AbstractCartCoupon.php | 12 - Classes/Domain/Model/Cart/BeVariant.php | 12 +- Classes/Domain/Model/Cart/Cart.php | 50 +- .../Domain/Model/Cart/CartCouponInterface.php | 10 +- Classes/Domain/Model/Cart/Product.php | 2 +- Classes/Domain/Model/Cart/Service.php | 12 +- .../Domain/Model/Order/AbstractAddress.php | 2 +- .../Domain/Model/Order/AddressInterface.php | 90 + Classes/Domain/Model/Order/Item.php | 12 +- .../Domain/Model/Product/CategoryTrait.php | 2 +- .../Model/Product/FileAndImageTrait.php | 2 +- Classes/Domain/Model/Product/MeasureTrait.php | 2 +- .../Model/Product/ServiceAttributeTrait.php | 2 +- Classes/Domain/Model/Product/StockTrait.php | 2 +- Classes/Domain/Model/Product/TagTrait.php | 2 +- .../Order/ProductAdditionalRepository.php | 2 +- Classes/Event/Cart/BeforeShowCartEvent.php | 15 +- Classes/Event/Cart/UpdateCountryEvent.php | 6 +- .../Cart/UpdateCountryEventInterface.php | 6 +- Classes/Event/Cart/UpdateCurrencyEvent.php | 6 +- .../Cart/UpdateCurrencyEventInterface.php | 6 +- .../Event/CheckProductAvailabilityEvent.php | 6 +- ...CheckProductAvailabilityEventInterface.php | 11 +- .../RetrieveProductsFromRequestEvent.php | 6 +- ...rieveProductsFromRequestEventInterface.php | 6 +- .../Session/AfterRestoreAddressEvent.php | 8 +- .../Event/Session/BeforeWriteAddressEvent.php | 8 +- Classes/EventListener/Order/Create/Number.php | 16 +- .../Order/Create/PersistOrder/Item.php | 11 +- .../EventListener/Order/Finish/ClearCart.php | 2 +- Classes/EventListener/Order/Finish/Email.php | 4 +- .../Template/Components/ModifyButtonBar.php | 4 +- Classes/Service/SessionHandler.php | 12 +- Classes/Service/TaxClassService.php | 3 +- Classes/Updates/ExtcodeCartCTypeMigration.php | 36 + Classes/Updates/ListTypeToCTypeUpdate.php | 8 +- Classes/Utility/CartUtility.php | 16 +- Classes/Utility/CurrencyUtility.php | 15 +- .../Validation/Validator/EmptyValidator.php | 8 +- Classes/ViewHelpers/IncludeFileViewHelper.php | 15 +- Classes/ViewHelpers/MetaTagViewHelper.php | 4 +- Classes/ViewHelpers/TitleTagViewHelper.php | 23 +- .../Traversable/ExtractViewHelper.php | 2 +- Classes/Widgets/PaymentPaidShippingOpen.php | 3 +- .../Widgets/Provider/OrdersPerDayProvider.php | 7 +- .../Provider/TurnoverPerDayProvider.php | 7 +- Configuration/Icons.php | 14 +- Configuration/Services.php | 12 +- Configuration/TCA/Overrides/tt_content.php | 28 +- .../Command/OrderItemCleanupCommandTest.php | 116 +- .../Mail/AttachmentFromTypoScriptTest.php | 2 +- Tests/ObjectAccess.php | 29 + .../Unit/Domain/Model/Cart/BeVariantTest.php | 101 +- .../Domain/Model/Cart/CartCouponFixTest.php | 79 +- .../Model/Cart/CartCouponPercentageTest.php | 79 +- Tests/Unit/Domain/Model/Cart/CartTest.php | 13 +- Tests/Unit/Domain/Model/Cart/ProductTest.php | 125 +- Tests/Unit/Domain/Model/Cart/ServiceTest.php | 4 + Tests/Unit/Domain/Model/Cart/TaxClassTest.php | 10 +- Tests/Unit/Domain/Model/CouponTest.php | 72 +- .../Model/Order/AbstractAddressTest.php | 84 +- .../Model/Order/AbstractServiceTest.php | 4 +- .../Unit/Domain/Model/Order/DiscountTest.php | 92 +- Tests/Unit/Domain/Model/Order/ItemTest.php | 2 + Tests/Unit/Domain/Model/Order/PaymentTest.php | 2 + .../Model/Order/ProductAdditionalTest.php | 38 +- Tests/Unit/Domain/Model/Order/ProductTest.php | 2 + .../Unit/Domain/Model/Order/ShippingTest.php | 2 + .../Unit/Domain/Model/Order/TaxClassTest.php | 2 + Tests/Unit/Domain/Model/Order/TaxTest.php | 24 +- .../Domain/Model/Order/TransactionTest.php | 2 + .../Model/Product/AbstractProductTest.php | 12 +- .../Model/Product/CategoryTraitStub.php | 19 + .../Model/Product/CategoryTraitTest.php | 2 +- .../Domain/Model/Product/MeasureTraitStub.php | 19 + .../Domain/Model/Product/MeasureTraitTest.php | 2 +- .../Product/ServiceAttributeTraitStub.php | 19 + .../Product/ServiceAttributeTraitTest.php | 2 +- .../Domain/Model/Product/StockTraitStub.php | 19 + .../Domain/Model/Product/StockTraitTest.php | 2 +- .../Domain/Model/Product/TagTraitStub.php | 19 + .../Domain/Model/Product/TagTraitTest.php | 2 +- Tests/Unit/Domain/Model/TagTest.php | 12 +- Tests/Unit/Service/TaxClassServiceTest.php | 18 +- .../Validator/EmptyValidatorTest.php | 2 + composer.json | 37 +- ext_emconf.php | 2 +- ext_localconf.php | 12 +- rector.php | 4 +- shell.nix | 4 +- 104 files changed, 6346 insertions(+), 1119 deletions(-) delete mode 100644 Build/UnitTests.xml rename Build/{FunctionalTests.xml => phpunit.xml.dist} (88%) create mode 100644 Classes/Domain/Model/Order/AddressInterface.php create mode 100644 Classes/Updates/ExtcodeCartCTypeMigration.php create mode 100644 Tests/ObjectAccess.php create mode 100644 Tests/Unit/Domain/Model/Product/CategoryTraitStub.php create mode 100644 Tests/Unit/Domain/Model/Product/MeasureTraitStub.php create mode 100644 Tests/Unit/Domain/Model/Product/ServiceAttributeTraitStub.php create mode 100644 Tests/Unit/Domain/Model/Product/StockTraitStub.php create mode 100644 Tests/Unit/Domain/Model/Product/TagTraitStub.php 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..26a03f23 100644 --- a/Build/UnitTestsBootstrap.php +++ b/Build/UnitTestsBootstrap.php @@ -1,5 +1,18 @@ 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..1878ea93 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -1,21 +1,5629 @@ parameters: ignoreErrors: - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Service\\\\PaymentMethodsServiceInterface\\:\\:getConfigurationsForType\\(\\)\\.$#" + 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: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Parameter \#2 \$messageTitle of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Controller/Cart/CartController.php + + - + message: '#^Parameter \#3 \$severity of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects TYPO3\\CMS\\Core\\Type\\ContextualFeedbackSeverity, mixed given\.$#' + identifier: argument.type + count: 1 + 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: "#^Call to an undefined method Extcode\\\\Cart\\\\Domain\\\\Model\\\\Cart\\\\CartCouponInterface\\:\\:getTaxClass\\(\\)\\.$#" + 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: '#^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\\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: 9 + 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: 1 + 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: '#^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: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' + identifier: argument.type + 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 \$object of method TYPO3\\CMS\\Extbase\\Persistence\\Repository\\:\:add\(\) expects TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface, Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php + + - + message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int 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 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' + identifier: argument.type + count: 1 + 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 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int 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: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php + + - + message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/EventListener/Order/Create/PersistOrder/Taxes.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: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''code'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''countries'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 4 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''options'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''preset'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''settings'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset ''zones'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Cannot access offset mixed on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getConfigurationsForType\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getConfigurationsForType\(\) should return array\|null but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getServices\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getServices\(\) has parameter \$services with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getServices\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getTypeZonesPluginSettings\(\) has parameter \$zoneSettings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getTypeZonesPluginSettings\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getTypeZonesPluginSettings\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.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/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Parameter \#2 \$country of method Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:getTypeZonesPluginSettings\(\) expects string, mixed given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.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/Service/AbstractConfigurationFromTypoScriptService.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/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.php + + - + message: '#^Property Extcode\\Cart\\Service\\AbstractConfigurationFromTypoScriptService\:\:\$configurations type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/AbstractConfigurationFromTypoScriptService.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 getEmail\(\) on Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface\|null\.$#' + identifier: method.nonObject + count: 4 + 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: '#^Method Extcode\\Cart\\Service\\PaymentMethodsFromTypoScriptService\:\:getPaymentMethods\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Service/PaymentMethodsFromTypoScriptService.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: '#^Method Extcode\\Cart\\Service\\ShippingMethodsFromTypoScriptService\:\:getShippingMethods\(\) should return array\ but returns array\.$#' + identifier: return.type + count: 1 + path: ../Classes/Service/ShippingMethodsFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\SpecialOptionsFromTypoScriptService\:\:getSpecialOptions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/SpecialOptionsFromTypoScriptService.php + + - + message: '#^Method Extcode\\Cart\\Service\\SpecialOptionsServiceInterface\:\:getSpecialOptions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/SpecialOptionsServiceInterface.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: ../Classes/Service/TaxClassService.php + + - + message: '#^Parameter \#1 \$key of function array_key_exists expects int\|string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: ../Classes/Service/TaxClassService.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/Service/TaxClassService.php + + - + message: '#^Parameter \#2 \$array of function array_key_exists expects array, mixed given\.$#' + identifier: argument.type + count: 2 + path: ../Classes/Service/TaxClassService.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/Service/TaxClassService.php + + - + message: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 1 + path: ../Classes/Service/TaxClassService.php + + - + message: '#^Property Extcode\\Cart\\Service\\TaxClassService\:\:\$settings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/Service/TaxClassService.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\\Service\\TaxClassServiceInterface\:\: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: 2 + 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 was…'' 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: '#^Method Extcode\\Cart\\ViewHelpers\\Form\\IsServiceAvailableAtPriceViewHelper\:\:evaluateCondition\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php + + - + message: '#^Offset ''price'' might not exist on array\|null\.$#' + identifier: offsetAccess.notFound + count: 1 + path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php + + - + message: '#^Offset ''service'' might not exist on array\|null\.$#' + identifier: offsetAccess.notFound + 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: binaryOp.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 array\.$#' + identifier: return.type + 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: '#^Possibly invalid array key type mixed\.$#' + identifier: offsetAccess.invalidOffset + count: 2 + 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: '#^Method Extcode\\Cart\\ViewHelpers\\Traversable\\ExtractViewHelper\:\:render\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Classes/ViewHelpers/Traversable/ExtractViewHelper.php + + - + message: '#^Method Extcode\\Cart\\ViewHelpers\\Traversable\\ExtractViewHelper\:\:render\(\) should return array but returns mixed\.$#' + identifier: return.type + count: 2 + 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 an offset on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 3 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''columns'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''config'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''contains\-coupons'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''contains\-orders'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''ctrl'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''doktype'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''items'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''module'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''pages'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset ''typeicon_classes'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../Configuration/TCA/Overrides/pages.php + + - + message: '#^Cannot access offset 181 on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + 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\(\) has no return type specified\.$#' + identifier: missingType.return + 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: '#^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: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Cannot call method getTitle\(\) on mixed\.$#' + identifier: method.nonObject + count: 1 + path: ../Tests/Unit/Controller/ProductControllerTest.php + + - + 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: ../Tests/Unit/Controller/ProductControllerTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Controller\\ProductControllerTest\:\:getHighestSeverityDataProvider\(\) return type has no value type specified in iterable type Traversable\.$#' + 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 Traversable\.$#' + 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: '#^Parameter \#1 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' + identifier: argument.type + count: 1 + 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 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' + identifier: argument.type + count: 1 + path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.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: ../Classes/Domain/Model/Cart/Cart.php + 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: "#^Call to an undefined method Extcode\\\\Cart\\\\Domain\\\\Model\\\\Cart\\\\CartCouponInterface\\:\\:setCart\\(\\)\\.$#" + 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: ../Classes/Domain/Model/Cart/Cart.php + path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php - - message: "#^Call to an undefined method Extcode\\\\Cart\\\\Service\\\\PaymentMethodsServiceInterface\\:\\:getConfigurationsForType\\(\\)\\.$#" + 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: '#^Parameter \#1 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' + identifier: argument.type count: 1 - path: ../Classes/EventListener/Order/Finish/ClearCart.php + 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 array\.$#' + 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: '#^Cannot call method getConfigurationsForType\(\) on mixed\.$#' + identifier: method.nonObject + count: 2 + path: ../Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Service\\AbstractConfigurationFromTypoScriptServiceTest\:\:createSubject\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: ../Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Service\\AbstractConfigurationFromTypoScriptServiceTest\:\:createSubject\(\) has parameter \$configurations with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Service/AbstractConfigurationFromTypoScriptServiceTest.php + + - + message: '#^Method Extcode\\Cart\\Tests\\Unit\\Service\\TaxClassServiceTest\:\:createSubject\(\) has parameter \$settings with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../Tests/Unit/Service/TaxClassServiceTest.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 + + - + message: '#^Cannot access offset ''cart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_emconf.php + + - + message: '#^Cannot access an offset on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''1588829280'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 2 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''MAIL'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''SYS'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''cart'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''fluid'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''namespaces'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''partialRootPaths'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php + + - + message: '#^Cannot access offset ''templateRootPaths'' on mixed\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: ../ext_localconf.php diff --git a/Build/phpstan.neon b/Build/phpstan.neon index 13c67700..06ce5b1c 100644 --- a/Build/phpstan.neon +++ b/Build/phpstan.neon @@ -1,10 +1,36 @@ 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/Controller/Backend/ActionController.php b/Classes/Controller/Backend/ActionController.php index 75ab8d30..bc5dd35c 100644 --- a/Classes/Controller/Backend/ActionController.php +++ b/Classes/Controller/Backend/ActionController.php @@ -12,12 +12,15 @@ */ 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 { @@ -33,9 +36,7 @@ protected function initializeAction(): void $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..4bddb8dc 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; diff --git a/Classes/Controller/Backend/Order/OrderController.php b/Classes/Controller/Backend/Order/OrderController.php index 15cefc8b..556ecb91 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; @@ -47,7 +47,8 @@ public function __construct( protected readonly IconFactory $iconFactory, protected readonly PersistenceManager $persistenceManager, protected readonly ItemRepository $itemRepository, - private readonly PageRenderer $pageRenderer + private readonly PageRenderer $pageRenderer, + private readonly ComponentFactory $componentFactory ) {} protected function initializeAction(): void @@ -275,9 +276,9 @@ 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']) diff --git a/Classes/Controller/Cart/CartController.php b/Classes/Controller/Cart/CartController.php index de0e7a34..b2a4976a 100755 --- a/Classes/Controller/Cart/CartController.php +++ b/Classes/Controller/Cart/CartController.php @@ -11,6 +11,7 @@ * 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; @@ -24,8 +25,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(); @@ -69,7 +70,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(); diff --git a/Classes/Controller/Cart/CountryController.php b/Classes/Controller/Cart/CountryController.php index 6c03cb26..2f7fce13 100644 --- a/Classes/Controller/Cart/CountryController.php +++ b/Classes/Controller/Cart/CountryController.php @@ -23,7 +23,11 @@ public function updateAction(): ResponseInterface { //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(); diff --git a/Classes/Controller/Cart/CurrencyController.php b/Classes/Controller/Cart/CurrencyController.php index a0868958..4cf44a0a 100644 --- a/Classes/Controller/Cart/CurrencyController.php +++ b/Classes/Controller/Cart/CurrencyController.php @@ -24,7 +24,11 @@ public function __construct( 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..7828dc52 100644 --- a/Classes/Controller/Cart/OrderController.php +++ b/Classes/Controller/Cart/OrderController.php @@ -10,7 +10,8 @@ * 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\AddressInterface; use Extcode\Cart\Domain\Model\Order\Item; use Extcode\Cart\Domain\Model\Order\ShippingAddress; use Extcode\Cart\Domain\Validator\OrderItemValidator; @@ -21,15 +22,12 @@ 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 { @@ -58,8 +56,8 @@ public function initializeCreateAction(): void #[IgnoreValidation(['value' => 'shippingAddress'])] public function createAction( ?Item $orderItem = null, - ?BillingAddress $billingAddress = null, - ?ShippingAddress $shippingAddress = null + ?AddressInterface $billingAddress = null, + ?AddressInterface $shippingAddress = null ): ResponseInterface { $this->restoreSession(); @@ -122,10 +120,14 @@ public function createAction( $this->view->assign('orderItem', $orderItem); $paymentId = $this->cart->getPayment()->getId(); - $paymentSettings = $this->paymentMethodsService->getConfigurationsForType('payments', $this->cart->getBillingCountry()); + $paymentSettings = $this->paymentMethodsService->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(); @@ -171,9 +173,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,36 +209,36 @@ 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()) { + if ($finishEvent->isPropagationStopped()) { return true; } diff --git a/Classes/Controller/Cart/ProductController.php b/Classes/Controller/Cart/ProductController.php index b93dc4b5..13c7e959 100644 --- a/Classes/Controller/Cart/ProductController.php +++ b/Classes/Controller/Cart/ProductController.php @@ -27,7 +27,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(); diff --git a/Classes/Domain/Finisher/Form/AddToCartFinisher.php b/Classes/Domain/Finisher/Form/AddToCartFinisher.php index 864c68b3..2b49858c 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, @@ -109,8 +111,8 @@ protected function executeInternal(): ?string 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( 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/BeVariant.php b/Classes/Domain/Model/Cart/BeVariant.php index 98748db6..bdcdf84d 100644 --- a/Classes/Domain/Model/Cart/BeVariant.php +++ b/Classes/Domain/Model/Cart/BeVariant.php @@ -125,11 +125,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(); } @@ -215,10 +213,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) { @@ -295,11 +291,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(); } diff --git a/Classes/Domain/Model/Cart/Cart.php b/Classes/Domain/Model/Cart/Cart.php index e635b3aa..2b71d3d6 100644 --- a/Classes/Domain/Model/Cart/Cart.php +++ b/Classes/Domain/Model/Cart/Cart.php @@ -29,7 +29,7 @@ class Cart implements AdditionalDataInterface protected int $count; /** - * @var Product[] + * @var ProductInterface[] */ protected array $products = []; @@ -484,14 +484,14 @@ 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; } @@ -678,7 +678,7 @@ public function getDiscountTaxes(): array return $taxes; } - public function addProduct(Product $newProduct): void + public function addProduct(ProductInterface $newProduct): void { $id = $newProduct->getId(); @@ -695,7 +695,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(); @@ -725,34 +725,32 @@ 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()); - } } } @@ -789,9 +787,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,7 +809,7 @@ public function removeProduct(Product $product, array $productVariantIds = []): return true; } - protected function addServiceAttributes(Product $newProduct): void + protected function addServiceAttributes(ProductInterface $newProduct): void { if ($this->maxServiceAttr1 < $newProduct->getServiceAttribute1()) { $this->maxServiceAttr1 = $newProduct->getServiceAttribute1(); 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/Product.php b/Classes/Domain/Model/Cart/Product.php index 58d9a08b..fd963f86 100644 --- a/Classes/Domain/Model/Cart/Product.php +++ b/Classes/Domain/Model/Cart/Product.php @@ -312,7 +312,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); diff --git a/Classes/Domain/Model/Cart/Service.php b/Classes/Domain/Model/Cart/Service.php index ab39b10c..fd3dd0b9 100644 --- a/Classes/Domain/Model/Cart/Service.php +++ b/Classes/Domain/Model/Cart/Service.php @@ -202,12 +202,16 @@ public function getFallBackId(): ?int 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; } } diff --git a/Classes/Domain/Model/Order/AbstractAddress.php b/Classes/Domain/Model/Order/AbstractAddress.php index 8906247b..75dc3c22 100755 --- a/Classes/Domain/Model/Order/AbstractAddress.php +++ b/Classes/Domain/Model/Order/AbstractAddress.php @@ -15,7 +15,7 @@ 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; diff --git a/Classes/Domain/Model/Order/AddressInterface.php b/Classes/Domain/Model/Order/AddressInterface.php new file mode 100644 index 00000000..648adb89 --- /dev/null +++ b/Classes/Domain/Model/Order/AddressInterface.php @@ -0,0 +1,90 @@ +shippingSameAsBilling = $shippingSameAsBilling; } - 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/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..eb5cac3a 100644 --- a/Classes/Domain/Model/Product/MeasureTrait.php +++ b/Classes/Domain/Model/Product/MeasureTrait.php @@ -9,7 +9,7 @@ * LICENSE file that was distributed with this source code. */ -trait MeasureTrait +trait MeasureTrait // @phpstan-ignore trait.unused (provided for product extensions) { protected float $priceMeasure = 0.0; diff --git a/Classes/Domain/Model/Product/ServiceAttributeTrait.php b/Classes/Domain/Model/Product/ServiceAttributeTrait.php index cf1face1..039c6e33 100644 --- a/Classes/Domain/Model/Product/ServiceAttributeTrait.php +++ b/Classes/Domain/Model/Product/ServiceAttributeTrait.php @@ -9,7 +9,7 @@ * LICENSE file that was distributed with this source code. */ -trait ServiceAttributeTrait +trait ServiceAttributeTrait // @phpstan-ignore trait.unused (provided for product extensions) { protected float $serviceAttribute1 = 0.0; diff --git a/Classes/Domain/Model/Product/StockTrait.php b/Classes/Domain/Model/Product/StockTrait.php index ffae62dc..b2e7c44f 100644 --- a/Classes/Domain/Model/Product/StockTrait.php +++ b/Classes/Domain/Model/Product/StockTrait.php @@ -11,7 +11,7 @@ * LICENSE file that was distributed with this source code. */ -trait StockTrait +trait StockTrait // @phpstan-ignore trait.unused (provided for product extensions) { protected bool $handleStock = false; diff --git a/Classes/Domain/Model/Product/TagTrait.php b/Classes/Domain/Model/Product/TagTrait.php index 23e238d3..22301e13 100644 --- a/Classes/Domain/Model/Product/TagTrait.php +++ b/Classes/Domain/Model/Product/TagTrait.php @@ -14,7 +14,7 @@ use Extcode\Cart\Domain\Model\Tag; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; -trait TagTrait +trait TagTrait // @phpstan-ignore trait.unused (provided for product extensions) { /** * @var ObjectStorage diff --git a/Classes/Domain/Repository/Order/ProductAdditionalRepository.php b/Classes/Domain/Repository/Order/ProductAdditionalRepository.php index 56b65baa..e26778e1 100644 --- a/Classes/Domain/Repository/Order/ProductAdditionalRepository.php +++ b/Classes/Domain/Repository/Order/ProductAdditionalRepository.php @@ -33,7 +33,7 @@ public function findAllByAdditionalType(array $arguments = [], string $additiona } } - $constraint = $query->logicalAnd($and); + $constraint = $query->logicalAnd(...$and); $query->matching($constraint); return $query->execute(); diff --git a/Classes/Event/Cart/BeforeShowCartEvent.php b/Classes/Event/Cart/BeforeShowCartEvent.php index 88bc36d9..b18f091c 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,8 +23,8 @@ 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 +47,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..cf381e5b 100644 --- a/Classes/Event/Cart/UpdateCountryEvent.php +++ b/Classes/Event/Cart/UpdateCountryEvent.php @@ -12,13 +12,13 @@ */ 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 @@ -26,7 +26,7 @@ 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..f6ea0adf 100644 --- a/Classes/Event/Cart/UpdateCountryEventInterface.php +++ b/Classes/Event/Cart/UpdateCountryEventInterface.php @@ -3,13 +3,13 @@ namespace Extcode\Cart\Event\Cart; use Extcode\Cart\Domain\Model\Cart\Cart; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; interface UpdateCountryEventInterface { - public function __construct(Cart $cart, Request $request); + public function __construct(Cart $cart, RequestInterface $request); public function getCart(): Cart; - public function getRequest(): Request; + public function getRequest(): RequestInterface; } diff --git a/Classes/Event/Cart/UpdateCurrencyEvent.php b/Classes/Event/Cart/UpdateCurrencyEvent.php index a9bdb2b4..481e6ca3 100644 --- a/Classes/Event/Cart/UpdateCurrencyEvent.php +++ b/Classes/Event/Cart/UpdateCurrencyEvent.php @@ -12,13 +12,13 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; final readonly class UpdateCurrencyEvent implements UpdateCurrencyEventInterface { public function __construct( private Cart $cart, - private Request $request, + private RequestInterface $request, private array $settings = [] ) {} @@ -27,7 +27,7 @@ public function getCart(): Cart return $this->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..f6118a66 100644 --- a/Classes/Event/Cart/UpdateCurrencyEventInterface.php +++ b/Classes/Event/Cart/UpdateCurrencyEventInterface.php @@ -3,15 +3,15 @@ namespace Extcode\Cart\Event\Cart; use Extcode\Cart\Domain\Model\Cart\Cart; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; interface UpdateCurrencyEventInterface { - public function __construct(Cart $cart, Request $request, array $settings); + public function __construct(Cart $cart, RequestInterface $request, array $settings); public function getCart(): Cart; - public function getRequest(): Request; + public function getRequest(): RequestInterface; public function getSettings(): array; } diff --git a/Classes/Event/CheckProductAvailabilityEvent.php b/Classes/Event/CheckProductAvailabilityEvent.php index 5d23c297..2c85e502 100644 --- a/Classes/Event/CheckProductAvailabilityEvent.php +++ b/Classes/Event/CheckProductAvailabilityEvent.php @@ -12,7 +12,7 @@ */ 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; class CheckProductAvailabilityEvent implements CheckProductAvailabilityEventInterface @@ -26,7 +26,7 @@ class CheckProductAvailabilityEvent implements CheckProductAvailabilityEventInte public function __construct( private readonly Cart $cart, - private readonly Product $product, + private readonly ProductInterface $product, private readonly mixed $quantity, private readonly string $mode = 'update' ) {} @@ -36,7 +36,7 @@ public function getCart(): Cart return $this->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/RetrieveProductsFromRequestEvent.php b/Classes/Event/RetrieveProductsFromRequestEvent.php index b296b4b6..5ad1d5b5 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,7 +31,7 @@ final class RetrieveProductsFromRequestEvent implements RetrieveProductsFromRequ private array $products = []; public function __construct( - private readonly Request $request, + private readonly RequestInterface $request, private readonly Cart $cart ) {} @@ -40,7 +40,7 @@ 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..1998df1a 100644 --- a/Classes/Event/Session/AfterRestoreAddressEvent.php +++ b/Classes/Event/Session/AfterRestoreAddressEvent.php @@ -11,21 +11,21 @@ * 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/BeforeWriteAddressEvent.php b/Classes/Event/Session/BeforeWriteAddressEvent.php index 13972bb4..2145e6c4 100644 --- a/Classes/Event/Session/BeforeWriteAddressEvent.php +++ b/Classes/Event/Session/BeforeWriteAddressEvent.php @@ -11,21 +11,21 @@ * 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/EventListener/Order/Create/Number.php b/Classes/EventListener/Order/Create/Number.php index ba1727c4..0d4a7cb2 100644 --- a/Classes/EventListener/Order/Create/Number.php +++ b/Classes/EventListener/Order/Create/Number.php @@ -19,25 +19,11 @@ 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 = [] - ) { - $this->persistenceManager = $persistenceManager; - $this->orderItemRepository = $orderItemRepository; - $this->options = $options; - } + public function __construct(protected PersistenceManager $persistenceManager, protected OrderItemRepository $orderItemRepository, protected array $options = []) {} protected function generateNumber(NumberGeneratorEventInterface $event): string { diff --git a/Classes/EventListener/Order/Create/PersistOrder/Item.php b/Classes/EventListener/Order/Create/PersistOrder/Item.php index 7b245c32..b920f16f 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,7 +26,8 @@ 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 +39,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 ); diff --git a/Classes/EventListener/Order/Finish/ClearCart.php b/Classes/EventListener/Order/Finish/ClearCart.php index 88fbd26b..c4c2c6a1 100644 --- a/Classes/EventListener/Order/Finish/ClearCart.php +++ b/Classes/EventListener/Order/Finish/ClearCart.php @@ -33,7 +33,7 @@ public function __invoke(EventInterface $event): void $settings = $event->getSettings(); $paymentId = $cart->getPayment()->getId(); - $paymentSettings = $this->paymentMethodsService->getConfigurationsForType('payments', $cart->getBillingCountry()); + $paymentSettings = $this->paymentMethodsService->getPaymentMethods($cart); if ((int)($paymentSettings['options'][$paymentId]['preventClearCart'] ?? 0) != 1) { $cartPid = $settings['settings']['cart']['pid']; diff --git a/Classes/EventListener/Order/Finish/Email.php b/Classes/EventListener/Order/Finish/Email.php index e8dcc94b..48878104 100644 --- a/Classes/EventListener/Order/Finish/Email.php +++ b/Classes/EventListener/Order/Finish/Email.php @@ -34,13 +34,13 @@ public function __invoke(EventInterface $event): void 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/Template/Components/ModifyButtonBar.php b/Classes/EventListener/Template/Components/ModifyButtonBar.php index ed6b3dad..b9f3a853 100644 --- a/Classes/EventListener/Template/Components/ModifyButtonBar.php +++ b/Classes/EventListener/Template/Components/ModifyButtonBar.php @@ -31,7 +31,7 @@ public function __invoke(ModifyButtonBarEvent $event): void } } - private function modifyListActionButtons(ModifyButtonBarEvent $event) + private function modifyListActionButtons(ModifyButtonBarEvent $event): void { $event->setButtons( array_merge( @@ -51,7 +51,7 @@ private function modifyListActionButtons(ModifyButtonBarEvent $event) ); } - private function modifyShowActionButtons(ModifyButtonBarEvent $event) + private function modifyShowActionButtons(ModifyButtonBarEvent $event): void { $event->setButtons( array_merge( diff --git a/Classes/Service/SessionHandler.php b/Classes/Service/SessionHandler.php index 804c7d01..48ac5cab 100644 --- a/Classes/Service/SessionHandler.php +++ b/Classes/Service/SessionHandler.php @@ -10,7 +10,7 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; -use Extcode\Cart\Domain\Model\Order\AbstractAddress; +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Extcode\Cart\Event\Session\AfterRestoreAddressEvent; use Extcode\Cart\Event\Session\AfterRestoreCartEvent; use Extcode\Cart\Event\Session\BeforeWriteAddressEvent; @@ -72,15 +72,15 @@ 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 +91,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/Service/TaxClassService.php b/Classes/Service/TaxClassService.php index a1615a45..65ff9000 100644 --- a/Classes/Service/TaxClassService.php +++ b/Classes/Service/TaxClassService.php @@ -39,8 +39,7 @@ public function getTaxClasses(?string $countryCode = null): array $taxClassSettings = $this->settings['taxClasses']; if ( - is_null($countryCode) === false - && array_key_exists($countryCode, $taxClassSettings) + array_key_exists($countryCode, $taxClassSettings) && is_array($taxClassSettings[$countryCode]) ) { $taxClassSettings = $taxClassSettings[$countryCode]; 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..cc231681 100644 --- a/Classes/Updates/ListTypeToCTypeUpdate.php +++ b/Classes/Updates/ListTypeToCTypeUpdate.php @@ -1,9 +1,8 @@ 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()); @@ -87,7 +93,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 diff --git a/Classes/Utility/CurrencyUtility.php b/Classes/Utility/CurrencyUtility.php index a92b9f10..e0099945 100644 --- a/Classes/Utility/CurrencyUtility.php +++ b/Classes/Utility/CurrencyUtility.php @@ -12,7 +12,7 @@ use Extcode\Cart\Event\Cart\UpdateCurrencyEvent; use Extcode\Cart\Service\SessionHandler; use Psr\EventDispatcher\EventDispatcherInterface; -use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; class CurrencyUtility { @@ -21,11 +21,18 @@ public function __construct( protected SessionHandler $sessionHandler ) {} - public function updateCurrency(array $cartSettings, array $pluginSettings, Request $request): void - { + public function updateCurrency( + array $cartSettings, + array $pluginSettings, + RequestInterface $request + ): void { $cart = $this->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/Validation/Validator/EmptyValidator.php b/Classes/Validation/Validator/EmptyValidator.php index 3f992295..7319803d 100644 --- a/Classes/Validation/Validator/EmptyValidator.php +++ b/Classes/Validation/Validator/EmptyValidator.php @@ -39,7 +39,7 @@ public function isValid(mixed $value): void ); } elseif ( is_string($value) - && $value != '' + && !empty($value) ) { $this->addError( $this->translateErrorMessage( @@ -59,7 +59,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', diff --git a/Classes/ViewHelpers/IncludeFileViewHelper.php b/Classes/ViewHelpers/IncludeFileViewHelper.php index 3b83421f..e33ee4b4 100644 --- a/Classes/ViewHelpers/IncludeFileViewHelper.php +++ b/Classes/ViewHelpers/IncludeFileViewHelper.php @@ -8,6 +8,8 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ + +use Psr\Log\LogLevel; use TYPO3\CMS\Core\Http\ApplicationType; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException; @@ -15,12 +17,17 @@ use TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException; use TYPO3\CMS\Core\Resource\Exception\InvalidPathException; use TYPO3\CMS\Core\TimeTracker\TimeTracker; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Resource\FilePathSanitizer; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; class IncludeFileViewHelper extends AbstractViewHelper { + public function __construct( + private readonly PageRenderer $pageRenderer, + private readonly TimeTracker $timeTracker, + private readonly FilePathSanitizer $filePathSanitizer, + ) {} + public function initializeArguments(): void { parent::initializeArguments(); @@ -48,16 +55,16 @@ public function render(): void $path = $this->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) { $path = null; if ($GLOBALS['TSFE']->tmpl->tt_track) { - GeneralUtility::makeInstance(TimeTracker::class)->setTSlogMessage($e->getMessage(), 3); + $this->timeTracker->setTSlogMessage($e->getMessage(), LogLevel::ERROR); } } } diff --git a/Classes/ViewHelpers/MetaTagViewHelper.php b/Classes/ViewHelpers/MetaTagViewHelper.php index 01c91e6e..690362a3 100644 --- a/Classes/ViewHelpers/MetaTagViewHelper.php +++ b/Classes/ViewHelpers/MetaTagViewHelper.php @@ -10,7 +10,6 @@ */ use TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; /** @@ -27,6 +26,7 @@ class MetaTagViewHelper extends AbstractViewHelper { protected string $tagName = 'meta'; + public function __construct(private readonly MetaTagManagerRegistry $metaTagManagerRegistry) {} public function initializeArguments(): void { @@ -46,7 +46,7 @@ public function initializeArguments(): void public function render(): void { - $metaTagManager = GeneralUtility::makeInstance(MetaTagManagerRegistry::class) + $metaTagManager = $this->metaTagManagerRegistry ->getManagerForProperty($this->arguments['property']); $metaTagManager->addProperty( $this->arguments['property'], diff --git a/Classes/ViewHelpers/TitleTagViewHelper.php b/Classes/ViewHelpers/TitleTagViewHelper.php index a4f56815..4e801b4f 100644 --- a/Classes/ViewHelpers/TitleTagViewHelper.php +++ b/Classes/ViewHelpers/TitleTagViewHelper.php @@ -12,32 +12,33 @@ 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..6713a2be 100644 --- a/Classes/ViewHelpers/Traversable/ExtractViewHelper.php +++ b/Classes/ViewHelpers/Traversable/ExtractViewHelper.php @@ -25,7 +25,7 @@ public function initializeArguments(): void ); $this->registerArgument( 'content', - \Traversable::class, + 'array', 'Content', false ); diff --git a/Classes/Widgets/PaymentPaidShippingOpen.php b/Classes/Widgets/PaymentPaidShippingOpen.php index 81990dc1..5821795e 100644 --- a/Classes/Widgets/PaymentPaidShippingOpen.php +++ b/Classes/Widgets/PaymentPaidShippingOpen.php @@ -17,12 +17,11 @@ 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 { private ServerRequestInterface $request; - private StandaloneView|ViewInterface $view; + private ViewInterface $view; public function __construct( private readonly WidgetConfigurationInterface $configuration, diff --git a/Classes/Widgets/Provider/OrdersPerDayProvider.php b/Classes/Widgets/Provider/OrdersPerDayProvider.php index d810e81f..553277b9 100644 --- a/Classes/Widgets/Provider/OrdersPerDayProvider.php +++ b/Classes/Widgets/Provider/OrdersPerDayProvider.php @@ -113,11 +113,8 @@ public function getOrderItemsInPeriod(int $start, int $end): int $this->queryBuilder ->count('*') - ->from('tx_cart_domain_model_order_item'); - - if ($constraints !== []) { - $this->queryBuilder->where(... $constraints); - } + ->from('tx_cart_domain_model_order_item') + ->where(... $constraints); return $this->queryBuilder->executeQuery()->fetchOne(); } diff --git a/Classes/Widgets/Provider/TurnoverPerDayProvider.php b/Classes/Widgets/Provider/TurnoverPerDayProvider.php index 9b69ae34..86ee2d9c 100644 --- a/Classes/Widgets/Provider/TurnoverPerDayProvider.php +++ b/Classes/Widgets/Provider/TurnoverPerDayProvider.php @@ -95,11 +95,8 @@ public function getOrderItemsInPeriod(int $start, int $end): float ->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); - } + ->from('tx_cart_domain_model_order_item') + ->where(... $constraints); return $this->queryBuilder->executeQuery()->fetchOne() ?? 0; } diff --git a/Configuration/Icons.php b/Configuration/Icons.php index 5a0afe74..47ff99a3 100644 --- a/Configuration/Icons.php +++ b/Configuration/Icons.php @@ -1,28 +1,30 @@ [ - '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/Services.php b/Configuration/Services.php index 7579a4ec..054fd57d 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')) { + if ($containerBuilder->hasDefinition(BarChartWidget::class)) { $containerConfigurator->import('Backend/Provider/PaymentPaidShippingOpenProvider.php'); $containerConfigurator->import('Backend/Widgets/PaymentPaidShippingOpenWidget.php'); @@ -20,12 +24,12 @@ } 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') + $services->set(ItemsProcFunc::class) ->public(); } diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index d191504d..6d70cc95 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -2,7 +2,6 @@ defined('TYPO3') or die(); -use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; @@ -27,28 +26,21 @@ foreach ($pluginNames as $pluginName => $pluginConfig) { $pluginSignature = 'cart_' . 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/Tests/Functional/Command/OrderItemCleanupCommandTest.php b/Tests/Functional/Command/OrderItemCleanupCommandTest.php index d6c95fcd..25ea83a9 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', ], ], ]); diff --git a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php index 2f971431..1a6a277d 100644 --- a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php +++ b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php @@ -80,7 +80,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/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/Domain/Model/Cart/BeVariantTest.php b/Tests/Unit/Domain/Model/Cart/BeVariantTest.php index b1a267e3..1844a1c9 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 { @@ -440,53 +392,4 @@ public function getParentPriceRespectsTheQuantityDiscountsOfProductsForEachVaria // $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..770ece7a 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php @@ -1,5 +1,7 @@ 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 { diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php index 1c5dfea7..6adee706 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php @@ -1,5 +1,7 @@ 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 { diff --git a/Tests/Unit/Domain/Model/Cart/CartTest.php b/Tests/Unit/Domain/Model/Cart/CartTest.php index eccb7fdd..a3213ad9 100644 --- a/Tests/Unit/Domain/Model/Cart/CartTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartTest.php @@ -1,5 +1,7 @@ grossCart); - unset($this->netCart); - - unset($this->taxClasses); - - unset($this->normalTaxClass); - unset($this->reducedTaxClass); - unset($this->freeTaxClass); - parent::tearDown(); } diff --git a/Tests/Unit/Domain/Model/Cart/ProductTest.php b/Tests/Unit/Domain/Model/Cart/ProductTest.php index c8edf292..e0d95879 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..ff5a9607 100644 --- a/Tests/Unit/Domain/Model/Cart/ServiceTest.php +++ b/Tests/Unit/Domain/Model/Cart/ServiceTest.php @@ -1,5 +1,7 @@ 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..c94fa3c5 100644 --- a/Tests/Unit/Domain/Model/CouponTest.php +++ b/Tests/Unit/Domain/Model/CouponTest.php @@ -1,5 +1,7 @@ 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..63954d97 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..59a984a1 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(); } diff --git a/Tests/Unit/Domain/Model/Order/DiscountTest.php b/Tests/Unit/Domain/Model/Order/DiscountTest.php index 0df8791f..b9a44c22 100644 --- a/Tests/Unit/Domain/Model/Order/DiscountTest.php +++ b/Tests/Unit/Domain/Model/Order/DiscountTest.php @@ -1,5 +1,7 @@ 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..09224dae 100644 --- a/Tests/Unit/Domain/Model/Order/ItemTest.php +++ b/Tests/Unit/Domain/Model/Order/ItemTest.php @@ -1,5 +1,7 @@ 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..2f2e2b53 100644 --- a/Tests/Unit/Domain/Model/Order/ProductTest.php +++ b/Tests/Unit/Domain/Model/Order/ProductTest.php @@ -1,5 +1,7 @@ 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..789c3c38 100644 --- a/Tests/Unit/Domain/Model/Order/TransactionTest.php +++ b/Tests/Unit/Domain/Model/Order/TransactionTest.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] 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..1ce579dd 100644 --- a/Tests/Unit/Domain/Model/TagTest.php +++ b/Tests/Unit/Domain/Model/TagTest.php @@ -1,5 +1,7 @@ expectException(\TypeError::class); - - $this->tag = new Tag( - null - ); - } - #[Test] public function getTitleInitiallyReturnsTitleSetDirectlyByConstructor(): void { diff --git a/Tests/Unit/Service/TaxClassServiceTest.php b/Tests/Unit/Service/TaxClassServiceTest.php index 80996f99..c99c82fe 100644 --- a/Tests/Unit/Service/TaxClassServiceTest.php +++ b/Tests/Unit/Service/TaxClassServiceTest.php @@ -48,16 +48,14 @@ public function parsingTaxClassesFromTypoScriptWithoutCountryCodeReturnsDirectly $taxClasses = $this->createSubject($settings)->getTaxClasses($countryCode); - self::assertIsArray( - $taxClasses - ); - self::assertEquals( 3, count($taxClasses) ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses @@ -115,16 +113,14 @@ public function parsingTaxClassesFromTypoScriptWithCountryCodeReturnsCountrySpec $taxClasses = $this->createSubject($settings)->getTaxClasses($countryCode); - self::assertIsArray( - $taxClasses - ); - self::assertEquals( 3, count($taxClasses) ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses @@ -199,16 +195,14 @@ public function parsingTaxClassesFromTypoScriptWithNotConfiguredCountryCodeRetur $taxClasses = $this->createSubject($settings)->getTaxClasses($countryCode); - self::assertIsArray( - $taxClasses - ); - self::assertEquals( 3, count($taxClasses) ); $firstTaxClasses = $taxClasses[1]; + + // @phpstan-ignore-next-line staticMethod.alreadyNarrowedType self::assertInstanceOf( TaxClass::class, $firstTaxClasses diff --git a/Tests/Unit/Validation/Validator/EmptyValidatorTest.php b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php index 5ced1c1a..148372ea 100644 --- a/Tests/Unit/Validation/Validator/EmptyValidatorTest.php +++ b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php @@ -9,12 +9,14 @@ * LICENSE file that was distributed with this source code. */ use Extcode\Cart\Validation\Validator\EmptyValidator; +use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; +#[AllowMockObjectsWithoutExpectations] #[CoversClass(EmptyValidator::class)] class EmptyValidatorTest extends UnitTestCase { diff --git a/composer.json b/composer.json index 6e30a450..c493dee0 100644 --- a/composer.json +++ b/composer.json @@ -38,9 +38,11 @@ "allow-plugins": { "typo3/class-alias-loader": true, "typo3/cms-composer-installers": true, - "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": true + "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": true, + "phpstan/extension-installer": true } }, + "version": "12.0.0", "extra": { "typo3/cms": { "extension-key": "cart", @@ -51,19 +53,26 @@ "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.0", + "typo3/cms-extbase": "^14.0", + "typo3/cms-fluid": "^14.0", + "typo3/cms-form": "^14.0", + "typo3/cms-frontend": "^14.0" }, "require-dev": { - "codappix/typo3-php-datasets": "^2.0", + "codappix/typo3-php-datasets": "^2.1", "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" + "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.0", + "typo3/cms-dashboard": "^14.0", + "typo3/cms-form": "^14.0", + "typo3/testing-framework": "^9.0", + "ssch/typo3-rector": "^3.11" }, "scripts": { "test:cgl": [ @@ -79,7 +88,7 @@ ".build/bin/phpunit -c Build/UnitTests.xml" ], "test:php:functional": [ - "typo3DatabaseDriver=\"pdo_sqlite\" .build/bin/phpunit -c Build/FunctionalTests.xml" + "typo3DatabaseDriver=\"pdo_sqlite\" .build/bin/phpunit -c Build/phpunit.xml.dist" ], "test:phpstan:analyse": [ ".build/bin/phpstan analyse -c Build/phpstan.neon --memory-limit 256M" @@ -107,7 +116,7 @@ ] }, "suggest": { - "typo3/cms-dashboard": "^13.4", - "typo3/cms-form": "^13.4" + "typo3/cms-dashboard": "^14.0", + "typo3/cms-form": "^14.0" } } diff --git a/ext_emconf.php b/ext_emconf.php index a71cd715..4169be74 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -11,7 +11,7 @@ 'author_company' => 'extco.de UG (haftungsbeschränkt)', 'constraints' => [ 'depends' => [ - 'php' => '8.2.0-8.5.99', + 'php' => '8.2.0-8.4.99', 'typo3' => '13.4.0-13.4.99', 'extbase' => '13.4.0-13.4.99', 'fluid' => '13.4.0-13.4.99', diff --git a/ext_localconf.php b/ext_localconf.php index 24086288..3d5add58 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -25,8 +25,7 @@ [ CartPreviewController::class => 'show', CurrencyController::class => 'update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT + ] ); ExtensionUtility::configurePlugin( @@ -51,8 +50,7 @@ PaymentController::class => 'update', ProductController::class => 'add, remove', ShippingController::class => 'update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT + ] ); ExtensionUtility::configurePlugin( @@ -63,8 +61,7 @@ ], [ CurrencyController::class => 'edit, update', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT + ] ); ExtensionUtility::configurePlugin( @@ -75,8 +72,7 @@ ], [ \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', - ], - ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT + ] ); // register "cart:" namespace diff --git a/rector.php b/rector.php index 2c72b1d6..22291b6b 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; @@ -29,7 +28,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 +36,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..f321ebf8 100644 --- a/shell.nix +++ b/shell.nix @@ -83,7 +83,7 @@ let ]; text = '' project-install - .build/bin/phpunit -c Build/UnitTests.xml --display-deprecations --display-warnings + .build/bin/phpunit -c Build/phpunit.xml.dist --testsuite unit --display-warnings --display-deprecations --display-errors --display-notices ''; }; @@ -95,7 +95,7 @@ let ]; text = '' project-install - .build/bin/phpunit -c Build/FunctionalTests.xml --display-deprecations --display-warnings + .build/bin/phpunit -c Build/phpunit.xml.dist --testsuite functional --display-warnings --display-deprecations --display-errors ''; }; From f8047bd721567b45e90adf662f6c1d419e6be0e4 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 25 Mar 2026 14:39:41 +0100 Subject: [PATCH 02/14] [BUGFIX] Remove searchField and fix some issues --- Build/phpstan-baseline.neon | 68 +++++-------------- Classes/Domain/Model/Cart/Cart.php | 5 ++ Classes/Domain/Model/Cart/FeVariant.php | 12 +++- .../Domain/Model/Order/AbstractService.php | 4 +- .../Domain/Validator/OrderItemValidator.php | 6 +- Classes/EventListener/Order/Create/Number.php | 7 +- Classes/Service/OrderItemCleanupService.php | 2 +- Classes/Service/TaxClassService.php | 5 +- .../IsServiceAvailableAtPriceViewHelper.php | 10 +-- ...odelPropertiesToTableColumnsViewHelper.php | 7 +- .../TCA/tx_cart_domain_model_cart.php | 1 - .../TCA/tx_cart_domain_model_coupon.php | 1 - .../tx_cart_domain_model_order_address.php | 1 - .../tx_cart_domain_model_order_discount.php | 1 - .../TCA/tx_cart_domain_model_order_item.php | 1 - .../tx_cart_domain_model_order_payment.php | 1 - .../tx_cart_domain_model_order_product.php | 1 - ...t_domain_model_order_productadditional.php | 1 - .../tx_cart_domain_model_order_shipping.php | 1 - .../TCA/tx_cart_domain_model_order_tax.php | 1 - .../tx_cart_domain_model_order_taxclass.php | 1 - ...tx_cart_domain_model_order_transaction.php | 1 - .../TCA/tx_cart_domain_model_tag.php | 1 - .../Domain/Model/Cart/CartCouponFixTest.php | 4 +- .../Model/Cart/CartCouponPercentageTest.php | 4 +- Tests/Unit/Domain/Model/Cart/CartTest.php | 2 - Tests/Unit/Domain/Model/Cart/ServiceTest.php | 4 +- Tests/Unit/Domain/Model/Order/PaymentTest.php | 1 + .../Validator/EmptyValidatorTest.php | 2 - 29 files changed, 55 insertions(+), 101 deletions(-) diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index 1878ea93..33bdcc8a 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -1707,7 +1707,7 @@ parameters: - message: '#^Cannot cast mixed to float\.$#' identifier: cast.double - count: 9 + count: 7 path: ../Classes/Domain/Model/Cart/Service.php - @@ -3834,6 +3834,12 @@ parameters: 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: '#^Method Extcode\\Cart\\Service\\PaymentMethodsFromTypoScriptService\:\:getPaymentMethods\(\) should return array\ but returns array\.$#' identifier: return.type @@ -3888,12 +3894,6 @@ parameters: count: 1 path: ../Classes/Service/TaxClassService.php - - - message: '#^Parameter \#1 \$key of function array_key_exists expects int\|string, string\|null given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/Service/TaxClassService.php - - message: '#^Parameter \#1 \$taxClassKey of method Extcode\\Cart\\Domain\\Model\\Cart\\TaxClassFactoryInterface\:\:getTaxClass\(\) expects int, mixed given\.$#' identifier: argument.type @@ -4350,24 +4350,6 @@ parameters: count: 1 path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php - - - message: '#^Method Extcode\\Cart\\ViewHelpers\\Form\\IsServiceAvailableAtPriceViewHelper\:\:evaluateCondition\(\) has parameter \$arguments with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php - - - - message: '#^Offset ''price'' might not exist on array\|null\.$#' - identifier: offsetAccess.notFound - count: 1 - path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php - - - - message: '#^Offset ''service'' might not exist on array\|null\.$#' - identifier: offsetAccess.notFound - count: 1 - path: ../Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php - - message: '#^Binary operation "\." between mixed and ''''\|'' '' results in an error\.$#' identifier: binaryOp.invalid @@ -4524,12 +4506,6 @@ parameters: count: 1 path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php - - - message: '#^Method Extcode\\Cart\\ViewHelpers\\MapModelPropertiesToTableColumnsViewHelper\:\:render\(\) should return array\ but returns array\.$#' - identifier: return.type - count: 1 - path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php - - message: '#^Method Extcode\\Cart\\ViewHelpers\\MapModelPropertiesToTableColumnsViewHelper\:\:render\(\) should return array\ but returns mixed\.$#' identifier: return.type @@ -4542,12 +4518,6 @@ parameters: count: 1 path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php - - - message: '#^Possibly invalid array key type mixed\.$#' - identifier: offsetAccess.invalidOffset - count: 2 - path: ../Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php - - message: '#^Parameter \#1 \$property of method TYPO3\\CMS\\Core\\MetaTag\\MetaTagManagerInterface\:\:addProperty\(\) expects string, mixed given\.$#' identifier: argument.type @@ -5058,12 +5028,6 @@ parameters: count: 4 path: ../Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php - - - message: '#^Parameter \#1 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' - identifier: argument.type - count: 1 - 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 @@ -5083,10 +5047,16 @@ parameters: path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php - - message: '#^Parameter \#1 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' + message: '#^Parameter \#1 \$array of function array_diff_assoc expects an array of values castable to string, array given\.$#' identifier: argument.type - count: 1 - path: ../Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php + 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\.$#' @@ -5118,12 +5088,6 @@ parameters: count: 14 path: ../Tests/Unit/Domain/Model/Cart/ServiceTest.php - - - message: '#^Parameter \#1 \$methods of method PHPUnit\\Framework\\MockObject\\TestDoubleBuilder\:\:onlyMethods\(\) expects list\, array given\.$#' - identifier: argument.type - count: 1 - 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 diff --git a/Classes/Domain/Model/Cart/Cart.php b/Classes/Domain/Model/Cart/Cart.php index 2b71d3d6..a720cc8a 100644 --- a/Classes/Domain/Model/Cart/Cart.php +++ b/Classes/Domain/Model/Cart/Cart.php @@ -12,6 +12,7 @@ */ use Extcode\Cart\Service\CurrencyTranslationServiceInterface; +use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; class Cart implements AdditionalDataInterface @@ -763,6 +764,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; } diff --git a/Classes/Domain/Model/Cart/FeVariant.php b/Classes/Domain/Model/Cart/FeVariant.php index bc202f2d..265b72b3 100644 --- a/Classes/Domain/Model/Cart/FeVariant.php +++ b/Classes/Domain/Model/Cart/FeVariant.php @@ -51,7 +51,9 @@ 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,7 +62,9 @@ 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,7 +73,9 @@ 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/Order/AbstractService.php b/Classes/Domain/Model/Order/AbstractService.php index 52afb128..b5920d6f 100644 --- a/Classes/Domain/Model/Order/AbstractService.php +++ b/Classes/Domain/Model/Order/AbstractService.php @@ -24,7 +24,7 @@ abstract class AbstractService extends AbstractEntity protected string $serviceCountry = ''; #[Validate(['validator' => 'NotEmpty'])] - protected ?int $serviceId = null; + protected int $serviceId; #[Validate(['validator' => 'NotEmpty'])] protected string $name = ''; @@ -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/Validator/OrderItemValidator.php b/Classes/Domain/Validator/OrderItemValidator.php index c57d9df3..ff5d147c 100644 --- a/Classes/Domain/Validator/OrderItemValidator.php +++ b/Classes/Domain/Validator/OrderItemValidator.php @@ -127,7 +127,7 @@ public function addPropertyValidator(string $propertyName, ValidatorInterface $v if (!isset($this->propertyValidators[$propertyName])) { $this->propertyValidators[$propertyName] = new \SplObjectStorage(); } - $this->propertyValidators[$propertyName]->attach($validator); + $this->propertyValidators[$propertyName]->offsetSet($validator); } protected function isValidatedAlready(object $object): bool @@ -135,11 +135,11 @@ protected function isValidatedAlready(object $object): bool if ($this->validatedInstancesContainer === null) { $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; } diff --git a/Classes/EventListener/Order/Create/Number.php b/Classes/EventListener/Order/Create/Number.php index 0d4a7cb2..68f90e22 100644 --- a/Classes/EventListener/Order/Create/Number.php +++ b/Classes/EventListener/Order/Create/Number.php @@ -35,11 +35,12 @@ protected function generateNumber(NumberGeneratorEventInterface $event): string $format = $this->options['format'] ?? '%d'; $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/Service/OrderItemCleanupService.php b/Classes/Service/OrderItemCleanupService.php index e6e95059..8b23654e 100644 --- a/Classes/Service/OrderItemCleanupService.php +++ b/Classes/Service/OrderItemCleanupService.php @@ -74,7 +74,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/TaxClassService.php b/Classes/Service/TaxClassService.php index 65ff9000..8fdfb3b9 100644 --- a/Classes/Service/TaxClassService.php +++ b/Classes/Service/TaxClassService.php @@ -39,8 +39,9 @@ public function getTaxClasses(?string $countryCode = null): array $taxClassSettings = $this->settings['taxClasses']; if ( - 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/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php b/Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php index 9dab71d4..df30c140 100644 --- a/Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php +++ b/Classes/ViewHelpers/Form/IsServiceAvailableAtPriceViewHelper.php @@ -14,8 +14,8 @@ * * The TYPO3 project - inspiring people to share! */ - use Extcode\Cart\Domain\Model\Cart\ServiceInterface; +use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper; /** @@ -26,6 +26,7 @@ class IsServiceAvailableAtPriceViewHelper extends AbstractConditionViewHelper public function initializeArguments(): void { parent::initializeArguments(); + $this->registerArgument( 'service', ServiceInterface::class, @@ -38,12 +39,7 @@ 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']; diff --git a/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php b/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php index 744a5877..ae2de97a 100644 --- a/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php +++ b/Classes/ViewHelpers/MapModelPropertiesToTableColumnsViewHelper.php @@ -67,15 +67,18 @@ public function render(): array $mapping = []; foreach ($this->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; } } diff --git a/Configuration/TCA/tx_cart_domain_model_cart.php b/Configuration/TCA/tx_cart_domain_model_cart.php index 244445fd..bd73bbd5 100644 --- a/Configuration/TCA/tx_cart_domain_model_cart.php +++ b/Configuration/TCA/tx_cart_domain_model_cart.php @@ -17,7 +17,6 @@ 'hideTable' => true, 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => '', ], 'types' => [ '1' => [ diff --git a/Configuration/TCA/tx_cart_domain_model_coupon.php b/Configuration/TCA/tx_cart_domain_model_coupon.php index 5f01fa5a..7dc50d09 100644 --- a/Configuration/TCA/tx_cart_domain_model_coupon.php +++ b/Configuration/TCA/tx_cart_domain_model_coupon.php @@ -24,7 +24,6 @@ 'starttime' => '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..069e5389 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_address.php +++ b/Configuration/TCA/tx_cart_domain_model_order_address.php @@ -22,7 +22,6 @@ 'hideTable' => 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..16ba3f19 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_discount.php +++ b/Configuration/TCA/tx_cart_domain_model_order_discount.php @@ -18,7 +18,6 @@ 'hideTable' => 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..22d76f24 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_item.php +++ b/Configuration/TCA/tx_cart_domain_model_order_item.php @@ -20,7 +20,6 @@ 'origUid' => 't3_origuid', 'delete' => 'deleted', 'enablecolumns' => [], - 'searchFields' => 'order_number, invoice_number', 'iconfile' => 'EXT:cart/Resources/Public/Icons/Order/Item.svg', ], 'types' => [ diff --git a/Configuration/TCA/tx_cart_domain_model_order_payment.php b/Configuration/TCA/tx_cart_domain_model_order_payment.php index e8e0e091..ab145474 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_payment.php +++ b/Configuration/TCA/tx_cart_domain_model_order_payment.php @@ -16,7 +16,6 @@ 'hideTable' => 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..66995ff8 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_product.php +++ b/Configuration/TCA/tx_cart_domain_model_order_product.php @@ -18,7 +18,6 @@ 'hideTable' => 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..8c4ea1d3 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_productadditional.php +++ b/Configuration/TCA/tx_cart_domain_model_order_productadditional.php @@ -18,7 +18,6 @@ 'hideTable' => 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..e9b74428 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_shipping.php +++ b/Configuration/TCA/tx_cart_domain_model_order_shipping.php @@ -16,7 +16,6 @@ 'hideTable' => 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..c0b19f50 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_tax.php +++ b/Configuration/TCA/tx_cart_domain_model_order_tax.php @@ -16,7 +16,6 @@ 'hideTable' => 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..e6ffd836 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_taxclass.php +++ b/Configuration/TCA/tx_cart_domain_model_order_taxclass.php @@ -16,7 +16,6 @@ 'hideTable' => 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..4163b058 100644 --- a/Configuration/TCA/tx_cart_domain_model_order_transaction.php +++ b/Configuration/TCA/tx_cart_domain_model_order_transaction.php @@ -16,7 +16,6 @@ 'hideTable' => 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..a728ca3c 100644 --- a/Configuration/TCA/tx_cart_domain_model_tag.php +++ b/Configuration/TCA/tx_cart_domain_model_tag.php @@ -22,7 +22,6 @@ 'starttime' => 'starttime', 'endtime' => 'endtime', ], - 'searchFields' => 'title', 'iconfile' => 'EXT:cart/Resources/Public/Icons/tx_cart_domain_model_tag.svg', ], 'hideTable' => 1, diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php index 770ece7a..368eb21e 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php @@ -16,14 +16,12 @@ use Extcode\Cart\Domain\Model\Cart\TaxClass; use Extcode\Cart\Service\CurrencyTranslationService; use Extcode\Cart\Service\CurrencyTranslationServiceInterface; -use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -#[AllowMockObjectsWithoutExpectations] #[CoversClass(CartCouponFix::class)] class CartCouponFixTest extends UnitTestCase { @@ -247,7 +245,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) ->setConstructorArgs([[$this->taxClass]]) ->getMock(); } diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php index 6adee706..d54041cd 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php @@ -16,14 +16,12 @@ use Extcode\Cart\Domain\Model\Cart\TaxClass; use Extcode\Cart\Service\CurrencyTranslationService; use Extcode\Cart\Service\CurrencyTranslationServiceInterface; -use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -#[AllowMockObjectsWithoutExpectations] #[CoversClass(CartCouponPercentage::class)] class CartCouponPercentageTest extends UnitTestCase { @@ -277,7 +275,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) ->setConstructorArgs([[$this->taxClass]]) ->getMock(); } diff --git a/Tests/Unit/Domain/Model/Cart/CartTest.php b/Tests/Unit/Domain/Model/Cart/CartTest.php index a3213ad9..fbf41ecf 100644 --- a/Tests/Unit/Domain/Model/Cart/CartTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartTest.php @@ -18,13 +18,11 @@ use Extcode\Cart\Domain\Model\Cart\TaxClass; use Extcode\Cart\Service\CurrencyTranslationService; use Extcode\Cart\Service\CurrencyTranslationServiceInterface; -use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -#[AllowMockObjectsWithoutExpectations] #[CoversClass(Cart::class)] class CartTest extends UnitTestCase { diff --git a/Tests/Unit/Domain/Model/Cart/ServiceTest.php b/Tests/Unit/Domain/Model/Cart/ServiceTest.php index ff5a9607..3b0a6b6a 100644 --- a/Tests/Unit/Domain/Model/Cart/ServiceTest.php +++ b/Tests/Unit/Domain/Model/Cart/ServiceTest.php @@ -17,14 +17,12 @@ use Extcode\Cart\Domain\Model\Cart\TaxClass; use Extcode\Cart\Service\CurrencyTranslationService; use Extcode\Cart\Service\CurrencyTranslationServiceInterface; -use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -#[AllowMockObjectsWithoutExpectations] #[CoversClass(Service::class)] class ServiceTest extends UnitTestCase { @@ -477,7 +475,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods($methods) + ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) ->setConstructorArgs([$this->taxClasses]) ->getMock(); } diff --git a/Tests/Unit/Domain/Model/Order/PaymentTest.php b/Tests/Unit/Domain/Model/Order/PaymentTest.php index f20c83ac..d22c010c 100644 --- a/Tests/Unit/Domain/Model/Order/PaymentTest.php +++ b/Tests/Unit/Domain/Model/Order/PaymentTest.php @@ -35,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/Validation/Validator/EmptyValidatorTest.php b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php index 148372ea..5ced1c1a 100644 --- a/Tests/Unit/Validation/Validator/EmptyValidatorTest.php +++ b/Tests/Unit/Validation/Validator/EmptyValidatorTest.php @@ -9,14 +9,12 @@ * LICENSE file that was distributed with this source code. */ use Extcode\Cart\Validation\Validator\EmptyValidator; -use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -#[AllowMockObjectsWithoutExpectations] #[CoversClass(EmptyValidator::class)] class EmptyValidatorTest extends UnitTestCase { From b9aef5f8528c14b886de8034abf95dfaa9b64a10 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 25 Mar 2026 19:52:45 +0100 Subject: [PATCH 03/14] [BUGFIX] Extbase DataMapFactory cannot handle Interfaces for properties --- Build/phpstan-baseline.neon | 48 ------------------ Classes/Controller/Cart/OrderController.php | 50 +++++++++++++++---- .../Domain/Model/Order/AbstractAddress.php | 2 +- .../Domain/Model/Order/AbstractService.php | 12 ++--- Classes/Domain/Model/Order/Discount.php | 16 +++--- Classes/Domain/Model/Order/Item.php | 14 +++--- Classes/Domain/Model/Order/Payment.php | 2 +- Classes/Domain/Model/Order/Product.php | 22 ++++---- Classes/Domain/Model/Order/Tax.php | 6 +-- Classes/Domain/Model/Order/TaxClass.php | 8 +-- .../Domain/Model/Product/AbstractProduct.php | 6 +-- Classes/Event/Order/PersistOrderEvent.php | 11 ++-- Classes/Service/MailHandler.php | 10 +++- 13 files changed, 99 insertions(+), 108 deletions(-) diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index 33bdcc8a..d12d4fb6 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -3018,12 +3018,6 @@ parameters: count: 1 path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php - - - message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/EventListener/Order/Create/PersistOrder/Coupons.php - - message: '#^Cannot access offset ''currency'' on mixed\.$#' identifier: offsetAccess.nonOffsetAccessible @@ -3054,18 +3048,6 @@ parameters: count: 1 path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php - - - message: '#^Parameter \#1 \$object of method TYPO3\\CMS\\Extbase\\Persistence\\Repository\\:\:add\(\) expects TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface, Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface given\.$#' - identifier: argument.type - count: 2 - path: ../Classes/EventListener/Order/Create/PersistOrder/Item.php - - - - message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int 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 @@ -3126,12 +3108,6 @@ parameters: count: 2 path: ../Classes/EventListener/Order/Create/PersistOrder/Payment.php - - - message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' - identifier: argument.type - count: 1 - 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 @@ -3252,30 +3228,12 @@ parameters: count: 1 path: ../Classes/EventListener/Order/Create/PersistOrder/Shipping.php - - - message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int 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: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/EventListener/Order/Create/PersistOrder/TaxClasses.php - - - - message: '#^Parameter \#1 \$pid of method TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject\:\:setPid\(\) expects int\<0, max\>, int given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/EventListener/Order/Create/PersistOrder/Taxes.php - - message: '#^Binary operation "\." between ''billing_address_'' and mixed results in an error\.$#' identifier: binaryOp.invalid @@ -3744,12 +3702,6 @@ parameters: count: 1 path: ../Classes/Service/MailHandler.php - - - message: '#^Cannot call method getEmail\(\) on Extcode\\Cart\\Domain\\Model\\Order\\AddressInterface\|null\.$#' - identifier: method.nonObject - count: 4 - path: ../Classes/Service/MailHandler.php - - message: '#^Cannot call method getStatus\(\) on Extcode\\Cart\\Domain\\Model\\Order\\Payment\|null\.$#' identifier: method.nonObject diff --git a/Classes/Controller/Cart/OrderController.php b/Classes/Controller/Cart/OrderController.php index 7828dc52..d09b272d 100644 --- a/Classes/Controller/Cart/OrderController.php +++ b/Classes/Controller/Cart/OrderController.php @@ -11,7 +11,7 @@ * 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\Domain\Validator\OrderItemValidator; @@ -56,26 +56,32 @@ public function initializeCreateAction(): void #[IgnoreValidation(['value' => 'shippingAddress'])] public function createAction( ?Item $orderItem = null, - ?AddressInterface $billingAddress = null, - ?AddressInterface $shippingAddress = null + ?BillingAddress $billingAddress = null, + ?ShippingAddress $shippingAddress = null ): 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'); } @@ -93,10 +99,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); @@ -104,6 +110,9 @@ public function createAction( $shippingAddress = null; $orderItem->removeShippingAddress(); } else { + if (($shippingAddress instanceof ShippingAddress) === false) { + $shippingAddress = new ShippingAddress(); + } $shippingAddress->setPid($storagePid); $orderItem->setShippingAddress($shippingAddress); } @@ -244,4 +253,23 @@ protected function dispatchOrderCreateEvents(Item $orderItem): bool return false; } + + /** + * @return int<0,max> + */ + private function getOrderPidFromSettings(): int + { + $orderPid = (int)($this->settings['order']['pid'] ?? 0); + + if ($orderPid < 0) { + $orderPid = 0; + } + + return $orderPid; + } + + private function getCartPidFromSettings(): int + { + return (int)$this->settings['cart']['pid']; + } } diff --git a/Classes/Domain/Model/Order/AbstractAddress.php b/Classes/Domain/Model/Order/AbstractAddress.php index 75dc3c22..2186dd33 100755 --- a/Classes/Domain/Model/Order/AbstractAddress.php +++ b/Classes/Domain/Model/Order/AbstractAddress.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\DomainObject\AbstractEntity; use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy; diff --git a/Classes/Domain/Model/Order/AbstractService.php b/Classes/Domain/Model/Order/AbstractService.php index b5920d6f..592946e9 100644 --- a/Classes/Domain/Model/Order/AbstractService.php +++ b/Classes/Domain/Model/Order/AbstractService.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; @@ -23,13 +23,13 @@ abstract class AbstractService extends AbstractEntity protected string $serviceCountry = ''; - #[Validate(['validator' => 'NotEmpty'])] + #[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 = ''; diff --git a/Classes/Domain/Model/Order/Discount.php b/Classes/Domain/Model/Order/Discount.php index 0c08964d..d0a44e9e 100644 --- a/Classes/Domain/Model/Order/Discount.php +++ b/Classes/Domain/Model/Order/Discount.php @@ -12,8 +12,8 @@ */ use Extcode\Cart\Domain\Model\Cart\TaxClass; -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; @@ -23,17 +23,17 @@ class Discount extends AbstractEntity protected LazyLoadingProxy|Item $item; public function __construct( - #[Validate(['validator' => '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 ) {} diff --git a/Classes/Domain/Model/Order/Item.php b/Classes/Domain/Model/Order/Item.php index 7b471a86..ab935163 100644 --- a/Classes/Domain/Model/Order/Item.php +++ b/Classes/Domain/Model/Order/Item.php @@ -13,7 +13,7 @@ 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; @@ -38,9 +38,9 @@ class Item extends AbstractEntity protected bool $shippingSameAsBilling = false; - protected ?AddressInterface $billingAddress = null; + protected ?BillingAddress $billingAddress = null; - protected ?AddressInterface $shippingAddress = null; + protected ?ShippingAddress $shippingAddress = null; protected string $additionalData = ''; @@ -259,22 +259,22 @@ public function setShippingSameAsBilling(bool $shippingSameAsBilling): void $this->shippingSameAsBilling = $shippingSameAsBilling; } - public function getBillingAddress(): ?AddressInterface + public function getBillingAddress(): ?BillingAddress { return $this->billingAddress; } - public function setBillingAddress(AddressInterface $billingAddress): void + public function setBillingAddress(BillingAddress $billingAddress): void { $this->billingAddress = $billingAddress; } - public function getShippingAddress(): ?AddressInterface + public function getShippingAddress(): ?ShippingAddress { return $this->shippingAddress; } - public function setShippingAddress(AddressInterface $shippingAddress): void + public function setShippingAddress(ShippingAddress $shippingAddress): void { $this->shippingAddress = $shippingAddress; } 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..9c637bdf 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; @@ -26,31 +26,31 @@ class Product extends AbstractEntity 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 = ''; diff --git a/Classes/Domain/Model/Order/Tax.php b/Classes/Domain/Model/Order/Tax.php index 02091102..969bc8ed 100644 --- a/Classes/Domain/Model/Order/Tax.php +++ b/Classes/Domain/Model/Order/Tax.php @@ -11,15 +11,15 @@ * 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 ) {} 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/Event/Order/PersistOrderEvent.php b/Classes/Event/Order/PersistOrderEvent.php index 28b42eda..9feea164 100644 --- a/Classes/Event/Order/PersistOrderEvent.php +++ b/Classes/Event/Order/PersistOrderEvent.php @@ -47,13 +47,18 @@ public function setSettings(array $settings): void $this->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/Service/MailHandler.php b/Classes/Service/MailHandler.php index 9bd4c96a..f18a2640 100644 --- a/Classes/Service/MailHandler.php +++ b/Classes/Service/MailHandler.php @@ -10,6 +10,7 @@ */ use Extcode\Cart\Domain\Model\Cart\Cart; +use Extcode\Cart\Domain\Model\Order\AddressInterface; use Extcode\Cart\Domain\Model\Order\Item; use Extcode\Cart\Event\Mail\AttachmentEvent; use Psr\EventDispatcher\EventDispatcherInterface; @@ -292,7 +293,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; } @@ -356,7 +360,9 @@ public function sendSellerMail(Item $orderItem): void ->assign('cart', $this->cart) ->assign('orderItem', $orderItem); - if ($orderItem->getBillingAddress()->getEmail()) { + if (($orderItem->getBillingAddress() instanceof AddressInterface) + && $orderItem->getBillingAddress()->getEmail() + ) { $email->replyTo($orderItem->getBillingAddress()->getEmail()); } if ($this->getSellerEmailCc()) { From 7fe809003e08bc1f472467a6963b270de12c40f9 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 26 Mar 2026 10:05:51 +0100 Subject: [PATCH 04/14] [BUGFIX] Use correct lowercase type hint in registerArgument() --- Classes/ViewHelpers/TitleTagViewHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/ViewHelpers/TitleTagViewHelper.php b/Classes/ViewHelpers/TitleTagViewHelper.php index 4e801b4f..2b7c8e84 100644 --- a/Classes/ViewHelpers/TitleTagViewHelper.php +++ b/Classes/ViewHelpers/TitleTagViewHelper.php @@ -29,7 +29,7 @@ public function initializeArguments(): void $this->registerArgument( 'pageTitle', - 'String', + 'string', 'The page title' ); } From aec1bd8cac0eac61c0e88fd6f291d34c299c43d9 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 26 Mar 2026 10:07:51 +0100 Subject: [PATCH 05/14] [BUGFIX] Use newer cachix/install-nix-action version --- .github/workflows/ci.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 23b27d08..a38cd0b6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -89,13 +89,13 @@ jobs: matrix: include: - php-version: '8.2' - typo3-version: '^13.4' + typo3-version: '^14.1' - php-version: '8.3' - typo3-version: '^13.4' + typo3-version: '^14.1' - php-version: '8.4' - typo3-version: '^13.4' + typo3-version: '^14.1' - php-version: '8.5' - typo3-version: '^13.4' + typo3-version: '^14.1' steps: - uses: actions/checkout@v4 @@ -114,15 +114,15 @@ jobs: - name: Code Quality (by PHPStan) run: .build/bin/phpstan analyse -c Build/phpstan.neon - tests-phpunit: + tests-unit-and-functional: runs-on: ubuntu-latest needs: - coding-guideline - code-quality steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - - uses: cachix/install-nix-action@v17 + - uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixos-unstable From cf92f25cedcd62c04b7aa16b23c3cacd9de673e6 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 26 Mar 2026 10:13:07 +0100 Subject: [PATCH 06/14] [BUGFIX] Return null if array key not exists --- Classes/Domain/Model/Cart/AdditionalDataTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From fc3305dc476b1eb653df0cd012d6cdc5158f4005 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 26 Mar 2026 22:30:53 +0100 Subject: [PATCH 07/14] [BUGFIX] Remove entries from phpstan baseline after rebase --- Build/phpstan-baseline.neon | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index d12d4fb6..2e11cf9b 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -372,24 +372,6 @@ parameters: count: 4 path: ../Classes/Controller/Cart/CartController.php - - - message: '#^Parameter \#1 \$messageBody of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, mixed given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/Controller/Cart/CartController.php - - - - message: '#^Parameter \#2 \$messageTitle of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects string, mixed given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/Controller/Cart/CartController.php - - - - message: '#^Parameter \#3 \$severity of method TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController\:\:addFlashMessage\(\) expects TYPO3\\CMS\\Core\\Type\\ContextualFeedbackSeverity, mixed given\.$#' - identifier: argument.type - count: 1 - path: ../Classes/Controller/Cart/CartController.php - - message: '#^Cannot access offset ''pid'' on mixed\.$#' identifier: offsetAccess.nonOffsetAccessible From a631cd876ded33bfdaf7b6f364da12d361df01e7 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 27 Mar 2026 10:48:21 +0100 Subject: [PATCH 08/14] [TASK] Add LogInterface for orders Relates: #752 --- Build/phpstan-baseline.neon | 53 ------ Classes/Domain/Log/DatabaseWriter.php | 57 ++++++ Classes/Domain/Log/LogService.php | 27 +++ Classes/Domain/Log/LogServiceInterface.php | 12 ++ Classes/Domain/Log/Model/Log.php | 90 ++++++++++ Classes/Domain/Log/Model/LogInterface.php | 49 +++++ .../Domain/Log/Repository/LogRepository.php | 58 ++++++ Classes/Service/MailHandler.php | 64 ++++++- .../12.0/Feature-752-AddLogForOrders.rst | 21 +++ Documentation/Changelog/12.0/Index.rst | 20 +++ Documentation/Changelog/Index.rst | 1 + ext_localconf.php | 167 +++++++++++------- ext_tables.sql | 18 ++ 13 files changed, 519 insertions(+), 118 deletions(-) create mode 100644 Classes/Domain/Log/DatabaseWriter.php create mode 100644 Classes/Domain/Log/LogService.php create mode 100644 Classes/Domain/Log/LogServiceInterface.php create mode 100644 Classes/Domain/Log/Model/Log.php create mode 100644 Classes/Domain/Log/Model/LogInterface.php create mode 100644 Classes/Domain/Log/Repository/LogRepository.php create mode 100644 Documentation/Changelog/12.0/Feature-752-AddLogForOrders.rst create mode 100644 Documentation/Changelog/12.0/Index.rst diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index 2e11cf9b..d393686c 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -5472,56 +5472,3 @@ parameters: count: 1 path: ../ext_emconf.php - - - message: '#^Cannot access an offset on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''1588829280'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 2 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''MAIL'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''SYS'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''cart'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''fluid'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''namespaces'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''partialRootPaths'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php - - - - message: '#^Cannot access offset ''templateRootPaths'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_localconf.php diff --git a/Classes/Domain/Log/DatabaseWriter.php b/Classes/Domain/Log/DatabaseWriter.php new file mode 100644 index 00000000..f993928c --- /dev/null +++ b/Classes/Domain/Log/DatabaseWriter.php @@ -0,0 +1,57 @@ +getData(); + + $log = $recordData['log'] ?? null; + if (($log instanceof LogInterface) === false) { + return $this; + } + unset($recordData['log']); + + $fieldValues = [ + 'identifier' => $log->getIdentifier(), + 'logLevel' => $log->getLogLevel(), + 'arguments' => $this->jsonEncodeWithThrowable($log->getArguments()), + 'request_id' => $record->getRequestId(), + 'time_micro' => $record->getCreated(), + 'level' => $record->getLevel(), + 'message' => $record->getMessage(), + '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..7217d568 --- /dev/null +++ b/Classes/Domain/Log/LogService.php @@ -0,0 +1,27 @@ +logger->log( + $log->getLogLevel(), + $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 getIdentifier(): string + { + return $this->identifier; + } + + 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..1633ba10 --- /dev/null +++ b/Classes/Domain/Log/Model/LogInterface.php @@ -0,0 +1,49 @@ +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/Service/MailHandler.php b/Classes/Service/MailHandler.php index f18a2640..eede674f 100644 --- a/Classes/Service/MailHandler.php +++ b/Classes/Service/MailHandler.php @@ -9,6 +9,9 @@ * LICENSE file that was distributed with this source code. */ +use Exception; +use Extcode\Cart\Domain\Log\LogServiceInterface; +use Extcode\Cart\Domain\Log\Model\Log; use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Order\AddressInterface; use Extcode\Cart\Domain\Model\Order\Item; @@ -45,7 +48,8 @@ class MailHandler implements SingletonInterface public function __construct( private readonly ConfigurationManagerInterface $configurationManager, private readonly EventDispatcherInterface $eventDispatcher, - private readonly MailerInterface $mailer + private readonly MailerInterface $mailer, + private readonly LogServiceInterface $logService, ) { $this->setPluginSettings(); } @@ -332,7 +336,29 @@ public function sendBuyerMail(Item $orderItem): void $email->setRequest($GLOBALS['TYPO3_REQUEST']); } - $this->mailer->send($email); + try { + $this->mailer->send($email); + $this->logService->write( + Log::info( + (string) $orderItem->getUid(), + 'Mail was send to buyer.', + [ + 'time' => time(), + ] + ) + ); + } catch (Exception $e) { + $this->logService->write( + Log::error( + (string) $orderItem->getUid(), + 'Mail could not send to buyer.', + [ + 'time' => time(), + 'exception' => $e->__toString(), + ] + ) + ); + } } /** @@ -380,7 +406,29 @@ public function sendSellerMail(Item $orderItem): void $email->setRequest($GLOBALS['TYPO3_REQUEST']); } - $this->mailer->send($email); + try { + $this->mailer->send($email); + $this->logService->write( + Log::info( + (string) $orderItem->getUid(), + 'Mail was send to seller.', + [ + 'time' => time(), + ] + ) + ); + } catch (Exception $e) { + $this->logService->write( + Log::error( + (string) $orderItem->getUid(), + 'Mail could not send to seller.', + [ + 'time' => time(), + 'exception' => $e->__toString(), + ] + ) + ); + } } public function addAttachments(string $type, Item $orderItem, FluidEmail $email): void @@ -394,6 +442,16 @@ 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( + (string) $orderItem->getUid(), + 'Mail could add attachment ' . $attachment . ' to mail.', + [ + 'time' => time(), + ] + ) + ); } } } 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/Index.rst b/Documentation/Changelog/12.0/Index.rst new file mode 100644 index 00000000..dec9057d --- /dev/null +++ b/Documentation/Changelog/12.0/Index.rst @@ -0,0 +1,20 @@ +.. include:: ../../Includes.rst.txt + +12.0 Changes +============ + +**Table of contents** + +.. contents:: + :local: + :depth: 1 + +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/ext_localconf.php b/ext_localconf.php index 3d5add58..426e4017 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -11,73 +11,116 @@ use Extcode\Cart\Controller\Cart\PaymentController; use Extcode\Cart\Controller\Cart\ProductController; use Extcode\Cart\Controller\Cart\ShippingController; +use Extcode\Cart\Domain\Log\DatabaseWriter; +use TYPO3\CMS\Core\Log\LogLevel; +use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; -// configure plugins +(static function (string $extKey) { + if (is_array($GLOBALS['TYPO3_CONF_VARS'] ?? null) === false) { + throw new Exception('$GLOBALS[\'TYPO3_CONF_VARS\'] is not an array', 1774601240); + } -ExtensionUtility::configurePlugin( - 'Cart', - 'MiniCart', - [ - CartPreviewController::class => 'show', - CurrencyController::class => 'update', - ], - [ - CartPreviewController::class => 'show', - CurrencyController::class => 'update', - ] -); + 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', - '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', - ] -); + // configure plugins + ExtensionUtility::configurePlugin( + 'Cart', + 'MiniCart', + [ + CartPreviewController::class => 'show', + CurrencyController::class => 'update', + ], + [ + CartPreviewController::class => 'show', + CurrencyController::class => 'update', + ] + ); -ExtensionUtility::configurePlugin( - 'Cart', - 'Currency', - [ - CurrencyController::class => 'edit, update', - ], - [ - CurrencyController::class => 'edit, update', - ] -); + 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::configurePlugin( - 'Cart', - 'Order', - [ - \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', - ], - [ - \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', - ] -); + ExtensionUtility::configurePlugin( + 'Cart', + 'Currency', + [ + CurrencyController::class => 'edit, update', + ], + [ + CurrencyController::class => 'edit, update', + ] + ); -// register "cart:" namespace -$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['cart'][] = 'Extcode\\Cart\\ViewHelpers'; + ExtensionUtility::configurePlugin( + 'Cart', + 'Order', + [ + \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', + ], + [ + \Extcode\Cart\Controller\Order\OrderController::class => 'list, show', + ] + ); -// 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/'; +})('cart'); diff --git a/ext_tables.sql b/ext_tables.sql index acc70928..56aeba4f 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -269,3 +269,21 @@ CREATE TABLE tx_cart_domain_model_tag ( INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); + +# +# Table structure for table 'tx_cart_domain_model_log' +# +CREATE TABLE tx_cart_domain_model_log ( + uid int(11) NOT NULL auto_increment, + indentifier char(40) DEFAULT '' NOT NULL, + + request_id varchar(13) DEFAULT '' NOT NULL, + crdate int(11) DEFAULT '0' NOT NULL, + time_micro float DEFAULT '0' NOT NULL, + level varchar(10) DEFAULT 'info' NOT NULL, + message text, + data text, + + PRIMARY KEY (uid), +); + From ffab4a62c23e42bcd79f4b7bc777e1f8fba518b0 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 27 Mar 2026 14:02:14 +0100 Subject: [PATCH 09/14] [TASK] Add first test for logging in MailHandler Relates: #752 --- Build/phpstan-baseline.neon | 90 ++++++++++ Classes/Domain/Log/DatabaseWriter.php | 3 +- Classes/Domain/Log/Model/Log.php | 4 +- Classes/Domain/Log/Model/LogInterface.php | 6 +- .../Domain/Log/Repository/LogRepository.php | 5 +- Classes/Service/MailHandler.php | 18 +- Tests/Functional/Service/MailHandlerTest.php | 155 ++++++++++++++++++ ext_tables.sql | 36 ++-- 8 files changed, 281 insertions(+), 36 deletions(-) create mode 100644 Tests/Functional/Service/MailHandlerTest.php diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index d393686c..a93ad23f 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -1038,6 +1038,96 @@ parameters: 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 diff --git a/Classes/Domain/Log/DatabaseWriter.php b/Classes/Domain/Log/DatabaseWriter.php index f993928c..1f01a5b3 100644 --- a/Classes/Domain/Log/DatabaseWriter.php +++ b/Classes/Domain/Log/DatabaseWriter.php @@ -26,12 +26,11 @@ public function writeLog(LogRecord $record): WriterInterface $fieldValues = [ 'identifier' => $log->getIdentifier(), - 'logLevel' => $log->getLogLevel(), + 'message' => $record->getMessage(), 'arguments' => $this->jsonEncodeWithThrowable($log->getArguments()), 'request_id' => $record->getRequestId(), 'time_micro' => $record->getCreated(), 'level' => $record->getLevel(), - 'message' => $record->getMessage(), 'data' => $this->jsonEncodeWithThrowable($recordData), ]; diff --git a/Classes/Domain/Log/Model/Log.php b/Classes/Domain/Log/Model/Log.php index a1e0fd7d..042e923a 100644 --- a/Classes/Domain/Log/Model/Log.php +++ b/Classes/Domain/Log/Model/Log.php @@ -9,7 +9,7 @@ final readonly class Log implements LogInterface { public function __construct( - private LogLevel $logLevel, + private string $logLevel, private string $identifier, private string $message, private array $arguments = [], @@ -67,7 +67,7 @@ public static function error( ); } - public function getLogLevel(): LogLevel + public function getLogLevel(): string { return $this->logLevel; } diff --git a/Classes/Domain/Log/Model/LogInterface.php b/Classes/Domain/Log/Model/LogInterface.php index 1633ba10..45337bd5 100644 --- a/Classes/Domain/Log/Model/LogInterface.php +++ b/Classes/Domain/Log/Model/LogInterface.php @@ -4,12 +4,10 @@ namespace Extcode\Cart\Domain\Log\Model; -use TYPO3\CMS\Core\Log\LogLevel; - interface LogInterface { public function __construct( - LogLevel $logLevel, + string $logLevel, string $identifier, string $message, array $arguments = [], @@ -39,7 +37,7 @@ public static function error( array $arguments = [], ): self; - public function getLogLevel(): LogLevel; + public function getLogLevel(): string; public function getIdentifier(): string; diff --git a/Classes/Domain/Log/Repository/LogRepository.php b/Classes/Domain/Log/Repository/LogRepository.php index 04e11677..c0a129f8 100644 --- a/Classes/Domain/Log/Repository/LogRepository.php +++ b/Classes/Domain/Log/Repository/LogRepository.php @@ -6,16 +6,17 @@ use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; final readonly class LogRepository { - public const TABLE_NAME = 'tx_cart_domain_model_log'; + public const TABLE_NAME = 'tx_cart_domain_model_order_log'; private QueryBuilder $queryBuilder; public function __construct( - ConnectionPool $connectionPool, ) { + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); $this->queryBuilder = $connectionPool ->getQueryBuilderForTable(self::TABLE_NAME) ; diff --git a/Classes/Service/MailHandler.php b/Classes/Service/MailHandler.php index eede674f..5a58d244 100644 --- a/Classes/Service/MailHandler.php +++ b/Classes/Service/MailHandler.php @@ -314,7 +314,7 @@ 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); @@ -332,7 +332,7 @@ 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']); } @@ -340,7 +340,7 @@ public function sendBuyerMail(Item $orderItem): void $this->mailer->send($email); $this->logService->write( Log::info( - (string) $orderItem->getUid(), + (string)$orderItem->getUid(), 'Mail was send to buyer.', [ 'time' => time(), @@ -350,7 +350,7 @@ public function sendBuyerMail(Item $orderItem): void } catch (Exception $e) { $this->logService->write( Log::error( - (string) $orderItem->getUid(), + (string)$orderItem->getUid(), 'Mail could not send to buyer.', [ 'time' => time(), @@ -382,7 +382,7 @@ 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); @@ -402,7 +402,7 @@ 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']); } @@ -410,7 +410,7 @@ public function sendSellerMail(Item $orderItem): void $this->mailer->send($email); $this->logService->write( Log::info( - (string) $orderItem->getUid(), + (string)$orderItem->getUid(), 'Mail was send to seller.', [ 'time' => time(), @@ -420,7 +420,7 @@ public function sendSellerMail(Item $orderItem): void } catch (Exception $e) { $this->logService->write( Log::error( - (string) $orderItem->getUid(), + (string)$orderItem->getUid(), 'Mail could not send to seller.', [ 'time' => time(), @@ -445,7 +445,7 @@ public function addAttachments(string $type, Item $orderItem, FluidEmail $email) } else { $this->logService->write( Log::warning( - (string) $orderItem->getUid(), + (string)$orderItem->getUid(), 'Mail could add attachment ' . $attachment . ' to mail.', [ 'time' => time(), diff --git a/Tests/Functional/Service/MailHandlerTest.php b/Tests/Functional/Service/MailHandlerTest.php new file mode 100644 index 00000000..949c4f08 --- /dev/null +++ b/Tests/Functional/Service/MailHandlerTest.php @@ -0,0 +1,155 @@ +testExtensionsToLoad[] = 'extcode/cart'; + $this->testExtensionsToLoad[] = 'typo3conf/ext/cart/Tests/Fixtures/cart_example'; + + $this->configurationToUseInTestInstance = [ + 'LOG' => [ + 'Extcode' => [ + 'Cart' => [ + 'Tests' => [ + 'writerConfiguration' => [ + LogLevel::INFO => [ + DatabaseWriter::class => [], + ], + ], + ], + ], + ], + ], + ]; + + parent::setUp(); + + $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BaseDatabase.php'); + } + + #[Test] + public function logSucessAfterEmailWasSend(): void + { + $configurationManager = self::createStub(ConfigurationManagerInterface::class); + + $eventDispatcher = self::createStub(EventDispatcherInterface::class); + + $mailer = self::createStub(MailerInterface::class); + + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logService = GeneralUtility::makeInstance( + LogService::class, + $logger, + ); + + $mockBuilder = $this->getMockBuilder(MailHandler::class); + $mockBuilder->setConstructorArgs( + [ + $configurationManager, + $eventDispatcher, + $mailer, + $logService, + ] + ); + $mockBuilder->onlyMethods( + [ + 'getBuyerEmailFrom', + 'getBuyerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getBuyerEmailFrom')->willReturn('buyerEmailFrom@example.com'); + $mailHandler->method('getBuyerEmailName')->willReturn('Buyer Email Name'); + + $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); + + $mailHandler->sendBuyerMail( + $orderItem + ); + + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries + ); + self::assertIsArray($logEntries[0]); + self::assertArrayHasKey( + 'level', + $logEntries[0] + ); + self::assertSame( + 'info', + $logEntries[0]['level'] + ); + self::assertArrayHasKey( + 'identifier', + $logEntries[0] + ); + self::assertSame( + '142', + $logEntries[0]['identifier'] + ); + self::assertArrayHasKey( + 'message', + $logEntries[0] + ); + self::assertSame( + 'Mail was send to buyer.', + $logEntries[0]['message'] + ); + self::assertArrayHasKey( + 'arguments', + $logEntries[0] + ); + self::assertIsString( + $logEntries[0]['arguments'] + ); + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments + ); + self::assertArrayHasKey( + 'time', + $arguments + ); + } +} diff --git a/ext_tables.sql b/ext_tables.sql index 56aeba4f..8a32bf21 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -237,6 +237,25 @@ 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, + identifier char(40) DEFAULT '' NOT NULL, + + request_id varchar(13) DEFAULT '' NOT NULL, + crdate int(11) DEFAULT '0' NOT NULL, + time_micro float DEFAULT '0' 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' # @@ -270,20 +289,3 @@ CREATE TABLE tx_cart_domain_model_tag ( INDEX `parent` (pid), INDEX `t3ver_oid` (t3ver_oid,t3ver_wsid), ); -# -# Table structure for table 'tx_cart_domain_model_log' -# -CREATE TABLE tx_cart_domain_model_log ( - uid int(11) NOT NULL auto_increment, - indentifier char(40) DEFAULT '' NOT NULL, - - request_id varchar(13) DEFAULT '' NOT NULL, - crdate int(11) DEFAULT '0' NOT NULL, - time_micro float DEFAULT '0' NOT NULL, - level varchar(10) DEFAULT 'info' NOT NULL, - message text, - data text, - - PRIMARY KEY (uid), -); - From 9fbb76810c56428bdca094ae8359473a55c3731a Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Sat, 28 Mar 2026 19:28:52 +0100 Subject: [PATCH 10/14] [TASK] Add own LogLevel enum and more tests Relates: #752 --- .../Backend/Order/PaymentController.php | 1 + .../Backend/Order/ShippingController.php | 1 + Classes/Domain/Log/DatabaseWriter.php | 6 +- Classes/Domain/Log/LogService.php | 2 +- Classes/Domain/Log/Model/Log.php | 42 ++- Classes/Domain/Log/Model/LogInterface.php | 23 +- Classes/Domain/Log/Model/LogLevel.php | 19 ++ Classes/Service/MailHandler.php | 30 +- Tests/Functional/Service/MailHandlerTest.php | 319 +++++++++++++++--- ext_tables.sql | 4 +- 10 files changed, 370 insertions(+), 77 deletions(-) create mode 100644 Classes/Domain/Log/Model/LogLevel.php diff --git a/Classes/Controller/Backend/Order/PaymentController.php b/Classes/Controller/Backend/Order/PaymentController.php index 76dc559c..d7be1247 100644 --- a/Classes/Controller/Backend/Order/PaymentController.php +++ b/Classes/Controller/Backend/Order/PaymentController.php @@ -26,6 +26,7 @@ public function __construct( public function updateAction(Payment $payment): ResponseInterface { + // todo: add logging here $this->paymentRepository->update($payment); $event = new UpdateServiceEvent($payment); diff --git a/Classes/Controller/Backend/Order/ShippingController.php b/Classes/Controller/Backend/Order/ShippingController.php index f2cfed3e..1ad1cc58 100644 --- a/Classes/Controller/Backend/Order/ShippingController.php +++ b/Classes/Controller/Backend/Order/ShippingController.php @@ -26,6 +26,7 @@ public function __construct( public function updateAction(Shipping $shipping): ResponseInterface { + // todo: add logging here $this->shippingRepository->update($shipping); $event = new UpdateServiceEvent($shipping); diff --git a/Classes/Domain/Log/DatabaseWriter.php b/Classes/Domain/Log/DatabaseWriter.php index 1f01a5b3..2aba1e54 100644 --- a/Classes/Domain/Log/DatabaseWriter.php +++ b/Classes/Domain/Log/DatabaseWriter.php @@ -25,8 +25,10 @@ public function writeLog(LogRecord $record): WriterInterface unset($recordData['log']); $fieldValues = [ - 'identifier' => $log->getIdentifier(), - 'message' => $record->getMessage(), + '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(), diff --git a/Classes/Domain/Log/LogService.php b/Classes/Domain/Log/LogService.php index 7217d568..167c4ec5 100644 --- a/Classes/Domain/Log/LogService.php +++ b/Classes/Domain/Log/LogService.php @@ -17,7 +17,7 @@ public function write( LogInterface $log ): void { $this->logger->log( - $log->getLogLevel(), + $log->getLogLevel()->value, $log->getMessage(), [ 'log' => $log, diff --git a/Classes/Domain/Log/Model/Log.php b/Classes/Domain/Log/Model/Log.php index 042e923a..7620a5e9 100644 --- a/Classes/Domain/Log/Model/Log.php +++ b/Classes/Domain/Log/Model/Log.php @@ -4,77 +4,89 @@ namespace Extcode\Cart\Domain\Log\Model; -use TYPO3\CMS\Core\Log\LogLevel; - final readonly class Log implements LogInterface { public function __construct( - private string $logLevel, - private string $identifier, + private LogLevel $logLevel, + private int $orderItemId, + private string $type, private string $message, private array $arguments = [], ) {} public static function info( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self { return new self( LogLevel::INFO, - $identifier, + $orderItemId, + $type, $message, $arguments, ); } public static function notice( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self { return new self( LogLevel::NOTICE, - $identifier, + $orderItemId, + $type, $message, $arguments, ); } public static function warning( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self { return new self( LogLevel::WARNING, - $identifier, + $orderItemId, + $type, $message, $arguments, ); } public static function error( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self { return new self( LogLevel::ERROR, - $identifier, + $orderItemId, + $type, $message, $arguments, ); } - public function getLogLevel(): string + public function getLogLevel(): LogLevel { return $this->logLevel; } - public function getIdentifier(): string + public function getOrderItemId(): int + { + return $this->orderItemId; + } + + public function getType(): string { - return $this->identifier; + return $this->type; } public function getMessage(): string diff --git a/Classes/Domain/Log/Model/LogInterface.php b/Classes/Domain/Log/Model/LogInterface.php index 45337bd5..bb4ce8a8 100644 --- a/Classes/Domain/Log/Model/LogInterface.php +++ b/Classes/Domain/Log/Model/LogInterface.php @@ -7,39 +7,46 @@ interface LogInterface { public function __construct( - string $logLevel, - string $identifier, + LogLevel $logLevel, + int $orderItemId, + string $type, string $message, array $arguments = [], ); public static function info( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self; public static function notice( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self; public static function warning( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self; public static function error( - string $identifier, + int $orderItemId, + string $type, string $message, array $arguments = [], ): self; - public function getLogLevel(): string; + public function getLogLevel(): LogLevel; - public function getIdentifier(): string; + public function getOrderItemId(): int; + + public function getType(): string; public function getMessage(): string; diff --git a/Classes/Domain/Log/Model/LogLevel.php b/Classes/Domain/Log/Model/LogLevel.php new file mode 100644 index 00000000..e5fe3667 --- /dev/null +++ b/Classes/Domain/Log/Model/LogLevel.php @@ -0,0 +1,19 @@ +mailer->send($email); $this->logService->write( Log::info( - (string)$orderItem->getUid(), + $this->getOrderItemUid($orderItem), + 'sendBuyerMail', 'Mail was send to buyer.', [ 'time' => time(), @@ -350,7 +352,8 @@ public function sendBuyerMail(Item $orderItem): void } catch (Exception $e) { $this->logService->write( Log::error( - (string)$orderItem->getUid(), + $this->getOrderItemUid($orderItem), + 'sendBuyerMail', 'Mail could not send to buyer.', [ 'time' => time(), @@ -366,6 +369,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; @@ -410,7 +416,8 @@ public function sendSellerMail(Item $orderItem): void $this->mailer->send($email); $this->logService->write( Log::info( - (string)$orderItem->getUid(), + $this->getOrderItemUid($orderItem), + 'sendSellerMail', 'Mail was send to seller.', [ 'time' => time(), @@ -420,7 +427,8 @@ public function sendSellerMail(Item $orderItem): void } catch (Exception $e) { $this->logService->write( Log::error( - (string)$orderItem->getUid(), + $this->getOrderItemUid($orderItem), + 'sendSellerMail', 'Mail could not send to seller.', [ 'time' => time(), @@ -445,7 +453,8 @@ public function addAttachments(string $type, Item $orderItem, FluidEmail $email) } else { $this->logService->write( Log::warning( - (string)$orderItem->getUid(), + $this->getOrderItemUid($orderItem), + 'addAttachments', 'Mail could add attachment ' . $attachment . ' to mail.', [ 'time' => time(), @@ -456,4 +465,15 @@ public function addAttachments(string $type, Item $orderItem, FluidEmail $email) } } } + + private 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/Tests/Functional/Service/MailHandlerTest.php b/Tests/Functional/Service/MailHandlerTest.php index 949c4f08..cf1b3eb9 100644 --- a/Tests/Functional/Service/MailHandlerTest.php +++ b/Tests/Functional/Service/MailHandlerTest.php @@ -10,6 +10,7 @@ */ use Codappix\Typo3PhpDatasets\TestingFramework; +use Exception; use Extcode\Cart\Domain\Log\DatabaseWriter; use Extcode\Cart\Domain\Log\LogService; use Extcode\Cart\Domain\Model\Order\BillingAddress; @@ -17,6 +18,8 @@ use Extcode\Cart\Domain\Model\Order\Payment; use Extcode\Cart\Service\MailHandler; use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\MockObject\MockBuilder; +use PHPUnit\Framework\MockObject\Stub; use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\Log\LogLevel; use TYPO3\CMS\Core\Log\LogManager; @@ -56,29 +59,69 @@ public function setUp(): void } #[Test] - public function logSucessAfterEmailWasSend(): void + public function logSucessAfterEmailToBuyerWasSend(): void { - $configurationManager = self::createStub(ConfigurationManagerInterface::class); - - $eventDispatcher = self::createStub(EventDispatcherInterface::class); + $mockBuilder = $this->getMockBuilderForMailHandlerClass(); + $mockBuilder->onlyMethods( + [ + 'getBuyerEmailFrom', + 'getBuyerEmailName', + ] + ); + $mailHandler = $mockBuilder->getMock(); + $mailHandler->method('getBuyerEmailFrom')->willReturn('buyerEmailFrom@example.com'); + $mailHandler->method('getBuyerEmailName')->willReturn('Buyer Email Name'); - $mailer = self::createStub(MailerInterface::class); + $mailHandler->sendBuyerMail( + $this->createStubForOrderItem() + ); - $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); - $logService = GeneralUtility::makeInstance( - LogService::class, - $logger, + $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); + self::assertCount( + 1, + $logEntries ); + self::assertIsArray($logEntries[0]); - $mockBuilder = $this->getMockBuilder(MailHandler::class); - $mockBuilder->setConstructorArgs( + self::assertArrayIsEqualToArrayIgnoringListOfKeys( [ - $configurationManager, - $eventDispatcher, - $mailer, - $logService, + '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', @@ -89,18 +132,8 @@ public function logSucessAfterEmailWasSend(): void $mailHandler->method('getBuyerEmailFrom')->willReturn('buyerEmailFrom@example.com'); $mailHandler->method('getBuyerEmailName')->willReturn('Buyer Email Name'); - $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); - $mailHandler->sendBuyerMail( - $orderItem + $this->createStubForOrderItem() ); $logEntries = $this->getAllRecords('tx_cart_domain_model_order_log'); @@ -109,34 +142,165 @@ public function logSucessAfterEmailWasSend(): void $logEntries ); self::assertIsArray($logEntries[0]); - self::assertArrayHasKey( - 'level', - $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::assertSame( - 'info', - $logEntries[0]['level'] + + self::assertIsString( + $logEntries[0]['arguments'] ); - self::assertArrayHasKey( - 'identifier', - $logEntries[0] + $arguments = json_decode( + ltrim($logEntries[0]['arguments'], '- '), + true + ); + self::assertIsArray( + $arguments ); - self::assertSame( - '142', - $logEntries[0]['identifier'] + self::assertArrayHasKey( + 'time', + $arguments ); self::assertArrayHasKey( - 'message', - $logEntries[0] + 'exception', + $arguments + ); + self::assertIsString( + $arguments['exception'] + ); + self::assertStringStartsWith( + 'Exception in ', + $arguments['exception'] + ); + self::assertStringContainsString( + '/cart/Tests/Functional/Service/MailHandlerTest.php', + $arguments['exception'] ); - self::assertSame( - 'Mail was send to buyer.', - $logEntries[0]['message'] + } + + #[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( + $this->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( - 'arguments', - $logEntries[0] + '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( + $this->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'] ); @@ -151,5 +315,70 @@ public function logSucessAfterEmailWasSend(): void '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(__CLASS__); + $logService = GeneralUtility::makeInstance( + LogService::class, + $logger, + ); + + $mockBuilder = $this->getMockBuilder(MailHandler::class); + $mockBuilder->setConstructorArgs( + [ + $configurationManager, + $eventDispatcher, + $mailer, + $logService, + ] + ); + + return $mockBuilder; + } + + private 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/ext_tables.sql b/ext_tables.sql index 8a32bf21..686dc4f6 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -242,11 +242,13 @@ CREATE TABLE tx_cart_domain_model_coupon ( # CREATE TABLE tx_cart_domain_model_order_log ( uid int(11) NOT NULL auto_increment, - identifier char(40) DEFAULT '' NOT NULL, + 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, From 422e37746c5d1cc19972bc9ad4b249240f3115e5 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Sat, 28 Mar 2026 23:13:07 +0100 Subject: [PATCH 11/14] [TASK] Add Logging for updating payment and shipping Relates: #752 --- .../Backend/Order/PaymentController.php | 28 +++++++++++++++++-- .../Backend/Order/ShippingController.php | 28 +++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Classes/Controller/Backend/Order/PaymentController.php b/Classes/Controller/Backend/Order/PaymentController.php index d7be1247..e8ea0607 100644 --- a/Classes/Controller/Backend/Order/PaymentController.php +++ b/Classes/Controller/Backend/Order/PaymentController.php @@ -12,22 +12,35 @@ */ 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 { - // todo: add logging here $this->paymentRepository->update($payment); + $this->logService->write( + Log::info( + $this->getOrderItemUid($payment), + 'updatePayment', + 'Payment was set to ' . $payment->getStatus() . '.', + [ + 'time' => time(), + ] + ) + ); $event = new UpdateServiceEvent($payment); $this->eventDispatcher->dispatch($event); @@ -41,4 +54,15 @@ public function updateAction(Payment $payment): ResponseInterface return $this->redirect('show', 'Backend\Order\Order', null, ['orderItem' => $payment->getItem()]); } + + private 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 1ad1cc58..f1b97aee 100644 --- a/Classes/Controller/Backend/Order/ShippingController.php +++ b/Classes/Controller/Backend/Order/ShippingController.php @@ -12,22 +12,35 @@ */ 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 { - // todo: add logging here $this->shippingRepository->update($shipping); + $this->logService->write( + Log::info( + $this->getOrderItemUid($shipping), + 'updateShipping', + 'Shipping was set to ' . $shipping->getStatus() . '.', + [ + 'time' => time(), + ] + ) + ); $event = new UpdateServiceEvent($shipping); $this->eventDispatcher->dispatch($event); @@ -41,4 +54,15 @@ public function updateAction(Shipping $shipping): ResponseInterface return $this->redirect('show', 'Backend\Order\Order', null, ['orderItem' => $shipping->getItem()]); } + + private 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; + } } From 5baaebb84e2bdce43787f05ea89a444e813d29a3 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Sat, 28 Mar 2026 23:14:07 +0100 Subject: [PATCH 12/14] [TASK] Update version numbers in several files Relates: #752 --- Documentation/Introduction/Index.rst | 8 -------- Documentation/Introduction/NoteOfThanks/Index.rst | 15 --------------- Documentation/Introduction/Sponsoring/Index.rst | 3 --- Documentation/guides.xml | 6 +++--- README.md | 10 +++++----- ext_emconf.php | 8 ++++---- 6 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 Documentation/Introduction/NoteOfThanks/Index.rst 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..a2c4e1cc 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.1 | 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/ext_emconf.php b/ext_emconf.php index 4169be74..105ca46a 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -4,7 +4,7 @@ 'title' => 'Cart', 'description' => 'Shopping Cart(s) for TYPO3', 'category' => 'plugin', - 'version' => '11.7.2', + 'version' => '12.0.0', 'state' => 'stable', 'author' => 'Daniel Gohlke', 'author_email' => 'ext@extco.de', @@ -12,9 +12,9 @@ 'constraints' => [ 'depends' => [ 'php' => '8.2.0-8.4.99', - 'typo3' => '13.4.0-13.4.99', - 'extbase' => '13.4.0-13.4.99', - 'fluid' => '13.4.0-13.4.99', + 'typo3' => '14.1.0-14.4.99', + 'extbase' => '14.1.0-14.1.99', + 'fluid' => '14.1.0-14.1.99', ], 'conflicts' => [], 'suggests' => [], From 9e67159f64da77b08ff1a29f60792f93598b7932 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 2 Apr 2026 19:22:17 +0200 Subject: [PATCH 13/14] [TASK] Make extension compatible to TYPO3 v14.2 --- Build/.php-cs-fixer.dist.php | 5 ++ Build/phpstan-baseline.neon | 13 ++-- Build/phpstan.neon | 1 - Classes/Service/OrderItemCleanupService.php | 2 +- Tests/Fixtures/BackendUser.php | 15 +++++ Tests/Fixtures/BaseDatabase.php | 18 +++++ .../Command/AbstractCommandTestCase.php | 24 ++++--- .../Mail/AttachmentFromOrderItemTest.php | 11 ++- .../Mail/AttachmentFromTypoScriptTest.php | 11 ++- Tests/Functional/Service/MailHandlerTest.php | 13 +++- .../ViewHelpers/CsvHeaderViewHelperTest.php | 9 ++- .../ViewHelpers/CsvValuesViewHelperTest.php | 9 ++- .../Domain/Model/Cart/CartCouponFixTest.php | 2 +- .../Model/Cart/CartCouponPercentageTest.php | 2 +- Tests/Unit/Domain/Model/Cart/ServiceTest.php | 2 +- composer.json | 67 ++++--------------- ext_emconf.php | 22 ------ rector.php | 1 - 18 files changed, 118 insertions(+), 109 deletions(-) create mode 100644 Tests/Fixtures/BackendUser.php delete mode 100644 ext_emconf.php diff --git a/Build/.php-cs-fixer.dist.php b/Build/.php-cs-fixer.dist.php index 58818f6f..f33cf71a 100644 --- a/Build/.php-cs-fixer.dist.php +++ b/Build/.php-cs-fixer.dist.php @@ -11,6 +11,11 @@ (new PhpCsFixer\Finder()) ->ignoreVCSIgnored(true) ->in(__DIR__ . '/../') + ->exclude( + [ + 'var/', + ] + ) ) ->setRiskyAllowed(true) ->setRules([ diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon index a93ad23f..b9fbd0f3 100644 --- a/Build/phpstan-baseline.neon +++ b/Build/phpstan-baseline.neon @@ -2436,6 +2436,12 @@ parameters: 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 @@ -5555,10 +5561,3 @@ parameters: identifier: argument.templateType count: 1 path: ../Tests/Unit/Validation/Validator/EmptyValidatorTest.php - - - - message: '#^Cannot access offset ''cart'' on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: ../ext_emconf.php - diff --git a/Build/phpstan.neon b/Build/phpstan.neon index 06ce5b1c..f582a280 100644 --- a/Build/phpstan.neon +++ b/Build/phpstan.neon @@ -8,7 +8,6 @@ parameters: - ../Classes - ../Configuration - ../Tests - - ../ext_emconf.php - ../ext_localconf.php disallowedFunctionCalls: diff --git a/Classes/Service/OrderItemCleanupService.php b/Classes/Service/OrderItemCleanupService.php index 8b23654e..3f4933fe 100644 --- a/Classes/Service/OrderItemCleanupService.php +++ b/Classes/Service/OrderItemCleanupService.php @@ -74,7 +74,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(', ', array_filter($dataHandler->errorLog, 'is_string')), + 'Could not properly delete records for table: ' . $tableName . ', got the following errors: ' . implode(', ', array_filter($dataHandler->errorLog, is_string(...))), 1751526777 ); } 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..a8f90bda 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,26 @@ 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/EventListener/Mail/AttachmentFromOrderItemTest.php b/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php index e7037257..713d6b30 100644 --- a/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php +++ b/Tests/Functional/EventListener/Mail/AttachmentFromOrderItemTest.php @@ -24,8 +24,15 @@ class AttachmentFromOrderItemTest extends FunctionalTestCase public function setUp(): void { - $this->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(); diff --git a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php index 1a6a277d..f5d8153d 100644 --- a/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php +++ b/Tests/Functional/EventListener/Mail/AttachmentFromTypoScriptTest.php @@ -26,8 +26,15 @@ class AttachmentFromTypoScriptTest extends FunctionalTestCase public function setUp(): void { - $this->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(); diff --git a/Tests/Functional/Service/MailHandlerTest.php b/Tests/Functional/Service/MailHandlerTest.php index cf1b3eb9..80f9d4ec 100644 --- a/Tests/Functional/Service/MailHandlerTest.php +++ b/Tests/Functional/Service/MailHandlerTest.php @@ -34,8 +34,15 @@ class MailHandlerTest extends FunctionalTestCase public function setUp(): void { - $this->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', + ]; $this->configurationToUseInTestInstance = [ 'LOG' => [ @@ -346,7 +353,7 @@ private function getMockBuilderForMailHandlerClass(bool $mailerThrowException = $mailer->method('send')->willThrowException(new Exception()); } - $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(self::class); $logService = GeneralUtility::makeInstance( LogService::class, $logger, diff --git a/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php b/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php index fce4bbd8..88366219 100644 --- a/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/CsvHeaderViewHelperTest.php @@ -25,7 +25,14 @@ final class CsvHeaderViewHelperTest extends FunctionalTestCase public function setUp(): void { - $this->testExtensionsToLoad[] = 'extcode/cart'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); } diff --git a/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php b/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php index 9ccb78f9..9550ca16 100644 --- a/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/CsvValuesViewHelperTest.php @@ -29,7 +29,14 @@ final class CsvValuesViewHelperTest extends FunctionalTestCase public function setUp(): void { - $this->testExtensionsToLoad[] = 'extcode/cart'; + $this->testExtensionsToLoad = [ + 'extcode/cart', + ]; + + $this->coreExtensionsToLoad = [ + 'typo3/cms-beuser', + 'typo3/cms-core', + ]; parent::setUp(); diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php index 368eb21e..8314dab6 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponFixTest.php @@ -245,7 +245,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([[$this->taxClass]]) ->getMock(); } diff --git a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php index d54041cd..3003dc3d 100644 --- a/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php +++ b/Tests/Unit/Domain/Model/Cart/CartCouponPercentageTest.php @@ -275,7 +275,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([[$this->taxClass]]) ->getMock(); } diff --git a/Tests/Unit/Domain/Model/Cart/ServiceTest.php b/Tests/Unit/Domain/Model/Cart/ServiceTest.php index 3b0a6b6a..579c0aa8 100644 --- a/Tests/Unit/Domain/Model/Cart/ServiceTest.php +++ b/Tests/Unit/Domain/Model/Cart/ServiceTest.php @@ -475,7 +475,7 @@ private function createCartMock(array $methods = ['getGross']): Cart|MockObject ); return $this->getMockBuilder(Cart::class) - ->onlyMethods(array_values(array_filter(array_filter($methods, 'is_string')))) + ->onlyMethods(array_values(array_filter(array_filter($methods, is_string(...))))) ->setConstructorArgs([$this->taxClasses]) ->getMock(); } diff --git a/composer.json b/composer.json index c493dee0..44bf2bfb 100644 --- a/composer.json +++ b/composer.json @@ -38,9 +38,10 @@ "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": { @@ -53,11 +54,10 @@ "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "ext-json": "*", "ext-openssl": "*", - "typo3/cms-core": "^14.0", - "typo3/cms-extbase": "^14.0", - "typo3/cms-fluid": "^14.0", - "typo3/cms-form": "^14.0", - "typo3/cms-frontend": "^14.0" + "typo3/cms-core": "^14.2", + "typo3/cms-extbase": "^14.2", + "typo3/cms-fluid": "^14.2", + "typo3/cms-frontend": "^14.2" }, "require-dev": { "codappix/typo3-php-datasets": "^2.1", @@ -68,55 +68,14 @@ "phpstan/phpstan-phpunit": "^2.0", "spaze/phpstan-disallowed-calls": "^4.7", "staabm/phpstan-todo-by": "^0.3", - "typo3/cms-beuser": "^14.0", - "typo3/cms-dashboard": "^14.0", - "typo3/cms-form": "^14.0", - "typo3/testing-framework": "^9.0", + "typo3/cms-beuser": "^14.2", + "typo3/cms-dashboard": "^14.2", + "typo3/cms-form": "^14.2", + "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/phpunit.xml.dist" - ], - "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" - ] - }, "suggest": { - "typo3/cms-dashboard": "^14.0", - "typo3/cms-form": "^14.0" + "typo3/cms-dashboard": "^14.2", + "typo3/cms-form": "^14.2" } } diff --git a/ext_emconf.php b/ext_emconf.php deleted file mode 100644 index 105ca46a..00000000 --- a/ext_emconf.php +++ /dev/null @@ -1,22 +0,0 @@ - 'Cart', - 'description' => 'Shopping Cart(s) for TYPO3', - 'category' => 'plugin', - 'version' => '12.0.0', - 'state' => 'stable', - 'author' => 'Daniel Gohlke', - 'author_email' => 'ext@extco.de', - 'author_company' => 'extco.de UG (haftungsbeschränkt)', - 'constraints' => [ - 'depends' => [ - 'php' => '8.2.0-8.4.99', - 'typo3' => '14.1.0-14.4.99', - 'extbase' => '14.1.0-14.1.99', - 'fluid' => '14.1.0-14.1.99', - ], - 'conflicts' => [], - 'suggests' => [], - ], -]; diff --git a/rector.php b/rector.php index 22291b6b..1ac2c13a 100644 --- a/rector.php +++ b/rector.php @@ -19,7 +19,6 @@ __DIR__ . '/Classes', __DIR__ . '/Configuration', __DIR__ . '/Tests', - __DIR__ . '/ext_emconf.php', __DIR__ . '/ext_localconf.php', ]) // uncomment to reach your current PHP version From ff32a7bc041877b4275d3195f33ae98722686c7a Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 10 Apr 2026 21:15:45 +0200 Subject: [PATCH 14/14] [TASK] Change prices in database to fixed-point numbers --- ext_tables.sql | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/ext_tables.sql b/ext_tables.sql index 686dc4f6..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,