Reading list Switch to dark mode

    How to config the custom field with default entity

    Updated 30 December 2021

    In this blog, you are going to learn “How to config the custom field with default entity.”
    I hope you know the directory structure of Shopware 6 plugin, if you don’t know, see here- https://docs.shopware.com/en/shopware-platform-dev-en/internals/directory-structure.

    The purpose of custom field is used to add the additional information in the entity, so that we can used that information according to our need. It allows you to extend entities.

    For adding the custom field, you can write the query in the migration file. In my case, I write in the base file of plugin under install function of plugin.

    WebkulTest.php
    public function install(InstallContext $installContext): void
        {
            $customFieldRepository = $this->container->get('custom_field_set.repository');
            $customFieldData = $customFieldRepository->search((new Criteria())->addFilter(new EqualsFilter('name','sample_task')), $installContext->getContext())->first();
            if (!$customFieldData) {
                $customFieldRepository->create([
                    [
                        'name' => 'sample_task',
                        'config' => [
                            'label' => [
                                'en-GB' => 'Sample Task',
                                'de-DE' => 'Sample Task'
                            ]
                        ],
                        'customFields' => [
                            [
                                'name' => 'sample_task_floor',
                                'type' => CustomFieldTypes::INT,
                                'config' => [
                                    'label' => [
                                    'en-GB' => 'Floor',
                                    'de-DE' => 'Floor'
                                    ],
                                    'type' => 'number',
                                    'componentName'=> 'sw-field',
                                    'customFieldType'=> 'number',
                                ]
                            ]
                        ],
                    
                        'relations' => [
                            [
                            'entityName' => 'customer_address'
                            ]
                        ]
                    ]
                ], $installContext->getContext());
            }
        
        }

    In the above code, add the custom field for floor value which is type of number with the relation of customer address table which means floor field is linked/relation with customer address table.

    It automatically add the floor field under the custom field section of customer address in the admin.Now we need to save the floor value from the storefront section. So override the address-form.html.twig file and add the input field for floor.

    Searching for an experienced
    Shopware Company ?
    Find out More
    address-form.html.twig
    {% sw_extends '@Storefront/storefront/component/address/address-form.html.twig' %}
    
    {% block component_address_form_street
    %}
    {% block component_address_form_floor %}
        <div class="form-group col-md-6">
            {% if formViolations.getViolations("/floor") is not empty %}
                {% set violationPath = "/floor" %}
            {% elseif formViolations.getViolations("/#{prefix}/floor") is not empty %}
                {% set violationPath = "/#{prefix}/floor" %}
            {% endif %}
    
            {% block component_address_form_floor_label %}
                <label class="form-label"
                    for="{{ idPrefix ~ prefix }}AddressFloor">
                    Floor{{ "general.required"|trans|sw_sanitize }}
                </label>
            {% endblock %}
        
            {% block component_address_form_floor_input %}
                <input type="number"
                    class="form-control{% if violationPath %} is-invalid{% endif %}"
                    id="{{ idPrefix ~ prefix }}AddressFloor"
                    placeholder="Enter the Floor of building"
                    name="{{ prefix }}[floor]"
                    value="{{ data.get('customFields')['sample_task_floor'] }}"
                    required="required">
            {% endblock %}
    
            {% block component_address_form_floor_input_error %}
                {% if violationPath %}
                    {% sw_include '@Storefront/storefront/utilities/form-violation.html.twig' %}
                {% endif %}
            {% endblock %}
        </div>
        {% endblock %}
        {{parent()}}
    {% endblock %}

    In above code, extends the address-form.html.twig and override the block component_address_form_street and add input field for floor same as the address form is implement.

    Now one part is remaining that is how to save the floor value in the custom field of customer address table.
    We need to use the event subscriber of the shopware.

    TestSubscriber.php
    <?php declare(strict_types=1);
    
    namespace Sample\Task\Subscriber;
    
    use Shopware\Core\Checkout\Customer\CustomerEvents;
    use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
    use Shopware\Core\Checkout\Customer\Event\CustomerLogoutEvent;
    use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
    use Shopware\Core\Content\Product\ProductEvents;
    use Shopware\Core\Framework\Context;
    use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
    use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
    use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class RegisterSubscriber implements EventSubscriberInterface
    {   
        /**
         * @var ContainerInterface
         */
        private $container;
    
        /**
         * @var EntityRepositoryInterface
         */
        protected $customerAddressRepository;
    
        public function __construct(ContainerInterface $container, EntityRepositoryInterface $customerAddressRepository)
        {
            $this->container = $container;
            $this->customerAddressRepository = $customerAddressRepository;
        }
    
        public static function getSubscribedEvents(): array
        {
            return [
                CustomerEvents::CUSTOMER_ADDRESS_WRITTEN_EVENT => 'addFloor',
            ];
        }
        public function addFloor(EntityWrittenEvent $event) {
            $requestStack = $this->container->get('request_stack');
            $request = $requestStack->getCurrentRequest();
            if ($request->request->get('address')) {
                $floor = $request->request->get('address')['floor'];
            } else if ($request->request->get('shippingAddress')) {
                $floor = $request->request->get('shippingAddress')['floor'];
            } else {
                $floor = $request->request->get('billingAddress')['floor'];
            }
          
            if ($event->getWriteResults() && $floor) {
                foreach($event->getWriteResults() as $data) {
                    if ($data->getExistence() !== null && $data->getExistence()->exists()) {
                        break;
                    }
                    $payload = $data->getPayload();
                    if ($payload) {
                        $operation = $data->getOperation();                    
                        $id = $payload['id'];
                        $customField = array("sample_task_floor" => (int)$floor);
                        $customerAddress = [
                            'id' => $id,
                            'customFields' => $customField
                        ];
                        
                        $this->customerAddressRepository->upsert([$customerAddress], Context::createDefaultContext());
    
                    }
                }
            }
        }
    }

    In the above code, we used the CUSTOMER_ADDRESS_WRITTEN_EVENT of CustomerEvents. In the case whenever the address is written in the table that event is called and we get all the value of customer address. Now how to get the floor value for that we used the request stack class.

    From request stack we get current request of the shopware, in there we also get the floor value which save from the storefront and we have id of customer address table from the event and floor value.Now persist the floor value in the custom field of customer address table as you can seen in the above code.

    Hope it will help you. Thanks for reading. Happy Coding 🙂
    Thank You.

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home