CaptchaBundle/Type/CaptchaType.php

144 lines
4.2 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\Type;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvents;
use Symfony\Contracts\Translation\TranslatorInterface;
use Gregwar\CaptchaBundle\Validator\CaptchaValidator;
2011-08-25 23:10:24 +02:00
use Gregwar\CaptchaBundle\Generator\CaptchaGenerator;
/**
2020-01-03 00:12:44 +01:00
* Captcha type.
*
* @author Gregwar <g.passault@gmail.com>
*/
class CaptchaType extends AbstractType
{
2017-03-27 21:32:00 +02:00
const SESSION_KEY_PREFIX = '_captcha_';
2017-03-19 16:40:34 +01:00
/** @var SessionInterface */
protected $session;
/** @var CaptchaGenerator */
protected $generator;
/** @var TranslatorInterface */
protected $translator;
/** @var array */
private $options = array();
/**
* @param SessionInterface $session
* @param CaptchaGenerator $generator
* @param TranslatorInterface $translator
* @param array $options
*/
public function __construct(SessionInterface $session, CaptchaGenerator $generator, TranslatorInterface $translator, $options)
{
$this->session = $session;
$this->generator = $generator;
$this->translator = $translator;
$this->options = $options;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
2012-12-04 00:54:39 +01:00
$validator = new CaptchaValidator(
$this->translator,
2012-12-04 00:54:39 +01:00
$this->session,
2017-03-19 16:40:34 +01:00
sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']),
2012-12-04 00:54:39 +01:00
$options['invalid_message'],
2012-12-04 12:20:23 +01:00
$options['bypass_code'],
$options['humanity'],
$options['request']
2012-12-04 00:54:39 +01:00
);
$builder->addEventListener(FormEvents::POST_SUBMIT, array($validator, 'validate'));
}
/**
* {@inheritdoc}
*/
2012-07-23 23:02:37 +02:00
public function buildView(FormView $view, FormInterface $form, array $options)
{
if ($options['reload'] && !$options['as_url']) {
throw new \InvalidArgumentException('GregwarCaptcha: The reload option cannot be set without as_url, see the README for more information');
}
2017-03-19 16:40:34 +01:00
$sessionKey = sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']);
2020-01-03 00:12:44 +01:00
$isHuman = false;
2014-07-21 14:46:14 +02:00
2012-12-04 12:20:23 +01:00
if ($options['humanity'] > 0) {
2014-07-29 19:03:41 +02:00
$humanityKey = sprintf('%s_humanity', $sessionKey);
2012-12-04 12:20:23 +01:00
if ($this->session->get($humanityKey, 0) > 0) {
$isHuman = true;
}
}
if ($options['as_url']) {
$keys = $this->session->get($options['whitelist_key'], array());
2014-07-29 19:03:41 +02:00
if (!in_array($sessionKey, $keys)) {
$keys[] = $sessionKey;
}
$this->session->set($options['whitelist_key'], $keys);
2014-07-29 19:03:41 +02:00
$options['session_key'] = $sessionKey;
}
$view->vars = array_merge($view->vars, array(
2020-01-03 00:12:44 +01:00
'captcha_width' => $options['width'],
'captcha_height' => $options['height'],
'reload' => $options['reload'],
'image_id' => uniqid('captcha_'),
'captcha_code' => $this->generator->getCaptchaCode($options),
'value' => '',
'is_human' => $isHuman,
));
$persistOptions = array();
foreach (array('phrase', 'width', 'height', 'distortion', 'length',
2020-01-03 00:12:44 +01:00
'quality', 'background_color', 'background_images', 'text_color', ) as $key) {
$persistOptions[$key] = $options[$key];
}
2014-07-29 19:03:41 +02:00
$this->session->set($sessionKey, $persistOptions);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
2013-02-13 18:29:40 +01:00
$this->options['mapped'] = false;
$this->options['request'] = null;
$resolver->setDefaults($this->options);
}
public function getParent(): string
{
return TextType::class;
}
public function getName(): string
{
return $this->getBlockPrefix();
}
public function getBlockPrefix(): string
{
return 'captcha';
}
}