From b39d6567c28a8376b98b7f39932d1a0249194579 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Mon, 29 Jul 2024 10:55:08 +0200 Subject: [PATCH] Fix compatibility with Sylius 1.13 --- .github/workflows/build.yml | 2 +- composer.json | 2 +- ...g_fees_for_table_rate_based_method.feature | 4 +- .../Calculator/TableRateConfigurationType.php | 67 +++++++++++++++++-- src/Resolver/TableRateResolver.php | 16 ++--- src/Resources/config/services.yml | 2 + .../config/routes/sylius_shop.yaml | 2 +- .../Setup/ShippingTableRateContext.php | 2 +- 8 files changed, 78 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 42bc2fc..101fa19 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: matrix: php: [ "8.1", "8.2", "8.3" ] symfony: [ "5.4.*", "^6.4" ] - sylius: ["1.12.16", "1.13.1"] + sylius: ["1.13.3"] node: ["18.x"] mysql: ["8.0"] diff --git a/composer.json b/composer.json index f475547..833e70e 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "license": "MIT", "require": { "php": "^8.1", - "sylius/sylius": "^1.12", + "sylius/sylius": "^1.13.3", "symfony/webpack-encore-bundle": "^1.15" }, "require-dev": { diff --git a/features/seeing_correct_shipping_fees_for_table_rate_based_method.feature b/features/seeing_correct_shipping_fees_for_table_rate_based_method.feature index e8fbce5..680eaa8 100644 --- a/features/seeing_correct_shipping_fees_for_table_rate_based_method.feature +++ b/features/seeing_correct_shipping_fees_for_table_rate_based_method.feature @@ -8,8 +8,8 @@ Feature: Seeing correct shipping fees for table rate based shipping methods Given the store operates on a single channel in "United States" And the store has a product "Bottle of water" which weights 1 kg And the store has a shipping table rate "Weight-based" for currency "USD" - And it has a rate "$5" for shipments up to 5 kg - And it has a rate "$10" for shipments up to 20 kg + And it has a rate "$5.00" for shipments up to 5 kg + And it has a rate "$10.00" for shipments up to 20 kg And the store has "Basic" shipping method using "Weight-based" table rate for "United States" channel And I am a logged in customer diff --git a/src/Form/Type/Shipping/Calculator/TableRateConfigurationType.php b/src/Form/Type/Shipping/Calculator/TableRateConfigurationType.php index 262af7d..a12621f 100644 --- a/src/Form/Type/Shipping/Calculator/TableRateConfigurationType.php +++ b/src/Form/Type/Shipping/Calculator/TableRateConfigurationType.php @@ -6,15 +6,24 @@ use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; +use Sylius\Component\Resource\Repository\RepositoryInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\DataMapperInterface; +use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\NotBlank; use Webgriffe\SyliusTableRateShippingPlugin\Entity\ShippingTableRate; -final class TableRateConfigurationType extends AbstractType +final class TableRateConfigurationType extends AbstractType implements DataMapperInterface { + public function __construct( + private RepositoryInterface $tableRateRepository, + ) { + } + public const TABLE_RATE_FIELD_NAME = 'table_rate'; public function buildForm(FormBuilderInterface $builder, array $options): void @@ -26,7 +35,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void EntityType::class, [ 'label' => $messagesNamespace . 'table_rate.label', - 'placeholder' => '' . $messagesNamespace . 'table_rate.placeholder', + 'placeholder' => $messagesNamespace . 'table_rate.placeholder', 'class' => ShippingTableRate::class, 'query_builder' => function (EntityRepository $entityRepository) use ($currency): QueryBuilder { return $entityRepository @@ -36,10 +45,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ; }, 'choice_label' => 'name', - 'choice_value' => 'code', 'constraints' => [new NotBlank(['groups' => ['sylius']])], - ] - ); + ], + )->setDataMapper($this); } public function configureOptions(OptionsResolver $resolver): void @@ -54,4 +62,53 @@ public function getBlockPrefix(): string { return 'webgriffe_sylius_table_rate_shipping_plugin_calculator_table_rate'; } + + /** + * @psalm-suppress MoreSpecificImplementedParamType + * @psalm-suppress PossiblyInvalidArgument + */ + public function mapDataToForms(mixed $viewData, \Traversable $forms): void + { + // there is no data yet, so nothing to prepopulate + if (null === $viewData) { + return; + } + + // invalid data type + if (!is_array($viewData)) { + throw new UnexpectedTypeException($viewData, 'array'); + } + + /** @var FormInterface[] $forms */ + $forms = iterator_to_array($forms); + + if (!array_key_exists(self::TABLE_RATE_FIELD_NAME, $viewData)) { + return; + } + + // initialize form field values + $forms['table_rate']->setData($this->tableRateRepository->findOneBy(['code' => $viewData[self::TABLE_RATE_FIELD_NAME]])); + } + + /** + * @psalm-suppress MoreSpecificImplementedParamType + * @psalm-suppress PossiblyInvalidArgument + */ + public function mapFormsToData(\Traversable $forms, mixed &$viewData): void + { + /** @var FormInterface[] $forms */ + $forms = iterator_to_array($forms); + + // as data is passed by reference, overriding it will change it in + // the form object as well + // beware of type inconsistency, see caution below + $tableRateSelected = $forms[self::TABLE_RATE_FIELD_NAME]->getData(); + if (!$tableRateSelected instanceof ShippingTableRate) { + $viewData = []; + + return; + } + + $viewData = [self::TABLE_RATE_FIELD_NAME => $tableRateSelected->getCode()]; + } } diff --git a/src/Resolver/TableRateResolver.php b/src/Resolver/TableRateResolver.php index 28af63f..b6baf5f 100644 --- a/src/Resolver/TableRateResolver.php +++ b/src/Resolver/TableRateResolver.php @@ -29,7 +29,7 @@ public function resolve(ShipmentInterface $shipment, array $calculatorConfig): S $channel = $order->getChannel(); if (null === $channel) { throw new \RuntimeException( - 'Cannot resolve a table rate, there\'s no channel for this shipment\'s order.' + 'Cannot resolve a table rate, there\'s no channel for this shipment\'s order.', ); } $channelCode = $channel->getCode(); @@ -40,8 +40,8 @@ public function resolve(ShipmentInterface $shipment, array $calculatorConfig): S throw new MissingChannelConfigurationException( sprintf( 'This shipment has no configuration for channel "%s".', - $channel->getName() - ) + $channel->getName(), + ), ); } @@ -49,14 +49,14 @@ public function resolve(ShipmentInterface $shipment, array $calculatorConfig): S sprintf( 'Shipping method "%s" has no configuration for channel "%s".', $shippingMethod->getName(), - $channel->getName() - ) + $channel->getName(), + ), ); } - /** @var ShippingTableRate $tableRate */ - $tableRate = $calculatorConfig[$channelCode][TableRateConfigurationType::TABLE_RATE_FIELD_NAME]; - $tableRate = $this->tableRateRepository->findOneBy(['code' => $tableRate->getCode()]); + /** @var string $tableRateCode */ + $tableRateCode = $calculatorConfig[$channelCode][TableRateConfigurationType::TABLE_RATE_FIELD_NAME]; + $tableRate = $this->tableRateRepository->findOneBy(['code' => $tableRateCode]); Assert::isInstanceOf($tableRate, ShippingTableRate::class); return $tableRate; diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 18b6271..652f45f 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -36,6 +36,8 @@ services: - { name: form.type } Webgriffe\SyliusTableRateShippingPlugin\Form\Type\Shipping\Calculator\TableRateConfigurationType: + arguments: + - '@webgriffe.repository.shipping_table_rate' tags: - { name: form.type } diff --git a/tests/Application/config/routes/sylius_shop.yaml b/tests/Application/config/routes/sylius_shop.yaml index 92eeae0..fae46cb 100644 --- a/tests/Application/config/routes/sylius_shop.yaml +++ b/tests/Application/config/routes/sylius_shop.yaml @@ -11,4 +11,4 @@ sylius_shop_default_locale: path: / methods: [GET] defaults: - _controller: sylius.controller.shop.locale_switch:switchAction + _controller: sylius.controller.shop.locale_switch::switchAction diff --git a/tests/Behat/Context/Setup/ShippingTableRateContext.php b/tests/Behat/Context/Setup/ShippingTableRateContext.php index e51873f..579563a 100644 --- a/tests/Behat/Context/Setup/ShippingTableRateContext.php +++ b/tests/Behat/Context/Setup/ShippingTableRateContext.php @@ -89,7 +89,7 @@ public function theStoreHasShippingMethodUsingTableRateForChannel( 'zone' => $this->getShippingZone(), 'calculator' => [ 'type' => TableRateShippingCalculator::TYPE, - 'configuration' => [$channel->getCode() => ['table_rate' => $shippingTableRate]], + 'configuration' => [$channel->getCode() => [TableRateShippingCalculator::TYPE => $shippingTableRate->getCode()]], ], 'channels' => [$channel], ]);