<?php declare(strict_types=1);
namespace ProxaInternationalPhoneNumber\Subscriber\Storefront;
use ProxaInternationalPhoneNumber\Components\Validator\PhoneCode;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\Event\DataMappingEvent;
use Shopware\Core\Framework\Validation\BuildValidationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Constraints\Length;
class CheckoutSubscriber implements EventSubscriberInterface
{
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
'framework.validation.address.create' => 'addValidation',
'framework.validation.address.update' => 'addValidation',
CustomerEvents::MAPPING_REGISTER_ADDRESS_BILLING => 'onMappingAddress',
CustomerEvents::MAPPING_REGISTER_ADDRESS_SHIPPING => 'onMappingAddress',
CustomerEvents::MAPPING_ADDRESS_CREATE => 'onMappingAddress'
];
}
/**
* @param BuildValidationEvent $event
* @return void
*/
public function addValidation(BuildValidationEvent $event): void
{
$data = $event->getData();
$this->addBillingAddressValidation($data, $event);
}
/**
* @param $data
* @param $event
* @return void
*/
private function addBillingAddressValidation($data, $event)
{
$address = !empty($data->get('billingAddress')) ? $data->get('billingAddress') : $event->getData();
if($address){
$phone = $address->get('phoneNumber');
$code = (int)$address->get('phoneNumberCode');
if ($phone && $code) {
$lengths = $this->getLengths($code);
$this->addDefinition($event, $lengths);
}
}
}
/**
* @param int $code
* @return array|null
*/
public function getLengths(int $code): ?array
{
$availableLength = $this->getPhoneNumberLength($code);
if ($availableLength) {
$minLength = current($availableLength);
$maxLength = end($availableLength);
return ['minLength' => $minLength, 'maxLength' => $maxLength];
}
return null;
}
/**
* @param int $code
* @return mixed
*/
public function getPhoneNumberLength(int $code)
{
$numberLengths = $this->getInternationalNumbersLengths();
return $numberLengths[$code] ?? null;
}
/**
* @param DataMappingEvent $event
* @return void
*/
public function onMappingAddress(DataMappingEvent $event): void
{
$address = $event->getOutput();
if ($event->getInput()->get('phoneNumberCode')) {
$address['customFields']['phoneNumberCode'] = $event->getInput()->get('phoneNumberCode');
}
$event->setOutput($address);
}
/**
* @param BuildValidationEvent $event
* @param $lengths
* @return void
*/
private function addDefinition(BuildValidationEvent $event, $lengths)
{
$event->getDefinition()->add('phoneNumberCode', new PhoneCode());
if ($lengths) {
$event->getDefinition()->add('phoneNumber', new Length(['min' => $lengths['minLength']]), new Length(['max' => $lengths['maxLength']]));
}
}
/**
* @return \int[][]
*/
public function getInternationalNumbersLengths(): array
{
$version1 = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
$version2 = [9, 10, 11, 12, 13, 14, 15];
$version3 = [8, 9, 10, 11, 12, 13, 14, 15];
$version4 = [7, 8, 9, 10, 11, 12, 13, 14, 15];
$version5 = [10, 11, 12, 13, 14, 15];
return [
49 => $version1,/*Deutschland (+49)*/
33 => $version2,/*Frankreich (+33)*/
39 => $version2,/*Italien (+39)*/
34 => $version2,/*Spanien (+34)*/
351 => $version2,/*Portugal (+351)*/
45 => $version3,/*Dänemark (+45)*/
358 => $version3,/*Finnland (+358)*/
46 => $version4,/*Schweden (+46)*/
41 => $version2,/*Schweiz (+41)*/
32 => $version2,/*Belgien (+32)*/
372 => $version4,/*Estland (+372)*/
386 => $version3,/*Slowenien (+386)*/
40 => $version5,/*Rumänien (+40)*/
420 => $version2,/*Tschechische Republik (+420)*/
421 => $version2,/*Slowakei (+421)*/
31 => $version3,/*Niederlande (+31)*/
30 => $version5,/*Griechenland (+30)*/
48 => $version1,/*Poland (+48)*/
370 => $version3,/*Litauen (+370)*/
43 => $version1,/*Austria (+43)*/
];
}
}