diff --git a/Classes/Controller/Cart/CountryController.php b/Classes/Controller/Cart/CountryController.php index f398b7b3..8de40f02 100644 --- a/Classes/Controller/Cart/CountryController.php +++ b/Classes/Controller/Cart/CountryController.php @@ -4,6 +4,7 @@ namespace Extcode\Cart\Controller\Cart; +use Extcode\Cart\Service\TaxClassServiceInterface; use Psr\Http\Message\ResponseInterface; /* @@ -14,6 +15,10 @@ */ class CountryController extends ActionController { + public function __construct( + protected TaxClassServiceInterface $taxClassService + ) {} + public function updateAction(): ResponseInterface { //ToDo check country is allowed by TypoScript @@ -22,7 +27,7 @@ public function updateAction(): ResponseInterface $this->restoreSession(); - $taxClasses = $this->parserUtility->parseTaxClasses($this->configurations, $this->cart->getBillingCountry()); + $taxClasses = $this->taxClassService->getTaxClasses($this->cart->getBillingCountry()); $this->cart->setTaxClasses($taxClasses); $this->cart->reCalc(); diff --git a/Classes/Domain/Model/Cart/TaxClass.php b/Classes/Domain/Model/Cart/TaxClass.php index 20db512e..f43ec0fa 100644 --- a/Classes/Domain/Model/Cart/TaxClass.php +++ b/Classes/Domain/Model/Cart/TaxClass.php @@ -11,27 +11,14 @@ * LICENSE file that was distributed with this source code. */ -class TaxClass +final class TaxClass implements TaxClassInterface { - protected int $id; - - protected string $value; - - protected float $calc; - - protected string $title; - public function __construct( - int $id, - string $value, - float $calc, - string $title - ) { - $this->id = $id; - $this->value = $value; - $this->calc = $calc; - $this->title = $title; - } + private readonly int $id, + private readonly string $value, + private readonly float $calc, + private readonly string $title + ) {} public function getId(): int { diff --git a/Classes/Domain/Model/Cart/TaxClassFactory.php b/Classes/Domain/Model/Cart/TaxClassFactory.php new file mode 100644 index 00000000..87547156 --- /dev/null +++ b/Classes/Domain/Model/Cart/TaxClassFactory.php @@ -0,0 +1,50 @@ +isValidTaxClassConfig($taxClassKey, $taxClassValue)) { + return new TaxClass( + $taxClassKey, + $taxClassValue['value'], + (float)$taxClassValue['calc'], + $taxClassValue['name'] + ); + } + + return null; + } + + private function isValidTaxClassConfig(int $key, array $value): bool + { + if (empty($value) || + empty($value['name']) || + !isset($value['calc']) || + !is_numeric($value['calc']) + ) { + $this->logger->error('Can\'t create tax class object for the configuration with the index=' . $key . '.', []); + + return false; + } + + return true; + } +} diff --git a/Classes/Domain/Model/Cart/TaxClassFactoryInterface.php b/Classes/Domain/Model/Cart/TaxClassFactoryInterface.php new file mode 100644 index 00000000..e9daabc7 --- /dev/null +++ b/Classes/Domain/Model/Cart/TaxClassFactoryInterface.php @@ -0,0 +1,17 @@ +settings = $this->configurationManager->getConfiguration( - ConfigurationManager::CONFIGURATION_TYPE_FRAMEWORK, + ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'Cart' ); } /** - * @inheritDoc + * @return TaxClass[] */ public function getTaxClasses(string $countryCode = null): array { @@ -49,33 +51,13 @@ public function getTaxClasses(string $countryCode = null): array } foreach ($taxClassSettings as $taxClassKey => $taxClassValue) { - if ($this->isValidTaxClassConfig($taxClassKey, $taxClassValue)) { - $taxClasses[$taxClassKey] = GeneralUtility::makeInstance( - TaxClass::class, - (int)$taxClassKey, - $taxClassValue['value'], - (float)$taxClassValue['calc'], - $taxClassValue['name'] - ); + $taxClass = $this->taxClassFactory->getTaxClass($taxClassKey, $taxClassValue); + + if ($taxClass instanceof TaxClassInterface) { + $taxClasses[$taxClassKey] = $taxClass; } } return $taxClasses; } - - protected function isValidTaxClassConfig(int $key, array $value): bool - { - if (empty($value) || - empty($value['name']) || - !isset($value['calc']) || - (isset($value['calc']) && !is_numeric($value['calc'])) - ) { - $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); - $logger->error('Can\'t create tax class object for the configuration with the index=' . $key . '.', []); - - return false; - } - - return true; - } } diff --git a/Classes/Service/TaxClassServiceInterface.php b/Classes/Service/TaxClassServiceInterface.php index 98856a3c..e1c20143 100644 --- a/Classes/Service/TaxClassServiceInterface.php +++ b/Classes/Service/TaxClassServiceInterface.php @@ -16,7 +16,7 @@ interface TaxClassServiceInterface { /** - * @return array + * @return TaxClass[] */ public function getTaxClasses(string $countryCode = null): array; } diff --git a/Classes/Utility/CartUtility.php b/Classes/Utility/CartUtility.php index f4d94c3f..5b479695 100644 --- a/Classes/Utility/CartUtility.php +++ b/Classes/Utility/CartUtility.php @@ -13,27 +13,19 @@ use Extcode\Cart\Domain\Model\Cart\Service; use Extcode\Cart\Event\Cart\UpdateCountryEvent; use Extcode\Cart\Service\SessionHandler; +use Extcode\Cart\Service\TaxClassServiceInterface; use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Request; class CartUtility { - protected EventDispatcherInterface $eventDispatcher; - - protected SessionHandler $sessionHandler; - - protected ParserUtility $parserUtility; - public function __construct( - EventDispatcherInterface $eventDispatcher, - ParserUtility $parserUtility, - SessionHandler $sessionHandler - ) { - $this->eventDispatcher = $eventDispatcher; - $this->parserUtility = $parserUtility; - $this->sessionHandler = $sessionHandler; - } + protected EventDispatcherInterface $eventDispatcher, + protected ParserUtility $parserUtility, + protected TaxClassServiceInterface $taxClassService, + protected SessionHandler $sessionHandler + ) {} public function getServiceById(array $services, int $serviceId): mixed { @@ -104,7 +96,7 @@ public function getNewCart(array $configurations): Cart $defaultCountry = $configurations['settings']['countries']['options'][$configurations['settings']['countries']['preset']]['code']; - $taxClasses = $this->parserUtility->parseTaxClasses($configurations, $defaultCountry); + $taxClasses = $this->taxClassService->getTaxClasses($defaultCountry); /** @var Cart $cart */ $cart = GeneralUtility::makeInstance( diff --git a/Classes/Utility/ParserUtility.php b/Classes/Utility/ParserUtility.php index e10aa55e..91d31bde 100644 --- a/Classes/Utility/ParserUtility.php +++ b/Classes/Utility/ParserUtility.php @@ -12,26 +12,10 @@ use Extcode\Cart\Domain\Model\Cart\Cart; use Extcode\Cart\Domain\Model\Cart\Service; use Extcode\Cart\Domain\Model\Cart\ServiceInterface; -use Extcode\Cart\Service\TaxClassService; -use Extcode\Cart\Service\TaxClassServiceInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; class ParserUtility { - public function parseTaxClasses(array $pluginSettings, string $countryCode = null): array - { - $className = $pluginSettings['taxClasses']['className'] ?? TaxClassService::class; - - $service = GeneralUtility::makeInstance( - $className - ); - if (!$service instanceof TaxClassServiceInterface) { - throw new \UnexpectedValueException($className . ' must implement interface ' . TaxClassServiceInterface::class, 123); - } - - return $service->getTaxClasses($countryCode); - } - /** * Parse Services * diff --git a/Documentation/Changelog/9.0/Breaking-505-ReplaceParserUtilityParseTaxByDI.rst b/Documentation/Changelog/9.0/Breaking-505-ReplaceParserUtilityParseTaxByDI.rst new file mode 100644 index 00000000..32019d5e --- /dev/null +++ b/Documentation/Changelog/9.0/Breaking-505-ReplaceParserUtilityParseTaxByDI.rst @@ -0,0 +1,31 @@ +.. include:: ../../Includes.txt + +====================================================== +Breaking: #505 - Replace ParserUtility::parseTax by DI +====================================================== + +See :issue:`480` + +Description +=========== + +The existing `\Extcode\Cart\Utility\ParserUtility::parseTax()` uses a TaxClassService +which could be configured by a TypoScript Configuration. The change remove the +method from the class and injecting the `Extcode\Cart\Service\TaxClassServiceInterface` +by Dependency Injection. + +Affected Installations +====================== + +All installations where `plugin.tx_cart.taxClasses.className` is used to replace +the default TaxClassService. + +Migration +========= + +Remove the old configuration from TypoScript. +Add an entry to your `Services.yaml` or `Services.php` and configure your +implementation of the `Extcode\Cart\Service\TaxClassServiceInterface` for the +`$taxClassService` constructor argument. + +.. index:: Backend, Dependency Injection diff --git a/Tests/Functional/Service/TaxClassServiceTest.php b/Tests/Functional/Service/TaxClassServiceTest.php index 94aaf1cb..93d6747a 100644 --- a/Tests/Functional/Service/TaxClassServiceTest.php +++ b/Tests/Functional/Service/TaxClassServiceTest.php @@ -16,20 +16,12 @@ class TaxClassServiceTest extends FunctionalTestCase { - /** - * @var TaxClassService - */ - protected $taxClassService; - - /** - * @var non-empty-string[] - */ - protected array $testExtensionsToLoad = [ - 'typo3conf/ext/cart', - ]; + protected TaxClassService $taxClassService; public function setUp(): void { + $this->testExtensionsToLoad[] = 'extcode/cart'; + parent::setUp(); $this->taxClassService = GeneralUtility::makeInstance( diff --git a/Tests/Functional/Utility/ParserUtilityTest.php b/Tests/Functional/Utility/ParserUtilityTest.php index b7a69456..66b6907f 100644 --- a/Tests/Functional/Utility/ParserUtilityTest.php +++ b/Tests/Functional/Utility/ParserUtilityTest.php @@ -17,20 +17,12 @@ class ParserUtilityTest extends FunctionalTestCase { - /** - * @var ParserUtility - */ - protected $parserUtility; - - /** - * @var non-empty-string[] - */ - protected array $testExtensionsToLoad = [ - 'typo3conf/ext/cart', - ]; + protected ParserUtility $parserUtility; public function setUp(): void { + $this->testExtensionsToLoad[] = 'extcode/cart'; + parent::setUp(); $this->parserUtility = GeneralUtility::makeInstance( @@ -50,50 +42,51 @@ public function getTypePluginSettingsReturnsTypeCountrySettings() $pluginSettings = [ $type => [ - 'default' => 'de', - 'de' => [ - 'preset' => 1, - 'options' => [ - '1' => [ - 'title' => 'Payment 1 DE', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', - ], - '2' => [ - 'title' => 'Payment 2 DE', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', - ], - '3' => [ - 'title' => 'Payment 3 DE', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', + 'countries' => [ + 'de' => [ + 'preset' => 1, + 'options' => [ + '1' => [ + 'title' => 'Payment 1 DE', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], + '2' => [ + 'title' => 'Payment 2 DE', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], + '3' => [ + 'title' => 'Payment 3 DE', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], ], ], - ], - 'at' => [ - 'preset' => 1, - 'options' => [ - '1' => [ - 'title' => 'Payment 1 AT', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', - ], - '2' => [ - 'title' => 'Payment 2 AT', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', - ], - '3' => [ - 'title' => 'Payment 3 AT', - 'extra' => '0.00', - 'taxClassId' => '1', - 'status' => 'open', + 'at' => [ + 'preset' => 1, + 'options' => [ + '1' => [ + 'title' => 'Payment 1 AT', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], + '2' => [ + 'title' => 'Payment 2 AT', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], + '3' => [ + 'title' => 'Payment 3 AT', + 'extra' => '0.00', + 'taxClassId' => '1', + 'status' => 'open', + ], ], ], ], @@ -121,7 +114,7 @@ public function getTypePluginSettingsReturnsTypeCountrySettings() ); self::assertEquals( - $pluginSettings[$type][$country]['options'], + $pluginSettings[$type]['countries'][$country]['options'], $parsedData['options'] ); }