implement profile page #17

This commit is contained in:
ghost 2023-10-03 22:35:13 +03:00
parent 737b79b608
commit ae8ec4823a
21 changed files with 740 additions and 364 deletions

View file

@ -0,0 +1,33 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class DashboardController extends AbstractController
{
#[Route('/')]
public function indexNoLocale(): Response
{
return $this->redirectToRoute(
'dashboard_index',
[
'_locale' => 'en'
]
);
}
#[Route(
'/{_locale}',
name: 'dashboard_index'
)]
public function index(Request $request): Response
{
return $this->render(
'default/dashboard/index.html.twig'
);
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class HomeController extends AbstractController
{
#[Route(
'/{_locale}/',
name: 'home_index'
)]
public function index(Request $request): Response
{
return $this->render('default/home/index.html.twig');
}
}

View file

@ -15,6 +15,11 @@ class PageController extends AbstractController
)]
public function submit(): Response
{
/*
return $this->redirectToRoute('page', [
'id' => $page->getId()
]);
*/
return $this->render('default/page/submit.html.twig', [
// @TODO
]);

View file

@ -1,76 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use App\Service\User;
class ProfileController extends AbstractController
{
#[Route(
'/{_locale}/profile',
name: 'profile_index'
)]
public function index(Request $request, User $user): Response
{
return $this->render(
'default/profile/index.html.twig',
[
'user' => $user->init($request->getClientIp())
]
);
}
#[Route(
'/{_locale}/profile/setting',
name: 'profile_setting'
)]
public function setting(): Response
{
// @TODO
return $this->render(
'default/profile/setting.html.twig'
);
}
public function module(string $route = ''): Response
{
return $this->render(
'default/profile/module.html.twig',
[
'route' => $route,
'stars' => 0,
'views' => 0,
'comments' => 0,
'downloads' => 0,
'editions' => 0,
'identicon' => $this->_getIdenticon(
'@TODO',
17,
[
'backgroundColor' => 'rgba(255, 255, 255, 0)',
]
)
]
);
}
private function _getIdenticon(
mixed $id,
int $size,
array $style,
string $format = 'webp') : string
{
$identicon = new \Jdenticon\Identicon();
$identicon->setValue($id);
$identicon->setSize($size);
$identicon->setStyle($style);
return $identicon->getImageDataUri($format);
}
}

View file

@ -0,0 +1,161 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use App\Service\UserService;
use App\Service\TimeService;
class UserController extends AbstractController
{
#[Route(
'/{_locale}/profile',
name: 'user_profile',
defaults: [
'_locale' => '%app.locale%'
],
requirements: [
'_locale' => '%app.locales%',
],
)]
public function profile(
Request $request,
UserService $userService,
TimeService $timeService): Response
{
// Init user
$user = $userService->init(
$request->getClientIp()
);
// Process post request
if ($request->isMethod('post'))
{
// Update locale
if (in_array($request->get('locale'), explode('|', $this->getParameter('app.locales'))))
{
$user->setLocale(
$request->get('locale')
);
}
// Update locales
if ($request->get('locales'))
{
$user->setLocales(
$request->get('locales')
);
}
// Save changes to DB
$userService->save($user);
}
// Generate identicon
$identicon = new \Jdenticon\Identicon();
$identicon->setValue($user->getAddress());
$identicon->setSize(48);
$identicon->setStyle(
[
'backgroundColor' => 'rgba(255, 255, 255, 0)',
'padding' => 0
]
);
// Render template
return $this->render(
'default/user/profile.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' => $timeService->ago(
$user->getAdded()
),
'identicon' => $identicon->getImageDataUri('webp'),
],
'locales' => explode('|', $this->getParameter('app.locales'))
]
);
}
#[Route(
'/{_locale}/user/{id}',
name: 'user_info',
defaults: [
'_locale' => '%app.locale%'
],
requirements: [
'_locale' => '%app.locales%',
],
)]
public function info(
int $id,
Request $request,
UserService $userService,
TimeService $timeService): Response
{
// Init user
if (!$user = $userService->get($id))
{
throw $this->createNotFoundException();
}
// Generate identicon
$identicon = new \Jdenticon\Identicon();
$identicon->setValue($user->getAddress());
$identicon->setSize(48);
$identicon->setStyle(
[
'backgroundColor' => 'rgba(255, 255, 255, 0)',
'padding' => 0
]
);
// Render template
return $this->render(
'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' => $timeService->ago(
$user->getAdded()
),
'identicon' => $identicon->getImageDataUri('webp'),
]
]
);
}
public function module(string $route = ''): Response
{
return $this->render(
'default/user/module.html.twig',
[
'route' => $route,
'stars' => 0,
'views' => 0,
'comments' => 0,
'downloads' => 0,
'editions' => 0,
]
);
}
}

