Compare commits

...

100 Commits
v1.1 ... master

Author SHA1 Message Date
5778c54ae0 Add missing initialization 2022-02-09 10:19:13 +01:00
9b65966d27 update composer.json 2021-05-28 11:53:54 +02:00
633e30ae47 Add flow registration validation support 2021-05-28 08:08:42 +02:00
Grégoire Passault
2f96c759ab
Merge pull request #223 from Gemorroj/patch-1
php 8 support
2021-04-20 09:20:37 +02:00
Gemorroj
2769e4791a
php 8 support
#222
2021-04-18 12:06:03 +03:00
Gregwar
5e434e1859 gregwar/captcha version bump 2021-01-09 01:01:13 +01:00
Gregwar
df6915eb5e README details 2020-04-28 10:45:36 +02:00
Gregwar
b7685e63a1 README indentation 2020-04-28 10:44:39 +02:00
Gregwar
15bee25e9c Indentation in README 2020-04-28 10:43:03 +02:00
Gregwar
3a4e31473a Adding some note about session_key option for multiple captcha on same
page
2020-04-17 16:13:37 +02:00
Gregwar
fec0ebb2f1 Autowire controller 2020-04-09 10:18:10 +02:00
Grégoire Passault
cdbe566acc
Merge pull request #212 from l-vo/bundle_auto_registration
Fix flex auto-registration
2020-03-02 11:00:37 +01:00
Laurent VOULLEMIER
93f9d3c1a7 Fix flex auto-registration 2020-02-29 20:31:09 +01:00
Gregwar
d4475118d0 Merge branch 'master' of github.com:Gregwar/CaptchaBundle 2020-01-14 11:15:40 +01:00
Gregwar
b8a129fc2a Adding controller class in services.yml 2020-01-14 11:14:42 +01:00
Grégoire Passault
fe4b0dea2b
Merge pull request #210 from alexander-schranz/patch-1
Fix compatibility table
2020-01-14 10:06:23 +01:00
Alexander Schranz
640acadeea
Fix compatibility table 2020-01-13 18:35:47 +01:00
Grégoire Passault
a22ba77f52
Merge pull request #208 from Olaf1989/symfony-5
Fully support Symfony 4 and 5
2020-01-08 16:31:01 +01:00
Olaf
459a108ee6 docs (Readme) update README.md 2020-01-03 01:07:49 +01:00
Olaf
3691a30240 chore (Packages) allow Symfony 4 and PHP 7.1 2020-01-03 01:01:41 +01:00
Olaf
2012808bc6 docs (Readme) update README.md 2020-01-03 00:43:31 +01:00
Olaf
2b62be4af1 fix (Symfony) use Symfony 5 web_path 2020-01-03 00:42:56 +01:00
Olaf
3f25597f94 Merge branch 'symfony-5' of https://github.com/Olaf1989/CaptchaBundle into symfony-5 2020-01-03 00:17:34 +01:00
Olaf
478c64633e fix (ECS) apply coding standard 2020-01-03 00:12:44 +01:00
Olaf
2ed4f74954 chore (ECS) add easy coding standard 2020-01-03 00:09:09 +01:00
Olaf
60c0e04366
Delete composer.lock 2020-01-03 00:05:31 +01:00
Olaf
61a8561dd6 fix (Captcha) allow null value for bypassCode 2020-01-03 00:04:18 +01:00
Olaf
5515c25872 chore (Symfony) use Symfony 5 + strict typing
Update Symfony version to 5
Use strict typing
2019-12-30 00:27:20 +01:00
Gregwar
eeb01bdca5 Typo 2019-12-02 10:24:14 +01:00
Grégoire Passault
678459f58f
Merge pull request #205 from tacman/patch-1
Support Symfony 5, drop support for Symfony 2
2019-12-02 10:23:50 +01:00
tacman
1781a6aa62
Support Symfony 5, drop support for Symfony 2 2019-12-01 08:00:17 -05:00
Grégoire Passault
3ccfdf1c93
Merge pull request #200 from adamwojs/fix_deprecated_tree_builder_root_call
Fixed deprecated TreeBuilder::root method call in SF 4
2019-09-23 15:07:46 +02:00
Grégoire Passault
b703ed1a0c
Merge pull request #201 from adamwojs/fix_deprecated_spacelesss_tag
Removed deprecated spaceless tag
2019-09-23 15:07:20 +02:00
Adam Wójs
25de43ac90 Removed deprecated spaceless tag 2019-09-22 13:59:41 +02:00
Adam Wójs
1b4835eb4d Fixed deprecated TreeBuilder::root method call in SF 4 2019-09-22 13:10:16 +02:00
Grégoire Passault
be1ce45060
Merge pull request #196 from ferdynator/master
Fixes deprecation warnings in Symfony 4.2
2019-08-15 18:04:18 +02:00
Frederik Schubert
0f6cd70920
Fixed deprecation warning 2019-01-23 11:01:56 +01:00
Frederik Schubert
754310f488
Fixed deprecation warning 2019-01-23 11:01:17 +01:00
Grégoire Passault
c2d5468556
Merge pull request #172 from cengizhancaliskan/master
Support of multiple instance
2018-11-20 11:41:34 +01:00
Grégoire Passault
980afdc10a
Merge pull request #187 from mandalor-development/master
Changed template reference
2018-04-24 11:22:05 +02:00
Mandalor-Development
791128c0fd Changed template reference
According to:
https://symfony.com/doc/current/templating.html#referencing-templates-in-a-bundle

