glueful / email-notification
Provides email notification capabilities using Symfony Mailer
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:glueful-extension
pkg:composer/glueful/email-notification
Requires
- php: ^8.2
- symfony/mailer: ^6.3 || ^7.0
- symfony/mime: ^6.3 || ^7.0
- vlucas/phpdotenv: ^5.6
Requires (Dev)
- glueful/framework: dev-main
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.5
- squizlabs/php_codesniffer: ^3.6
Suggests
- symfony/amazon-mailer: Install if using Amazon SES
- symfony/brevo-mailer: Install if using Brevo/Sendinblue
- symfony/http-client: ^6.3 for API mail transports
- symfony/mailgun-mailer: Install if using Mailgun
- symfony/postmark-mailer: Install if using Postmark
- symfony/sendgrid-mailer: Install if using SendGrid
- twig/twig: ^3.0 for EnhancedEmailFormatter
README
Overview
The EmailNotification extension provides a modern, enterprise-grade email delivery system for the Glueful Framework's notification system. Built on Symfony Mailer, it features robust multi-provider support, advanced queue integration, comprehensive monitoring, and extensible transport architecture.
🚀 Version 1.0.0: Complete migration from PHPMailer to Symfony Mailer with enhanced performance, reliability, and modern provider bridge support.
Deprecation notice
manifest.json
is deprecated and removed in favor of Composer discovery (extra.glueful.provider
).- The top-level
EmailNotification
class has been removed; use the ServiceProvider-driven registration. Code that previously referencedGlueful\\Extensions\\EmailNotification
should instead use the framework's notification system and/or resolveEmailNotificationProvider
via DI.
Features
- ✅ Modern Symfony Mailer Integration - Enterprise-grade email infrastructure
- ✅ Multi-Provider Support - Brevo, SendGrid, Mailgun, Amazon SES, Postmark, and custom providers
- ✅ Provider Bridges - Native API integrations for optimal performance and reliability
- ✅ Advanced Queue System - Integration with Glueful's database/Redis queue system
- ✅ Failover & Load Balancing - Multiple transport support with automatic failover
- ✅ Extensible Architecture - Support for any Symfony Mailer provider bridge
- ✅ Advanced Template System - Responsive templates with variable substitution and conditional logic
- ✅ Performance Monitoring - Rate limiting, metrics collection, and resource tracking
- ✅ Enhanced Security - Modern encryption, validation, and provider isolation
- ✅ Developer Experience - Clear error messages, debugging tools, and type safety
Requirements
- PHP 8.2 or higher with strict typing
- Glueful Framework 0.29.0 or higher
- OpenSSL PHP extension
- Symfony Mailer (included)
- Composer for provider bridge dependencies
Installation
Install via Composer (Recommended)
composer require glueful/email-notification # Build/refresh the extensions cache php glueful extensions:clear && php glueful extensions:cache # Verify discovery php glueful extensions:list php glueful extensions:info EmailNotification
Development enable/disable (optional)
# Enable the extension locally (updates config/extensions.php) php glueful extensions:enable EmailNotification # Disable locally php glueful extensions:disable EmailNotification
Provider Bridge Installation
Install required Symfony provider bridges based on your email providers:
# For Brevo (Sendinblue) composer require symfony/brevo-mailer # For SendGrid composer require symfony/sendgrid-mailer # For Mailgun composer require symfony/mailgun-mailer # For Amazon SES composer require symfony/amazon-mailer # For Postmark composer require symfony/postmark-mailer
Configuration
Environment Variables
Configure your email providers in your .env
file:
# Email Provider Selection MAIL_MAILER=brevo # Brevo Configuration (Sendinblue) BREVO_TRANSPORT=brevo+smtp # or brevo+api BREVO_API_KEY=your-brevo-api-key MAIL_USERNAME=your-smtp-username MAIL_PASSWORD=your-smtp-password # Generic SMTP Configuration MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_ENCRYPTION=tls # tls, ssl, or none MAIL_USERNAME=your-email@example.com MAIL_PASSWORD=your-app-password # Email Addresses MAIL_FROM=noreply@example.com MAIL_FROM_NAME=Your Application # Performance & Queue Settings MAIL_QUEUE_ENABLED=true MAIL_RATE_LIMIT_PER_MINUTE=60 MAIL_DEBUG=false
Services Configuration
Configure multiple email providers in config/services.php
:
return [ 'mail' => [ 'default' => env('MAIL_MAILER', 'smtp'), 'mailers' => [ // Generic SMTP 'smtp' => [ 'transport' => 'smtp', 'host' => env('MAIL_HOST'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), ], // Brevo (Sendinblue) - API or SMTP 'brevo' => [ 'transport' => env('BREVO_TRANSPORT', 'brevo+api'), 'key' => env('BREVO_API_KEY'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'dsn' => env('BREVO_DSN'), // Override for custom DSN ], // SendGrid 'sendgrid' => [ 'transport' => 'sendgrid+api', 'key' => env('SENDGRID_API_KEY'), ], // Mailgun 'mailgun' => [ 'transport' => 'mailgun+api', 'domain' => env('MAILGUN_DOMAIN'), 'key' => env('MAILGUN_SECRET'), 'region' => env('MAILGUN_REGION', 'us'), ], // Amazon SES 'ses' => [ 'transport' => 'ses+api', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], // Postmark 'postmark' => [ 'transport' => 'postmark+api', 'token' => env('POSTMARK_TOKEN'), ], ], 'from' => [ 'address' => env('MAIL_FROM', 'noreply@example.com'), 'name' => env('MAIL_FROM_NAME', 'Glueful Application'), ], // Failover configuration 'failover' => [ 'mailers' => explode(',', env('MAIL_FAILOVER_MAILERS', '')), ], ], ];
Custom Provider Support
The extension supports any Symfony Mailer provider bridge through three methods:
1. Custom DSN (Most Flexible)
'custom_provider' => [ 'transport' => 'custom', 'dsn' => 'mandrill+api://your-api-key@default', ],
2. Auto-Configuration (Standard Patterns)
'office365' => [ 'transport' => 'office365+smtp', 'username' => 'user@company.com', 'password' => 'password', // Auto-builds: office365+smtp://user:password@default ],
3. Explicit Support (Built-in)
Already supported providers work without additional configuration.
Usage
Basic Email Sending
The extension integrates seamlessly with Glueful's notification system:
use Glueful\Notifications\NotificationService; $notificationService = container()->get(NotificationService::class); // Simple email notification $notificationService->send( 'account_activity', $user, 'Account Login Alert', [ 'message' => 'Your account was accessed from a new device.', 'location' => 'San Francisco, CA', 'device' => 'iPhone 13', 'timestamp' => '2024-06-21 14:30:00', ], ['channels' => ['email']] );
Template-Based Emails
Use professional templates for rich email experiences:
// Email verification with OTP using verification template $result = $notificationService->send( 'email_verification', $notifiable, 'Verify your email address', [ 'otp' => '123456', 'expiry_minutes' => 15, 'template_name' => 'verification' ], ['channels' => ['email']] ); // Password reset with OTP using password-reset template $result = $notificationService->send( 'password_reset', $notifiable, 'Password Reset Code', [ 'name' => $user->getFirstName(), 'otp' => '654321', 'expiry_minutes' => 15, 'template_name' => 'password-reset' ], ['channels' => ['email']] ); // Welcome email using welcome template $result = $notificationService->send( 'user_welcome', $user, 'Welcome to Our Platform', [ 'user_name' => $user->getName(), 'welcome_message' => 'Thank you for joining us!', 'get_started_url' => 'https://example.com/onboarding', 'template_name' => 'welcome' ], ['channels' => ['email']] ); // Alert notification using alert template $result = $notificationService->send( 'security_alert', $user, 'Security Alert', [ 'alert_type' => 'login_from_new_device', 'message' => 'Your account was accessed from a new device.', 'location' => 'San Francisco, CA', 'device' => 'iPhone 13', 'timestamp' => '2024-06-21 14:30:00', 'template_name' => 'alert' ], ['channels' => ['email']] );
Key Benefits of this Approach:
- ✅ Clean and Simple - Minimal code required for template-based emails
- ✅ Automatic Global Variables - Variables like
app_name
,current_year
,logo_url
are automatically available - ✅ Template Mappings - Use friendly template names that map to actual template files
- ✅ No Duplication - Each piece of data specified only once
- ✅ Type Safety - All template variables are validated and type-checked
Global Variables Available in All Templates:
// These are automatically available without specifying them: $globalVariables = [ 'app_name' => 'Glueful Application', 'app_url' => 'https://example.com', 'support_email' => 'support@example.com', 'logo_url' => 'https://brand.glueful.com/logo.png', 'current_year' => '2024', 'company_name' => 'Your Company' ];
Advanced Email Features
Leverage Symfony Mailer's advanced capabilities:
// Email with attachments, custom headers, and advanced features $notificationService->send( 'invoice_generated', $customer, 'Your Invoice #' . $invoice->number, [ 'invoice_number' => $invoice->number, 'amount' => $invoice->total, 'due_date' => $invoice->due_date, 'embedImages' => [ 'logo' => '/path/to/logo.png', ], ], [ 'channels' => ['email'], 'email_options' => [ 'attachments' => [ [ 'path' => $invoice->pdf_path, 'name' => 'Invoice-' . $invoice->number . '.pdf', 'contentType' => 'application/pdf' ] ], 'cc' => ['accounting@example.com'], 'bcc' => ['archive@example.com'], 'priority' => 'high', 'headers' => [ 'X-Invoice-ID' => $invoice->id, 'X-Customer-ID' => $customer->id, ], 'returnPath' => 'bounces@example.com', ] ] );
Queue Integration
Framework Queue System
The extension integrates with Glueful's robust queue system:
// Emails are automatically queued when MAIL_QUEUE_ENABLED=true // The framework's SendNotification job handles email processing // Monitor queue size use Glueful\Extensions\EmailNotification\EmailChannel; $emailChannel = container()->get(EmailChannel::class); $queueSize = $emailChannel->getQueueSize(); // Returns emails in queue // Start queue workers // php glueful queue:work --queue=emails
Queue Configuration
Configure email queue processing:
// In config/queue.php 'queues' => [ 'emails' => [ 'workers' => env('EMAIL_QUEUE_WORKERS', 2), 'max_workers' => env('EMAIL_QUEUE_MAX_WORKERS', 4), 'priority' => 5, 'timeout' => env('EMAIL_QUEUE_TIMEOUT', 120), 'auto_scale' => true, ], ],
Transport Features
Multi-Transport Support
Configure failover and load balancing:
// Failover configuration 'failover' => [ 'mailers' => ['brevo', 'sendgrid', 'smtp'], ], // Round-robin load balancing 'round_robin' => [ 'mailers' => ['ses', 'mailgun'], ],
Transport Health Monitoring
use Glueful\Extensions\EmailNotification\TransportFactory; // Check available providers $providers = TransportFactory::getAvailableProviders(); // Returns status of all Symfony provider bridges // Verify transport configuration $emailChannel->isAvailable(); // Returns true if transport is configured
Template System
The extension provides a flexible template system with built-in responsive templates and support for custom templates.
Built-in Templates
The extension includes 5 professionally designed, responsive email templates:
1. Default Template (default.html
)
- Use Case: General notifications, alerts, and multi-purpose emails
- Features: OTP support, action buttons, customizable styling
- Variables:
{{subject}}
,{{message}}
,{{action_url}}
,{{action_text}}
,{{otp_code}}
2. Welcome Template (welcome.html
)
- Use Case: User onboarding and welcome emails
- Features: Friendly greeting, getting started guidance
- Variables:
{{user_name}}
,{{app_name}}
,{{welcome_message}}
,{{get_started_url}}
3. Alert Template (alert.html
)
- Use Case: Security alerts, important notifications, warnings
- Features: Attention-grabbing design, urgency indicators
- Variables:
{{alert_type}}
,{{message}}
,{{timestamp}}
,{{action_required}}
4. Password Reset Template (password-reset.html
)
- Use Case: Password reset functionality
- Features: Secure reset process, expiry warnings
- Variables:
{{user_name}}
,{{reset_url}}
,{{expiry_time}}
,{{security_tip}}
5. Verification Template (verification.html
)
- Use Case: Account verification, email confirmation
- Features: Verification codes, confirmation links
- Variables:
{{user_name}}
,{{verification_code}}
,{{verification_url}}
,{{expiry_time}}
Custom Templates
You can add your own email templates and customize the template system through configuration.
Template Configuration
Configure custom templates in config/services.php
:
'mail' => [ 'templates' => [ // Primary template directory (optional override). By default, the // extension's own templates are used. To override explicitly: // 'path' => base_path('vendor/glueful/email-notification/src/Templates/html'), // Additional custom template directories (checked in order) 'custom_paths' => [ // Framework's mail templates dirname(__DIR__) . '/resources/mail', // Your custom templates directory dirname(__DIR__) . '/templates/email', ], // Template caching for performance 'cache_enabled' => env('MAIL_TEMPLATE_CACHE', true), 'cache_path' => env('MAIL_TEMPLATE_CACHE_PATH', dirname(__DIR__) . '/storage/cache/mail-templates'), // Layout and partials 'default_layout' => env('MAIL_DEFAULT_LAYOUT', 'layout'), 'partials_directory' => 'partials', // Template file extension 'extension' => '.html', // Custom template mappings (aliases) 'mappings' => [ // Map friendly names to actual template files 'user_welcome' => 'onboarding/welcome', 'password_reset' => 'auth/reset-password', 'invoice' => 'billing/invoice-generated', ], // Global variables available to all templates 'global_variables' => [ 'app_name' => env('APP_NAME', 'Glueful Application'), 'app_url' => env('BASE_URL', 'https://example.com'), 'support_email' => env('MAIL_SUPPORT_EMAIL', 'support@example.com'), 'logo_url' => env('MAIL_LOGO_URL', 'https://brand.glueful.com/logo.png'), 'current_year' => date('Y'), 'company_name' => env('COMPANY_NAME', 'Your Company'), ], ], ],
Creating Custom Templates
-
Create Template Directory Structure:
resources/mail/ ├── custom-welcome.html ├── invoice.html ├── newsletter.html └── partials/ ├── layout.html ├── header.html └── footer.html
-
Custom Template Example (
resources/mail/invoice.html
):<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{subject}}</title> <style> .invoice-header { background: #f8f9fa; padding: 20px; } .invoice-details { margin: 20px 0; } .total { font-weight: bold; font-size: 18px; } </style> </head> <body> <div class="invoice-header"> <h1>{{app_name}}</h1> <h2>Invoice #{{invoice_number}}</h2> </div> <div class="invoice-details"> <p>Dear {{customer_name}},</p> <p>Your invoice is ready for review.</p> <table> <tr><td>Invoice Number:</td><td>{{invoice_number}}</td></tr> <tr><td>Amount:</td><td class="total">${{amount}}</td></tr> <tr><td>Due Date:</td><td>{{due_date}}</td></tr> </table> <p><a href="{{invoice_url}}">View Invoice Online</a></p> </div> {{> footer}} </body> </html>
-
Using Custom Templates:
// Use by filename $notificationService->sendWithTemplate( 'invoice_generated', $customer, 'invoice', // Uses resources/mail/invoice.html [ 'invoice_number' => 'INV-2024-001', 'customer_name' => $customer->name, 'amount' => '299.99', 'due_date' => '2024-07-15', 'invoice_url' => 'https://app.com/invoices/123', ] ); // Use with mapping alias $notificationService->sendWithTemplate( 'user_registration', $user, 'user_welcome', // Maps to onboarding/welcome.html via template mappings [ 'user_name' => $user->name, 'activation_url' => $activationUrl, ] );
Template Features
Variable Substitution:
- Simple variables:
{{variable_name}}
- Default values:
{{variable_name|default_value}}
- Nested variables:
{{user.profile.name}}
Conditional Blocks:
{{#if show_discount}} <div class="discount"> <p>Special offer: {{discount_percent}}% off!</p> </div> {{/if}}
Partials (Template Includes):
{{> header}} <div class="content"> <!-- Your content --> </div> {{> footer}}
Global Variables:
All templates automatically have access to configured global variables like {{app_name}}
, {{logo_url}}
, {{current_year}}
, etc.
Template Inheritance
Create a base layout in partials/layout.html
:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{subject}} - {{app_name}}</title> <style> /* Your base styles */ </style> </head> <body> <header> <img src="{{logo_url}}" alt="{{app_name}}"> </header> <main> {{{content}}} <!-- Template content goes here --> </main> <footer> <p>© {{current_year}} {{company_name}}. All rights reserved.</p> </footer> </body> </html>
Templates without <!DOCTYPE html>
automatically use this layout.
Performance Features
Rate Limiting
Protect against email abuse with configurable rate limits:
EMAIL_RATE_LIMIT_PER_MINUTE=60 # Max 60 emails per minute EMAIL_RATE_LIMIT_PER_HOUR=1000 # Max 1000 emails per hour EMAIL_RATE_LIMIT_PER_DAY=10000 # Max 10000 emails per day
Connection Optimization
- Provider Bridges: Direct API integrations for better performance
- Connection Pooling: Efficient SMTP connection management
- Batch Processing: Optimized for high-volume sending
- Memory Management: Proper object lifecycle management
Security Features
Modern Security Standards
- Symfony Mailer Security: Built on Symfony's security standards
- Provider Isolation: Isolated transport creation prevents configuration leakage
- Input Validation: Enhanced validation for transport configurations
- Error Sanitization: Sanitized error messages to prevent credential exposure
SSL/TLS Encryption
MAIL_ENCRYPTION=tls # Enable TLS encryption EMAIL_SSL_VERIFY=true # Verify SSL certificates
Monitoring and Debugging
Health & Metrics
use Glueful\Extensions\EmailNotification\EmailNotificationProvider; $provider = app()->get(EmailNotificationProvider::class); // Check provider configuration status $isConfigured = $provider->isEmailProviderConfigured(); // Get metrics (success rate, queue size, etc.) $metrics = $provider->getMetrics();
Debug Mode
Enable detailed logging for troubleshooting:
EMAIL_DEBUG=true APP_DEBUG=true MAIL_LOG_CHANNEL=mail
Migration from PHPMailer
Breaking Changes in v1.0.0
- Transport Configuration: New multi-mailer structure required
- Queue System: File-based queue replaced with framework queue
- Provider Specification: Explicit transport types required (e.g.,
brevo+api
) - Dependencies: Symfony Mailer replaces PHPMailer
Migration Steps
-
Update Dependencies:
composer require symfony/mailer symfony/brevo-mailer
-
Update Configuration:
// OLD (PHPMailer) 'mail' => [ 'host' => 'smtp.brevo.com', 'port' => 587, 'username' => 'user@domain.com', 'password' => 'password', ] // NEW (Symfony Mailer) 'mail' => [ 'default' => 'brevo', 'mailers' => [ 'brevo' => [ 'transport' => 'brevo+smtp', 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), ], ], ]
-
Update Environment Variables:
MAIL_MAILER=brevo BREVO_TRANSPORT=brevo+smtp # or brevo+api MAIL_ENCRYPTION=tls # not MAIL_SECURE
-
Test Configuration:
# Test email sending php glueful test:email # Check extension health php glueful extensions info EmailNotification
Troubleshooting
Common Issues
-
Transport Creation Errors
- Verify provider bridge is installed:
composer require symfony/brevo-mailer
- Check configuration structure in
services.php
- Review error logs for specific transport issues
- Verify provider bridge is installed:
-
Queue Not Processing
- Ensure
MAIL_QUEUE_ENABLED=true
- Start queue workers:
php glueful queue:work --queue=emails
- Check queue configuration in
config/queue.php
- Ensure
-
Provider Bridge Issues
- Verify API credentials are correct
- Check transport specification (e.g.,
brevo+api
vsbrevo+smtp
) - Review provider-specific documentation
-
Configuration Path Issues
- Ensure the provider is discovered (composer-installed) and, if needed, enabled in
config/extensions.php
- Verify
services.mail
configuration exists - Check
from
address is configured
- Ensure the provider is discovered (composer-installed) and, if needed, enabled in
Health Checks
Use built-in health checks to diagnose issues:
# Check email system health curl -H "Authorization: Bearer your-token" \ http://your-domain.com/health/email # View email metrics curl -H "Authorization: Bearer your-token" \ http://your-domain.com/metrics/email
Provider-Specific Setup
Brevo (Sendinblue)
MAIL_MAILER=brevo BREVO_TRANSPORT=brevo+api # API mode (recommended) # BREVO_TRANSPORT=brevo+smtp # SMTP mode BREVO_API_KEY=your-brevo-api-key MAIL_USERNAME=your-smtp-login MAIL_PASSWORD=your-smtp-key
SendGrid
MAIL_MAILER=sendgrid SENDGRID_API_KEY=your-sendgrid-key
Amazon SES
MAIL_MAILER=ses AWS_ACCESS_KEY_ID=your-access-key AWS_SECRET_ACCESS_KEY=your-secret-key AWS_DEFAULT_REGION=us-east-1
Mailgun
MAIL_MAILER=mailgun MAILGUN_DOMAIN=your-domain.mailgun.org MAILGUN_SECRET=your-mailgun-key MAILGUN_REGION=us # or eu
License
This extension is licensed under the MIT License.
Support
For issues, feature requests, or questions about the EmailNotification extension:
- Create an issue in the repository
- Consult the Symfony Mailer documentation
- Check the extension health monitoring for diagnostics
📚 Documentation: Glueful Framework Documentation
🔧 Provider Bridges: Symfony Mailer Bridges
âš¡ Queue System: Glueful Queue Documentation