Add fields to Back Office forms

Edit on GitHub

This document explains how to add fields to Back Office forms. The email field is used as an example.

Add a contact email field to the store settings in the Back Office

To add the contactEmail field to StoreContextApplicationTransfer and configure it for each application in the store, follow the steps:

  1. Add the field to StoreContextApplicationTransfer:

src/Pyz/Shared/StoreContext/Transfer/store_context.transfer.xml

<?xml version="1.0"?>
<transfers xmlns="spryker:transfer-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="spryker:transfer-01 http://static.spryker.com/transfer-01.xsd">
    <transfer name="StoreApplicationContext" strict="true">
        <property name="contactEmail" type="string"/>
    </transfer>
</transfers>

  1. Add validation rules for the field:

src/Pyz/Zed/StoreContext/Business/Validator/Rule/СontactEmailRule.php


namespace Pyz\Zed\StoreContext\Business\Validator\Rule;

use Generated\Shared\Transfer\StoreContextTransfer;
use Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface;

class СontactEmailRule implements StoreContextValidatorRuleInterface
{
    /**
     * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer
     *
     * @return array<\Generated\Shared\Transfer\ErrorTransfer>
     */
    public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array
    {
        $storeApplicationContextTransfers = $storeContextTransfer->getApplicationContextCollectionOrFail()->getApplicationContexts();

        foreach ($storeApplicationContextTransfers as $storeApplicationContextTransfer) {
            $contactEmail = $storeApplicationContextTransfer->getContactEmail();

            if ($contactEmail === null) {
                continue;
            }

            // Add your custom validation logic here
        }

        return [];
    }
}

  1. Add a rule to the validator by extending StoreContextBusinessFactory:
src/Pyz/Zed/StoreContext/Business/StoreContextBusinessFactory.php
namespace Pyz\Zed\StoreContext\Business;

use Pyz\Zed\StoreContext\Business\Validator\Rule\СontactEmailRule;
use Spryker\Zed\StoreContext\Business\StoreContextBusinessFactory as SprykerStoreContextBusinessFactory;
use Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface;

class StoreContextBusinessFactory extends SprykerStoreContextBusinessFactory
{
    /**
     * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface
     */
    public function createСontactEmailRule(): StoreContextValidatorRuleInterface
    {
        return new СontactEmailRule();
    }

    /**
     * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface>
     */
    public function getDefaultValidatorRules(): array
    {
        $rules = parent::getDefaultValidatorRules();

        $rules[] = $this->createСontactEmailRule();

        return $rules;
    }

    /**
     * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface>
     */
    public function getCreateValidatorRules(): array
    {
        $rules = parent::getDefaultValidatorRules();

        $rules[] = $this->createСontactEmailRule();

        return $rules;
    }

    /**
     * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface>
     */
    public function getUpdateValidatorRules(): array
    {
        $rules = parent::getDefaultValidatorRules();

        $rules[] = $this->createСontactEmailRule();

        return $rules;
    }
}
  1. Extend the StoreContextForm form with the contactEmail field:
src/Pyz/Zed/StoreContextGui/Communication/Form/StoreContextForm.php

namespace Pyz\Zed\StoreContextGui\Communication\Form;

use Spryker\Zed\StoreContextGui\Communication\Form\StoreContextForm as SprykerStoreContextForm;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;

class StoreContextForm extends SprykerStoreContextForm
{
    /**
     * @var string
     */
    protected const FIELD_SUPPORT_CONTACT_EMAIL = 'contactEmail';

    /**
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
     * @param array<string, mixed> $options
     *
     * @return void
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        parent::buildForm($builder, $options);

        $this->addContactEmailField($builder, $options);
    }

    /**
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
     * @param array<string, mixed> $options
     *
     * @return \Spryker\Zed\StoreContextGui\Communication\Form\StoreContextForm
     */
    protected function addContactEmailField(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(static::FIELD_SUPPORT_CONTACT_EMAIL, EmailType::class, [
                'label' => 'Contact Email',
                'constraints' => $this->createEmailConstraints(),
            ]);

        return $this;
    }