Fixed error:
[critical] Uncaught PHP Exception Twig_Error_Loader: "Unable to find template "GregwarCaptchaBundle::captcha.html.twig" (looked into: /[path]/templates, /[path]/templates, /[path]/vendor/symfony/twig-bridge/Resources/views/Form)." at /[path]/templates/form.html.twig line 17
2018-02-28 15:15:55 +01:00
Grégoire Passault
639430383f
Merge pull request #180 from andreybolonin/master
add sf 4.0 support
2017-12-28 12:21:03 +01:00
andreybolonin
8e98c5c0ab add public services 2017-12-28 12:30:19 +02:00
andreybolonin
539884cd5d add sf 4.0 support 2017-11-27 18:08:24 +02:00
Gregwar
8ce4adb1b1 Adding background_images in persisted options (fixes #175) 2017-10-02 11:12:17 +02:00
Gregwar
b787a8002e Rising default quality to 50 2017-09-27 12:01:02 +02:00
Cengizhan Çalışkan
ba9c0e6166 Change session key for as_url option 2017-03-27 22:32:00 +03:00
Cengizhan Çalışkan
25b8840f2a Support of multiple instance 2017-03-19 18:40:34 +03:00
Grégoire Passault
045ba7e67e Merge pull request #150 from dprolife/patch-1
Update composer.json
2017-02-23 10:26:22 +01:00
Gregwar
18c85d3a4f donate 2016-10-24 12:05:50 +02:00
Gregwar
f6c45045f0 Adding class captcha_image on the <img> captcha tag (see #160) 2016-09-21 10:36:55 +02:00
Gregwar
f95a951b26 Detail 2016-08-05 20:07:20 +02:00
Grégoire Passault
e1ed228b8b Merge pull request #168 from linnaea/patch-1
Quote parameter references in services.yml
2016-05-30 12:28:28 +02:00
Linnaea Von Lavia
0b3495a081 Quote parameter references in services.yml
Not quoting a scalar starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.
2016-05-28 22:40:00 +08:00
Grégoire Passault
53c25b2e9a Merge pull request #163 from hackzilla/master
Update CaptchaType.php
2016-02-02 23:40:33 +01:00
Daniel Platt
fcf8c4fd01 Update CaptchaType.php
add getBlockPrefix for Symfony3 compatibility.
2016-02-02 22:15:18 +00:00
Grégoire Passault
e91cb1a3b7 Merge pull request #139 from RicoVZ/patch-1
Replaced usage of "pattern" with "path"
2015-12-30 19:19:50 +01:00
dprolife
1f6c80c326 Update composer.json
Fix symfony requirements
2015-12-17 22:51:31 +01:00
Gregwar
f06ff4d2c2 Clarification 2015-12-13 12:12:45 +01:00
Gregwar
42cb26794d Getting compatible with php>=5.3.9 2015-12-13 12:10:14 +01:00
Gregwar
e10494a767 Using | instead of || 2015-12-13 12:03:17 +01:00
Gregwar
8682eee873 README 2015-12-11 10:02:21 +01:00
Gregwar
c508d510ff README (see #148) 2015-12-11 10:01:40 +01:00
Gregwar
d328f215b2 Merge branch 'master' of github.com:Gregwar/CaptchaBundle 2015-12-07 14:25:30 +01:00
Gregwar
a26f03cc93 Using php 5.5 as a dependency because of ::class (see #148) 2015-12-07 14:25:06 +01:00
Gregwar
1862776c9a Supporting v3 2015-12-06 23:20:09 +01:00
Gregwar
c989422a82 Clarifying readme 2015-12-06 23:10:05 +01:00
Gregwar
52107b0c32 Using ::class instead of type alias (working w/ sf3, see #148) 2015-12-06 23:07:05 +01:00
Grégoire Passault
e335e2a924 Merge pull request #149 from Restless-ET/patch-1
Fix YAML syntax in services.yml file
2015-12-05 14:22:11 +01:00
Restless-ET
0971f224f4 Fix YAML syntax in services.yml file
The '@' character is supposed to be a reserved indicator for YAML. Therefore when using it at the beginning of a string (as in this case) we should enclose it in quotes.
http://yaml.org/spec/1.2/spec.html#id2774228

Also, since Symfony 2.8 this kind of usage is already marked as deprecated: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#yaml
2015-12-05 00:52:50 +00:00
Grégoire Passault
29610bb574 Merge pull request #145 from verschoof/patch-1
Update README.md
2015-10-29 11:14:06 +01:00
Mitchel
018fdd3f35 Update README.md
Added composer require instead of the manual way.
Composer require will search the latest version and install it for you.
2015-10-29 10:15:34 +01:00
Grégoire Passault
476530a212 Merge pull request #141 from max-kovpak/patch-2
POST_BIND deprecated
2015-09-25 09:21:54 +02:00
Max Kovpak
87d38d98a4 Update CaptchaType.php
Checkout version
2015-08-26 11:26:01 +03:00
Max Kovpak
3cc4b072c3 POST_BIND deprecated
POST_BIND deprecated since version 2.3, to be removed in 3.0. Use POST_SUBMIT instead.
2015-08-25 17:15:15 +03:00
Grégoire Passault
0f5e9870f1 Merge pull request #140 from max-kovpak/patch-1
Make it more unique
2015-08-25 16:06:15 +02:00
Max Kovpak
c844cbcdbc Update CaptchaGenerator.php 2015-08-25 17:05:28 +03:00
Max Kovpak
50405a74a1 Make it more unique
If you have 2 forms on one page time will be not unique
2015-08-25 16:57:49 +03:00
Grégoire Passault
84760b0a9f Merge pull request #136 from StudioMaX/patch-1
Add configureOptions method to form types for SF 2.7
2015-08-18 20:19:33 +02:00
RicoVZ
ef281889ab Replaced usage of "pattern" with "path"
As described in issue #135
2015-08-18 09:48:41 +02:00
Grégoire Passault
8468f93194 Merge pull request #81 from ChessCom/master
Add the option of custom background images for the captcha
2015-08-13 12:30:47 +02:00
Grégoire Passault
fe1102f5c6 Merge pull request #138 from Burakhan/master
Adding Turkish language translate
2015-08-10 12:05:33 +02:00
Burakhan
f1fdfc142f Adding Turkish language translate 2015-08-10 11:15:05 +03:00
StudioMaX
2e49f50c1a Add configureOptions method to form types for SF 2.7 2015-07-09 22:19:21 +06:00
Grégoire Passault
8d3ee7334f Merge pull request #130 from amouhzi/patch-1
Arabic translations: gregwar_captcha.ar.yml
2015-05-28 00:16:52 +02:00
Grégoire Passault
805e77f24a Merge pull request #131 from amouhzi/patch-2
Arabic translations: validators.ar.yml
2015-05-28 00:15:59 +02:00
Hassan Amouhzi
adab98ad84 Arabic translations: validators.ar.yml 2015-05-27 22:49:51 +02:00
Hassan Amouhzi
4040d06508 Arabic translations: gregwar_captcha.ar.yml 2015-05-27 22:45:26 +02:00
Gregwar
448b812f65 Fixing captcha url (broken in #128, see also #129) 2015-05-25 11:41:13 +02:00
Grégoire Passault
4aba359e71 Merge pull request #128 from piotrantosik/master
Don't cache captcha image
2015-05-22 18:00:07 +02:00
Piotr Antosik
8c39274fa4 don't cache captcha image 2015-05-22 15:01:00 +02:00
Ivan Lackovic
232168d408 remove comments 2015-05-19 20:20:14 +02:00
Ivan Lackovic
6a147a2ea3 Merge remote-tracking branch 'upstream/master' 2015-05-13 16:24:05 +02:00
Ivan Lackovic
3d1383e8ae Merge remote-tracking branch 'upstream/master' 2014-09-04 14:04:51 +02:00
Ivan Lackovic
798f29e635 Merge remote-tracking branch 'upstream/master'
Conflicts:
	DependencyInjection/Configuration.php
2014-03-19 16:27:04 +01:00
lackovic10
34a84af209 README.md - updated docs, added background images and ignore all effects descriptions 2013-09-26 21:22:02 +02:00
lackovic10
3ad62e4d0d added ignore_all_effects to configuration 2013-09-26 21:10:02 +02:00
lackovic10
a16743a230 added background_images to configuration 2013-09-26 20:38:39 +02:00
lackovic10
4f46a609ba Revert "composer.json - updated to use a gregwar/captcha fork (chesscom)"
This reverts commit b085af6e0078d216d048422bb5816ce06ae1bd21.
2013-09-26 17:28:48 +02:00
lackovic10
b085af6e00 composer.json - updated to use a gregwar/captcha fork (chesscom) 2013-09-25 20:53:52 +02:00
18 changed files with 478 additions and 374 deletions

View File

@ -1,32 +1,37 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Gregwar\CaptchaBundle\Generator\CaptchaGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Generates a captcha via a URL
* Generates a captcha via a URL.
*
* @author Jeremy Livingston <jeremy.j.livingston@gmail.com>
*/
class CaptchaController extends Controller
class CaptchaController extends AbstractController
{
/**
* Action that is used to generate the captcha, save its code, and stream the image
*
* @param string $key
*
* @return Response
*
* @throws NotFoundHttpException
*/
public function generateCaptchaAction($key)
/** @var CaptchaGenerator */
private $captchaGenerator;
/** @var array */
private $config;
public function __construct(CaptchaGenerator $captchaGenerator, array $config)
{
$options = $this->container->getParameter('gregwar_captcha.config');
$session = $this->get('session');
$whitelistKey = $options['whitelist_key'];
$this->captchaGenerator = $captchaGenerator;
$this->config = $config;
}
public function generateCaptchaAction(Request $request, string $key): Response
{
$session = $request->getSession();
$whitelistKey = $this->config['whitelist_key'];
$isOk = false;
if ($session->has($whitelistKey)) {
@ -37,21 +42,18 @@ class CaptchaController extends Controller
}
if (!$isOk) {
return $this->error($options);
return $this->error($this->config);
}
/* @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator $generator */
$generator = $this->container->get('gregwar_captcha.generator');
$persistedOptions = $session->get($key, array());
$options = array_merge($options, $persistedOptions);
$options = array_merge($this->config, $persistedOptions);
$phrase = $generator->getPhrase($options);
$generator->setPhrase($phrase);
$phrase = $this->captchaGenerator->getPhrase($options);
$this->captchaGenerator->setPhrase($phrase);
$persistedOptions['phrase'] = $phrase;
$session->set($key, $persistedOptions);
$response = new Response($generator->generate($options));
$response = new Response($this->captchaGenerator->generate($options));
$response->headers->set('Content-type', 'image/jpeg');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Cache-Control', 'no-cache');
@ -59,20 +61,11 @@ class CaptchaController extends Controller
return $response;
}
/**
* Returns an empty image with status code 428 Precondition Required
*
* @param array $options
*
* @return Response
*/
protected function error($options)
private function error(array $options): Response
{
/* @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator $generator */
$generator = $this->container->get('gregwar_captcha.generator');
$generator->setPhrase('');
$this->captchaGenerator->setPhrase('');
$response = new Response($generator->generate($options));
$response = new Response($this->captchaGenerator->generate($options));
$response->setStatusCode(428);
$response->headers->set('Content-type', 'image/jpeg');
$response->headers->set('Pragma', 'no-cache');

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@ -7,15 +9,10 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
/**
* Generates the configuration tree.
*
* @return TreeBuilder
*/
public function getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('gregwar_captcha');
$treeBuilder = new TreeBuilder('gregwar_captcha');
$rootNode = $treeBuilder->getRootNode();
$rootNode
->addDefaultsIfNotSet()
@ -30,10 +27,10 @@ class Configuration implements ConfigurationInterface
->scalarNode('as_url')->defaultValue(false)->end()
->scalarNode('reload')->defaultValue(false)->end()
->scalarNode('image_folder')->defaultValue('captcha')->end()
->scalarNode('web_path')->defaultValue('%kernel.root_dir%/../web')->end()
->scalarNode('web_path')->defaultValue('%kernel.project_dir%/public')->end()
->scalarNode('gc_freq')->defaultValue(100)->end()
->scalarNode('expiration')->defaultValue(60)->end()
->scalarNode('quality')->defaultValue(30)->end()
->scalarNode('quality')->defaultValue(50)->end()
->scalarNode('invalid_message')->defaultValue('Bad code value')->end()
->scalarNode('bypass_code')->defaultValue(null)->end()
->scalarNode('whitelist_key')->defaultValue('captcha_whitelist_key')->end()
@ -44,7 +41,10 @@ class Configuration implements ConfigurationInterface
->scalarNode('interpolation')->defaultValue(true)->end()
->arrayNode('text_color')->prototype('scalar')->end()->end()
->arrayNode('background_color')->prototype('scalar')->end()->end()
->arrayNode('background_images')->prototype('scalar')->end()->end()
->scalarNode('disabled')->defaultValue(false)->end()
->scalarNode('ignore_all_effects')->defaultValue(false)->end()
->scalarNode('session_key')->defaultValue('captcha')->end()
->end()
;

View File

@ -1,24 +1,29 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\DependencyInjection;
use Exception;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
/**
* Extension used to load the configuration, set parameters, and initialize the captcha view
* Extension used to load the configuration, set parameters, and initialize the captcha view.
*
* @author Gregwar <g.passault@gmail.com>
*/
class GregwarCaptchaExtension extends Extension
{
/**
* @param array $configs
* @param array $configs
* @param ContainerBuilder $container
*
* @throws Exception
*/
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
@ -34,6 +39,6 @@ class GregwarCaptchaExtension extends Extension
$container->setParameter('gregwar_captcha.config.whitelist_key', $config['whitelist_key']);
$resources = $container->getParameter('twig.form.resources');
$container->setParameter('twig.form.resources', array_merge(array('GregwarCaptchaBundle::captcha.html.twig'), $resources));
$container->setParameter('twig.form.resources', array_merge(array('@GregwarCaptcha/captcha.html.twig'), $resources));
}
}

View File

@ -1,48 +1,40 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\Generator;
use Gregwar\Captcha\CaptchaBuilder;
use Gregwar\Captcha\PhraseBuilder;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Gregwar\Captcha\CaptchaBuilderInterface;
use Gregwar\Captcha\PhraseBuilderInterface;
/**
* Uses configuration parameters to call the services that generate captcha images
* Uses configuration parameters to call the services that generate captcha images.
*
* @author Gregwar <g.passault@gmail.com>
* @author Jeremy Livingston <jeremy.j.livingston@gmail.com>
*/
class CaptchaGenerator
{
/**
* @var RouterInterface
*/
/** @var RouterInterface */
protected $router;
/**
* @var CaptchaBuilder
*/
/** @var CaptchaBuilder */
protected $builder;
/**
* @var PhraseBuilder
*/
/** @var PhraseBuilder */
protected $phraseBuilder;
/**
* @var ImageFileHandler
*/
/** @var ImageFileHandler */
protected $imageFileHandler;
/**
* @param RouterInterface $router
* @param RouterInterface $router
* @param CaptchaBuilderInterface $builder
* @param PhraseBuilderInterface $phraseBuilder
* @param ImageFileHandler $imageFileHandler
* @param PhraseBuilderInterface $phraseBuilder
* @param ImageFileHandler $imageFileHandler
*/
public function __construct(
RouterInterface $router,
@ -50,20 +42,13 @@ class CaptchaGenerator
PhraseBuilderInterface $phraseBuilder,
ImageFileHandler $imageFileHandler
) {
$this->router = $router;
$this->builder = $builder;
$this->phraseBuilder = $phraseBuilder;
$this->imageFileHandler = $imageFileHandler;
$this->router = $router;
$this->builder = $builder;
$this->phraseBuilder = $phraseBuilder;
$this->imageFileHandler = $imageFileHandler;
}
/**
* Get the captcha URL, stream, or filename that will go in the image's src attribute
*
* @param array $options
*
* @return array
*/
public function getCaptchaCode(array &$options)
public function getCaptchaCode(array &$options): string
{
$this->builder->setPhrase($this->getPhrase($options));
@ -76,26 +61,21 @@ class CaptchaGenerator
// Returns the image generation URL
if ($options['as_url']) {
return $this->router->generate('gregwar_captcha.generate_captcha', array('key' => $options['session_key']));
return $this->router->generate(
'gregwar_captcha.generate_captcha',
array('key' => $options['session_key'], 'n' => md5(microtime(true).mt_rand()))
);
}
return 'data:image/jpeg;base64,' . base64_encode($this->generate($options));
return 'data:image/jpeg;base64,'.base64_encode($this->generate($options));
}
/**
* Sets the phrase to the builder
*/
public function setPhrase($phrase)
public function setPhrase(string $phrase): void
{
$this->builder->setPhrase($phrase);
}
/**
* @param array $options
*
* @return string
*/
public function generate(array &$options)
public function generate(array &$options): string
{
$this->builder->setDistortion($options['distortion']);
@ -103,7 +83,7 @@ class CaptchaGenerator
$this->builder->setMaxBehindLines($options['max_behind_lines']);
if (isset($options['text_color']) && $options['text_color']) {
if (count($options['text_color']) !== 3) {
if (3 !== count($options['text_color'])) {
throw new \RuntimeException('text_color should be an array of r, g and b');
}
@ -112,7 +92,7 @@ class CaptchaGenerator
}
if (isset($options['background_color']) && $options['background_color']) {
if (count($options['background_color']) !== 3) {
if (3 !== count($options['background_color'])) {
throw new \RuntimeException('background_color should be an array of r, g and b');
}
@ -124,6 +104,9 @@ class CaptchaGenerator
$fingerprint = isset($options['fingerprint']) ? $options['fingerprint'] : null;
$this->builder->setBackgroundImages($options['background_images']);
$this->builder->setIgnoreAllEffects($options['ignore_all_effects']);
$content = $this->builder->build(
$options['width'],
$options['height'],
@ -145,12 +128,7 @@ class CaptchaGenerator
return $this->imageFileHandler->saveAsFile($content);
}
/**
* @param array $options
*
* @return string
*/
public function getPhrase(array &$options)
public function getPhrase(array &$options): string
{
// Get the phrase that we'll use for this image
if ($options['keep_value'] && isset($options['phrase'])) {
@ -159,7 +137,7 @@ class CaptchaGenerator
$phrase = $this->phraseBuilder->build($options['length'], $options['charset']);
$options['phrase'] = $phrase;
}
return $phrase;
}
}

View File

@ -1,11 +1,13 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\Generator;
use Symfony\Component\Finder\Finder;
/**
* Handles actions related to captcha image files including saving and garbage collection
* Handles actions related to captcha image files including saving and garbage collection.
*
* @author Gregwar <g.passault@gmail.com>
* @author Jeremy Livingston <jeremy@quizzle.com>
@ -13,69 +15,61 @@ use Symfony\Component\Finder\Finder;
class ImageFileHandler
{
/**
* Name of folder for captcha images
* Name of folder for captcha images.
*
* @var string
*/
protected $imageFolder;
/**
* Absolute path to public web folder
* Absolute path to public web folder.
*
* @var string
*/
protected $webPath;
/**
* Frequency of garbage collection in fractions of 1
* Frequency of garbage collection in fractions of 1.
*
* @var int
*/
protected $gcFreq;
/**
* Maximum age of images in minutes
* Maximum age of images in minutes.
*
* @var int
*/
protected $expiration;
/**
* @param $imageFolder
* @param $webPath
* @param $gcFreq
* @param $expiration
* @param string $imageFolder
* @param string $webPath
* @param string $gcFreq
* @param string $expiration
*/
public function __construct($imageFolder, $webPath, $gcFreq, $expiration)
public function __construct(string $imageFolder, string $webPath, string $gcFreq, string $expiration)
{
$this->imageFolder = $imageFolder;
$this->webPath = $webPath;
$this->gcFreq = $gcFreq;
$this->expiration = $expiration;
$this->imageFolder = $imageFolder;
$this->webPath = $webPath;
$this->gcFreq = $gcFreq;
$this->expiration = $expiration;
}
/**
* Saves the provided image content as a file
*
* @param string $contents
*
* @return string
*/
public function saveAsFile($contents)
public function saveAsFile($contents): string
{
$this->createFolderIfMissing();
$filename = md5(uniqid()) . '.jpg';
$filePath = $this->webPath . '/' . $this->imageFolder . '/' . $filename;
$filename = md5(uniqid()).'.jpg';
$filePath = $this->webPath.'/'.$this->imageFolder.'/'.$filename;
imagejpeg($contents, $filePath, 15);
return '/' . $this->imageFolder . '/' . $filename;
return '/'.$this->imageFolder.'/'.$filename;
}
/**
* Randomly runs garbage collection on the image directory
*
* @return bool
*/
public function collectGarbage()
public function collectGarbage(): bool
{
if (!mt_rand(1, $this->gcFreq) == 1) {
if (1 == !mt_rand(1, $this->gcFreq)) {
return false;
}
@ -83,23 +77,20 @@ class ImageFileHandler
$finder = new Finder();
$criteria = sprintf('<= now - %s minutes', $this->expiration);
$finder->in($this->webPath . '/' . $this->imageFolder)
$finder->in($this->webPath.'/'.$this->imageFolder)
->date($criteria);
foreach($finder->files() as $file) {
foreach ($finder->files() as $file) {
unlink($file->getPathname());
}
return true;
}
/**
* Creates the folder if it doesn't exist
*/
protected function createFolderIfMissing()
protected function createFolderIfMissing(): void
{
if (!file_exists($this->webPath . '/' . $this->imageFolder)) {
mkdir($this->webPath . '/' . $this->imageFolder, 0755);
if (!file_exists($this->webPath.'/'.$this->imageFolder)) {
mkdir($this->webPath.'/'.$this->imageFolder, 0755);
}
}
}

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;

164
README.md
View File

@ -1,109 +1,66 @@
Gregwar's CaptchaBundle
=====================
The `GregwarCaptchaBundle` adds support for a "captcha" form type for the
Symfony2 form component.
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUXRLWHQSWS6L)
The `GregwarCaptchaBundle` adds support for a captcha form type for the
Symfony form component.
It uses [gregwar/captcha](https://github.com/Gregwar/Captcha) as captcha generator, which is a separate standalone library that can be used for none-symfony projects.
Compatibility with Symfony
==========================
| CaptchaBundle | Symfony | PHP |
|:---------------:|:---------:|:--------:|
| 2.1.* | 4.* - 5.* | >= 7.1 |
| 2.0.* | 2.8 - 3.* | >= 5.3.9 |
| 1.* | 2.1 - 2.7 | >= 5.3.0 |
Important note: the master of this repository is containing current development
in order to work with Symfony 2.1. If you are using Symfony 2.0 please checkout
the 2.0 branch.
Installation
============
### Step 1: Download the GregwarCaptchaBundle
Ultimately, the GregwarCaptchaBundle files should be downloaded to the
'vendor/bundles/Gregwar/CaptchaBundle' directory.
You can accomplish this several ways, depending on your personal preference.
The first method is the standard Symfony2 method.
***Using the vendors script***
Add the following lines to your `deps` file:
```
[GregwarCaptchaBundle]
git=http://github.com/Gregwar/CaptchaBundle.git
target=/bundles/Gregwar/CaptchaBundle
version=origin/2.0 <- add this if you are using Symfony 2.0
```
Now, run the vendors script to download the bundle:
Use composer require to download and install the package.
At the end of the installation, the bundle is automatically registered thanks to the Symfony recipe.
``` bash
$ php bin/vendors install
composer require gregwar/captcha-bundle
```
***Using submodules***
If you prefer instead to use git submodules, then run the following:
``` bash
$ git submodule add git://github.com/Gregwar/CaptchaBundle.git vendor/bundles/Gregwar/CaptchaBundle
$ git submodule update --init
```
***Using Composer***
Add the following to the "require" section of your `composer.json` file:
```
"gregwar/captcha-bundle": "dev-master"
```
And update your dependencies
### Step 2: Configure the Autoloader
If you use composer, you can skip this step.
Now you will need to add the `Gregwar` namespace to your autoloader:
``` php
<?php
// app/autoload.php
$loader->registerNamespaces(array(
// ...
'Gregwar' => __DIR__.'/../vendor/bundles',
));
```
### Step 3: Enable the bundle
Finally, enable the bundle in the kernel:
If you don't use flex, register it manually:
```php
<?php
// app/appKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Gregwar\CaptchaBundle\GregwarCaptchaBundle(),
);
}
// config/bundles.php
return [
// ...
Gregwar\CaptchaBundle\GregwarCaptchaBundle::class => ['all' => true]
];
```
Configuration
=============
Add the following configuration to your `app/config/config.yml`:
gregwar_captcha: ~
If you need to customize the global bundle configuration, you can create a `/config/packages/gregwar_captcha.yaml` file with your configuration:
``` yaml
gregwar_captcha:
width: 160
height: 50
```
Usage
=====
You can use the "captcha" type in your forms this way:
```php
``` php
<?php
// ...
$builder->add('captcha', 'captcha'); // That's all !
// ...
use Gregwar\CaptchaBundle\Type\CaptchaType;
// ...
$builder->add('captcha', CaptchaType::class); // That's all !
// ...
```
Note that the generated image will, by default, be embedded in the HTML document
@ -115,7 +72,7 @@ Options
You can define the following configuration options globally:
* **image_folder**: name of folder for captcha images relative to public web folder in case **as_file** is set to true (default="captcha")
* **web_path**: absolute path to public web folder (default="%kernel.root_dir%/../web")
* **web_path**: absolute path to public web folder (default='%kernel.project_dir%/public')
* **gc_freq**: frequency of garbage collection in fractions of 1 (default=100)
* **expiration**: maximum lifetime of captcha image files in minutes (default=60)
@ -141,27 +98,32 @@ You can define the following configuration options globally or on the CaptchaTyp
* **max_front_lines**, **max_behind_lines**: the maximum number of lines to draw on top/behind the image. `0` will draw no lines; `null` will use the default algorithm (the
number of lines depends on the size of the image). (default=null)
* **background_color**: sets the background color, if you want to force it, this should be an array of r,g &b, for instance [255, 255, 255] will force the background to be white
* **background_images**: Sets custom user defined images as the captcha background (1 image is selected randomly). It is recommended to turn off all the effects on the image (ignore_all_effects). The full paths to the images must be passed.
* **interpolation**: enable or disable the interpolation on the captcha
* **ignore_all_effects**: Recommended to use when setting background images, will disable all image effects.
* **session_key**, if you want to host multiple CAPTCHA on the same page, you might have different session keys to ensure proper storage of the clear phrase for those different forms
Example :
```php
``` php
<?php
// ...
$builder->add('captcha', 'captcha', array(
'width' => 200,
'height' => 50,
'length' => 6,
));
use Gregwar\CaptchaBundle\Type\CaptchaType;
// ...
$builder->add('captcha', CaptchaType::class, array(
'width' => 200,
'height' => 50,
'length' => 6,
));
```
You can also set these options for your whole application using the `gregwar_captcha`
configuration entry in your `config.yml` file:
gregwar_captcha:
width: 200
height: 50
length: 6
``` yaml
gregwar_captcha:
width: 200
height: 50
length: 6
```
Translation
===========
@ -170,16 +132,20 @@ The messages are using the translator, you can either change the `invalid_messag
As URL
============
To use a URL to generate a captcha image, you must add the bundle's routing configuration to your app/routing.yml file:
To use a URL to generate a captcha image, you must add the bundle's routing configuration to your `config/routes.yaml` file:
gregwar_captcha_routing:
resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml"
``` yaml
gregwar_captcha_routing:
resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml"
```
This will use the bundle's route of "/generate-captcha/{key}" to handle the generation. If this route conflicts with an application route, you can prefix the bundle's routes when you import:
This will use the bundle's route of `/generate-captcha/{key}` to handle the generation. If this route conflicts with an application route, you can prefix the bundle's routes when you import:
gregwar_captcha_routing:
resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml"
prefix: /_gcb
``` yaml
gregwar_captcha_routing:
resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml"
prefix: /_gcb
```
Since the session key is transported in the URL, it's also added in another session array, under the `whitelist_key` key, for security reasons
@ -190,7 +156,7 @@ The widget support the standard Symfony theming, see the [documentation](http://
The default rendering is:
```html
``` twig
{% block captcha_widget %}
{% spaceless %}
<img src="{{ captcha_code }}" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />

View File

@ -1,3 +1,3 @@
gregwar_captcha.generate_captcha:
pattern: /generate-captcha/{key}
defaults: { _controller: GregwarCaptchaBundle:Captcha:generateCaptcha }
path: /generate-captcha/{key}
defaults: { _controller: Gregwar\CaptchaBundle\Controller\CaptchaController::generateCaptchaAction }

View File

@ -1,4 +1,5 @@
parameters:
gregwar_captcha.controller.class: Gregwar\CaptchaBundle\Controller\CaptchaController
gregwar_captcha.captcha_type.class: Gregwar\CaptchaBundle\Type\CaptchaType
gregwar_captcha.captcha_generator.class: Gregwar\CaptchaBundle\Generator\CaptchaGenerator
gregwar_captcha.image_file_handler.class: Gregwar\CaptchaBundle\Generator\ImageFileHandler
@ -6,34 +7,52 @@ parameters:
gregwar_captcha.phrase_builder.class: Gregwar\Captcha\PhraseBuilder
services:
captcha.type:
class: %gregwar_captcha.captcha_type.class%
Gregwar\CaptchaBundle\Controller\CaptchaController:
public: true
alias: 'gregwar_captcha.controller'
gregwar_captcha.controller:
class: '%gregwar_captcha.controller.class%'
public: true
arguments:
- @session
- @gregwar_captcha.generator
- @translator
- %gregwar_captcha.config%
- '@gregwar_captcha.generator'
- '%gregwar_captcha.config%'
autowire: true
# captcha.type:
gregwar_captcha.type:
class: '%gregwar_captcha.captcha_type.class%'
public: true
arguments:
- '@session'
- '@gregwar_captcha.generator'
- '@translator'
- '%gregwar_captcha.config%'
tags:
- { name: form.type, alias: captcha }
gregwar_captcha.generator:
class: %gregwar_captcha.captcha_generator.class%
class: '%gregwar_captcha.captcha_generator.class%'
public: true
arguments:
- @router
- @gregwar_captcha.captcha_builder
- @gregwar_captcha.phrase_builder
- @gregwar_captcha.image_file_handler
- '@router'
- '@gregwar_captcha.captcha_builder'
- '@gregwar_captcha.phrase_builder'
- '@gregwar_captcha.image_file_handler'
gregwar_captcha.image_file_handler:
class: %gregwar_captcha.image_file_handler.class%
class: '%gregwar_captcha.image_file_handler.class%'
public: true
arguments:
- %gregwar_captcha.config.image_folder%
- %gregwar_captcha.config.web_path%
- %gregwar_captcha.config.gc_freq%
- %gregwar_captcha.config.expiration%
- '%gregwar_captcha.config.image_folder%'
- '%gregwar_captcha.config.web_path%'
- '%gregwar_captcha.config.gc_freq%'
- '%gregwar_captcha.config.expiration%'
gregwar_captcha.captcha_builder:
class: %gregwar_captcha.captcha_builder.class%
class: '%gregwar_captcha.captcha_builder.class%'
public: true
gregwar_captcha.phrase_builder:
class: %gregwar_captcha.phrase_builder.class%
class: '%gregwar_captcha.phrase_builder.class%'
public: true

View File

@ -0,0 +1 @@
Renew: تجديد

View File

@ -0,0 +1 @@
Renew: Yenile

View File

@ -0,0 +1 @@
Bad code value: الرمز غير متطابق

View File

@ -0,0 +1 @@
Bad code value: Kod eşleşmiyor

View File

@ -2,8 +2,8 @@
{% if is_human %}
-
{% else %}
{% spaceless %}
<img id="{{ image_id }}" src="{{ captcha_code }}" alt="" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />
{% apply spaceless %}
<img class="captcha_image" id="{{ image_id }}" src="{{ captcha_code }}" alt="" title="captcha" width="{{ captcha_width }}" height="{{ captcha_height }}" />
{% if reload %}
<script type="text/javascript">
function reload_{{ image_id }}() {
@ -14,7 +14,6 @@
<a class="captcha_reload" href="javascript:reload_{{ image_id }}();">{{ 'Renew'|trans({}, 'gregwar_captcha') }}</a>
{% endif %}
{{ form_widget(form) }}
{% endspaceless %}
{% endapply %}
{% endif %}
{% endblock %}

View File

@ -1,45 +1,40 @@
<?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\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Gregwar\CaptchaBundle\Validator\CaptchaValidator;
use Gregwar\CaptchaBundle\Generator\CaptchaGenerator;
/**
* Captcha type
* Captcha type.
*
* @author Gregwar <g.passault@gmail.com>
*/
class CaptchaType extends AbstractType
{
/**
* @var SessionInterface
*/
const SESSION_KEY_PREFIX = '_captcha_';
/** @var SessionInterface */
protected $session;
/**
* @var CaptchaGenerator
*/
/** @var CaptchaGenerator */
protected $generator;
/**
* @var TranslatorInterface
*/
/** @var TranslatorInterface */
protected $translator;
/**
* Options
* @var array
*/
/** @var array */
private $options = array();
/**
@ -50,10 +45,10 @@ class CaptchaType extends AbstractType
*/
public function __construct(SessionInterface $session, CaptchaGenerator $generator, TranslatorInterface $translator, $options)
{
$this->session = $session;
$this->generator = $generator;
$this->session = $session;
$this->generator = $generator;
$this->translator = $translator;
$this->options = $options;
$this->options = $options;
}
/**
@ -64,13 +59,14 @@ class CaptchaType extends AbstractType
$validator = new CaptchaValidator(
$this->translator,
$this->session,
sprintf('gcb_%s', $builder->getForm()->getName()),
sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']),
$options['invalid_message'],
$options['bypass_code'],
$options['humanity']
$options['humanity'],
$options['request']
);
$builder->addEventListener(FormEvents::POST_BIND, array($validator, 'validate'));
$builder->addEventListener(FormEvents::POST_SUBMIT, array($validator, 'validate'));
}
/**
@ -82,8 +78,8 @@ class CaptchaType extends AbstractType
throw new \InvalidArgumentException('GregwarCaptcha: The reload option cannot be set without as_url, see the README for more information');
}
$sessionKey = sprintf('gcb_%s', $form->getName());
$isHuman = false;
$sessionKey = sprintf('%s%s', self::SESSION_KEY_PREFIX, $options['session_key']);
$isHuman = false;
if ($options['humanity'] > 0) {
$humanityKey = sprintf('%s_humanity', $sessionKey);
@ -102,17 +98,18 @@ class CaptchaType extends AbstractType
}
$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
'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) {
foreach (array('phrase', 'width', 'height', 'distortion', 'length',
'quality', 'background_color', 'background_images', 'text_color', ) as $key) {
$persistOptions[$key] = $options[$key];
}
@ -122,24 +119,24 @@ class CaptchaType extends AbstractType
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
public function configureOptions(OptionsResolver $resolver)
{
$this->options['mapped'] = false;
$this->options['request'] = null;
$resolver->setDefaults($this->options);
}
/**
* @return string
*/
public function getParent()
public function getParent(): string
{
return 'text';
return TextType::class;
}
/**
* @return string
*/
public function getName()
public function getName(): string
{
return $this->getBlockPrefix();
}
public function getBlockPrefix(): string
{
return 'captcha';
}

View File

@ -1,73 +1,86 @@
<?php
declare(strict_types=1);
namespace Gregwar\CaptchaBundle\Validator;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Captcha validator
* Captcha validator.
*
* @author Gregwar <g.passault@gmail.com>
*/
class CaptchaValidator
{
/**
* @var SessionInterface
*/
/** @var SessionInterface */
private $session;
/**
* Session key to store the code
* Session key to store the code.
*
* @var string
*/
private $key;
/**
* Error message text for non-matching submissions
* Error message text for non-matching submissions.
*
* @var string
*/
private $invalidMessage;
/**
* Configuration parameter used to bypass a required code match
* Configuration parameter used to bypass a required code match.
*
* @var string
*/
private $bypassCode;
/**
* Number of form that the user can submit without captcha
* Number of form that the user can submit without captcha.
*
* @var int
*/
private $humanity;
/**
* Translator
* Translator.
*
* @var TranslatorInterface
*/
private $translator;
/**
* @param TranslatorInterface $translator
* @param SessionInterface $session
* @param string $key
* @param string $invalidMessage
* @param string $bypassCode
* @param int $humanity
* Request
*
* @var Request
*/
public function __construct(TranslatorInterface $translator, SessionInterface $session, $key, $invalidMessage, $bypassCode, $humanity)
{
$this->translator = $translator;
$this->session = $session;
$this->key = $key;
$this->invalidMessage = $invalidMessage;
$this->bypassCode = (string)$bypassCode;
$this->humanity = $humanity;
private $req;
public function __construct(
TranslatorInterface $translator,
SessionInterface $session,
string $key,
string $invalidMessage,
?string $bypassCode,
int $humanity,
?Request $req
) {
$this->translator = $translator;
$this->session = $session;
$this->key = $key;
$this->invalidMessage = $invalidMessage;
$this->bypassCode = $bypassCode;
$this->humanity = $humanity;
$this->req = $req;
}
/**
* @param FormEvent $event
*/
public function validate(FormEvent $event)
public function validate(FormEvent $event): void
{
$form = $event->getForm();
@ -77,12 +90,13 @@ class CaptchaValidator
if ($this->humanity > 0) {
$humanity = $this->getHumanity();
if ($humanity > 0) {
$this->updateHumanity($humanity-1);
$this->updateHumanity($humanity - 1);
return;
}
}
if (!($code !== null && is_string($code) && ($this->compare($code, $expectedCode) || $this->compare($code, $this->bypassCode)))) {
if (!(null !== $code && is_string($code) && ($this->compare($code, $expectedCode) || $this->compare($code, $this->bypassCode)))) {
$form->addError(new FormError($this->translator->trans($this->invalidMessage, array(), 'validators')));
} else {
if ($this->humanity > 0) {
@ -90,15 +104,16 @@ class CaptchaValidator
}
}
$this->session->remove($this->key);
if ($this->session->has($this->key . '_fingerprint')) {
$this->session->remove($this->key . '_fingerprint');
if (null == $this->req || 1 < $this->req->get('flow_registration_step')) {
$this->session->remove($this->key);
if ($this->session->has($this->key.'_fingerprint')) {
$this->session->remove($this->key.'_fingerprint');
}
}
}
/**
* Retrieve the expected CAPTCHA code
* Retrieve the expected CAPTCHA code.
*
* @return mixed|null
*/
@ -114,51 +129,39 @@ class CaptchaValidator
}
/**
* Retrieve the humanity
* Retrieve the humanity.
*
* @return mixed|null
*/
protected function getHumanity()
{
return $this->session->get($this->key . '_humanity', 0);
return $this->session->get($this->key.'_humanity', 0);
}
/**
* Updates the humanity
*/
protected function updateHumanity($newValue)
protected function updateHumanity(int $newValue): void
{
if ($newValue > 0) {
$this->session->set($this->key . '_humanity', $newValue);
$this->session->set($this->key.'_humanity', $newValue);
} else {
$this->session->remove($this->key . '_humanity');
$this->session->remove($this->key.'_humanity');
}
return null;
}
/**
* Process the codes
*
* @param $code
*
* @return string
*/
protected function niceize($code)
protected function niceize(string $code): string
{
return strtr(strtolower($code), 'oil', '01l');
}
/**
* Run a match comparison on the provided code and the expected code
* Run a match comparison on the provided code and the expected code.
*
* @param $code
* @param $expectedCode
* @param string $code
* @param string|null $expectedCode
*
* @return bool
*/
protected function compare($code, $expectedCode)
protected function compare($code, $expectedCode): bool
{
return ($expectedCode !== null && is_string($expectedCode) && $this->niceize($code) == $this->niceize($expectedCode));
return null !== $expectedCode && is_string($expectedCode) && $this->niceize($code) == $this->niceize($expectedCode);
}
}

View File

@ -1,9 +1,9 @@
{
"name": "gregwar/captcha-bundle",
"type": "captcha-bundle",
"name": "cadoles/captcha",
"type": "symfony-bundle",
"description": "Captcha bundle",
"keywords": ["symfony2", "captcha", "bot", "visual", "code", "security", "spam"],
"homepage": "https://github.com/Gregwar/CaptchaBundle",
"keywords": ["symfony2", "symfony", "captcha", "bot", "visual", "code", "security", "spam"],
"homepage": "https://github.com/Cadoles/CaptchaBundle",
"license": "MIT",
"authors": [
{
@ -17,14 +17,23 @@
}
],
"require": {
"php": ">=5.3.0",
"gregwar/captcha": "~1.1",
"symfony/framework-bundle": "~2.1",
"symfony/form": "~2.1"
"php": ">=7.1.3",
"ext-gd": "*",
"gregwar/captcha": "^1.1.9",
"symfony/form": "~4.0|~5.0",
"symfony/framework-bundle": "~4.0|~5.0",
"symfony/translation": "~4.0|^5.0",
"twig/twig": "^2.10|^3.0"
},
"autoload": {
"psr-4": {
"Gregwar\\CaptchaBundle\\": "/"
}
},
"config": {
"sort-packages": true
},
"require-dev": {
"symplify/easy-coding-standard": "^6.1"
}
}

138
ecs.yaml Normal file
View File

@ -0,0 +1,138 @@
parameters:
exclude_files:
- 'vendor/*'
- 'LICENSE'
- 'README.md'
services:
# PSR1
PhpCsFixer\Fixer\Basic\EncodingFixer: ~
PhpCsFixer\Fixer\PhpTag\FullOpeningTagFixer: ~
PhpCsFixer\Fixer\NamespaceNotation\BlankLineAfterNamespaceFixer: ~
PhpCsFixer\Fixer\ControlStructure\ElseifFixer: ~
PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer: ~
PhpCsFixer\Fixer\Whitespace\IndentationTypeFixer: ~
PhpCsFixer\Fixer\Whitespace\LineEndingFixer: ~
PhpCsFixer\Fixer\Casing\ConstantCaseFixer: ~
PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer: ~
PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer:
ensure_fully_multiline: true
PhpCsFixer\Fixer\ControlStructure\NoBreakCommentFixer: ~
PhpCsFixer\Fixer\PhpTag\NoClosingTagFixer: ~
PhpCsFixer\Fixer\FunctionNotation\NoSpacesAfterFunctionNameFixer: ~
PhpCsFixer\Fixer\Whitespace\NoSpacesInsideParenthesisFixer: ~
PhpCsFixer\Fixer\Whitespace\NoTrailingWhitespaceFixer: ~
PhpCsFixer\Fixer\Comment\NoTrailingWhitespaceInCommentFixer: ~
PhpCsFixer\Fixer\Whitespace\SingleBlankLineAtEofFixer: ~
PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer:
elements:
- 'property'
PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer: ~
PhpCsFixer\Fixer\Import\SingleLineAfterImportsFixer: ~
PhpCsFixer\Fixer\ControlStructure\SwitchCaseSemicolonToColonFixer: ~
PhpCsFixer\Fixer\ControlStructure\SwitchCaseSpaceFixer: ~
PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer: ~
PhpCsFixer\Fixer\Basic\BracesFixer:
allow_single_line_closure: true
PhpCsFixer\Fixer\PhpTag\BlankLineAfterOpeningTagFixer: ~
PhpCsFixer\Fixer\Operator\ConcatSpaceFixer:
spacing: none
PhpCsFixer\Fixer\Operator\NewWithBracesFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocAlignFixer:
tags:
- method
- param
- property
- return
- throws
- type
- var
PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer: ~
PhpCsFixer\Fixer\Operator\IncrementStyleFixer: ~
PhpCsFixer\Fixer\Operator\UnaryOperatorSpacesFixer: ~
PhpCsFixer\Fixer\Whitespace\BlankLineBeforeStatementFixer: ~
PhpCsFixer\Fixer\CastNotation\CastSpacesFixer: ~
PhpCsFixer\Fixer\LanguageConstruct\DeclareEqualNormalizeFixer: ~
PhpCsFixer\Fixer\FunctionNotation\FunctionTypehintSpaceFixer: ~
PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer:
comment_types:
- hash
PhpCsFixer\Fixer\ControlStructure\IncludeFixer: ~
PhpCsFixer\Fixer\CastNotation\LowercaseCastFixer: ~
PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer:
elements:
- method
PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer: ~
PhpCsFixer\Fixer\ClassNotation\NoBlankLinesAfterClassOpeningFixer: ~
PhpCsFixer\Fixer\Phpdoc\NoBlankLinesAfterPhpdocFixer: ~
PhpCsFixer\Fixer\Comment\NoEmptyCommentFixer: ~
PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocSeparationFixer: ~
PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer: ~
PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer:
tokens:
- curly_brace_block
- extra
- parenthesis_brace_block
- square_brace_block
- throw
- use
PhpCsFixer\Fixer\NamespaceNotation\NoLeadingNamespaceWhitespaceFixer: ~
PhpCsFixer\Fixer\ArrayNotation\NoMultilineWhitespaceAroundDoubleArrowFixer: ~
PhpCsFixer\Fixer\CastNotation\NoShortBoolCastFixer: ~
PhpCsFixer\Fixer\Semicolon\NoSinglelineWhitespaceBeforeSemicolonsFixer: ~
PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer: ~
PhpCsFixer\Fixer\ControlStructure\NoTrailingCommaInListCallFixer: ~
PhpCsFixer\Fixer\ArrayNotation\NoTrailingCommaInSinglelineArrayFixer: ~
PhpCsFixer\Fixer\ArrayNotation\TrailingCommaInMultilineArrayFixer: ~
PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer: ~
PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer: ~
PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer: ~
PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer: ~
PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocAnnotationWithoutDotFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocInlineTagFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocNoAccessFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocNoEmptyReturnFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocNoPackageFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocNoUselessInheritdocFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocReturnSelfReferenceFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocScalarFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocSingleLineVarSpacingFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocSummaryFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocToCommentFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocVarWithoutNameFixer: ~
PhpCsFixer\Fixer\FunctionNotation\ReturnTypeDeclarationFixer: ~
PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer: ~
PhpCsFixer\Fixer\CastNotation\ShortScalarCastFixer: ~
PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer: ~
PhpCsFixer\Fixer\Semicolon\SpaceAfterSemicolonFixer: ~
PhpCsFixer\Fixer\Operator\StandardizeNotEqualsFixer: ~
PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer: ~
PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer: ~
PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer: ~
PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer:
singleLine: true
PhpCsFixer\Fixer\Casing\MagicConstantCasingFixer: ~
PhpCsFixer\Fixer\Alias\NoMixedEchoPrintFixer:
use: echo
PhpCsFixer\Fixer\Import\NoLeadingImportSlashFixer: ~
PhpCsFixer\Fixer\Import\NoUnusedImportsFixer: ~
PhpCsFixer\Fixer\PhpUnit\PhpUnitFqcnAnnotationFixer: ~
PhpCsFixer\Fixer\Phpdoc\PhpdocNoAliasTagFixer: ~
PhpCsFixer\Fixer\ClassNotation\ProtectedToPrivateFixer: ~
PhpCsFixer\Fixer\NamespaceNotation\SingleBlankLineBeforeNamespaceFixer: ~
# new since PHP-CS-Fixer 2.6
PhpCsFixer\Fixer\ControlStructure\NoUnneededCurlyBracesFixer: ~
PhpCsFixer\Fixer\ClassNotation\NoUnneededFinalMethodFixer: ~
PhpCsFixer\Fixer\Semicolon\SemicolonAfterInstructionFixer: ~
PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer: ~
# new since 2.11
PhpCsFixer\Fixer\Operator\StandardizeIncrementFixer: ~