Как взять плоский файл JSON и построить иерархическое меню, используя PHP - PullRequest
0 голосов
/ 12 июля 2020

У меня есть база данных со списком ссылок меню. Каждая ссылка меню имеет идентификатор в поле «menu_pages_id».

В базе данных есть поле «subPageOf», в котором указано, что это за родитель. Есть также три различных типа ссылок меню, которые определены в поле «menuType»

Я вывел этот список в плоский файл JSON и хочу восстановить иерархию.

$jsonMenu = json_decode($jsonMenu);
foreach ($jsonMenu as $pageInfo ) {
    $pageUrl = $pageInfo->pageUrl;
    $menuPageName = $pageInfo->pageName;
    $menuType = $pageInfo->menuType;
    $subPageOf = $pageInfo->subPageOf;
    $menu_pages_id = $pageInfo->menu_pages_id;
    
    if( $menuType == 'header' &&  $subPageOf == '0' ){
        $headerMenu .= "<a href='$pageUrl'>$menuPageName</a>"; 
    }
    
    if( $menuType == 'category' &&  $subPageOf == '0'){
        $categoryMenu .= "<li><a href='$pageUrl'>$menuPageName</a></li>";
    }
    
    if( $menuType == 'footer' &&  $subPageOf == '0' ){
        $footerMenu .= "<a href='$pageUrl'>$menuPageName</a>"; 
    } 
}

$categoryMenu = '<ul>'.$categoryMenu.'</ul>';
echo $headerMenu
echo $categoryMenu
echo $footerMenu

Это, конечно, выведет первый уровень ... но как мне вложить вложенные страницы в

его родительского элемента для меню категорий.

Я мог бы поместить еще один целиком foreach l oop в элементе

и снова запустите его с фильтрацией по родительскому идентификатору. Но это означает, что мне пришлось бы жестко закодировать глубину поиска, а это похоже на много лишнего кода. Надеюсь на более элегантное решение.

Вот пример Json Меню

[{"menu_pages_id":"77","menu_id":"1","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"78","menu_id":"1","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"80","menu_id":"1","page_id":"6","listOrder":"0","subPageOf":"0","pageName":"Register","pageUrl":"register","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"81","menu_id":"1","page_id":"7","listOrder":"0","subPageOf":"0","pageName":"Your Account","pageUrl":"account","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"82","menu_id":"1","page_id":"9","listOrder":"0","subPageOf":"0","pageName":"Logout","pageUrl":"logout","pageType":"system","isProtected":"1","customerGroup":"1003","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"83","menu_id":"2","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"84","menu_id":"2","page_id":"44","listOrder":"0","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Footer","menuType":"footer","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"97","menu_id":"24","page_id":"1","listOrder":"0","subPageOf":"0","pageName":"Home","pageUrl":"home","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"98","menu_id":"24","page_id":"14","listOrder":"0","subPageOf":"0","pageName":"About Us","pageUrl":"aboutus","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"99","menu_id":"24","page_id":"5","listOrder":"0","subPageOf":"97","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"100","menu_id":"24","page_id":"3","listOrder":"0","subPageOf":"99","pageName":"Support","pageUrl":"support","pageType":"system","isProtected":"1","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"101","menu_id":"24","page_id":"15","listOrder":"0","subPageOf":"0","pageName":"Terms and Conditions","pageUrl":"terms-and-conditions","pageType":"content","isProtected":"0","customerGroup":"1001","menuName":"Test Menu","menuType":"category","assignedGroup_id":"3","menuStatus":"Active"},{"menu_pages_id":"79","menu_id":"1","page_id":"5","listOrder":"3","subPageOf":"0","pageName":"Login","pageUrl":"login","pageType":"system","isProtected":"1","customerGroup":"1004","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"},{"menu_pages_id":"96","menu_id":"1","page_id":"44","listOrder":"8","subPageOf":"0","pageName":"Wholesale","pageUrl":"wholesale","pageType":"content","isProtected":"0","customerGroup":"1005, 1007","menuName":"Header Menu","menuType":"header","assignedGroup_id":"1","menuStatus":"Active"}]

Ответы [ 2 ]

1 голос
/ 12 июля 2020

Думаю, следует использовать рекурсию. Некоторый код, основанный на приблизительном примере ниже, будет работать:

$menus = "your flat menu array";

function getNestedMenu($menus,$subPageOf){
    $nestedMenus = array();
    foreach($menus as $menu){
        if($menu['subPageOf'] = $subPageOf){
            $nestedMenu = $menu;
            $nestedMenu['subPages'] = getNestedMenu($menus,$menu['page_id']);
            $nestedMenus[] = $nestedMenu;
        }
    }
    return $nestedMenus;
}

$myNestedMenus = getNestedMenu($menu,"0");

Используя приведенный выше код, вы также можете адаптировать его для создания вложенного ul li меню на основе html кода

0 голосов
/ 12 июля 2020

Исходя из того, что сказал Кевлашу, я смог заставить его работать, используя следующее.

$jsonMenu = json_decode($menus);
function makeMenu($jsonMenu,$parentId) {
    $menu .=  "<ul>";
    foreach ($jsonMenu as $pageInfo ) {
        $menuCustomerGroup = $pageInfo->customerGroup;
        $pageUrl = $pageInfo->pageUrl;
        $menuPageName = $pageInfo->pageName;
        $menuType = $pageInfo->menuType;
        $subPageOf = $pageInfo->subPageOf;
        $menu_pages_id = $pageInfo->menu_pages_id;
        if($menuType == 'category' &&  $subPageOf == $parentId){
            $menu .= "<li><a href='$pageUrl'>$menuPageName</a>".makeMenu($jsonMenu,$menu_pages_id)."</li>";
        }   
    }
    $menu .= "</ul>";
    return $menu;    
} 

$menu = makeMenu($jsonMenu,0);
$menu = str_replace("<ul></ul>",'', $menu);
echo $menu;

Это решение оставило пустые элементы

    внизу каждого подменю, поэтому я использовал замену строки чтобы удалить их перед выводом.
    Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
    ...