127 lines
4.8 KiB
PHP
127 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Entity\User;
|
|
use App\Form\ProfileFormType;
|
|
use App\Repository\ReviewRepository;
|
|
use App\Service\UploadStorage;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Form\FormError;
|
|
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
/**
|
|
* AccountController hosts authenticated self-service pages.
|
|
*/
|
|
#[IsGranted('ROLE_USER')]
|
|
class AccountController extends AbstractController
|
|
{
|
|
/**
|
|
* Summarizes the signed-in user's recent activity.
|
|
*/
|
|
#[Route('/dashboard', name: 'account_dashboard', methods: ['GET'])]
|
|
public function dashboard(ReviewRepository $reviews): Response
|
|
{
|
|
/** @var User $user */
|
|
$user = $this->getUser();
|
|
|
|
$reviewCount = (int) $reviews->createQueryBuilder('r')
|
|
->select('COUNT(r.id)')
|
|
->where('r.author = :u')->setParameter('u', $user)
|
|
->getQuery()->getSingleScalarResult();
|
|
$albumCount = (int) $reviews->createQueryBuilder('r')
|
|
->select('COUNT(DISTINCT a.id)')
|
|
->innerJoin('r.album', 'a')
|
|
->where('r.author = :u')->setParameter('u', $user)
|
|
->getQuery()->getSingleScalarResult();
|
|
if ($this->isGranted('ROLE_ADMIN')) {
|
|
$userType = 'Admin';
|
|
} elseif ($this->isGranted('ROLE_MODERATOR')) {
|
|
$userType = 'Moderator';
|
|
} else {
|
|
$userType = 'User';
|
|
}
|
|
$userReviews = $reviews->createQueryBuilder('r')
|
|
->where('r.author = :u')->setParameter('u', $user)
|
|
->orderBy('r.createdAt', 'DESC')
|
|
->setMaxResults(10)
|
|
->getQuery()->getResult();
|
|
$userAlbums = $reviews->createQueryBuilder('r')
|
|
->select('DISTINCT a')
|
|
->innerJoin('r.album', 'a')
|
|
->where('r.author = :u')->setParameter('u', $user)
|
|
->orderBy('r.createdAt', 'DESC')
|
|
->setMaxResults(10)
|
|
->getQuery()->getResult();
|
|
|
|
return $this->render('account/dashboard.html.twig', [
|
|
'email' => $user->getEmail(),
|
|
'displayName' => $user->getDisplayName(),
|
|
'profileImage' => $user->getProfileImagePath(),
|
|
'reviewCount' => $reviewCount,
|
|
'albumCount' => $albumCount,
|
|
'userType' => $userType,
|
|
'userReviews' => $userReviews,
|
|
'userAlbums' => $userAlbums,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Allows users to update profile details and avatar.
|
|
*/
|
|
#[Route('/account/profile', name: 'account_profile', methods: ['GET', 'POST'])]
|
|
public function profile(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $hasher, UploadStorage $uploadStorage): Response
|
|
{
|
|
/** @var User $user */
|
|
$user = $this->getUser();
|
|
$form = $this->createForm(ProfileFormType::class, $user);
|
|
$form->handleRequest($request);
|
|
|
|
if ($form->isSubmitted()) {
|
|
$newPassword = (string) $form->get('newPassword')->getData();
|
|
if ($newPassword !== '') {
|
|
$current = (string) $form->get('currentPassword')->getData();
|
|
if ($current === '' || !$hasher->isPasswordValid($user, $current)) {
|
|
$form->get('currentPassword')->addError(new FormError('Current password is incorrect.'));
|
|
} else {
|
|
// Allow password updates inside the same form submission instead of forcing a separate flow.
|
|
$user->setPassword($hasher->hashPassword($user, $newPassword));
|
|
}
|
|
}
|
|
|
|
if ($form->isValid()) {
|
|
$upload = $form->get('profileImage')->getData();
|
|
if ($upload instanceof UploadedFile) {
|
|
$uploadStorage->remove($user->getProfileImagePath());
|
|
$user->setProfileImagePath($uploadStorage->storeProfileImage($upload));
|
|
}
|
|
|
|
$em->flush();
|
|
$this->addFlash('success', 'Profile updated.');
|
|
return $this->redirectToRoute('account_profile');
|
|
}
|
|
}
|
|
|
|
return $this->render('account/profile.html.twig', [
|
|
'form' => $form->createView(),
|
|
'profileImage' => $user->getProfileImagePath(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Shows account-level settings options.
|
|
*/
|
|
#[Route('/settings', name: 'account_settings', methods: ['GET'])]
|
|
public function settings(): Response
|
|
{
|
|
return $this->render('account/settings.html.twig');
|
|
}
|
|
}
|
|
|