1

So I'm having a bit of an issue when trying to send an email to myself with an attachment. I'm not using the standard php mail function, I'm using PHPMailer because of convenience. I'm running the post through an Ajax call and I've done extensive research to make sure that it formats correctly.

What is happening is that when I am submitting my form all the data sends through correctly. I'm getting the image name, but nothing else with it. My content type is set correctly, and everything else is set correctly, so I"m just confused as to what is going on and could use a little insight.

All my code is sectioned off below

html form index.php

<form id='requestArtForm' action='' method='post'>
    <div class='row'>
        <section class='form-group col-sm-6 col-xs-12'>
            <label class='control-label req'>Name</label>
            <input type='text' class='form-control' id='name' data-validator='notEmpty'/>
        </section>
        <section class='clearfix'></section>
        <section class='form-group col-sm-6 col-xs-12'>
            <label class='control-label req'>E-Mail Address</label>
            <input type='email' class='form-control' id='email_address' data-validator='notEmpty|isEmail' />
        </section>
        <section class='clearfix'></section>
        <section class='form-group col-sm-6 col-xs-12'>
            <label class='control-label'>Phone Number</label>
            <input type='tel' class='form-control' id='phone' data-validator='isPhoneNumber' />
        </section>
        <section class='clearfix'></section>
        <section class='form-group col-sm-6 col-xs-12'>
            <label class='control-label'>Upload an Image</label>
            <input type='file' name='images[]' multiple/>
        </section>
        <section class='clearfix'></section>
        <section class='form-group col-xs-12'>
            <label class='control-label req'>Additional Comments</label>
            <textarea class='form-control' rows='5' id='comments' data-validator='notEmpty'></textarea>
        </section>
        <section class='form-group col-xs-12'>
            <button type='submit' class='btn btn-primary pull-right'>Send Message</button>
        </section>
    </div>
</form>

javascript main_scripts.php

$('#requestArtForm').submit(function(e){
    e.preventDefault();
    $('body').spin('large');
    var formData = new FormData();
    formData.append('callback', 'requestDrawing');
    formData.append('parameters[]', $('#requestArtForm #name').val());
    formData.append('parameters[]', $('#requestArtForm #email_address').val());
    formData.append('parameters[]', $('#requestArtForm #phone').val());
    formData.append('parameters[]', $('#requestArtForm #comments').val());
    $.each($('[name="images[]"]')[0].files, function(i, file){
        formData.append('images[]', file);
    });
    if(validator($(this))){
        $.ajax({
            url : "<?=APP_BASE?>assets/server/callbacks.php",
            type : 'POST',
            data : formData,
            dataType : 'JSON',
            contentType : 'multipart/form-data',
            processData : false,
            success : function(data){
                $('body').spin(false);
                if(!data.errors){
                    }else{
                    }
            }
        });
    }else{
        $('body').spin(false);
    }
});

PHP callbacks.php

$enabledFunctions = array();
$MAIL = new PHPMailer();

function enableFunction($function){
    global $enabledFunctions;
    array_push($enabledFunctions, $function);
}

function requestDrawing($name, $email_address, $phone, $comments){
    global $MAIL;
    $response = array();

    if(empty($name) or empty($email_address)){
        $response['errors'] = true;
        $response['message'] = "Please make sure all the required fields are filled out. Fields marked with an asterisk are required.";
    }else{

        $body = "You have a new message from $name\n\n";
        $body .= "Name: $name\n";
        $body .= "Email Address: $email_address\n";
        $body .= "Phone Number: $phone\n";
        $body .= "Comments: $comments\n\n";

        $MAIL->From = "$email_address";
        $MAIL->FromName = "$name";
        $MAIL->AddAddress("mark@neartist.com", "Mark Hill");
        $MAIL->AddReplyTo("$email_address", "$name");
        if (isset($_FILES['images']) && $_FILES['images']['error'] == UPLOAD_ERR_OK) {
            $MAIL->AddAttachment($_FILES['images']['tmp_name'], $_FILES['images']['name']);
        }
        $MAIL->Subject = "New Message from $name";
        $MAIL->Body = $body;

        if(!$MAIL->Send()){
            $response['errors'] = true;
            $response['success'] = "There was an error when trying to send you message, please try again later.";
        }else{
            $response['success'] = "Your message has been sent!";
        }
    }

    return $response;
}
enableFunction('requestDrawing');

