Adding option "humanity" (fixes #40)

This commit is contained in:
Gregwar 2012-12-04 12:20:23 +01:00
parent 3794a12e80
commit 11fe650bde
5 changed files with 40 additions and 2 deletions

View File

@ -36,6 +36,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('invalid_message')->defaultValue('Bad code value')->end() ->scalarNode('invalid_message')->defaultValue('Bad code value')->end()
->scalarNode('bypass_code')->defaultValue(null)->end() ->scalarNode('bypass_code')->defaultValue(null)->end()
->scalarNode('whitelist_key')->defaultValue('captcha_whitelist_key')->end() ->scalarNode('whitelist_key')->defaultValue('captcha_whitelist_key')->end()
->scalarNode('humanity')->defaultValue(0)->end()
->end() ->end()
; ;

View File

@ -133,6 +133,7 @@ You can define the following configuration options globally or on the CaptchaTyp
* **invalid_message**: error message displayed when an non-matching code is submitted (default="Bad code value") * **invalid_message**: error message displayed when an non-matching code is submitted (default="Bad code value")
* **bypass_code**: code that will always validate the captcha (default=null) * **bypass_code**: code that will always validate the captcha (default=null)
* **whitelist_key**: the session key to use for keep the session keys that can be used for captcha storage, when using as_url (default=captcha_whitelist_key) * **whitelist_key**: the session key to use for keep the session keys that can be used for captcha storage, when using as_url (default=captcha_whitelist_key)
* **humanity**: number of extra forms that the user can submit after a correct validation, if set to a value different of 0, only 1 over (1+humanity) forms will contain a CAPTCHA (default=0, i.e each form will contain the CAPTCHA)
Example : Example :

View File

@ -1,7 +1,11 @@
{% block captcha_widget %} {% block captcha_widget %}
{% if is_human %}
-
{% else %}
{% spaceless %} {% spaceless %}
<img src="{{ captcha_code }}" alt="" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" /> <img src="{{ captcha_code }}" alt="" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />
{{ form_widget(form) }} {{ form_widget(form) }}
{% endspaceless %} {% endspaceless %}
{% endif %}
{% endblock %} {% endblock %}

View File

@ -66,7 +66,8 @@ class CaptchaType extends AbstractType
$this->session, $this->session,
$this->key, $this->key,
$options['invalid_message'], $options['invalid_message'],
$options['bypass_code'] $options['bypass_code'],
$options['humanity']
); );
$builder->addEventListener(FormEvents::POST_BIND, array($validator, 'validate')); $builder->addEventListener(FormEvents::POST_BIND, array($validator, 'validate'));
@ -79,11 +80,21 @@ class CaptchaType extends AbstractType
*/ */
public function buildView(FormView $view, FormInterface $form, array $options) public function buildView(FormView $view, FormInterface $form, array $options)
{ {
$isHuman = false;
if ($options['humanity'] > 0) {
$humanityKey = $this->key.'_humanity';
if ($this->session->get($humanityKey, 0) > 0) {
$isHuman = true;
}
}
$view->vars = array_merge($view->vars, array( $view->vars = array_merge($view->vars, array(
'captcha_width' => $options['width'], 'captcha_width' => $options['width'],
'captcha_height' => $options['height'], 'captcha_height' => $options['height'],
'captcha_code' => $this->generator->getCaptchaCode($this->key, $options), 'captcha_code' => $this->generator->getCaptchaCode($this->key, $options),
'value' => '', 'value' => '',
'is_human' => $isHuman
)); ));
} }

View File

@ -33,18 +33,25 @@ class CaptchaValidator
*/ */
private $bypassCode; private $bypassCode;
/**
* Number of form that the user can submit without captcha
* @var int
*/
private $humanity;
/** /**
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session * @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
* @param string $key * @param string $key
* @param string $invalidMessage * @param string $invalidMessage
* @param string|null $bypassCode * @param string|null $bypassCode
*/ */
public function __construct(SessionInterface $session, $key, $invalidMessage, $bypassCode) public function __construct(SessionInterface $session, $key, $invalidMessage, $bypassCode, $humanity)
{ {
$this->session = $session; $this->session = $session;
$this->key = $key; $this->key = $key;
$this->invalidMessage = $invalidMessage; $this->invalidMessage = $invalidMessage;
$this->bypassCode = $bypassCode; $this->bypassCode = $bypassCode;
$this->humanity = $humanity;
} }
/** /**
@ -53,12 +60,26 @@ class CaptchaValidator
public function validate(FormEvent $event) public function validate(FormEvent $event)
{ {
$form = $form = $event->getForm(); $form = $form = $event->getForm();
$humanityKey = $this->key . '_humanity';
$code = $form->getData(); $code = $form->getData();
$expectedCode = $this->getExpectedCode(); $expectedCode = $this->getExpectedCode();
if ($this->humanity > 0) {
if ($this->session->get($humanityKey, 0) > 0) {
$this->session->set($humanityKey, $this->session->get($humanityKey, 0)-1);
return;
} else {
$this->session->remove($humanityKey);
}
}
if (!($code && is_string($code) && ($this->compare($code, $expectedCode) || $this->compare($code, $this->bypassCode)))) { if (!($code && is_string($code) && ($this->compare($code, $expectedCode) || $this->compare($code, $this->bypassCode)))) {
$form->addError(new FormError($this->invalidMessage)); $form->addError(new FormError($this->invalidMessage));
} else {
if ($this->humanity > 0) {
$this->session->set($humanityKey, $this->humanity);
}
} }
$this->session->remove($this->key); $this->session->remove($this->key);