From c6b47017b2e6b8da39f8872291e9b7a8353f332e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 9 Nov 2011 17:58:53 +0100 Subject: [PATCH] Added options for garbage collection frequency and expiration time of captcha image files. --- DependencyInjection/Configuration.php | 2 + .../GregwarCaptchaExtension.php | 2 + Generator/CaptchaGenerator.php | 41 +++++++++++++++++-- README.md | 6 ++- Resources/config/services.yml | 2 +- Type/CaptchaType.php | 18 +++++++- 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 6b52af7..a93abf4 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -25,6 +25,8 @@ class Configuration implements ConfigurationInterface ->scalarNode('as_file')->defaultValue(false)->end() ->scalarNode('image_folder')->defaultValue('captcha')->end() ->scalarNode('web_path')->defaultValue('%kernel.root_dir%/../web')->end() + ->scalarNode('gc_freq')->defaultValue(100)->end() + ->scalarNode('expiration')->defaultValue(60)->end() ->end() ; return $treeBuilder; diff --git a/DependencyInjection/GregwarCaptchaExtension.php b/DependencyInjection/GregwarCaptchaExtension.php index 76e9813..05ec528 100755 --- a/DependencyInjection/GregwarCaptchaExtension.php +++ b/DependencyInjection/GregwarCaptchaExtension.php @@ -25,6 +25,8 @@ class GregwarCaptchaExtension extends Extension $container->setParameter('gregwar_captcha.as_file', $config['as_file']); $container->setParameter('gregwar_captcha.image_folder', $config['image_folder']); $container->setParameter('gregwar_captcha.web_path', $config['web_path']); + $container->setParameter('gregwar_captcha.gc_freq', $config['gc_freq']); + $container->setParameter('gregwar_captcha.expiration', $config['expiration']); $resources = $container->getParameter('twig.form.resources'); $container->setParameter('twig.form.resources',array_merge(array('GregwarCaptchaBundle::captcha.html.twig'), $resources)); diff --git a/Generator/CaptchaGenerator.php b/Generator/CaptchaGenerator.php index afc66dd..3c3a879 100644 --- a/Generator/CaptchaGenerator.php +++ b/Generator/CaptchaGenerator.php @@ -9,15 +9,43 @@ use Symfony\Component\Finder\Finder; */ class CaptchaGenerator { + /** + * Name of folder for captcha images + * @var string + */ public $imageFolder; + + /** + * Absolute path to public web folder + * @var string + */ public $webPath; + + /** + * Frequence of garbage collection in fractions of 1 + * @var int + */ + public $gcFreq; + + /** + * Maximum age of images in minutes + * @var int + */ + public $expiration; + + /** + * The captcha code + * @var string + */ public $value; - public function __construct($value, $imageFolder, $webPath) + public function __construct($value, $imageFolder, $webPath, $gcFreq, $expiration) { $this->value = $value; $this->imageFolder = $imageFolder; $this->webPath = $webPath; + $this->gcFreq = intval($gcFreq); + $this->expiration = intval($expiration); } public function getCode($width = 120, $height = 40) @@ -35,7 +63,7 @@ class CaptchaGenerator { */ public function getFile($width = 120, $height = 40) { - if (rand(0, 10) == 5) { + if (mt_rand(1, $this->gcFreq) == 1) { $this->garbageCollection(); } @@ -51,12 +79,13 @@ class CaptchaGenerator { public function garbageCollection() { $finder = new Finder(); + $criteria = sprintf('>= now - %s minutes', $this->expiration); $finder->in($this->webPath . '/' . $this->imageFolder) - ->date('since 10 minutes ago'); + ->date($criteria); foreach($finder->files() as $file) { - @unlink($file->getPathname()); + unlink($file->getPathname()); } } @@ -133,6 +162,10 @@ class CaptchaGenerator { imagejpeg($out, null, 15); return ob_get_clean(); } else { + // Check if folder exists and create it if not + if (!file_exists($this->webPath . '/' . $this->imageFolder)) { + mkdir($this->webPath . '/' . $this->imageFolder, 0755); + } $filename = md5(uniqid()) . '.jpg'; $filepath = $this->webPath . '/' . $this->imageFolder . '/' . $filename; imagejpeg($out, $filepath, 15); diff --git a/README.md b/README.md index 8f1cd3f..29d9672 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ You can define the following type option : * **as_file**: if set to true an image file will be created instead of embedding to please IE6/7 (default=false) * **image_folder**: name of folder for captcha images relative to public web folder in case **as_file** ist set to true (default="captcha") * **web_path**: absolute path to public web folder (default="%kernel.root_dir%/../web") +* **gc_freq**: frequency of garbage collection in fractions of 1 (default=100) +* **expiration**: maximum lifetime of captcha image files in minutes (default=60) Example : @@ -142,8 +144,8 @@ The default rendering is: Image creation ============== -If you choose to use real images instead of embedded the widget will execute a garbage collection -randomly and delete images that are older than 10 minutes. +If you choose to use image files instead of embedding the widget will execute a garbage collection +randomly and delete images that exceed the configured lifetime. License ======= diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 56c1ca3..990e47b 100755 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -3,6 +3,6 @@ services: # captcha type captcha.type: class: Gregwar\CaptchaBundle\Type\CaptchaType - arguments: [ "@session", %gregwar_captcha.width%, %gregwar_captcha.height%, %gregwar_captcha.length%, %gregwar_captcha.as_file%, %gregwar_captcha.image_folder%, %gregwar_captcha.web_path% ] + arguments: [ "@session", %gregwar_captcha.width%, %gregwar_captcha.height%, %gregwar_captcha.length%, %gregwar_captcha.as_file%, %gregwar_captcha.image_folder%, %gregwar_captcha.web_path%, %gregwar_captcha.gc_freq%, %gregwar_captcha.expiration% ] tags: - { name: form.type, alias: captcha } diff --git a/Type/CaptchaType.php b/Type/CaptchaType.php index 9baac91..ffada26 100755 --- a/Type/CaptchaType.php +++ b/Type/CaptchaType.php @@ -58,6 +58,18 @@ class CaptchaType extends AbstractType */ protected $webPath; + /** + * Frequence of garbage collection in fractions of 1 + * @var int + */ + public $gcFreq; + + /** + * Maximum age of images in minutes + * @var int + */ + public $expiration; + /** * The session * @var Symfony\Component\HttpFoundation\Session @@ -67,7 +79,7 @@ class CaptchaType extends AbstractType private $key = 'captcha'; - public function __construct(Session $session, $width, $height, $length, $asFile, $imageFolder, $webPath) + public function __construct(Session $session, $width, $height, $length, $asFile, $imageFolder, $webPath, $gcFreq, $expiration) { $this->session = $session; $this->width = $width; @@ -76,6 +88,8 @@ class CaptchaType extends AbstractType $this->asFile = $asFile; $this->imageFolder = $imageFolder; $this->webPath = $webPath; + $this->gcFreq = $gcFreq; + $this->expiration = $expiration; } public function buildForm(FormBuilder $builder, array $options) @@ -87,7 +101,7 @@ class CaptchaType extends AbstractType public function buildView(FormView $view, FormInterface $form) { - $generator = new CaptchaGenerator($this->generateCaptchaValue(), $this->imageFolder, $this->webPath); + $generator = new CaptchaGenerator($this->generateCaptchaValue(), $this->imageFolder, $this->webPath, $this->gcFreq, $this->expiration); if ($this->asFile) { $view->set('captcha_code', $generator->getFile($this->width, $this->height));