carlos-mg89/symfony-captcha-bundle
Installation
composer require carlos-mg89/symfony-captcha-bundle
Ensure your config/bundles.php includes:
CarlosMG89\SymfonyCaptchaBundle\CarlosMG89SymfonyCaptchaBundle::class => ['all' => true],
Configuration Publish the default config:
php bin/console config:dump-reference CarlosMG89\SymfonyCaptchaBundle\Configuration
Update config/packages/carlos_mg89_symfony_captcha.yaml with your BotDetect license key and desired settings:
carlos_mg89_symfony_captcha:
license_key: "YOUR_LICENSE_KEY"
captcha_service: "botdetect"
default_captcha_theme: "CleanArithmetic" # Optional: Customize theme
First Use Case
Add CAPTCHA to a form (e.g., src/Form/ContactType.php):
use CarlosMG89\SymfonyCaptchaBundle\Form\Type\CaptchaType;
$builder->add('captcha', CaptchaType::class, [
'mapped' => false, // CAPTCHA is not bound to an entity
'label' => 'Verify you are human',
]);
Validate Submission In your controller, verify the CAPTCHA:
use CarlosMG89\SymfonyCaptchaBundle\Validator\Constraints\ValidCaptcha;
/**
* @ValidCaptcha(message="Invalid CAPTCHA")
*/
public function submitForm(Request $request, ContactFormType $form) { ... }
Form Integration
CaptchaType in any Symfony form (Symfony UX, API Platform, etc.).use ApiPlatform\Core\Validator\Constraints\ValidEntity;
use CarlosMG89\SymfonyCaptchaBundle\Validator\Constraints\ValidCaptcha;
#[ValidCaptcha]
#[ValidEntity]
public function __construct(...) { ... }
Dynamic CAPTCHA Themes Override themes in config:
carlos_mg89_symfony_captcha:
themes:
"CustomTheme": { "background": "#f0f0f0", "font": "Arial" }
Apply in form:
$builder->add('captcha', CaptchaType::class, [
'theme' => 'CustomTheme',
]);
API/JSON Responses For APIs, return CAPTCHA as a JSON field:
$captcha = $this->get('carlos_mg89_symfony_captcha.captcha_manager')->createCaptcha();
return $this->json(['captcha' => $captcha->getImageBase64()]);
Validate via:
$validator = $this->get('validator');
$errors = $validator->validate($request->request->all(), [
new ValidCaptcha(),
]);
Event-Driven CAPTCHA Listen for CAPTCHA generation/validation:
// config/services.yaml
services:
App\EventListener\CaptchaListener:
tags:
- { name: kernel.event_listener, event: carlos_mg89_symfony_captcha.on_generate, method: onGenerate }
Multi-Step Forms Store CAPTCHA token in session and validate later:
// Step 1: Generate and store
$session->set('captcha_token', $captcha->getToken());
// Step 2: Validate
$validator->validate($request->get('captcha_token'), [new ValidCaptcha()]);
symfony/http-foundation for request/response handling if integrating with Laravel.
$request = Request::createFromGlobals();
$validator = $this->get('validator');
{{ form_row(form.captcha) }}
$this->container->set('carlos_mg89_symfony_captcha.captcha_manager', $this->createMock(CaptchaManager::class));
License Key Validation
$this->get('carlos_mg89_symfony_captcha.captcha_manager')->createCaptcha();
Throws InvalidLicenseException if invalid.Session Dependencies
session.start() is called before generation/validation.stateless mode (requires manual token storage):
carlos_mg89_symfony_captcha:
sessionless: true
Caching Issues
php bin/console cache:clear
Form Validation Order
if ($form->isSubmitted() && $form->isValid()) {
$validator->validate($form->getData(), [new ValidCaptcha()]);
}
Symfony 6+ Compatibility
config/services.yaml:
CarlosMG89\SymfonyCaptchaBundle\:
resource: '../vendor/carlos-mg89/symfony-captcha-bundle/src/'
exclude: '../vendor/carlos-mg89/symfony-captcha-bundle/src/{Entity,Migrations,Tests}/*'
Enable Debug Mode
Set debug: true in config to log CAPTCHA generation/validation:
carlos_mg89_symfony_captcha:
debug: true
Common Errors
| Error | Solution |
|---|---|
InvalidCaptchaException |
Check token case-sensitivity; ensure token matches stored value. |
CaptchaNotFoundException |
Regenerate CAPTCHA or verify session/token storage. |
| Blank CAPTCHA image | Check license_key and internet connectivity (BotDetect fetches assets). |
Log CAPTCHA Tokens
Override CaptchaManager to log tokens for debugging:
public function createCaptcha(): Captcha
{
$captcha = parent::createCaptcha();
$this->logger->debug('Generated CAPTCHA token:', ['token' => $captcha->getToken()]);
return $captcha;
}
Custom Validators
Extend ValidCaptcha constraint:
use CarlosMG89\SymfonyCaptchaBundle\Validator\Constraints\ValidCaptcha as BaseValidCaptcha;
#[Attribute]
class CustomValidCaptcha extends BaseValidCaptcha
{
public function validatedBy(): string
{
return get_class($this) . 'Validator';
}
}
Theme Customization
Override BotDetect themes by extending the bundle’s Theme class:
namespace App\Captcha;
use CarlosMG89\SymfonyCaptchaBundle\Theme\Theme;
class DarkTheme extends Theme
{
public function getBackgroundColor(): string
{
return '#121212';
}
}
Register in config:
carlos_mg89_symfony_captcha:
themes:
"DarkTheme": App\Captcha\DarkTheme::class
Event Subscribers Listen for CAPTCHA events to modify behavior:
use CarlosMG89\SymfonyCaptchaBundle\Event\CaptchaEvents;
$dispatcher->addListener(CaptchaEvents::ON_GENERATE, function ($event) {
$event->getCaptcha()->setTheme('CustomTheme');
});
API Platform Integration
Use ApiPlatform\Metadata\Operation to add CAPTCHA to API endpoints:
#[ApiResource(
operations: [
new Post(
input: ContactInput::class,
validationContext: [new ValidCaptcha()]
)
]
)]
How can I help you explore Laravel packages today?