<?php
namespace App\Controller\Front;
use DateTime;
use App\Entity\User;
use App\Entity\Alert;
use App\Entity\Booking;
use App\Entity\Trainee;
use App\Entity\SearchNote;
use App\Entity\SportTrainee;
use App\Form\SearchNoteType;
use App\Service\BrevoService;
use App\Entity\PasswordUpdate;
use App\Form\NotificationType;
use App\Service\ImageOptimizer;
use App\Form\PasswordUpdateType;
use App\Form\TraineeProfileType;
use App\Form\TraineeRegisterType;
use App\Repository\AgeRepository;
use App\Repository\NoteRepository;
use App\Repository\RoleRepository;
use App\Repository\UserRepository;
use App\Service\DocumentGenerator;
use App\Form\SearchNoteTraineeType;
use App\Form\TraineePreferenceType;
use App\Repository\AlertRepository;
use App\Repository\LevelRepository;
use App\Repository\SportRepository;
use App\EmailNotification\ToTrainee;
use App\Form\TraineeShowContactType;
use App\Repository\BookingRepository;
use App\Repository\MessageRepository;
use App\Repository\TraineeRepository;
use App\Service\InternationalService;
use Symfony\Component\Form\FormError;
use App\Repository\LanguageRepository;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\NoteRequestRepository;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\String\Slugger\AsciiSlugger;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
#[Route(path: '/{_locale}')]
class TraineeController extends AbstractController
{
private $translator;
private $imageOptimizer;
private $internationalService;
private $request;
public function __construct(TranslatorInterface $translator, ImageOptimizer $imageOptimizer, InternationalService $internationalService, RequestStack $requestStack)
{
$this->translator = $translator;
$this->imageOptimizer = $imageOptimizer;
$this->internationalService = $internationalService;
$this->request = $requestStack->getCurrentRequest();
}
#[Route(path: '/trainee/my-profile', name: 'trainee_profile')]
public function traineeProfil(SportRepository $sportRepository, Request $request, EntityManagerInterface $manager, UserPasswordHasherInterface $passwordHasher, ToTrainee $toTrainee)
{
$slugger = new AsciiSlugger();
/**
* @var Trainee $trainee
*/
$trainee = $this->getUser();
$sports = $sportRepository->findAll();
$traineeSports = [];
$oldSportsTrainee = $trainee->getSports();
foreach ($oldSportsTrainee as $sportTrainee) {
$traineeSports[] = $sportTrainee->getSport();
}
foreach ($sports as $sport) {
if (!in_array($sport, $traineeSports)) {
$sportTrainee = new SportTrainee();
$sportTrainee->setTrainee($trainee)
->setSport($sport);
$trainee->addSport($sportTrainee);
}
}
$passUpdate = new PasswordUpdate();
$formPassword = $this->createForm(PasswordUpdateType::class, $passUpdate);
$formNotification = $this->createForm(NotificationType::class, $trainee);
$formProfile = $this->createForm(TraineeProfileType::class, $trainee);
$formPreference = $this->createForm(TraineePreferenceType::class, $trainee);
$formShowContact = $this->createForm(TraineeShowContactType::class, $trainee);
$formPassword->handleRequest($request);
$formNotification->handleRequest($request);
$formProfile->handleRequest($request);
$formPreference->handleRequest($request);
$formShowContact->handleRequest($request);
if ($formPreference->isSubmitted() && $formPreference->isValid()) {
$sportsTrainee = $trainee->getSports();
$haveSport = false;
foreach ($sportsTrainee as $sportTrainee) {
if ($sportTrainee->getLevel() === null || $sportTrainee->getLevel() == 'none') {
$trainee->removeSport($sportTrainee);
$manager->remove($sportTrainee);
} else {
$haveSport = true;
$manager->persist($sportTrainee);
}
}
if (!$haveSport) {
$this->addFlash(
'error',
$this->translator->trans("flashes.trainee_controller.need_preference")
);
return $this->redirectToRoute('trainee_profile');
}
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.trainee_controller.update_preferences')
);
return $this->redirectToRoute('trainee_profile');
}
if ($formPassword->isSubmitted() && $formPassword->isValid()) {
if (!password_verify($passUpdate->getOldPassword(), $trainee->getPassword())) {
$formPassword->get('oldPassword')->addError(new FormError("Ce n'est pas votre de passe actuel!"));
} else {
$newPass = $passUpdate->getNewPassword();
$hash = $passwordHasher->hashPassword($trainee, $newPass);
$trainee->setPassword($hash);
foreach ($trainee->getSports() as $sportTrainee) {
if (!in_array($sportTrainee->getSport(), $traineeSports)) {
$trainee->removeSport($sportTrainee);
} else {
$manager->persist($sportTrainee);
}
}
$manager->persist($trainee);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.trainee_controller.update_password')
);
$toTrainee->confirmUpdatePassword($trainee);
return $this->redirectToRoute('trainee_profile');
}
}
if ($formProfile->isSubmitted() && $formProfile->isValid()) {
foreach ($trainee->getSports() as $sportTrainee) {
if (!in_array($sportTrainee->getSport(), $traineeSports)) {
$trainee->removeSport($sportTrainee);
} else {
$manager->persist($sportTrainee);
}
}
$slug = strtolower($slugger->slug($trainee->getFirstname() . ' ' . $trainee->getLastname() . ' ' . $trainee->getId(), '-'));
$trainee->setSlug($slug);
$manager->persist($trainee);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.trainee_controller.update_info')
);
return $this->redirectToRoute('trainee_profile');
}
if ($formNotification->isSubmitted() && $formNotification->isValid()) {
foreach ($trainee->getSports() as $sportTrainee) {
if (!in_array($sportTrainee->getSport(), $traineeSports)) {
$trainee->removeSport($sportTrainee);
} else {
$manager->persist($sportTrainee);
}
}
$manager->persist($trainee);
$manager->flush();
if ($trainee->getNotification() == true) {
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.activate_notifications')
);
} else {
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.disable_notifications')
);
}
return $this->redirectToRoute('trainee_profile');
}
if ($formShowContact->isSubmitted() && $formShowContact->isValid()) {
foreach ($trainee->getSports() as $sportTrainee) {
if (!in_array($sportTrainee->getSport(), $traineeSports)) {
$trainee->removeSport($sportTrainee);
} else {
$manager->persist($sportTrainee);
}
}
$manager->persist($trainee);
$manager->flush();
$this->addFlash(
'success',
"L'affichage de vos coordonnées a été mis à jour."
);
return $this->redirectToRoute('trainee_profile');
}
return $this->render('front/trainee/profile.html.twig', [
'menu' => 'profile',
'formProfile' => $formProfile->createView(),
'formPreference' => $formPreference->createView(),
'formPassword' => $formPassword->createView(),
'formNotification' => $formNotification->createView(),
'formShowContact' => $formShowContact->createView(),
'sports' => $trainee->getSports(),
'trainee' => $trainee,
]);
}
#[Route(path: '/trainee/my-alerts', name: 'trainee_alerts')]
public function alerts(AlertRepository $alertRepository): Response
{
$trainee = $this->getUser();
$alerts = $alertRepository->findBy(['trainee' => $trainee]);
return $this->render('front/trainee/alerts.html.twig', [
'menu' => 'alerts',
'alerts' => $alerts
]);
}
#[Route(path: '/edit-email-activation', name: 'edit_email_activation')]
public function editEmailActivation(AlertRepository $alertRepository, EntityManagerInterface $manager)
{
$id = $_POST['id'];
$alert = $alertRepository->find($id);
if ($alert->getEmailActivated()) {
$alert->setEmailActivated(false);
} else {
$alert->setEmailActivated(true);
}
$manager->persist($alert);
$manager->flush();
if ($alert->getEmailActivated()) {
$this->addFlash(
'success',
$this->translator->trans("flashes.trainee_controller.notifications_enabled")
);
} else {
$this->addFlash(
'success',
$this->translator->trans("flashes.trainee_controller.notifications_disabled")
);
}
return $this->redirectToRoute('trainee_alerts');
}
#[Route(path: '/edit-alert', name: 'edit_alert')]
public function editAlert(AlertRepository $alertRepository, SportRepository $sportRepository, AgeRepository $ageRepository, LanguageRepository $languageRepository, LevelRepository $levelRepository, EntityManagerInterface $manager)
{
$id = $_POST['id'];
$alert = $alertRepository->find($id);
if ($_POST['title']) {
$alert->setTitle($_POST['title']);
}
if (count($_POST) > 1) {
if (!isset($_POST['country'])) {
$alert->setCountryCode(null);
}
foreach ($alert->getSports() as $sport) {
$alert->removeSport($sport);
}
if (isset($_POST['sports'])) {
foreach ($_POST['sports'] as $sportId) {
$alert->addSport($sportRepository->find($sportId));
}
}
if (!isset($_POST['begin'])) {
$alert->setBegin(null);
}
foreach ($alert->getAges() as $age) {
$alert->removeAge($age);
}
if (isset($_POST['ages'])) {
foreach ($_POST['ages'] as $ageId) {
$alert->addAge($ageRepository->find($ageId));
}
}
foreach ($alert->getLanguages() as $language) {
$alert->removeLanguage($language);
}
if (isset($_POST['languages'])) {
foreach ($_POST['languages'] as $languageId) {
$alert->addLanguage($languageRepository->find($languageId));
}
}
foreach ($alert->getLevels() as $level) {
$alert->removeLevel($level);
}
if (isset($_POST['levels'])) {
foreach ($_POST['levels'] as $levelId) {
$alert->addLevel($levelRepository->find($levelId));
}
}
$manager->persist($alert);
$this->addFlash(
'success',
$this->translator->trans("flashes.trainee_controller.alert_modified")
);
} else {
$manager->remove($alert);
$this->addFlash(
'success',
$this->translator->trans("flashes.trainee_controller.alert_deleted")
);
}
$manager->flush();
return $this->redirectToRoute('trainee_alerts');
}
#[Route(path: '/delete-alert/{id}', name: 'delete_alert', requirements: ['id' => '\d+'])]
public function deleteAlert(Alert $alert, EntityManagerInterface $manager)
{
$manager->remove($alert);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans("flashes.trainee_controller.alert_deleted")
);
return $this->redirectToRoute('trainee_alerts');
}
#[Route(path: '/trainee/my-favorites-courses', name: 'trainee_courses_favorites')]
public function favoriteCourses(): Response
{
$user = $this->getUser();
if ($user instanceof Trainee) {
$courses = $user->getFavorites();
return $this->render('front/trainee/favorites-courses.html.twig', [
'menu' => 'favoris',
'courses' => $courses,
'startingDate' => null
]);
}
}
#[Route(path: '/trainee/my-favorites-pros', name: 'trainee_pros_favorites')]
public function favoritePros(): Response
{
$user = $this->getUser();
if ($user instanceof Trainee) {
$pros = $user->getProFavorites();
return $this->render('front/trainee/favorites-pros.html.twig', [
'menu' => 'favoris',
'pros' => $pros,
]);
}
}
#[route(path: '/trainee/my-bookings/{status}', name: 'list_bookings', defaults: ['status' => null])]
public function listBookings($status, BookingRepository $bookingRepository)
{
$trainee = $this->getUser();
if ($status == null) {
$status = 'accepted';
}
if (in_array($status, ['accepted', 'pending', 'done', 'canceled'])) {
$bookings = $bookingRepository->findTraineeBookingByStatus($trainee, $status);
} else {
return $this->redirectToRoute('list_bookings');
}
if ($status == 'accepted') {
usort($bookings, array($this, "cmp"));
}
return $this->render('/front/trainee/list-bookings.html.twig', [
'bookings' => $bookings,
'status' => $status,
'menu' => 'bookings'
]);
}
function cmp($a, $b)
{
$aBegin = date_create_from_format('d.m.y', $a->getBegin());
$bBegin = date_create_from_format('d.m.y', $b->getBegin());
return ($aBegin > $bBegin);
}
#[Route(path: '/trainee/course-bill/booking-{ref}', name: 'generate_course_bill')]
public function generateCourseBill($ref, BookingRepository $bookingRepo, DocumentGenerator $documentGenerator)
{
$trainee = $this->getUser();
$booking = $bookingRepo->findOneBy(['ref' => $ref, 'trainee' => $trainee]);
if ($booking) {
try {
$documentGenerator->generateBookingRecap($booking, 'trainee');
die();
} catch (\Throwable $th) {
$this->addFlash(
"success",
$this->translator->trans("flashes.pro_controller.error_occured")
);
return $this->redirectToRoute('list_bookings');
}
} else {
return $this->redirectToRoute('list_bookings');
}
}
#[Route(path: '/trainee/given-reviews', name: 'trainee_note_given')]
public function noteGiven(NoteRepository $noteRepository, PaginatorInterface $paginator, Request $request): Response
{
$trainee = $this->getUser();
$form = $this->createForm(SearchNoteTraineeType::class, null, ['trainee' => $trainee]);
$form->handleRequest($request);
$searchSubmitted = null;
if ($form->isSubmitted() && $form->isValid()) {
$searchSubmitted = $form->getData();
}
$notes = $paginator->paginate(
$noteRepository->searchTraineeGivenNotes($trainee, $searchSubmitted),
$this->request->query->getInt('page', 1),
15
);
return $this->render('front/trainee/note/note-given.html.twig', [
'menu' => 'note',
'trainee' => $trainee,
'form' => $form->createView(),
'notes' => $notes
]);
}
#[Route(path: '/trainee/pending-reviews', name: 'trainee_note_pending')]
public function notePending(MessageRepository $messageRepository, BookingRepository $bookingRepository, NoteRequestRepository $noteRequestRepository, Request $request, PaginatorInterface $paginator): Response
{
$locale = $request->getLocale();
/** @var User $trainee */
$trainee = $this->getUser();
$searchSubmitted = null;
$nameSearch = null;
$courseToken = null;
$form = $this->createForm(SearchNoteTraineeType::class, null, ['trainee' => $trainee]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$searchSubmitted = $form->getData();
$nameSearch = $searchSubmitted['name'];
$courseToken = $searchSubmitted['course'] ? $searchSubmitted['course']->getToken() : '';
}
$notationMessages = $messageRepository->findTraineePendingNotationMessages($trainee);
$requests = [];
foreach ($notationMessages as $message) {
$booking = $bookingRepository->findOneBy(['ref' => $message->getBookingRef()]);
$requestData = [
'id' => $message->getId(),
'type' => 'message',
'fullname' => $booking->getCourse()->getOwner()->getProInfo()->getFullname(),
'photo' => $booking->getCourse()->getOwner()->getPhoto(),
'sendingDate' => $message->getCreatedAt()->format('d/m/Y'),
'courseName' => $booking->getCourse()->getTranslatedContent($locale)->getName(),
'courseToken' => $booking->getCourse()->getToken(),
'link' => $this->generateUrl('rate_course', ['_locale' => $locale, 'booking' => $booking->getRef()])
];
// Appliquer les filtres de recherche
if (($nameSearch === '' || stripos($requestData['fullname'], $nameSearch) !== false) &&
($courseToken === '' || stripos($requestData['courseToken'], $courseToken) !== false)) {
$requests[] = $requestData;
}
}
$noteRequests = $noteRequestRepository->findBy(['email' => $trainee->getEmail(), 'status' => 'pending']);
foreach ($noteRequests as $noteRequest) {
$requestData = [
'id' => $noteRequest->getId(),
'type' => 'request',
'fullname' => $noteRequest->getPro()->getProInfo()->getFullname(),
'photo' => $noteRequest->getPro()->getPhoto(),
'sendingDate' => $noteRequest->getCreatedAt()->format('d/m/Y'),
'courseName' => $noteRequest->getCourse()->getTranslatedContent($locale)->getName(),
'courseToken' => $noteRequest->getCourse()->getToken(),
'link' => $this->generateUrl('rate_course', ['_locale' => $locale, 'noteRequestReference' => $noteRequest->getReference()])
];
// Appliquer les filtres de recherche
if (($nameSearch === '' || stripos($requestData['fullname'], $nameSearch) !== false) &&
($courseToken === '' || stripos($requestData['courseToken'], $courseToken) !== false)) {
$requests[] = $requestData;
}
}
// Trier les résultats par date d'envoi
usort($requests, function ($a, $b) {
return strtotime($a['sendingDate']) <=> strtotime($b['sendingDate']);
});
$requests = $paginator->paginate(
$requests,
$request->query->getInt('page', 1),
15
);
return $this->render('front/trainee/note/pending-reviews.html.twig', [
'menu' => 'note',
'trainee' => $trainee,
'requests' => $requests,
'form' => $form->createView()
]);
}
}