From 0a9ed479d9200d80d565d914e622a8f1a0d510cc Mon Sep 17 00:00:00 2001 From: Etienne Gutbub Date: Fri, 27 Oct 2023 10:25:14 +0200 Subject: [PATCH 1/3] feat(menu item attributes): Add column for attributes on MenuItem entity --- src/Entity/MenuItem.php | 48 +++++++++++++++++++ src/Entity/MenuItemInterface.php | 16 +++++++ src/Migrations/Version20231027081424.php | 40 ++++++++++++++++ .../config/doctrine/MenuItem.orm.xml | 12 +++++ 4 files changed, 116 insertions(+) create mode 100644 src/Migrations/Version20231027081424.php diff --git a/src/Entity/MenuItem.php b/src/Entity/MenuItem.php index d876b33..6b0cb8b 100644 --- a/src/Entity/MenuItem.php +++ b/src/Entity/MenuItem.php @@ -42,6 +42,14 @@ class MenuItem implements MenuItemInterface protected ?int $position = null; + protected bool $targetBlank = false; + + protected bool $noreferrer = false; + + protected bool $noopener = false; + + protected bool $nofollow = false; + /** * MenuItem constructor. */ @@ -158,6 +166,46 @@ public function removeItem(MenuItemInterface $item): void } } + public function isTargetBlank(): bool + { + return $this->targetBlank; + } + + public function setTargetBlank(bool $targetBlank): void + { + $this->targetBlank = $targetBlank; + } + + public function isNoreferrer(): bool + { + return $this->noreferrer; + } + + public function setNoreferrer(bool $noreferrer): void + { + $this->noreferrer = $noreferrer; + } + + public function isNoopener(): bool + { + return $this->noopener; + } + + public function setNoopener(bool $noopener): void + { + $this->noopener = $noopener; + } + + public function isNofollow(): bool + { + return $this->nofollow; + } + + public function setNofollow(bool $nofollow): void + { + $this->nofollow = $nofollow; + } + /** * @inheritdoc */ diff --git a/src/Entity/MenuItemInterface.php b/src/Entity/MenuItemInterface.php index cab9d4f..6a5cf6e 100644 --- a/src/Entity/MenuItemInterface.php +++ b/src/Entity/MenuItemInterface.php @@ -62,6 +62,22 @@ public function addItem(self $item): void; */ public function removeItem(self $item): void; + public function isTargetBlank(): bool; + + public function setTargetBlank(bool $targetBlank): void; + + public function isNoreferrer(): bool; + + public function setNoreferrer(bool $noreferrer): void; + + public function isNoopener(): bool; + + public function setNoopener(bool $noopener): void; + + public function isNofollow(): bool; + + public function setNofollow(bool $nofollow): void; + public function getLabel(): ?string; public function getUrl(): ?string; diff --git a/src/Migrations/Version20231027081424.php b/src/Migrations/Version20231027081424.php new file mode 100644 index 0000000..974b343 --- /dev/null +++ b/src/Migrations/Version20231027081424.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace MonsieurBiz\SyliusMenuPlugin\Migrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20231027081424 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE monsieurbiz_menu_item ADD target_blank TINYINT(1) NOT NULL, ADD noreferrer TINYINT(1) NOT NULL, ADD noopener TINYINT(1) NOT NULL, ADD nofollow TINYINT(1) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE monsieurbiz_menu_item DROP target_blank, DROP noreferrer, DROP noopener, DROP nofollow'); + } +} diff --git a/src/Resources/config/doctrine/MenuItem.orm.xml b/src/Resources/config/doctrine/MenuItem.orm.xml index d47ab19..27b3444 100644 --- a/src/Resources/config/doctrine/MenuItem.orm.xml +++ b/src/Resources/config/doctrine/MenuItem.orm.xml @@ -28,5 +28,17 @@ null + + false + + + false + + + false + + + false + From 591c12df27d85b5df8d5bd453a30bec403c9fdf3 Mon Sep 17 00:00:00 2001 From: Etienne Gutbub Date: Fri, 27 Oct 2023 10:32:44 +0200 Subject: [PATCH 2/3] feat(menu item attributes): Add fields to form --- src/Form/Type/MenuItemType.php | 21 ++++++++++++++++ src/Resources/translations/messages.en.yaml | 8 +++++++ src/Resources/translations/messages.fr.yaml | 8 +++++++ .../views/Admin/MenuItem/_form.html.twig | 24 +++++++++++++++++++ .../views/Layout/Header/_menu.html.twig | 12 +++++++++- 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/Form/Type/MenuItemType.php b/src/Form/Type/MenuItemType.php index 1844a18..e564fff 100644 --- a/src/Form/Type/MenuItemType.php +++ b/src/Form/Type/MenuItemType.php @@ -17,6 +17,7 @@ use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType; use Sylius\Bundle\ResourceBundle\Form\Type\ResourceTranslationsType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; @@ -55,6 +56,26 @@ public function buildForm(FormBuilderInterface $builder, array $options): void return $qb; }, ]) + ->add('targetBlank', CheckboxType::class, [ + 'label' => 'monsieurbiz_menu.ui.target_blank', + 'help' => 'monsieurbiz_menu.ui.help_target_blank', + 'required' => false, + ]) + ->add('noreferrer', CheckboxType::class, [ + 'label' => 'monsieurbiz_menu.ui.noreferrer', + 'help' => 'monsieurbiz_menu.ui.help_noreferrer', + 'required' => false, + ]) + ->add('noopener', CheckboxType::class, [ + 'label' => 'monsieurbiz_menu.ui.noopener', + 'help' => 'monsieurbiz_menu.ui.help_noopener', + 'required' => false, + ]) + ->add('nofollow', CheckboxType::class, [ + 'label' => 'monsieurbiz_menu.ui.nofollow', + 'help' => 'monsieurbiz_menu.ui.help_nofollow', + 'required' => false, + ]) ->add('translations', ResourceTranslationsType::class, [ 'label' => 'sylius.ui.translations', 'entry_type' => MenuItemTranslationType::class, diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml index 2251d6f..47adbb8 100644 --- a/src/Resources/translations/messages.en.yaml +++ b/src/Resources/translations/messages.en.yaml @@ -13,3 +13,11 @@ monsieurbiz_menu: menu_items: 'Menu elements' label: 'Label' url: 'URL' + target_blank: 'Target _blank' + help_target_blank: 'Open the link in a new tab' + noreferrer: 'noreferer' + help_noreferrer: 'Add "noreferrer" to the rel attribute' + noopener: 'noopener' + help_noopener: 'Add "noopener" to the rel attribute' + nofollow: 'nofollow' + help_nofollow: 'Add "nofollow" to the rel attribute' diff --git a/src/Resources/translations/messages.fr.yaml b/src/Resources/translations/messages.fr.yaml index ce7e15b..94b1848 100644 --- a/src/Resources/translations/messages.fr.yaml +++ b/src/Resources/translations/messages.fr.yaml @@ -13,3 +13,11 @@ monsieurbiz_menu: menu_items: 'Éléments de menu' label: 'Label' url: 'URL' + target_blank: 'Target _blank' + help_target_blank: 'Ouvrir le lien dans un nouvel onglet' + noreferrer: 'noreferer' + help_noreferrer: 'Ajoute "noreferrer" à l''attribut rel' + noopener: 'noopener' + help_noopener: 'Ajoute "noopener" à l''attribut rel' + nofollow: 'nofollow' + help_nofollow: 'Ajoute "nofollow" à l''attribut rel' diff --git a/src/Resources/views/Admin/MenuItem/_form.html.twig b/src/Resources/views/Admin/MenuItem/_form.html.twig index 993b372..9265d7b 100644 --- a/src/Resources/views/Admin/MenuItem/_form.html.twig +++ b/src/Resources/views/Admin/MenuItem/_form.html.twig @@ -1,10 +1,34 @@ {% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} {{ form_errors(form) }}
{{ form_row(form.parent) }} + +
+
+ {{ form_row(form.targetBlank) }} + {{ form_help(form.targetBlank) }} +
+ +
+ {{ form_row(form.noreferrer) }} + {{ form_help(form.noreferrer) }} +
+ +
+ {{ form_row(form.noopener) }} + {{ form_help(form.noopener) }} +
+ +
+ {{ form_row(form.nofollow) }} + {{ form_help(form.nofollow) }} +
+
+ {{ translationForm(form.translations) }}
diff --git a/src/Resources/views/Layout/Header/_menu.html.twig b/src/Resources/views/Layout/Header/_menu.html.twig index dcc9f7e..73b3851 100644 --- a/src/Resources/views/Layout/Header/_menu.html.twig +++ b/src/Resources/views/Layout/Header/_menu.html.twig @@ -12,7 +12,17 @@ {% else %} - {{ menu.label }} + {% set noreferrer = menu.noreferrer %} + {% set noopener = menu.noopener %} + {% set nofollow = menu.nofollow %} + {% set hasRel = noreferrer or noopener or nofollow %} + + {{ menu.label }} + {% endif %} {% endmacro %} From 2a4a2db62e14fb70220df2bfc66ab2e98962f2b2 Mon Sep 17 00:00:00 2001 From: Etienne Gutbub Date: Fri, 27 Oct 2023 10:33:24 +0200 Subject: [PATCH 3/3] feat(menu item attributes): update fixture --- src/Fixture/Factory/MenuFixtureFactory.php | 5 +++++ src/Fixture/MenuFixture.php | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/Fixture/Factory/MenuFixtureFactory.php b/src/Fixture/Factory/MenuFixtureFactory.php index 9f577e6..3d4b744 100644 --- a/src/Fixture/Factory/MenuFixtureFactory.php +++ b/src/Fixture/Factory/MenuFixtureFactory.php @@ -91,6 +91,11 @@ private function createMenuItem(array $item, int $position, MenuInterface $menu, $menuItem->setPosition($position); $menuItem->setMenu($menu); + $menuItem->setTargetBlank($item['targetBlank'] ?? false); + $menuItem->setNoreferrer($item['noreferrer'] ?? false); + $menuItem->setNoopener($item['noopener'] ?? false); + $menuItem->setNofollow($item['nofollow'] ?? false); + if (null !== $parentItem) { $menuItem->setParent($parentItem); } diff --git a/src/Fixture/MenuFixture.php b/src/Fixture/MenuFixture.php index d69265c..e790c26 100644 --- a/src/Fixture/MenuFixture.php +++ b/src/Fixture/MenuFixture.php @@ -41,6 +41,10 @@ public function configureResourceNode(ArrayNodeDefinition $resourceNode): void ->children() ->scalarNode('label')->cannotBeEmpty()->end() ->scalarNode('url')->defaultValue('')->end() + ->booleanNode('targetBlank')->defaultFalse()->end() + ->booleanNode('noreferrer')->defaultFalse()->end() + ->booleanNode('noopener')->defaultFalse()->end() + ->booleanNode('nofollow')->defaultFalse()->end() ->end() ->end() ->end()