I'm trying to send the form data to spreadsheet and send an email with the data + attachments. My current code might be a mess a little bit, cuz before it was sending the data to firebase db, but now I reworked it to send the data to spreadsheet instead. The problem is, that my current code sends the data to spreadsheet well and it sends the email with the data but without attachments. Tried it different ways, but can't find out what is the problem.
form code:
<div class="form-div">
<div class="progress">
<div class="progress-bar"></div>
</div>
<form method="post" enctype="multipart/form-data" action="/mailer.php" class="col-12 mx-auto order-0" id="main-form">
<div class="form-sections">
<div class="first-section section">
<div class="heading-container">
<h5 class="pager">1 von 6</h5>
<div class="category-header-text ">
<span>
<svg class="category-header-icon" fill="none" height="6" viewBox="0 0 6 6" width="6" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9061 0.397705H0.303589V11.9077H11.9061V0.397705Z" fill="#FD3C21"></path>
</svg>
</span> WAS IST PASSIERT?
</div><br>
</div>
<div class="form-group group-first group">
<h1 class="title font-weight-bold row">Bitte beschreibe kurz, in welcher Angelegenheit wir dich rechtlich unterstützen können.</h1>
<textarea class="problem-textarea textarea form-control" autocapitalize="none" maxlength="2000" name="problem" id="problem" placeholder="" rows="5"></textarea>
<label class="nicht-ausfuhlen" for="checkbox-1" style="margin-top: 50px;">
<input type="checkbox" id="checkbox-1" name="checkbox-1" value="true">
<span class="checkbox-label">Ich möchte darüber lieber mit justify kostenlos und unverbindlich am Telefon sprechen und hier nichts ausfüllen.</span>
</label>
</div>
<div class="action-buttons" style="margin-bottom: 70px;">
<button class="next-button disabled first-next-button btn disabled" type="button"> WEITER </button>
</div>
</div>
<div class="second-section section">
<div class="heading-container">
<h5 class="pager">2 von 6</h5>
<div class="category-header-text">
<span>
<svg class="category-header-icon" fill="none" height="6" viewBox="0 0 6 6" width="6" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9061 0.397705H0.303589V11.9077H11.9061V0.397705Z" fill="#FD3C21"></path>
</svg>
</span> DEINE ERWARTUNGEN AN JUSTIFY
</div><br>
</div>
<div class="form-group group-second group">
<h1 class="title font-weight-bold">Was soll justify für dich erreichen?</h1>
<textarea id="justify" class="textarea form-control erreichen-textarea" autocapitalize="none" maxlength="2000" name="justify" placeholder="" rows="5"></textarea>
<label class="vorher" for="checkbox-2" style="margin-top: 50px;">
<input type="checkbox" id="checkbox-2" name="checkbox-2" value="true">
<span class="checkbox-label">Ich würde mich vorher gerne von justify unverbindlich und kostenlos beraten lassen, bevor ich dazu etwas sagen kann. </span>
</label>
</div>
<div class="action-buttons">
<button class="previous-button second-previous-button btn" type="button" tabindex="0"> <
ZURÜCK</button>
<button class="next-button second-next-button btn disabled" type="button"> WEITER </button>
</div>
</div>
<div class="section third-section" id="">
<div class="heading-container">
<h5 class="pager ion-padding-bottom">3 von 6</h5>
<div class="category-header-text">
<span>
<svg class="category-header-icon" fill="none" height="6" viewBox="0 0 6 6" width="6" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9061 0.397705H0.303589V11.9077H11.9061V0.397705Z" fill="#FD3C21"></path>
</svg>
</span> OPTIONAL: UPLOAD NACHWEISE
</div><br>
</div>
<div class="form-group group-first group">
<h1 class="title font-weight-bold unterlagen">Falls Unterlagen vorhanden und griffbereit… <br/> <span>(z.B. Verträge, Fotos, E-Mails...)</span></h1>
<div class="drag-box">
<div class="input-field">
<div class="input-images-2" style="padding-top: .5rem;"></div>
</div>
<div class="mobile-uploads-container col-12 mx-auto order-0"
style="padding-top: .5rem; width: 498px; border: 1px dashed #ddd !important; height:147px; text-align:center; color:#989aa2; font-size:13px; padding-top:6%;">
<div class="mobile-uploads text-left"> </div>
<label for="mobile-upload-photo"
class="mx-auto order-0 mobile-upload-label text-center "><span class="label-contents"><i
class="fa fa-cloud-upload" style="width:450px; height:100%;font-size:50px"></i>
<br>Click
to Upload</span></label>
<input type="file" name="photos[]" id="mobile-upload-photo" multiple
accept="image/png, image/jpeg , image/gif, image/svg, application/pdf" />
</div>
<div class="text-center info"> Max. Datei Größe: 20 MB
</div>
</div>
</div>
<div class="action-buttons">
<button class="previous-button third-previous-button btn" type="button" tabindex="0"> <
ZURÜCK</button>
<button class="next-button third-next-button btn" type="button"> WEITER </button>
</div>
</div>
<div class="fourth-section section">
<div class="heading-container">
<h5 class="pager ion-padding-bottom">4 von 6</h5>
<div class="category-header-text"><span><svg class="category-header-icon" fill="none" height="6"
viewBox="0 0 6 6" width="6" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9061 0.397705H0.303589V11.9077H11.9061V0.397705Z" fill="#FD3C21"></path>
</svg></span> KONTAKTDATEN
</div><br>
</div>
<div class="form-group">
<select name="anrede" id="anrede" style="height: 40px" class="form-control" id="">
<option value="" selected disabled>Anrede*</option>
<option value="Frau">Frau</option>
<option value="Herr">Herr</option>
</select>
</div>
<div class="form-group">
<input name="vorname" style="height: 40px" class="form-control" id="vorname" placeholder="Vorname*">
</div>
<div class="form-group">
<input name="nachname" style="height: 40px" class="form-control" id="nachname"
placeholder="Nachname*">
</div>
<div class="form-group">
<input name="email" style="height: 40px" class="form-control" id="email" placeholder="Email*">
</div>
<div class="form-group">
<input name="telefonenummer" style="height: 40px" class="form-control" id="telefone"
placeholder="Telefonnummer">
</div><br>
<div class="action-buttons">
<button class="previous-button fourth-previous-button btn" type="button" tabindex="0"> <
ZURÜCK</button>
<button class="next-button fourth-next-button btn disabled" type="button"> WEITER </button>
</div>
</div>
<div class="fourth-section-extended section" id="">
<div class="heading-container">
<h5 class="pager ion-padding-bottom">5 von 6</h5>
<div class="category-header-text"><span><svg class="category-header-icon" fill="none" height="6"
viewBox="0 0 6 6" width="6" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9061 0.397705H0.303589V11.9077H11.9061V0.397705Z" fill="#FD3C21"></path>
</svg></span> WIE BIST DU AUF UNS AUFMERKSAM GEWORDEN?
</div><br>
</div>
<label class="" for="checkbox-3"><input type="checkbox" id="checkbox-3" class="checkbox"
name="aufmerksam[]" value="Freunde/Familie/Bekannte">
<span class="checkbox-label-2">Freunde / Familie / Bekannte </span></label><br>
<label class="" for="checkbox-4"><input type="checkbox" id="checkbox-4" class="checkbox"
name="aufmerksam[]" value="Fernsehen/Radio">
<span class="checkbox-label-2">Fernsehen / Radio </span></label><br>
<label class="" for="checkbox-5"><input type="checkbox" id="checkbox-5" class="checkbox"
name="aufmerksam[]" value="Zeitungen">
<span class="checkbox-label-2">Zeitungen </span></label><br>
<label class="" for="checkbox-6"><input type="checkbox" id="checkbox-6" class="checkbox"
name="aufmerksam[]" value="Facebook">
<span class="checkbox-label-2">Facebook </span></label><br>
<label class="" for="checkbox-7"><input type="checkbox" id="checkbox-7" class="checkbox"
name="aufmerksam[]" value="Plakat">
<span class="checkbox-label-2">Außenwerbung (Plakat)</span></label><br>
<label class="" for="checkbox-8"><input type="checkbox" id="checkbox-8" class="checkbox"
name="aufmerksam[]" value="Google">
<span class="checkbox-label-2">Google</span></label><br>
<label class="" for="checkbox-9"><input type="checkbox" id="checkbox-9" class="checkbox"
name="aufmerksam[]" value="Taxi">
<span class="checkbox-label-2">Außenwerbung (Taxi) </span></label><br>
<label class="sonstiges-field" for="checkbox-10"><input type="checkbox"
class="sonstiges-checkbox checkbox" id="checkbox-10" name="aufmerksam[]" value="Sonstiges">
<span class="checkbox-label-2">Sonstiges </span></label><br>
<input type="text" name="sonstiges" class="col-6 form-control sonstiges hide" id="sonstiges">
<br><br>
<div class="action-buttons">
<button class="previous-button extended-fourth-previous-button btn" type="button" tabindex="0"> <
ZURÜCK</button>
<button class="next-button extended-fourth-next-button btn " type="button"> WEITER
</button>
</div>
</div>
<div class="fifth-section section" id="">
<div class="heading-container">
<h5 class="pager ">6 von 6</h5>
<div class="title font-weight-bold"> Zusammenfassung </div><br>
</div>
<div class="alert alert-success success-message" style="display:none;">Thank you!</div>
<div class="form-group">
<label for="thema">Thema</label>
<input id="thema" style="height: 40px" value="Nicht angegeben" disabled class="form-control" id=""
placeholder="thema*">
</div>
<div class="form-group">
<label for="problem-container">Problem*</label>
<input name="problem-container" style="height: 40px" value="Bitte noch angeben" class="form-control"
disabled id="problem-container">
</div>
<div class="form-group">
<label for="justify-container">Erwartung</label>
<input name="jusify-container" style="height: 40px" value="Nicht angegeben" disabled
class="form-control" id="jusify-container">
</div>
<div class="form-group">
<label for="name-container">Name*</label>
<input name="name-container" style="height: 40px" value="Bitte noch angeben" disabled
class="form-control" id="name-container">
</div>
<div class="form-group">
<label for="email-container">Email*</label>
<input name="email-container" style="height: 40px" value="Bitte noch angeben" disabled
class="form-control" id="email-container">
</div>
<div class="form-group">
<label for="telefone-container">Telefonnummer</label>
<input name="telefone-container" style="height: 40px" disabled value="Nicht angegeben"
class="form-control" id="telefone-container">
</div><br>
<div class="form-group diff-checkbox-container col-12 row">
<label class="" for="diff-checkbox"><input required type="checkbox" id="diff-checkbox" name="diff-checkbox"
value="true">
<span class="checkbox-label">Ich habe die <a href="/datenschutz">Datenschutzbestimmungen</a> gelesen und
akzeptiere sie.* </span></label>
</div>
<div class="action-buttons">
<button class="previous-button fifth-previous-button btn" type="button" tabindex="0"> <
ZURÜCK</button>
<button class="submit-button fifth-next-button btn disabled" type="submit">submit </button>
</div><br><br>
</div>
</div>
</form>
js code:
// Variable to store your files
var files;
// Add events
$('input[type=file]').on('change', prepareUpload);
// Grab the files and set them to our variable
function prepareUpload(event)
{
files = event.target.files;
}
// Catch the form submit and upload the files
function uploadFiles(event)
{
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
// START A LOADING SPINNER HERE
// Create a formdata object and add the files
var data = new FormData();
$.each(files, function(key, value)
{
data.append(key, value);
});
$.ajax({
url: 'mailer.php?files',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data, textStatus, jqXHR)
{
if(typeof data.error === 'undefined')
{
// Success so call function to process the form
// submitForm(event, data);
console.log("success")
}
else
{
// Handle errors here
console.log('ERRORS1: ' + data.error);
}
},
error: function(jqXHR, textStatus, errorThrown)
{
// Handle errors here
console.log('ERRORS2: ' + textStatus);
// STOP LOADING SPINNER
}
});
}
function submitForm(event, data)
{
// Create a jQuery object from the form
$form = $(event.target);
// Serialize the form data
var serializedData = $form.serialize();
// You should sterilise the file names
$.each(data.files, function(key, value)
{
serializedData = serializedData + '&filenames[]=' + value;
});
$.ajax({
url: 'mailer.php',
type: 'POST',
data: serializedData,
cache: false,
// dataType: 'json',
success: function(data, textStatus, jqXHR)
{
if(typeof data.error === 'undefined')
{
// Success so call function to process the form
console.log('SUCCESS: ' + data.success);
setTimeout(function() {
window.location.href = "erfolg";
}, 1000);
}
else
{
// Handle errors here
console.log('ERRORS3: ' + data.error);
}
},
error: function(jqXHR, textStatus, errorThrown)
{
// Handle errors here
console.log('ERRORS4: ' + textStatus);
},
complete: function()
{
// STOP LOADING SPINNER
}
});
}
// https://artisansweb.net/how-to-connect-firebase-realtime-database-to-your-website-form/
// TODO: Replace the following with your app's Firebase project configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
//databaseURL: "",
databaseURL: "",
storageBucket: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Get a reference to the database service
var database = firebase.database().ref();
$('#main-form').submit(function(e) {
e.preventDefault();
prepareUpload(e);
uploadFiles(e);
var newMessageRef = database.push();
var problemInput = $('#problem').val();
var problemDefault = 'Ich möchte darüber mit justify lieber kostenlos und unverbindlich am Telefon sprechen und nichts ausfüllen.';
var problem = '';
if (problemInput != '') {
problem = problemInput;
} else {
problem = problemDefault;
}
var justifyInput = $('#justify').val();
var justifyDefault = 'Ich würde mich vorher gerne von justify unverbindlich und kostenlos beraten lassen, bevor ich dazu etwas sagen kann.';
var justify = '';
if (justifyInput != '') {
justify = justifyInput;
} else {
justify = justifyDefault;
}
var FreundeFamilieBekannte = '';
var FernsehenRadio = '';
var Zeitungen = '';
var Facebook = '';
var Plakat = '';
var Google = '';
var Taxi = '';
var Sonstiges = '';
if($('#checkbox-3').is(":checked")) {
FreundeFamilieBekannte = $('#checkbox-3').val();
}
if($('#checkbox-4').is(":checked")) {
FernsehenRadio = $('#checkbox-4').val();
}
if($('#checkbox-5').is(":checked")) {
Zeitungen = $('#checkbox-5').val();
}
if($('#checkbox-6').is(":checked")) {
Facebook = $('#checkbox-6').val();
}
if($('#checkbox-7').is(":checked")) {
Plakat = $('#checkbox-7').val();
}
if($('#checkbox-8').is(":checked")) {
Google = $('#checkbox-8').val();
}
if($('#checkbox-9').is(":checked")) {
Taxi = $('#checkbox-9').val();
}
if($('#checkbox-10').is(":checked")) {
Sonstiges = $('#sonstiges').val();
}
newMessageRef.set({
BittebeschreibeDeinProblemSoGenauWieMöglich: problem,
WasSollJustifyFürDichErreichen: justify,
Anrede: $('#anrede').val(),
Vorname: $('#vorname').val(),
Nachname: $('#nachname').val(),
Email: $('#email').val(),
Telefonenummer: $('#telefone').val(),
WieBistDuAufUnsAufmerksamGeworden: {
FreundeFamilieBekannte: FreundeFamilieBekannte,
FernsehenRadio: FernsehenRadio,
Zeitungen: Zeitungen,
Facebook: Facebook,
Plakat: Plakat,
Google: Google,
Taxi: Taxi,
Sonstiges: Sonstiges
}
});
var WieBistDuAufUnsAufmerksamGeworden = {
FreundeFamilieBekannte: FreundeFamilieBekannte,
FernsehenRadio: FernsehenRadio,
Zeitungen: Zeitungen,
Facebook: Facebook,
Plakat: Plakat,
Google: Google,
Taxi: Taxi,
Sonstiges: Sonstiges
}
// setup some local variables
var $form = $(this);
// send array data aufmerksam[]
var aufmerksam = document.createElement("input")
aufmerksam.name = "aufmerksam[]"
var joinedChoices = '';
for (const choice in WieBistDuAufUnsAufmerksamGeworden) {
if (WieBistDuAufUnsAufmerksamGeworden[choice] != '') {
joinedChoices += `${WieBistDuAufUnsAufmerksamGeworden[choice]}, `
}
}
joinedChoices = joinedChoices.replace(RegExp(", $"), "")
aufmerksam.value = joinedChoices;
// Let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
$inputs = $inputs.filter((index, element) => {
return element.name != "aufmerksam[]"
})
$inputs = $inputs.add(aufmerksam)
// Serialize the data in the form
var serializedData = $inputs.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
$inputs.prop("disabled", true);
var data = new FormData();
$.each(files, function(key, value)
{
data.append(key, value);
});
$.each(data.files, function(key, value)
{
serializedData = serializedData + '&filenames[]=' + value;
});
request = $.ajax({
url: "https://script.google.com/macros/s/",
type: "post",
data: serializedData
});
// Callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
// Log a message to the console
console.log("Hooray, it worked!");
//uploadFiles(e);
//submitForm(e,serializedData);
$.ajax({
url: 'mailer.php',
type: 'POST',
dataType: 'html',//'default: Intelligent Guess (Other values: xml, json, script, or html)',
data: serializedData,
processData: false,
success: function(response) {
if(response == 'success') {
setTimeout(function() {
window.location.href = "erfolg";
}, 1000);
}
}
});
});
// Callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
// Log the error to the console
console.error(
"The following error occurred: "+
textStatus, errorThrown
);
});
// Callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// Reenable the inputs
$inputs.prop("disabled", false);
});
});
php mail:
<?php
$data = array();
if(isset($_GET['files'])) {
$error = false;
$files = array();
$maxsize = 10485760; // 10 MB
$format = array(
'application/pdf',
'image/jpeg',
'image/jpg',
'image/gif',
'image/png'
);
$uploaddir = 'uploads/';
foreach($_FILES as $file) {
// Get file type
$target_file = $uploaddir .basename($file['name']);
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
// Get image details
$check = getimagesize($file['tmp_name']);
// Get file size
$fileSize = $file['size'];
// Rename to new file name
$temp = explode(".", $file['name']);
$newfilename = round(microtime(true)) . '.' . end($temp);
// check file size and format
if($fileSize >= $maxsize || $fileSize == 0 || !in_array($file['type'],$format)) {
$error = true;
} else {
if(move_uploaded_file($file['tmp_name'], $uploaddir .basename($file['name']))) {
$files[] = $uploaddir .$file['name'];
} else {
$error = true;
}
}
}
$data = ($error) ? array('error' => 'There was an error uploading your files') : array('files' => $files);
} else {
if ($_POST['problem']) {
$problem = $_POST['problem'];
} else {
$problem = "Ich möchte darüber mit justify lieber kostenlos und unverbindlich am Telefon sprechen und nichts ausfüllen.";
}
if ($_POST['justify']) {
$justify = $_POST['justify'];
} else {
$justify = "Ich würde mich vorher gerne von justify unverbindlich und kostenlos beraten lassen, bevor ich dazu etwas sagen kann.";
}
$anrede = $_POST['anrede'];
$vorname = $_POST['vorname'];
$nachname = $_POST['nachname'];
$email = $_POST['email'];
$telefonenummer = $_POST['telefonenummer'];
$aufmerksam = $_POST['aufmerksam'];
$check_msg = '';
foreach($_POST['aufmerksam'] as $value) {
if($value === 'Sonstiges') {
$sonstigesValue = $_POST['sonstiges'];
$check_msg .= "Checked: $value ($sonstigesValue)";
} else {
$check_msg .= "Checked: $value <br>";
}
}
$fromemail = "etc@email.de";
$subject = "Form Contents";
$email_message1 = '<div style="background:#F8F8F8; font-size:12px;"><h2 style="font-size:20px; background:#004c66;color:white; padding:20px 30px"> FORM CONTENTS</h2>
<div style="padding:0px 30px 20px;"><p><b>Bitte beschreibe kurz, in welcher Angelegenheit wir dich rechtlich unterstützen können:</b> ' . $problem . '</p>
<p><b>Was soll justify für dich erreichen?</b> ' . $justify . '</p>
<p><b>Anrede:</b> ' . $anrede . '</p>
<p><b>Vorname:</b> ' . $vorname . '</p>
<p><b>Nachname:</b> ' . $nachname . '</p>
<p><b>E-Mail:</b> ' . $email . '</p>
<p><b>Telefonnummer:</b> ' . $telefonenummer . '</p>
<p><b>Wie bist du auf uns aufmerksam geworden?</b><br> ' . $check_msg . '</p>
</div></div>';
// Attachment file
// $file = "files/codexworld.pdf";
$file = $uploadedFile = $_POST['filenames'][0]; //"uploads/footer.png";
// Boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Headers for attachment
$headers = "From: " . $fromemail;
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// Multipart boundary
$email_message = "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"UTF-8\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" . $email_message1 . "\n\n";
// Preparing attachment
if(!empty($file) > 0){
if(is_file($file)){
$email_message .= "--{$mime_boundary}\n";
$fp = @fopen($file,"rb");
$data = @fread($fp,filesize($file));
@fclose($fp);
$data = chunk_split(base64_encode($data));
$email_message .= "Content-Type: application/octet-stream; name=\"".basename($file)."\"\n" .
"Content-Description: ".basename($file)."\n" .
"Content-Disposition: attachment;\n" . " filename=\"".basename($file)."\"; size=".filesize($file).";\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
}
}
$email_message .= "--{$mime_boundary}--";
$toemail = "blahblah@gmail.com";
$message2 = "CHECK MESSAGE";
$headers2 = "From: " . $fromemail;
if (mail($toemail, $subject, $email_message, $headers)) {
mail($email, $subject, $message2, $headers2);
} else {
}
}
echo json_encode($data);
?>
UPD: The main problem is inside the js code. As far as I understand now, $serializedData variable does not include the attachments, in spite of the fact it should based on this part of the code:
var data = new FormData();
$.each(files, function(key, value)
{
data.append(key, value);
});
$.each(data.files, function(key, value)
{
serializedData = serializedData + '&filenames[]=' + value;
});