<?php
namespace App\Controller\FrontEnd;
use App\Entity\Post;
use App\Entity\User;
use App\Entity\Forms;
use App\Entity\Country;
use App\Entity\Commande;
use App\Entity\FormsData;
use App\Entity\FormsFields;
use App\Twig\CryptExtension;
use App\Entity\ParametreSite;
use App\Service\EmailService;
use App\Entity\CommandeLignes;
use App\Entity\FormsTranslation;
use App\Service\EncryptionService;
use Symfony\Component\Intl\Locale;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpClient\CurlHttpClient;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class FormHandlerController extends AbstractController
{
private $theme;
private $emailService;
private $projectDir;
private $formUploadDir;
private $slugger;
private $encryptionService;
private $em;
private $client;
private $cryptExtension;
protected $session;
private $parameterBag;
public function __construct(string $theme,string $projectDir,string $formUploadDir,
HttpClientInterface $client,
ParameterBagInterface $parameterBag,
EmailService $emailService,
EntityManagerInterface $em,
SluggerInterface $slugger,
EncryptionService $encryptionService,
SessionInterface $session,
CryptExtension $cryptExtension){
$this->theme = $theme;
$this->emailService = $emailService;
$this->projectDir = $projectDir;
$this->formUploadDir = $formUploadDir;
$this->slugger = $slugger;
$this->encryptionService = $encryptionService;
$this->em = $em;
$this->session = $session;
$this->client = $client;
$this->cryptExtension = $cryptExtension;
$this->parameterBag = $parameterBag;
}
/**
* @Route("/api/submit-request", methods={"POST"} ,name="submit_request")
*/
public function index(Request $request)
{
$_locale = $request->getLocale();
$parametre = $this->em->getRepository(ParametreSite::class)->findOneBy([],['id'=> 'ASC']);
$recaptchaGoogle = $request->request->get('g-recaptcha-response');
$csrfToken = $request->request->get('token_id');
$formId = $this->cryptExtension->decryptValue($request->request->get('form-id'));
$data = $request->request->all();
$files = $request->files->all();
if (!$this->isCsrfTokenValid('form_handler', $csrfToken)) {
return new JsonResponse(['status' => 'erreur','message' => 'Token CSRF du formulaire invalide.']);
}
$app_env = $this->parameterBag->get('APP_ENV');
$fichiers = !empty($files) ? $this->processUpload($files):[];
try {
if($app_env != 'dev'){
if (!$recaptchaGoogle) {
return new JsonResponse(['status' => 'erreur','message' => 'reCAPTCHA invalide.']);
}
$response = $this->client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
'body' => ['secret' => $parametre->getCleSecret(),'response' => $recaptchaGoogle]
]);
$responseKeys = $response->toArray();
if (empty($responseKeys['success']) || !$responseKeys['success']) {
return new JsonResponse(['status' => 'erreur','message' => 'reCAPTCHA invalide.']);
}
if ($parametre->getTypeRecaptcha() == 1 && $responseKeys['score'] < 0.3) {
return new JsonResponse(['status' => 'erreur','message' => 'Score reCAPTCHA faible.']);
}
}
$formulaire = $this->em->getRepository(Forms::class)->findOneBy(['id'=> $formId]);
if($formulaire){
$methode = $formulaire->getMethode();
$formField = $this->em->getRepository(FormsFields::class)->findOneBy(['form'=> $formulaire,'local'=> $_locale]);
$message_sucess = $formulaire->translate($_locale)->getSuccessMessage() ?? 'Votre formulaire a été soumis avec succès.';
if($formField){
$fields = unserialize($formField->getData());
}
$data_form = $this->filterDataForm($data,$fields);
$email_user = isset($data['email']) ? $data['email']:null;
switch ($methode) {
case 'database':
$formsData = new FormsData();
$formsData->setForm($formulaire);
$formsData->setData(serialize($data));
$formsData->setFiles(serialize($fichiers));
$formsData->setLocal($_locale);
$this->em->persist($formsData);
$this->em->flush();
break;
case 'database_email':
$formsData = new FormsData();
$formsData->setForm($formulaire);
$formsData->setData(serialize($data));
$formsData->setFiles(serialize($fichiers));
$formsData->setLocal($_locale);
$this->em->persist($formsData);
$this->em->flush();
if($formulaire->getEmail()){
$emails = unserialize($formulaire->getEmail());
$this->emailService->sendEmailForm($formulaire->getEmailSubject(),$emails,$email_user,$data_form,$fichiers);
}
break;
case 'email':
if($formulaire->getEmail()){
$emails = unserialize($formulaire->getEmail());
$this->emailService->sendEmailForm($formulaire->getEmailSubject(),$emails,$email_user,$data_form,$fichiers);
}
break;
}
}
return new JsonResponse(['status' => 'success','message' => $message_sucess]);
} catch (\Exception $e) {
return new JsonResponse(['status' => 'erreur','message' => 'Erreur lors de la vérification du reCAPTCHA.', 'details' => $e->getMessage()]);
}
}
public function filterDataForm($dataForm,$fields,$fichiers = null){
$data = [];
$locale = Locale::getDefault();
$em = $this->getDoctrine()->getManager();
$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$index = 0;
if(isset($dataForm['id_etablissement'])){
$etablisement = $em->getRepository(Post::class)->find($dataForm['id_etablissement']);
if($etablisement){
$data[$index]['type'] = 'etablissment';
$data[$index]['label'] = 'Réservation';
$data[$index]['value'] = 'Je voudrais faire une réservation au '.$etablisement->translate($locale)->getTitle();
$index++;
}
}
if ($fields) {
foreach ($fields as $value) {
if($value){
foreach($value as $field){
if($field['type'] != 'header' && $field['name'] != 'check-condition'){
if($field['type'] != 'file'){
if(isset($field['name']) && isset($dataForm[str_replace("[]","",$field['name'])])){
if (isset($field['label'])) {
if ($field['label'] != '') {
$label = $field['label'];
}
}elseif(isset($field['placeholder'])){
if ($field['placeholder'] != ''){
$label = $field['placeholder'];
}
}else{
$label = null;
}
$data[$index]['type'] = $field['type'];
$data[$index]['label'] = $label;
$data[$index]['value'] = $dataForm[str_replace("[]","",$field['name'])];
}
$index++;
}else{
if ($fichiers) {
foreach($fichiers as $fichier){
if(isset($field['name']) && isset($fichier['name']) && ($field['name'] == $fichier['name']) && isset($fichier['value'])){
if (isset($field['label'])) {
if ($field['label'] != '') {
$label = $field['label'];
}
}else{
$label = null;
}
$data[$index]['type'] = $field['type'];
$data[$index]['label'] = $label;
$data[$index]['value'] = $protocol.$fichier[str_replace("[]","",'value')];
}
$index++;
}
}
}
}
}
}
}
}
return $data;
}
public function processUpload(array $files): array
{
$uploadedFiles = [];
$allowedTypes = ['pdf', 'doc', 'docx', 'txt', 'jpg', 'jpeg', 'png'];
$maxFileSize = 2048 * 1024; // 2 MB
foreach ($files['files'] as $file) {
if (!$file) {
continue;
}
$fileSize = $file->getSize();
$fileExtension = $file->guessExtension();
if (!in_array($fileExtension, $allowedTypes) || $fileSize > $maxFileSize) {
continue;
}
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $this->slugger->slug($originalFilename);
$uniqueId = hash('sha256', uniqid((string) mt_rand(), true));
$newFilename = sprintf('%s-%s.%s', $safeFilename, $uniqueId, $fileExtension);
$uploadPath = $this->formUploadDir . '/' . $newFilename;
if (file_exists($file->getRealPath())) {
move_uploaded_file($file->getRealPath(), $uploadPath);
$uploadedFiles[] = '/uploads/form-files/' . $newFilename;
}
}
return $uploadedFiles;
}
}