implement user stars feature

This commit is contained in:
ghost 2023-10-09 16:07:28 +03:00
parent d97a678952
commit 0a218cfd3a
5 changed files with 288 additions and 26 deletions

View file

@ -3,6 +3,8 @@
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
@ -56,7 +58,7 @@ class UserController extends AbstractController
continue;
}
$activityUser = $userService->get(
$activityUser = $userService->getUser(
$activity->getUserId()
);
@ -168,7 +170,7 @@ class UserController extends AbstractController
}
#[Route(
'/{_locale}/user/{id}',
'/{_locale}/user/{userId}',
name: 'user_info',
defaults: [
'_locale' => '%app.locale%'
@ -178,12 +180,25 @@ class UserController extends AbstractController
],
)]
public function info(
int $id,
Request $request,
TranslatorInterface $translator,
UserService $userService): Response
{
// Init user
if (!$user = $userService->get($id))
$user = $userService->init(
$request->getClientIp()
);
if (!$user->isStatus())
{
// @TODO
throw new \Exception(
$translator->trans('Access denied')
);
}
// Init target user
if (!$userTarget = $userService->getUser($request->get('userId')))
{
throw $this->createNotFoundException();
}
@ -193,23 +208,87 @@ class UserController extends AbstractController
'default/user/info.html.twig',
[
'user' => [
'id' => $user->getId(),
'address' => $request->getClientIp() == $user->getAddress() ? $user->getAddress() : false,
'moderator' => $user->isModerator(),
'approved' => $user->isApproved(),
'status' => $user->isStatus(),
'locale' => $user->getLocale(),
'locales' => $user->getLocales(),
'added' => $user->getAdded(),
'id' => $userTarget->getId(),
'address' => $request->getClientIp() == $userTarget->getAddress() ? $userTarget->getAddress() : false,
'moderator' => $userTarget->isModerator(),
'approved' => $userTarget->isApproved(),
'status' => $userTarget->isStatus(),
'locale' => $userTarget->getLocale(),
'locales' => $userTarget->getLocales(),
'added' => $userTarget->getAdded(),
'identicon' => $userService->identicon(
$user->getAddress(),
$userTarget->getAddress(),
48
),
'star' =>
[
'exist' => (bool) $userService->findUserStar(
$user->getId(),
$userTarget->getId()
),
'total' => $userService->findUserStarsTotalByUserIdTarget(
$userTarget->getId()
)
],
]
]
);
}
#[Route(
'/{_locale}/user/star/toggle/{userId}',
name: 'user_star_toggle',
requirements:
[
'userId' => '\d+',
],
methods:
[
'GET'
]
)]
public function toggleStar(
Request $request,
TranslatorInterface $translator,
UserService $userService
): Response
{
// Init user
$user = $userService->init(
$request->getClientIp()
);
if (!$user->isStatus())
{
// @TODO
throw new \Exception(
$translator->trans('Access denied')
);
}
// Init target user
if (!$userTarget = $userService->getUser($request->get('userId')))
{
throw $this->createNotFoundException();
}
// Update
$userService->toggleUserStar(
$user->getId(),
$userTarget->getId(),
time()
);
// Redirect to info page created
return $this->redirectToRoute(
'user_info',
[
'_locale' => $request->get('_locale'),
'userId' => $userTarget->getId()
]
);
}
public function module(string $route = ''): Response
{
return $this->render(

65
src/Entity/UserStar.php Normal file
View file

@ -0,0 +1,65 @@
<?php
namespace App\Entity;
use App\Repository\UserStarRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserStarRepository::class)]
class UserStar
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column]
private ?int $userId = null;
#[ORM\Column]
private ?int $userIdTarget = null;
#[ORM\Column]
private ?int $added = null;
public function getId(): ?int
{
return $this->id;
}
public function getUserId(): ?int
{
return $this->userId;
}
public function setUserId(int $userId): static
{
$this->userId = $userId;
return $this;
}
public function getUserIdTarget(): ?int
{
return $this->userIdTarget;
}
public function setUserIdTarget(int $userIdTarget): static
{
$this->userIdTarget = $userIdTarget;
return $this;
}
public function getAdded(): ?int
{
return $this->added;
}
public function setAdded(int $added): static
{
$this->added = $added;
return $this;
}
}