$function = $_POST['callback'];
$parameters = isset($_POST['parameters']) ? array_values($_POST['parameters']) : "";
if(empty($parameters) && in_array($function, $enabledFunctions)){
    echo json_encode(call_user_func($function));
}elseif(in_array($function, $enabledFunctions)){
    echo json_encode(call_user_func_array($function, $parameters));
}

I thoroughly followed the PHPMailer documentation and double checked what I have written out here, but nothing seems to be giving me the proper solution.

Edit:

Setting the content-Type : 'multipart/form-data' provides a PHP error of Undefined index: callback. Setting enctype on the form provides the identical error. Setting it to false sends the message but I have no attachment.

Also, when looking through the devloper tools, when I check the response tab, I get this when I run print_r($_FILES['images']

Array
(
    [name] => 20150625_140017.jpg
    [type] => 
    [tmp_name] => 
    [error] => 1
    [size] => 0
)
Mark Hill
  • 1,769
  • 2
  • 18
  • 33
  • are you using a valid enctype? if not, do. – Funk Forty Niner Aug 19 '15 at 15:31
  • you mean like `multipart/form-data`? Wouldn't that be set under the `content-type` option? Futhermore, wouldn't that jack up the entire code structure for the ajax if `content-type` was not set to false? Also good to see you again @Fred-ii- – Mark Hill Aug 19 '15 at 15:32
  • if that isn't implied anywhere, it will fail. It is required when dealing with files/uploads/attachments. add it in your form tags – Funk Forty Niner Aug 19 '15 at 15:33
  • I thought setting the `content-type` to false took care of that situation though? I have updated the code to reflect this change – Mark Hill Aug 19 '15 at 15:34
  • *Hm...* TBH Mark, I'm not entirely sure about that, yet alone convinced. Have you tried either? Adding the enctype in the form tags? – Funk Forty Niner Aug 19 '15 at 15:36
  • 1
    I am trying this as we speak, both with the content-type as false, and set to multipart/form-data, if that fails I will set `enctype` in the form tag as well and see what happens. Stand by please! – Mark Hill Aug 19 '15 at 15:38
  • 1
    this may help also http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously and http://stackoverflow.com/questions/23980733/jquery-ajax-file-upload-php and http://www.sanwebe.com/2012/06/ajax-file-upload-with-php-and-jquery – Funk Forty Niner Aug 19 '15 at 15:42
  • setting the `content-Type : 'multipart/form-data'` provides a PHP error of `Undefined index: callback`. Setting enctype on the form provides the identical error. setting it to false sends the message but I have no attachtment. – Mark Hill Aug 19 '15 at 15:45
  • @Fred-ii- I read through those articles and I've implemented a few things, but I'm getting no results, but I did run a `print_r` on the files constant, and posted my results under the edits. – Mark Hill Aug 19 '15 at 15:59
  • 1
    Ok Mark. I added your earlier comment to the question, but couldn't comment further since I cannot solve it for you. I upvoted the question, hoping someone will pick up on it. Good luck Mark, I hope you get this resolved :) *cheers* – Funk Forty Niner Aug 19 '15 at 16:01

1 Answers1

-1

Take a look at the example provided with PHPMailer. You're missing some standard stuff for handling file uploads in PHP, but it's done correctly in that example.

Setting the submitter's address as the From address will fail SPF checks - put your own address in From and the submitter's in reply-to.

It looks like you've based your code on an obsolete example, so make sure you have the latest PHPMailer too.

Synchro
  • 35,538
  • 15
  • 81
  • 104
  • I don't think you fully read the problem or looked at the edits up top. It has nothing to do with when the e-mail is actually being sent. That works just fine. I'm also using the most up to date version of PHPMailer. What is happening is that the file data such as type, and size, and tmp_name, are not being sent over to the sever, they are null. I want to know how and why this is occurring. – Mark Hill Aug 19 '15 at 17:54
  • Then you need to split up your problem and isolate the part that's not working. PHPMailer can set the type and size for you, but it's PHP itself that sets the values in $_FILES, not your client. Everything I said is still true. – Synchro Aug 19 '15 at 18:18
  • while it may be true, my version is still working, nor was it the problem. It turns out I need a different hosting plan that allows a file size greater than 500KB. fml – Mark Hill Aug 19 '15 at 18:20