<?php
namespace App\Core\Controller;
use App\Core\Entity\User;
use App\Core\Repository\TutorialRepository;
use App\Core\Repository\UserRepository;
use App\Core\Security\LoginUserAuthenticator;
use App\EventSubscriber\LocaleSubscriber;
use App\EventSubscriber\UserLocaleSubscriber;
use App\Service\TutorialService;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Client\Provider\GoogleClient;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use KnpU\OAuth2ClientBundle\Exception\MissingAuthorizationCodeException;
class OAuthController extends AbstractController
{
/**
* @var TutorialRepository
*/
private $tutorialRepository;
/**
* @var TutorialService
*/
private $tutorialService;
function __construct(TutorialRepository $tutorialRepository, TutorialService $tutorialService) {
$this->tutorialRepository = $tutorialRepository;
$this->tutorialService = $tutorialService;
}
#[Route('/login/google', name: 'app_verificar_login_google')]
function googleVerficarLogin(ClientRegistry $clientRegistry) {
return $clientRegistry->getClient('google')->redirect([],[]);
}
#[Route('/login/google/correcto', name: 'app_login_google')]
function googleLogin(Request $request, ClientRegistry $clientRegistry, UserRepository $userRepository, EntityManagerInterface $entityManager, LoginUserAuthenticator $loginUserAuthenticator, GuardAuthenticatorHandler $guardAuthenticatorHandler) {
/** @var GoogleClient $client */
$client = $clientRegistry->getClient('google');
try {
$accessToken = $client->getAccessToken();
/** @var \League\OAuth2\Client\Provider\GoogleUser $user */
$user = $client->fetchUserFromToken($accessToken);
$usuarioExistente = $userRepository->findOneBy(['email' => $user->getEmail()]);
if ($usuarioExistente) {
if (!$usuarioExistente->getGoogleId()) {
$usuarioExistente->setGoogleId($user->getId());
$entityManager->persist($usuarioExistente);
}
$request->request->set('usuarioExiste', true);
}
else {
$usuarioExistente = new User();
$usuarioExistente->setGoogleId($user->getId());
$usuarioExistente->setEmail($user->getEmail());
$usuarioExistente->setPrimerNombre($user->getFirstName());
$usuarioExistente->setPrimerApellido($user->getLastName());
$usuarioExistente->setUsername($user->getEmail());
$usuarioExistente->asignarNombreCompleto();
$usuarioExistente->setCreatedAt(new \DateTime());
$localeDelNavegador = strtolower(str_split($_SERVER['HTTP_ACCEPT_LANGUAGE'], 2)[0]);
if ($localeDelNavegador && trim($localeDelNavegador) !== '' && in_array($localeDelNavegador, UserLocaleSubscriber::getLenguajesDisponibles())) {
$usuarioExistente->setIdioma($localeDelNavegador);
}
else {
$usuarioExistente->setIdioma(LocaleSubscriber::$defaultLocale);
}
$entityManager->persist($usuarioExistente);
//Agregarle todos los tutoriales al nuevo usuario
$tutoriales = $this->tutorialRepository->findAll();
foreach ($tutoriales as $tutorial) {
$this->tutorialService->agregarTutorialAUsuario($usuarioExistente, $tutorial);
}
$request->request->set('usuarioExiste', false);
}
$entityManager->flush();
return $guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
$usuarioExistente,
$request,
$loginUserAuthenticator,
'main'
);
} catch (IdentityProviderException $e) {
return new Response($e->getMessage());
}
}
#[Route('/login/facebook', name: 'app_verificar_login_facebook')]
function facebookVerficarLogin(ClientRegistry $clientRegistry) {
return $clientRegistry->getClient('facebook')->redirect([],[]);
}
#[Route('/login/facebook/correcto', name: 'app_login_facebook')]
function facebookLogin(Request $request, ClientRegistry $clientRegistry, UserRepository $userRepository, EntityManagerInterface $entityManager, LoginUserAuthenticator $loginUserAuthenticator, GuardAuthenticatorHandler $guardAuthenticatorHandler) {
/** @var \KnpU\OAuth2ClientBundle\Client\Provider\FacebookClient $client */
$client = $clientRegistry->getClient('facebook');
try {
$accessToken = $client->getAccessToken();
/** @var \League\OAuth2\Client\Provider\FacebookUser $user */
$user = $client->fetchUserFromToken($accessToken);
$usuarioExistente = $userRepository->findOneBy(['email' => $user->getEmail()]);
if ($usuarioExistente) {
if (!$usuarioExistente->getFacebookId()) {
$usuarioExistente->setFacebookId($user->getId());
$entityManager->persist($usuarioExistente);
}
$request->request->set('usuarioExiste', true);
}
else {
$usuarioExistente = new User();
$usuarioExistente->setFacebookId($user->getId());
$usuarioExistente->setEmail($user->getEmail());
$usuarioExistente->setPrimerNombre($user->getFirstName());
$usuarioExistente->setPrimerApellido($user->getLastName());
$usuarioExistente->setUsername($user->getEmail());
$usuarioExistente->asignarNombreCompleto();
$usuarioExistente->setCreatedAt(new \DateTime());
$localeDelNavegador = strtolower(str_split($_SERVER['HTTP_ACCEPT_LANGUAGE'], 2)[0]);
if ($localeDelNavegador && trim($localeDelNavegador) !== '' && in_array($localeDelNavegador, UserLocaleSubscriber::getLenguajesDisponibles())) {
$usuarioExistente->setIdioma($localeDelNavegador);
}
else {
$usuarioExistente->setIdioma(LocaleSubscriber::$defaultLocale);
}
$entityManager->persist($usuarioExistente);
//Agregarle todos los tutoriales al nuevo usuario
$tutoriales = $this->tutorialRepository->findAll();
foreach ($tutoriales as $tutorial) {
$this->tutorialService->agregarTutorialAUsuario($usuarioExistente, $tutorial);
}
$request->request->set('usuarioExiste', false);
}
$entityManager->flush();
return $guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
$usuarioExistente,
$request,
$loginUserAuthenticator,
'main'
);
} catch (IdentityProviderException $e) {
return new Response($e->getMessage());
}
catch (MissingAuthorizationCodeException $missingAuthorizationCodeException) {
return $this->redirectToRoute('app_login', ['error' => 'Invalid Facebook token']);
}
}
}