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

Captcha Bundle Laravel Package

gregwar/captcha-bundle

Symfony bundle that adds a Captcha form type powered by gregwar/captcha. Simple Composer install, Flex auto-registration, and optional global YAML config. Supports inline embedded images by default or file-based captchas with cleanup/expiration options.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require gregwar/captcha-bundle
    

    (No manual registration needed if using Symfony Flex.)

  2. First Use Case: Add the GregwarCaptchaType to a form in your controller or entity:

    use Gregwar\CaptchaBundle\Form\Type\CaptchaType;
    
    $form = $this->createFormBuilder()
        ->add('name', TextType::class)
        ->add('captcha', CaptchaType::class, [
            'mapped' => false, // Important: Captcha is not mapped to an entity
        ])
        ->getForm();
    
  3. Display in Twig:

    {{ form_row(form.captcha) }}
    
  4. Validate Submission:

    if ($form->isSubmitted() && $form->isValid()) {
        // Captcha is automatically validated
        $this->addFlash('success', 'Form submitted!');
    }
    

Key Files to Review

  • config/packages/gregwar_captcha.yaml (default config)
  • src/Form/Type/CaptchaType.php (customization entry point)
  • vendor/gregwar/captcha/src/Captcha.php (core logic)

Implementation Patterns

Common Workflows

1. Basic Form Integration

// src/Form/RegistrationType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('email')
        ->add('captcha', CaptchaType::class, [
            'label' => 'Verify you are human',
            'config' => [
                'background' => '#f9f9f9',
            ],
        ]);
}

2. Dynamic Captcha Configuration

Override defaults per-form:

# config/packages/gregwar_captcha.yaml
gregwar_captcha:
    default:
        background: '#ffffff'
        length: 6
        width: 120
        height: 40

Override for a specific form:

$builder->add('captcha', CaptchaType::class, [
    'config' => [
        'length' => 8,
        'font' => '/path/to/custom_font.ttf',
    ],
]);

3. Custom Validation Logic

Extend the default validator:

// src/Validator/Constraints/CustomCaptcha.php
use Symfony\Component\Validator\Constraint;

class CustomCaptcha extends Constraint
{
    public $message = 'Invalid captcha. Try again.';
}

// src/Validator/Constraints/CustomCaptchaValidator.php
use Symfony\Component\Validator\ConstraintValidator;

class CustomCaptchaValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        // Custom logic (e.g., rate-limiting)
    }
}

Bind to the form:

$builder->add('captcha', CaptchaType::class, [
    'constraints' => [
        new CustomCaptcha(),
    ],
]);

4. API/Headless Usage

Generate captcha without a form:

use Gregwar\Captcha\Captcha;

$captcha = new Captcha();
$captcha->setBackground($backgroundColor);
$captcha->setLength(6);
$image = $captcha->get();

// Save to file or return as response
header('Content-Type: image/jpeg');
echo $image;

5. Multi-Language Support

Use Twig to localize labels:

{{ form_label(form.captcha, 'captcha.label'|trans) }}
{{ form_help(form.captcha, 'captcha.hint'|trans) }}

Translations in translations/messages.en.yaml:

captcha:
    label: "Please enter the code above"
    hint: "Letters are case-sensitive"

Integration Tips

Symfony Events

Listen for captcha generation:

// src/EventListener/CaptchaListener.php
use Gregwar\CaptchaBundle\Event\CaptchaEvent;

class CaptchaListener
{
    public function onCaptchaGenerate(CaptchaEvent $event)
    {
        $captcha = $event->getCaptcha();
        $captcha->setFont('/custom/path/font.ttf');
    }
}

Register in services.yaml:

services:
    App\EventListener\CaptchaListener:
        tags:
            - { name: kernel.event_listener, event: gregwar.captcha.generate, method: onCaptchaGenerate }

Twig Extensions

Extend Twig for reusable captcha logic:

// src/Twig/CaptchaExtension.php
use Gregwar\Captcha\Captcha;

class CaptchaExtension extends \Twig\Extension\AbstractExtension
{
    public function getFunctions()
    {
        return [
            new \Twig\TwigFunction('generate_captcha', [$this, 'generateCaptcha']),
        ];
    }

    public function generateCaptcha($config = [])
    {
        $captcha = new Captcha($config);
        return $captcha->get();
    }
}

Use in Twig:

<img src="{{ generate_captcha({'width': 150}) }}">

Security Considerations

  • Rate Limiting: Combine with Symfony’s RateLimiter to prevent brute force.
  • CSRF Protection: Ensure the form has csrf_protection: true (default in Symfony).
  • Session Storage: Captcha codes are stored in the session by default. For distributed setups, consider a cache layer.

Gotchas and Tips

Pitfalls

  1. mapped => false Requirement

    • Issue: Forgetting mapped: false causes the captcha to be treated as a form field in your entity.
    • Fix: Always set 'mapped' => false in the form type options.
  2. Font Path Issues

    • Issue: Custom fonts not found if paths are relative or incorrect.
    • Fix: Use absolute paths (e.g., %kernel.project_dir%/public/fonts/arial.ttf).
  3. Case Sensitivity

    • Issue: Default captcha validation is case-sensitive. Users may fail due to uppercase/lowercase mismatches.
    • Fix: Normalize input in validation:
      $userInput = strtolower($userInput);
      $storedCode = strtolower($session->get('captcha_code'));
      
  4. Session Expiry

    • Issue: Captcha codes expire after 1 hour (default). Users may see stale codes.
    • Fix: Adjust lifetime in config:
      gregwar_captcha:
          lifetime: 3600  # 1 hour (default)
      
  5. Image Output Corruption

    • Issue: Captcha images may appear corrupted if gd or imagick extensions are missing.
    • Fix: Verify PHP extensions:
      php -m | grep -E 'gd|imagick'
      
  6. Caching Headaches

    • Issue: Captcha images cached aggressively by browsers or CDNs, showing stale codes.
    • Fix: Add a query string with a timestamp:
      <img src="{{ path('app_captcha') }}?{{ 'now'|date('U') }}">
      

Debugging Tips

  1. Log Captcha Codes Add a listener to log generated codes for debugging:

    public function onCaptchaGenerate(CaptchaEvent $event)
    {
        $this->logger->debug('Generated captcha:', [
            'code' => $event->getCaptcha()->getCode(),
        ]);
    }
    
  2. Inspect Session Data Check if the captcha code is stored correctly:

    $session = $this->get('session');
    $this->logger->debug('Session captcha:', $session->get('captcha_code'));
    
  3. Validate PHP Extensions Ensure gd or imagick is installed:

    php -i | grep -A5 "gd\|imagick"
    
  4. Test with Defaults First Start with default config to isolate issues:

    gregwar_captcha: ~
    

Extension Points

  1. Custom Captcha Generators Extend the core Captcha class:

    class CustomCaptcha extends Captcha
    {
        public function __construct()
        {
            $this->setBackground('#000000');
            $this->setLength(8);
            $this->setFont('/custom/font.ttf');
        }
    
        public function getCode()
        {
            return strtoupper(parent::getCode());
        }
    }
    

    Use in the bundle config:

    gregwar_captcha:
        captcha_class: App\Service\CustomCaptcha
    
  2. Override Twig Templates Customize the captcha widget template:

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.
bugban/symfony
beyonder-capi/workflow-extensions-bundle
beyonder-capi/job-queue-bundle
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin