local/modules/ForcePhone/EventListeners/ForcePhoneEventListener.php line 77

  1. <?php
  2. /*
  3.  * This file is part of the Thelia package.
  4.  * http://www.thelia.net
  5.  *
  6.  * (c) OpenStudio <info@thelia.net>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. /*      Copyright (c) OpenStudio                                                     */
  12. /*      email : dev@thelia.net                                                       */
  13. /*      web : http://www.thelia.net                                                  */
  14. /*      For the full copyright and license information, please view the LICENSE.txt  */
  15. /*      file that was distributed with this source code.                             */
  16. namespace ForcePhone\EventListeners;
  17. use ForcePhone\Constraints\AtLeastOnePhone;
  18. use ForcePhone\Constraints\CheckPhoneFormat;
  19. use ForcePhone\ForcePhone;
  20. use libphonenumber\PhoneNumberFormat;
  21. use libphonenumber\PhoneNumberUtil;
  22. use OpenApi\Events\ModelValidationEvent;
  23. use OpenApi\Model\Api\Address;
  24. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  25. use Symfony\Component\Form\Extension\Core\Type\TextType;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\RequestStack;
  28. use Symfony\Component\Validator\Constraints\NotBlank;
  29. use Thelia\Core\Event\TheliaEvents;
  30. use Thelia\Core\Event\TheliaFormEvent;
  31. use Thelia\Core\Translation\Translator;
  32. use Thelia\Log\Tlog;
  33. use Thelia\Model\CountryQuery;
  34. use Thelia\Model\Event\AddressEvent;
  35. use Thelia\Model\Event\CustomerEvent;
  36. /**
  37.  * Class ForcePhoneEventListener.
  38.  *
  39.  * @author Etienne Perriere <eperriere@openstudio.fr>
  40.  */
  41. class ForcePhoneEventListener implements EventSubscriberInterface
  42. {
  43.     protected ?Request $request;
  44.     /**
  45.      * ForcePhoneEventListener constructor.
  46.      */
  47.     public function __construct(RequestStack $requestStack)
  48.     {
  49.         $this->request $requestStack->getCurrentRequest();
  50.     }
  51.     /**
  52.      * @return array
  53.      */
  54.     public static function getSubscribedEvents()
  55.     {
  56.         return [
  57.             TheliaEvents::FORM_AFTER_BUILD.'.thelia_customer_create' => ['forcePhoneInput'128],
  58.             TheliaEvents::FORM_AFTER_BUILD.'.thelia_customer_update' => ['forcePhoneInput'128],
  59.             TheliaEvents::FORM_AFTER_BUILD.'.thelia_address_update' => ['forcePhoneInput'128],
  60.             TheliaEvents::FORM_AFTER_BUILD.'.thelia_address_creation' => ['forcePhoneInput'128],
  61.             CustomerEvent::POST_INSERT => ['customerPhoneUpdate'125],
  62.             CustomerEvent::POST_UPDATE => ['customerPhoneUpdate'125],
  63.             AddressEvent::PRE_INSERT => ['addressPhoneUpdate'125],
  64.             AddressEvent::PRE_UPDATE => ['addressPhoneUpdate'125],
  65.             ModelValidationEvent::MODEL_VALIDATION_EVENT_PREFIX.'address' => ['validateOpenApiAddress'125],
  66.         ];
  67.     }
  68.     public function forcePhoneInput(TheliaFormEvent $event): void
  69.     {
  70.         $constraints = [];
  71.         if (ForcePhone::getConfigValue('force_one'false)) {
  72.             $constraints[] = new AtLeastOnePhone();
  73.         }
  74.         $validateFormat ForcePhone::getConfigValue('validate_format'false);
  75.         if ($validateFormat) {
  76.             $constraints[] = new CheckPhoneFormat();
  77.         }
  78.         $forcePhone ForcePhone::getConfigValue('force_phone'false);
  79.         if (!empty($constraints) || $forcePhone) {
  80.             $event->getForm()->getFormBuilder()
  81.                 ->remove('phone')
  82.                 ->add(
  83.                     'phone',
  84.                     TextType::class,
  85.                     [
  86.                         'constraints' => $forcePhone array_merge([new NotBlank()], $constraints) : $constraints,
  87.                         'label' => Translator::getInstance()->trans('Phone'),
  88.                         'label_attr' => ['for' => 'phone'],
  89.                         'required' => $forcePhone,
  90.                     ]
  91.                 );
  92.         }
  93.         $forceCellPhone ForcePhone::getConfigValue('force_cellphone'false);
  94.         if (!empty($constraints) || $forceCellPhone) {
  95.             $event->getForm()->getFormBuilder()
  96.                 ->remove('cellphone')
  97.                 ->add(
  98.                     'cellphone',
  99.                     TextType::class,
  100.                     [
  101.                         'constraints' => $forceCellPhone array_merge([new NotBlank()], $constraints) : $constraints,
  102.                         'label' => Translator::getInstance()->trans('Cellphone'),
  103.                         'label_attr' => ['for' => 'cellphone'],
  104.                         'required' => $forceCellPhone,
  105.                     ]
  106.                 );
  107.         }
  108.     }
  109.     public function addressPhoneUpdate(AddressEvent $addressEvent): void
  110.     {
  111.         $validateFormat ForcePhone::getConfigValue('validate_format'false);
  112.         if ($validateFormat) {
  113.             $address $addressEvent->getModel();
  114.             try {
  115.                 $phoneUtil PhoneNumberUtil::getInstance();
  116.                 if (!empty($address->getPhone())) {
  117.                     $phoneNumberProto $phoneUtil->parse($address->getPhone(), $address->getCountry()->getIsoalpha2());
  118.                     $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  119.                     if ($isValid) {
  120.                         $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  121.                         $address->setPhone($phone);
  122.                     }
  123.                 }
  124.                 if (!empty($address->getCellphone())) {
  125.                     $phoneNumberProto $phoneUtil->parse($address->getCellphone(), $address->getCountry()->getIsoalpha2());
  126.                     $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  127.                     if ($isValid) {
  128.                         $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  129.                         $address->setCellphone($phone);
  130.                     }
  131.                 }
  132.             } catch (\Exception $exception) {
  133.                 Tlog::getInstance()->warning('Error on update phone format');
  134.             }
  135.         }
  136.     }
  137.     public function customerPhoneUpdate(CustomerEvent $customerEvent): void
  138.     {
  139.         $validateFormat ForcePhone::getConfigValue('validate_format'false);
  140.         if ($validateFormat) {
  141.             $address $customerEvent->getModel()->getDefaultAddress();
  142.             try {
  143.                 $phoneUtil PhoneNumberUtil::getInstance();
  144.                 if (!empty($address->getPhone())) {
  145.                     $phoneNumberProto $phoneUtil->parse($address->getPhone(), $address->getCountry()->getIsoalpha2());
  146.                     $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  147.                     if ($isValid) {
  148.                         $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  149.                         $address->setPhone($phone)->save();
  150.                     }
  151.                 }
  152.                 if (!empty($address->getCellphone())) {
  153.                     $phoneNumberProto $phoneUtil->parse($address->getCellphone(), $address->getCountry()->getIsoalpha2());
  154.                     $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  155.                     if ($isValid) {
  156.                         $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  157.                         $address->setCellphone($phone)->save();
  158.                     }
  159.                 }
  160.             } catch (\Exception $exception) {
  161.                 Tlog::getInstance()->warning('Error on update phone format');
  162.             }
  163.         }
  164.     }
  165.     public function validateOpenApiAddress(ModelValidationEvent $event): void
  166.     {
  167.         if ($event->getGroups() === 'read') {
  168.             return;
  169.         }
  170.         /** @var Address $address */
  171.         $address $event->getModel();
  172.         $country CountryQuery::create()->filterById($address->getCountryId())->findOne();
  173.         $violations $event->getViolations();
  174.         $phoneUtil PhoneNumberUtil::getInstance();
  175.         if (!empty($address->getPhone())) {
  176.             try {
  177.                 $phoneNumberProto $phoneUtil->parse($address->getPhone(), $country->getIsoalpha2());
  178.                 $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  179.                 if (!$isValid) {
  180.                     throw new \Exception('Invalid phone number');
  181.                 }
  182.                 $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  183.                 $address->setPhone($phone);
  184.             } catch (\Exception $exception) {
  185.                 $violations['phone'] = $event->getModelFactory()->buildModel('SchemaViolation', ['message' => $exception->getMessage()]);
  186.             }
  187.         }
  188.         if (!empty($address->getCellphone())) {
  189.             try {
  190.                 $phoneNumberProto $phoneUtil->parse($address->getCellphone(), $country->getIsoalpha2());
  191.                 $isValid $phoneUtil->isValidNumber($phoneNumberProto);
  192.                 if (!$isValid) {
  193.                     throw new \Exception('Invalid cellphone number');
  194.                 }
  195.                 $phone $phoneUtil->format($phoneNumberProtoPhoneNumberFormat::INTERNATIONAL);
  196.                 $address->setCellphone($phone);
  197.             } catch (\Exception $exception) {
  198.                 $violations['cellphone'] = $event->getModelFactory()->buildModel('SchemaViolation', ['message' => $exception->getMessage()]);
  199.             }
  200.         }
  201.         $event->setModel($address);
  202.         $event->setViolations($violations);
  203.     }
  204. }