MailerFactory damage the attached files

Hi Everyone!

I have a problem with a code, I have a logichook that sends an email with files attached, but some days ago the customer reported an issue... the files arrive damage to the inbox email. I'm using the 'MailFactory::getSystemDefaultMailer()' method to make this (I let my code). I'm not sure since what sugarCRM version this problem appears; 'cause the issue is present over the SugarCRM 12.2. I tested the same code over my local with the same instance but with the version 11.3 and the functionality works fine, making various tests. So, I would like if someone have had the same problem and how managed this, 'cause the SugarCRM personal of the Case Portal says the problem is the custom code; but I repet, the code works fine on a previous version (11.3)

Thank you, and I expect some help.
Regards.

        $mailer = MailerFactory::getSystemDefaultMailer();
        $mailTransmissionProtocol = $mailer->getMailTransmissionProtocol();
        $mailer->setSubject($mailSubject);
        $body = trim($mailHTML);
        $textOnly = EmailFormatter::isTextOnly($body);
        if ($textOnly) {
          $mailer->setTextBody($body);
        } else {
          $textBody = strip_tags(br2nl($body)); // need to create the plain-text part
          $mailer->setTextBody($textBody);
          $mailer->setHtmlBody($body);
        }
        $mailer->clearRecipients();
        if (count($mailTo) > 0) {
          foreach ($mailTo as $mailTo) {
            $mailer->addRecipientsTo(new \EmailIdentity($mailTo['email'], $mailTo['name']));
          }
        }
        //VALIDACION POR SI NO TIENE CONTACTO
        if (count($mailTo2) > 0) {
          $mailer->addRecipientsTo(new \EmailIdentity($mailTo2, 'Contacto'));
        }
        if (count($mailTo3) > 0) {
          foreach ($mailTo3 as $mailTo3) {
            $mailer->addRecipientsTo(new \EmailIdentity($mailTo3['email'], $mailTo3['name']));
          }
        }
        if (count($mailTo4) > 0) {
          foreach ($mailTo4 as $mailTo4) {
            $mailer->addRecipientsTo(new \EmailIdentity($mailTo4['email'], $mailTo4['name']));
          }
        }
        if (count($mailTo5) > 0) {
          foreach ($mailTo5 as $mailTo5) {
            $mailer->addRecipientsTo(new \EmailIdentity($mailTo5['email'], $mailTo5['name']));
          }
        }

        $bd3 = " SELECT id FROM notes WHERE note_parent_id = '{$NoteId}' ";
        $adj_id = $GLOBALS['db']->getOne($bd3);

        $bd2 = " SELECT filename FROM notes WHERE note_parent_id = '{$NoteId}' ";
        $Name_nota = $GLOBALS['db']->getOne($bd2);

        $folder = substr($adj_id, 5, 3);
        $GLOBALS['log']->fatal("****** Busca id Note adjunto ****");
        $mailAttachment = "upload/" . $folder . "/" . $adj_id;
        $GLOBALS['log']->fatal("****** mailAttachment ****" . $mailAttachment);
        $GLOBALS['log']->fatal("****** Id Adjunto " . $adj_id . " ****");
        $GLOBALS['log']->fatal("****** Nombre adjunto " . $Name_nota . " ****");

        $mailer->addAttachment(new \Attachment($mailAttachment, $Name_nota));
        $bean->tct_email_contrato_c = true;
        $result = $mailer->send();
  • Hi - did you ever find a solution as I'm getting exactly the same on the latest v13? It's included images that are being messed up.

    Thanks

  • For reference, I found the issue - uploaded files now need to use the  FilePhpEntriesConverter class to get the correctly formatted file.  

     When you obtain the file location, you are referencing it from the uploads folder, it appears these have been encoded in some way (i think the images). You used a note attachment:

    $mailAttachment = "upload/" . $folder . "/" . $adj_id;

    whereas I used the UploadFile class to do the same for a document revision:

    $fileLoc = (new UploadFile)->realpath((new UploadFile)->get_upload_path($revision->id));

    $revision is a bean of the document revision class, it's id field is the name of the uploaded file - the same as your $adj_id

    The fix is to the the FilePhpEntriesConverter class to copy that upload file to the 'temp' directory, unencoding it at the same time. So my line becomes:

    use Sugarcrm\Sugarcrm\Util\Files\FilePhpEntriesConverter;
    ...
    $fileConverter = new FilePhpEntriesConverter();
    $fileLoc = $fileConverter->revert(UploadFile::realpath((new UploadFile)->get_upload_path($revision->id)));

    Then, attaching the file reference as this new $fileLoc will use the new unencoded version.