Steps to reproduce
- Edit a menu item, enable Mega Menu in the builder, add a row and insert menu items and/or modules into cells via the builder popover.
- Save the mega menu settings.
- Reopen the builder, or load any front-end page.
Actual result
- Every assigned cell is persisted as {"type":"menu","id":"0"} / {"type":"module","id":"0","moduleId":"0"} - all assignments are silently lost.
- The admin builder floods with PHP warnings (one per cell; for module cells one per installed module, because getTitle() loops all modules):
Warning: Undefined property: stdClass::$item_id in
src\Platform\Builders\MegaMenuBuilder.php on line 179 (module) / 189 (menu)
- The front end floods with the same warnings from src\Core\Classes\HelixultimateMenu.php lines 507 and 516, and the rendered mega menu is empty.
Isolated reproduction of the data loss (PHP, against the shipped code)
Input = exactly what assets/js/admin/megamenu.js (handleAddNewCell) sends:
$layout = [[ 'type' => 'row', 'attr' => [[ 'type' => 'column', 'colGrid' => '6', 'items' => [
['type' => 'menu_item', 'item_id' => '2933'],
['type' => 'module', 'item_id' => '311'],
]]]]];
// HelixUltimate\Framework\Platform\Helper::sanitizeMegaMenuLayout($layout) returns:
// [{"type":"row","attr":[{"type":"column","colGrid":"6","menuParentId":"0","moduleId":"0",
// "items":[{"type":"menu","id":"0"},{"type":"module","id":"0","moduleId":"0"}]}]}]
Root cause
Save pipeline Response::saveMegaMenuSettings() → Helper::sanitizeMegaMenuSettings() → Helper::sanitizeMegaMenuLayout() (Helper.php, ~line 1380):
$type = ($cell['type'] ?? '') === 'module' ? 'module' : 'menu'; // 'menu_item' coerced to 'menu'
$cleanCell = [
'type' => $type,
'id' => (string) (int) ($cell['id'] ?? 0), // JS sends 'item_id', not 'id' -> always "0"
];
The builder JS sends {type: 'menu_item'|'module', item_id: <id>}; the sanitizer keeps neither the type nor the id. Both consumers then read the missing item_id unguarded: MegaMenuBuilder::getTitle() (lines 179/189, admin) and HelixultimateMenu::mega() (lines 507/516, front).
Expected result
Saving the mega menu preserves assigned items; no PHP warnings.
Suggested fix in my humble oppinion:
$type = ($cell['type'] ?? '') === 'module' ? 'module' : 'menu_item';
$cleanCell = [
'type' => $type,
'item_id' => (string) (int) ($cell['item_id'] ?? $cell['id'] ?? 0),
];
if ($type === 'module')
{
$cleanCell['moduleId'] = (string) (int) ($cell['moduleId'] ?? $cell['item_id'] ?? 0);
}
Plus $item->item_id ?? 0 guards in MegaMenuBuilder::getTitle() and HelixultimateMenu::mega() so already-broken layouts stop emitting warnings.
Thank you and hope for quick fix on this.