<?php
/**
* Created by PhpStorm.
* User: SEBASTIAN TOVAR
* Date: 21/06/2019
* Time: 12:34 PM
*/
namespace App\EventSubscriber\Onboarding;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\App\User;
use App\Entity\Onboarding\Lead;
use App\Exception\SubmittedOnboardingException;
use App\Repository\App\UserRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\Translation\TranslatorInterface;
use App\Exception\InvalidArgumentException;
use App\Services\UtilsService;
class LeadPostValidateSubscriber implements EventSubscriberInterface
{
private $translator;
private $request;
private $utilsService;
private $userRepository;
public function __construct(
TranslatorInterface $translator,
UtilsService $utilsService,
UserRepository $userRepository
){
$this->translator = $translator;
$this->utilsService = $utilsService;
$this->userRepository = $userRepository;
}
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$lead = $event->getControllerResult();
$this->request = $event->getRequest();
$method = $this->request->getMethod();
if (!($lead instanceof Lead) || (Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method)) {
return;
}
if ($lead->getIsCompleted()) {
throw new SubmittedOnboardingException(
$this->translator->trans('Onboarding already submitted')
);
}
$version = $lead->getVersion();
switch ($version) {
case 1:
$this->validateFieldsV1($lead);
break;
case 2:
$this->validateFieldsV2($lead);
break;
default:
throw new InvalidArgumentException(
$this->translator->trans('Onboarding wrong version')
);
break;
}
return;
}
/**
* @param Lead $lead
* @throws InvalidArgumentException
*/
protected function validateFieldsV2(Lead $lead)
{
$step = $lead->getStep();
switch ($step) {
case Lead::V2_USER_STEP:
$this->stepOneValidationV2($lead);
break;
case Lead::V2_COMPANY_STEP:
break;
case Lead::V2_TASK_STEP:
break;
default:
throw new InvalidArgumentException(
$this->translator->trans('Onboarding wrong step',
['%step%' => $lead->getStep()]
)
);
break;
}
}
protected function stepOneValidationV2(Lead $lead) {
//$content = $this->request->getContent();
//$params = json_decode($content, true);
$email = $lead->getEmail() ?? null;
$mobileNumber = $lead->getMobileNumber() ?? null;
$qiipUserEmail = null;
$qiipUserMobile = null;
if (is_null($email) && is_null($mobileNumber)) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding field null',
['%fieldName%' => 'Email / Mobile number']
)
);
}
if (!is_null($mobileNumber)) {
$mobileArray = explode('~',$mobileNumber);
if (count($mobileArray) != 3) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding mobile number error',
['%mobileNumber%' => $lead->getMobileNumber()]
)
);
}
$criteria = $mobileArray[1] . $mobileArray[2];
$qiipUserMobile = $this->userRepository->loadUserByUsername($criteria);
if ($qiipUserMobile instanceof User) {
//TODO Enviar SMS
throw new InvalidArgumentException(
$this->translator->trans('Onboarding existing user')
);
}
}
if (!is_null($email)) {
$criteria = $email;
$qiipUserEmail = $this->userRepository->loadUserByUsername($criteria);
if ($qiipUserEmail instanceof User) {
//TODO Enviar mail
throw new InvalidArgumentException(
$this->translator->trans('Onboarding existing user')
);
}
}
}
protected function stepTwoValidationV2(Lead $lead) {
if (is_null($lead->getVendor() ?? null)) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding field null',
['%fieldName%' => 'Company']
)
);
}
}
/**
* @param Lead $lead
* @throws InvalidArgumentException
*/
protected function validateFieldsV1(Lead $lead)
{
$step = $lead->getStep();
switch ($step) {
case Lead::GENERAL_INFO_STEP:
$this->stepOneValidation($lead);
break;
case Lead::USERS_STEP:
$this->validateEmailsAndMobileNumbers($lead->getUsers(), "User contact info");
break;
case Lead::OPERATORS_STEP:
$this->validateEmailsAndMobileNumbers($lead->getOperators(), "Operator contact info");
break;
case Lead::TASKS_STEP:
break;
default:
throw new InvalidArgumentException(
$this->translator->trans('Onboarding wrong step',
['%step%' => $lead->getStep()]
)
);
break;
}
}
protected function stepOneValidationV1(Lead $lead) {
$content = $this->request->getContent();
$params = json_decode($content, true);
$email = $params['email'] ?? null;
$mobileNumber = $params['mobileNumber'] ?? null;
if (is_null($email) && is_null($mobileNumber)) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding field null',
['%fieldName%' => 'Email / Mobile number']
)
);
}
if (!is_null($mobileNumber)) {
$lead->setEmail(null);
if (!preg_match('/^\+[\d -]+$/', $lead->getMobileNumber())) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding mobile number error',
['%mobileNumber%' => $lead->getMobileNumber()]
)
);
}
$criteria = $mobileNumber;
}
else {
$lead->setMobileNumber(null);
$criteria = $email;
}
$qiipUser = $this->userRepository->loadUserByUsername($criteria);
if (!is_null($qiipUser)) {
throw new InvalidArgumentException(
$this->translator->trans('Onboarding existing user')
);
}
}
protected function validateEmailsAndMobileNumbers($contactsField, $fieldName) {
if (!is_null($contactsField) && !empty($contactsField)) {
$contactArray = explode(",",preg_replace('/\s+/','',$contactsField));
$validData = array();
$noValidData = array();
foreach ($contactArray as $key => $contact) {
if(!empty($contact)) {
if (filter_var($contact, FILTER_VALIDATE_EMAIL)) {
$validData[] = $contact;
}
else {
if (preg_match('/^\+[\d -]+$/', $contact)) {
$validData[] = $contact;
}
else {
$noValidData[] = $contact;
}
}
}
}
if (!empty($noValidData)) {
$wrongLeads = implode(", ", $noValidData);
throw new InvalidArgumentException(
$this->translator->trans('Onboarding number/email error',
['%wrongLeads%' => $wrongLeads]
)
);
}
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_VALIDATE]
];
}
}