<?php
namespace App\Controller;
use App\Entity\InscripcionUsuarioJornadaCurso;
use App\Entity\JornadaCurso;
use App\Entity\Usuario;
use App\Exception\CustomException;
use App\Form\FrontFormBusquedaJornadaCursoType;
use App\Form\FrontInscripcionUsuarioJornadaCursoType;
use App\Service\JornadaCursoService;
use App\Service\Mails;
use Symfony\Component\HttpFoundation\RedirectResponse;
use App\Entity\Localidad;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
#[Route(path: '/jornadas-cursos')]
class FrontJornadaCursoController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly JornadaCursoService $jornadaCursoService,
private readonly UserPasswordHasherInterface $encoder,
private readonly Mails $mails)
{
}
#[Route(path: '/ver/{jornadaCurso}-{slug}', name: 'front_ver_jornada_curso', methods: 'GET|POST')]
#[ParamConverter('jornadaCurso', options: ['mapping' => ['jornadaCurso' => 'id']])]
public function ver(JornadaCurso $jornadaCurso, string $slug): RedirectResponse|Response
{
// Redirigir si el slug no coincide con el actual (SEO)
if ($slug !== $jornadaCurso->getSlug()) {
return $this->redirectToRoute('front_ver_jornada_curso', [
'jornadaCurso' => $jornadaCurso->getId(),
'slug' => $jornadaCurso->getSlug()
], Response::HTTP_MOVED_PERMANENTLY);
}
$usuario = $this->getUser();
// Obtiene y comprueba que la jornada cumpla unos criterios. Ver repo.
$jornadaCurso = $this->em->getRepository(JornadaCurso::class)->comprobarAccesibilidadJornadaCurso($jornadaCurso);
if (!$jornadaCurso) {
return $this->redirectToRoute('front_inicio');
}
// Comprueba si $now está dentro de las fechas de inicio y fin de solicitud de inscripción del curso.
$fechasEnPlazo = $jornadaCurso->estaInscripcionAbierta();
return $this->render('front-jornadas-cursos/ver.html.twig', [
'jornadaCurso' => $jornadaCurso,
'fechasEnPlazo' => $fechasEnPlazo
]);
}
#[Route(path: '/inscribirse/{jornadaCurso}', name: 'front_solicitar_inscripcion_jornada_curso', methods: 'GET|POST')]
public function inscribirseJornadaCurso(Request $request, JornadaCurso $jornadaCurso): Response
{
try {
$usuario = $this->getUser();
$confirmarRegistro = $this->getParameter('confirmarRegistro');
$repoUsuario = $this->em->getRepository(Usuario::class);
// Comprueba si $now está dentro de las fechas de inicio y fin de la jornada del curso.
$fechasEnPlazo = $jornadaCurso->estaInscripcionAbierta();
if (!$fechasEnPlazo) {
throw new CustomException('No está dentro del plazo para poder realizar la solicitud.');
}
$inscripcionUsuarioJornada = new InscripcionUsuarioJornadaCurso();
$inscripcionUsuarioJornada->setJornadaCurso($jornadaCurso);
// Si está logueado, se le precargan los campos del form.
if ($this->isGranted('IS_AUTHENTICATED')) {
$inscripcionUsuarioJornada
->setUsuario($usuario)
->setEmail($usuario->getEmail())
->setNombre($usuario->getNombre())
->setApellidos($usuario->getApellidos())
->setDniNie($usuario->getDniNie())
->setSexo($usuario->getSexo())
->setLocalidad($usuario->getLocalidad())
->setDireccion($usuario->getDireccion())
->setCodigoPostal($usuario->getCodigoPostal())
->setTelefono1($usuario->getTelefono1())
->setTelefono2($usuario->getTelefono2())
->setFechaNacimiento($usuario->getFechaNacimiento());
}
$this->em->persist($inscripcionUsuarioJornada);
$form = $this->createForm(FrontInscripcionUsuarioJornadaCursoType::class, $inscripcionUsuarioJornada);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($this->jornadaCursoService->plazasDisponiblesEnJornada($jornadaCurso) <= 0) {
throw new CustomException('No quedan plazas disponibles para inscribirse.');
}
$passTexto = null;
$cuentaNueva = false;
if (!$this->isGranted('IS_AUTHENTICATED')) {
$usuario = $repoUsuario->findOneBy(['email' => $form->get('email')->getData()]);
if (!$usuario) {
$usuario = $repoUsuario->findOneBy(['dniNie' => $form->get('dniNie')->getData()]);
}
if (!$usuario) {
$usuario = new Usuario();
$passTexto = uniqid();
$passTemp = $this->encoder->hashPassword($usuario, $passTexto);
$usuario
->setUsuario($form->get('email')->getData())
->setEmail($form->get('email')->getData())
->setNombre($form->get('nombre')->getData())
->setApellidos($form->get('apellidos')->getData())
->setDniNie($form->get('dniNie')->getData())
->setSexo($form->get('sexo')->getData())
->setLocalidad($form->get('localidad')->getData())
->setDireccion($form->get('direccion')->getData())
->setCodigoPostal($form->get('codigoPostal')->getData())
->setTelefono1($form->get('telefono1')->getData())
->setTelefono2($form->get('telefono2')->getData())
->setPassword($passTemp)
->setFechaNacimiento($form->get('fechaNacimiento')->getData())
->setAceptaCondicionesPrivacidad($form->get('aceptaCondicionesPrivacidad')->getData())
->setLlamar(false)
->setActivo(!$confirmarRegistro);
$this->em->persist($usuario);
$inscripcionUsuarioJornada->setUsuario($usuario);
$cuentaNueva = true;
}
}
$this->em->flush();
if ($cuentaNueva) {
$htmlConfirmarRegistro = "";
if ($confirmarRegistro) {
$urlConfirmacionRegistro = $this->generateUrl('front_confirmar_registro', [
'tokenConfirmacion' => $usuario->getTokenConfirmacion()
], UrlGeneratorInterface::ABSOLUTE_URL);
$htmlConfirmarRegistro = "
<br><br>
Para acceder al sistema es necesario confirmar su registro. Para confirmarlo acceda
<u><a class='btn btn-sm btn-primary' href='".$urlConfirmacionRegistro."'>aquí</a></u>
";
$usuario->setTokenConfirmacion(sha1(uniqid(mt_rand(), true)));
}
$this->mails->sendNotification(
'Confirmación de su registro',
"
<p>Hola {$usuario->getUsuario()}: </p>
<p>
Al realizar la inscripción a la joranda <b>{$jornadaCurso->getNombre()}</b>, hemos detectado
que no tenía una cuenta creada en el sistema de Proempleo 8 y se la hemos creado automáticamente.
$htmlConfirmarRegistro.
</p>
<p>
Una vez que haya confirmado su cuenta, los datos de acceso son:<br>
- Email: <b>{$usuario->getEmail()}</b><br>
- Contraseña: <b>$passTexto</b><br>
</p>
<p>Por seguridad, cambie su contraseña una vez que inicie sesión en la cuenta desde
su perfil accediendo mediante el item de menú superior <b>Mi perfil</b>.</p>
",
$usuario->getEmail(),
null,
true
);
}
$this->mails->sendNotification(
'Confirmación de inscripción en la jornada',
"
<p>Estimado/a {$usuario->getUsuario()}:</p>
<p>Nos complace informarle que su inscripción a la jornada <b>{$jornadaCurso->getNombre()}</b> ha
sido confirmada correctamente. Le agradecemos su interés en participar.</p>
<p>Si tiene alguna duda o necesita realizar alguna consulta, no dude en ponerse en contacto con nosotros.</p>
<p>Atentamente,<br>
Proempleo 8</p>
",
$usuario->getEmail(),
null,
true
);
$this->addFlash('success', 'Operación realizada correctamente.');
return $this->redirectToRoute('front_ver_jornada_curso', [
'jornadaCurso' => $jornadaCurso->getId(),
'slug' => $jornadaCurso->getSlug()
]);
}
return $this->render('front-jornadas-cursos/inscribirse-jornada-curso.html.twig', [
'jornadaCurso' => $jornadaCurso,
'form' => $form->createView()
]);
} catch (CustomException $e) {
$this->addFlash('error', $e->getMessage());
return $this->redirectToRoute('front_ver_jornada_curso', [
'jornadaCurso' => $jornadaCurso->getId(),
'slug' => $jornadaCurso->getSlug()
]);
} catch (Exception $e) {
$this->addFlash('error', 'Se ha producido un error.');
return $this->redirectToRoute('front_ver_jornada_curso', [
'jornadaCurso' => $jornadaCurso->getId(),
'slug' => $jornadaCurso->getSlug()
]);
}
}
#[Route(path: '', name: 'front_listado_jornadas_cursos', options: ['expose' => true], methods: 'GET|POST')]
#[Route(path: '/{slugLocalidad}', name: 'front_listado_jornadas_cursos_localidad', options: ['expose' => true], methods: 'GET|POST')]
#[ParamConverter('slugLocalidad', options: ['mapping' => ['slugLocalidad' => 'slug']])]
public function listado(Request $request, Localidad $slugLocalidad = null): Response
{
$ordenarPor = 'masReciente';
$nombre = '';
$itemsPorPagina = 30;
$pagina = $request->query->getInt('page', 1);
if ($request->query->get('itemsPorPagina') && trim($request->query->get('itemsPorPagina')) !== '') {
$itemsPorPagina = $request->query->get('itemsPorPagina');
}
$localidad = null;
if ($slugLocalidad instanceof Localidad) {
$localidad = $slugLocalidad->getSlug();
}
// FORM BÚSQUEDA
$frontFormBusquedaJornadasCursos = $this->createForm(FrontFormBusquedaJornadaCursoType::class, [
'localidad' => $slugLocalidad
]);
$frontFormBusquedaJornadasCursos->handleRequest($request);
if ($frontFormBusquedaJornadasCursos->isSubmitted() && $frontFormBusquedaJornadasCursos->isValid()) {
$nombre = $frontFormBusquedaJornadasCursos->get('nombre')->getData() ?? '';
}
// FIN FORM BÚSQUEDA
$jornadasCursos = $this->em->getRepository(JornadaCurso::class)->obtenerBuscadorFront($nombre, $localidad, $pagina, $itemsPorPagina, $ordenarPor);
return $this->render('front-jornadas-cursos/listado.html.twig', [
'jornadasCursos' => $jornadasCursos,
'itemsPorPagina' => $itemsPorPagina,
'frontFormBusquedaJornadasCursos' => $frontFormBusquedaJornadasCursos->createView(),
'localidad' => $slugLocalidad,
]);
}
}