welcome back to dyb-tech

This commit is contained in:
Daniel Guzman
2024-05-18 02:28:01 +02:00
parent 9513cdba09
commit 9f30bc98c7
6149 changed files with 668407 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace DMD\LaLigaApi\Service\Common;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\LeagueRepository;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class AuthorizeRequest
{
public function __construct(
public Security $security,
public CustomRoleRepository $customRoleRepository,
public LeagueRepository $leagueRepository
)
{}
public function authorizeLeaguePresident(int $leagueId): void
{
$userEntity = $this->security->getUser();
if (is_null($userEntity))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Unauthorized.");
}
$customRole = $this->customRoleRepository->findBy([
'name' => $leagueId . Role::LEAGUE_PRESIDENT->value,
'userEntity' => $userEntity
]);
if (is_null($customRole))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Usuario no tiene permiso para editar la liga.");
}
}
public function teamCaptainRequest(int $leagueId, $teamId): User
{
$userEntity = $this->security->getUser();
if (!$userEntity instanceof User)
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Unauthorized");
}
$captainCustomRole = $this->customRoleRepository->findBy([
'name' => $teamId . Role::TEAM_CAPTAIN->value,
]);
if (!is_null($captainCustomRole))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Equipo con id: $teamId ya tiene capitan");
}
$leagueMemberRole = $this->customRoleRepository->findBy([
'name' => $leagueId . Role::LEAGUE_MEMBER->value,
'user' => $userEntity
]);
if (is_null($leagueMemberRole))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Usuario no es miembro de la liga");
}
return $userEntity;
}
public function isLeaguePresident(int $leagueId, User $leagueAdmin): bool
{
$adminRoles = $leagueAdmin->getCustomRoles();
if (!$adminRoles->isEmpty())
{
foreach ($adminRoles as $adminRoleEntity)
{
$explodedRole = explode('_', $adminRoleEntity->getName());
if (
strtolower($explodedRole[1]) == 'league' &&
strtolower($explodedRole[2]) == 'president' &&
$explodedRole[0] == $leagueId
)
{
return true;
}
}
}
throw new HttpException(Response::HTTP_NOT_FOUND,'Forbidden.');
}
}
+112
View File
@@ -0,0 +1,112 @@
<?php
namespace DMD\LaLigaApi\Service\Common;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\Team;
use DMD\LaLigaApi\Entity\User;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
class EmailSender
{
public function __construct(
public MailerInterface $mailer
)
{
}
/**
* @throws TransportExceptionInterface
*/
public function newJoinLeagueRequest(User $leagueAdminEntity, User $requestingUserEntity, League $leagueEntity): void
{
$requestingUserFullName = $requestingUserEntity->getFirstName() . ' '. $requestingUserEntity->getLastName();
$email = (new TemplatedEmail())
->from('soporteliga@dyb-tech.com')
->to(
(new Address($leagueAdminEntity?->getEmail()))
)
->subject("Nueva solicitud: $requestingUserFullName se quiere unir a ". $leagueEntity->getName())
->htmlTemplate('joinLeague.html.twig')
->context([
'user' => $requestingUserEntity,
'president'=> $leagueAdminEntity,
'league' => $leagueEntity
]);
$this->mailer->send($email);
}
/**
* @throws TransportExceptionInterface
*/
public function teamCaptainRequest(Team $teamEntity, User $leagueAdminEntity, User $requestingUser, League $leagueEntity): void
{
$requestingUserFullName = $requestingUser->getFirstName() .' '. $requestingUser->getLastName();
$email = (new TemplatedEmail())
->from('soporteliga@dyb-tech.com')
->to(
(new Address($leagueAdminEntity->getEmail()))
)
->subject("Nueva solicitud: $requestingUserFullName se quiere unir a ". $leagueEntity->getName())
->htmlTemplate('teamCaptainRequest.html.twig')
->context([
'userToNotify' => $leagueAdminEntity,
'requestingUser'=> $requestingUser,
'league'=> $leagueEntity,
'team' => $teamEntity
]);
$this->mailer->send($email);
}
/**
* @throws TransportExceptionInterface
*/
public function declineTeamCaptainRequest(User $rejectedUser, League $leagueEntity): void
{
$email = (new TemplatedEmail())
->from('soporte@leagueranks.es')
->to((new Address($rejectedUser->getEmail())))
->subject('Tu solicitud ha sido rechazada.')
->htmlTemplate('declinedRequest.html.twig')
->context([
'rejectedUserEntity' => $rejectedUser,
'leagueEntity'=> $leagueEntity
]);
$this->mailer->send($email);
}
/**
* @throws TransportExceptionInterface
*/
public function joinLeagueRequestAccepted(User $user, League $league): void
{
$email = (new TemplatedEmail())
->from('soporte@leagueranks.es')
->to((new Address($user->getEmail())))
->subject('Tu solicitud ha sido aceptada.')
->htmlTemplate('welcomeToLeague.html.twig')
->context([
'user' => $user,
'leagueName'=> $league->getName()
]);
$this->mailer->send($email);
}
/**
* @throws TransportExceptionInterface
*/
public function joinLeagueRequestDeclined(User $user, League $league): void
{
$email = (new TemplatedEmail())
->from('soporte@leagueranks.es')
->to((new Address($user->getEmail())))
->subject('Tu solicitud ha sido rechazada.')
->htmlTemplate('leagueRequestDeclined.html.twig')
->context([
'user' => $user,
'leagueName'=> $league->getName()
]);
$this->mailer->send($email);
}
}
@@ -0,0 +1,96 @@
<?php
namespace DMD\LaLigaApi\Service\Common;
use DMD\LaLigaApi\Dto\NotificationDto;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\Notification;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Enum\NotificationType;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\TeamRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class NotificationFactory
{
public function __construct(
public CustomRoleRepository $customRoleRepository,
public TeamRepository $teamRepository,
public EntityManagerInterface $entityManager,
public EmailSender $emailSender
)
{
}
/**
* @throws TransportExceptionInterface
*/
public function newJoinLeagueRequest(User $requestingUserEntity, League $leagueEntity, ?string $message): void
{
$leagueAdminEntity = $this->customRoleRepository->findUserByRoleName($leagueEntity->getId() . Role::LEAGUE_PRESIDENT->value);
if (is_null($leagueAdminEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND,'Presidente de liga con id' . $leagueEntity->getId() .' no ha sido encontrado');
}
$requestingUserFullName = $requestingUserEntity->getFirstName() . ' '. $requestingUserEntity->getLastName();
$notification = new Notification();
$notification->setUserWhoFiredEvent($requestingUserEntity);
$notification->setUserToNotify($leagueAdminEntity);
$notification->setType(NotificationType::NEW_JOIN_LEAGUE_REQUEST->name);
$notification->setMessage(
$message ?? NotificationType::NEW_JOIN_LEAGUE_REQUEST->getMessage(
$requestingUserFullName,
$leagueEntity->getName()
)
);
$notification->setLeague($leagueEntity);
$this->entityManager->persist($notification);
$this->entityManager->flush();
$this->emailSender->newJoinLeagueRequest($leagueAdminEntity, $requestingUserEntity, $leagueEntity);
}
public function teamCaptainRequest(User $requestingUser, User $leagueAdminEntity, string $message, League $leagueEntity, int $teamId): void
{
$teamEntity = $this->teamRepository->find($teamId);
if (is_null($teamEntity))
{
throw new HttpException(
Response::HTTP_NOT_FOUND,
"Equipo con ID $teamId no ha sido encontrado"
);
}
$requestingUserFullName = $requestingUser->getFirstName() .' '. $requestingUser->getLastName();
$notification = new Notification();
$notification->setUserWhoFiredEvent($requestingUser);
$notification->setUserToNotify($leagueAdminEntity);
$notification->setType(NotificationType::NEW_CAPTAIN_REQUEST->name);
$notification->setMessage($message ?? NotificationType::NEW_CAPTAIN_REQUEST->getMessage($requestingUserFullName, $teamEntity->getName()));
$notification->setTeamId($teamId);
$notification->setLeague($leagueEntity);
$notification->setIsRead(false);
$this->entityManager->persist($notification);
$this->entityManager->flush();
$this->emailSender->teamCaptainRequest($teamEntity, $leagueAdminEntity, $requestingUser, $leagueEntity);
}
public function joinLeagueRequestDeclined(User $rejectedUser, League $leagueEntity): void
{
$notification = new Notification();
$notification->setUserToNotify($rejectedUser);
$notification->setType(NotificationType::DECLINED_CAPTAIN_REQUEST->name);
$notification->setMessage(
NotificationType::DECLINED_JOIN_LEAGUE_REQUEST->getMessage(
requestingUserFullName: null,
entityName: $leagueEntity->getName()
)
);
$notification->setIsRead(false);
$this->entityManager->persist($notification);
$this->entityManager->flush();
$this->emailSender->joinLeagueRequestDeclined($rejectedUser, $leagueEntity);
}
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace DMD\LaLigaApi\Service\Common;
use DMD\LaLigaApi\Dto\TeamDto;
use DMD\LaLigaApi\Entity\Team;
class TeamFactory
{
public static function create(TeamDto $teamDto): Team
{
$teamEntity = new Team();
if (!empty($teamDto->name))
{
$teamEntity->setName($teamDto->name);
}
$teamEntity->setActive(true);
return $teamEntity;
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace DMD\LaLigaApi\Service\League;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Entity\League;
class LeagueFactory
{
public static function create(LeagueDto $leagueDto): League
{
$leagueEntity = new League();
if (!empty($leagueDto->name))
{
$leagueEntity->setName($leagueDto->name);
}
if (!empty($leagueDto->logo))
{
$leagueEntity->setLogo($leagueDto->logo);
}
if (!empty($leagueDto->description))
{
$leagueEntity->setDescription($leagueDto->description);
}
if (isset($leagueDto->pointsPerWin))
{
$leagueEntity->setPointsPerWin($leagueDto->pointsPerWin);
}
if (!empty($leagueDto->pointsPerDraw))
{
$leagueEntity->setPointsPerDraw($leagueDto->pointsPerDraw);
}
if (!empty($leagueDto->pointsPerLoss))
{
$leagueEntity->setPointsPerLoss($leagueDto->pointsPerLoss);
}
if (!empty($leagueDto->matchesBetweenTeams))
{
$leagueEntity->setMatchesBetweenTeams($leagueDto->matchesBetweenTeams);
}
if (!empty($leagueDto->blockedMatchDates))
{
$leagueEntity->setBlockedMatchDates($leagueDto->blockedMatchDates);
}
if (!empty($leagueDto->city))
{
$leagueEntity->setCity($leagueDto->city);
}
$leagueEntity->setActive(true);
return $leagueEntity;
}
}
@@ -0,0 +1,74 @@
<?php
namespace DMD\LaLigaApi\Service\League\acceptJoinLeagueRequest;
use DMD\LaLigaApi\Entity\CustomRole;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\TeamRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use DMD\LaLigaApi\Service\Common\EmailSender;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
class HandleAcceptJoinLeagueRequest
{
public function __construct(
public EntityManagerInterface $entityManager,
public Security $security,
public AuthorizeRequest $authorizeRequest,
public UserRepository $userRepository,
public LeagueRepository $leagueRepository,
public TeamRepository $teamRepository,
public EmailSender $emailSender
){}
/**
* @throws TransportExceptionInterface
*/
public function __invoke(Request $request, int $leagueId, int $userId): JsonResponse
{
$leagueAdminEntity = $this->security->getUser();
if (!$leagueAdminEntity instanceof User)
{
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error');
}
$this->authorizeRequest->isLeaguePresident($leagueId, $leagueAdminEntity);
$leagueEntity = $this->leagueRepository->find($leagueId);
if (is_null($leagueEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND, "Liga con id $leagueId no ha sido encontrada");
}
$requestingUserEntity = $this->userRepository->find($userId);
if (is_null($requestingUserEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND,"El usuario con id: $userId no ha sido encontrado.");
}
$customRoleEntity = new CustomRole();
$customRoleEntity->setName($leagueId. Role::LEAGUE_MEMBER->value);
$customRoleEntity->setUser($requestingUserEntity);
$this->entityManager->persist($customRoleEntity);
$this->entityManager->flush();
$this->emailSender->joinLeagueRequestAccepted(
$requestingUserEntity,
$leagueEntity
);
return new JsonResponse(
data: [
'success' => true,
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,69 @@
<?php
namespace DMD\LaLigaApi\Service\League\createLeague;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Entity\CustomRole;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Exception\ValidationException;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\League\LeagueFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleCreateLeague
{
public function __construct(
public LeagueFactory $leagueFactory,
public EntityManagerInterface $entityManager,
public Security $security,
public UserRepository $userRepository
){}
/**
* @throws ValidationException
*/
public function __invoke(Request $request): JsonResponse
{
$userEntity = $this->userRepository->findOneBy([
'email' => $this->security->getUser()?->getUserIdentifier()
]);
if (is_null($userEntity))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Unauthorized.");
}
$leagueDto = new LeagueDto();
$leagueDto->fillFromArray($request->toArray());
$leagueDto->validate();
$leagueEntity = $this->leagueFactory::create($leagueDto);
$leagueEntity->setActive(true);
$this->assignPresidentRole($leagueEntity->getId(), $userEntity);
$this->entityManager->persist($leagueEntity);
$this->entityManager->flush();
$leagueDto->id = $leagueEntity->getId();
$leagueDto->createdAt = $leagueEntity->getCreatedAt();
return new JsonResponse(
data: [
'success' => true,
'league' => $leagueDto->toArray()
],
status: Response::HTTP_OK
);
}
public function assignPresidentRole(int $leagueId, User $userEntity): void
{
$leaguePresidentRole = new CustomRole();
$leaguePresidentRole->setName($leagueId. Role::LEAGUE_PRESIDENT->value);
$leaguePresidentRole->setUser($userEntity);
$this->entityManager->persist($leaguePresidentRole);
}
}
@@ -0,0 +1,62 @@
<?php
namespace DMD\LaLigaApi\Service\League\declineJoinLeagueRequest;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use DMD\LaLigaApi\Service\Common\NotificationFactory;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class HandleDeclineJoinLeagueRequest
{
public function __construct(
public Security $security,
public UserRepository $userRepository,
public LeagueRepository $leagueRepository,
public AuthorizeRequest $authorizeRequest,
public NotificationFactory $notificationFactory
){}
/**
* @throws TransportExceptionInterface
*/
public function __invoke(
Request $request,
int $leagueId,
int $rejectedUserId
): JsonResponse
{
$leagueAdmin = $request->getUser();
if (!$leagueAdmin instanceof User)
{
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error');
}
$this->authorizeRequest->isLeaguePresident($leagueId, $leagueAdmin);
$leagueEntity = $this->leagueRepository->find($leagueId);
if (is_null($leagueEntity))
{
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, "Liga con id: $leagueId no ha sido encontrada");
}
$rejectedUser = $this->userRepository->find($rejectedUserId);
if (is_null($rejectedUser))
{
throw new HttpException(Response::HTTP_NOT_FOUND, "El usuario con id $rejectedUserId no ha sido encontrado.");
}
$this->notificationFactory->joinLeagueRequestDeclined($rejectedUser, $leagueEntity);
return new JsonResponse(
data: [
'success' => true,
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,48 @@
<?php
namespace DMD\LaLigaApi\Service\League\getAllLeagues;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Service\League\getLeagueById\HandleGetLeagueById;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleGetAllLeagues
{
private static int $PAGE_SIZE = 100;
public function __construct(
public LeagueRepository $leagueRepository
){}
public function __invoke(): JsonResponse
{
$page = 1;
$leagueCollection = $this->leagueRepository->findBy([
'active' => true
],
limit: self::$PAGE_SIZE,
offset: ($page * self::$PAGE_SIZE) - self::$PAGE_SIZE
);
$leagueArray = [];
if (!is_null($leagueCollection))
{
foreach ($leagueCollection as $leagueObj)
{
$leagueDto = new LeagueDto();
$leagueDto->fillFromObject($leagueObj);
$leagueArray[] = $leagueDto->toArray();
}
}
return new JsonResponse(
data: [
'success' => true,
'leagues' => $leagueArray
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,38 @@
<?php
namespace DMD\LaLigaApi\Service\League\getLeagueById;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Repository\LeagueRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleGetLeagueById
{
public function __construct(
public LeagueRepository $leagueRepository,
){}
public function __invoke(Request $request, int $leagueId): JsonResponse
{
$leagueEntity = $this->leagueRepository->find($leagueId);
if (is_null($leagueEntity))
{
throw new HttpException(
Response::HTTP_NOT_FOUND,
"Liga no encontrada"
);
}
$leagueDto = new LeagueDto();
$leagueDto->fillFromObject($leagueEntity);
return new JsonResponse(
data: [
'success' => true,
'league' => $leagueDto->toArray()
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,64 @@
<?php
namespace DMD\LaLigaApi\Service\League\joinTeam;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\TeamRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use DMD\LaLigaApi\Service\Common\NotificationFactory;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleCaptainRequest
{
public function __construct(
public AuthorizeRequest $authorizeRequest,
public CustomRoleRepository $customRoleRepository,
public LeagueRepository $leagueRepository,
public TeamRepository $teamRepository,
public NotificationFactory $notificationFactory
){}
public function __invoke(
Request $request,
int $leagueId,
int $teamId
): JsonResponse
{
$leagueToJoinEntity = $this->leagueRepository->find($leagueId);
if (is_null($leagueToJoinEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND, "Liga con id: $leagueId no ha sido encontrada");
}
$requestingUserEntity = $this->authorizeRequest->teamCaptainRequest($leagueId, $teamId);
$userToNotifyEntity = $this->customRoleRepository->findUserByRoleName($leagueId . Role::LEAGUE_PRESIDENT->value);
if (is_null($userToNotifyEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND, "No se ha encontrado presidente de la liga con id $leagueId");
}
$teamToJoinEntity = $this->teamRepository->find($teamId);
if (is_null($teamToJoinEntity))
{
throw new HttpException(Response::HTTP_NOT_FOUND, 'Equipo no encontrado.');
}
$this->notificationFactory->teamCaptainRequest(
$requestingUserEntity,
$userToNotifyEntity,
$request->toArray()['message'],
$leagueToJoinEntity,
$teamId
);
return new JsonResponse(
data: [
'success' => true,
'message' => 'La solicitud ha sido enviada correctamente.'
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,71 @@
<?php
namespace DMD\LaLigaApi\Service\League\newJoinLeagueRequest;
use DMD\LaLigaApi\Dto\NotificationDto;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\Notification;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\TeamRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\Common\NotificationFactory;
use DMD\LaLigaApi\Service\League\LeagueFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
class HandleNewJoinLeagueRequest
{
public function __construct(
public Security $security,
public LeagueRepository $leagueRepository,
public NotificationFactory $notificationFactory,
public MailerInterface $mailer
){}
/**
* @throws TransportExceptionInterface
*/
public function __invoke(
Request $request,
int $leagueId
): JsonResponse
{
$requestingUser = $this->security->getUser();
if (!($requestingUser instanceof User))
{
throw new HttpException(
Response::HTTP_FORBIDDEN,
"Unauthorized.");
}
$leagueToJoin = $this->leagueRepository->find($leagueId);
if (is_null($leagueToJoin))
{
throw new HttpException(
Response::HTTP_NOT_FOUND,
'Liga no encontrada.');
}
$this->notificationFactory->newJoinLeagueRequest(
$requestingUser,
$leagueToJoin,
($request->toArray())['message'] ?? null
);
return new JsonResponse(
data: [
'success' => true,
'message' => 'La solicitud ha sido enviada correctamente.'
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,87 @@
<?php
namespace DMD\LaLigaApi\Service\League\updateLeague;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\League\LeagueFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleUpdateLeague
{
public function __construct(
public LeagueFactory $leagueSaver,
public EntityManagerInterface $entityManager,
public Security $security,
public UserRepository $userRepository,
public LeagueRepository $leagueRepository,
public CustomRoleRepository $customRoleRepository,
){}
public function __invoke(Request $request, int $leagueId): JsonResponse
{
$authorizationResult = $this->checkUserAuthorization($leagueId);
$leagueDto = new LeagueDto();
$leagueDto->fillFromObject($authorizationResult['leagueObj']);
$leagueDto->fillFromArray($request->toArray());
$leagueDto->validate();
if (!empty($leagueDto->validationErrors))
{
return $this->generateErrorResponse($leagueDto->validationErrors);
}
$this->leagueSaver->save($authorizationResult['leagueObj'], $leagueDto);
$this->entityManager->flush();
return new JsonResponse(
data: [
'success' => true,
'league' => $leagueDto->toArray()
],
status: Response::HTTP_OK
);
}
public function generateErrorResponse(array $validationErrors): JsonResponse
{
return new JsonResponse(
data: [
'success' => false,
'error' => $validationErrors
],
status: Response::HTTP_OK
);
}
public function checkUserAuthorization(int $leagueId): array
{
$user = $this->security->getUser();
if (is_null($user))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Unauthorized.");
}
$customRole = $this->customRoleRepository->findBy([
'name' => $leagueId.'_LEAGUE_PRESIDENT',
'user' => $user
]);
if (is_null($customRole))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Usuario no tiene permiso para editar la liga.");
}
$leagueObj = $this->leagueRepository->find($leagueId);
if (is_null($leagueObj))
{
throw new HttpException(Response::HTTP_NOT_FOUND, "Liga con id: ". $leagueId .' no ha sido encontrada.');
}
return [
'leagueObj' => $leagueObj,
'userObj' => $user
];
}
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace DMD\LaLigaApi\Service\Season;
use DMD\LaLigaApi\Dto\SeasonDto;
use DMD\LaLigaApi\Entity\Season;
class SeasonFactory
{
public static function create(SeasonDto $seasonDto): Season
{
$seasonEntity = new Season();
$seasonEntity->setActive(true);
if (!empty($seasonDto->dateStart))
{
$seasonEntity->setDateStart($seasonDto->dateStart);
}
return $seasonEntity;
}
}
@@ -0,0 +1,60 @@
<?php
namespace DMD\LaLigaApi\Service\Season\addTeam;
use DMD\LaLigaApi\Dto\TeamDto;
use DMD\LaLigaApi\Exception\ValidationException;
use DMD\LaLigaApi\Repository\SeasonRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use DMD\LaLigaApi\Service\Common\TeamFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleAddTeam
{
public function __construct(
public AuthorizeRequest $authorizeRequest,
public TeamFactory $teamFactory,
public EntityManagerInterface $entityManager,
public SeasonRepository $seasonRepository
){}
/**
* @throws ValidationException
*/
public function __invoke(
Request $request,
int $leagueId,
int $seasonId
): JsonResponse
{
$this->authorizeRequest->authorizeLeaguePresident($leagueId);
$seasonEntity = $this->seasonRepository->find($seasonId);
if (is_null($seasonEntity))
{
throw new HttpException(
Response::HTTP_NOT_FOUND,
'Temporada con ID: '. $seasonId .' no ha sido encontrada.'
);
}
$teamDto = new TeamDto();
$teamDto->fillFromArray($request->toArray());
$teamDto->validate();
$teamEntity = $this->teamFactory::create($teamDto);
$teamEntity->addSeason($seasonEntity);
$this->entityManager->persist($teamEntity);
$this->entityManager->flush();
$teamDto->id = $teamEntity->getId();
return new JsonResponse(
data: [
'success' => true,
'team' => $teamDto->toArray()
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,260 @@
<?php
namespace DMD\LaLigaApi\Service\Season\createGameCalendar;
use DMD\LaLigaApi\Dto\GameDto;
use DMD\LaLigaApi\Dto\TeamDto;
use DMD\LaLigaApi\Entity\Game;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\Season;
use DMD\LaLigaApi\Entity\Team;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Exception\ValidationException;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Repository\SeasonRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Security\Core\User\UserInterface;
class HandleCreateGameCalendarRequest
{
public function __construct(
public AuthorizeRequest $authorizeRequest,
public Security $security,
public LeagueRepository $leagueRepository,
public SeasonRepository $seasonRepository
)
{
}
/**
* @throws ValidationException
* @throws \Exception
*/
public function __invoke(Request $request, int $leagueId, int $seasonId): JsonResponse
{
$this->authorizeRequest->authorizeLeaguePresident($leagueId);
$leaguePresidentEntity = $this->security->getUser();
$leagueEntity = $this->leagueRepository->find($leagueId);
$seasonEntity = $this->seasonRepository->findOneBy([
'active' => true,
'id' => $seasonId,
'league' => $leagueEntity
]);
$this->validateEntities($leaguePresidentEntity, $leagueEntity, $leagueId, $seasonEntity);
$teamEntityList = ($seasonEntity->getTeams())->toArray();
$requestArray = $request->toArray();
$numberOfTeams = count($teamEntityList);
$numberOfWeeks = (2 * ($numberOfTeams * ($numberOfTeams - 1))) / $requestArray['gamesPerWeek'];
$fromDate = new \DateTime($requestArray['fromDate'], new \DateTimeZone('Europe/Madrid'));
$fromDate = match($fromDate->format('l')){
'Saturday', 'Sunday' => $fromDate->modify('next monday'),
default => $fromDate
};
$totalWeeks = $this->weeksBetweenTwoDates(
new \DateTime($request->toArray()['fromDate'], new \DateTimeZone('Europe/Madrid')),
new \DateTime($request->toArray()['toDate'], new \DateTimeZone('Europe/Madrid'))
);
$currentWeek = 1;
$currentGame = 1;
$totalGames = (count($teamEntityList) * ((count($teamEntityList) - 1)) / 2) * ($request->toArray()['gamesBetweenTeams'] ?? 2); //todo con esto puedes validar si el rango de fecha es suficiente para que se jueguen todos los juegos
$calendarInWeeks = [];
$gameDtoList = [];
$firstDayOfWeek = new \DateTime($request->toArray()['fromDate']);
$lastDayOfWeek = (clone $firstDayOfWeek)->modify('+7 days'); //todo forzar o dar la opcion de que la semana siguiente empiece el lunes
while ($currentWeek <= $totalWeeks)
{
$gamesForCurrentWeekList = [];
for ($i = 0; $i < $request->toArray()['gamesPerWeek']; $i++)
{
$gameEntity = $this->generateCalendar(
$teamEntityList->toArray(),
$currentGame,
$request->toArray()['unavailableLeagueDays'],
$request->toArray()['specificDatesNotAvailable']
);
$gamesForCurrentWeekList[] = $gameEntity;
$currentGame++;
}
$calendar[$currentWeek] = $gamesForCurrentWeekList;
$currentWeek++;
}
foreach ($calendar as $gamesForWeekList)
{
foreach ($gamesForWeekList as $gameEntity)
{
$gameDto = new GameDto();
$gameDto->fillFromObject($gameEntity);
$gameDtoList[] = $gameDto->toArray();
}
}
return new JsonResponse([
'success' => true,
'games' => $gameDtoList
]);
}
public function validateEntities(?UserInterface $leaguePresidentEntity, ?League $leagueEntity, int $leagueId, ?Season $seasonEntity): void
{
if (!($leaguePresidentEntity instanceof User))
{
throw new HttpException(Response::HTTP_UNAUTHORIZED, 'Forbidden');
}
if (!($leagueEntity instanceof League))
{
throw new HttpException(Response::HTTP_UNAUTHORIZED, "Liga con ID $leagueId no ha sido encontrada");
}
if (!($seasonEntity instanceof Season))
{
throw new HttpException(Response::HTTP_UNAUTHORIZED, "La liga no tiene temporadas activas");
}
}
/**
* @throws ValidationException
*/
public function weeksBetweenTwoDates(\DateTime $fromDate, \DateTime $toDate): float
{
if ($fromDate > $toDate)
{
$toDateString = $toDate->format('Y-m-d');
$fromDateString = $fromDate->format('Y-m-d');
throw new ValidationException(["$toDateString no puede ser anterior a $fromDateString"]);
}
return floor($fromDate->diff($toDate)->days/7);
}
public function generateCalendar(array $teamEntityArray, array $daysNotAvailable, array $specificDatesNotAvailable, int $totalGames): Game
{
$gameDtoList = [];
//generar los posibles juegos
/**
* @var Team $awayTeamEntity
* @var Team $homeTeamEntity
*/
foreach ($teamEntityArray as $homeTeamEntity)
{
foreach ($teamEntityArray as $awayTeamEntity)
{
if ($homeTeamEntity->getId() !== $awayTeamEntity->getId())
{
$gameDtoList[$homeTeamEntity->getName().':'. $awayTeamEntity->getName()] = $this->createGameDto(
homeTeamEntity: $homeTeamEntity,
awayTeamEntity: $awayTeamEntity
);
$gameDtoList[$awayTeamEntity->getName().':'. $homeTeamEntity->getName()] = $this->createGameDto(
homeTeamEntity: $awayTeamEntity,
awayTeamEntity: $homeTeamEntity
);
if (count($gameDtoList) == $totalGames)
{
break;
}
}
}
}
//asumiendo que tengo un juego por semana por cada equipo y 3 juegos, dame todas las posibles fechas
//puedes tener un from date o tomas hoy de fecha de partida,
if (empty($requestArray['fromDate']))
{
$fromDate = new \DateTimeImmutable('now', new \DateTimeZone('Europe/Madrid'));
}
else
{
$fromDate = \DateTimeImmutable::createFromFormat('Y-m-d', $requestArray['fromDate'], new \DateTimeZone('Europe/Madrid'));
}
// $totalGames = count($gameDtoList);
// $totalWeeks = $totalGames/$requestArray['gamesPerWeek'];
// $toDate = $fromDate->modify("+$totalWeeks weeks");
// return $game;
}
private function createGameDto(Team $homeTeamEntity, Team $awayTeamEntity): GameDto
{
$gameDto = new GameDto();
$homeTeamDto = new TeamDto();
$homeTeamDto->fillFromObject($homeTeamEntity);
$gameDto->homeTeamDto = $homeTeamDto;
$awayTeamDto = new TeamDto();
$awayTeamDto->fillFromObject($awayTeamEntity);
$gameDto->awayTeamDto = $awayTeamDto;
return $gameDto;
}
private function generateWeeklyRanges($fromDate, $toDate)
{
$start = new \DateTime($fromDate);
$end = new \DateTime($toDate);
$ranges = [];
// If the start date is not a Monday, adjust it to the next Monday
if ($start->format('N') != 1) {
$start->modify('next Monday');
}
while ($start <= $end) {
$endOfWeek = clone $start;
$endOfWeek->modify('next Sunday');
// Ensure the end of the week does not exceed the end date
if ($endOfWeek > $end) {
$endOfWeek = clone $end;
}
$ranges[] = [
'start' => $start->format('Y-m-d'),
'end' => $endOfWeek->format('Y-m-d')
];
// Move to the next Monday
$start->modify('next Monday');
}
return $ranges;
}
function generatePossibleDates($games, $restrictions)
{
global $gamesByDate;
foreach ($games as $game) {
$team1 = $game[0];
$team2 = $game[1];
// Generate dates for the next 4 weeks
for ($week = 0; $week < 4; $week++) {
for ($day = 0; $day < 7; $day++) {
$date = new \DateTime();
$date->modify("+$week weeks");
$date->modify("+$day days");
// Check if the day is off for either team
if (in_array($date->format('l'), $restrictions['daysOff'])) {
continue;
}
// Check if the date is a specific date off for either team
if (in_array($date->format('Y-m-d'), $restrictions['specificDatesOff'])) {
continue;
}
// Check if the team has reached the maximum games per week
$dateStr = $date->format('Y-m-d');
if (isset($gamesByDate[$dateStr])) {
$gameCount = count($gamesByDate[$dateStr]);
if ($gameCount >= $restrictions['gamesPerWeek']) {
continue;
}
}
// Add the game to the list of possible dates for the date
$gamesByDate[$dateStr][] = [$team1, $team2];
}
}
}
}
}
@@ -0,0 +1,60 @@
<?php
namespace DMD\LaLigaApi\Service\Season\createSeason;
use DMD\LaLigaApi\Dto\SeasonDto;
use DMD\LaLigaApi\Exception\ValidationException;
use DMD\LaLigaApi\Repository\LeagueRepository;
use DMD\LaLigaApi\Service\Common\AuthorizeRequest;
use DMD\LaLigaApi\Service\Common\TeamFactory;
use DMD\LaLigaApi\Service\Season\SeasonFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HandleCreateSeason
{
public function __construct(
public SeasonFactory $seasonFactory,
public TeamFactory $teamFactory,
public AuthorizeRequest $authorizeRequest,
public LeagueRepository $leagueRepository,
public EntityManagerInterface $entityManager,
){}
/**
* @throws ValidationException
*/
public function __invoke(Request $request, int $leagueId): JsonResponse
{
$this->authorizeRequest->authorizeLeaguePresident($leagueId);
$leagueEntity = $this->leagueRepository->find($leagueId);
$seasonDto = new SeasonDto();
$seasonDto->fillFromArray($request->toArray());
$seasonDto->validate();
$seasonEntity = $this->seasonFactory::create($seasonDto);
$seasonEntity->setLeague($leagueEntity);
if (!empty($seasonDto->teamDtoList))
{
foreach ($seasonDto->teamDtoList as $teamDto)
{
$teamEntity = $this->teamFactory::create($teamDto);
$this->entityManager->persist($teamEntity);
}
}
$this->entityManager->persist($seasonEntity);
$this->entityManager->flush();
$seasonDto->id = $seasonEntity->getId();
return new JsonResponse(
data: [
'success' => true,
'season' => $seasonDto->toArray()
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,47 @@
<?php
namespace DMD\LaLigaApi\Service\Season\getAllSeasons;
use DMD\LaLigaApi\Dto\SeasonDto;
use DMD\LaLigaApi\Repository\SeasonRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HandleGetAllSeason
{
public const PAGE_SIZE = 10;
public function __construct(
public EntityManagerInterface $entityManager,
public SeasonRepository $seasonRepository,
){}
public function __invoke(Request $request, int $page): JsonResponse
{
$seasonCollection = $this->seasonRepository->findBy([
'active' => true
],
limit: 10,
offset: ($page * self::PAGE_SIZE) - self::PAGE_SIZE
);
$seasonArray = [];
if (!is_null($seasonCollection))
{
foreach ($seasonCollection as $seasonObj)
{
$seasonDto = new SeasonDto();
$seasonDto->fillFromObject($seasonObj);
$seasonArray[] = $seasonDto->toArray();
}
}
return new JsonResponse(
data: [
'success' => true,
'seasons' => $seasonArray
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,44 @@
<?php
namespace DMD\LaLigaApi\Service\Season\getSeasonById;
use DMD\LaLigaApi\Dto\LeagueDto;
use DMD\LaLigaApi\Dto\SeasonDto;
use DMD\LaLigaApi\Repository\SeasonRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\League\LeagueFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleGetSeasonById
{
public function __construct(
public EntityManagerInterface $entityManager,
public SeasonRepository $seasonRepository,
){}
public function __invoke(Request $request, int $seasonId): JsonResponse
{
$seasonObj = $this->seasonRepository->find($seasonId);
if (is_null($seasonObj))
{
throw new HttpException(
Response::HTTP_NOT_FOUND,
"Temporada no encontrada."
);
}
$seasonDto = new SeasonDto();
$seasonDto->fillFromObject($seasonObj);
return new JsonResponse(
data: [
'success' => true,
'season' => $seasonDto->toArray()
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,85 @@
<?php
namespace DMD\LaLigaApi\Service\Season\updateSeason;
use DMD\LaLigaApi\Dto\SeasonDto;
use DMD\LaLigaApi\Entity\Season;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\SeasonRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\Season\SeasonFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HandleUpdateSeason
{
public function __construct(
public SeasonFactory $seasonSaver,
public EntityManagerInterface $entityManager,
public Security $security,
public SeasonRepository $seasonRepository,
public CustomRoleRepository $customRoleRepository,
public UserRepository $userRepository
){}
public function __invoke(Request $request, int $leagueId, int $seasonId): JsonResponse
{
$seasonObj = $this->checkUserAuthorization($leagueId, $seasonId);
$seasonDto = new SeasonDto();
$seasonDto->fillFromObject($seasonObj);
$seasonDto->fillFromArray($request->toArray());
$seasonDto->validate();
if (!empty($seasonDto->validationErrors))
{
return $this->generateErrorResponse($seasonDto->validationErrors);
}
$seasonObj->setActive(true);
$this->seasonSaver->save($seasonObj, $seasonDto);
$this->entityManager->flush();
return new JsonResponse(
data: [
'success' => true,
'season' => $seasonDto->toArray()
],
status: Response::HTTP_OK
);
}
public function generateErrorResponse(array $validationErrors): JsonResponse
{
return new JsonResponse(
data: [
'success' => false,
'errors' => $validationErrors
],
status: Response::HTTP_OK
);
}
public function checkUserAuthorization(int $leagueId, int $seasonId): Season
{
$user = $this->security->getUser();
if (is_null($user))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Usuario no encontrado.");
}
$customRole = $this->customRoleRepository->findBy([
'name' => $leagueId.'_LEAGUE_PRESIDENT',
'user' => $user
]);
if (is_null($customRole))
{
throw new HttpException(Response::HTTP_FORBIDDEN, "Usuario no tiene permiso para editar la liga.");
}
$seasonObj = $this->seasonRepository->find($seasonId);
if (is_null($seasonObj))
{
throw new HttpException(Response::HTTP_NOT_FOUND, 'Temporada no encontrada.');
}
return $seasonObj;
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserSaver
{
public function __construct(
public EntityManagerInterface $entityManager,
public UserPasswordHasherInterface $passwordHasher,
)
{}
public function save(User $user, UserDto $userDto): User
{
if (!empty($userDto->email))
{
$user->setEmail($userDto->email);
}
if (!empty($userDto->password))
{
$hashedPassword = $this->passwordHasher->hashPassword($user, $userDto->password);
$user->setPassword($hashedPassword);
}
if (!empty($userDto->firstName))
{
$user->setFirstName($userDto->firstName);
}
if (!empty($userDto->lastName))
{
$user->setLastName($userDto->firstName);
}
if (!empty($userDto->birthday))
{
$user->setBirthday($userDto->birthday);
}
if (!empty($userDto->phone))
{
$user->setPhone($userDto->phone);
}
if (!empty($userDto->profilePicture))
{
$user->setProfilePicture($userDto->profilePicture);
}
$this->entityManager->persist($user);
return $user;
}
}
@@ -0,0 +1,43 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers\delete;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\User\Handlers\UserSaver;
use Doctrine\ORM\EntityManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class HandleDeleteUser
{
public function __construct(
public EntityManagerInterface $entityManager,
public UserRepository $userRepository,
){}
public function __invoke(Request $request): JsonResponse
{
$requestArray = $request->toArray();
$existingUser = $this->userRepository->findOneBy(['email'=> $requestArray['email']]);
if (!is_null($existingUser))
{
throw new HttpException(400,'Ya hay un usuario registrado con este correo.');
}
$this->entityManager->remove((object)$existingUser);
$this->entityManager->flush();
$this->entityManager->clear();
return new JsonResponse(
data: [
'success' => true,
'message' => 'Usuario eliminado.'
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,75 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers\getNotifications;
use DMD\LaLigaApi\Dto\NotificationDto;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Repository\NotificationRepository;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\User\Handlers\UserSaver;
use Doctrine\ORM\EntityManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class HandleGetNotifications
{
public function __construct(
public EntityManagerInterface $entityManager,
public NotificationRepository $notificationRepository,
public Security $security
){}
public function __invoke(): JsonResponse
{
$user = $this->security->getUser();
$notifications = $this->notificationRepository->findBy(
criteria: [
'userToNotify' => $user
],
orderBy: [
'createdAt' => 'DESC'
]
);
if (empty($notifications))
{
return new JsonResponse([
'success' => true,
'notifications' => []
], Response::HTTP_OK);
}
$notificationDtoList = [];
foreach ($notifications as $notificationObj)
{
if (
($notificationObj->isIsRead()) &&
(($notificationObj->getReadAt())->diff(new \DateTime('now'))->days > 30)
)
{
$this->entityManager->remove($notificationObj);
continue;
}
if (!$notificationObj->isIsRead())
{
$notificationObj->setIsRead(true);
$notificationObj->setReadAt(new \DateTimeImmutable('now'));
$this->entityManager->persist($notificationObj);
}
$notificationDto = new NotificationDto();
$notificationDtoList[] = ($notificationDto->fillFromObj($notificationObj))->toArray();
}
$this->entityManager->flush();
return new JsonResponse(
data: [
'success' => true,
'notifications' => $notificationDtoList
],
status: Response::HTTP_OK
);
}
}
@@ -0,0 +1,42 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers\login;
use DMD\LaLigaApi\Dto\NotificationDto;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Entity\User;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Security\Core\User\UserInterface;
class AuthenticationSuccessListener
{
public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event): void
{
$data = $event->getData();
$userDto = new UserDto();
$user = $event->getUser();
if (!$user instanceof User)
{
throw new HttpException(500, 'Internal server error');
}
$notificationEntityList = $user->getReceivedNotifications(); // todo hacer query de notificaciones no leidas
$notificationDtoList = [];
if (!empty($notificationEntityList))
{
foreach ($notificationEntityList as $notificationEntity)
{
$notificationDto = new NotificationDto();
$notificationDto->fillFromObj($notificationEntity);
$notificationDtoList[] = $notificationDto;
}
}
$userDto->notificationDtoList = $notificationDtoList;
$userDto->fillFromObject($user);
$expirationDateTime = (new \DateTime('now', new \DateTimeZone('Europe/Madrid')))->modify('+1800 seconds');
$data['expirationDateTime'] = $expirationDateTime->format('Y-m-d H:i:s');
$data['user'] = $userDto->toArray();
$event->setData($data);
}
}
@@ -0,0 +1,74 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers\register;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\User\Handlers\UserSaver;
use Doctrine\ORM\EntityManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class HandleRegistration
{
public function __construct(
public EntityManagerInterface $entityManager,
public UserSaver $userSaver,
public UserRepository $userRepository,
public JWTTokenManagerInterface $tokenManager,
public ValidatorInterface $validator
){}
public function __invoke(Request $request): JsonResponse
{
$requestArray = $request->toArray();
$existingUser = $this->userRepository->findOneBy([
'email'=> $requestArray['email']
]);
if (!is_null($existingUser))
{
throw new HttpException(400,'Ya hay un usuario registrado con este correo.');
}
$userDto = new UserDto();
$userDto->fillFromArray($requestArray);
$userDto->validate();
if (!empty($userDto->validationErrors))
{
return $this->generateErrorResponse($userDto->validationErrors);
}
$userDto->active = true;
$newUser = new User();
$newUser->setRoles(['ROLE_USER']);
$newUser = $this->userSaver->save($newUser, $userDto);
$this->entityManager->flush();
$this->entityManager->clear();
$userDto->id = $newUser->getId();
$token = $this->tokenManager->create($newUser);
return new JsonResponse(
data: [
'success' => true,
'message' => 'Usuario creado.',
'token' => $token,
'user' => $userDto->toArray(),
],
status: Response::HTTP_OK
);
}
public function generateErrorResponse(array $validationErrors): JsonResponse
{
return new JsonResponse(
data: [
'success' => false,
'errors' => $validationErrors
],
status: Response::HTTP_BAD_REQUEST
);
}
}
@@ -0,0 +1,72 @@
<?php
namespace DMD\LaLigaApi\Service\User\Handlers\update;
use DMD\LaLigaApi\Dto\UserDto;
use DMD\LaLigaApi\Repository\UserRepository;
use DMD\LaLigaApi\Service\User\Handlers\UserSaver;
use Doctrine\ORM\EntityManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class HandleUpdateUser
{
public function __construct(
public EntityManagerInterface $entityManager,
public Security $security,
public UserSaver $userSaver,
public UserRepository $userRepository,
public JWTTokenManagerInterface $tokenManager,
public ValidatorInterface $validator
){}
public function __invoke(Request $request): JsonResponse
{
$requestArray = $request->toArray();
$requestUserEmail = $this->security->getUser()?->getUserIdentifier();
$requestUserObj = $this->userRepository->findOneBy([
'email' => $requestUserEmail
]);
if (is_null($requestUserObj))
{
throw new HttpException(500, 'Usuario no encontrado.');
}
$userDto = new UserDto();
$userDto->fillFromObject($requestUserObj);
$userDto->fillFromArray($requestArray);
$userDto->validate();
if (!empty($userDto->validationErrors))
{
$this->generateErrorResponse($userDto->validationErrors);
}
$editedUserObj = $this->userSaver->save($requestUserObj, $userDto);
$this->entityManager->flush();
$this->entityManager->clear();
$userDto->id = $editedUserObj->getId();
return new JsonResponse(
data: [
'success' => true,
'message' => 'Usuario editado.',
'user' => $userDto->toArray(),
],
status: Response::HTTP_OK
);
}
public function generateErrorResponse(array $validationErrors): JsonResponse
{
return new JsonResponse(
data: [
'success' => false,
'errors' => $validationErrors
],
status: Response::HTTP_OK
);
}
}