Skip to content

Commit

Permalink
Add menu tags
Browse files Browse the repository at this point in the history
  • Loading branch information
AchillesKal committed Apr 7, 2024
1 parent 608872d commit f489692
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 15 deletions.
27 changes: 27 additions & 0 deletions migrations/Version20240407152914.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240407152914 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
$this->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');
}
}
12 changes: 11 additions & 1 deletion src/DataFixtures/AppFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
17 changes: 17 additions & 0 deletions src/Entity/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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()
{
Expand Down Expand Up @@ -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;
}
}
1 change: 1 addition & 0 deletions src/Factory/BlogPostFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 4 additions & 7 deletions src/Form/TagType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
])
]);
;
}

Expand Down
14 changes: 13 additions & 1 deletion src/Twig/AppExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']),
];
}

Expand All @@ -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']);
}
}
19 changes: 19 additions & 0 deletions src/Validator/LimitMenuTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Validator;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class LimitMenuTags extends Constraint
{
/*
* Any public properties become valid options for the annotation.
* Then, use these in your validator class.
*/
public $message = 'You cannot have more than 6 menu tags.';
}
34 changes: 34 additions & 0 deletions src/Validator/LimitMenuTagsValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Validator;

use App\Repository\TagRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class LimitMenuTagsValidator extends ConstraintValidator
{
public function __construct(private TagRepository $tagRepository)
{
}

public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof LimitMenuTags) {
throw new UnexpectedTypeException($constraint, LimitMenuTags::class);
}

/* @var LimitMenuTags $constraint */

if (null === $value || '' === $value) {
return;
}
$menuTagsCount = $this->tagRepository->count(['isMenu' => true]);

if ($menuTagsCount > 5) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}
10 changes: 4 additions & 6 deletions templates/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
</a>
<div class="flex space-x-8 *:font-bold *:text-sm hidden lg:block">
<a href="{{ path('app_blog_post_index') }}" class="text-gray-800 hover:text-gray-600">Home</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Travel</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Deals</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Entertainment</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Science</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Tech</a>
<a href="{{ path('app_about') }}" class="text-gray-800 hover:text-gray-600">Shopping</a>
{% for tag in get_menu_tags() %}
<a href="{{ path('app_tag_show', { 'slug': tag.slug}) }}" class="text-gray-800 hover:text-gray-600">{{tag.title}}</a>
{% endfor %}
</div>

{% if app.user %}
<a href="{{ path('app_logout') }}" class="flex gap-2 items-center">
<span>Logout</span>
Expand Down

0 comments on commit f489692

Please sign in to comment.