Skip to main content

Customize the Sylius Checkout

· 2 min read
Stephan Hochdörfer

There are multiple things one can customize in the Sylius checkout. For example, you can change the order of checkout steps or come up with a complete custom checkout flow. Or a bit simpler: You can remove or hide specific fields in the checkout process.

In this blog post, we dive into how to customize a form used in the checkout process. Specifically, I want to remove (or hide) the checkbox to activate a different address for the shipment.

Diving into the Sylius codebase, we see that the class \Sylius\Bundle\CoreBundle\Form\Type\Checkout\AddressType is responsible for building the form. Since Sylius is based on the Symfony framework, we can use a form type extension to modify any existing form field type.

This is done by extending the \Symfony\Component\Form\AbstractTypeExtension class like this:

<?php

declare(strict_types=1);

namespace App\Form\Extension;

use Sylius\Bundle\CoreBundle\Form\Type\Checkout\AddressType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;

class HideDifferentShippingAddressCheckbox extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('differentShippingAddress', HiddenType::class, [
'mapped' => false,
'required' => false,
'data' => 0,
'empty_data' => 0,
]);
}

public static function getExtendedTypes(): iterable
{
return [AddressType::class];
}
}

The getExtendedTypes() method defines the \Symfony\Component\Form\AbstractType types that should be modified. In the buildForm() method, you get the form builder injected that is used by the class you want to extend, allowing you to modify the form builder how you need to.

In this example, I decided not to remove the differentShippingAddress but to make it hidden via the Symfony\Component\Form\Extension\Core\Type\HiddenType. This will make sure any existing logic relying on the field won't break.

The mapped option needs to be set to false to let Doctrine ignore the field when mapping the form to the entity, and we set the data and empty_data to a value of 0 to indicate the checkbox is not checked.

Lastly, the service needs to be configured in the ./config/services.yaml file like this:

App\Form\Extension\HideDifferentShippingAddressCheckbox:
class: App\Form\Extension\HideDifferentShippingAddressCheckbox
tags:
- { name: 'form.type_extension', extended_type: 'Sylius\Bundle\CoreBundle\Form\Type\Checkout\AddressType' }