Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c167e55
chore: require Thelia 3.0 and bump to 2.0.0
Sep 10, 2026
f44882e
feat(front): render the menu through a Twig function instead of a Sma…
Sep 10, 2026
b8666c1
feat(back-office): port the composition screen to the default-twig theme
Sep 10, 2026
d46a19c
feat(api): expose the menu tree as a read-only API Platform resource
Sep 10, 2026
afb816b
chore: drop the empty deprecated routing.xml
Sep 10, 2026
9e22e74
fix(model): pass null, not an empty string, to the nullable view_id s…
Sep 10, 2026
65e9851
docs: drop the OpenApi module prerequisite
Sep 10, 2026
a97630a
fix: resolve every static analysis finding reported at level 5
Sep 10, 2026
9065d36
feat(back-office): rebuild the composition screen on the theme's tree…
Sep 10, 2026
403d53a
feat(back-office): reparent a menu entry from its edit page
Sep 11, 2026
2d52391
fix(i18n): refresh the Spanish and Italian back-office catalogs
Sep 11, 2026
a0a3806
fix(i18n): refresh the Spanish and Italian flash message catalogs
Sep 11, 2026
35da085
feat: address a menu by its code instead of its id
Sep 11, 2026
dd2c873
chore: drop the destroy hook that cleared the dropped menu cookie
Sep 11, 2026
66c3636
feat: validate a typed menu code instead of slugifying it silently
Sep 11, 2026
ffa512b
refactor(front): answer the menu tree as data, not markup
Sep 11, 2026
905df5d
fix(security): reject protocol-relative menu links, on write and on read
Sep 11, 2026
055bb9a
fix: make the 2.0.0 migration replayable and recoverable
Sep 11, 2026
9912c1a
update sql
Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Api/Resource/CustomFrontMenu.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/*************************************************************************************/

namespace CustomFrontMenu\Api\Resource;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use CustomFrontMenu\Api\State\CustomFrontMenuProvider;
use Symfony\Component\Serializer\Attribute\Groups;

/**
* One composed menu, as the normalised tree the front renders.
*
* Read-only: composing a menu is a back-office operation, done through the module's
* configuration screen, not through this resource.
*/
#[ApiResource(
operations: [
new Get(
uriTemplate: '/front/custom-front-menus/{code}',
uriVariables: ['code'],
normalizationContext: ['groups' => [self::GROUP_FRONT_READ]],
provider: CustomFrontMenuProvider::class,
),
],
)]
class CustomFrontMenu
{
public const GROUP_FRONT_READ = 'custom_front_menu:front:read';

/**
* The code the shop owner gave the menu, which is also how a theme addresses it.
*
* The identifier of the resource, so the IRI is stable across installations: the
* numeric id of a menu is not, it comes from an autoincrement shared with the entries.
*/
#[ApiProperty(identifier: true)]
#[Groups([self::GROUP_FRONT_READ])]
public string $code = '';

/**
* Nodes of {id, title, href, children}, children nested to any depth.
*
* @var list<array<string, mixed>>
*/
#[Groups([self::GROUP_FRONT_READ])]
public array $items = [];
}
59 changes: 59 additions & 0 deletions Api/State/CustomFrontMenuProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/*************************************************************************************/

namespace CustomFrontMenu\Api\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use CustomFrontMenu\Api\Resource\CustomFrontMenu;
use CustomFrontMenu\Service\Front\MenuTreeResolver;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Thelia\Domain\Localization\Service\LangService;

/**
* @implements ProviderInterface<CustomFrontMenu>
*/
final readonly class CustomFrontMenuProvider implements ProviderInterface
{
public function __construct(
private MenuTreeResolver $treeResolver,
private LangService $langService,
) {
}

/**
* @param array<string, mixed> $uriVariables
* @param array<string, mixed> $context
*/
public function provide(Operation $operation, array $uriVariables = [], array $context = []): CustomFrontMenu
{
$code = trim((string) ($uriVariables['code'] ?? ''));

if ('' === $code) {
throw new NotFoundHttpException('Menu not found');
}

$items = $this->treeResolver->resolve($code, $this->langService->getLocale() ?? 'en_US');

if (null === $items) {
throw new NotFoundHttpException('Menu not found');
}

$menu = new CustomFrontMenu();
$menu->code = $code;
$menu->items = $items;

return $menu;
}
}
4 changes: 3 additions & 1 deletion Config/TheliaMain.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ DROP TABLE IF EXISTS `custom_front_menu_item`;
CREATE TABLE `custom_front_menu_item`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`code` VARCHAR(255),
`view` VARCHAR(255),
`view_id` INTEGER,
`tree_left` INTEGER,
`tree_right` INTEGER,
`tree_level` INTEGER,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
UNIQUE INDEX `custom_front_menu_item_code_unique` (`code`)
) ENGINE=InnoDB;

-- ---------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions Config/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<language>en_US</language>
<language>fr_FR</language>
</languages>
<version>1.2.0</version>
<version>2.0.0</version>
<authors>
<author>
<name>Delage Mathis</name>
Expand All @@ -44,7 +44,7 @@
<module version="&gt;0.2">HookSearch</module>
</required>
-->
<thelia>2.4.0</thelia>
<thelia>3.0.0</thelia>
<stability>other</stability>
<mandatory>0</mandatory>
<hidden>0</hidden>
Expand Down
6 changes: 0 additions & 6 deletions Config/routing.xml

This file was deleted.

8 changes: 8 additions & 0 deletions Config/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@

<table name="custom_front_menu_item" namespace="CustomFrontMenu\Model">
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER"/>
<!-- Only a menu (tree level 1) carries a code: it is the name a theme calls the
menu by, so it must survive a reinstall, which an autoincrement id does not.
Entries keep it null; MySQL allows many nulls under a unique index. -->
<column name="code" size="255" type="VARCHAR"/>
<column name="view" size="255" type="VARCHAR"/>
<column name="view_id" type="INTEGER"/>
<column name="title" size="255" type="VARCHAR"/>
<column name="url" size="255" type="VARCHAR"/>
<unique name="custom_front_menu_item_code_unique">
<unique-column name="code"/>
</unique>

<behavior name="nested_set" />
<behavior name="i18n">
<parameter name="i18n_columns" value="title, url" />
Expand Down
55 changes: 0 additions & 55 deletions Controller/Front/CustomFrontMenuAPIController.php

This file was deleted.

Loading