Cleaning session usage to keep options during as_url (fixes #41)
This commit is contained in:
parent
2e17d9c035
commit
42f6e92560
|
@ -42,7 +42,15 @@ class CaptchaController extends Controller
|
||||||
/* @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator $generator */
|
/* @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator $generator */
|
||||||
$generator = $this->container->get('gregwar_captcha.generator');
|
$generator = $this->container->get('gregwar_captcha.generator');
|
||||||
|
|
||||||
$response = new Response($generator->generate($key, $options));
|
$persistedOptions = $session->get($key, array());
|
||||||
|
$options = array_merge($options, $persistedOptions);
|
||||||
|
|
||||||
|
$phrase = $generator->getPhrase($options);
|
||||||
|
$generator->setPhrase($phrase);
|
||||||
|
$persistedOptions['phrase'] = $phrase;
|
||||||
|
$session->set($key, $persistedOptions);
|
||||||
|
|
||||||
|
$response = new Response($generator->generate($options));
|
||||||
$response->headers->set('Content-type', 'image/jpeg');
|
$response->headers->set('Content-type', 'image/jpeg');
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
|
|
|
@ -17,17 +17,6 @@ use Gregwar\Captcha\PhraseBuilderInterface;
|
||||||
*/
|
*/
|
||||||
class CaptchaGenerator
|
class CaptchaGenerator
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var \Symfony\Component\HttpFoundation\Session\SessionInterface
|
|
||||||
*/
|
|
||||||
protected $session;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the whitelist key
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $whitelistKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\Routing\RouterInterface
|
* @var \Symfony\Component\Routing\RouterInterface
|
||||||
*/
|
*/
|
||||||
|
@ -49,20 +38,16 @@ class CaptchaGenerator
|
||||||
protected $imageFileHandler;
|
protected $imageFileHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
|
|
||||||
* @param \Symfony\Component\Routing\RouterInterface $router
|
* @param \Symfony\Component\Routing\RouterInterface $router
|
||||||
* @param CaptchaBuilderInterface $builder
|
* @param CaptchaBuilderInterface $builder
|
||||||
* @param ImageFileHandlerInterface $imageFileHandler
|
* @param ImageFileHandlerInterface $imageFileHandler
|
||||||
* @param string $whitelistKey
|
|
||||||
*/
|
*/
|
||||||
public function __construct(SessionInterface $session, RouterInterface $router, CaptchaBuilderInterface $builder, PhraseBuilderInterface $phraseBuilder, ImageFileHandler $imageFileHandler, $whitelistKey)
|
public function __construct(RouterInterface $router, CaptchaBuilderInterface $builder, PhraseBuilderInterface $phraseBuilder, ImageFileHandler $imageFileHandler)
|
||||||
{
|
{
|
||||||
$this->session = $session;
|
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
$this->builder = $builder;
|
$this->builder = $builder;
|
||||||
$this->phraseBuilder = $phraseBuilder;
|
$this->phraseBuilder = $phraseBuilder;
|
||||||
$this->imageFileHandler = $imageFileHandler;
|
$this->imageFileHandler = $imageFileHandler;
|
||||||
$this->whitelistKey = $whitelistKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,26 +58,31 @@ class CaptchaGenerator
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getCaptchaCode($key, array $options)
|
public function getCaptchaCode(array &$options)
|
||||||
{
|
{
|
||||||
|
$this->builder->setPhrase($this->getPhrase($options));
|
||||||
|
|
||||||
// Randomly execute garbage collection and returns the image filename
|
// Randomly execute garbage collection and returns the image filename
|
||||||
if ($options['as_file']) {
|
if ($options['as_file']) {
|
||||||
$this->imageFileHandler->collectGarbage();
|
$this->imageFileHandler->collectGarbage();
|
||||||
|
|
||||||
return $this->generate($key, $options);
|
return $this->generate($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the image generation URL
|
// Returns the image generation URL
|
||||||
if ($options['as_url']) {
|
if ($options['as_url']) {
|
||||||
$keys = $this->session->get($this->whitelistKey, array());
|
return $this->router->generate('gregwar_captcha.generate_captcha', array('key' => $options['session_key']));
|
||||||
if (!in_array($key, $keys)) {
|
|
||||||
$keys[] = $key;
|
|
||||||
}
|
|
||||||
$this->session->set($this->whitelistKey, $keys);
|
|
||||||
return $this->router->generate('gregwar_captcha.generate_captcha', array('key' => $key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'data:image/jpeg;base64,' . base64_encode($this->generate($key, $options));
|
return 'data:image/jpeg;base64,' . base64_encode($this->generate($options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the phrase to the builder
|
||||||
|
*/
|
||||||
|
public function setPhrase($phrase)
|
||||||
|
{
|
||||||
|
$this->builder->setPhrase($phrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,12 +91,12 @@ class CaptchaGenerator
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function generate($key, array $options)
|
public function generate(array &$options)
|
||||||
{
|
{
|
||||||
$fingerprint = $this->getFingerprint($key, $options);
|
|
||||||
|
|
||||||
$this->builder->setDistortion($options['distortion']);
|
$this->builder->setDistortion($options['distortion']);
|
||||||
|
|
||||||
|
$fingerprint = isset($options['fingerprint']) ? $options['fingerprint'] : null;
|
||||||
|
|
||||||
$content = $this->builder->build(
|
$content = $this->builder->build(
|
||||||
$options['width'],
|
$options['width'],
|
||||||
$options['height'],
|
$options['height'],
|
||||||
|
@ -115,7 +105,7 @@ class CaptchaGenerator
|
||||||
)->getGd();
|
)->getGd();
|
||||||
|
|
||||||
if ($options['keep_value']) {
|
if ($options['keep_value']) {
|
||||||
$this->session->set($key . '_fingerprint', $this->builder->getFingerprint());
|
$options['fingerprint'] = $this->builder->getFingerprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$options['as_file']) {
|
if (!$options['as_file']) {
|
||||||
|
@ -134,33 +124,17 @@ class CaptchaGenerator
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getPhrase($key, array $options)
|
public function getPhrase(array &$options)
|
||||||
{
|
{
|
||||||
// Get the phrase that we'll use for this image
|
// Get the phrase that we'll use for this image
|
||||||
if ($options['keep_value'] && $this->session->has($key)) {
|
if ($options['keep_value'] && isset($options['phrase'])) {
|
||||||
return $this->session->get($key);
|
$phrase = $options['phrase'];
|
||||||
|
} else {
|
||||||
|
$phrase = $this->phraseBuilder->build($options['length'], $options['charset']);
|
||||||
|
$options['phrase'] = $phrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
$phrase = $this->phraseBuilder->build($options['length'], $options['charset']);
|
|
||||||
$this->session->set($key, $phrase);
|
|
||||||
$this->captchaBuilder->setPhrase($phrase);
|
|
||||||
|
|
||||||
return $phrase;
|
return $phrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $key
|
|
||||||
* @param array $options
|
|
||||||
*
|
|
||||||
* @return array|null
|
|
||||||
*/
|
|
||||||
protected function getFingerprint($key, array $options)
|
|
||||||
{
|
|
||||||
if ($options['keep_value'] && $this->session->has($key . '_fingerprint')) {
|
|
||||||
return $this->session->get($key . '_fingerprint');
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,10 @@ services:
|
||||||
gregwar_captcha.generator:
|
gregwar_captcha.generator:
|
||||||
class: Gregwar\CaptchaBundle\Generator\CaptchaGenerator
|
class: Gregwar\CaptchaBundle\Generator\CaptchaGenerator
|
||||||
arguments:
|
arguments:
|
||||||
- @session
|
|
||||||
- @router
|
- @router
|
||||||
- @gregwar_captcha.captcha_builder
|
- @gregwar_captcha.captcha_builder
|
||||||
- @gregwar_captcha.phrase_builder
|
- @gregwar_captcha.phrase_builder
|
||||||
- @gregwar_captcha.image_file_handler
|
- @gregwar_captcha.image_file_handler
|
||||||
- %gregwar_captcha.config.whitelist_key%
|
|
||||||
|
|
||||||
gregwar_captcha.image_file_handler:
|
gregwar_captcha.image_file_handler:
|
||||||
class: Gregwar\CaptchaBundle\Generator\ImageFileHandler
|
class: Gregwar\CaptchaBundle\Generator\ImageFileHandler
|
||||||
|
|
|
@ -89,15 +89,32 @@ class CaptchaType extends AbstractType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['as_url']) {
|
||||||
|
$key = $this->key;
|
||||||
|
$keys = $this->session->get($options['whitelist_key'], array());
|
||||||
|
if (!in_array($key, $keys)) {
|
||||||
|
$keys[] = $key;
|
||||||
|
}
|
||||||
|
$this->session->set($options['whitelist_key'], $keys);
|
||||||
|
$options['session_key'] = $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
$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'],
|
||||||
'reload' => $options['reload'],
|
'reload' => $options['reload'],
|
||||||
'image_id' => uniqid('captcha_'),
|
'image_id' => uniqid('captcha_'),
|
||||||
'captcha_code' => $this->generator->getCaptchaCode($this->key, $options),
|
'captcha_code' => $this->generator->getCaptchaCode($options),
|
||||||
'value' => '',
|
'value' => '',
|
||||||
'is_human' => $isHuman
|
'is_human' => $isHuman
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$persistOptions = array();
|
||||||
|
foreach (array('phrase', 'width', 'height', 'distortion', 'quality') as $key) {
|
||||||
|
$persistOptions[$key] = $options[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->session->set($this->key, $persistOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -60,17 +60,15 @@ 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->humanity > 0) {
|
||||||
if ($this->session->get($humanityKey, 0) > 0) {
|
$humanity = $this->getHumanity();
|
||||||
$this->session->set($humanityKey, $this->session->get($humanityKey, 0)-1);
|
if ($humanity > 0) {
|
||||||
|
$this->updateHumanity($humanity-1);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
$this->session->remove($humanityKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +76,7 @@ class CaptchaValidator
|
||||||
$form->addError(new FormError($this->invalidMessage));
|
$form->addError(new FormError($this->invalidMessage));
|
||||||
} else {
|
} else {
|
||||||
if ($this->humanity > 0) {
|
if ($this->humanity > 0) {
|
||||||
$this->session->set($humanityKey, $this->humanity);
|
$this->updateHumanity($this->humanity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +94,34 @@ class CaptchaValidator
|
||||||
*/
|
*/
|
||||||
protected function getExpectedCode()
|
protected function getExpectedCode()
|
||||||
{
|
{
|
||||||
if ($this->session->has($this->key)) {
|
$options = $this->session->get($this->key, array());
|
||||||
return $this->session->get($this->key);
|
|
||||||
|
if (is_array($options) && isset($options['phrase'])) {
|
||||||
|
return $options['phrase'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retreive the humanity
|
||||||
|
*
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
protected function getHumanity()
|
||||||
|
{
|
||||||
|
return $this->session->get($this->key . '_humanity', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the humanity
|
||||||
|
*/
|
||||||
|
protected function updateHumanity($newValue)
|
||||||
|
{
|
||||||
|
if ($newValue > 0) {
|
||||||
|
$this->session->set($this->key . '_humanity', $newValue);
|
||||||
|
} else {
|
||||||
|
$this->session->remove($this->key . '_humanity');
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in New Issue