<?php
/*
*
* (c) Loïc Haas <loic.haas@outlook.com>
* http://www.haas-info.com/
*
*/
namespace App\Framework\FrontBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use App\Framework\AppBundle\Entity\User;
use App\Security\LoginFormAuthenticator;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class SecurityController extends AbstractController
{
use TargetPathTrait;
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
/**
* @Route("/login", name="security_login")
* @Route("/{locale}/security_login", name="security_login_locale", requirements={"locale" = "([a-z\-0-9]+)"})
*/
public function login(Request $request, Security $security, AuthenticationUtils $helper, $locale = NULL): Response
{
if($locale){
$request->setLocale($locale);
}
// if user is already logged in, don't display the login page again
if ($security->isGranted('ROLE_MANAGER')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
} elseif ($security->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
} elseif ($security->isGranted('ROLE_USER')) {
return $this->redirectToRoute('framework_front_account_histo', ['locale' => $request->getLocale()]);
}
// this statement solves an edge-case: if you change the locale in the login
// page, after a successful login you are redirected to a page in the previous
// locale. This code regenerates the referrer URL whenever the login page is
// browsed, to ensure that its locale is always the current one.
// $this->saveTargetPath($request->getSession(), 'main', $this->generateUrl('admin_index'));
$metaDesc = 'Bienvenue dans votre espace';
$metaTitle = 'Se connecter';
if($locale == 'de'){
$metaDesc = 'Willkommen in Ihrem Mitgliederbereich';
$metaTitle = 'Sich anmelden';
}
if($locale == 'en'){
$metaDesc = 'Welcome to your member area';
$metaTitle = 'Login';
}
return $this->render('AdminBundle/Security/login.html.twig', [
// last username entered by the user (if any)
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
'metaTitle' => $metaTitle,
'metaDesc' => $metaDesc,
]);
}
/**
* @Route("/backoffrp/login", name="security_login_admin")
*/
public function loginAdmin(Request $request, Security $security, AuthenticationUtils $helper): Response
{
// if user is already logged in, don't display the login page again
if ($security->isGranted('ROLE_MANAGER')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
} elseif ($security->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
}
// this statement solves an edge-case: if you change the locale in the login
// page, after a successful login you are redirected to a page in the previous
// locale. This code regenerates the referrer URL whenever the login page is
// browsed, to ensure that its locale is always the current one.
// $this->saveTargetPath($request->getSession(), 'main', $this->generateUrl('admin_index'));
return $this->render('AdminBundle/Security/login_admin.html.twig', [
// last username entered by the user (if any)
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
]);
}
/**
* This is the route the user can use to logout.
*
* But, this will never be executed. Symfony will intercept this first
* and handle the logout automatically. See logout in config/packages/security.yaml
*
* @Route("/logout", name="security_logout")
*/
public function logout(): void
{
throw new \Exception('This should never be reached!');
}
/**
* This is the route the user can use to logout.
*
* But, this will never be executed. Symfony will intercept this first
* and handle the logout automatically. See logout in config/packages/security.yaml
*
* @Route("/backoffrp/logout", name="security_logout_admin")
*/
public function logoutAdmin(): void
{
throw new \Exception('This should never be reached!');
}
/**
* @Route("/dispatch", name="security_dispatch")
*/
public function dispatch(Request $request, Security $security, AuthenticationUtils $helper): Response
{
if ($security->isGranted('ROLE_MANAGER')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
} elseif ($security->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('framework_admin_dashboard_index');
} else {
return $this->redirectToRoute('framework_front_account_histo', ['locale' => $request->getLocale()]);
}
}
/**
* @Route("/dispatchadmin", name="security_dispatch_admin")
*/
public function dispatchadmin(Request $request, Security $security, AuthenticationUtils $helper): Response
{
// if ($security->isGranted('ROLE_MANAGER')) {
// return $this->redirectToRoute('framework_admin_dashboard_index');
// } elseif ($security->isGranted('ROLE_ADMIN')) {
// return $this->redirectToRoute('framework_admin_dashboard_index');
// } else {
// return $this->redirectToRoute('framework_front_account_histo', ['locale' => $request->getLocale()]);
// }
// exit;
return $this->redirectToRoute('framework_admin_dashboard_index');
}
/**
* @Route("/mon-compte/infos", name="security_infos")
* @Route("/mon-compte/infos/{locale}", name="security_infos_locale", requirements={"locale" = "([a-z\-0-9]+)"})
*/
public function infosAction(Request $request, Security $security, UserPasswordEncoderInterface $passwordEncoder, $locale = NULL)
{
if($locale){
$request->setLocale($locale);
}
$tr = $this->loadTranslation($locale);
require_once dirname(__FILE__).'/../../plugins/stripe-php-10.12.1/init.php';
$em = $this->getDoctrine()->getManager();
$locale = $request->getLocale();
$globals = $this->get("twig")->getGlobals();
$isAjax = $request->isXMLHttpRequest();
if ($isAjax) {
$error = $error_name = "";
$success = true;
if (!$security->isGranted('ROLE_USER')) {
$error = $tr['signup_error5'];
$success = false;
}
$user = $this->getUser();
$infos = $user->getInfos();
if($infos == null){
$infos = json_decode('{}');
}
if(
$request->get('firstname') == '' ||
$request->get('lastname') == '' ||
$request->get('address1') == '' ||
$request->get('zipcode') == '' ||
$request->get('city') == '' ||
$request->get('country_code') == '' ||
$request->get('country') == '' ||
$request->get('phone') == ''
){
$error = $tr['contact_error2'];
$success = false;
$error_name = 'form';
}
if( $request->get('password') != '' ){
$passwordValid = true;
if( $request->get('password') != $request->get('confirm') ){
$error = $tr['signup_error3'];
$success = false;
$error_name = 'confirm';
$passwordValid = false;
}
if( strlen($request->get('password')) < 8 ){
$error = $tr['signup_error2'];
$success = false;
$error_name = 'confirm';
$passwordValid = false;
}
if( $passwordValid ){
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$request->get('confirm')
)
);
$em->persist($user);
$em->flush();
}
}
if( $success ){
$infos->firstname = ucwords(strtolower(trim($request->get('firstname'))));
$infos->lastname = strtoupper(trim($request->get('lastname')));
$infos->company = trim($request->get('company'));
$infos->address1 = trim($request->get('address1'));
$infos->zipcode = trim($request->get('zipcode'));
$infos->city = ucwords(strtolower(trim($request->get('city'))));
$infos->country_code = $request->get('country_code');
$infos->country = ucwords(strtolower(trim($request->get('country'))));
$infos->phone = trim($request->get('phone'));
$user->setInfos(json_encode($infos));
$stripe = new \Stripe\StripeClient(
$globals['stripe_secret_key']
);
$customer = $stripe->customers->update(
$user->getInfo('stripe_id'),
[
'name' => ucwords(strtolower(trim($request->get('firstname')))).' '.strtoupper(trim($request->get('lastname'))),
'address' => [
'city' => trim($request->get('city')),
'country' => $request->get('country_code'),
'line1' => trim($request->get('address1')),
// 'line2' => trim($request->get('address_line2')),
'postal_code' => trim($request->get('zipcode')),
],
'phone' => trim($request->get('phone')),
'preferred_locales' =>[strtolower($request->getLocale())],
'metadata' => ['company_name' => trim($request->get('company'))]
]
);
$em->persist($user);
$em->flush();
}
$data = [
'error' => $error,
'success' => $success,
'error_name' => $error_name
];
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
return $response;
} else {
return $this->redirectToRoute('security_login');
}
}
/**
* @Route("/forgot", name="security_forgot")
* @Route("/forgot/{locale}", name="security_forgot_locale", requirements={"locale" = "([a-z\-0-9]+)"})
*/
public function forgot(Request $request, MailerInterface $mailer, $locale = NULL): Response
{
if($locale){
$request->setLocale($locale);
} else {
$locale = 'fr';
$request->setLocale('fr');
}
$em = $this->getDoctrine()->getManager();
$globals = $this->get("twig")->getGlobals();
$tr = $this->loadTranslation($locale);
$isAjax = $request->isXMLHttpRequest();
if (!$isAjax) {
return $this->redirectToRoute('framework_front_page_404', ['locale' => $locale]);
}
$success = false;
$error = '';
$user = $em->getRepository('FrameworkAppBundle:User')->findOneBy(['email' => $request->get('email')]);
$forgot = $this->randomPassword();
if( !$user ){
$error = $tr['login_error1'];
} else {
$user->setForgot($forgot);
$em->persist($user);
$em->flush();
$subject = 'Votre compte Royal Palace';
$title = $subject;
$content = '<p>Bonjour,</p>
<strong><a href="'.$this->urlGenerator->generate('security_reset_locale', ['token' => $forgot, 'locale' => $locale], UrlGeneratorInterface::ABSOLUTE_URL).'">Cliquez ici pour créer un nouveau mot de passe</a></strong>
<p><br>A bientôt au <a href="'.$globals['app_email_domain'].'"><strong>Royal Palace</strong></a></p>';
if($locale == 'de'){
$subject = 'Ihr Konto bei Royal Palace';
$title = $subject;
$content = '<p>Hallo,</p>
<strong><a href="'.$this->urlGenerator->generate('security_reset_locale', ['token' => $forgot, 'locale' => $locale], UrlGeneratorInterface::ABSOLUTE_URL).'">Klicken Sie hier, um ein neues Passwort zu erstellen</a></strong>
<p><br>Bis bald im <a href="'.$globals['app_email_domain'].'"><strong>Royal Palace</strong></a></p>';
}
if($locale == 'en'){
$subject = 'Your Royal Palace account';
$title = $subject;
$content = '<p>Hello,</p>
<strong><a href="'.$this->urlGenerator->generate('security_reset_locale', ['token' => $forgot, 'locale' => $locale], UrlGeneratorInterface::ABSOLUTE_URL).'">Click here to create a new password</a></strong>
<p><br>See you soon at the <a href="'.$globals['app_email_domain'].'"><strong>Royal Palace</strong></a></p>';
}
//ENVOI EMAIL
$from = $globals['app_email_noreply'];
$to = $globals['app_email_address'];
$contact = $globals['app_email_contact'];
$email = (new Email())
->from($from)
->to($user->getEmail())
//->cc('cc@example.com')
//->bcc('bcc@example.com')
->replyTo($contact)
//->priority(Email::PRIORITY_HIGH)
->subject($subject)
// ->text(nl2br('Royal Palace').nl2br('Royal Palace : Réinitialiser le mot de passe').nl2br('Bonjour,').nl2br('Suivez ce lien pour créer un nouveau mot de passe :').nl2br($this->urlGenerator->generate('security_reset', ['token' => $forgot], UrlGeneratorInterface::ABSOLUTE_URL)).nl2br('A bientôt au Royal Palace'))
->html($this->renderView(
'FrontBundle/Emails/general.html.twig', array(
'title' => $title,
'content' => $content
)
));
$mailer->send($email);
//FIN ENVOI EMAIL
$success = true;
}
$data = [
'error' => $error,
'success' => $success
];
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
private function randomPassword() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return substr(str_shuffle($chars),0,16);
}
/**
* @Route("/reset/{token}", name="security_reset")
* @Route("/reset/{token}/{locale}", name="security_reset_locale", requirements={"locale" = "([a-z\-0-9]+)"})
*/
public function reset(string $token = NULL, Request $request, Security $security, AuthenticationUtils $helper, $locale = NULL): Response
{
if($locale){
$request->setLocale($locale);
} else {
$locale = 'fr';
$request->setLocale('fr');
}
if (!$security->isGranted('ROLE_USER') && $token == null) {
return $this->redirectToRoute('security_login');
}
// this statement solves an edge-case: if you change the locale in the login
// page, after a successful login you are redirected to a page in the previous
// locale. This code regenerates the referrer URL whenever the login page is
// browsed, to ensure that its locale is always the current one.
// $this->saveTargetPath($request->getSession(), 'main', $this->generateUrl('admin_index'));
$em = $this->getDoctrine()->getManager();
$locale = $request->getLocale();
$tr = $this->loadTranslation($locale);
$globals = $this->get("twig")->getGlobals();
$metaTitle = $tr['reset_title'];
$metaDesc = $tr['reset_subtitle'];
$noindex = true;
if ($security->isGranted('ROLE_USER')){
$user = $this->getUser();
} else {
$user = $em->getRepository('FrameworkAppBundle:User')->findOneBy(['forgot' => $token]);
}
if (!$user) {
return $this->redirectToRoute('security_login');
}
$page = $em->getRepository('FrameworkAppBundle:Page')->findOneBy(['slug' => 'connexion', 'locale' => $locale]);
return $this->render('AdminBundle/Security/reset.html.twig', [
'metaTitle' => $metaTitle,
'metaDesc' => $metaDesc,
'noindex' => $noindex,
'page' => $page,
'token' => $token,
]);
}
/**
* @Route("/change", name="security_change")
*/
public function resetChange(Request $request, Security $security, UserPasswordEncoderInterface $passwordEncoder)
{
$isAjax = $request->isXMLHttpRequest();
if (!$isAjax) {
return $this->redirectToRoute('security_login');
}
$success = false;
$error = '';
$em = $this->getDoctrine()->getManager();
if($security->isGranted('ROLE_USER')) {
$user = $this->getUser();
$test_password = $passwordEncoder->isPasswordValid($user, $request->get('password'));;
if(!$test_password){
$success = false;
$error = 'Mauvais mot de passe';
} else {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$request->get('new_password')
)
);
$user->setForgot(NULL);
$em->persist($user);
$em->flush();
$success = true;
}
} else {
$user = $em->getRepository('FrameworkAppBundle:User')->findOneBy(['forgot' => $request->get('token')]);
if (!$user) {
$success = false;
$error = 'Ce compte n\'existe pas';
} elseif($request->get('confirm_password') != $request->get('new_password')) {
$success = false;
$error = 'La confirmation et le mot de passe ne correspondent pas';
} else {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$request->get('new_password')
)
);
$user->setForgot(NULL);
$em->persist($user);
$em->flush();
$success = true;
}
}
$data = [
'error' => $error,
'success' => $success
];
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
/**
* @Route("/signup", name="security_signup")
* @Route("/signup/{locale}", name="security_signup_locale", requirements={"locale" = "([a-z\-0-9]+)"})
*/
public function signupAjax(Request $request, UserPasswordEncoderInterface $passwordEncoder, LoginFormAuthenticator $login, GuardAuthenticatorHandler $guard, MailerInterface $mailer, $locale = NULL)
{
if($locale){
$request->setLocale($locale);
} else {
$locale = 'fr';
$request->setLocale('fr');
}
require_once dirname(__FILE__).'/../../plugins/stripe-php-10.12.1/init.php';
$em = $this->getDoctrine()->getManager();
$globals = $this->get("twig")->getGlobals();
$tr = $this->loadTranslation($locale);
$isAjax = $request->isXMLHttpRequest();
if (!$isAjax) {
return $this->redirectToRoute('framework_front_page_404', ['locale' => $locale]);
}
$success = false;
$error = '';
if( $em->getRepository('FrameworkAppBundle:User')->findOneBy(['email' => $request->get('email')]) ){
$error = $tr['signup_error1'];
} elseif($request->get('email') == '' || $request->get('password') == '' || $request->get('confirm') == '') {
$error = $tr['contact_error2'];
} else {
if(trim($request->get('email')) == 'sample@email.tst'){
exit;
}
$user = new User();
$user->setUsername(strtolower(trim($request->get('email'))));
$user->setEmail(strtolower(trim($request->get('email'))));
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$request->get('password')
)
);
$user->setDeleted(0);
$user->setRoles(["ROLE_USER"]);
$stripe = new \Stripe\StripeClient(
$globals['stripe_secret_key']
);
$customer = $stripe->customers->create([
'email' => strtolower(trim($request->get('email'))),
// 'name' => ucwords(strtolower(trim($request->get('firstname')))).' '.strtoupper(trim($request->get('lastname'))),
// 'address' => [
// 'city' => trim($request->get('address_city')),
// 'country' => $request->get('address_country'),
// 'line1' => trim($request->get('address_line1')),
// 'line2' => trim($request->get('address_line2')),
// 'postal_code' => trim($request->get('address_postal_code')),
// ],
'metadata' => ['user_id' => $user->getId()],
]);
$user->setInfos(json_encode(['stripe_id' => $customer->id]));
$em->persist($user);
$em->flush();
$globals = $this->get("twig")->getGlobals();
$subject = 'Votre compte Royal Palace';
$title = $subject;
$content = '<p>Bonjour,</p>
<p>Merci beaucoup pour votre inscription. Complétez vos informations de contact dans la section <a href="'.$globals['app_email_domain'].'fr/mon-compte">"Mon Compte"</a>.</p>
<p>Nous vous invitons à découvrir nos spectacles sur notre site. Pour réserver dès maintenant, consultez <a href="'.$globals['app_email_domain'].'fr/reservation"> notre calendrier</a> et laissez vous guider.</p>
<p><br>A bientôt au <a href="'.$globals['app_email_domain'].'"><strong>Royal Palace</strong></a></p>';
if($locale == 'de'){
$subject = 'Ihr Konto bei Royal Palace';
$title = $subject;
$content = '<p>Hallo,</p>
<p>Vielen Dank für Ihre Anmeldung. Vervollständigen Sie Ihre Kontaktinformationen im Abschnitt <a href="'.$globals['app_email_domain'].'de/mon-compte">"Mein Konto"</a>.</p>
<p>Wir laden Sie ein, unsere Aufführungen auf unserer Website zu entdecken. Um schon jetzt zu buchen, werfen Sie einen Blick auf <a href="'.$globals['app_email_domain'].'de/buchen"> unseren Kalender</a> und lassen Sie sich führen.</p>
<p><br>Bis bald im <a href="'.$globals['app_email_domain'].'de"><strong>Royal Palace</strong></a></p>';
}
if($locale == 'en'){
$subject = 'Your Royal Palace account';
$title = $subject;
$content = '<p>Hello,</p>
<p>Thank you very much for registering. Please fill in your contact information in the <a href="'.$globals['app_email_domain'].'en/mon-compte">"My account"</a> section.</p>
<p>We invite you to discover our shows on our website. To book now, consult <a href="'.$globals['app_email_domain'].'en/book"> our calendar</a> and let us guide you.</p>
<p><br>See you soon at the <a href="'.$globals['app_email_domain'].'en"><strong>Royal Palace</strong></a></p>';
}
//ENVOI EMAIL
$from = $globals['app_email_noreply'];
$to = $globals['app_email_address'];
$contact = $globals['app_email_contact'];
$email = (new Email())
->from($from)
->to($user->getEmail())
//->cc('cc@example.com')
//->bcc('bcc@example.com')
->replyTo($contact)
//->priority(Email::PRIORITY_HIGH)
->subject($subject)
// ->text(nl2br('Royal Palace').nl2br('Royal Palace : Inscription').nl2br('Bonjour,').nl2br('Merci beaucoup pour votre inscription. Complétez vos informations de contact dans la section "Mon Compte". Nous vous invitons à découvrir nos spectacles sur notre site. Pour réserver dès maintenant, consultez notre calendrier et laissez vous guider.').nl2br('A bientôt au Royal Palace'))
->html($this->renderView(
'FrontBundle/Emails/general.html.twig', array(
'title' => $title,
'content' => $content
)
));
$mailer->send($email);
//FIN ENVOI EMAIL
$success = true;
$guard->authenticateUserAndHandleSuccess($user,$request,$login,'main');
}
$data = [
'error' => $error,
'success' => $success
];
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
public function loadTranslation($locale){
$arr = [];
$em = $this->getDoctrine()->getManager();
$translations = $em->getRepository('FrameworkAppBundle:Translation')->findAll();
foreach ($translations as $key => $translation) {
$content = $translation->getContent();
if(isset($content[$locale])){
$arr[$translation->getSlug()] = $content[$locale];
} else {
$arr[$translation->getSlug()] = $translation->getSlug();
}
}
return $arr;
}
}