Installation
Requirements
Section titled “Requirements”- PHP 8.2+
- Symfony 6.4, 7.x or 8.x, with
symfony/twig-bundleto render the widget - A Cap Standalone server reachable from your visitors’ browsers, and a site key created in its dashboard: you get a site key and a secret key
Installation
Section titled “Installation”composer require silarhi/cap-bundleRegister the bundle if Flex did not:
return [ // ... Silarhi\CapBundle\SilarhiCapBundle::class => ['all' => true],];Copy its script to public/bundles/silarhicap/ (Flex runs this command after every composer install already):
php bin/console assets:installConfiguration
Section titled “Configuration”The bundle reads the URL of your Cap server and the secret key from two env vars:
CAP_ENDPOINT=https://cap.example.com/<site-key>/# .env.local, or your secrets vaultCAP_SECRET_KEY=<the secret key of the site key>CAP_ENDPOINT is the URL the browser uses: your Cap instance followed by the site key, as in Cap’s
data-cap-api-endpoint. The secret key is the one of the site key, not the ADMIN_KEY of the dashboard.
Disable the bundle in the test environment:
when@test: silarhi_cap: # No widget, every submission accepted: see the testing guide enabled: falseEvery option, other env var names included, is in the configuration reference.
Your first protected form
Section titled “Your first protected form”use Silarhi\CapBundle\Form\CapType;use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\Extension\Core\Type\EmailType;use Symfony\Component\Form\Extension\Core\Type\TextareaType;use Symfony\Component\Form\FormBuilderInterface;
final class ContactType extends AbstractType{ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('email', EmailType::class) ->add('message', TextareaType::class) ->add('cap', CapType::class); }}That’s it:
{{ form(form) }}(or{{ form_row(form.cap) }}) renders Cap’s checkbox and the script of the bundle;- the widget solves the challenge and posts the token as
contact[cap]; $form->isValid()redeems the token against your Cap server. A missing or rejected token is an error on the field: “Please verify you are human.” or “The human verification failed, please try again.”
The field is not mapped: it never touches your entity or DTO.
