<?php
namespace App\Controller\Front;
use Exception;
use App\Entity\Club;
use App\Entity\User;
use App\Entity\Coach;
use App\Entity\Label;
use App\Entity\Photo;
use App\Entity\Video;
use App\Entity\ProInfo;
use App\Entity\Sponsor;
use App\Entity\Trainee;
use App\Form\LabelType;
use App\Form\PhotoType;
use App\Form\VideoType;
use App\Entity\Operator;
use App\Entity\CourtInfo;
use App\Entity\Formation;
use App\Entity\SearchPro;
use App\Form\ProAreaType;
use App\Form\SponsorType;
use App\Entity\Experience;
use App\Form\ClubInfoType;
use App\Form\ProSportType;
use App\Twig\AppExtension;
use App\Form\FormationType;
use App\Form\SearchProType;
use App\Entity\Availability;
use App\Entity\ProViewsStat;
use App\Form\ExperienceType;
use App\Form\ProProfileType;
use App\Entity\PasswordUpdate;
use App\Entity\ProDescription;
use App\Form\AvailabilityType;
use App\Form\NotificationType;
use App\Service\GoogleService;
use App\Service\ImageOptimizer;
use App\EmailNotification\ToPro;
use App\Form\PasswordUpdateType;
use App\Form\ProDescriptionType;
use App\Form\ProPageProfileType;
use App\Repository\UserRepository;
use App\Repository\SportRepository;
use App\Repository\CourseRepository;
use App\Repository\AddressRepository;
use Symfony\Component\Form\FormError;
use Symfony\Component\Intl\Countries;
use App\Repository\ClubInfoRepository;
use App\Repository\CoachInfoRepository;
use App\Repository\CourtInfoRepository;
use App\Repository\FormationRepository;
use Doctrine\Persistence\ObjectManager;
use App\Repository\ExperienceRepository;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\AvailabilityRepository;
use App\Repository\OperatorInfoRepository;
use App\Repository\ProViewsStatRepository;
use Knp\Component\Pager\PaginatorInterface;
use App\Repository\ProDescriptionRepository;
use App\Repository\WebsiteLanguageRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\String\Slugger\AsciiSlugger;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class ProController extends AbstractController
{
private $apiKey;
private $stripe;
public function __construct(
private TranslatorInterface $translator,
private ImageOptimizer $imageOptimizer,
private WebsiteLanguageRepository $websiteLanguageRepository,
private GoogleService $googleService,
) {
$this->apiKey = $_ENV['STRIPE_SECRET_KEY'];
$this->stripe = $this->stripe = new \Stripe\StripeClient($this->apiKey);
}
private function generateUniqueFileName()
{
return md5(uniqid());
}
#[Route(path: '/{_locale}/directory', name: 'directory')]
public function directory(UserRepository $userRepo, AddressRepository $addressRepository, Request $request, PaginatorInterface $paginator): Response
{
$search = new SearchPro();
$countries = [];
$criteria = null;
foreach ($addressRepository->getExistingCountries() as $country) {
$countries[Countries::getName($country['countryCode'], $request->getSession()->get('_locale'))] = strtolower($country['countryCode']);
}
$form = $this->createForm(SearchProType::class, $search, ['countries' => $countries]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$pros = $paginator->paginate(
$userRepo->searchPro($search),
$request->query->getInt('page', 1),
24
);
$criteria = $search;
} else {
$pros = $paginator->paginate(
$userRepo->findPros(),
$request->query->getInt('page', 1),
24
);
}
return $this->render('front/pro/search-pro.html.twig', [
'menu' => 'directory',
'pros' => $pros,
'form' => $form->createView(),
'criteria' => $criteria
]);
}
#[Route(path: '/{_locale}/{type}s/{slug}', name: 'view_pro')]
public function viewPro($slug, Request $request, UserRepository $userRepo, ClubInfoRepository $clubInfoRepository, CoachInfoRepository $coachInfoRepository, CourseRepository $courseRepository, ProViewsStatRepository $proViewsStatRepository, AppExtension $appExtension, SportRepository $sportRepository, ProDescriptionRepository $proDescriptionRepository)
{
$pro = $userRepo->findOneBy(['slug' => $slug]);
if ($pro == null || $pro->getStatus() != 'online' || ($pro != $this->getUser() && $pro->getProInfo()->getPageVisible() == false)) {
/*$this->addFlash(
'info',
$this->translator->trans("flashes.pro_controller.unknown_profile")
);*/
return $this->redirectToRoute('homepage');
}
$courseList = $courseRepository->findMyCoursesByStatus($pro, 'active');
$courses = null;
foreach ($courseList as $course) {
if ($appExtension->getNextDate($course)->getBegin() != null) {
$courses[] = $course;
}
}
$inactive = false;
if (!$pro->getProInfo()->getHaveSubscription()) {
$inactive = true;
}
$months = ['jan', 'feb', 'mar', 'apr', 'may', 'june', 'july', 'aug', 'sept', 'oct', 'nov', 'dec'];
//View stat
$ip = $_SERVER['REMOTE_ADDR'];
if ($ip) {
$proViewsStat = $proViewsStatRepository->findByIp($ip, $pro);
$manager = $this->getDoctrine()->getManager();
if ($proViewsStat) {
$origin = new \DateTime();
$target = new \DateTime($proViewsStat->getDate());
$interval = $origin->diff($target)->format('%a');
if ($interval > 2) {
$proViewsStat->setViews($proViewsStat->getViews() + 1)
->setDate(date_format(new \DateTime(), 'Y-m-d'));
}
} else {
$proViewsStat = new ProViewsStat();
$proViewsStat->setPro($pro)
->setDate(date_format(new \DateTime(), 'Y-m-d'))
->setIp($ip)
->setViews(1);
$manager->persist($proViewsStat);
}
$manager->flush();
}
$coachPartners = null;
$clubPartners = null;
$clubPartners = $clubInfoRepository->findActiveClubPartners($pro);
$coachPartners = $coachInfoRepository->findActiveCoachPartners($pro);
// Areas
$mainAddress = $pro->getAddress();
$areas = $pro->getAreas()->toArray();
array_unshift($areas, $mainAddress);
$splittedAreas = array();
foreach ($areas as $area) {
$splittedAreas[$area->getCountryCode()][] = $area;
}
$partnershipCourses = $courseRepository->findActiveCoursesByProPartner($pro, 3);
$proDescription = $proDescriptionRepository->findProDescriptionByLocaleOrOriginal($pro, $request->getLocale());
return $this->render('/front/pro/pro-public.html.twig', [
'pro' => $pro,
'proDescription' => $proDescription,
'months' => $months,
'courses' => $courses,
'partnershipCourses' => $partnershipCourses,
'startingDate' => null,
'inactive' => $inactive,
'coachPartners' => $coachPartners->getQuery()->getResult(),
'clubPartners' => $clubPartners->getQuery()->getResult(),
'sports' => $sportRepository->findAll(),
'splittedAreas' => $splittedAreas
]);
}
#[Route(path: '/{_locale}/pro/parameters', name: 'pro_parameters')]
public function proParameters(Request $request, ObjectManager $manager, UserPasswordHasherInterface $passwordHasher, ToPro $toPro, WebsiteLanguageRepository $websiteLanguageRepository)
{
$slugger = new AsciiSlugger();
/**
* @var User $pro
*/
$pro = $this->getUser();
if (!$pro->getHasAccess()) {
$proType = $pro->getProType();
$session = $request->getSession();
$session->set('first-login', true);
return $this->redirectToRoute('membership', [
'type' => $proType,
]);
}
/**
* @var ProInfo $proInfo
*/
$proInfo = $pro->getProInfo();
$oldPhoto = $pro->getPhoto();
$passUpdate = new PasswordUpdate();
$formProfile = $this->createForm(ProProfileType::class, $pro);
$formPassword = $this->createForm(PasswordUpdateType::class, $passUpdate);
$formNotification = $this->createForm(NotificationType::class, $pro);
$formProfile->handleRequest($request);
$formPassword->handleRequest($request);
$formNotification->handleRequest($request);
if ($formProfile->isSubmitted() && $formProfile->isValid()) {
if ($pro instanceof Coach) {
$slug = strtolower($slugger->slug($pro->getFirstname() . ' ' . $pro->getLastname() . ' ' . $pro->getId(), '-'));
} elseif ($pro instanceof Club) {
$slug = strtolower($slugger->slug($pro->getClubInfo()->getName() . ' ' . $pro->getId(), '-'));
} else {
$slug = strtolower($slugger->slug($pro->getOperatorInfo()->getName() . ' ' . $pro->getId(), '-'));
}
$language = $websiteLanguageRepository->findOneBy(["name" => $pro->getLanguage()]);
$pro->setLanguage($language->getSlug());
$pro->setSlug($slug);
$manager->flush();
$this->addFlash('success', $this->translator->trans("flashes.pro_controller.profile_updated"));
$this->redirectToRoute('pro_parameters');
}
if ($formPassword->isSubmitted() && $formPassword->isValid()) {
if (!password_verify($passUpdate->getOldPassword(), $pro->getPassword())) {
$formPassword->get('oldPassword')->addError(new FormError("Ce n'est pas votre de passe actuel !"));
} else {
$newPass = $passUpdate->getNewPassword();
$hash = $passwordHasher->hashPassword($pro, $newPass);
$pro->setPassword($hash);
$manager->persist($pro);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_password')
);
$toPro->confirmUpdatePassword($pro);
return $this->redirectToRoute('pro_parameters');
}
}
if ($formNotification->isSubmitted() && $formNotification->isValid()) {
$manager->persist($pro);
$manager->flush();
if ($pro->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('pro_parameters');
}
$accountLinks = null;
try {
$useStripe = $proInfo->getUseStripe();
$proStripeAccountId = $pro->getStripeInfo()->getAccountId();
$stripeAccount = $this->stripe->accounts->retrieve(
$proStripeAccountId,
[]
);
if ($useStripe === null || $useStripe === false) {
$returnUrl = $this->generateUrl('stripe_connect_return', ['id' => $pro->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
$refreshUrl = $this->generateUrl('pro_parameters', [], UrlGeneratorInterface::ABSOLUTE_URL);
$accountLinks = $this->stripe->accountLinks->create([
'account' => $proStripeAccountId,
'refresh_url' => $refreshUrl,
'return_url' => $returnUrl,
'type' => 'account_onboarding',
]);
}
} catch (\Throwable $th) {
$accountLinks = false;
$stripeAccount = null;
}
return $this->render('front/pro/parameters.html.twig', [
'formProfile' => $formProfile->createView(),
'formPassword' => $formPassword->createView(),
'formNotification' => $formNotification->createView(),
'stripeAccount' => $stripeAccount,
'accountLinks' => $accountLinks,
'useStripe' => $useStripe
]);
}
#[Route(path: '/en/pro-{id}/check-stripe-onboarding', name: 'stripe_connect_return')]
public function stripeConnectReturnUrl(User $pro, Request $request, EntityManagerInterface $manager)
{
$stripeInfo = $pro->getStripeInfo();
$proInfo = $pro->getProInfo();
$proStripeAccountId = $stripeInfo->getAccountId();
$stripeAccount = $this->stripe->accounts->retrieve(
$proStripeAccountId,
[]
);
if ($stripeAccount->details_submitted) {
$proInfo->setUseStripe(true);
$this->addFlash(
'success',
$this->translator->trans("flashes.pro_controller.stripe_connect_success")
);
} else {
$proInfo->setUseStripe(false);
$this->addFlash(
'error',
$this->translator->trans("flashes.pro_controller.stripe_connect_error")
);
}
$manager->persist($proInfo);
$manager->flush();
return $this->redirectToRoute('pro_parameters');
}
/*
#[Route(path: '/{_locale}/pro-descriptions', name: 'pro_description')]
public function createProDescriptions(EntityManagerInterface $entityManager, WebsiteLanguageRepository $websiteLanguageRepository, ProDescriptionRepository $proDescriptionRepository, UserRepository $userRepository, CoachInfoRepository $coachInfoRepository, ClubInfoRepository $clubInfoRepository, OperatorInfoRepository $operatorInfoRepository)
{
// Récupérer tous les utilisateurs avec isPro = true
$proUsers = $userRepository->findBy(['isPro' => true]);
foreach ($proUsers as $user) {
// Vérifier s'il existe déjà une description originale pour ce pro
$existingDescription = $proDescriptionRepository->findOneBy([
'pro' => $user,
'isOriginal' => true
]);
// Si une description originale existe déjà , on continue avec l'utilisateur suivant
if ($existingDescription) {
continue;
}
// Initialiser les valeurs
$description = null;
$language = $user->getLanguage();
if ($user instanceof \App\Entity\Coach) {
$coachInfo = $coachInfoRepository->findOneBy(['owner' => $user]);
if ($coachInfo) {
$description = $coachInfo->getDescription();
}
} elseif ($user instanceof \App\Entity\Club) {
$clubInfo = $clubInfoRepository->findOneBy(['owner' => $user]);
if ($clubInfo) {
$description = $clubInfo->getDescription();
}
} elseif ($user instanceof \App\Entity\Operator) {
$operatorInfo = $operatorInfoRepository->findOneBy(['owner' => $user]);
if ($operatorInfo) {
$description = $operatorInfo->getDescription();
}
}
// Créer l'entité ProDescription même si la description est nulle
$proDescription = new ProDescription();
$proDescription->setPro($user)
->setDescription($description)
->setLanguage($language)
->setIsOriginal(true);
$entityManager->persist($proDescription);
$languages = $this->websiteLanguageRepository->findAll();
foreach($languages as $language) {
$languageSlug = $language->getSlug();
if($language->getSlug() != $proDescription->getLanguage()){
$translatedDescription = $proDescriptionRepository->findOneBy(['pro' => $user, 'language' => $languageSlug]);
if ($translatedDescription == null) {
$translatedDescription = new ProDescription();
}
try {
$descriptionTranslate = $this->googleService->translateWithGoogle($proDescription->getDescription(), $languageSlug);
$translatedDescription->setDescription($descriptionTranslate)
->setPro($user)
->setLanguage($languageSlug)
->setIsOriginal(false);
$entityManager->persist($translatedDescription);
}
catch(Exception $e) {
// Créer une exeption;
}
}
}
}
// Enregistrer toutes les nouvelles ProDescriptions en base de données
$entityManager->flush();
return $this->redirectToRoute('homepage');
}
*/
#[Route(path: '/{_locale}/pro/edit-profile', name: 'pro_page')]
public function proPage(Request $request, ProDescriptionRepository $proDescriptionRepository, CourtInfoRepository $courtInfoRepository, ObjectManager $manager, SportRepository $sportRepo, CourseRepository $courseRepository, UserRepository $userRepo, SportRepository $sportRepository)
{
/**
* @var User $pro
*/
$pro = $this->getUser();
$proType = $pro->getProType();
if (!$pro->getHasAccess()) {
$session = $request->getSession();
$session->set('first-login', true);
return $this->redirectToRoute('membership', [
'type' => $proType,
]);
}
$proInfo = $pro->getProInfo();
// Pro page info
// Sponsor
$sponsor = new Sponsor();
$sponsorForm = $this->createForm(SponsorType::class, $sponsor);
$sponsorForm->handleRequest($request);
if ($sponsorForm->isSubmitted() && $sponsorForm->isValid()) {
$logo = $sponsorForm->get('logo')->getData();
$fileName = $this->generateUniqueFileName() . '.' . $logo->guessExtension();
$newName = $this->imageOptimizer->maxImageResize($logo, $fileName, 'sponsor_directory', 'logo');
$sponsor->setLogo($newName);
$sponsor->setOwner($proInfo);
$manager->persist($sponsor);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_sponsor')
);
return $this->redirectToRoute('pro_page');
}
//Photos
$photoForm = $this->createForm(PhotoType::class, $proInfo);
//Videos
$video = new Video();
$videoForm = $this->createForm(VideoType::class, $video);
$videoForm->handleRequest($request);
if ($videoForm->isSubmitted() && $videoForm->isValid()) {
if ($video->getVideoId() != null) {
$regExps = [
'youtube' => "/^.*(youtu\.?be\.?[a-z]*\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/",
'vimeo' => "/^.*(vimeo.?[a-z]*\/)([^#&?]*).*/",
];
$videoType = null;
$videoId = null;
foreach ($regExps as $type => $regExp) {
preg_match($regExp, $video->getVideoId(), $match);
if ($match) {
$videoType = $type;
$videoId = $match[2];
$video->setVideoId($videoId)
->setType($videoType)
->setPath(null);
break;
}
}
if ($videoType) {
$proInfo->addVideo($video);
} else {
$this->addFlash(
'success',
$this->translator->trans("flashes.pro_course_controller.use_valide_video_link")
);
return $this->redirectToRoute('pro_page');
}
$manager->persist($proInfo);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_video')
);
}
return $this->redirectToRoute('pro_page');
}
//Description
$proDescription = $proDescriptionRepository->findProDescriptionByLocaleOrOriginal($pro, $request->getLocale());
if ($proDescription == null) {
$proDescription = new ProDescription();
$proDescription->setPro($pro)
->setLanguage($request->getLocale())
->setIsOriginal(true);
}
$descriptionForm = $this->createForm(ProDescriptionType::class, $proDescription);
$descriptionForm->handleRequest($request);
if ($descriptionForm->isSubmitted() && $descriptionForm->isValid()) {
$manager->persist($proDescription);
if ($proDescription->getIsOriginal()) {
$languages = $this->websiteLanguageRepository->findAll();
try {
foreach ($languages as $language) {
$languageSlug = $language->getSlug();
if ($language->getSlug() != $proDescription->getLanguage()) {
$translatedDescription = $proDescriptionRepository->findOneBy(['pro' => $pro, 'language' => $languageSlug]);
if ($translatedDescription == null) {
$translatedDescription = new ProDescription();
}
$descriptionTranslate = $this->googleService->translateWithGoogle($proDescription->getDescription(), $languageSlug);
$translatedDescription->setDescription($descriptionTranslate)
->setPro($pro)
->setLanguage($languageSlug)
->setIsOriginal(false);
$manager->persist($translatedDescription);
}
}
} catch (Exception $e) {
// Créer une exeption;
/*
$this->addFlash(
'error',
"Une erreur s'est produite lors de l'enregistrement de votre présentation"
);
return $this->redirectToRoute('pro_page');
*/
}
}
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_description')
);
return $this->redirectToRoute('pro_page');
}
// Coach forms
if ($pro instanceof Coach) {
$coach = $this->getUser();
$coachInfo = $coach->getCoachInfo();
// Coach public info
$infoForm = $this->createForm(ProPageProfileType::class, $coach, ['type' => $proType]);
$infoForm->handleRequest($request);
if ($infoForm->isSubmitted() && $infoForm->isValid()) {
//$this->checkSocialMedia($coach->getProInfo());
$address = $coach->getAddress();
$coachInfo->setName($coach->getFirstname() . ' ' . $coach->getLastname())
->setAddress($address);
$proInfo->setFullname($coachInfo->getName());
$manager->persist($coachInfo);
$manager->persist($proInfo);
$manager->persist($coach);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile')
);
return $this->redirectToRoute('pro_page');
}
//Formation
$formation = new Formation();
$formationForm = $this->createForm(FormationType::class, $formation);
$formationForm->handleRequest($request);
if ($formationForm->isSubmitted() && $formationForm->isValid()) {
$formation->setCoach($coachInfo);
$manager->persist($formation);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_training')
);
return $this->redirectToRoute('pro_page');
}
//Experience
$experience = new Experience();
$experienceForm = $this->createForm(ExperienceType::class, $experience);
$experienceForm->handleRequest($request);
if ($experienceForm->isSubmitted() && $experienceForm->isValid()) {
$experience->setCoach($coachInfo);
$manager->persist($experience);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_experience')
);
return $this->redirectToRoute('pro_page');
}
// Sports
$currentSports = $proInfo->getSports()->toArray();
$sportForm = $this->createForm(ProSportType::class, $proInfo);
$sportForm->handleRequest($request);
if ($sportForm->isSubmitted() && $sportForm->isValid()) {
$selectedSports = $proInfo->getSports()->toArray();
/*
if (empty(array_diff($currentSports, $selectedSports))) {
dump("selectedSports contains all values from currentSports");
} else {
dump("selectedSports does not contain all values from currentSports");
}
dd($selectedSports);
*/
if ($pro->getSubscriptions()->last()->getOffer()->getSportLimit() == "1") {
if (count($proInfo->getSports()) > 1) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_add_sport')
);
return $this->redirectToRoute('pro_page');
}
$courses = $courseRepository->checkCourseBySports($pro, $proInfo->getSports());
if ($courses > 0) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_update_sports')
);
return $this->redirectToRoute('pro_page');
}
} else {
if (!empty(array_diff($currentSports, $selectedSports))) {
//dump("selectedSports does not contain all values from currentSports");
$courses = $courseRepository->checkCourseBySports($pro, array_diff($currentSports, $selectedSports));
if ($courses > 0) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_update_sports')
);
return $this->redirectToRoute('pro_page');
}
} else {
//dump("selectedSports contains all values from currentSports");
}
}
foreach ($selectedSports as $sport) {
$sport->addPro($proInfo);
$manager->persist($sport);
}
$manager->persist($proInfo);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_sports')
);
return $this->redirectToRoute('pro_page');
}
// Coach Areas
$areaForm = $this->createForm(ProAreaType::class, $coach);
$areaForm->handleRequest($request);
if ($areaForm->isSubmitted() && $areaForm->isValid()) {
foreach ($coach->getAreas() as $area) {
$area->setPro($coach);
$manager->persist($area);
}
$manager->persist($coach);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_areas')
);
return $this->redirectToRoute('pro_page');
}
$mainAddress = $coach->getAddress();
$areas = $coach->getAreas()->toArray();
array_unshift($areas, $mainAddress);
$splittedAreas = array();
foreach ($areas as $area) {
$splittedAreas[$area->getCountryCode()][] = $area;
}
$template = "front/pro/coach-page.html.twig";
$parameters = [
'coach' => $coach,
'sponsorForm' => $sponsorForm->createView(),
'photoForm' => $photoForm->createView(),
'videoForm' => $videoForm->createView(),
'descriptionForm' => $descriptionForm->createView(),
'proDescription' => $proDescription,
'formationForm' => $formationForm->createView(),
'experienceForm' => $experienceForm->createView(),
'sportForm' => $sportForm->createView(),
'infoForm' => $infoForm->createView(),
'areaForm' => $areaForm->createView(),
'type' => 'coach',
'sports' => $sportRepo->findAll(),
'splittedAreas' => $splittedAreas
];
}
// Club forms
if ($pro instanceof Club) {
$club = $this->getUser();
$clubInfo = $club->getClubInfo();
$proInfo = $club->getProInfo();
$oldEmail = $club->getEmail();
// Club public info
$infoForm = $this->createForm(ProPageProfileType::class, $club, ['type' => $proType]);
$infoForm->handleRequest($request);
if ($infoForm->isSubmitted() && $infoForm->isValid()) {
$email = $club->getEmail();
$proInfo->setFullname($clubInfo->getName());
$address = $club->getAddress();
$clubInfo->setAddress($address);
if ($oldEmail != $email && $userRepo->findOneBy(['email' => $email])) {
$club->setEmail($oldEmail);
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile_wrong_email')
);
} else {
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile')
);
}
$manager->persist($club);
$manager->persist($clubInfo);
$manager->persist($proInfo);
$manager->flush();
return $this->redirectToRoute('pro_page');
}
//Club info options
$sports = $sportRepo->findAll();
foreach ($sports as $sport) {
if ($courtInfoRepository->findOneBy(['sport' => $sport, 'clubInfo' => $clubInfo]) == null) {
$courtInfo = new CourtInfo;
$courtInfo->setSport($sport)
->setClubInfo($clubInfo)
->setNbOpen(0)
->setNbCovered(0)
->setNbSemiOpen((0));
$clubInfo->addCourtInfo($courtInfo);
}
}
$optionForm = $this->createForm(ClubInfoType::class, $clubInfo);
$optionForm->handleRequest($request);
if ($optionForm->isSubmitted() && $optionForm->isValid()) {
$courtInfos = $clubInfo->getCourtInfos();
foreach ($courtInfos as $courtInfo) {
$manager->persist($courtInfo);
}
$manager->persist($clubInfo);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile')
);
return $this->redirectToRoute('pro_page');
}
//Availabilities
$availability = new Availability();
$availability->setClub($club);
$allSports = $sportRepository->findAll();
$clubSports = $club->getProInfo()->getSports()->toArray();
$clubNotAvailableSports = array_diff($allSports, $clubSports);
//dd($clubNotAvailableSports);
$availabilityForm = $this->createForm(AvailabilityType::class, $availability, ['clubNotAvailableSports' => $clubNotAvailableSports]);
$availabilityForm->handleRequest($request);
if ($availabilityForm->isSubmitted() && $availabilityForm->isValid()) {
$sport = $availability->getSport();
if (!in_array($sport, $clubSports)) {
$sport->addPro($proInfo);
$manager->persist($sport);
$manager->persist($availability);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_availabilities')
);
} else {
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.sport_already_exist')
);
}
return $this->redirectToRoute('pro_page');
}
$months = ['jan', 'feb', 'mar', 'apr', 'may', 'june', 'july', 'aug', 'sept', 'oct', 'nov', 'dec'];
$template = "front/pro/club-page.html.twig";
$parameters = [
'club' => $club,
'sponsorForm' => $sponsorForm->createView(),
'photoForm' => $photoForm->createView(),
'videoForm' => $videoForm->createView(),
'infoForm' => $infoForm->createView(),
'optionForm' => $optionForm->createView(),
'descriptionForm' => $descriptionForm->createView(),
'proDescription' => $proDescription,
'availabilityForm' => $availabilityForm->createView(),
'clubNotAvailableSports' => $clubNotAvailableSports,
'months' => $months,
'type' => 'club',
'sports' => $sports
];
}
// Operator forms
if ($pro instanceof Operator) {
$operator = $this->getUser();
$operatorInfo = $operator->getOperatorInfo();
$proInfo = $operator->getProInfo();
$oldEmail = $operator->getEmail();
// Operator public info
$infoForm = $this->createForm(ProPageProfileType::class, $operator, ['type' => $proType]);
$infoForm->handleRequest($request);
if ($infoForm->isSubmitted() && $infoForm->isValid()) {
$proInfo->setFullname($operatorInfo->getName());
$email = $operator->getEmail();
if ($oldEmail != $email && $userRepo->findOneBy(['email' => $email])) {
$operator->setEmail($oldEmail);
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile_wrong_email')
);
} else {
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_profile')
);
}
$manager->persist($operator);
$manager->persist($operatorInfo);
$manager->persist($proInfo);
$manager->flush();
return $this->redirectToRoute('pro_page');
}
//Sport
$currentSports = $proInfo->getSports()->toArray();
$sportForm = $this->createForm(ProSportType::class, $proInfo);
$sportForm->handleRequest($request);
if ($sportForm->isSubmitted() && $sportForm->isValid()) {
$selectedSports = $proInfo->getSports()->toArray();
if ($pro->getSubscriptions()->last()->getOffer()->getSportLimit() == "1") {
if (count($proInfo->getSports()) > 1) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_add_sport')
);
return $this->redirectToRoute('pro_page');
}
$courses = $courseRepository->checkCourseBySports($pro, $proInfo->getSports());
if ($courses > 0) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_update_sports')
);
return $this->redirectToRoute('pro_page');
}
} else {
if (!empty(array_diff($currentSports, $selectedSports))) {
//dump("selectedSports does not contain all values from currentSports");
$courses = $courseRepository->checkCourseBySports($pro, array_diff($currentSports, $selectedSports));
if ($courses > 0) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_update_sports')
);
return $this->redirectToRoute('pro_page');
}
}
}
foreach ($selectedSports as $sport) {
$sport->addPro($proInfo);
$manager->persist($sport);
}
$manager->persist($proInfo);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_sports')
);
return $this->redirectToRoute('pro_page');
}
// Label
$label = new Label();
$labelForm = $this->createForm(LabelType::class, $label);
$labelForm->handleRequest($request);
if ($labelForm->isSubmitted() && $labelForm->isValid()) {
$logo = $labelForm->get('logo')->getData();
$fileName = $this->generateUniqueFileName() . '.' . $logo->guessExtension();
$newName = $this->imageOptimizer->maxImageResize($logo, $fileName, 'label_directory', 'logo');
$label->setLogo($newName);
$label->setOwner($operator->getProInfo());
$manager->persist($label);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_label')
);
return $this->redirectToRoute('pro_page');
}
// Operator Areas
$areaForm = $this->createForm(ProAreaType::class, $operator);
$areaForm->handleRequest($request);
if ($areaForm->isSubmitted() && $areaForm->isValid()) {
foreach ($operator->getAreas() as $area) {
$area->setPro($operator);
$manager->persist($area);
}
$manager->persist($operator);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_areas')
);
return $this->redirectToRoute('pro_page');
}
$mainAddress = $operator->getAddress();
$areas = $operator->getAreas()->toArray();
array_unshift($areas, $mainAddress);
$splittedAreas = array();
foreach ($areas as $area) {
$splittedAreas[$area->getCountryCode()][] = $area;
}
$template = "front/pro/operator-page.html.twig";
$parameters = [
'operator' => $operator,
'sponsorForm' => $sponsorForm->createView(),
'photoForm' => $photoForm->createView(),
'videoForm' => $videoForm->createView(),
'infoForm' => $infoForm->createView(),
'labelForm' => $labelForm->createView(),
'descriptionForm' => $descriptionForm->createView(),
'proDescription' => $proDescription,
'sportForm' => $sportForm->createView(),
'type' => 'operator',
'sports' => $sportRepo->findAll(),
'areaForm' => $areaForm->createView(),
'splittedAreas' => $splittedAreas
];
}
$parameters['menu'] = 'pro-page';
return $this->render($template, $parameters);
}
#[Route(path: '/{_locale}/hide-me', name: 'pro_hide_me')]
public function hideMe(ObjectManager $manager, Request $request)
{
$pro = $this->getUser();
$proInfo = $pro->getProInfo();
$proInfo->setIsHidden(!$proInfo->getIsHidden());
$manager->persist($proInfo);
$manager->flush();
if ($proInfo->getIsHidden()) {
$this->addFlash('success', $this->translator->trans("flashes.pro_controller.be_invisible"));
} else {
$this->addFlash('success', $this->translator->trans("flashes.pro_controller.be_visible"));
}
return $this->redirectToRoute('pro_page');
}
#[Route(path: '/{_locale}/edit-formation-experience', name: 'edit_formation_experience')]
public function editFormationExperience(ObjectManager $manager, Request $request, FormationRepository $formationRepository, ExperienceRepository $experienceRepository)
{
$id = $_POST['id'];
$action = $request->request->get('action');
if ($action == 'deleteFormation') {
$formation = $formationRepository->findOneBy(['id' => $id]);
$manager->remove($formation);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.delete_training')
);
return $this->redirectToRoute('pro_page');
} else if ($action == 'deleteExperience') {
$experience = $experienceRepository->findOneBy(['id' => $id]);
$manager->remove($experience);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.delete_experience')
);
return $this->redirectToRoute('pro_page');
}
if (isset($_POST['edit-formation'])) {
$organisation = $_POST['organisation'];
$diploma = $_POST['diploma'];
$begin = $_POST['begin'];
$end = $_POST['end'];
$formation = $formationRepository->findOneBy(['id' => $id]);
$formation->setOrganisation($organisation)
->setDiploma($diploma)
->setBegin($begin)
->setEnd($end);
$manager->persist($formation);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_training')
);
return $this->redirectToRoute('pro_page');
} else if (isset($_POST['edit-experience'])) {
$id = $_POST['id'];
$jobTitle = $_POST['job-title'];
$sector = $_POST['sector'];
$address = $_POST['address'];
$description = $_POST['description'];
$begin = $_POST['begin'];
$end = $_POST['end'];
$company = $_POST['company'];
$experience = $experienceRepository->findOneBy(['id' => $id]);
$experience->setJobTitle($jobTitle)
->setSector($sector)
->setAddress($address)
->setDescription($description)
->setBegin($begin)
->setEnd($end)
->setCompany($company);
$manager->persist($experience);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_experience')
);
return $this->redirectToRoute('pro_page');
}
}
#[Route(path: '/{_locale}/edit-availability', name: 'edit_availability')]
public function editAvailability(ObjectManager $manager, AvailabilityRepository $availabilityRepository)
{
$id = $_POST['id'];
$availability = $availabilityRepository->findOneBy(['id' => $id]);
$availabilities = [];
if (!empty($_POST['available'])) {
foreach ($_POST['available'] as $a) {
$availabilities[] = $a;
}
}
$availability->setAvailabilities($availabilities);
$manager->persist($availability);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.update_availability')
);
return $this->redirectToRoute('pro_page');
}
#[Route(path: '/{_locale}/delete-availability', name: 'delete_availability', requirements: ['id' => '\d+'])]
public function deleteAvailability(Request $request, ObjectManager $manager, AvailabilityRepository $availabilityRepository, CourseRepository $courseRepository)
{
$club = $this->getUser();
$availability = $availabilityRepository->find($request->request->get('availabilityId'));
if ($availability) {
$sport = $availability->getSport();
$proInfo = $club->getProInfo();
$courses = $courseRepository->checkCourseBySports($club, $sport);
if ($courses > 0) {
$this->addFlash(
'error',
$this->translator->trans('flashes.pro_controller.cant_delete_sport_availablity')
);
} else {
$proInfo->removeSport($sport);
$manager->persist($proInfo);
$manager->remove($availability);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.delete_availability')
);
}
}
return $this->redirectToRoute('pro_page');
}
#[Route(path: '/pro/upload-gallery', name: 'pro_upload_gallery')]
public function proUploadGallery(EntityManagerInterface $manager, ImageOptimizer $imageOptimizer)
{
$pro = $this->getUser();
$proInfo = $pro->getProInfo();
$files = $_FILES;
foreach (array_reverse($files) as $fileSended) {
$file = null;
$file = new UploadedFile($fileSended['tmp_name'], $fileSended['name']);
/*
$path = $fileSended['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
$directory = $this->getParameter('gallery_directory');
*/
$ext = $file->guessExtension();
$fileName = $this->generateUniqueFileName() . '.' . $ext;
//$isFileUploaded = move_uploaded_file($file["tmp_name"], "$directory/" . $fileName);
$newName = $imageOptimizer->maxImageResize($file, $fileName, 'gallery_directory', 'gallery');
$photo = new Photo();
$photo->setName($newName);
$proInfo->addPhoto($photo);
$manager->persist($photo);
$manager->persist($proInfo);
}
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans('flashes.pro_controller.add_pictures')
);
return new JsonResponse(['total' => count($files)]);
}
#[Route(path: '/pro/delete-video/{id}', name: 'delete_video', requirements: ['id' => '\d+'], methods: ['DELETE'])]
public function deleteVideo(ObjectManager $manager, Video $video, Request $request)
{
$data = json_decode($request->getContent(), true);
if ($this->isCsrfTokenValid('delete' . $video->getId(), $data['_token'])) {
if ($video->getType() == 'local') {
if (file_exists($this->getParameter('video_directory') . '/' . $video->getPath())) {
unlink($this->getParameter('video_directory') . '/' . $video->getPath());
}
}
$manager->remove($video);
$manager->flush();
return new JsonResponse(['success' => 1]);
} else {
return new JsonResponse(['error' => 'Token invalide'], 400);
}
}
#[Route(path: '/pro/delete-photo/{id}', name: 'delete_photo', requirements: ['id' => '\d+'], methods: ['DELETE'])]
public function deletePhoto(ObjectManager $manager, Photo $photo, Request $request)
{
$data = json_decode($request->getContent(), true);
if ($this->isCsrfTokenValid('delete' . $photo->getId(), $data['_token'])) {
if (file_exists($this->getParameter('gallery_directory') . '/' . $photo->getName())) {
unlink($this->getParameter('gallery_directory') . '/' . $photo->getName());
}
$manager->remove($photo);
$manager->flush();
return new JsonResponse(['success' => 1]);
} else {
return new JsonResponse(['error' => 'Token invalide'], 400);
}
}
#[Route(path: '/pro/delete-sponsor/{id}', name: 'delete_sponsor', requirements: ['id' => '\d+'], methods: ['DELETE'])]
public function deleteSponsor(ObjectManager $manager, Sponsor $sponsor, Request $request)
{
$data = json_decode($request->getContent(), true);
if ($this->isCsrfTokenValid('delete' . $sponsor->getId(), $data['_token'])) {
if (file_exists($this->getParameter('sponsor_directory') . '/' . $sponsor->getLogo())) {
unlink($this->getParameter('sponsor_directory') . '/' . $sponsor->getLogo());
}
$manager->remove($sponsor);
$manager->flush();
return new JsonResponse(['success' => 1]);
} else {
return new JsonResponse(['error' => 'Token invalide'], 400);
}
}
#[Route(path: '/pro/delete-label/{id}', name: 'delete_label', requirements: ['id' => '\d+'], methods: ['DELETE'])]
public function deleteLabel(ObjectManager $manager, Label $label, Request $request)
{
$data = json_decode($request->getContent(), true);
if ($this->isCsrfTokenValid('delete' . $label->getId(), $data['_token'])) {
if (file_exists($this->getParameter('label_directory') . '/' . $label->getLogo())) {
unlink($this->getParameter('label_directory') . '/' . $label->getLogo());
}
$manager->remove($label);
$manager->flush();
return new JsonResponse(['success' => 1]);
} else {
return new JsonResponse(['error' => 'Token invalide'], 400);
}
}
#[Route(path: '/{_locale}/pro/iframe', name: 'pro_iframe')]
public function proIframe()
{
$user = $this->getUser();
if ($user->getIsPro()) {
if ($user instanceof Coach) {
$type = 'coach';
} else if ($user instanceof Club) {
$type = 'club';
} else if ($user instanceof Operator) {
$type = 'operator';
}
$courses = $user->getCourses();
$response = $this->render('front/pro/iframe.html.twig', [
'slug' => $user->getSlug(),
'type' => $type,
'courses' => $courses,
]);
return $response;
}
}
#[Route(path: '/add-pro-to-favorite/{id}', name: 'add_pro_favorite', methods: ['POST'])]
public function addToFavorite(User $pro, ObjectManager $manager, Request $request)
{
$user = $this->getUser();
$data = json_decode($request->getContent(), true);
if ($this->isCsrfTokenValid('favorite' . $pro->getId(), $data['_token'])) {
if ($user instanceof Trainee) {
if ($pro->getTraineesFavorites()->contains($user)) {
$user->removeProFavorite($pro);
} else {
$user->addProFavorite($pro);
}
$manager->flush();
}
return new JsonResponse(['success' => 1]);
} else {
return new JsonResponse(['error' => 'token invalid'], 400);
}
}
#[Route(path: '/pro/publish-my-page', name: 'publish_my_page')]
public function publishMyPage(ObjectManager $manager)
{
$pro = $this->getUser();
if ($pro->getIsPro()) {
# code...
if ($pro instanceof Coach) {
$type = 'coach';
} elseif ($pro instanceof Club) {
$type = 'club';
} else {
$type = 'operator';
}
$pro->getProInfo()->setPageVisible(true);
$manager->flush();
$this->addFlash(
'success',
$this->translator->trans("flashes.pro_controller.page_published")
);
return $this->redirectToRoute('view_pro', [
'type' => $type,
'slug' => $pro->getSlug()
]);
}
return $this->redirectToRoute('homepage');
}
function compareSports($oldSports, $newSports)
{
$sportDiff = [];
foreach ($oldSports as $oldSport) {
if (!in_array($oldSport, $newSports)) {
$sportDiff[] = $oldSport;
}
}
return $sportDiff;
}
private function checkUrl($url): bool
{
if (substr($url, 0, 5) == "https") {
return false;
}
return true;
}
}