Slonmamont-elgg

Send private message

You must be logged in to send a private message.

Friends

No friends yet.

Group membership

Activity

  • Slonmamont-elgg replied on the discussion topic Laminas - Simfony Amason SES email
    Thanks, Nikolai, looks like a new plugin to intercept the email process...  I also found a realtively easy fix ... Remove this line: 'Content-Transfer-Encoding' =>... view reply
  • Slonmamont-elgg added a new discussion topic Laminas - Simfony Amason SES email in the group Elgg Technical Support
    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...
    • 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):

      • 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.

      Bootstrap.php (plugin's main boot file):

      • 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.

      Transport Factory Class

      EmailTransport.php (namespace MyPlugin\Core\Notifications\Email\Transport):

      • 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.

      Amazon SES Transport Impl

      AmazonSesEmailTransport.php (namespace MyPlugin\Notifications\Email, implements Laminas\Mail\Transport\TransportInterface):

      • 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.

      SES Low-Level Classes

      SimpleEmailService.php (namespace MyPlugin\Notifications\Email\AmazonSes):

      • 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.

      SimpleEmailServiceEnvelope.php (same namespace):

      • 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.

      SimpleEmailServiceError.php (same namespace):

      • Error handler with SES-specific codes/messages (e.g., MessageRejected, Throttling).
      • Purpose: Structured exception mapping for debugging.

      Final Result & Config

      • 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):
      $CONFIG->{'email.transport'} = 'amazonses';
      $CONFIG->{'email.amazonses_region'} = 'us-east-1';
      $CONFIG->{'email.amazonses_access_key_id'} = 'YOUR_KEY';
      $CONFIG->{'email.amazonses_secret_access_key'} = 'YOUR_SECRET';
      

      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:

      'Content-Transfer-Encoding' => '8bit',

      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...