View file

@ -0,0 +1,52 @@
<?php
namespace App\Repository;
use App\Entity\UserStar;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<UserStar>
*
* @method UserStar|null find($id, $lockMode = null, $lockVersion = null)
* @method UserStar|null findOneBy(array $criteria, array $orderBy = null)
* @method UserStar[] findAll()
* @method UserStar[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserStarRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, UserStar::class);
}
public function findUserStar(
int $userId,
int $userIdTarget
): ?UserStar
{
return $this->createQueryBuilder('us')
->where('us.userId = :userId')
->andWhere('us.userIdTarget = :userIdTarget')
->setParameter('userId', $userId)
->setParameter('userIdTarget', $userIdTarget)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult()
;
}
public function findUserStarsTotalByUserIdTarget(
int $userIdTarget
): int
{
return $this->createQueryBuilder('us')
->select('count(us.userId)')
->where('us.userIdTarget = :userIdTarget')
->setParameter('userIdTarget', $userIdTarget)
->getQuery()
->getSingleScalarResult()
;
}
}

View file

@ -3,6 +3,7 @@
namespace App\Service;
use App\Entity\User;
use App\Entity\UserStar;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
@ -10,24 +11,24 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class UserService
{
private EntityManagerInterface $entityManager;
private UserRepository $userRepository;
private EntityManagerInterface $entityManagerInterface;
private ParameterBagInterface $parameterBagInterface;
public function __construct(
EntityManagerInterface $entityManager,
EntityManagerInterface $entityManagerInterface,
ParameterBagInterface $parameterBagInterface
)
{
$this->entityManager = $entityManager;
$this->userRepository = $entityManager->getRepository(User::class);
$this->entityManagerInterface = $entityManagerInterface;
$this->parameterBagInterface = $parameterBagInterface;
}
public function init(string $address): User
{
// Return existing user
if ($result = $this->userRepository->findOneByAddressField($address))
if ($result = $this->entityManagerInterface
->getRepository(User::class)
->findOneByAddressField($address))
{
return $result;
}
@ -61,9 +62,11 @@ class UserService
return $user;
}
public function get(int $id): ?User
public function getUser(int $userId): ?User
{
return $this->userRepository->getUser($id);
return $this->entityManagerInterface
->getRepository(User::class)
->getUser($userId);
}
public function identicon(
@ -86,9 +89,52 @@ class UserService
return $identicon->getImageDataUri($format);
}
public function save(User $user) : void
public function save(User $user) : void // @TODO delete
{
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->entityManagerInterface->persist($user);
$this->entityManagerInterface->flush();
}
// User star
public function findUserStar(
int $userId,
int $userIdTarget
): ?UserStar
{
return $this->entityManagerInterface
->getRepository(UserStar::class)
->findUserStar($userId, $userIdTarget);
}
public function findUserStarsTotalByUserIdTarget(int $torrentId): int
{
return $this->entityManagerInterface
->getRepository(UserStar::class)
->findUserStarsTotalByUserIdTarget($torrentId);
}
public function toggleUserStar(
int $userId,
int $userIdTarget,
int $added
): void
{
if ($userStar = $this->findUserStar($userId, $userIdTarget))
{
$this->entityManagerInterface->remove($userStar);
$this->entityManagerInterface->flush();
}
else
{
$userStar = new UserStar();
$userStar->setUserId($userId);
$userStar->setUserIdTarget($userIdTarget);
$userStar->setAdded($added);
$this->entityManagerInterface->persist($userStar);
$this->entityManagerInterface->flush();
}
}
}