    /**
     * @return array
     */
    protected function createEmailConstraints(): array
    {
        return  [
            new Email(),
        ];
    }
}

  1. Use StoreContextForm , which is extended with the field, in the extended StoreContextGuiCommunicationFactory class:

src/Pyz/Zed/StoreContextGui/Communication/StoreContextGuiCommunicationFactory.php


namespace Pyz\Zed\StoreContextGui\Communication;

use Pyz\Zed\StoreContextGui\Communication\Form\StoreContextForm;
use Spryker\Zed\StoreContextGui\Communication\StoreContextGuiCommunicationFactory as SprykerStoreContextGuiCommunicationFactory;

class StoreContextGuiCommunicationFactory extends SprykerStoreContextGuiCommunicationFactory
{
    /**
     * @return string
     */
    public function getStoreContextFormClass(): string
    {
        return StoreContextForm::class;
    }
}
Verification
  1. In the Back Office, go to Administration>Stores.
  2. On the Stores page, click Edit store next to a store.
  3. On the Edit store page, click the Settings tab. In the Settings tab, make sure the following applies:
  • The default block with the APPLICATION value set to Default is displayed.
  • The CONTACT EMAIL field is displayed.
  • The CONTACT EMAIL field is required and accepts only valid email addresses.

contact-email-field

  1. For CONTACT EMAIL, enter an email address.
  2. Click Save. Make sure the email address is saves successfully.

Configure access to the email field

This section explains how to extend StoreTransfer and extract a field using a plugin to access contactEmail field directly from the StoreTransfer. The contact email field is used as an example.

  1. Add the contactEmail field to StoreTransfer:

src/Pyz/Shared/StoreContextStorage/Transfer/store_context_storage.transfer.xml

<?xml version="1.0"?>
<transfers xmlns="spryker:transfer-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="spryker:transfer-01 http://static.spryker.com/transfer-01.xsd">
    <transfer name="Store">
        <property name="contactEmail" type="string"/>
    </transfer>
</transfers>


  1. To expand StoreTransfer, implement the following plugin:

src/Pyz/Client/StoreContextStorage/Plugin/Store/ContactEmailStoreStorageStoreExpanderPlugin.php

namespace Pyz\Client\StoreContextStorage\Plugin\Store;

use Generated\Shared\Transfer\StoreTransfer;
use Spryker\Client\Kernel\AbstractPlugin;
use Spryker\Client\StoreExtension\Dependency\Plugin\StoreExpanderPluginInterface;

class ContactEmailStoreStorageStoreExpanderPlugin  extends AbstractPlugin implements StoreExpanderPluginInterface
{
    /**
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
     *
     * @return \Generated\Shared\Transfer\StoreTransfer
     */
    public function expand(StoreTransfer $storeTransfer): StoreTransfer
    {
        if ($storeTransfer->getApplicationContextCollection() === null) {
            return $storeTransfer;
        }

        foreach ($storeTransfer->getApplicationContextCollectionOrFail()->getApplicationContexts() as $storeApplicationContextTransfer) {
            if ($storeApplicationContextTransfer->getApplication() === APPLICATION && $storeApplicationContextTransfer->getContactEmail() !== null) {
                return $storeTransfer->setContactEmail($storeApplicationContextTransfer->getContactEmail());
            }

            if ($storeApplicationContextTransfer->getApplication() === null) {
                $storeTransfer->setContactEmail($storeApplicationContextTransfer->getContactEmail());
            }
        }

        return $storeTransfer;
    }
}


  1. Register the plugin in StoreDependencyProvider:

src/Pyz/Client/Store/StoreDependencyProvider.php

namespace Pyz\Client\Store;

use Pyz\Client\StoreContextStorage\Plugin\Store\ContactEmailStoreStorageStoreExpanderPlugin;
use Spryker\Client\Store\StoreDependencyProvider as SprykerStoreDependencyProvider;

class StoreDependencyProvider extends SprykerStoreDependencyProvider
{
    /**
     * @return array<\Spryker\Client\StoreExtension\Dependency\Plugin\StoreExpanderPluginInterface>
     */
    protected function getStoreExpanderPlugins(): array
    {
        return [
            new ContactEmailStoreStorageStoreExpanderPlugin(),
        ];
    }
}

Now you can use the contactEmail field in StoreTransfer.