View file

@ -3,6 +3,7 @@
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserRepository::class)]
@ -19,15 +20,6 @@ class User
#[ORM\Column]
private ?int $added = null;
#[ORM\Column]
private ?int $updated = null;
#[ORM\Column]
private ?int $visited = null;
#[ORM\Column]
private ?bool $public = null;
#[ORM\Column]
private ?bool $moderator = null;
@ -37,6 +29,12 @@ class User
#[ORM\Column]
private ?bool $status = null;
#[ORM\Column(length: 2)]
private ?string $locale = null;
#[ORM\Column(type: Types::ARRAY)]
private array $locales = [];
public function getId(): ?int
{
return $this->id;
@ -73,42 +71,6 @@ class User
return $this;
}
public function getUpdated(): ?int
{
return $this->updated;
}
public function setUpdated(int $updated): static
{
$this->updated = $updated;
return $this;
}
public function getVisited(): ?int
{
return $this->visited;
}
public function setVisited(int $visited): static
{
$this->visited = $visited;
return $this;
}
public function isPublic(): ?bool
{
return $this->public;
}
public function setPublic(bool $public): static
{
$this->public = $public;
return $this;
}
public function isModerator(): ?bool
{
return $this->moderator;
@ -144,4 +106,28 @@ class User
return $this;
}
public function getLocale(): ?string
{
return $this->locale;
}
public function setLocale(string $locale): static
{
$this->locale = $locale;
return $this;
}
public function getLocales(): array
{
return $this->locales;
}
public function setLocales(array $locales): static
{
$this->locales = $locales;
return $this;
}
}

View file

@ -21,28 +21,23 @@ class UserRepository extends ServiceEntityRepository
parent::__construct($registry, User::class);
}
// /**
// * @return User[] Returns an array of User objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('u.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
public function findOneByIdField(int $id): ?User
{
return $this->createQueryBuilder('u')
->where('u.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult()
;
}
// public function findOneBySomeField($value): ?User
// {
// return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
public function findOneByAddressField(string $address): ?User
{
return $this->createQueryBuilder('u')
->where('u.address = :address')
->setParameter('address', $address)
->getQuery()
->getOneOrNullResult()
;
}
}

View file

@ -1,12 +0,0 @@
<?php
namespace App\Service;
class User
{
public function init(string $address): string
{
// @TODO
return $address;
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace App\Service;
use App\Entity\User;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class UserService
{
private EntityManagerInterface $entityManager;
private UserRepository $userRepository;
private ParameterBagInterface $parameterBagInterface;
public function __construct(EntityManagerInterface $entityManager, ParameterBagInterface $parameterBagInterface)
{
$this->entityManager = $entityManager;
$this->userRepository = $entityManager->getRepository(User::class);
$this->parameterBagInterface = $parameterBagInterface;
}
public function init(string $address): User
{
// Return existing user
if ($result = $this->userRepository->findOneByAddressField($address))
{
return $result;
}
// Create new user
$user = new User();
$user->setAddress($address);
$user->setAdded(time());
$user->setApproved(false);
$user->setModerator(false);
$user->setStatus(true);
$user->setLocale(
$this->parameterBagInterface->get('app.locale')
);
$user->setLocales(
explode('|', $this->parameterBagInterface->get('app.locales'))
);
$this->save($user);
// Return user data
return $user;
}
public function get(int $id): ?User
{
return $this->userRepository->findOneByIdField($id);
}
public function save(User $user) : void
{
$this->entityManager->persist($user);
$this->entityManager->flush();
}
}