src/Controller/MarketingController.php line 410

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Component\HttpFoundation\Response;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\Routing\Annotation\Route;
  6. use Symfony\Component\Mailer\Exception\TransportException;
  7. use Symfony\Component\DependencyInjection\ContainerInterface;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  10. use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
  11. use Symfony\Component\HttpFoundation\JsonResponse;
  12. use Orc\UserBundle\Entity\User;
  13. use App\Controller\BaseController;
  14. use App\Entity\MarketerClientRequest;
  15. use App\Entity\MarketerRedemptionCode;
  16. use App\Entity\SignUpCode;
  17. use App\Form\Marketing\Account;
  18. use App\Form\Marketing\AccountType;
  19. use App\Form\Marketing\RegistrationAppsumoType;
  20. use App\Model\EntityModel\SiteEntityModel;
  21. use App\Model\EntityModel\ClientEntityModel;
  22. use App\Model\MarketingModel;
  23. use App\Mailer\MarketerRequestMailer;
  24. use App\Form\Marketing\RegistrationType;
  25. use App\Security\LoginFormAuthenticator;
  26. use App\Model\EntityModel\WorkerEnityModel;
  27. use App\Repository\MarketerValidRedemptionCodesRepository;
  28. use App\Repository\SignUpCodeRepository;
  29. use App\Service\IntercomIntegrationService;
  30. use Orc\SaasBundle\Repository\ClientRepository;
  31. use Symfony\Component\Form\FormError;
  32. use Symfony\Component\Mailer\MailerInterface;
  33. use Symfony\Component\Mime\Email;
  34. use Twilio\Rest\Client as TwilioClient;
  35. class MarketingController extends BaseController {
  36.     
  37.     const LABEL_AUTHORIZATION_SUCCESS "You successfully authorized %s to have access to your account.";
  38.     const LABEL_AUTHORIZATION_ALREADY_AUTHORIZED "You already authorized %s to have access to your account.";
  39.     const LABEL_AUTHORIZATION_FAIL "An unexpected error error prevented us from authorizing %s to access your account.";
  40.     const MSG_DELETE_ONE_SUCCESS 'Account deleted successfully.';
  41.     const MSG_DELETE_ONE_NOT_FOUND 'Account not found.';
  42.     const MSG_DELETE_ONE_NOT_YOURS 'You are not authorized to this account.';
  43.     const MSG_DELETE_ONE_FAIL 'Unable to delte account (unexpected error).';
  44.     const MSG_DENY_STATUS_ERROR 'An unexpected error prevented us from completing your request. But %s is still not authorized to have access to your account.';
  45.     const MSG_DENY_STATUS_SUCCESS "You successfully denied %s from having access to your account.";
  46.     const MSG_DENY_STATUS_ALREADY_DENIED "You already denied %s from having access to your account.";
  47.     const MSG_DENY_STATUS_PREVIOUSLY_AUTHORIZED "You authorized %s to have access to your account previously.";
  48.     const MSG_DENY_STATUS_NOT_FOUND 4;    
  49.     const NUMBER_OF_ITEMS_PER_PAGE 20;
  50.     
  51.     /**
  52.      * @Route("/marketing", name="app_marketing_index")
  53.      */
  54.     public function index(
  55.         Request $requestSiteEntityModel $siteEntityModel
  56.         ClientEntityModel $clientEntityModelMarketingModel $marketingModel,
  57.         MarketerRequestMailer $marketerRequestMailerContainerInterface $container
  58.     )
  59.     {
  60.         $marketer $this->getUser()->getMarketer();
  61.         if (!$marketer) {
  62.             return $this->redirect($this->generateUrl('app_logout'));
  63.         }
  64.         $domain $container->getParameter('marketing_subdomain'). '.' 
  65.             $container->getParameter('domain_name');
  66.         $form $this->createForm(AccountType::class, (new Account())->setMarketer($marketer));
  67.         $form->handleRequest($request);
  68.         if ( $form->isSubmitted() && $form->isValid() ) {
  69.             $account $form->getData();
  70.             $accountUrl $account->getUrl();
  71.             $domain str_replace(
  72.                 ['http://''https://''/'], [''''], $accountUrl
  73.             );
  74.             $site $siteEntityModel->findOneByDomain($domain);
  75.             $accountClient $site->getClient();
  76.             if (!$marketer) {
  77.                 throw new \Exception('Marketer not defined');
  78.             }            
  79.             $marketerClientRequest $marketingModel->addMarketingClientRequest($marketer$accountClient);
  80.             try {
  81.                 $blnSent $marketerRequestMailer->send($marketerClientRequest);
  82.                 if ($blnSent) {
  83.                     //$this->addFlash('success', "Request sent to {$domain} owner.");
  84.                     return $this->redirect($this->generateUrl(
  85.                         'app_marketing_index'
  86.                     ));
  87.                 }
  88.                 else {
  89.                     $this->addFlash('error'"Unexpected error: Unable to send request to {$domain} owner.");
  90.                 }                
  91.             }
  92.             catch(TransportException $e) {
  93.                 $this->addFlash('error'"Unable to send request to {$domain} owner. Maybe the email in their account is not valid.");
  94.             }
  95.         }
  96.         else if ($request->isMethod('post')) {
  97.             //$this->addFlash('error', 'Please correct the errors!');
  98.             //$this->addFlash('error', 'Account Not Found!');
  99.         }
  100.         $from $request->query->has('from') ? $request->query->get('from') : 1;
  101.         $to $request->query->has('to') ? $request->query->get('to') : self::NUMBER_OF_ITEMS_PER_PAGE;
  102.         if ($from >= $to) {
  103.             $from 1;
  104.             $to self::NUMBER_OF_ITEMS_PER_PAGE;
  105.         }
  106.         $marketerClientRequests $marketingModel->findMarketerClientRequestsByMarketerPaginated($marketer$from-1self::NUMBER_OF_ITEMS_PER_PAGE);
  107.         $totalItems $marketingModel->countMarketerClientRequestsByMarketer($marketer); 
  108.         
  109.         return $this->render('orc/views/marketing/index.html.twig', [
  110.             'marketer' => $marketer,
  111.             'form' => $form->createView(),
  112.             'marketerClientRequests' => $marketerClientRequests,
  113.             //'site' => $marketer->getSite(),
  114.             'queryText' => '',
  115.             'totalItems' => $totalItems,
  116.             'from' => $from,
  117.             'to' => $to,
  118.             'numberOfItemsPerPage' => 5//self::NUMBER_OF_ITEMS_PER_PAGE,   
  119.             'deleteSelectedRoute' => 'app_marketing_delete_selected',
  120.             'domain' => $domain
  121.         ]);
  122.     }
  123.         
  124.     /**
  125.      * @Route("/dashboard/marketer-request/{id}/{token}/{choice}", 
  126.      * name="app_marketing_authorize_marketer",
  127.      * requirements={"choice"="yes|no"}
  128.      * )
  129.      */
  130.     public function authorize(
  131.         Request $requestMarketerClientRequest $marketerClientRequest
  132.         string $token$choiceSiteEntityModel $siteEntityModel
  133.         ClientEntityModel $clientEntityModelMarketingModel $marketingModel
  134.         ContainerInterface $container
  135.     )
  136.     {
  137.         $domain $container->getParameter('marketing_subdomain'). '.' 
  138.             $container->getParameter('domain_name');
  139.         $marketer $this->getUser()->getMarketer();
  140.         if ($choice == 'yes') {
  141.             $status $marketingModel->authorizeRequest($marketerClientRequest$token);
  142.             if ($status == MarketingModel::RESPONSE_STATUS_SUCCESS) {
  143.                 $this->addFlash('success'sprintf(
  144.                     self::LABEL_AUTHORIZATION_SUCCESS
  145.                     $marketerClientRequest->getMarketer()->getName()
  146.                 ));
  147.             }
  148.             else if ($status == MarketingModel::RESPONSE_STATUS_ALREADY_AUTHORIZED) {
  149.                 $this->addFlash('error'sprintf(
  150.                     self::LABEL_AUTHORIZATION_ALREADY_AUTHORIZED
  151.                     $marketerClientRequest->getMarketer()->getName()
  152.                 ));            
  153.             }        
  154.             else {
  155.                 $this->addFlash('error'sprintf(
  156.                     self::LABEL_AUTHORIZATION_FAIL
  157.                     $marketerClientRequest->getMarketer()->getName()
  158.                 ));            
  159.             }
  160.         }
  161.         else if ($choice == 'no') {
  162.             $status $marketingModel->denyRequest($marketerClientRequest$token);
  163.             switch ($status) {
  164.                 case MarketingModel::DENY_STATUS_SUCCESS:
  165.                     $this->addFlash('success'sprintf(
  166.                         self::MSG_DENY_STATUS_SUCCESS
  167.                         $marketerClientRequest->getMarketer()->getName()
  168.                     ));
  169.                     break;
  170.                 case MarketingModel::DENY_STATUS_ALREADY_AUTHORIZED:
  171.                     $this->addFlash('success'sprintf(
  172.                         self::MSG_DENY_STATUS_PREVIOUSLY_AUTHORIZED
  173.                         $marketerClientRequest->getMarketer()->getName()
  174.                     ));
  175.                     break;
  176.                 case MarketingModel::DENY_STATUS_ALREADY_DENIED:
  177.                     $this->addFlash('success'sprintf(
  178.                         self::MSG_DENY_STATUS_ALREADY_DENIED
  179.                         $marketerClientRequest->getMarketer()->getName()
  180.                     ));
  181.                     break; 
  182.                 case MarketingModel::DENY_STATUS_NOT_FOUND:
  183.                     throw $this->createNotFoundException('Page not found');
  184.                     break;  
  185.                 case MarketingModel::DENY_STATUS_ERROR:
  186.                     $this->addFlash('error'sprintf(
  187.                         self::MSG_DENY_STATUS_ERROR
  188.                         $marketerClientRequest->getMarketer()->getName()
  189.                     ));
  190.                     break;                
  191.                 default:
  192.                     break;
  193.             }
  194.         }
  195.             
  196.         return $this->redirect($this->generateUrl('app_client_marketing'));
  197.     }
  198.     
  199.     /**
  200.      * @Route("/marketing/list/filter", name="app_marketing_list_filter")
  201.      */    
  202.     public function listFilter(Request $requestMarketingModel $marketingModelContainerInterface $containerEntityManagerInterface $entityManager)
  203.     {
  204.         //$marketerRepository = $entityManager->getRepository('App\\Entity\\Marketer');
  205.         //$marketer = $marketerRepository->find($this->getUser()->getMarketer()->getId());
  206.         $marketer $this->getUser()->getMarketer();
  207.         if (!$marketer) {
  208.             return $this->redirect($this->generateUrl('app_logout'));
  209.         }
  210.         $marketer->getName();
  211.         $domain $container->getParameter('marketing_subdomain'). '.' 
  212.             $container->getParameter('domain_name');
  213.         $marketer $this->getUser()->getMarketer();
  214.         $marketer $this->getUser()->getMarketer();
  215.         if (!$marketer) {
  216.             return $this->redirect($this->generateUrl('app_logout'));
  217.         }        
  218.         $queryText $request->query->get('q');
  219.         if (!$queryText || empty($queryText)) {
  220.             return $this->redirect($this->generateUrl('app_marketing_index'));
  221.         } 
  222.         $form $this->createForm(AccountType::class, (new Account())->setMarketer($marketer));
  223.         $form->handleRequest($request);        
  224.         $from $request->query->has('from') ? $request->query->get('from') : 1;
  225.         $to $request->query->has('from') ? $request->query->get('to') : self::NUMBER_OF_ITEMS_PER_PAGE;
  226.         if ($from >= $to) {
  227.             $from 1;
  228.             $to self::NUMBER_OF_ITEMS_PER_PAGE;
  229.         }
  230.         $marketerClientRequests $marketingModel->findFilteredMarketerClientRequestsPaginated($marketer$from-1$to$queryText);
  231.         $totalItems $marketingModel->countFilteredMarketerClientRequests($marketer$queryText); 
  232.         return $this->render('orc/views/marketing/index.html.twig', array(
  233.             'site' => $this->site,
  234.             'client'  => $marketer,
  235.             'form' => $form->createView(),
  236.             'marketer' => $marketer,
  237.             'marketerClientRequests' => $marketerClientRequests,
  238.             'totalItems' => $totalItems,
  239.             'from' => $from,
  240.             'to' => $to,
  241.             'queryText' => $queryText,
  242.             'numberOfItemsPerPage' => self::NUMBER_OF_ITEMS_PER_PAGE,  
  243.             'deleteSelectedRoute' => 'app_marketing_delete_selected',
  244.             'domain' => $domain,
  245.             'user' => $this->getUser()
  246.         ));        
  247.     }  
  248.     
  249.     /**
  250.      * @Route("/marketing/requests/delete-selected/{ids}", name="app_marketing_delete_selected")
  251.      */     
  252.     public function deleteSelected(
  253.         Request $requeststring $ids,
  254.         MarketingModel $marketingModel
  255.     )
  256.     {
  257.         $marketer $this->getUser()->getMarketer();
  258.         $marketer $this->getUser()->getMarketer();
  259.         if (!$marketer) {
  260.             return $this->redirect($this->generateUrl('app_logout'));
  261.         }        
  262.         $deleted $marketingModel->deleteMarketerClientRequestsByIds(
  263.             $marketer$ids
  264.         );
  265.         if ($deleted) {
  266.             $this->addFlash('success''Accounts removed successfully.');
  267.         }
  268.         else {
  269.             $this->addFlash('success''Unexpected error.');
  270.         }
  271.         
  272.         return $this->redirect($this->generateUrl('app_marketing_index'));
  273.     }  
  274.     /**
  275.      * @Route("/marketing/requests/{id}", name="app_marketing_delete", methods={"GET"})
  276.      */
  277.     public function delete(
  278.         Request $requestMarketerClientRequest $marketerClientRequest
  279.         MarketingModel $marketingModel
  280.     )
  281.     {
  282.         $marketer $this->getUser()->getMarketer();
  283.         if (!$marketer) {
  284.             return $this->redirect($this->generateUrl('app_logout'));
  285.         }        
  286.         $deleteStatus $marketingModel->deleteMarketerClientRequest(
  287.             $marketer$marketerClientRequest
  288.         );
  289.         if ($deleteStatus == MarketingModel::DELETE_ONE_STATUS_SUCCESS) {
  290.             $this->addFlash('success'self::MSG_DELETE_ONE_SUCCESS);
  291.         }
  292.         else if ($deleteStatus == MarketingModel::DELETE_ONE_STATUS_NOT_FOUND) {
  293.             throw $this->createNotFoundException(MarketingModel::DELETE_ONE_STATUS_NOT_FOUND);
  294.         }  
  295.         else if ($deleteStatus == MarketingModel::DELETE_ONE_STATUS_ACCOUNT_NOT_YOURS) {
  296.             $this->addFlash('error'self::MSG_DELETE_ONE_NOT_YOURS);
  297.         }         
  298.         else {
  299.             $this->addFlash('error'self::MSG_DELETE_ONE_FAIL);
  300.         } 
  301.         
  302.         return $this->redirect($this->generateUrl('app_marketing_index'));
  303.     }   
  304.     /**
  305.      * @Route("/marketing/redemption/add", name="app_marketing_redemtioncode_add", methods={"POST"})
  306.      */
  307.     public function redemtioncode_add(
  308.         Request $request
  309.         MarketerValidRedemptionCodesRepository $marketerValidRedemptionCodesRepository
  310.     )
  311.     {
  312.         try {
  313.             $marketer $this->getUser()->getMarketer();
  314.             $now = new \DateTime();
  315.             $entityManager $this->getDoctrine()->getManager();
  316.             $odata json_decode($request->getContent());
  317.             if (!$marketer->isLicensed()) {
  318.                 throw new \Exception("This is not a licensed marketer!");
  319.             }
  320.             if (empty($odata) || !property_exists($odata'code') || empty($odata->code)) {
  321.                 throw new \Exception("Please provide a valid redemption code!");
  322.             }
  323.             $ncodes count($marketer->getMarketerRedemptionCodes());
  324.             if ($ncodes >= 3) {
  325.                 throw new \Exception("You cannot add more than three redemption codes!");
  326.             }
  327.             $vrcode $odata->code;
  328.             $marketerValidRedemptionCode $marketerValidRedemptionCodesRepository->findOneBy(['code' => $vrcode'status' => false]);
  329.             if ($marketerValidRedemptionCode == null) {
  330.                 throw new \Exception("Please provide a valid redemption code!");
  331.             }
  332.             $marketerValidRedemptionCode->setStatus(true);
  333.             $entityManager->persist($marketerValidRedemptionCode);
  334.             $entityManager->flush();
  335.             $marketerRedemptionCode = new MarketerRedemptionCode();
  336.             $marketerRedemptionCode->setMarketer($marketer);
  337.             $marketerRedemptionCode->setStatus(MarketerRedemptionCode::STATUS_ENABLED);
  338.             $marketerRedemptionCode->setDateAdded(clone $now);
  339.             $marketerRedemptionCode->setIpaddress($request->getClientIp());
  340.             $marketerRedemptionCode->setCode($vrcode);
  341.             $entityManager->persist($marketerRedemptionCode);
  342.             $entityManager->flush();
  343.             $signUpCode $marketer->getSignUpCodes()[0];
  344.             $ncodesnew $ncodes 1;
  345.             $newmaxusagecount null;
  346.             switch ($ncodesnew) {
  347.                 case 2:
  348.                     {
  349.                         $newmaxusagecount MarketerRedemptionCode::MAXUSAGECOUNT_2;
  350.                     }
  351.                     break;
  352.                 case 3:
  353.                     {
  354.                         $newmaxusagecount MarketerRedemptionCode::MAXUSAGECOUNT_3;
  355.                     }
  356.                     break;
  357.             }
  358.             $signUpCode->setStatus('new');
  359.             if (!empty($newmaxusagecount)) {
  360.                 $signUpCode->setMaxUsageCount($newmaxusagecount);
  361.             }
  362.             $entityManager->persist($signUpCode);
  363.             $entityManager->flush();
  364.                         
  365.             return new JsonResponse(
  366.                 [
  367.                     'status' => 'ok',
  368.                     'usage' => [
  369.                         'current' => $signUpCode->getUsageCount(),
  370.                         'max' => $signUpCode->getMaxUsageCount()
  371.                     ]
  372.                 ],
  373.                 Response::HTTP_OK,
  374.                 ['content-type' => 'application/json']
  375.             );
  376.         } catch (\Throwable $throwable) {
  377.             
  378.             return new JsonResponse(
  379.                 [
  380.                     'message' => $throwable->getMessage(),
  381.                     'trace' => $throwable->getTrace(),
  382.                     'file' => $throwable->getFile(),
  383.                     'line' => $throwable->getLine()
  384.                 ],
  385.                 Response::HTTP_BAD_REQUEST,
  386.                 ['content-type' => 'application/json']
  387.             );
  388.         }
  389.         
  390.     }
  391.     
  392.     /**
  393.      * @Route("/marketing/requests/{id}/togglelive", name="app_marketing_togglelive", methods={"POST"})
  394.      */
  395.     public function togglelive(
  396.         Request $requestMarketerClientRequest $marketerClientRequest,
  397.         MarketingModel $marketingModel,EntityManagerInterface $entityManager,
  398.         MailerInterface $mailerInterfaceContainerInterface $container,
  399.         IntercomIntegrationService $intercomIntegrationService
  400.     )
  401.     {
  402.         $marketer $this->getUser()->getMarketer();
  403.         if (!$marketer) {
  404.             return $this->redirect($this->generateUrl('app_logout'));
  405.         }
  406.         $client $marketerClientRequest->getClient();
  407.         $doSendToIntercom false;
  408.         if ($client->getLive()) {
  409.             $client->setLive(false);
  410.         } else {
  411.             $client->setLive(true);
  412.             if (!$client->getLiveNotified()) {
  413.                 /*
  414.                 try {
  415.                     $email = (new Email())
  416.                         ->from('info@routezilla.com')
  417.                         ->to($client->getEmail())
  418.                         //->cc('cc@example.com')
  419.                         //->bcc('bcc@example.com')
  420.                         //->replyTo('fabien@example.com')
  421.                         //->priority(Email::PRIORITY_HIGH)
  422.                         //->subject('Your new Routezilla Account is ready!')
  423.                         ->subject('Your New Routezilla Account is Now Live!')
  424.                         //->html(sprintf('<p>Your new Routezilla Account <a href="%s">%s</a> is now live! Please <a href="%s/reset-password">click here</a> to set your password and start your journey!</p>', $client->getDomainWithProtocol(), $client->getName(), $client->getDomainWithProtocol()));
  425.                         ->html(sprintf('<p>Your new Routezilla Account, <a href="%s">%s</a>, is now live! Please <a href="%s/reset-password">click here</a> to set your password and start your journey!</p>', $client->getDomainWithProtocol(), $client->getName(), $client->getDomainWithProtocol()));
  426.                     $mailerInterface->send($email);
  427.                 } catch (\Throwable $throwable) {
  428.                     // NOTHING
  429.                 }
  430.                 */
  431.                 try {
  432.                     $phoneNumber $client->getPhone();
  433.                     $phoneNumber MarketingController::enforcePhoneNumberPattern($phoneNumber);
  434.                     $account_sid $container->getParameter('twilio_account_sid');
  435.                     $auth_token $container->getParameter('twilio_auth_token');
  436.                     $twilio_number $container->getParameter('twilio_number');
  437.                     $twilioClient = new TwilioClient($account_sid$auth_token);
  438.                     $resp $twilioClient->messages->create(
  439.                         // Where to send a text message (your cell phone?)
  440.                         //'+16048077923',
  441.                         $phoneNumber,
  442.                         array(
  443.                             'from' => $twilio_number,
  444.                             'body' => 'Congrats! Your Routezilla account is now set up. We are launching your account. Check your email in 30 minutes to reset your password and get started.'
  445.                             //'body' => 'Congrats! Your Routezilla account is now set up. Check your email to reset your password and get started.'
  446.                             //'body' => 'Congratulations, your Routezilla account is setup.  Go to you email to reset your password and learn more about Routezilla',
  447.                             // implode(' ',[
  448.                             //     sprintf('Your new Routezilla Account %s is now live!', $client->getName()),
  449.                             //     sprintf('Please click the link below to set your password and start your journey:'),
  450.                             //     sprintf('%s/reset-password .', $client->getDomainWithProtocol()),
  451.                             //     sprintf('Your Routezilla booking link is:'),
  452.                             //     sprintf('%s .', $client->getDomainWithProtocol())
  453.                             // ])
  454.                         )
  455.                     );
  456.                 } catch (\Throwable $throwable) {
  457.                     // NOTHING
  458.                 }
  459.                 $doSendToIntercom true;
  460.                 $client->setLiveNotified(true);
  461.                 $entityManager->persist($client);
  462.                 $entityManager->flush();
  463.             }
  464.         }
  465.         $entityManager->persist($client);
  466.         $entityManager->flush();
  467.         //dd($doSendToIntercom);
  468.         if ($doSendToIntercom) {
  469.             try {
  470.                 $data $intercomIntegrationService->sendToIntercom($client->getId(), truefalse, [], []);
  471.                 // dump($client);
  472.                 // dd($data);
  473.             } catch (\Throwable $throwable) {
  474.                 //dd($throwable->getMessage());
  475.                 // NOTHING
  476.             }
  477.             $intercomIntegrationService->sendMerchantNotifyEvent($client->getId());
  478.         }
  479.         
  480.         return new JsonResponse(
  481.             [ 'client' => $client ],
  482.             Response::HTTP_OK,
  483.             ['content-type' => 'application/json']
  484.         );
  485.         
  486.     }
  487.     /**
  488.      * @Route("/marketing/licenses/requests", name="app_marketing_post_licenses_requests", methods={"POST"})
  489.      */
  490.     public function post_licenses_requests(Request $request)
  491.     {
  492.         $user $this->getUser();
  493.         $marketer $this->getUser()->getMarketer();
  494.         $odata json_decode($request->getContent());
  495.         $subject 'License request submitted';
  496.         $text sprintf('You have successfully requested %d licenses for your marketing portal on Routezilla. Our team will contact you for next steps.'$odata->number_of_licenses);
  497.         $email = (new Email())
  498.             ->from('notifications@routezilla.com')
  499.             ->to($user->getEmail())
  500.             //->cc('cc@example.com')
  501.             ->bcc('info@routezilla.com''brent@routezilla.com''ken@routezilla.com''robert@routezilla.com''pedro@routezilla.com')
  502.             ->replyTo('info@routezilla.com')
  503.             //->priority(Email::PRIORITY_HIGH)
  504.             ->subject("$subject")
  505.             ->text($text)
  506.             ->html($text);
  507.         
  508.         return new JsonResponse(
  509.             [ 'ok' => true ],
  510.             Response::HTTP_OK,
  511.             ['content-type' => 'application/json']
  512.         );
  513.     }
  514.     
  515.     /**
  516.      * @Route("/signup/marketer", name="app_marketing_signup", methods={"GET", "POST"})
  517.      */    
  518.     public function signup(
  519.         Request $requestLoginFormAuthenticator $authenticator,
  520.         UserPasswordEncoderInterface $passwordEncoder
  521.         GuardAuthenticatorHandler $guardAuthenticatorHandler
  522.     )
  523.     {
  524.         $now = new \DateTime();
  525.         $user = new User();
  526.         $form $this->createForm(RegistrationType::class, $user);
  527.         $form->handleRequest($request);
  528.         if ($form->isSubmitted() && $form->isValid()) {
  529.             $user $form->getData();
  530.             $user->setPassword(
  531.                 $passwordEncoder->encodePassword($user$user->getPassword())
  532.             );
  533.             $roles $user->getRoles();
  534.             $roles[] = 'ROLE_MARKETER';
  535.             $user->setRoles($roles);
  536.             $user->getMarketer()->setUser($user);
  537.             $entityManager $this->getDoctrine()->getManager();
  538.             $entityManager->persist($user);
  539.             $entityManager->flush();
  540.             $code $this->generateRandomString();
  541.             $signUpCode = new SignUpCode();
  542.             $signUpCode->setCode($code);
  543.             $signUpCode->setCreatedAt($now);
  544.             $signUpCode->setStatus('new');
  545.             $signUpCode->setMarketer($user->getMarketer());
  546.             $signUpCode->setOriginallyMarketer($user->getMarketer());
  547.             $signUpCode->setMaxUsageCount(null);
  548.             $signUpCode->setUsageCount(null);
  549.             $entityManager->persist($signUpCode);
  550.             $entityManager->flush();
  551.             return $guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
  552.                 $user,          // the User object you just created
  553.                 $request,
  554.                 $authenticator// authenticator whose onAuthenticationSuccess you want to use
  555.                 'main'          // the name of your firewall in security.yaml
  556.             );            
  557.         }
  558.         else if ($request->isMethod('post')) {
  559.             $this->addFlash('error''Please correct the errors!');
  560. //            $errors = $this->getErrorMessages($form);
  561. //            error_log(__FILE__ . ': ' . __LINE__ . ': $errors = ' . var_export($errors, true));
  562.         }       
  563.         return $this->render('orc/views/marketing/signup.html.twig', array(
  564.             'form'   => $form->createView()
  565.         ));
  566.     } 
  567.     /**
  568.      * @Route("/appsumo/signup", name="app_marketing_appsumo_signup", methods={"GET", "POST"})
  569.      * * @Route("/appsumo/signup/{code}", name="app_marketing_appsumo_signup", methods={"GET", "POST"})
  570.      */    
  571.     public function signup_appsumo(
  572.         Request $requestLoginFormAuthenticator $authenticator,
  573.         UserPasswordEncoderInterface $passwordEncoder
  574.         GuardAuthenticatorHandler $guardAuthenticatorHandler,
  575.         MarketerValidRedemptionCodesRepository $marketerValidRedemptionCodesRepository,
  576.         $code ''
  577.     )
  578.     {
  579.         $now = new \DateTime();
  580.         $user = new User();
  581.         $form $this->createForm(RegistrationAppsumoType::class, $user, [
  582.             'hascode' => !empty($code)
  583.         ]);
  584.         $setformcode false;
  585.         $marketerValidRedemptionCode null;
  586.         $isValidCode false;
  587.         if ($request->isMethod('post')) {
  588.             $vrcode $_POST['registration_appsumo']['appsumoredemptioncode'];
  589.             $marketerValidRedemptionCode $marketerValidRedemptionCodesRepository->findOneBy(['code' => $vrcode'status' => false]);
  590.             if ($marketerValidRedemptionCode == null) {
  591.                 $form->get('appsumoredemptioncode')->addError(new FormError('Invalid Redemption Code!'));
  592.             } else {
  593.                 $isValidCode true;
  594.             }
  595.         } else if ($request->isMethod('get')) {
  596.             if (!empty($code)) {
  597.                 $setformcode true;
  598.                 $vrcode $code;        
  599.                 $marketerValidRedemptionCode $marketerValidRedemptionCodesRepository->findOneBy(['code' => $vrcode'status' => false]);
  600.                 if ($marketerValidRedemptionCode == null) {
  601.                     $form->get('appsumoredemptioncode')->addError(new FormError('Invalid Redemption Code!'));
  602.                 } else {
  603.                     $isValidCode true;
  604.                 }
  605.             }
  606.         }
  607.         $form->handleRequest($request);
  608.         if ($form->isSubmitted() && $form->isValid() && $isValidCode) {
  609.             $user $form->getData();
  610.             $user->setPassword(
  611.                 $passwordEncoder->encodePassword($user$user->getPassword())
  612.             );
  613.             $roles $user->getRoles();
  614.             $roles[] = 'ROLE_MARKETER';
  615.             $user->setRoles($roles);
  616.             $user->getMarketer()->setUser($user);
  617.             $entityManager $this->getDoctrine()->getManager();
  618.             $entityManager->persist($user);
  619.             $entityManager->flush();
  620.             $marketerValidRedemptionCode->setStatus(true);
  621.             $entityManager->persist($marketerValidRedemptionCode);
  622.             $entityManager->flush();
  623.             $marketerRedemptionCode = new MarketerRedemptionCode();
  624.             $marketerRedemptionCode->setMarketer($user->getMarketer());
  625.             $marketerRedemptionCode->setStatus(MarketerRedemptionCode::STATUS_ENABLED);
  626.             $marketerRedemptionCode->setDateAdded(clone $now);
  627.             $marketerRedemptionCode->setIpaddress($request->getClientIp());
  628.             $marketerRedemptionCode->setCode($code);
  629.             $entityManager->persist($marketerRedemptionCode);
  630.             $entityManager->flush();
  631.             $sucode $this->generateRandomString();
  632.             $signUpCode = new SignUpCode();
  633.             $signUpCode->setCode($sucode);
  634.             $signUpCode->setCreatedAt($now);
  635.             $signUpCode->setStatus('new');
  636.             $signUpCode->setMarketer($user->getMarketer());
  637.             $signUpCode->setOriginallyMarketer($user->getMarketer());
  638.             $signUpCode->setMaxUsageCount(MarketerRedemptionCode::MAXUSAGECOUNT_1);
  639.             $signUpCode->setUsageCount(null);
  640.             $entityManager->persist($signUpCode);
  641.             $entityManager->flush();
  642.             return $guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
  643.                 $user,          // the User object you just created
  644.                 $request,
  645.                 $authenticator// authenticator whose onAuthenticationSuccess you want to use
  646.                 'main'          // the name of your firewall in security.yaml
  647.             );            
  648.         } else if ($request->isMethod('post')) {
  649.             $errors $this->getErrorMessages($form);
  650.             if (count($errors) > 0) {
  651.                 foreach ($errors as $key => $message) {
  652.                     $this->addFlash('error'gettype($message) == 'array' implode(' '$message) : $message);
  653.                 }
  654.             } 
  655.             if (!$isValidCode) {
  656.                 $this->addFlash('error''The code you entered is invalid!');
  657.             }
  658. //            error_log(__FILE__ . ': ' . __LINE__ . ': $errors = ' . var_export($errors, true));
  659.         } else if ($setformcode) {
  660.             $form->get('appsumoredemptioncode')->setData($code);
  661.         }
  662.         return $this->render('orc/views/marketing/signup_appsumo.html.twig', array(
  663.             'form'   => $form->createView()
  664.         ));
  665.     } 
  666.     
  667.     /**
  668.      * @Route("/marketing/requests/{id}/resend", name="app_marketing_request_resend", methods={"GET"})
  669.      */    
  670.     public function resend(
  671.         MarketerClientRequest $marketerClientRequest
  672.         MarketerRequestMailer $marketerRequestMailer
  673.     )
  674.     {
  675.         $domain $marketerClientRequest->getClient()->getDomain();
  676.         try {
  677.             $blnSent $marketerRequestMailer->send($marketerClientRequest);
  678.             if ($blnSent) {
  679.                 $this->addFlash('success'"Request re-sent to {$domain} owner.");
  680.             }
  681.             else {
  682.                 $this->addFlash('error'"Unexpected error: Unable to send request to {$domain} owner.");
  683.             }                
  684.         }
  685.         catch(TransportException $e) {
  686.             $this->addFlash('error'"Unable to re-send request to {$domain} owner. Maybe the email in their account is not valid.");
  687.         }
  688.         
  689.         return $this->redirect($this->generateUrl(
  690.             'app_marketing_index'
  691.         ));        
  692.     }
  693.     
  694.     /**
  695.      * @Route("/dashboard/marketing", name="app_client_marketing", methods={"GET"})
  696.      */    
  697.     public function clientMarketers(
  698.         Request $requestMarketingModel $marketingModel
  699.         WorkerEnityModel $workerEntityModel
  700.     )
  701.     {
  702.         $client $this->getClient();
  703.         $marketerRequests $marketingModel->findNonDeniedByClient($client);
  704.         $totalItems count($marketerRequests);
  705.         $worker $workerEntityModel->findByUser($this->getUser());
  706.         if (!$worker) {
  707.             $worker $workerEntityModel->findByUser($client->getUser());
  708.         }
  709.         
  710.         return $this->render('orc/views/marketing/client/client-marketing.html.twig', array(
  711.             'site'       => $client->getSite(),
  712.             'totalItems' => $totalItems,
  713.             'marketerRequests' => $marketerRequests,
  714.             'requestStatuses'  => MarketerClientRequest::getStatuses(),
  715.             'worker'           => $worker
  716.         ));       
  717.     } 
  718.     /**
  719.      * @Route("/dashboard/client/revoke", name="app_marketing_client_revoke", methods={"GET"})
  720.      */     
  721.     public function revokeAccess(MarketingModel $marketingModel
  722.     {
  723.         $client $this->getClient();
  724.         $marketer $marketingModel->revokeAccess($client);
  725.         $this->addFlash(
  726.                 'success''Access revoked from marketer ' $marketer->getName()
  727.         );
  728.         return $this->redirect($this->generateUrl('app_client_marketing'));
  729.     }   
  730.     /**
  731.     * Convert string to match E.164 phone number pattern (e.g. +1234567890),
  732.     * otherwise return empty string.
  733.     */
  734.     public function enforcePhoneNumberPattern($string) {
  735.         $hasplus false;
  736.         if (strlen($string) > && $string[0] === '+') {
  737.             $hasplus true;
  738.         }
  739.         $newString preg_replace("/[^0-9]/"""$string);
  740.         if ($newString == '') {
  741.             return '';
  742.         }
  743.         if ($hasplus) {
  744.             $newString "+$newString";
  745.         } else {
  746.             $newString "+1$newString";
  747.         }
  748.         
  749.         return $newString;
  750.     }
  751.     private function generateRandomString($length 10) {
  752.         $characters '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  753.         $charactersLength strlen($characters);
  754.         $randomString '';
  755.         for ($i 0$i $length$i++) {
  756.             $randomString .= $characters[random_int(0$charactersLength 1)];
  757.         }
  758.         return $randomString;
  759.     }
  760.     
  761. }