I have a problem with file uploading using AJAX and Symfony. I'd like to allow to a user to register and choose a custom profile picture when registering. If no profile pictures are uploaded, it will set a default profile picture. The problem is that I've tried many possibilities and none of them work. I'll give you my AJAX script, my PHP function and my HTML form so that you could help me to find where is the problem.
AJAX Script and HTML form :
<div class="modal fade" tabindex="-1" role="dialog" id="registerModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Inscription</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body" align="center">
<form action="#" method="POST" enctype="multipart/form-data">
<label for="pseudo">Pseudo<a class="logout">*</a> : </label>
<input type="text" name="pseudo" placeholder="Pseudo" id="pseudo" required><br>
<label for="mail">E-mail<a class="logout">*</a> : </label>
<input type="text" name="mail" placeholder="E-mail" id="mail" required><br>
<label for="motdepasse">Mot de passe<a class="logout">*</a> : </label>
<input type="password" name="motdepasse" placeholder="Mot de passe" id="motdepasse" required><br>
<label for="checkMotdepasse">Vérifiez le mot de passe<a class="logout">*</a> : </label>
<input type="password" name="checkMotdepasse" placeholder="Vérifiez votre mot de passe" id="checkMotdepasse" required><br>
<label for="adresse">Adresse postale<a class="logout">*</a> : </label>
<input type="text" name="adresse" placeholder="Adresse" id="adresse" required><br>
<label for="numAdresse">N° adresse<a class="logout">*</a> : </label>
<input type="text" name="numAdresse" placeholder="N° adresse" id="numAdresse" required><br>
<label for="cp">Code postal<a class="logout">*</a> : </label>
<input type="text" name="cp" placeholder="Code postal" id="cp" required><br>
<label for="ville">Ville<a class="logout">*</a> : </label>
<input type="text" name="ville" placeholder="Ville" id="ville" required><br>
<label for="avatar">Avatar (2Mb max) : </label>
<input type="file" name="avatar" id="avatar">
<input type="submit" class="btn btn-primary" id="register" value="S'inscrire"/>
</form><br>
<div id="messageOKRegister" style="color: limegreen">Vous êtes correctement inscrit ! Vous allez être automatiquement redirigé.</div>
<div id="messageErrorRegister" class="logout">Le formulaire n'est pas correctement rempli. Veuillez réessayer.</div>
<p>Les champs marqués d'un <a class="logout">*</a> sont obligatoires.</p>
</div>
</div>
</div>
</div>
<script src="{{ asset('js/jquery-3.5.1.min.js') }}"></script>
<script src="{{ asset('js/jquery-ui.min.js') }}"></script>
<script>
$(document).ready(function () {
$('#messageOKRegister').toggle(false);
$('#messageErrorRegister').toggle(false);
$("#register").click(function(event)
{
event.preventDefault();//Permet d'empêcher que la page se recharge après l'envoi du formulaire
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: '{{ path('checkReg') }}',
data: {
pseudo: $('input#pseudo').val(),
mail: $('input#mail').val(),
motdepasse: $('input#motdepasse').val(),
checkMotdepasse: $('input#checkMotdepasse').val(),
adresse: $('input#adresse').val(),
numAdresse: $('input#numAdresse').val(),
cp: $('input#cp').val(),
ville: $('input#ville').val(),
avatar: $('input#avatar').val()
},
dataType: 'json',
success: function(data)
{
console.log("OK ! " + data);
let sound = document.createElement('audio');
$('#register').prop('disabled', true);
if(data.loginOK === true)
{
sound.setAttribute('src', 'https://themushroomkingdom.net/sounds/wav/smb/smb_1-up.wav');
sound.onloadeddata = function () {
sound.play();
$('#messageErrorRegister').toggle(false);
$('#messageOKRegister').toggle(true);
bounce($('#registerModal'));
};
setTimeout(function () {window.location.replace('{{ path('boutique') }}');}, 5000);
}
else
{
sound.setAttribute('src', 'https://themushroomkingdom.net/sounds/wav/smb/smb_fireworks.wav');
sound.onloadeddata = function() {
sound.play();
$('#messageOKRegister').toggle(false);
$('#messageErrorRegister').replaceWith("<div id = \"messageErrorRegister\" class = \"logout\">" + data.message + "</div>").toggle(true);
shake($('#registerModal'));
$('#register').prop('disabled', false);
};
}
},
error: function(data)
{
console.log("Données PHP : " + data);
alert("Erreur détectée ! " + JSON.stringify(data));
}
});
});
});
function shake(thing) {
var interval = 100;
var distance = 10;
var times = 6;
for (var i = 0; i < (times + 1); i++) {
$(thing).animate({
left:
(i % 2 == 0 ? distance : distance * -1)
}, interval);
}
$(thing).animate({
left: 0,
top: 0
}, interval);
}
function bounce(thing) {
var interval = 100;
var distance = 20;
var times = 6;
var damping = 0.8;
for (var i = 0; i < (times + 1); i++) {
var amt = Math.pow(-1, i) * distance / (i * damping);
$(thing).animate({
top: amt
}, 100);
}
$(thing).animate({
top: 0
}, interval);
}
</script>
PHP function :
/**
* @Route("/checkReg", name="checkReg")
*/
public function checkRegister(Request $request)//TODO vérifier les inscriptions pour éviter des renvois de formulaire en rafraichissant la page
{
$pseudo = $request->request->get('pseudo');
$mail = $request->request->get('mail');
$motdepasse = $request->request->get('motdepasse');
$checkMotdepasse = $request->request->get('checkMotdepasse');
$adresse = $request->request->get('adresse');
$numAdresse = $request->request->get('numAdresse');
$adresseComplete = ($adresse . " " . $numAdresse);
$codePostal = $request->request->get('cp');
$ville = $request->request->get('ville');
$avatar = $request->files->get('avatar');
$repoUser = $this->getDoctrine()->getRepository(Utilisateur::class);
$pseudoDB = $repoUser->findOneBy(["pseudo" => $pseudo]);
$mailDB = $repoUser->findOneBy(["email" => $mail]);
$user = new Utilisateur();
if ($pseudoDB)
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "Le pseudo est déjà utilisé."));
}
elseif ($mailDB)
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "L'e-mail est déjà utilisé."));
}
elseif ($motdepasse != $checkMotdepasse)
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "Échec de la vérification du mot de passe."));
}
elseif (!is_numeric($numAdresse))
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "Numéro d'adresse incorrect."));
}
elseif (!is_numeric($codePostal))
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "Code postal incorrect."));
}
else
{
$user->setPseudo($pseudo)->setEmail($mail)->setMotDePasse($motdepasse)->setAdresse($adresseComplete)->setCodePostal((int) $codePostal)
->setVille($ville)->setNoteGlobaleArticleConforme(0.0)->setNoteGlobaleCommunicationVendeur(0.0)
->setNoteGlobaleRapiditeLivraison(0.0)->setIsAdmin(false);
if ($avatar == "")
{
$user->setAvatar("/avatars/default.jpg");
}
else
{
if ($_FILES['avatar']['size'] <= 2000000)
{
$infoAvatar = pathinfo($_FILES['avatar']['name']);
$extension = $infoAvatar['extension'];
$tabExtension = array('jpg', 'jpeg', 'gif', 'png');
if (in_array($extension, $tabExtension))
{
move_uploaded_file($_FILES['avatar']['tmp_name'], '/avatars/' . basename($_FILES['avatar']['name']));
}
$user->setAvatar("/avatars/" . basename($_FILES['avatar']['name']));
}
else
{
return new JsonResponse(array('avatar' => $avatar, 'loginOK' => false, 'message' => "Votre avatar doit faire moins de 5Mb."));
}
}
$manager = $this->getDoctrine()->getManager();
$manager->persist($user);
$manager->flush();
return new JsonResponse(array('loginOK' => true));
}
}
If you could help me to find where is the problem, it will be wonderful ! Thank you in advance for your answers.