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

Confirmation Bundle Laravel Package

atournayre/confirmation-bundle

Symfony bundle that adds confirmation flows to your entities. Make entities confirmable via an interface/trait, generate and validate confirmation codes, and plug in custom delivery providers (email, SMS, etc.) configured through services and YAML routing.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation

    composer require atournayre/confirmation-bundle
    

    Register the bundle in config/bundles.php:

    Atournayre\Bundle\ConfirmationBundle\AtournayreConfirmationBundle::class => ['all' => true],
    
  2. Configure the Bundle Create config/packages/atournayre_confirmation.yaml:

    atournayre_confirmation:
      providers:
        # Example: email provider (replace with your custom provider)
        email: App\Provider\EmailConfirmationProvider
    
  3. Set Up Routing Create config/routes/atournayre_confirmation.yaml:

    atournayre_confirmation:
      resource: "@AtournayreConfirmationBundle/Resources/config/routing.yaml"
    
  4. Enable Services Add the required services to config/services.yaml (refer to the README for full config).

  5. First Use Case: Confirming a User Entity

    • Implement ConfirmableInterface and use ConfirmableTrait in your entity (e.g., User):
      use Atournayre\Bundle\ConfirmationBundle\Contracts\ConfirmableInterface;
      use Atournayre\Bundle\ConfirmationBundle\Traits\ConfirmableTrait;
      
      class User implements ConfirmableInterface
      {
          use ConfirmableTrait;
          // ...
      }
      
    • Create a custom provider (e.g., EmailConfirmationProvider) extending AbstractProvider:
      namespace App\Provider;
      
      use Atournayre\Bundle\ConfirmationBundle\Provider\AbstractProvider;
      
      class EmailConfirmationProvider extends AbstractProvider
      {
          public function getRecipient(User $entity): string
          {
              return $entity->getEmail();
          }
      
          public function sendConfirmationCode(User $entity, string $code): void
          {
              // Send email with $code to $entity->getEmail()
          }
      }
      
    • Register the provider in config/packages/atournayre_confirmation.yaml:
      atournayre_confirmation:
        providers:
          email: App\Provider\EmailConfirmationProvider
      
    • Generate a confirmation code for a user:
      $generateConfirmationService = app()->make(\Atournayre\Bundle\ConfirmationBundle\Service\GenerateConfirmationService::class);
      $generateConfirmationService($user);
      
    • The user will receive a confirmation link (via email/SMS) and can verify their account by clicking it or submitting the code via the provided routes (app_confirmation_code_with_code or app_confirmation_code).

Implementation Patterns

Common Workflows

  1. User Registration Confirmation

    • Trigger confirmation after user registration:
      $user = new User();
      $user->setEmail($request->email);
      $user->setPassword($request->password);
      $user->save();
      
      $generateConfirmationService($user); // Triggers email/SMS with confirmation code
      
    • Handle confirmation in the User entity:
      public function updateAfterConfirmation(): void
      {
          $this->setIsVerified(true);
          $this->setVerifiedAt(new \DateTime());
      }
      
  2. Password Reset Confirmation

    • Extend the same pattern for password reset tokens:
      $resetToken = new ResetPasswordToken();
      $resetToken->setUser($user);
      $resetToken->setToken($generatedToken);
      $resetToken->save();
      
      $generateConfirmationService($resetToken);
      
  3. Multi-Channel Confirmation (Email + SMS)

    • Register multiple providers in config/packages/atournayre_confirmation.yaml:
      atournayre_confirmation:
        providers:
          email: App\Provider\EmailConfirmationProvider
          sms: App\Provider\SmsConfirmationProvider
      
    • Use a custom provider to send both:
      class MultiChannelConfirmationProvider extends AbstractProvider
      {
          public function __construct(
              private EmailConfirmationProvider $emailProvider,
              private SmsConfirmationProvider $smsProvider
          ) {}
      
          public function sendConfirmationCode(User $entity, string $code): void
          {
              $this->emailProvider->sendConfirmationCode($entity, $code);
              $this->smsProvider->sendConfirmationCode($entity, $code);
          }
      }
      
  4. Custom Confirmation Logic

    • Override updateAfterConfirmation() in the entity for custom logic:
      public function updateAfterConfirmation(): void
      {
          $this->setStatus('active');
          $this->setConfirmedAt(now());
          // Trigger additional actions (e.g., send welcome email)
      }
      
  5. Testing Confirmations

    • Mock the GenerateConfirmationService in tests:
      $mockProvider = $this->createMock(EmailConfirmationProvider::class);
      $mockProvider->method('sendConfirmationCode')->willReturn(true);
      
      $container = new Container();
      $container->set('App\Provider\EmailConfirmationProvider', $mockProvider);
      
      $service = new GenerateConfirmationService($container);
      $service($user); // Will use the mocked provider
      

