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

Laminas Mail Laravel Package

oroinc/laminas-mail

oroinc/laminas-mail is a small bridge package for using Laminas Mail components within Oro applications. Provides the Laminas mail classes and configuration needed to send emails, manage transports, and integrate with Oro’s mailing features.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

To start using oroinc/laminas-mail in Laravel, install the package via Composer:

composer require oroinc/laminas-mail

First Use Case: Sending a Basic Email

use Laminas\Mail\Message;
use Laminas\Mail\Transport\Sendmail;

// Create a message
$message = new Message();
$message->setFrom('sender@example.com')
        ->addTo('recipient@example.com')
        ->setSubject('Hello World')
        ->setBody('This is a test email.');

// Send using Sendmail transport (default in Laravel)
$transport = new Sendmail();
$transport->send($message);

Key Entry Points

  1. Message Composition: Use Laminas\Mail\Message for constructing emails.
  2. Transports: Choose from Sendmail, Smtp, or File transports.
  3. Configuration: Use SmtpOptions or FileOptions for transport-specific settings.

Implementation Patterns

1. Message Composition Workflow

// Create a message
$message = new Message();

// Set basic headers
$message->setFrom('noreply@example.com')
        ->addTo('user@example.com')
        ->setSubject('Your Order Confirmation')
        ->setEncoding('UTF-8');

// Add HTML and plain-text parts
$htmlPart = new \Laminas\Mime\Part('HTML content');
$htmlPart->setType('text/html');
$textPart = new \Laminas\Mime\Part('Plain text content');
$textPart->setType('text/plain');

// Attach parts to the message
$body = new \Laminas\Mime\Message();
$body->setParts([$textPart, $htmlPart]);
$message->setBody($body);

// Send the message
$transport->send($message);

2. SMTP Transport Integration

// Configure SMTP transport
$transport = new \Laminas\Mail\Transport\Smtp();
$options = new \Laminas\Mail\Transport\SmtpOptions([
    'name' => 'example.com',
    'host' => env('MAIL_HOST'),
    'port' => env('MAIL_PORT'),
    'connection_class' => 'login',
    'connection_config' => [
        'username' => env('MAIL_USERNAME'),
        'password' => env('MAIL_PASSWORD'),
        'ssl' => env('MAIL_ENCRYPTION') === 'ssl' ? 'ssl' : null,
    ],
]);
$transport->setOptions($options);

3. File Transport for Debugging

// Save emails to a directory for debugging
$transport = new \Laminas\Mail\Transport\File();
$options = new \Laminas\Mail\Transport\FileOptions([
    'path' => storage_path('app/emails'),
    'mode' => 0777,
]);
$transport->setOptions($options);

4. Service Provider Integration

Register the transport in AppServiceProvider:

public function register()
{
    $this->app->singleton(\Laminas\Mail\Transport\TransportInterface::class, function ($app) {
        $transport = new \Laminas\Mail\Transport\Smtp();
        $options = new \Laminas\Mail\Transport\SmtpOptions([
            'name' => 'example.com',
            'host' => env('MAIL_HOST'),
            // ... other config
        ]);
        $transport->setOptions($options);
        return $transport;
    });
}

5. Reusable Email Templates

Create a helper class for common email templates:

class EmailHelper
{
    public static function createPasswordResetEmail(string $token, string $email)
    {
        $message = new Message();
        $message->setFrom('noreply@example.com')
                ->addTo($email)
                ->setSubject('Reset Your Password');

        $html = '<p>Click <a href="'.url('reset-password?token='.$token).'">here</a> to reset your password.</p>';
        $text = 'Click the link below to reset your password: '.url('reset-password?token='.$token);

        $htmlPart = new \Laminas\Mime\Part($html);
        $htmlPart->setType('text/html');
        $textPart = new \Laminas\Mime\Part($text);
        $textPart->setType('text/plain');

        $body = new \Laminas\Mime\Message();
        $body->setParts([$textPart, $htmlPart]);
        $message->setBody($body);

        return $message;
    }
}

Gotchas and Tips

1. PHP 8.4 Compatibility

  • The package is a fork to support PHP 8.4, but some edge cases may still exist.
  • Test thoroughly with your PHP version, especially when using:
    • Named arguments in constructors.
    • New union types (e.g., string|false returns).

2. SMTP Connection Issues

  • Timeouts: Always set a connection_time_limit for long-running scripts to avoid "Broken pipe" errors:
    $options->setConnectionConfig([
        'use_complete_quit' => false,
    ]);
    $options->setConnectionTimeLimit(300); // 5 minutes
    
  • SSL/TLS: Ensure openssl is enabled in your PHP installation. For TLS, use port 587 and set 'ssl' => 'tls'.

3. Authentication Pitfalls

  • CRAM-MD5: Requires laminas/laminas-crypt:
    composer require laminas/laminas-crypt
    
  • Plaintext Passwords: Avoid hardcoding credentials. Use Laravel's .env:
    'connection_config' => [
        'username' => env('MAIL_USERNAME'),
        'password' => env('MAIL_PASSWORD'),
    ]
    

4. Debugging Tips

  • File Transport: Use for debugging:
    $transport = new \Laminas\Mail\Transport\File([
        'path' => storage_path('app/emails'),
    ]);
    
  • Logging: Enable Laminas Mail logging via Monolog:
    $logger = new \Monolog\Logger('laminas-mail');
    $transport->setLogger($logger);
    

5. Performance Considerations

  • Connection Reuse: For high-volume sending, reuse the transport object:
    $transport = new \Laminas\Mail\Transport\Smtp($options);
    foreach ($emails as $email) {
        $message = $EmailHelper::createPasswordResetEmail($token, $email);
        $transport->send($message);
    }
    
  • Avoid QUIT: For servers with reuse limits, disable QUIT:
    $options->setConnectionConfig([
        'use_complete_quit' => false,
    ]);
    

6. Extending the Package

  • Custom Transports: Implement Laminas\Mail\Transport\TransportInterface:
    class CustomTransport implements TransportInterface
    {
        public function send(Message $message)
        {
            // Custom logic (e.g., API call)
        }
    }
    
  • Custom Auth Methods: Extend Laminas\Mail\Protocol\Smtp\Auth\AbstractAuth:
    class CustomAuth extends AbstractAuth
    {
        public function authenticate()
        {
            // Custom auth logic
        }
    }
    
    Register it in a plugin manager:
    $pluginManager = new \Laminas\Mail\Protocol\SmtpPluginManager();
    $pluginManager->setService('custom', new CustomAuth());
    

7. Common Errors and Fixes

Error Solution
Could not read from [host] Check SMTP server is running, firewall rules, and credentials.
Failed to authenticate Verify username/password and auth method (PLAIN, LOGIN, CRAM-MD5).
Invalid parameter number for hash() Ensure laminas/laminas-crypt is installed for CRAM-MD5.
Broken pipe during long scripts Set connection_time_limit and disable use_complete_quit.
Message must contain a body Always set a body or parts using setBody() or setParts().

8. Laravel-Specific Tips

  • Mailable Classes: While Laravel's Mailable is preferred, you can integrate Laminas Mail by overriding the build() method:
    public function build()
    {
        $message = new \Laminas\Mail\Message();
        // Custom Laminas Mail logic
        return $message;
    }
    
  • Queue Integration: Use Laravel's queue system with Laminas Mail:
    Mail::to('user@example.com')->send(new CustomMailable());
    // Inside CustomMailable, use Lamin
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky