src/Controller/EnquiryDefaultController.php line 38

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Swift_Mailer;
  4. use App\Entity\Enquiry;
  5. use App\Form\EnquiryType;
  6. use App\Annotation\CmsComponent;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Google\Cloud\RecaptchaEnterprise\V1\Event;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\Routing\Annotation\Route;
  12. use Google\Cloud\RecaptchaEnterprise\V1\Assessment;
  13. use Google\Cloud\RecaptchaEnterprise\V1\CreateAssessmentRequest;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason;
  16. use Google\Cloud\RecaptchaEnterprise\V1\Client\RecaptchaEnterpriseServiceClient;
  17. class EnquiryDefaultController extends AbstractController
  18. {
  19.     private ?RecaptchaEnterpriseServiceClient $client null;
  20.     private string $errorMessage '';
  21.     public function __construct(
  22.         private readonly EntityManagerInterface $em,
  23.         private readonly Swift_Mailer $mailer,
  24.         private readonly string $recaptcha_key,
  25.         private readonly string $recaptcha_project_id,
  26.         private readonly string $projectRoot
  27.     ) {
  28.     }
  29.     /**
  30.      * @CmsComponent("WhatsApp Block", active=true, routeName="whatsapp_block")
  31.      */
  32.     #[Route(path'/whatsapp-block'name'whatsapp_block')]
  33.     public function whatsappBlock(): Response
  34.     {
  35.         return $this->render('@theme/enquiry/whatsapp-block.html.twig');
  36.     }
  37.     /**
  38.      * @CmsComponent("Embed Enquiry Form", active=true, routeName="embed_enquiry")
  39.      */
  40.     #[Route(path'/pcgc-enquiry'name'embed_enquiry')]
  41.     public function embedEnquiry(Request $request): Response
  42.     {
  43.         $enquiry = new Enquiry();
  44.         $enquiry->setSubject('TaurusHR Website Enquiry');
  45.         // $this->setTempData($enquiry);
  46.         $form $this->createForm(EnquiryType::class, $enquiry);
  47.         $form->handleRequest($request);
  48.         $error false;
  49.         $success false;
  50.         $errorMessage '';
  51.         if ($form->isSubmitted()) {
  52.             if ($this->spamChecksPass($request)) {
  53.                 if ($form->isValid()) {
  54.                     $this->em->persist($enquiry);
  55.                     $this->em->flush();
  56.                     $success true;
  57.                     $this->sendEmail($enquiry);
  58.                 } else {
  59.                     $error true;
  60.                     $errorMessage 'Error - Check the form for errors';
  61.                 }
  62.             } else {
  63.                 $error true;
  64.                 $errorMessage $this->errorMessage;
  65.             }
  66.         }
  67.         return $this->render('@theme/enquiry/enquiry.html.twig', [
  68.             'enquiry' => $enquiry,
  69.             'error' => $error,
  70.             'success' => $success,
  71.             'errorMessage' => $errorMessage,
  72.             'form' => $form->createView(),
  73.         ]);
  74.     }
  75.     #[Route(path'/email-test'name'email_test')]
  76.     public function emailTest(): Response
  77.     {
  78.         return $this->render('@theme/emails/enquiry-confirmed.html.twig');
  79.     }
  80.     private function spamChecksPass(Request $request): bool
  81.     {
  82.         // also test form execution time
  83.         try {
  84.             $posted $request->request->All();
  85.             // check for captcha response
  86.             $recaptcha $posted['g-recaptcha-response'] ?? null;
  87.             if (empty($recaptcha)) {
  88.                 return false;
  89.             }
  90.             // check for form execution time
  91.             $loadedAt = (int) $posted['enquiry']['_loaded_at'] ?? 0;
  92.             if ($loadedAt && (time() - $loadedAt) < 3) {
  93.                 return false;
  94.             }
  95.             // check for $honeypot field
  96.             $honeypot $posted['enquiry']['website'] ?? null;
  97.             if (!empty($honeypot)) {
  98.                 return false;
  99.             }
  100.             return $this->verifyRecaptcha($recaptcha);
  101.         } catch (\Throwable $th) {
  102.             return false;
  103.         }
  104.     }
  105.     private function verifyRecaptcha($token): bool
  106.     {
  107.         $this->errorMessage '';
  108.         if (! $this->client) {
  109.             $this->client = new RecaptchaEnterpriseServiceClient([
  110.                 'credentials' => $this->projectRoot '/recaptcha-credentials.json',
  111.             ]);
  112.             $projectName $this->client->projectName($this->recaptcha_project_id);
  113.         }
  114.         // Set the properties of the event to be tracked.
  115.         $event = (new Event())
  116.             ->setSiteKey($this->recaptcha_key)
  117.             ->setToken($token);
  118.         $assessment = (new Assessment())
  119.             ->setEvent($event);
  120.         $request = (new CreateAssessmentRequest())
  121.             ->setParent($projectName)
  122.             ->setAssessment($assessment);
  123.         try {
  124.             $response $this->client->createAssessment($request);
  125.             if ($response->getTokenProperties()->getValid() == false) {
  126.                 $this->errorMessage InvalidReason::name($response->getTokenProperties()->getInvalidReason());
  127.                 return false;
  128.             }
  129.             $score $response->getRiskAnalysis()->getScore();
  130.             if ($score 0.5) {
  131.                 $this->errorMessage 'Low score: ' $score;
  132.                 return false;
  133.             }
  134.         } catch (\Exception $e) {
  135.             return false;
  136.         }
  137.         return true;
  138.     }
  139.     private function sendEmail(Enquiry $enquiry): void
  140.     {
  141.         $message_to_client = (new \Swift_Message())
  142.             ->setSubject('Enquiry Received via '.$this->getParameter('sitename').' website')
  143.             ->setFrom($this->getParameter('email_norely'))
  144.             ->setTo($this->getParameter('email_primary'))
  145.             ->setBody(
  146.                 $this->renderView('@theme/emails/enquiry-to-client.html.twig', ['enquiry' => $enquiry]),
  147.                 'text/html'
  148.             )
  149.         ;
  150.         $this->mailer->send($message_to_client);
  151.         $message_to_user = (new \Swift_Message())
  152.             ->setSubject('Enquiry sent to '.$this->getParameter('sitename').' confirmed')
  153.             ->setFrom($this->getParameter('email_norely'))
  154.             ->setTo($enquiry->getEmail())
  155.             ->setBody(
  156.                 $this->renderView(
  157.                     '@theme/emails/enquiry-confirmed.html.twig',
  158.                     ['enquiry' => $enquiry]
  159.                 ),
  160.                 'text/html'
  161.             )
  162.         ;
  163.         $this->mailer->send($message_to_user);
  164.     }
  165.     private function setTempData(Enquiry $enquiry): void
  166.     {
  167.         $enquiry->setName('Test Recaptcha');
  168.         $enquiry->setContactNumber('0400000000');
  169.         $enquiry->setEmail('dev@thetlb.co.uk');
  170.         $enquiry->setInterestedService('HR');
  171.         $enquiry->setMessage('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat.');
  172.     }
  173. }