<?php declare(strict_types=1);
namespace RhiemExtendedRegistration\Subscriber\Frontend;
use RhiemExtendedRegistration\Components\Services\RegistrationGroupService;
use RhiemExtendedRegistration\Entities\Attribute\AttributeEntity;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\Event\DataMappingEvent;
use Shopware\Core\Framework\Validation\DataValidator;
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
use Symfony\Component\Validator\Constraints\NotBlank;
use Shopware\Core\Framework\Validation\DataValidationDefinition;
class CustomerValidation implements EventSubscriberInterface
{
/**
* @var ContainerInterface
*/
private ContainerInterface $container;
/**
* @var RegistrationGroupService
*/
private RegistrationGroupService $registrationGroupService;
/**
* @var DataValidator $dataValidator
*/
private DataValidator $dataValidator;
/**
* CustomerValidation constructor.
*
* @param ContainerInterface $container
* @param RegistrationGroupService $registrationGroupService
* @param DataValidator $dataValidator
*/
public function __construct(
ContainerInterface $container,
RegistrationGroupService $registrationGroupService,
DataValidator $dataValidator
)
{
$this->container = $container;
$this->registrationGroupService = $registrationGroupService;
$this->dataValidator = $dataValidator;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::MAPPING_REGISTER_CUSTOMER => 'onValidateCustomer'
];
}
/**
* @param DataMappingEvent $event
*/
public function onValidateCustomer(DataMappingEvent $event): void
{
$data = $event->getInput()->all();
$definition = new DataValidationDefinition;
$salesChannelId = $event->getContext()->getSource()->getSalesChannelId();
try {
$registrationAttributes = $this->registrationGroupService->getRegistrationAttributes($salesChannelId);
} catch (\Exception $e) {
$registrationAttributes = [];
}
if (count($registrationAttributes) > 0) {
$additionalValidation = new DataValidationDefinition('rhiem.additional.registration.fields');
foreach ($registrationAttributes as $attribute) {
call_user_func_array(
[$additionalValidation, 'add'],
$this->createValidationParameters($attribute)
);
}
$definition->addSub('Rhiem_Additional_Registration_Fields_Personal', $additionalValidation);
}
try {
$this->dataValidator->validate($data, $definition);
} catch (ConstraintViolationException $formViolations) {
throw $formViolations;
}
}
/**
* @param AttributeEntity $attribute
*
* @return array
*/
private function createValidationParameters(AttributeEntity $attribute): array
{
$return = [];
$return[] = $attribute->getId();
if ($attribute->getRequired()) {
$return[] = new NotBlank();
}
if ($attribute->getMinMax()) {
$lengthOptions = ["min" => $attribute->getValueMin(), "max" => $attribute->getValueMax() ?: null];
if (!$attribute->getRequired()) {
$lengthOptions['allowEmptyString'] = true;
}
$return[] = new Length($lengthOptions);
}
return $return;
}
}