From 1e261bd3495a7b730972d5a903de6b2ecc9cc1e8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Gertz?= Date: Mon, 3 Oct 2022 05:13:03 +0200 Subject: [PATCH] Add captcha form type --- Form/CaptchaType.php | 121 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Form/CaptchaType.php diff --git a/Form/CaptchaType.php b/Form/CaptchaType.php new file mode 100644 index 0000000..d479b47 --- /dev/null +++ b/Form/CaptchaType.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Rapsys\PackBundle\Form; + +use Rapsys\PackBundle\Util\ImageUtil; +use Rapsys\PackBundle\Util\SluggerUtil; + +use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; +use Symfony\Component\Form\Extension\Core\Type\IntegerType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvents; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormError; + +/** + * Captcha Type class definition + * + * @see https://symfony.com/doc/current/form/create_custom_field_type.html + */ +class CaptchaType extends AbstractType { + /** + * @var ImageUtil $image + */ + private $image; + + /** + * @var SluggerUtil $slugger + */ + private $slugger; + + /** + * @var Translator instance + */ + private $translator; + + /** + * Constructor + * + * @param ImageUtil $image + * @param SluggerUtil $slugger + * @param TranslatorInterface $translator The translator instance + */ + public function __construct(ImageUtil $image, SluggerUtil $slugger, TranslatorInterface $translator) { + //Set image + $this->image = $image; + + //Set slugger + $this->slugger = $slugger; + + //Set translator + $this->translator = $translator; + } + + /** + * Build form + * + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) { + //Set captcha + $captcha = $this->image->getCaptcha((new \DateTime('-1 year'))->getTimestamp()); + + //Add captcha token + $builder->add('_captcha_token', HiddenType::class, ['data' => $captcha['token'], 'empty_data' => $captcha['token']]); + + //Add captcha + $builder->add('captcha', IntegerType::class, ['label_attr' => ['class' => 'captcha'], 'label' => ''.htmlentities($captcha['equation']).'', 'label_html' => true, 'translation_domain' => false]); + + //Add event listener on captcha + $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'validateCaptcha']); + } + + /** + * Validate captcha + * + * @param FormEvent $event The form event + */ + public function validateCaptcha(FormEvent $event): void { + //Get form + $form = $event->getForm(); + + //Get event data + $data = $event->getData(); + + //Set token + $token = $form->get('_captcha_token')->getConfig()->getData(); + + //Without captcha + if (empty($data['captcha'])) { + //Add error on captcha + $form->addError(new FormError($this->translator->trans('Captcha is empty'))); + + //Reset captcha token + $data['_captcha_token'] = $token; + + //Set event data + $event->setData($data); + //With invalid captcha + } elseif ($this->slugger->hash($data['captcha']) !== $data['_captcha_token']) { + //Add error on captcha + $form->addError(new FormError($this->translator->trans('Captcha is invalid'))); + + //Reset captcha token + $data['_captcha_token'] = $token; + + //Set event data + $event->setData($data); + } + } +} -- 2.41.0