gremo/captcha-form-bundle
gremo/captcha-form-bundle adds configurable CAPTCHA protection to Symfony forms via a reusable form type, helping block bots and spam. It handles challenge generation and validation with minimal setup and integrates cleanly into existing form workflows, making it suitable for public-facing forms suc...
This is a Symfony bundle, not a Laravel package. Before doing anything, decide which of two paths you are on:
composer require gremo/captcha-form-bundle to "just work." Laravel has no bundle registration, no Symfony Form component, and no auto-wired services.yaml config. You will either run it inside a Symfony kernel or, more realistically, mine the adapter pattern and port it (see below).composer require gremo/captcha-form-bundle
Then, in order:
composer.json first. Check the symfony/* and php constraints against your project. Given the age/size of this package, expect constraints that predate Symfony 5/6.DependencyInjection/ and Resources/config/ to see the service IDs and the configuration tree. The config root is conventionally gremo_captcha; verify the adapter node names there rather than guessing.Form/Type/ to find the CAPTCHA form type and Adapter/ to find the adapter interface implemented by each provider.config/bundles.php on modern Symfony, AppKernel on legacy), configure an adapter, then add the form type to one form.Add a CAPTCHA to a single public form (registration, contact, password reset request) and validate it server-side through the bundle's form type. Start with exactly one form and one adapter. Do not wire it into every form on day one — the bundle's value is the swappable adapter, and you want to confirm the adapter lifecycle (render token, persist state in session, validate on submit) before scaling.
Register the bundle, pick an adapter in config, and attach the form type:
# config/packages/gremo_captcha.yaml
gremo_captcha:
adapter: gremio_captcha.adapter.<name> # confirm exact service id in Resources/config
$builder->add('captcha', CaptchaType::class); // confirm FQCN in Form/Type/
The important architectural detail is that the form type delegates to an adapter. That means the day-to-day pattern is: keep business forms adapter-agnostic, and swap the adapter per environment.
A very practical pattern with this bundle:
test / dev: a no-op or fixed-value adapter, so feature tests and local logins don't require external CAPTCHA calls.Override the adapter service or config in config/packages/test/. This is the single biggest quality-of-life win with adapter-based CAPTCHA bundles; without it your CI will either hit third-party APIs or fail on token validation.
If you are a Laravel developer and want the same shape without the Symfony coupling, mirror the bundle's design rather than its code:
// config/captcha.php
return ['driver' => env('CAPTCHA_DRIVER', 'gregwar')];
interface CaptchaAdapter
{
public function render(): string; // markup or image URL
public function validate(?string $value, Request $request): bool;
}
Bind the adapter in a service provider, resolve it in a Blade component/partial, and wrap validation in a custom validation rule or a FormRequest:
class CaptchaRule implements ValidationRule
{
public function __construct(private CaptchaAdapter $adapter) {}
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (! $this->adapter->validate($value, request())) {
$fail('The CAPTCHA is incorrect.');
}
}
}
Then 'captcha' => ['required', new CaptchaRule(app(CaptchaAdapter::class))] in the FormRequest. This gives you the bundle's main benefit — swappable providers — with Laravel-native validation, localization, and testing.
Illuminate\Support\ServiceProvider, no config/ publish tag, no facade. Any "install guide" you find assumes Symfony's kernel and container.@include a Symfony form type. Any port means rewriting the rendering layer, not just the validation layer.bin/console debug:config gremo_captcha and debug:container --tag=...; clear cache after config edits. On a ported Laravel version, run php artisan config:clear.nonce/integrity handling.false returns from validate() are the usual symptom of an expired token, wrong adapter, or missing session.mews/captcha, a reCAPTCHA/hCaptcha SDK, or a thin custom adapter around Gregwar's captcha are all lower-risk than porting an unmaintained Symfony bundle. For Symfony projects, check whether gregwar/captcha-bundle or a maintained successor already covers your needs.How can I help you explore Laravel packages today?