Search code examples
javascriptphpjqueryhtmlswiftmailer

Sending Files Using SwiftMailer getting SwiftIOException


I am using Swiftmailer to send multiple attachments/files. I have Javascript and HTML generating each file upload on a button click. If the user clicks the add file button 3 times there will be 3 separate file upload buttons that allow ONE file/image to be uploaded. The issue I am having is if a user adds 3 file uploads and only attaches/uses 2 of the 3 slots and try to submit an email then I get the classic

Fatal error: Uncaught exception 'Swift_IoException' with message 'The path cannot be empty' 

How do i remedy this if I already have my uploads going to a loop. I believe the issue lies in me adding input type="file" tags dynamically. How do I stop the SWIFT IO Exception to either allow an empty file upload to pass or better yet, prevent the email from being submitted if one or more file uploads are empty?

Swiftmail Upload

 if($_FILES['upload']['tmp_name'][0] != ''){
            for ($i=0; $i < count($_FILES['upload']['tmp_name']); $i++) {
                $message->attach(Swift_Attachment::fromPath($_FILES['upload']['tmp_name'][$i])
                    ->setFilename($_FILES['upload']['name'][$i]));
            }
        }

HTML:

 <div class="form-group">
         <label class="col-sm-3 control-label text-white bg-secondary">You can add multiple
                            attachments</label>
            <div class="col-sm-9">
              <span class="btn btn-default btn-file text-white bg-secondary">
                <input id="upload" name="upload[]" type="file" class="file" data-show-upload="true" data-show-caption="true">
                 <button type="button" class="btn btn-primary btn-sm" id="plus">Add File</button>
                 <button type="button" class="btn btn-danger btn-sm" id="minus">Remove File</button>
            </div>
    </div>

Current JS

$(document).ready(function(){
 //Multiple attachment addition
            $("#plus").click(function (newChild, refChild) {
                $('<input id="upload" name="upload[]" type="file" class="file" data-show-upload="true" data-show-caption="true"></span>').insertBefore(this, refChild);
            });
          }

Solution

  • Try code below:

    foreach ($_FILES["upload"]["error"] as $key => $error) {
        if ($error == UPLOAD_ERR_OK) {
            $tmp_name = $_FILES["upload"]["tmp_name"][$key];
            $name = basename($_FILES["upload"]["name"][$key]);
            $message->attach(Swift_Attachment::fromPath($tmp_name)->setFilename($name));
        }
    }
    

    Hope help you.

    How do I set a try catch block to check the "setTo" in this message?

     // Create a message
    
    
          try {
        $message = (new Swift_Message($_POST['subject']))
            //Email will be from the signed in user and the reply to will go to the signed in user
            ->setFrom($_SESSION['gazette']['Email'])
            ->setTo($finalEmailList)
            ->setBody($_POST['message'], 'text/html')
            ->setReplyTo($_SESSION['gazette']['Email']);
    
    //Allow multiple uploads
        foreach ($_FILES["upload"]["error"] as $key => $error) {
            if ($error == UPLOAD_ERR_OK) {
                $tmp_name = $_FILES["upload"]["tmp_name"][$key];
                $name = basename($_FILES["upload"]["name"][$key]);
                $message->attach(Swift_Attachment::fromPath($tmp_name)->setFilename($name));
            }
        }
    
        // Send the message
        $result = $mailer->send($message);
    } catch (Exception $exception) {
        // some logic
    }
    
        }