I upgraded to 6.3.4 (from 6.2) hoping to get rid off Laminas adding double headers to the emails that Amazon rejects.
Installed Amazon SES bridge and followed the instrucitons how to use it but Elgg keeps using Laminas. Is there a way to get rid of it? Has anyone had experience connecting to Amazon SES beidge Simfony?
info@elgg.org
Security issues should be reported to security@elgg.org!
©2014 the Elgg Foundation
Elgg is a registered trademark of Thematic Networks.
Cover image by Raül Utrera is used under Creative Commons license.
Icons by Flaticon and FontAwesome.
- Nikolai Shcherbin@rivervanrain

Nikolai Shcherbin - 0 likes
- Add DI binding: 'email.transport' => \DI\create(\MyPlugin\Core\Notifications\Email\Transport\EmailTransport::class)->constructor(\DI\get('config'), \DI\get('events')).
- Purpose: Overrides Elgg's Laminas transport factory with your custom EmailTransport class, injecting Elgg's Config and EventsService. This hooks into Elgg's mailer pipeline without touching core Laminas code.
- Add: _elgg_services()->set('mailer', elgg()->{'email.transport'}->build());.
- Purpose: Manually builds and registers the mailer service post-DI, ensuring Elgg's elgg_send_email() uses your transport instead of Laminas default. Runs early in boot sequence.
- Create class implementing Laminas TransportInterface factory pattern.
- Constructor takes Elgg Config and EventsService.
- build() method: Reads $config->{'email.transport'} (set to 'amazonses' in admin), constructs transport per switch (Sendmail/SMTP/SparkPost/Mailgun/SendGrid/AmazonSes), triggers events->triggerResults('transport', 'system:email') for plugins to modify.
- Purpose: Centralized factory decouples config from transport impl, supports multiple providers, extensible via events. For SES: instantiates AmazonSesEmailTransport.
- Constructor: Stores SES region, access_key_id, secret_access_key from config.
- send(Laminas\Mail\Message $message): Parses Laminas message parts (text/HTML/attachments), builds SimpleEmailServiceEnvelope, sends via SimpleEmailService::sendEmail(). Logs SES errors via elgg_log(), rethrows as Laminas RuntimeException.
- Purpose: Direct SES API transport compatible with Elgg's Laminas Message API, bypasses SMTP bridges (no double headers). Handles multipart MIME parsing natively.
- AWS SigV4 signer + GuzzleHttp\Client for SES REST API calls.
- Methods: sendEmail($envelope) (main), listIdentities(), verifyEmailIdentity(), etc. Builds canonical requests, signs with HMAC-SHA256, handles XML responses.
- Purpose: Pure PHP SES client (no SDK deps), manages auth/requests. Requires guzzlehttp/guzzle composer dep.
- Builds SES SendEmail/SendRawEmail params from Laminas message data.
- Supports To/Cc/Bcc/ReplyTo/attachments/HTML/text, validates required fields, builds raw base64 MIME for attachments.
- Purpose: Converts Laminas Message to SES envelope format, handles MIME boundaries/encoding.
- Error handler with SES-specific codes/messages (e.g., MessageRejected, Throttling).
- Purpose: Structured exception mapping for debugging.
- Outcome: Elgg mailer fully bypasses Laminas transport (no double headers), uses direct SES API via your factory. Amazon SES Bridge plugin becomes redundant—uninstall it. Symfony Mailer not involved (custom DI override).
- Admin Config (via Elgg email settings or plugin):
- Slonmamont-elgg@Slonmamont-elgg

Slonmamont-elgg - 0 likes
You must log in to post replies.To bypass Laminas email transport in Elgg and integrate direct Amazon SES via custom Symfony DI container override, follow this exact implementation flow. This replaces Elgg's default Laminas mailer with your custom transport factory, enabling amazonses config while avoiding Symfony Mailer Bridge conflicts.
Core Files Setup
elgg-services.php (in your plugin's root or core override path):
Bootstrap.php (plugin's main boot file):
Transport Factory Class
EmailTransport.php (namespace MyPlugin\Core\Notifications\Email\Transport):
Amazon SES Transport Impl
AmazonSesEmailTransport.php (namespace MyPlugin\Notifications\Email, implements Laminas\Mail\Transport\TransportInterface):
SES Low-Level Classes
SimpleEmailService.php (namespace MyPlugin\Notifications\Email\AmazonSes):
SimpleEmailServiceEnvelope.php (same namespace):
SimpleEmailServiceError.php (same namespace):
Final Result & Config
Deploy in plugin (autoload PSR-4 namespaces), clear caches, test elgg_send_email(). Handles attachments/multipart, events-extensible.
Thanks, Nikolai, looks like a new plugin to intercept the email process...
I also found a realtively easy fix ...
Remove this line:
from /var/www/html/vendor/elgg/elgg/engine/classes/Elgg/EmailService.php
tested and works fine exept that it coould be refreshed on the next Elgg update...