Hello. i'm having problems to override states in sylius_order_checkout process. First thing i tried is follow instructions, but placing the file where it says, it doesn't seem to have any effect in the configurations...
Second thing i tried is to override this from my own bundle. so, i added a sylius_checkout_order.yml there and imported it from my config.yml. Just for testing purposes i added dummy values to the file. The plan is remove the shipping_selected state, so i went like
winzou_state_machine:
sylius_order_checkout:
class: my_class
property_path: checkoutState
graph: sylius_order_checkout_my_graph
state_machine_class: "%sylius.state_machine.class%"
states:
cart: ~
addressed: ~
payment_selected: ~
completed: ~
Now the problem: While the class and graph values are overrided, it looks i cannot delete that shipping_selected stated. doing a debug:container i can see this
winzou_state_machine:
sylius_order_checkout:
class: my_class
property_path: checkoutState
graph: sylius_order_checkout_my_graph
state_machine_class: Sylius\Component\Resource\StateMachine\StateMachine
states:
cart: null
addressed: null
shipping_selected: null
payment_selected: null
completed: null
As you see, shipping_selected is there and i can't find the way to remove it. just for testing i modified my yml to be like
winzou_state_machine:
sylius_order_checkout:
class: my_class
property_path: checkoutState
graph: sylius_order_checkout_my_graph
state_machine_class: "%sylius.state_machine.class%"
states:
a_dummy_state: ~
Doing the debug again i can see
winzou_state_machine:
sylius_order_checkout:
class: my_class
property_path: checkoutState
graph: sylius_order_checkout_my_graph
state_machine_class: Sylius\Component\Resource\StateMachine\StateMachine
states:
cart: null
addressed: null
shipping_selected: null
payment_selected: null
completed: null
a_dummy_state: null
So, looks that's something, and maybe not in the Sylius side, is merging the states isteand of replacing them?
Or am i missing something here?
Thanks a lot.
Hi @crevillo!
Yes. This is a known issue. We are not able to fully override state machines. The configurations are merged. And the problem lays rather in the state machine bundle than in Sylius itself :<
Although you can disable existing callbacks to certain transitions, and modify the graph, the old graph with its states and transition will still be there.
@TheMadeleine but if we "override" the whole file by placing a new one in app/... (as described here) shouldn't it work?
@michalmarcinkowski it doesn't as far i see. By the way, in the documentation your are told to that because is a standard procedure of overriding configs in Symfony, but if you open the symfony doc, in that page you are told to create a bundle having a parent in order to customize settings like this... don't you?
@crevillo I had the same issue. This is my way of solution. I overwrite the getContainerLoader method in app/AppKernel.php like this:
protected function getContainerLoader(ContainerInterface $container)
{
$locator = new FileLocator($this, $this->getRootDir() . '/Resources');
$resolver = new LoaderResolver(array(
new XmlFileLoader($container, $locator),
new YamlFileLoader($container, $locator),
new IniFileLoader($container, $locator),
new PhpFileLoader($container, $locator),
new DirectoryLoader($container, $locator),
new ClosureLoader($container),
));
return new DelegatingLoader($resolver);
}
After the instruction will work correctly.
this indeed seems to work. can we be sure this has no unwanted side effects?
hi , i've did all the instructions and i've overrided the getContainerLoader method in app/AppKernel.php and when i click next in the payment step it keeps redirect me to payment step ? what can be the problem
hmm, overriding the the getContainerLoaded and following the instructions worked for me perfectly....
i'm using sylius beta
@yosriMekni, are you sure you haven't any state machine overrides?
let me add something. i have indeed to change some things from the doc, even i don't know if this is related where the problem @yosriMekni is having.
First, in the app/Resources/SyliusShopBundle/config/routing/checkout.yml i needed to change the form definitions. for instance, where it reads
form:
type: sylius_checkout_address
i had to add the full form type class type there to make it work.
Second, in the last part of this file, when trying to make the payment (i'm using a custom payum gateway, btw)
redirect:
route: sylius_shop_order_pay
parameters:
paymentId: expr:service('sylius.context.cart').getCart().getLastNewPayment().getId()
i had to modify the parameters part leaving it like
redirect:
route: sylius_shop_order_pay
parameters:
tokenValue: resource.tokenValue
Btw, this last part is what the sylius file has now. Same goes for the form definitions
https://github.com/Sylius/Sylius/blob/master/src/Sylius/Bundle/ShopBundle/Resources/config/routing/checkout.yml#L95
Maybe we should update the doc...
i've just removed shipping state as the docs says :
app/syliuscorebundle/config/app/state_machine/sylius_order_checkout.yml :
winzou_state_machine:
sylius_order_checkout:
class: "%sylius.model.order.class%"
property_path: checkoutState
graph: sylius_order_checkout
state_machine_class: "%sylius.state_machine.class%"
states:
cart: ~
addressed: ~
payment_selected: ~
completed: ~
transitions:
address:
from: [cart, addressed, payment_selected]
to: addressed
select_payment:
from: [addressed, payment_selected]
to: payment_selected
complete:
from: [payment_selected]
to: completed
callbacks:
after:
sylius_process_cart:
on: ["address", "select_payment"]
do: ["@sylius.order_processing.order_processor", "process"]
args: ["object"]
sylius_create_order:
on: ["complete"]
do: ["@sm.callback.cascade_transition", "apply"]
args: ["object", "event", "'create'", "'sylius_order'"]
sylius_save_checkout_completion_date:
on: ["complete"]
do: ["object", "completeCheckout"]
args: ["object"]
app/Resources/syliusshopbundle/config/routing/checkout.yml:
```yaml
sylius_shop_checkout_start:
path: /
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: sylius_shop_checkout_address
sylius_shop_checkout_address:
path: /address
methods: [GET, PUT]
defaults:
_controller: sylius.controller.order:updateAction
_sylius:
event: address
flash: false
template: SyliusShopBundle:Checkout:address.html.twig
form:
type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\AddressType
options:
customer: expr:service('sylius.context.customer').getCustomer()
repository:
method: find
arguments:
- "expr:service('sylius.context.cart').getCart()"
state_machine:
graph: sylius_order_checkout
transition: address
redirect:
route: sylius_shop_checkout_select_payment
parameters: []
sylius_shop_checkout_select_payment:
path: /select-payment
methods: [GET, PUT]
defaults:
_controller: sylius.controller.order:updateAction
_sylius:
event: payment
flash: false
template: SyliusShopBundle:Checkout:selectPayment.html.twig
form: Sylius\Bundle\CoreBundle\Form\Type\Checkout\SelectPaymentType
repository:
method: find
arguments:
- "expr:service('sylius.context.cart').getCart()"
state_machine:
graph: sylius_order_checkout
transition: select_payment
redirect:
route: sylius_shop_checkout_complete
parameters: []
sylius_shop_checkout_complete:
path: /complete
methods: [GET, PUT]
defaults:
_controller: sylius.controller.order:updateAction
_sylius:
event: complete
flash: false
template: SyliusShopBundle:Checkout:complete.html.twig
repository:
method: find
arguments:
- "expr:service('sylius.context.cart').getCart()"
state_machine:
graph: sylius_order_checkout
transition: complete
redirect:
route: sylius_shop_order_pay
parameters:
tokenValue: resource.tokenValue
form:
type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType
options:
validation_groups: 'sylius_checkout_complete```
it worked , its a problem of cache , knowing that i've cleared it yesterday and nothing changed , and i've did it again now and it worked , confusing !!
An other problem appears , the order passed with total shipping costs = 20.64 , at the complete step !!
@yosriMekni is it wrong?
this make sense, afaik, if you still have some shipping method enabled for your channel and for the zone.
by default, when you add the product sylius adds a shipment if it finds one.
let the others correct me if i'm wrong, but i think yo need to delete every shipment method from your shop.
if i remove the shipping step it should passe the order without shipping costs .
i don't want to delete the shipping methods from my store because i'm tying to achieve that some products needs to be shipped and others not
*excuse my english
Then you need more work, You need to work in the OrderProcessors. These ones are executed in every step or your process. This one assigns a default shipment to your order/cart as soon as it's created. you'll probably need to override this so the method doesn't get added to the other.
@yosriMekni The solution for your problem is here: #7215. The shipment is still created for the order, even if you skip this step.
after removing the shipping step ,i've created an other channel with code 'tn_store' and i've added a product to it , and when i try to add the product to the cart and exception appears in the ajax call :
the url : web/app_dev.php/ajax/cart/add?productId=62
the exeption : Notice: Undefined index: tn_store / 500 Internal Server Error - ContextErrorException
stack trace :

hi again. i've just exposed this problem in a symfony-devs channel and somebody has pointed me to http://symfony.com/doc/current/components/config/definition.html#merging-options.
Do you think this can suitable? i guess this should added in the sylius bundle configuration... i'll give a try to it and let you know.
@c-revillo Looks really promising. Looking forward for your feedback on it! 馃憤
Still stumbled on this. i found another way to make the override part remove the 'shipping_selected' method but:
1) is not the method we have in the doc
2) if involves a change in the winzou_state_machine bundle.
So, what has worked for me is to add the winzow_state_machine part directly in the app/config/config.yml file, just aboves the import parts.
also, i needed to manually modify this file adding a new line there, like
$configNode
->arrayNode('states')
->performNoDeepMerging() // added line
->useAttributeAsKey('name')
->prototype('scalar')
->end()
;
with this, doing the debug container part i can't see the shipping_select anymore. but i need to recheck in this is not doing anything nasty with the rest of defined winzow_state_machines...
So, should we ping the Winzow state machine creator(s) to see if they can at least at that line to their code?
Most helpful comment
@crevillo I had the same issue. This is my way of solution. I overwrite the getContainerLoader method in app/AppKernel.php like this:
After the instruction will work correctly.