Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cap Bundle Laravel Package

aburg/cap-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle Run:

    composer require aburg/cap-bundle
    

    Then enable it in config/bundles.php:

    return [
        // ...
        Aburg\CapBundle\AburgCapBundle::class => ['all' => true],
    ];
    
  2. Configure the Bundle Publish the default config:

    php bin/console config:dump-reference Aburg\CapBundle\Configuration > config/packages/cap.yaml
    

    Update config/packages/cap.yaml with your Cap instance URL (e.g., https://trycap.dev/):

    aburg_cap:
        endpoint: 'https://trycap.dev/'
        # Optional: Customize timeout, retry logic, etc.
    
  3. First Use Case: Protect a Form Add the CAPTCHA widget to a Symfony form (e.g., src/Form/ContactType.php):

    use Aburg\CapBundle\Form\Type\CapType;
    
    $builder->add('captcha', CapType::class, [
        'label' => 'Verify you are human',
        'mapped' => false, // CAPTCHA is not bound to a model
    ]);
    

    Render the form template (e.g., templates/contact/index.html.twig):

    {{ form_row(form.captcha) }}
    
  4. Verify Submission In your controller, validate the CAPTCHA response:

    use Aburg\CapBundle\Validator\Constraints\ValidCap;
    
    #[ValidCap()]
    public function submit(ContactType $form, Request $request) {
        // ...
    }
    

Implementation Patterns

Workflows

  1. Frontend Integration (Symfony UX)

    • Use Stimulus/Turbo for dynamic CAPTCHA rendering without full page reloads.
    • Example Stimulus controller (assets/controllers/captcha_controller.js):
      import { Controller } from '@hotwired/stimulus';
      
      export default class extends Controller {
          connect() {
              this.element.querySelector('iframe').src = this.data.get('endpoint') + '/widget';
          }
      }
      
    • Bind to a Twig template:
      <div data-controller="captcha" data-captcha-endpoint="{{ aburg_cap.endpoint }}">
          {{ form_row(form.captcha) }}
      </div>
      
  2. Backend Validation

    • Use the ValidCap constraint in Symfony Validator:
      use Aburg\CapBundle\Validator\Constraints\ValidCap;
      
      #[ValidCap(message: 'CAPTCHA verification failed.')]
      public function handle(Request $request, ContactType $form) {
          // ...
      }
      
    • Customize error messages in translations/messages.en.yaml:
      aburg_cap:
          invalid: 'The CAPTCHA response is invalid.'
      
  3. API Endpoints

    • For API forms, pass the CAPTCHA token via POST:
      $builder->add('captcha_token', HiddenType::class, [
          'mapped' => false,
      ]);
      
    • Validate in the controller:
      $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
      $this->get('aburg_cap.validator')->validate($request->request->get('captcha_token'));
      
  4. AssetMapper Integration

    • Ensure CAPTCHA scripts/styles are loaded via AssetMapper:
      {{ asset('bundles/aburgcap/js/captcha.js') }}
      
    • Or use Symfony UX’s @stimulus import:
      {{ stimulus_controller('captcha', { endpoint: aburg_cap.endpoint }) }}
      

Gotchas and Tips

Pitfalls

  1. Missing Endpoint Configuration

    • Error: CapBundle requires a valid endpoint URL.
    • Fix: Always set aburg_cap.endpoint in config/packages/cap.yaml. Defaults to null.
  2. CSRF Token Conflicts

    • Issue: CAPTCHA submissions may fail if CSRF protection is misconfigured.
    • Fix: Ensure your form includes {{ form_rest(form) }} or manually add:
      {{ form_hidden(form._token) }}
      
  3. Caching CAPTCHA Responses

    • Problem: Repeated submissions may hit rate limits.
    • Solution: Use Symfony’s Cache component to throttle requests:
      $cache = $this->get('cache');
      if (!$cache->get('cap_verified_' . $userId, false)) {
          $this->get('aburg_cap.validator')->validate($token);
          $cache->set('cap_verified_' . $userId, true, 3600); // Cache for 1 hour
      }
      
  4. Asset Loading in Production

    • Issue: CAPTCHA widgets may fail to load if AssetMapper is misconfigured.
    • Fix: Verify config/packages/framework.yaml includes:
      assets:
          packages:
              cap:
                  json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
      

Debugging

  • Enable Debug Mode: Set debug: true in config/packages/cap.yaml to log CAPTCHA requests/responses.

    aburg_cap:
        debug: true
        endpoint: 'https://trycap.dev/'
    
  • Manual Validation: Test CAPTCHA responses directly:

    $validator = $this->get('aburg_cap.validator');
    $isValid = $validator->validate('user_provided_token');
    

Extension Points

  1. Custom CAPTCHA Widgets

    • Override the default widget by extending Aburg\CapBundle\Form\Type\CapType:
      namespace App\Form\Type;
      
      use Aburg\CapBundle\Form\Type\CapType as BaseCapType;
      
      class CustomCapType extends BaseCapType {
          public function configureOptions(OptionsResolver $resolver) {
              $resolver->setDefaults([
                  'widget_attr' => ['class' => 'custom-captcha'],
              ]);
          }
      }
      
    • Register the new type in services.yaml:
      services:
          App\Form\Type\CustomCapType:
              tags: [form.type]
      
  2. Alternative CAPTCHA Providers

    • Extend the bundle to support other CAPTCHA services (e.g., hCaptcha) by implementing Aburg\CapBundle\Client\CapClientInterface.
  3. Rate Limiting

    • Integrate with Symfony’s RateLimiter to block abusive CAPTCHA attempts:
      use Symfony\Component\RateLimiter\RateLimiterFactory;
      
      $factory = new RateLimiterFactory(10, 'second');
      $limiter = $factory->create($userId);
      if (!$limiter->consume()) {
          throw $this->createAccessDeniedException('Too many CAPTCHA attempts.');
      }
      

Tips

  • Test Locally: Use a local Cap instance (e.g., Docker) during development to avoid hitting rate limits:

    docker run -p 3000:3000 aburg/cap
    

    Then set endpoint: 'http://localhost:3000/'.

  • Performance: Lazy-load CAPTCHA widgets only when needed (e.g., on form submission):

    {% if form.vars.data is not empty %}
        {{ form_row(form.captcha) }}
    {% endif %}
    
  • Accessibility: Ensure CAPTCHA widgets comply with WCAG by adding ARIA labels:

    <div {{ form_widget(form.captcha) }} aria-label="Human verification"></div>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle