Skip to content

Menu systém - Core třídy

Dokumentace hlavních tříd pro práci s menu systémem. Menu systém se skládá ze dvou hlavních tříd: Menu pro správu celých menu a MenuNode pro práci s jednotlivými uzly.

Třída Menu

Namespace: Petrovo\Menu\Menu

Třída pro správu celých menu struktur. Hlavní funkcionalita je duplikace kompletního menu včetně všech uzlů a jazykových dat.

Klíčové metody

Vytvoří kompletní kopii celého menu včetně všech uzlů a jazykových variant.

Parametry:

  • $menuId - ID menu k duplikaci

Návratová hodnota:

  • array|null - pole s informacemi o novém menu nebo null při chybě

Struktura návratového pole:

php [ 
'new_menu_id' => 123, // ID nového menu 
'new_base_node_id' => 456, // ID základního uzlu 
'name' => 'Hlavní menu (copy 20.07.2025 14:30:15)'
]

Příklad použití:

php use Petrovo\Menu\Menu;
result = Menu::duplicate(5); 
if (result) { 
    echo "Nové menu vytvořeno s ID: " . result['new_menu_id']; 
    echo "Základní uzel: " .result['new_base_node_id']; 
} else { 
    echo "Duplikace se nezdařila"; 
}

Vnitřní metody

generateMenuAndBaseNode(object $menu): array

Vytvoří nový záznam menu a jeho základní uzel (base_node).

Důležité:

  • Každé menu má základní uzel (base_node), který nemá jazykové překlady
  • Základní uzel slouží jako kotva pro parent_id prvků první úrovně
  • Umožňuje snadné přesouvání a řazení položek první úrovně
  • Základní uzel se nikdy nezobrazuje ve frontend výstupu

Proces vytvoření:

  1. Vytvoří nový záznam v tabulce menu
  2. Vytvoří základní uzel (parent_id = null)
  3. Aktualizuje closure table procedurou menu_add_node
  4. Propojí menu se základním uzlem (base_node_id)

Použití v administraci

Třída Menu se používá v administračním rozhraní prostřednictvím MenusController.php.

Základní operace

Vytvoření nového menu:

public function new(): void { 
    // Vytvoří nové menu 
    $sql = "INSERT INTO menu (web_id, name) VALUES (?, ?)"; 
    DB::query(sql, [WEB, name]);
    $menuId = DB::$insertId;
    // Vytvoří základní uzel
    $baseNodeId = MenuNode::create($menuId, null);

    // Propojí menu se základním uzlem
    $sql = "UPDATE menu SET base_node_id = ? WHERE id = ?";
    DB::query($sql, [$baseNodeId, $menuId]);
}

Duplikace menu:

public function duplicate(): void { 
    $menuId = array_get_int(_GET, 'id', 0);
    $result = Menu::duplicate($menuId);
    if ($result) {
        Message::success('{S Menu was duplicated}');
    } else {
        Message::error('{S Menu could not be duplicated}');
    }

    redirect($this->urlListing());
}

Smazání menu:

public function delete(): void { 
    $menuId = array_get_int(_GET, 'id', 0);
    // Jednoduché SQL DELETE - databáze řeší CASCADE
    $sql = "DELETE FROM menu WHERE id = ?";
    DB::query($sql, [$menuId]);

    if (DB::$affectedRows > 0) {
        Message::success('{S Menu was deleted}');
    } else {
        Message::error('{S Menu could not be deleted}');
    }
}

Jak funguje duplikace menu

1. Načtení zdrojového menu

  • Načte základní informace o menu (web_id, name, base_node_id)
  • Pokud menu neexistuje, vrátí null

2. Vytvoření nové struktury

  • Vytvoří nový záznam v menu s timestampem
  • Vytvoří nový základní uzel
  • Propojí menu se základním uzlem

3. Duplikace stromu uzlů

  • Načte kompletní strom pomocí menu_get_tree_all()
  • Projde všechny uzly a vytvoří jejich kopie
  • Mapuje staré ID na nové ID ($nodeMap)
  • Zachovává hierarchickou strukturu

4. Duplikace jazykových dat

  • Pro každý uzel zkopíruje všechny jazykové varianty
  • Zachovává JSON data v menu_node_lang.data
  • Kopíruje viditelnost (is_hide) pro každý jazyk

5. Aktualizace closure table

  • Používá proceduru menu_add_node() pro správnou hierarchii
  • Automaticky spočítá všechny cesty v menu_node_path

Transakční bezpečnost

Celá operace duplikace probíhá v databázové transakci:

    DB::beginTransaction(); 
    try { 
        // Duplikace menu... 
        DB::commit(); 
        return result; 
    } catch (Exceptione) { 
        DB::rollback(); 
        throw $e; 
    }

Pokud dojde k chybě v jakékoli části, všechny změny se vrátí zpět.

Konvence pojmenování

  • Původní menu: "Hlavní menu"
  • Duplikát: "Hlavní menu (copy 20.07.2025 14:30:15)"

Timestamp zajišťuje jedinečnost názvů při více duplikacích.

Vztah k ostatním třídám

Menu (správa celých menu) 
├── MenuNode (správa jednotlivých uzlů)
├── MenusController (admin rozhraní) 
└── DB (databázové operace)

Třída Menu je vysokoúrovňové API pro práci s celými menu strukturami, zatímco MenuNode se zaměřuje na detailní operace s jednotlivými uzly.

MenuNode třída poskytuje kompletní API pro práci s jednotlivými uzly menu systému. Zahrnuje CRUD operace, manipulaci se stromovou strukturou a vícejazyčnou podporu.

Namespace: Petrovo\Menu\MenuNode

Hlavní metody pro práci s uzly

Načte jeden uzel menu s jeho jazykovými daty.

Parametry:

  • $nodeId - ID uzlu
  • $lang - kód jazyka (výchozí DEFAULT_LANG_WEB)

Návratová hodnota:

  • array|null - formátovaná data uzlu nebo null pokud uzel neexistuje

Struktura návratového pole:

[ 
    'id' => 123, 
    'parent_id' => 45, 
    'level' => 2, 
    'order' => 3, 
    'name' => 'Název položky', 
    'is_hide' => false, 
    'breadcrumbs' => [1, 45], 
    'title' => 'Alternativní název', 
    'href' => '/cesta-na-stranku', 
    'href_same' => false, 
    'new_window' => false, 
    'attr_class' => 'css-trida', 
    'attr_id' => 'css-id', 
    'seo_title' => 'SEO titulek', 
    'seo_keywords' => 'klíčová, slova', 
    'seo_description' => 'SEO popis', 
    'text' => 'Obsah stránky', 
    'multilingual' => ['name', 'title', 'is_hide', 'href', ...] 
]

Vytvoří nový uzel menu s vícejazyčnými daty.

Parametry:

  • $menuId - ID menu
  • $parentId - ID rodiče (null pro první úroveň pod base_node)
  • $langData - pole jazykových dat indexované kódem jazyka

Struktura $langData:

$langData = [ 
    'cs' => [ 
        'name' => 'Český název', 
        'is_hide' => false, 
        'data' => [ 
            'title' => 'Český titulek', 
            'href' => '/ceska-cesta', 
            'seo_title' => 'Český SEO titulek' 
            // další data... 
        ] 
    ], 
    'en' => [ 
        'name' => 'English name', 
        'is_hide' => false, 
        'data' => [ 
            'title' => 'English title', 
            'href' => '/english-path', 
            'seo_title' => 'English SEO title',
            ...
        ] 
    ] 
];

Návratová hodnota:

  • int - ID nově vytvořeného uzlu

Příklad použití:

use Petrovo\Menu\MenuNode;
$langData = [ 
    'cs' => [ 
    'name' => 'O nás', 
    'is_hide' => false, 
    'data' => ['href' => '/o-nas', 
    'title' => 'Informace o společnosti'] 
    ] 
];
nodeId = MenuNode::create(5, 12,langData); 
echo "Vytvořen uzel s ID: $nodeId";

