]> Raphaël G. Git Repositories - packbundle/blob - Form/CaptchaType.php
Strict types
[packbundle] / Form / CaptchaType.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys PackBundle package.
5 *
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\PackBundle\Form;
13
14 use Rapsys\PackBundle\Util\ImageUtil;
15 use Rapsys\PackBundle\Util\SluggerUtil;
16
17 use Symfony\Contracts\Translation\TranslatorInterface;
18 use Symfony\Component\Form\AbstractType;
19 use Symfony\Component\Form\Extension\Core\Type\HiddenType;
20 use Symfony\Component\Form\Extension\Core\Type\IntegerType;
21 use Symfony\Component\Form\FormBuilderInterface;
22 use Symfony\Component\Form\FormEvents;
23 use Symfony\Component\Form\FormEvent;
24 use Symfony\Component\Form\FormError;
25
26 /**
27 * Captcha Type class definition
28 *
29 * @see https://symfony.com/doc/current/form/create_custom_field_type.html
30 */
31 class CaptchaType extends AbstractType {
32 /**
33 * @var ImageUtil $image
34 */
35 private $image;
36
37 /**
38 * @var SluggerUtil $slugger
39 */
40 private $slugger;
41
42 /**
43 * @var Translator instance
44 */
45 private $translator;
46
47 /**
48 * Constructor
49 *
50 * @param ImageUtil $image
51 * @param SluggerUtil $slugger
52 * @param TranslatorInterface $translator The translator instance
53 */
54 public function __construct(ImageUtil $image, SluggerUtil $slugger, TranslatorInterface $translator) {
55 //Set image
56 $this->image = $image;
57
58 //Set slugger
59 $this->slugger = $slugger;
60
61 //Set translator
62 $this->translator = $translator;
63 }
64
65 /**
66 * Build form
67 *
68 * {@inheritdoc}
69 */
70 public function buildForm(FormBuilderInterface $builder, array $options): void {
71 //Set captcha
72 $captcha = $this->image->getCaptcha((new \DateTime('-1 year'))->getTimestamp());
73
74 //Add captcha token
75 $builder->add('_captcha_token', HiddenType::class, ['data' => $captcha['token'], 'empty_data' => $captcha['token']]);
76
77 //Add captcha
78 $builder->add('captcha', IntegerType::class, ['label_attr' => ['class' => 'captcha'], 'label' => '<img src="'.htmlentities($captcha['src']).'" alt="'.htmlentities($captcha['equation']).'" />', 'label_html' => true, 'translation_domain' => false]);
79
80 //Add event listener on captcha
81 $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'validateCaptcha']);
82 }
83
84 /**
85 * Validate captcha
86 *
87 * @param FormEvent $event The form event
88 */
89 public function validateCaptcha(FormEvent $event): void {
90 //Get form
91 $form = $event->getForm();
92
93 //Get event data
94 $data = $event->getData();
95
96 //Set token
97 $token = $form->get('_captcha_token')->getConfig()->getData();
98
99 //Without captcha
100 if (empty($data['captcha'])) {
101 //Add error on captcha
102 $form->addError(new FormError($this->translator->trans('Captcha is empty')));
103
104 //Reset captcha token
105 $data['_captcha_token'] = $token;
106
107 //Set event data
108 $event->setData($data);
109 //With invalid captcha
110 } elseif ($this->slugger->hash($data['captcha']) !== $data['_captcha_token']) {
111 //Add error on captcha
112 $form->addError(new FormError($this->translator->trans('Captcha is invalid')));
113
114 //Reset captcha token
115 $data['_captcha_token'] = $token;
116
117 //Set event data
118 $event->setData($data);
119 }
120 }
121 }