Integration Tips

  • Leverage Symfony’s Twig Templates Override default templates (e.g., confirmation emails) by copying them from: vendor/atournayre/confirmation-bundle/src/Resources/views/ to templates/atournayre_confirmation/.

  • Use Events for Extensibility Listen for confirmation events (e.g., ConfirmationGeneratedEvent) to add side effects:

    use Atournayre\Bundle\ConfirmationBundle\Event\ConfirmationGeneratedEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class ConfirmationSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                ConfirmationGeneratedEvent::class => 'onConfirmationGenerated',
            ];
        }
    
        public function onConfirmationGenerated(ConfirmationGeneratedEvent $event): void
        {
            // Log or trigger analytics when a confirmation is generated
        }
    }
    
  • Rate Limiting Implement rate limiting in your provider to prevent abuse:

    public function sendConfirmationCode(User $entity, string $code): void
    {
        if ($this->isRateLimited($entity)) {
            throw new \RuntimeException('Too many confirmation requests.');
        }
        // Send confirmation
    }
    
  • UUID Support If your entity uses UUIDs, pass the UUID as the 3rd argument to GenerateConfirmationService:

    $generateConfirmationService($user, null, $user->getUuid());
    

Gotchas and Tips

Pitfalls

  1. Provider Not Tagged

    • Issue: Confirmation codes aren’t sent because the provider isn’t tagged.
    • Fix: Ensure your provider is tagged in services.yaml:
      services:
        App\Provider\YourCustomProvider:
          tags: ['atournayre.confirmation_bundle.tag.provider']
      
  2. Overriding updateEntity()

    • Issue: The bundle discourages overriding updateEntity() in providers. Instead, use updateAfterConfirmation() in the entity.
    • Fix: Move logic to the entity’s updateAfterConfirmation() method.
  3. Missing realTargetId for UUIDs

    • Issue: Confirmation links fail if the entity uses both id and uuid.
    • Fix: Pass the UUID as the 3rd argument to GenerateConfirmationService:
      $generateConfirmationService($user, null, $user->getUuid());
      
  4. Template Overrides Not Working

    • Issue: Custom templates aren’t being picked up.
    • Fix: Ensure templates are placed in templates/atournayre_confirmation/ and named correctly (e.g., confirmation_email.html.twig).
  5. Confirmation Codes Not Expired

    • Issue: Codes remain valid indefinitely.
    • Fix: Configure expiration in your provider or use the bundle’s default TTL (check ConfirmationCodeRepository).
  6. Provider Not Public

    • Issue: GenerateConfirmationService fails with ServiceNotFoundException.
    • Fix: Ensure your provider is marked as public: true in services.yaml:
      App\Provider\YourCustomProvider:
        public: true
      

Debugging Tips

  1. Check Logs for Provider Errors

    • Enable debug mode and check storage/logs/laravel.log for provider-related errors (e.g., failed email/SMS sends).
  2. Verify Route Existence

    • Confirm routes are loaded:
      php bin/console debug:router | grep confirmation
      
    • Expected routes:
      • app_confirmation_code_with_code (direct link)
      • app_confirmation_code (form submission)
  3. Inspect Confirmation Codes

    • Query the confirmation_codes table to verify codes are generated:
      php
      
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle