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.
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.
Be the first to comment.