diff --git a/.bunnyshell/docker/php/Dockerfile b/.bunnyshell/docker/php/Dockerfile
index 78df60e65c..9634e6ca5f 100644
--- a/.bunnyshell/docker/php/Dockerfile
+++ b/.bunnyshell/docker/php/Dockerfile
@@ -1,10 +1,10 @@
# the different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/compose/compose-file/#target
-ARG PHP_VERSION=8.1
-ARG NODE_VERSION=16
-ARG ALPINE_VERSION=3.15
-ARG COMPOSER_VERSION=2.4
+ARG PHP_VERSION=8.2
+ARG NODE_VERSION=18
+ARG ALPINE_VERSION=3.18
+ARG COMPOSER_VERSION=2.6
ARG PHP_EXTENSION_INSTALLER_VERSION=latest
FROM composer:${COMPOSER_VERSION} AS composer
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 579c9164b2..88e98b0d80 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -38,9 +38,10 @@ parameters:
- 'src/Sylius/Bundle/ApiBundle/**.php'
ignoreErrors:
+ - '/(Interface|Class) [a-zA-Z\\]+ specifies template type (\w+) of interface [a-zA-Z\\]+ as [a-zA-Z\\]+ (of [a-zA-Z\\]+ )?but it''s already specified as/' # turns off a weird generics check behavior, we are basing on Psalm for generics checks
- '/Access to an undefined property Doctrine\\Common\\Collections\\ArrayCollection/'
+ - '/Class "Sylius\\Bundle\\CoreBundle\\Fixture\\PaymentFixture" not found/'
+ - '/Class Symfony\\Component\\Clock\\Clock not found\./'
- '/Class Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken constructor invoked with 4 parameters\, 2\-3 required./'
- '/Method Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface\:\:supportsNormalization\(\) invoked with 3 parameters\, 1\-2 required\./'
- - '/(Interface|Class) [a-zA-Z\\]+ specifies template type (\w+) of interface [a-zA-Z\\]+ as [a-zA-Z\\]+ (of [a-zA-Z\\]+ )?but it''s already specified as/' # turns off a weird generics check behavior, we are basing on Psalm for generics checks
- '/Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::normalize\(\) invoked with 2 parameters, 1 required./'
- - '/Class "Sylius\\Bundle\\CoreBundle\\Fixture\\PaymentFixture" not found/'
diff --git a/psalm.xml b/psalm.xml
index 6dff4b706a..1a3deaa214 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -265,6 +265,7 @@
+
diff --git a/src/Sylius/Bundle/ApiBundle/disabledSpec/DataPersister/MessengerDataPersisterSpec.php b/src/Sylius/Bundle/ApiBundle/disabledSpec/DataPersister/MessengerDataPersisterSpec.php
index 320ace81c5..57d235cb4a 100644
--- a/src/Sylius/Bundle/ApiBundle/disabledSpec/DataPersister/MessengerDataPersisterSpec.php
+++ b/src/Sylius/Bundle/ApiBundle/disabledSpec/DataPersister/MessengerDataPersisterSpec.php
@@ -17,6 +17,7 @@ use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder;
+use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
@@ -42,7 +43,13 @@ final class MessengerDataPersisterSpec extends ObjectBehavior
$completeOrder->setOrderTokenValue('ORDERTOKEN');
$envelope = new Envelope($completeOrder);
- $decoratedDataPersister->persist($envelope, [])->willThrow(new DelayedMessageHandlingException([new \RuntimeException('Delayed message exception')]));
+ if (version_compare(Kernel::VERSION, '6.3.5', '>=')) {
+ $exception = new DelayedMessageHandlingException([new \RuntimeException('Delayed message exception')], $envelope);
+ } else {
+ $exception = new DelayedMessageHandlingException([new \RuntimeException('Delayed message exception')]);
+ }
+
+ $decoratedDataPersister->persist($envelope, [])->willThrow($exception);
$this->shouldThrow(new \RuntimeException('Delayed message exception'))->during('persist', [$envelope, []]);
}
diff --git a/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/OrderShipping/AfterOrderShippedListener.php b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/OrderShipping/AfterOrderShippedListener.php
index c621d63873..e7a97e68c6 100644
--- a/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/OrderShipping/AfterOrderShippedListener.php
+++ b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/OrderShipping/AfterOrderShippedListener.php
@@ -26,10 +26,8 @@ final class AfterOrderShippedListener
public function onOrderShippingCompleted(CompletedEvent $event): void
{
- Assert::isInstanceOf($event->getSubject(), OrderInterface::class);
-
- /** @var OrderInterface $order */
$order = $event->getSubject();
+ Assert::isInstanceOf($order, OrderInterface::class);
$this->orderStateResolver->resolve($order);
}
diff --git a/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/AssignShippingDateListener.php b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/AssignShippingDateListener.php
new file mode 100644
index 0000000000..ad687c83dd
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/AssignShippingDateListener.php
@@ -0,0 +1,34 @@
+getSubject();
+ Assert::isInstanceOf($shipment, ShipmentInterface::class);
+
+ $this->shippingDateAssigner->assign($shipment);
+ }
+}
diff --git a/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListener.php b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListener.php
new file mode 100644
index 0000000000..a18fcc1861
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListener.php
@@ -0,0 +1,38 @@
+getSubject();
+ Assert::isInstanceOf($shipment, ShipmentInterface::class);
+
+ $order = $shipment->getOrder();
+ Assert::isInstanceOf($order, OrderInterface::class);
+
+ $this->orderStateResolver->resolve($order);
+ }
+}
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_order_shipping.yaml b/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_order_shipping.yaml
index d33661036d..7f48a51cec 100644
--- a/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_order_shipping.yaml
+++ b/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_order_shipping.yaml
@@ -4,7 +4,7 @@ framework:
type: state_machine
marking_store:
type: method
- property: ShippingState
+ property: shippingState
supports:
- Sylius\Component\Core\Model\OrderInterface
initial_marking: !php/const Sylius\Component\Core\OrderShippingStates::STATE_CART
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_shipment.yaml b/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_shipment.yaml
new file mode 100644
index 0000000000..bf1edf953b
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/Resources/config/app/workflow/sylius_shipment.yaml
@@ -0,0 +1,25 @@
+framework:
+ workflows:
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::GRAPH:
+ type: state_machine
+ marking_store:
+ type: method
+ property: state
+ supports:
+ - Sylius\Component\Core\Model\ShipmentInterface
+ initial_marking: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ places:
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_SHIPPED
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CANCELLED
+ transitions:
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_CREATE:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_SHIP:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_SHIPPED
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_CANCEL:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CANCELLED
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
index 03b3bb28fb..f377386cc7 100644
--- a/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
+++ b/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
@@ -42,7 +42,6 @@
-
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners.xml
index d52fe61c74..34d58f5f24 100644
--- a/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners.xml
+++ b/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners.xml
@@ -12,6 +12,10 @@
-->
+
+
+
+
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow/listeners.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners/workflow/order_shipping.xml
similarity index 98%
rename from src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow/listeners.xml
rename to src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners/workflow/order_shipping.xml
index 66bcbbcbd7..27e57021cc 100644
--- a/src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow/listeners.xml
+++ b/src/Sylius/Bundle/CoreBundle/Resources/config/services/listeners/workflow/order_shipping.xml
@@ -16,7 +16,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow.xml
deleted file mode 100644
index caabedb6cc..0000000000
--- a/src/Sylius/Bundle/CoreBundle/Resources/config/services/workflow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/ShipmentWorkflowTest.php b/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/ShipmentWorkflowTest.php
new file mode 100644
index 0000000000..75584484a4
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/ShipmentWorkflowTest.php
@@ -0,0 +1,66 @@
+order = new Order();
+
+ $this->shipment = new Shipment();
+ $this->shipment->setOrder($this->order);
+ }
+
+ /**
+ * @test
+ *
+ * @dataProvider availableTransitionsFromReadyState
+ */
+ public function it_applies_all_available_transitions_for_create_state(string $transition, string $expectedStatus): void
+ {
+ $stateMachine = $this->getStateMachine();
+ $stateMachine->apply($this->order, 'sylius_order_shipping', 'request_shipping');
+ $stateMachine->apply($this->shipment, 'sylius_shipment', 'create');
+ $stateMachine->apply($this->shipment, 'sylius_shipment', $transition);
+
+ $this->assertSame($expectedStatus, $this->shipment->getState());
+ }
+
+ public function availableTransitionsFromReadyState(): iterable
+ {
+ yield ['cancel', 'cancelled'];
+ yield ['ship', 'shipped'];
+ }
+
+ private function getStateMachine(): StateMachineInterface
+ {
+ return self::getContainer()->get('sylius.state_machine.adapter.symfony_workflow');
+ }
+}
diff --git a/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/WorkflowAdapter/OrderShippingWorkflowTest.php b/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/WorkflowAdapter/OrderShippingWorkflowTest.php
index 25650bc7ae..c28e7a354a 100644
--- a/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/WorkflowAdapter/OrderShippingWorkflowTest.php
+++ b/src/Sylius/Bundle/CoreBundle/Tests/Functional/StateMachine/WorkflowAdapter/OrderShippingWorkflowTest.php
@@ -35,9 +35,7 @@ final class OrderShippingWorkflowTest extends KernelTestCase
$this->assertSame($expectedStatus, $subject->getShippingState());
}
- /**
- * @test
- */
+ /** @test */
public function it_applies_ship_transition_if_order_is_partially_shipped(): void
{
$stateMachine = $this->getStateMachine();
diff --git a/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/OrderShipping/AfterOrderShippedListenerSpec.php b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/OrderShipping/AfterOrderShippedListenerSpec.php
index 86e1faa721..ccfeb82490 100644
--- a/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/OrderShipping/AfterOrderShippedListenerSpec.php
+++ b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/OrderShipping/AfterOrderShippedListenerSpec.php
@@ -28,10 +28,13 @@ final class AfterOrderShippedListenerSpec extends ObjectBehavior
function it_throws_an_exception_on_non_supported_subject(\stdClass $callback): void
{
- $this->shouldThrow(\InvalidArgumentException::class)->during('onOrderShippingCompleted', [new CompletedEvent($callback->getWrappedObject(), new Marking())]);
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('onOrderShippingCompleted', [new CompletedEvent($callback->getWrappedObject(), new Marking())])
+ ;
}
- function it_resolves_orders_after_order_being_shipped(
+ function it_resolves_order_state_after_order_being_shipped(
StateResolverInterface $stateResolver,
): void {
$order = new Order();
diff --git a/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/AssignShippingDateListenerSpec.php b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/AssignShippingDateListenerSpec.php
new file mode 100644
index 0000000000..a6896ee691
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/AssignShippingDateListenerSpec.php
@@ -0,0 +1,47 @@
+beConstructedWith($shippingDateAssigner);
+ }
+
+ function it_throws_an_exception_on_non_supported_subject(\stdClass $subject): void
+ {
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('__invoke', [new TransitionEvent($subject->getWrappedObject(), new Marking())])
+ ;
+ }
+
+ function it_resolves_order_state_after_order_being_shipped(
+ ShippingDateAssignerInterface $shippingDateAssigner,
+ ): void {
+ $shipment = new Shipment();
+ $event = new TransitionEvent($shipment, new Marking());
+
+ $shippingDateAssigner->assign($shipment)->shouldBeCalled();
+
+ $this->__invoke($event);
+ }
+}
diff --git a/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListenerSpec.php b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListenerSpec.php
new file mode 100644
index 0000000000..8d934ae192
--- /dev/null
+++ b/src/Sylius/Bundle/CoreBundle/spec/EventListener/Workflow/Shipment/ResolveOrderShipmentStateListenerSpec.php
@@ -0,0 +1,51 @@
+beConstructedWith($stateResolver);
+ }
+
+ function it_throws_an_exception_on_non_supported_subject(\stdClass $subject): void
+ {
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('__invoke', [new CompletedEvent($subject->getWrappedObject(), new Marking())])
+ ;
+ }
+
+ function it_resolves_order_shipment_state_after_order_being_shipped(
+ StateResolverInterface $stateResolver,
+ ): void {
+ $shipment = new Shipment();
+ $order = new Order();
+ $shipment->setOrder($order);
+
+ $event = new CompletedEvent($shipment, new Marking());
+
+ $stateResolver->resolve($order)->shouldBeCalled();
+
+ $this->__invoke($event);
+ }
+}
diff --git a/src/Sylius/Bundle/ShippingBundle/Provider/Calendar.php b/src/Sylius/Bundle/ShippingBundle/Provider/Calendar.php
index 150dbd8bdf..d2b29df8da 100644
--- a/src/Sylius/Bundle/ShippingBundle/Provider/Calendar.php
+++ b/src/Sylius/Bundle/ShippingBundle/Provider/Calendar.php
@@ -24,7 +24,7 @@ trigger_deprecation(
);
/**
- * @deprecated since Sylius 1.11 and will be removed in Sylius 2.0. Use {@see \Sylius\Calendar\Provider\Calendar} instead.
+ * @deprecated since Sylius 1.13 and will be removed in Sylius 2.0. Use {@see 'Symfony\Component\Clock\Clock'} instead.
*/
final class Calendar implements DateTimeProvider
{
diff --git a/src/Sylius/Bundle/ShippingBundle/Resources/config/workflow/state_machine.yaml b/src/Sylius/Bundle/ShippingBundle/Resources/config/workflow/state_machine.yaml
new file mode 100644
index 0000000000..289b675db0
--- /dev/null
+++ b/src/Sylius/Bundle/ShippingBundle/Resources/config/workflow/state_machine.yaml
@@ -0,0 +1,25 @@
+framework:
+ workflows:
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::GRAPH:
+ type: state_machine
+ marking_store:
+ type: method
+ property: shippingState
+ supports:
+ - Sylius\Component\Shipping\Model\ShipmentInterface
+ initial_marking: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ places:
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_SHIPPED
+ - !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CANCELLED
+ transitions:
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_CREATE:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CART
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_SHIP:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_SHIPPED
+ !php/const Sylius\Component\Shipping\ShipmentTransitions::TRANSITION_CANCEL:
+ from: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_READY
+ to: !php/const Sylius\Component\Shipping\Model\ShipmentInterface::STATE_CANCELLED
diff --git a/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonSlugController.php b/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonSlugController.php
index b48e9dfddb..72d043f66a 100644
--- a/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonSlugController.php
+++ b/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonSlugController.php
@@ -62,6 +62,12 @@ final class TaxonSlugController
$parentId = $request->query->get('parentId');
if (null !== $parentId) {
+ trigger_deprecation(
+ 'sylius/taxonomy-bundle',
+ '1.13',
+ 'Using "parentId" for slug generation is deprecated and will not be possible in 2.0. Use "parentCode" instead.',
+ );
+
return $this->taxonRepository->find($parentId);
}
diff --git a/src/Sylius/Component/Order/Modifier/OrderModifier.php b/src/Sylius/Component/Order/Modifier/OrderModifier.php
index ba6db458bc..de94d0a0df 100644
--- a/src/Sylius/Component/Order/Modifier/OrderModifier.php
+++ b/src/Sylius/Component/Order/Modifier/OrderModifier.php
@@ -35,6 +35,7 @@ final class OrderModifier implements OrderModifierInterface
public function removeFromOrder(OrderInterface $cart, OrderItemInterface $item): void
{
$cart->removeItem($item);
+
$this->orderProcessor->process($cart);
}