Q:

Formulario con imagen, ajax y phpmailer

Estoy intentando hacer una petición POST pero todos los datos se envían excepto la imagen.
¿Cómo puedo solucionarlo?
JavaScript
$(function () {
$("#botonEnviar").click(function () {
    var nombre = document.getElementById("nombre").value;
    var correo = document.getElementById("correo").value;
    var mensaje = document.getElementById("mensaje").value;
    var telefono = document.getElementById("telefono").value;
    var foto = document.getElementById("foto");
    if (nombre == "") {
        $('#nombre').focus();
        $('#nombre').css('border-color', 'red');
        return false;
    } else if (correo == "") {
        $('#correo').focus();
        $('#correo').css('border-color', 'red');
        return false;
    } else if (mensaje == "") {
        $('#mensaje').focus();
        $('#mensaje').css('border-color', 'red');
        return false;
    } else if (telefono == "") {
        $('#telefono').focus();
        $('#telefono').css('border-color', 'red');
    } else {
        var formData = new FormData();
        formData.append('nombre', nombre);
        formData.append('correo', correo);
        formData.append('mensaje', mensaje);
        formData.append('telefono', telefono);
        formData.append('foto', foto);
        $('input').val('');
        $('textarea').val('');
        $.ajax({
            url: 'php/procesar.php',
            data: formData,
            processData: false,
            contentType: false,
            type: 'POST',
            dataType: 'JSON',
            success: function () {
            },
            error: function (xhr, ajaxOptions, thrownError) {
                $('.msg').text(thrownError);
            }
        });
        return false;
    }
});
});

procesar.php
<?php
require 'PHPMailerAutoload.php';

$phpMailer = new PHPMailer;
$phpMailer->isSMTP();
$phpMailer->SMTPDebug = 2;
$phpMailer->Debugoutput = 'html';
$phpMailer->Host = 'smtp.gmail.com';
$phpMailer->Port = 587;
$phpMailer->SMTPSecure = 'tls';
$phpMailer->SMTPAuth = true;

/*Datos Formulario*/
$nombre = $_POST['nombre'];
$correo = $_POST['correo'];
$mensaje = $_POST['mensaje'];
$telefono = $_POST['telefono'];
$fotoTmp = $_FILES['foto']['tmp_name'];
$fotoName = $_FILES['foto']['name'];

/*Cuenta Info*/
$phpMailer->Username = $info;
$phpMailer->Password =  $pswp;
$phpMailer->setFrom($info, $asunto);
$phpMailer->addAddress($correo, $nombre);
$phpMailer->addAddress($info, $nmb);

if(isset($_FILES['foto']) && $_FILES['foto']['error'] == UPLOAD_ERR_OK){
    $phpMailer->addAttachment($fotoTmp, $fotoName);
}

/*Mensaje para contacto*/
$phpMailer->isHTML(true);
$phpMailer->Subject = 'Asunto Mensaje';
$phpMailer->IsHTML(true);
$phpMailer->msgHTML(file_get_contents('mensaje.html'),dirname(__FILE__));

$phpMailer->AltBody = 'Cuerpo del Mensaje';

if (!$phpMailer->Send()) {
    echo "Error: ".$phpMailer->ErrorInfo;
}else{
    echo "Mensaje Enviado";
}    
?>

A:

Debes usar new FormData(this); para facilitar la tarea de crear los datos del formulario que serán enviados a través de XHR, acceder campo a campo funciona con los de valores de texto, pero no con las imágenes:
$(function () {
$("body").on("submit", "form", function () {
    var nombre = document.getElementById("nombre").value;
    var correo = document.getElementById("correo").value;
    var mensaje = document.getElementById("mensaje").value;
    var telefono = document.getElementById("telefono").value;
    var foto = document.getElementById("foto");
    if (nombre == "") {
        $('#nombre').focus();
        $('#nombre').css('border-color', 'red');
        return false;
    } else if (correo == "") {
        $('#correo').focus();
        $('#correo').css('border-color', 'red');
        return false;
    } else if (mensaje == "") {
        $('#mensaje').focus();
        $('#mensaje').css('border-color', 'red');
        return false;
    } else if (telefono == "") {
        $('#telefono').focus();
        $('#telefono').css('border-color', 'red');
    } else {
        var formData = new FormData(this);
        $('input').val('');
        $('textarea').val('');
        $.ajax({
            url: 'php/procesar.php',
            data: formData,
            processData: false,
            contentType: false,
            type: 'POST',
            success: function () {
            },
            error: function (xhr, ajaxOptions, thrownError) {
                $('.msg').text(thrownError);
            }
        });
        return false;
    }
});
});

Deberás cambiar el <button> por un <input type="submit"> para que te funcione el evento submit. En caso contrario dime cómo acceder a tu formulario o pon su HTML para que te diga cómo acceder a sus datos.