Aktualizuje existující uzel s novými jazykovými daty.

Pozor: Base node (základní uzel) se nikdy neaktualizuje jazykovými daty!

Přesune uzel pod nového rodiče. Automaticky aktualizuje closure table.

Smaže uzel a všechny jeho potomky (CASCADE DELETE).

Metody pro manipulaci s pořadím

Změní pořadí uzlu mezi sourozenci a automaticky přeřadí všechny sourozence.

Posune uzel o jednu pozici nahoru/dolů mezi sourozenci.

Metody pro viditelnost

Nastaví viditelnost uzlu a všech jeho potomků v konkrétním jazyce.

Pomocné metody

Formátuje surová data z databáze do standardizovaného pole s rozdělenými JSON daty.

Důležité vlastnosti:

  • Parsuje JSON z menu_node_lang.data
  • Definuje vícejazyčná pole v multilingual klíči
  • Převádí typy dat (int, bool)
  • Zpracovává breadcrumbs jako pole integerů

Vrací ID rodiče uzlu nebo null pro uzly první úrovně.

Přeřadí všechny sourozence pod stejným rodičem (odstraní mezery v číslování).

Administrační struktura - Data endpoint

Speciální datový endpoint pro načtení kompletní struktury menu pro administraci.

URL: Data\get('Menus/structure?' . http_build_query($query))

Parametry:

  • id - ID menu

Použití v MenusNodesController:

query['id'] = this->menuId; 
items = Json\decode(Data\get('Menus/structure?' . http_build_query(query)));

Pomocná třída pro sestavení administrační struktury menu.

Načte surová data pomocí CALL menu_get_tree_all(?).

Seskupí plochá data podle ID uzlu a připojí všechny jazykové varianty.

Obohacuje uzel o data potřebná pro zobrazení v administraci:

Přidané vlastnosti:

  • level_visual - vizuální odsazení (bullet pointy)
  • name_default - název v hlavním jazyce
  • translations - přehled překladů
  • id_class - CSS třídy a ID
  • active_languages - jazyky kde je uzel viditelný
  • href_same - zda má stejný href ve všech jazycích
  • isPage / pageExists - zda odkazuje na existující stránku
  • showHref / showPage - zkrácené URL pro zobrazení
  • actions - dostupné akce (up, down, before, after, child)

Akce dostupné v administraci

MenusNodesController poskytuje tyto operace:

listing()

Zobrazí strukturu menu s všemi jazykovými variantami a dostupnými akcemi.

new() / edit()

Formuláře pro vytváření/editaci uzlů s podporou všech jazyků.

delete()

Smazání uzlu včetně všech potomků.

moveUp() / moveDown()

Přesunutí uzlu mezi sourozenci.

toggleVisibility()

Přepnutí viditelnosti uzlu v konkrétním jazyce.

Vícejazyčná pole

Systém automaticky rozpoznává vícejazyčná pole podle seznamu v formatNode():

$multilingualFields = 'name|title|is_hide|href|seo_title|seo_keywords|seo_description|text';

V administraci se pak pole zpracovávají s suffixem jazyka: - name_cs, name_en - title_cs, title_en - href_cs, href_en (pokud není href_same)

Speciální funkce

Automatické vytváření stránek

Pokud je při ukládání uzlu zaškrtnuto create_page, systém automaticky vytvoří odpovídající stránku s stejným názvem a href.

Konverze href

Metoda convertHref() automaticky převádí názvy na URL-friendly formát: - Převod na ASCII - Odstranění nepovolených znaků - Zpracování GET parametrů - Zachování externích URL a JavaScriptu

Base node koncept

  • Každé menu má base_node (základní uzel)
  • Base node se nikdy nezobrazuje na frontendu
  • Slouží jako kotva pro parent_id prvků první úrovně
  • Nemá jazykové překlady v menu_node_lang
  • Umožňuje snadné přesouvání a řazení první úrovně

Tento koncept zajišťuje konzistentní strukturu a umožňuje efektivní manipulaci se stromem menu.