All Site Activity

  • Nikolai Shcherbin replied on the discussion topic Laminas - Simfony Amason SES email
    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,... 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...

  • Mrs. Paige Roberts commented on the blog Elgg 6.3.4 release
    it just crashed my last version
  • Dave ONchE commented on a page titled Elgg/starter project
    You need to give more information on what you have tried and what errors you are getting. For instance, you said: "At one point i thought i had it figured, but i kept getting an internal server error. Can't seem to get this figured out....
  • Nikolai Shcherbin released a new version of the plugin IndieWeb
  • coreys079 replied on the discussion topic social network project
    Even though I haven't quit I am not asking for help anymore with my project for good. view reply
  • ChrisFr replied on the discussion topic Elgg 6.3.3 - Pages plugin
    Absolutely perfect ! Thanks again. view reply
  • Nikolai Shcherbin replied on the discussion topic Elgg 6.3.3 - Pages plugin
    Forgot about saving... Add a new event in your custom plugin: elgg-plugin.php 'events' => [         'fields' => [             'object:page' =>... view reply
  • ChrisFr replied on the discussion topic Elgg 6.3.3 - Pages plugin
    Thank you Nikolai. It works well ! But the writing dropdown list remains visible and displays "private". Is there a way to hide it? (I clear the cache before each test I run.) view reply
  • Nikolai Shcherbin released a new version of the plugin My plugin
  • Nikolai Shcherbin replied on the discussion topic Elgg 6.3.3 - Pages plugin
    I assume you mean 'Write access' field in the form. make the pages in the pages plugin always "private" You need to create an event in your custom plugin: elgg-plugin.php 'events' => [    ... view reply
  • coreys079 replied on the discussion topic social network project
    I haven't quit developing, still going. view reply
  • ChrisFr added a new discussion topic Elgg 6.3.3 - Pages plugin in the group Elgg Technical Support
    Hello, How can I make the pages in the pages plugin always "private" and remove the access dropdown list ? What do I need to change in the code ? Chris
    • Thank you Nikolai.

      It works well !

      But the writing dropdown list remains visible and displays "private".

      Is there a way to hide it?

      (I clear the cache before each test I run.)

    • Forgot about saving...

      Add a new event in your custom plugin:

      elgg-plugin.php

      'events' => [
              'fields' => [
                  'object:page' => [
                      \MyPlugin\Pages\FieldsHandler::class => ['priority' => 501],
                  ],
              ],
      ],

      Create a new file \mod\my_plugin\classes\MyPlugin\Pages\FieldsHandler.php

      <?php
      
      namespace MyPlugin\Pages;
      
      class FieldsHandler {
          
          public function __invoke(\Elgg\Event $event): ?array {
              $result = $event->getValue();
              
              foreach ($result as $k => $field) {
                  if (elgg_extract('name', $field) === 'write_access_id') {
                      unset($result[$k]);
                  }
              }
              
              $result = array_values($result);
              
              return $result;
          }
      }

      Note: your custom plugin must be placed under 'Pages' plugin on the /admin/plugins page.

       

       

    • Absolutely perfect !

      Thanks again.

  • Jerome Bakker published a blog post Elgg 6.3.4 release
    Bugfix release for Elgg 6.3 is now available
  • Nikolai Shcherbin replied on the discussion topic ELGG on mobiles
    I didn't have time to respond; you were quicker. This is a problem with the current Elgg layout. We often have to fix it using styles in custom plugins, but there's no single solution since 3rd-party plugins can also have their own... view reply
  • Chris Funderburg replied on the discussion topic ELGG on mobiles
    Nevermind!  Figured out the correct way to do it seems to be to create a new mod that overrides the css.  If it's any use to anyone else I just create this structure. tdntheme/ ├── composer.json # Plugin metadata ├──... view reply
  • Chris Funderburg added a new discussion topic ELGG on mobiles in the group General Discussion
    Hello.  So, I just finished upgrading our charity's ELLG instance from version 1.2.17 all the way up to 6.3.3 - along with shifting up various versions of PHP and MySQL to MariaDB along to way.  It's been a marathon to say the...
    • Nevermind!  Figured out the correct way to do it seems to be to create a new mod that overrides the css.  If it's any use to anyone else I just create this structure.

      tdntheme/
      ├── composer.json         # Plugin metadata
      ├── elgg-plugin.php       # Plugin configuration  
      ├── README.md
      └── views/
          └── default/
              └── tdntheme/
                  └── css/
                      └── custom.css   # Your CSS overrides

      And added this to the custom.css:

      /* ==========================================================================
         Walled Garden (Login Page) Mobile Fixes
         ========================================================================== */
      
      @media (max-width: 768px) {
          /* Fix: Login page content getting cut off on mobile */
          .elgg-page-walled-garden > .elgg-inner {
              min-width: auto !important;
              max-width: 100% !important;
              width: 100% !important;
              padding: 0 1rem;
              box-sizing: border-box;
          }
      
          /* Make the heading wrap properly */
          .elgg-heading-walled-garden {
              font-size: 1.5rem !important;
              line-height: 1.3 !important;
              word-wrap: break-word;
              overflow-wrap: break-word;
          }
      
          /* Ensure page body doesn't overflow */
          .elgg-page-walled-garden > .elgg-inner > .elgg-page-body {
              padding: 0.5rem !important;
          }
      }
      
      /*
      === Didn't need this but if the site title was longer... ===
      @media (max-width: 480px) {
          .elgg-heading-walled-garden {
              font-size: 1.2rem !important;
          }
      }
      */
      
      /* ==========================================================================
         Mobile Responsive Fixes (Logged-in pages)
         ========================================================================== */
      
      @media (max-width: 768px) {
          /* Fix: Site title getting cut off / center-justified on mobile */
          .elgg-page-header .elgg-heading-site,
          .elgg-page-topbar .elgg-heading-site,
          .elgg-heading-site {
              text-align: left;
              overflow: visible;
              white-space: normal;
              word-wrap: break-word;
          }
      
          /* Ensure header content doesn't overflow */
          .elgg-page-header,
          .elgg-page-topbar {
              padding-left: 10px;
              padding-right: 10px;
          }
      
          /* Make site title more readable on small screens */
          .elgg-heading-site a {
              font-size: 1.2em;
              line-height: 1.3;
          }
      }
      
      @media (max-width: 480px) {
          /* Extra small devices */
          .elgg-heading-site a {
              font-size: 1em;
          }
      }
      
      /* ==========================================================================
         Group Page / Owner Block - Mobile Fixes
         ========================================================================== */
      
      @media (max-width: 768px) {
          /* Stack image and description vertically on mobile */
          .elgg-image-block.groups-profile {
              flex-direction: column !important;
              align-items: center;
          }
      
          /* Limit the group icon size on mobile */
          .elgg-image-block.groups-profile > .elgg-image,
          .elgg-image-block.groups-profile img {
              max-width: 150px !important;
              height: auto !important;
          }
      
          /* Give the description full width when stacked */
          .elgg-image-block.groups-profile > .elgg-body,
          .elgg-image-block.groups-profile .elgg-profile-fields {
              width: 100%;
              text-align: left;
              margin-top: 1rem;
          }
      }

      There's probably some work to do with Pages too, but I ran out of time.  I'll find some time this week to do those, find the right-hand-side Pages menu that vanished somewhere along the line, and fix my personal bug-bear: members lists and counts including banned users literally everywhere...

    • I didn't have time to respond; you were quicker.

      This is a problem with the current Elgg layout.

      We often have to fix it using styles in custom plugins, but there's no single solution since 3rd-party plugins can also have their own styles, etc.

      I'm glad you fixed the issues in your custom plugin!

  • coreys079 replied on the discussion topic social network project
    Goodbye everyone my developing days are overwith for good. I don't know enough to carry out my project so, I am giving up on for it for good. My project is for someone with a lot more knowledge than me to do. No reason to come back anymore... view reply
  • Jeroen Dalsem replied on the discussion topic social network project
    Hi Corey, Thank you for your interest and for taking the time to share your choices with us. Although I regret that this community was not able to support you with your plans at this time, I sincerely hope you find the right opportunity to... view reply