*/ class CaptchaType extends AbstractType { const SESSION_KEY_PREFIX = '_captcha_'; /** * @var SessionInterface */ protected $session; /** * @var CaptchaGenerator */ protected $generator; /** * @var TranslatorInterface */ protected $translator; /** * Options * @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) { $validator = new CaptchaValidator( $this->translator, $this->session, sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']), $options['invalid_message'], $options['bypass_code'], $options['humanity'] ); $event = \Symfony\Component\HttpKernel\Kernel::VERSION >= 2.3 ? FormEvents::POST_SUBMIT : FormEvents::POST_BIND; $builder->addEventListener($event, array($validator, 'validate')); } /** * {@inheritdoc} */ 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'); } $sessionKey = sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']); $isHuman = false; if ($options['humanity'] > 0) { $humanityKey = sprintf('%s_humanity', $sessionKey); if ($this->session->get($humanityKey, 0) > 0) { $isHuman = true; } } if ($options['as_url']) { $keys = $this->session->get($options['whitelist_key'], array()); if (!in_array($sessionKey, $keys)) { $keys[] = $sessionKey; } $this->session->set($options['whitelist_key'], $keys); $options['session_key'] = $sessionKey; } $view->vars = array_merge($view->vars, array( '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', 'quality', 'background_color', 'text_color') as $key) { $persistOptions[$key] = $options[$key]; } $this->session->set($sessionKey, $persistOptions); } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $this->options['mapped'] = false; $resolver->setDefaults($this->options); } /** * {@inheritdoc} * BC for SF < 2.7 */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $this->configureOptions($resolver); } /** * @return string */ public function getParent() { // Not using ::class to support Symfony 2.8 w/ php>=5.3.9 return 'Symfony\Component\Form\Extension\Core\Type\TextType'; } /** * @return string */ public function getName() { return $this->getBlockPrefix(); } /** * @return string */ public function getBlockPrefix() { return 'captcha'; } }