Skip to content

Implementing EntityFormModifierInterface

Most customizations start with implementing an EntityFormModifierInterface.

For modifiers allow adding, removing and manipulating form elements.

The interface is very simple:

<?php
namespace Hyva\Checkout\Model\Form;

interface EntityFormModifierInterface
{
    public function apply(EntityFormInterface $form): EntityFormInterface;
}

The purpose of the apply method is to register hook callbacks on the form.

Registering hooks callbacks

The following example assumes there already is a custom module for the class. We will use the Magento module name Hyva_Example.

In the implementation of the apply method, callback methods are registered as "modification listeners".
Registering a listener requires three arguments:

  • An identifier
    This identifier string is used to refer to the listener in case it needs to be removed again.

  • A modification hook name
    This string determines when the callback will be executed.

  • A callback
    Anything PHP considers callable.
    The arguments for the callback depend on the modification hook.

public function apply(EntityFormInterface $form): EntityFormInterface
{
    $form->registerModificationListener(
        'myCallbackIdentifier',        // the callback identifier
        'form:build',                  // the modification name
        [$this, 'applyMyModification'] // the callback
    );

    return $form;
}

public function applyMyModification(EntityFormInterface $form)
{
    // code to apply my customization
}
Since 1.1.21

On many occasions, it is essential to first verify whether a specific field you wish to modify actually exists before attempting any changes. Since version 1.1.21, we have introduced several convenient helper methods to the form, namely modifyFields(), modifyField(), modifyElements(), and modifyElement(). These methods eliminate the need for repetitive boilerplate code, as they automatically check for the existence of fields or elements before applying your modifications. The relevant field or element is then passed as an argument to your callback.

See the form modification hooks table for available modification hooks.

Registering the form modifier

The form modifier is registered for the entity form it should be applied to in etc/frontend/di.xml:

<type name="Hyva\Checkout\Model\Form\EntityForm\EavAttributeBillingAddressForm">
    <arguments>
        <argument name="entityFormModifiers" xsi:type="array">
            <item name="hyva_example" xsi:type="object" sortOrder="1000">
                Hyva\Example\Model\BillingAddress\MyBillingAddressFormModifier
            </item>
        </argument>
    </arguments>
</type>

This will then cause the modifiers apply method to be called, where the hook callbacks are specified.

Choosing a sortOrder value

The order of items in the entityFormModifiers array is important. If two modifiers start manipulating the same field properties, the last one to execute may change any property set by an earlier modifier.

The sortOrder attribute can be used to give a modifier a higher or lower priority.
Items are processed in ascending sortOrder, meaning a modifier with sortOrder="1000" will be processed before a modifier with sortOrder="1100".

Modifiers that are executed later can change the values of modifiers that run earlier. Thus, items with a higher sortOrder have a higher priority.

Info

In order for the Magento DI configuration to reliably sort arrays, it is important every item has a sortOrder attribute.

However, unless there is another modifier that is interfering with your modifier is doing, there is no sensible default value. For that reason, our recommendation to use sortOrder="1000" as the default. This will ensure your modifier is executed after the Hyvä checkout core modifiers that have sort orders in the 0-999 range.

Modifier conflict resolution

If there is a conflict between two modifiers that needs to be resolved, add a higher sortOrder to one item, so it will become prioritized and the conflict can be resolved: