vendor/gregwar/captcha-bundle/Validator/CaptchaValidator.php line 97

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Gregwar\CaptchaBundle\Validator;
  4. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  5. use Symfony\Component\Form\FormError;
  6. use Symfony\Component\Form\FormEvent;
  7. use Symfony\Contracts\Translation\TranslatorInterface;
  8. /**
  9.  * Captcha validator.
  10.  *
  11.  * @author Gregwar <g.passault@gmail.com>
  12.  */
  13. class CaptchaValidator
  14. {
  15.     /** @var SessionInterface */
  16.     private $session;
  17.     /**
  18.      * Session key to store the code.
  19.      *
  20.      * @var string
  21.      */
  22.     private $key;
  23.     /**
  24.      * Error message text for non-matching submissions.
  25.      *
  26.      * @var string
  27.      */
  28.     private $invalidMessage;
  29.     /**
  30.      * Configuration parameter used to bypass a required code match.
  31.      *
  32.      * @var string|null
  33.      */
  34.     private $bypassCode;
  35.     /**
  36.      * Number of form that the user can submit without captcha.
  37.      *
  38.      * @var int
  39.      */
  40.     private $humanity;
  41.     /**
  42.      * Translator.
  43.      *
  44.      * @var TranslatorInterface
  45.      */
  46.     private $translator;
  47.     public function __construct(
  48.         TranslatorInterface $translator,
  49.         SessionInterface $session,
  50.         string $key,
  51.         string $invalidMessage,
  52.         ?string $bypassCode,
  53.         int $humanity
  54.     ) {
  55.         $this->translator $translator;
  56.         $this->session $session;
  57.         $this->key $key;
  58.         $this->invalidMessage $invalidMessage;
  59.         $this->bypassCode $bypassCode;
  60.         $this->humanity $humanity;
  61.     }
  62.     public function validate(FormEvent $event): void
  63.     {
  64.         $form $event->getForm();
  65.         $code $form->getData();
  66.         $expectedCode $this->getExpectedCode();
  67.         if ($this->humanity 0) {
  68.             $humanity $this->getHumanity();
  69.             if ($humanity 0) {
  70.                 $this->updateHumanity($humanity 1);
  71.                 return;
  72.             }
  73.         }
  74.         if (!(null !== $code && is_string($code) && ($this->compare($code$expectedCode) || $this->compare($code$this->bypassCode)))) {
  75.             $form->addError(new FormError($this->translator->trans($this->invalidMessage, array(), 'validators')));
  76.         } else {
  77.             if ($this->humanity 0) {
  78.                 $this->updateHumanity($this->humanity);
  79.             }
  80.         }
  81.         $this->session->remove($this->key);
  82.         if ($this->session->has($this->key.'_fingerprint')) {
  83.             $this->session->remove($this->key.'_fingerprint');
  84.         }
  85.     }
  86.     /**
  87.      * Retrieve the expected CAPTCHA code.
  88.      *
  89.      * @return mixed|null
  90.      */
  91.     protected function getExpectedCode()
  92.     {
  93.         $options $this->session->get($this->key, array());
  94.         if (is_array($options) && isset($options['phrase'])) {
  95.             return $options['phrase'];
  96.         }
  97.         return null;
  98.     }
  99.     /**
  100.      * Retrieve the humanity.
  101.      *
  102.      * @return mixed|null
  103.      */
  104.     protected function getHumanity()
  105.     {
  106.         return $this->session->get($this->key.'_humanity'0);
  107.     }
  108.     protected function updateHumanity(int $newValue): void
  109.     {
  110.         if ($newValue 0) {
  111.             $this->session->set($this->key.'_humanity'$newValue);
  112.         } else {
  113.             $this->session->remove($this->key.'_humanity');
  114.         }
  115.     }
  116.     protected function niceize(string $code): string
  117.     {
  118.         return strtr(strtolower($code), 'oil''01l');
  119.     }
  120.     /**
  121.      * Run a match comparison on the provided code and the expected code.
  122.      *
  123.      * @param string      $code
  124.      * @param string|null $expectedCode
  125.      *
  126.      * @return bool
  127.      */
  128.     protected function compare(string $code, ?string $expectedCode): bool
  129.     {
  130.         return null !== $expectedCode && is_string($expectedCode) && $this->niceize($code) == $this->niceize($expectedCode);
  131.     }
  132. }