Add some comments
continuous-integration/drone/push Build is passing Details

main
Clément FRÉVILLE 3 weeks ago
parent 71ddec420c
commit 11bcd9a83d

@ -18,8 +18,14 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\UX\Turbo\TurboBundle; use Symfony\UX\Turbo\TurboBundle;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
/**
* CRUD on posts and comments.
*/
class PostController extends AbstractController class PostController extends AbstractController
{ {
/**
* The number of item on a page for the pagination.
*/
private const POSTS_PER_PAGE = 10; private const POSTS_PER_PAGE = 10;
#[Route('/', name: 'app_posts')] #[Route('/', name: 'app_posts')]
@ -36,7 +42,7 @@ class PostController extends AbstractController
} }
#[Route('/posts', name: 'app_post_index', methods: ['GET'])] #[Route('/posts', name: 'app_post_index', methods: ['GET'])]
public function table(PostRepository $repository): Response public function table(): Response
{ {
return $this->redirectToRoute('app_posts', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_posts', [], Response::HTTP_SEE_OTHER);
} }

@ -10,6 +10,9 @@ use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
/**
* Creates fake data for testing purposes.
*/
class AppFixtures extends Fixture class AppFixtures extends Fixture
{ {
public function __construct( public function __construct(
@ -20,10 +23,12 @@ class AppFixtures extends Fixture
public function load(ObjectManager $manager): void public function load(ObjectManager $manager): void
{ {
// Dummy user
$user = (new User())->setEmail('test@test.fr'); $user = (new User())->setEmail('test@test.fr');
$user->setPassword($this->passwordHasher->hashPassword($user, 'password')); $user->setPassword($this->passwordHasher->hashPassword($user, 'password'));
$manager->persist($user); $manager->persist($user);
// Posts and their species
$faker = \Faker\Factory::create(); $faker = \Faker\Factory::create();
for ($i = 0; $i < 20; ++$i) { for ($i = 0; $i < 20; ++$i) {
$name = $faker->name(); $name = $faker->name();

@ -7,6 +7,9 @@ use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Translation\LocaleSwitcher; use Symfony\Component\Translation\LocaleSwitcher;
/**
* Reads the locale from the user session and change it for every request.
*/
final readonly class LocaleListener final readonly class LocaleListener
{ {
public function __construct(private LocaleSwitcher $localeSwitcher) public function __construct(private LocaleSwitcher $localeSwitcher)

@ -6,6 +6,9 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
/**
* Only allow admins or comment owners to edit their comments.
*/
class CommentVoter extends Voter class CommentVoter extends Voter
{ {
public const EDIT = 'COMMENT_EDIT'; public const EDIT = 'COMMENT_EDIT';

@ -4,6 +4,9 @@ namespace App\Service;
use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\File\File;
/**
* Ensures that an image is safe.
*/
interface ImageSafetyServiceInterface interface ImageSafetyServiceInterface
{ {
public function isValid(File $file): bool; public function isValid(File $file): bool;

@ -8,6 +8,8 @@ use App\Entity\User;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
/** /**
* Hashes plain text password in the API.
*
* @implements ProcessorInterface<User, User> * @implements ProcessorInterface<User, User>
*/ */
final readonly class UserPasswordHasher implements ProcessorInterface final readonly class UserPasswordHasher implements ProcessorInterface

@ -2,9 +2,9 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title"> <h5 class="card-title">
{{ comment.author.email }} le {{ comment.createdAt | date }} {{ 'commented_at'|trans({ email: comment.author.email, date: comment.createdAt|date }) }}
{% if comment.createdAt != comment.editedAt %} {% if comment.createdAt != comment.editedAt %}
(modifié le {{ comment.editedAt | date }}) {{ 'edited_at'|trans({ date: comment.editedAt|date }) }}
{% endif %} {% endif %}
</h5> </h5>
<p class="card-text">{{ comment.content }}</p> <p class="card-text">{{ comment.content }}</p>

@ -161,6 +161,14 @@
<source>save</source> <source>save</source>
<target>Save</target> <target>Save</target>
</trans-unit> </trans-unit>
<trans-unit id="zdhzvdha" resname="commented_at">
<source>commented_at</source>
<target>email on date</target>
</trans-unit>
<trans-unit id="zdhzvdht" resname="edited_at">
<source>edited_at</source>
<target>edited on date</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

@ -161,6 +161,14 @@
<source>save</source> <source>save</source>
<target>Sauvegarder</target> <target>Sauvegarder</target>
</trans-unit> </trans-unit>
<trans-unit id="zdhzvdha" resname="commented_at">
<source>commented_at</source>
<target>email le date</target>
</trans-unit>
<trans-unit id="zdhzvdht" resname="edited_at">
<source>edited_at</source>
<target>édité le date</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Loading…
Cancel
Save