From f489692a83f01c80cc82ea17af29178399cab734 Mon Sep 17 00:00:00 2001 From: AchillesKal Date: Sun, 7 Apr 2024 19:52:40 +0300 Subject: [PATCH] Add menu tags --- migrations/Version20240407152914.php | 27 +++++++++++++++++++ src/DataFixtures/AppFixtures.php | 12 ++++++++- src/Entity/Tag.php | 17 ++++++++++++ src/Factory/BlogPostFactory.php | 1 + src/Form/TagType.php | 11 +++----- src/Twig/AppExtension.php | 14 +++++++++- src/Validator/LimitMenuTags.php | 19 +++++++++++++ src/Validator/LimitMenuTagsValidator.php | 34 ++++++++++++++++++++++++ templates/base.html.twig | 10 +++---- 9 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 migrations/Version20240407152914.php create mode 100644 src/Validator/LimitMenuTags.php create mode 100644 src/Validator/LimitMenuTagsValidator.php diff --git a/migrations/Version20240407152914.php b/migrations/Version20240407152914.php new file mode 100644 index 0000000..d401347 --- /dev/null +++ b/migrations/Version20240407152914.php @@ -0,0 +1,27 @@ +addSql('ALTER TABLE tag ADD is_menu BOOLEAN DEFAULT FALSE NOT NULL'); + $this->addSql('ALTER TABLE tag ALTER is_menu DROP DEFAULT'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE tag DROP is_menu'); + } +} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index 8b742c1..7e408a8 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -13,7 +13,17 @@ class AppFixtures extends Fixture public function load(ObjectManager $manager): void { UserFactory::createOne(); - TagFactory::createMany(20); + + foreach (['Travel', 'Deals', 'Entertainment', 'Science', 'Tech', 'Shopping'] as $title) { + TagFactory::createOne( + [ + 'title' => $title, + 'isMenu' => true, + ] + ); + } + + TagFactory::createMany(15); BlogPostFactory::createMany(100, function() { return [ 'tags' => TagFactory::randomRange(1, 5), diff --git a/src/Entity/Tag.php b/src/Entity/Tag.php index c6db17f..67564e6 100644 --- a/src/Entity/Tag.php +++ b/src/Entity/Tag.php @@ -4,6 +4,7 @@ use App\Repository\TagRepository; use App\Util\TimestampableEntityTrait; +use App\Validator\LimitMenuTags; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -29,6 +30,10 @@ class Tag #[ORM\ManyToMany(targetEntity: BlogPost::class, mappedBy: 'tags')] private Collection $blogPosts; + #[ORM\Column] + #[LimitMenuTags] + private bool $isMenu = false; + public function __construct() { @@ -87,4 +92,16 @@ public function removeBlogPost(BlogPost $blogPost): static return $this; } + + public function isMenu(): bool + { + return $this->isMenu; + } + + public function setIsMenu(bool $isMenu): static + { + $this->isMenu = $isMenu; + + return $this; + } } diff --git a/src/Factory/BlogPostFactory.php b/src/Factory/BlogPostFactory.php index 24c3927..26b86c1 100644 --- a/src/Factory/BlogPostFactory.php +++ b/src/Factory/BlogPostFactory.php @@ -54,6 +54,7 @@ protected function getDefaults(): array // Copy the dummy image to a temporary file to simulate an upload copy($imagePath, $temporaryImagePath); $file = new UploadedFile($temporaryImagePath, $filename); + return [ 'title' => ucfirst(self::faker()->words(5, true)), 'summary' => self::faker()->text, diff --git a/src/Form/TagType.php b/src/Form/TagType.php index 7f70a38..d8f6d52 100644 --- a/src/Form/TagType.php +++ b/src/Form/TagType.php @@ -2,10 +2,9 @@ namespace App\Form; -use App\Entity\BlogPost; use App\Entity\Tag; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -15,12 +14,10 @@ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('title') - ->add('blogPosts', EntityType::class, [ - 'class' => BlogPost::class, - 'choice_label' => 'id', - 'multiple' => true, + ->add('isMenu', CheckboxType::class, [ + 'label' => 'Display in Menu', 'required' => false, - ]) + ]); ; } diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 9a7d2a7..e749c6d 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -2,16 +2,22 @@ namespace App\Twig; +use App\Repository\TagRepository; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; use Twig\TwigFunction; class AppExtension extends AbstractExtension { + public function __construct(private TagRepository $tagRepository) + { + } + public function getFunctions(): array { return [ - new TwigFunction('uploaded_asset', [$this, 'getUploadedAssetPath']) + new TwigFunction('uploaded_asset', [$this, 'getUploadedAssetPath']), + new TwigFunction('get_menu_tags', [$this, 'getMenuTags']), ]; } @@ -26,4 +32,10 @@ public function getUploadedAssetPath(string $path): string { return 'uploads/banners/' . $path; } + + public function getMenuTags() + { + // find all tags that have is menu true + return $this->tagRepository->findBy(['isMenu' => true], ['createdAt' => 'DESC']); + } } diff --git a/src/Validator/LimitMenuTags.php b/src/Validator/LimitMenuTags.php new file mode 100644 index 0000000..4f49adc --- /dev/null +++ b/src/Validator/LimitMenuTags.php @@ -0,0 +1,19 @@ +tagRepository->count(['isMenu' => true]); + + if ($menuTagsCount > 5) { + $this->context->buildViolation($constraint->message) + ->addViolation(); + } + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index 182a4b5..0b348be 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -22,13 +22,11 @@ + {% if app.user %} Logout