<?php
namespace App\Controller;
use App\Config;
use App\Entity\Candidature;
use App\Entity\CompteRecrutement;
use App\Entity\Enum\FrenchRegion;
use App\Entity\Enum\IconEnum;
use App\Entity\Enum\UAERegion;
use App\Entity\Enum\UAERegionNew;
use App\Entity\Experience;
use App\Entity\Notification;
use App\Entity\Offer;
use App\Entity\OfferVisit;
use App\Entity\Profile;
use App\Entity\ProfileVisit;
use App\Entity\Report;
use App\Entity\Society;
use App\Entity\TempMail;
use App\Entity\User;
use App\Form\FreelanceRegisterFormType;
use App\Form\RegistrationFormType;
use App\Form\ReportFormType;
use App\Form\ResetPasswordRequestFormType;
use App\Repository\CandidatureRepository;
use App\Repository\ForumPostRepository;
use App\Repository\NotificationRepository;
use App\Repository\OfferFavoriteRepository;
use App\Repository\OfferRepository;
use App\Repository\ProfileRepository;
use App\Repository\ProfileVisitRepository;
use App\Repository\PublicationRepository;
use App\Repository\NewsRepository;
use App\Repository\SocietyRepository;
use App\Service\Forum\ForumUserService;
use App\Service\LocationService;
use App\Service\OfferService;
use App\Service\TempMailService;
use App\UseCase\Commande\CreateCommande;
use DateTime;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Annotation\Route;
class WebController extends AbstractController
{
private function getYoutubeVideoId(string $url): string
{
$regex = '~^(?:https?://)?(?:www\\.)?(?:youtube\\.com/watch\\?v=|youtu\\.be/)([\\w-]{11})$~i';
preg_match($regex, $url, $matches);
return $matches[1];
}
/**
* @Route("/", name="homepage")
*/
public function index(
OfferRepository $offerRepository,
ProfileRepository $profileRepository,
NewsRepository $newsRepository,
LocationService $locationService,
ForumUserService $forumUserService,
ForumPostRepository $forumPostRepository
): Response
{
$offers = $offerRepository->getLatest();
$profiles = $profileRepository->getLatest(3);
$news = $newsRepository->getLatest();
$form = $this->createForm(RegistrationFormType::class, new User());
$resetForm = $this->createForm(ResetPasswordRequestFormType::class);
$userJobseeker = new User();
$userJobseeker->setCreatedAt(new DateTime());
$userJobseeker->setRoles(['ROLE_FREELANCE']);
$userJobseeker->setType('freelance');
$userJobseeker->setPhone('');
$formJobseeker = $this->createForm(FreelanceRegisterFormType::class, $userJobseeker, [
'forumPseudo' => $forumUserService->getNextForumUserID()
]);
return $this->render('page/home.html.twig', [
'offers' => $offers,
'profiles' => $profiles,
'regions' => $locationService->getSelectableArray(),
'registrationForm' => $form->createView(),
'resetForm' => $resetForm->createView(),
'formJobseeker' => $formJobseeker->createView(),
'formJobseeker2' => $formJobseeker->createView(),
'faqs' => Config::FAQ,
'cityList' => Config::FEATURED_CITY,
'news' => $news,
'isComing' => (bool)$this->getParameter('is_coming'),
'isNotShow' => (bool)$this->getParameter('is_not_show'),
'regionjson' => json_encode($locationService->getSelectableArray(), JSON_UNESCAPED_UNICODE),
'_recentPosts' => $forumPostRepository->recentPostLimit(4),
]);
}
/**
* @Route("/companies/{slug}", name="society_profil", methods={"GET"})
* @IsGranted("ROLE_USER")
*/
public function society(
Society $society,
Request $request,
OfferRepository $offerRepository,
PaginatorInterface $paginator,
OfferService $offerService
): Response
{
/* @var User $user */
$user = $this->getUser();
$offers = $offerRepository->findBy(['society' => $society], ['id' => 'desc']);
$offers = $offerService->filterOfferByExpire($offers);
$viewData = [
'society' => $society,
'offers' => $paginator->paginate($offers, $request->query->getInt('page', 1), 10),
'isOwner' => $user->isSociety() && ($society->getId() === $user->getSociety()->getId()),
'reportedId' => $society->getId(),
'reportedTarget' => 'society',
];
$viewData['reportForm'] = $this->createForm(ReportFormType::class, new Report())->createView();
$viewData['idYoutubePresentation'] = null;
if ($society->getPresentationYoutube()) {
$viewData['idYoutubePresentation'] = $this->getYoutubeVideoId($society->getPresentationYoutube());
}
if (!$this->getUser()) {
$viewData['registrationForm'] = $this->createForm(RegistrationFormType::class, new User())->createView();
}
return $this->render('page/society.html.twig', $viewData);
}
/**
* @Route("/job/offer/{slug}", name="public_mission", methods={"GET","POST"})
* @param Offer $offer
* @param OfferRepository $offerRepository
* @param Request $request
* @param EntityManagerInterface $entityManager
* @param CandidatureRepository $candidatureRepository
* @param ProfileRepository $profileRepository
* @param OfferFavoriteRepository $offerFavoriteRepository
* @param MailerInterface $mailer
* @param TempMailService $tempMailService
* @param OfferService $offerService
* @param NotificationRepository $notificationRepository
* @return Response
* @throws TransportExceptionInterface
*/
public function offer(
Offer $offer,
OfferRepository $offerRepository,
Request $request,
EntityManagerInterface $entityManager,
CandidatureRepository $candidatureRepository,
ProfileRepository $profileRepository,
OfferFavoriteRepository $offerFavoriteRepository,
MailerInterface $mailer,
TempMailService $tempMailService,
OfferService $offerService,
NotificationRepository $notificationRepository
): Response
{
/* @var User $user */
$user = $this->getUser();
$candidatures = [];
$currentDate = new DateTime();
$isOwner = false;
if ($user) {
$currentOwnerID = null;
if ($offer->getSociety()) {
$currentOwnerID = $offer->getSociety()->getId();
}
$isOwner = $user->isSociety() && ($user->getSociety()->getId() == $currentOwnerID);
$offerVisit = new OfferVisit();
if (!$isOwner) {
$offerVisit
->setUser($user)
->setOffer($offer)
->setCreatedAt(new DateTime());
$entityManager->persist($offerVisit);
$entityManager->flush();
}
// REDIRECT IF PROFIL NOT COMPLETE
if ($user->isFreelance()) {
$currentProfil = $user->getUniqueProfile();
if (!$currentProfil->getNationalityMultiple()) {
return $this->redirectToRoute('complete_resume_profile');
}
}
}
$alreadyPostulate = null;
if (!$isOwner) {
$offer->incrementView();
$entityManager->flush();
}
$similarOffers = $offerRepository->findSimilar($offer->getId(), 2);
$similarOffers = $offerService->filterOfferByExpire($similarOffers);
$candidature = new Candidature();
$candidature->setOffer($offer);
$candidature->setPostulateAt(new DateTimeImmutable());
$alreadyPostulate = false;
if ($user) {
if ($user->isFreelance()) {
$candidature->setProfile($user->getUniqueProfile());
$alreadyPostulate = $candidatureRepository->findOneBy([
'profile' => $user->getUniqueProfile(), 'offer' => $offer
]);
} else {
$profiles = $user->getProfiles();
$allCandidatures = $candidatureRepository->findByOfferAndSociety($offer, $profiles);
foreach ($allCandidatures as $c) {
$candidatures[] = $c->getProfile()->getId();
}
}
}
if ($request->isMethod('POST')) {
if ($user->isSociety()) {
$interContrat = $profileRepository->find($request->get('intercontrat'));
$candidature->setProfile($interContrat);
}
$offer->incrementUnseenCandidature();
$candidature->setAnswers($request->get('answers'));
$entityManager->persist($candidature);
$entityManager->flush();
// ------- ADD NOTIFICATION --------
$notificationAlert = $notificationRepository->findOneBy([
'seen' => false,
'type' => Notification::TYPE_MISSION_APPLY,
'user' => $offer->getSociety()->getUser(),
'rubriqueID' => $offer->getId()
]);
if (!$notificationAlert) {
$notificationAlert = new Notification();
$notificationAlert->setUser($offer->getSociety()->getUser());
$notificationAlert->setIcon(IconEnum::APPLY);
$notificationAlert->setType(Notification::TYPE_MISSION_APPLY);
$notificationAlert->setRubriqueID($offer->getId());
$notificationAlert->setContent('
<strong>' . $candidature->getProfile()->getFullName() . '</strong>
applied for a job <strong>' . $offer->getTitle() . '</strong>
');
} else {
$notificationAlert->setContent('
People applied for a job <strong>' . $offer->getTitle() . '</strong>
');
$notificationAlert->setUpdatedAt(new \DateTime());
}
$entityManager->persist($notificationAlert);
$entityManager->flush();
// ---- SEND MAIL SERVICE ----
// MAIL TO RECRUTEUR
$emailTo = $offer->getSociety()->getUser()->getEmail();
if ($offer->getUserRecruteur()) {
$emailTo = $offer->getUserRecruteur()->getEmail();
}
$tempMail = new TempMail();
$tempMail->setAdress($emailTo);
$tempMail->setType_OfferCandidature();
$tempMail->setOffer($offer);
$tempMail->setCandidature($candidature);
$tempMailService->sendingMail($tempMail);
// NOTIFICATION
return $this->redirectToRoute('public_mission', ['slug' => $offer->getSlug()]);
}
$offerFavorite = [];
if ($user) {
$offerFavorite = $offerFavoriteRepository->findOneBy(['user' => $user, 'offer' => $offer]);
}
/** @var DateTime $createdDate */
$createdDate = $offer->getCreatedAt();
$endDate = clone $createdDate;
$endDate->add(new \DateInterval('P6M'));
if ($offer->getExpireAt()) {
$endDate = $offer->getExpireAt();
}
return $this->render('page/offer.html.twig', [
'offer' => $offer,
'similarOffers' => $similarOffers,
'isOwner' => $isOwner,
'alreadyPostulate' => $alreadyPostulate,
'isInFavorite' => !empty($offerFavorite),
'candidatures' => $candidatures,
'offerEndDate' => $endDate,
'currentDate' => $currentDate,
]);
}
/**
* @Route("/offer/apply/{id}", name="public_redirect_offer_apply", methods={"GET"})
*
*/
public function redirectOfferApply(
Offer $offer
): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
if (!$currentUser) {
return $this->redirectToRoute('register_freelance');
}
return $this->redirectToRoute("public_mission", ['slug' => $offer->getSlug()]);
}
/**
* @Route("/profile/{slug}", name="public_profile", methods={"GET"})
* @IsGranted("ROLE_USER")
* @throws NonUniqueResultException
*/
public function profile(
Profile $profile,
EntityManagerInterface $entityManager,
ProfileRepository $profileRepository,
ProfileVisitRepository $profileVisitRepository,
CandidatureRepository $candidatureRepository
): Response
{
/* @var User $user */
$user = $this->getUser();
$isOwner = $profile->getUser()->getId() === $user->getId();
if ($user->getCompteSociety()) {
if ($user->getSociety()->getUser()->getId() === $profile->getUser()->getId()) {
$isOwner = true;
}
}
if (!$profile) {
throw new NotFoundHttpException();
}
if ($user->isFreelance() && $profile->getId() !== $user->getUniqueProfile()->getId()) {
return $this->redirectToRoute('dashboard');
}
if ($user->isSociety()) {
$society = $user->getSociety();
$candidatures = $candidatureRepository->findBySocietyAndProfile($society, $profile);
$ProfilesVisits = $profileVisitRepository->findBySociety($society);
$profileIds = [];
foreach ($ProfilesVisits as $visit) {
$profileIds[] = $visit['id'];
}
// if (!in_array($profile->getId(), $profileIds)) {
// if (!$candidatures && !$society->canViewProfile()) {
// $this->addFlash('package_error', "Acheter un package pour voir le profil");
//
// return $this->redirectToRoute('dashboard');
// }
// }
if ($profile->getUser()->isFreelance() ||
($profile->getUser()->isSociety() && $society->getId() != $profile->getUser()->getSociety()->getId())
) {
$profileVisit = new ProfileVisit();
$profileVisit->setSociety($society);
$profileVisit->setProfile($profile);
$profileVisit->setViewAt(new DateTimeImmutable());
$entityManager->persist($profileVisit);
if (!$candidatures) {
$society->decreaseProfileView();
}
$entityManager->flush();
}
}
return $this->render('page/profile.html.twig', [
'profile' => $profile,
'reportForm' => $this->createForm(ReportFormType::class, new Report())->createView(),
'reportedId' => $profile->getId(),
'reportedTarget' => 'profile',
'isOwner' => $isOwner,
// 'experience' => new Experience()
]);
}
/**
* @Route("/account-non-verified", name="email_unverified", methods={"GET"})
*/
public function userUnverified(): Response
{
$hasVerifiedUser = false;
if ($this->getUser()) {
$hasVerifiedUser = $this->getUser()->isVerified();
}
if ($hasVerifiedUser) {
return $this->redirectToRoute('dashboard');
} else {
return $this->render('page/email_must_verified.html.twig');
}
}
/**
* @Route("/pourquoi-s-inscrire", name="why_subscribe", methods={"GET"})
*/
public function whySubscribe(): Response
{
return $this->render('page/why-subscribe.html.twig');
}
/**
* @Route("/{slug}", name="public_page", methods={"GET"})
*/
public function page(string $slug, PublicationRepository $publicationRepository): Response
{
if ($slug == 'societe') {
return $this->render('page/error.html.twig');
}
$publication = $publicationRepository->findOneBy(['slug' => $slug]);
if (null === $publication) {
throw $this->createNotFoundException();
}
return $this->render('page/page.html.twig', [
'publication' => $publication,
]);
}
/**
* @Route("/package/checkout", name="payment_validation", methods={"GET"})
*/
public function paymentValidation(
Request $request,
CreateCommande $createCommande,
EntityManagerInterface $entityManager
): Response
{
if ($request->query->get('stripe') == 'success') {
$user = $this->getUser();
$society = $user->getSociety();
$commande = $createCommande->execute($request->query->get('package'), $society);
/* Set compte recrutement */
$nbMois = $request->query->get("nbMois");
if ($nbMois) {
$nbMois = intval($nbMois);
if ($nbMois > 0) {
$commande->setNbMoisRecruit($nbMois);
$entityManager->persist($commande);
for ($i = 1; $i <= $nbMois; $i++) {
$compteRecrutement = new CompteRecrutement();
$compteRecrutement->setSociete($society);
$compteRecrutement->setNbMois($nbMois);
$compteRecrutement->setCommande($commande);
$compteRecrutement->setIsJeton(true);
$entityManager->persist($compteRecrutement);
$entityManager->flush();
}
}
}
return $this->redirectToRoute('commande_list');
} else {
$this->addFlash('error', 'Une erreur s\'est produite lors de votre paiement.');
return $this->redirectToRoute('checkout_package', ['name' => $request->query->get('package')]);
}
}
/**
* @Route("/mail/send/reactivation", name="mail_s_sendReactivation")
*
*
* ENVOYE DE MAIL DE REACTIVATION
*/
public function sendReactivation(
EntityManagerInterface $entityManager,
SocietyRepository $societyRepository,
MailerInterface $mailer,
TempMailService $tempMailService
): Response
{
$societies = $societyRepository->findExpiredPauseDate();
$i = 0;
foreach ($societies as $society) {
$society->setPauseDate(null);
$entityManager->persist($society);
$i++;
$entityManager->flush();
// SEND MAIL
$tempMail = new TempMail();
$tempMail->setType_SocietyReactivation();
$tempMail->setAdress($society->getUser()->getEmail());
$tempMail->setSociety($society);
$tempMailService->sendingMail($tempMail);
}
return new Response($i . ' sociétés réactivées');
}
/**
* @Route("/123456/update/nationality", name="profile_update_nationality", methods={"GET"})
*
*/
public function profileNationality(
EntityManagerInterface $entityManager
): Response
{
/** @var Profile[] $profiles */
$profiles = $entityManager->getRepository(Profile::class)->findAll();
foreach ($profiles as $profile) {
if ($profile->getNationality() and !$profile->getNationalityMultiple()) {
$nationalities = [];
$nationalities[] = $profile->getNationality();
$profile->setNationalityMultiple($nationalities);
$entityManager->persist($profile);
}
}
$entityManager->flush();
return new Response('profile nationality update');
}
}