Помогите достроить дерево категорий

AlexB57

Новичок
Всем привет!
Есть таблица
id | parent_id | name
1848 | 0 | Все для мужчин
1849 | 1848 | Аксессуары и Сумки
1850 | 1849 | Сумки
1851 | 1850 | Сумки через плечо
1852 | 1850 | Сумки для ноутбука
1853 | 1850 | Спортивные сумки
1854 | 1850 | Рюкзаки
1855 | 1850 | Кожаные сумки
1856 | 1850 | Дорожные сумки
1857 | 1849 | Аксессуары
1858 | 1857 | Ювелирные украшения
1859 | 1857 | Шарфы
1860 | 1857 | Чехлы для мобильного телефона
1861 | 1857 | Часы
1862 | 1857 | Ремни
1863 | 1857 | Перчатки
1864 | 1857 | Очки
1865 | 1857 | Кошельки, обложки для документов
1866 | 1857 | Зонты
1867 | 1857 | Запонки
1868 | 1857 | Зажигалки
1869 | 1857 | Галстуки
1870 | 1857 | Браслеты
1871 | 1857 | Бижутерия
1872 | 1848 | Мужская одежда
1873 | 1872 | Шорты
1874 | 1873 | Бермуды
1875 | 1873 | Спортивные
1876 | 1872 | Футболки и поло
1877 | 1876 | Футболки
1878 | 1876 | Спортивные
1879 | 1876 | Майки
1880 | 1876 | Поло
1881 | 1872 | Толстовки
1882 | 1872 | Свитера, пуловеры
1883 | 1872 | Рубашки
1884 | 1872 | Пиджаки
1885 | 1884 | Пиджаки в стиле casual
1886 | 1884 | Классические пиджаки
1887 | 1872 | Жакеты
1888 | 1872 | Кофты и Кардиганы
1889 | 1872 | Костюмы
1890 | 1889 | Спортивные костюмы
1891 | 1889 | Классические костюмы
1892 | 1872 | Жилеты
1893 | 1892 | Меховые
1894 | 1892 | Классические
1895 | 1892 | Кожанные
1896 | 1892 | Дутые и стеганые
1897 | 1892 | Джинсовые
1898 | 1892 | В стиле casual
1899 | 1872 | Джинсы
1900 | 1899 | Прямой покрой
1901 | 1899 | Зауженные
1902 | 1872 | Головные уборы
1903 | 1902 | Шляпы
1904 | 1902 | Шапки
1905 | 1902 | Панамы
1906 | 1902 | Бейсболки, Кепки
1907 | 1872 | Верхняя одежда
1908 | 1907 | Пуховики
1909 | 1907 | Пальто
1910 | 1907 | Дубленка
1911 | 1907 | Куртки
1912 | 1907 | Вязанные кофты
1913 | 1872 | Брюки
1914 | 1913 | Спортивные
1915 | 1913 | Повседневные
1916 | 1913 | Классические
1917 | 1872 | Белье и Пляжная мода
1918 | 1917 | Трусы
1919 | 1917 | Термобелье
1920 | 1917 | Плавки
1921 | 1917 | Носки
1922 | 1917 | Майки
1923 | 1848 | Обувь
1924 | 1923 | Шлепанцы
1925 | 1923 | Угги
1926 | 1923 | Туфли
1927 | 1923 | Тапочки
1928 | 1923 | Сланцы
1929 | 1923 | Сапоги
1930 | 1923 | Сандали
1931 | 1923 | Резиновые сапоги
1932 | 1923 | Полуботинки
1933 | 1923 | Мокасины
1934 | 1923 | Кроссовки
1935 | 1923 | Кеды
1936 | 1923 | Галоши
1937 | 1923 | Ботинки

Есть скрипт который рекурсивно выводит категории в виде дерева

Код:
$cat_p = filter_input_var($_GET['cprod']);

//Выбираем данные из БД
$result=do_query("SELECT * FROM  tovars_categories");
//Если в базе данных есть записи, формируем массив
if   (mysql_num_rows($result) > 0){
    $cats = array();
//В цикле формируем массив разделов, ключом будет id родительской категории, а также массив разделов, ключом будет id категории
    while($cat =  mysql_fetch_assoc($result)){
        $cats_ID[$cat['id']][] = $cat;
        $cats[$cat['parent_id']][$cat['id']] =  $cat;
    }
}
// echo '<pre>';
// print_r($cats);
// echo '</pre>';

function build_tree($cats,$parent_id,$only_parent = false){
    if(is_array($cats) and isset($cats[$parent_id])){
  
    
    
        if($only_parent==false){
        $tree = '<ul>';
            foreach($cats[$parent_id] as $cat){ 
               $tree .= '<li class="custom_id'.$cat['id'].'"><a class="" href="/?cprod='.$cat['id'].'">'.$cat['name'].'</a><span class="down"></span>';
                $tree .=  build_tree($cats,$cat['id']);
                $tree .= '</li>';
                }
        $tree .= '</ul>';
        }elseif(is_numeric($only_parent)){
            $cat = $cats[$parent_id][$only_parent];
            $tree = '<li class="custom_id'.$cat['id'].'"><a class="" href="/?cprod='.$cat['id'].'">'.$cat['name'].'</a><span class="down"></span>';
            $tree .=  build_tree($cats,$cat['id']);
            $tree .= '</li>';
        }
      
    }
    else return null;
    return $tree;
}

function find_parent ($tmp, $cur_id){
    if($tmp[$cur_id][0]['parent_id']!=0){
        return find_parent($tmp,$tmp[$cur_id][0]['parent_id']);
    }
    return (int)$tmp[$cur_id][0]['id'];
}
Вот так вывожу в темплейте
Код:
<div class="box">
          <div class="box-heading">Категории</div>
          <div class="box-content box-category">
            <ul id="cat_accordion">
          
<?  echo build_tree($cats,0,find_parent($cats_ID,$cat_p)); ?>
</ul>
          </div>
        </div>
Скрипт не мой брал на просторах(немного лишь подправил)

Собственно все нормально работает, за исключением некоторых моментов, которые я не могу победить вторые сутки, поэтому прошу помощи у вас, господа профессионалы

Момент первый (просьба о помощи)

Определить что пользователь находится в текущей категории и добавить класс CSS для элемента <a>
Иначе говоря если GET совпадает с ID категории, нужно добавить класс

Я пробовал так:

Код:
if($cat_p == $cat['id']){
      $active = 'active';
      }else{
      $active = '';
      }
Где $cat_p есть GET содержащий id категории
Код:
$tree .= '<li class="custom_id'.$cat['id'].'"><a class="'.$active.'" href="/?cprod='.$cat['id'].'">'.$cat['name'].'</a><span class="down"></span>';
Но не получается, пробовал еще вариантов 5, та же фигня, моск кипит

Момент второй и снова прошу о помощи

Как не выводить самую главную категорию у которой parent_id равен нулю?

пробовал что-то типа этого

Код:
if($cat['parent_id'] != 0){

}
не фига не выходит

Как выводит сейчас:

+Все для мужчин
+-Аксессуары и Сумки
+---Подкатегория
+---Подкатегория
+---Подкатегория
+-Мужская одежда
+---Подкатегория
+---Подкатегория
+---Подкатегория
+-Обувь
+---Подкатегория
+---Подкатегория
+---Подкатегория

Что я хочу сделать, при нахождении в любой подкатегории раздела "для мужчин"

+Аксессуары и Сумки
+---Подкатегория
+---Подкатегория
+---Подкатегория
+Мужская одежда
+---Подкатегория
+---Подкатегория
+---Подкатегория
+Обувь
+---Подкатегория
+---Подкатегория
+---Подкатегория

Т.е. без самой родительской категории с parent_id = 0

PS Заранее спасибо всем откликнувшимся и помогающим мне в этих вопросах
 

AnrDaemon

Продвинутый новичок
Я не очень хорошо понял, что ты хочешь сделать... для себя я решил вопрос просто - рендерю по одной менюшке на каждый grp_id и складываю в кеш. При изменении элементов меню кеш на текущую и парент менюшку прибивается и при запросе регенерится. В страницу вставляется меню целиковым блоком из кеша.

А по поводу второго вопроса... Просто удалить то, что не нужно выводить. И не морочить себе голову.
 

riff

Новичок
Создай файл "test.php", без изменений добавь:
(если версия php < 5.4, то синтаксис описания массивов измени с $arr = []; на $arr = array(); )
PHP:
<?php

ini_set('display_errors', 1);
error_reporting(E_ALL | E_STRICT);

$rows = [
['id'=>1848,'parent_id'=>0,'name'=>'Все для мужчин'],
['id'=>1849,'parent_id'=>1848,'name'=>'Аксессуары и Сумки'],
['id'=>1850,'parent_id'=>1849,'name'=>'Сумки'],
['id'=>1851,'parent_id'=>1850,'name'=>'Сумки через плечо'],
['id'=>1852,'parent_id'=>1850,'name'=>'Сумки для ноутбука'],
['id'=>1853,'parent_id'=>1850,'name'=>'Спортивные сумки'],
['id'=>1854,'parent_id'=>1850,'name'=>'Рюкзаки'],
['id'=>1855,'parent_id'=>1850,'name'=>'Кожаные сумки'],
['id'=>1856,'parent_id'=>1850,'name'=>'Дорожные сумки'],
['id'=>1857,'parent_id'=>1849,'name'=>'Аксессуары'],
['id'=>1858,'parent_id'=>1857,'name'=>'Ювелирные украшения'],
['id'=>1859,'parent_id'=>1857,'name'=>'Шарфы'],
['id'=>1860,'parent_id'=>1857,'name'=>'Чехлы для мобильного телефона'],
['id'=>1861,'parent_id'=>1857,'name'=>'Часы'],
['id'=>1862,'parent_id'=>1857,'name'=>'Ремни'],
['id'=>1863,'parent_id'=>1857,'name'=>'Перчатки'],
['id'=>1864,'parent_id'=>1857,'name'=>'Очки'],
['id'=>1865,'parent_id'=>1857,'name'=>'Кошельки, обложки для документов'],
['id'=>1866,'parent_id'=>1857,'name'=>'Зонты'],
['id'=>1867,'parent_id'=>1857,'name'=>'Запонки'],
['id'=>1868,'parent_id'=>1857,'name'=>'Зажигалки'],
['id'=>1869,'parent_id'=>1857,'name'=>'Галстуки'],
['id'=>1870,'parent_id'=>1857,'name'=>'Браслеты'],
['id'=>1871,'parent_id'=>1857,'name'=>'Бижутерия'],
['id'=>1872,'parent_id'=>1848,'name'=>'Мужская одежда'],
['id'=>1873,'parent_id'=>1872,'name'=>'Шорты'],
['id'=>1874,'parent_id'=>1873,'name'=>'Бермуды'],
['id'=>1875,'parent_id'=>1873,'name'=>'Спортивные'],
['id'=>1876,'parent_id'=>1872,'name'=>'Футболки и поло'],
['id'=>1877,'parent_id'=>1876,'name'=>'Футболки'],
['id'=>1878,'parent_id'=>1876,'name'=>'Спортивные'],
['id'=>1879,'parent_id'=>1876,'name'=>'Майки'],
['id'=>1880,'parent_id'=>1876,'name'=>'Поло'],
['id'=>1881,'parent_id'=>1872,'name'=>'Толстовки'],
['id'=>1882,'parent_id'=>1872,'name'=>'Свитера, пуловеры'],
['id'=>1883,'parent_id'=>1872,'name'=>'Рубашки'],
['id'=>1884,'parent_id'=>1872,'name'=>'Пиджаки'],
['id'=>1885,'parent_id'=>1884,'name'=>'Пиджаки в стиле casual'],
['id'=>1886,'parent_id'=>1884,'name'=>'Классические пиджаки'],
['id'=>1887,'parent_id'=>1872,'name'=>'Жакеты'],
['id'=>1888,'parent_id'=>1872,'name'=>'Кофты и Кардиганы'],
['id'=>1889,'parent_id'=>1872,'name'=>'Костюмы'],
['id'=>1890,'parent_id'=>1889,'name'=>'Спортивные костюмы'],
['id'=>1891,'parent_id'=>1889,'name'=>'Классические костюмы'],
['id'=>1892,'parent_id'=>1872,'name'=>'Жилеты'],
['id'=>1893,'parent_id'=>1892,'name'=>'Меховые'],
['id'=>1894,'parent_id'=>1892,'name'=>'Классические'],
['id'=>1895,'parent_id'=>1892,'name'=>'Кожанные'],
['id'=>1896,'parent_id'=>1892,'name'=>'Дутые и стеганые'],
['id'=>1897,'parent_id'=>1892,'name'=>'Джинсовые'],
['id'=>1898,'parent_id'=>1892,'name'=>'В стиле casual'],
['id'=>1899,'parent_id'=>1872,'name'=>'Джинсы'],
['id'=>1900,'parent_id'=>1899,'name'=>'Прямой покрой'],
['id'=>1901,'parent_id'=>1899,'name'=>'Зауженные'],
['id'=>1902,'parent_id'=>1872,'name'=>'Головные уборы'],
['id'=>1903,'parent_id'=>1902,'name'=>'Шляпы'],
['id'=>1904,'parent_id'=>1902,'name'=>'Шапки'],
['id'=>1905,'parent_id'=>1902,'name'=>'Панамы'],
['id'=>1906,'parent_id'=>1902,'name'=>'Бейсболки, Кепки'],
['id'=>1907,'parent_id'=>1872,'name'=>'Верхняя одежда'],
['id'=>1908,'parent_id'=>1907,'name'=>'Пуховики'],
['id'=>1909,'parent_id'=>1907,'name'=>'Пальто'],
['id'=>1910,'parent_id'=>1907,'name'=>'Дубленка'],
['id'=>1911,'parent_id'=>1907,'name'=>'Куртки'],
['id'=>1912,'parent_id'=>1907,'name'=>'Вязанные кофты'],
['id'=>1913,'parent_id'=>1872,'name'=>'Брюки'],
['id'=>1914,'parent_id'=>1913,'name'=>'Спортивные'],
['id'=>1915,'parent_id'=>1913,'name'=>'Повседневные'],
['id'=>1916,'parent_id'=>1913,'name'=>'Классические'],
['id'=>1917,'parent_id'=>1872,'name'=>'Белье и Пляжная мода'],
['id'=>1918,'parent_id'=>1917,'name'=>'Трусы'],
['id'=>1919,'parent_id'=>1917,'name'=>'Термобелье'],
['id'=>1920,'parent_id'=>1917,'name'=>'Плавки'],
['id'=>1921,'parent_id'=>1917,'name'=>'Носки'],
['id'=>1922,'parent_id'=>1917,'name'=>'Майки'],
['id'=>1923,'parent_id'=>1848,'name'=>'Обувь'],
['id'=>1924,'parent_id'=>1923,'name'=>'Шлепанцы'],
['id'=>1925,'parent_id'=>1923,'name'=>'Угги'],
['id'=>1926,'parent_id'=>1923,'name'=>'Туфли'],
['id'=>1927,'parent_id'=>1923,'name'=>'Тапочки'],
['id'=>1928,'parent_id'=>1923,'name'=>'Сланцы'],
['id'=>1929,'parent_id'=>1923,'name'=>'Сапоги'],
['id'=>1930,'parent_id'=>1923,'name'=>'Сандали'],
['id'=>1931,'parent_id'=>1923,'name'=>'Резиновые сапоги'],
['id'=>1932,'parent_id'=>1923,'name'=>'Полуботинки'],
['id'=>1933,'parent_id'=>1923,'name'=>'Мокасины'],
['id'=>1934,'parent_id'=>1923,'name'=>'Кроссовки'],
['id'=>1935,'parent_id'=>1923,'name'=>'Кеды'],
['id'=>1936,'parent_id'=>1923,'name'=>'Галоши'],
['id'=>1937,'parent_id'=>1923,'name'=>'Ботинки'],
];

$current_id = array_key_exists('id', $_GET) ? $_GET['id'] : 0;

function build_tree($rows)
{
    $list = [];
    foreach ($rows as &$item)
    {
        $list[$item['id']] = &$item;
        unset($item);
    }

    $tree = [];
    foreach ($list as &$item)
    {
        if (array_key_exists($item['parent_id'], $list))
        {
            $list[$item['parent_id']]['#nodes'][] = &$item;
        }
        elseif ($item['parent_id'] == 0)
        {
            $tree[] = &$item;
        }
        unset($item);
    }

    return $tree;
}

function print_tree($nodes, $current_id) {
    ?>
        <ul>
            <? foreach($nodes as $node) { ?>
                <li class="custom_id<?=$node['id'] ?>">
                    <a class="<?=$node['id'] == $current_id ? 'active' : '' ?>" href="?id=<?=$node['id'] ?>"><?=htmlspecialchars($node['name']) ?></a><span class="down"></span>
                    <? if (isset($node['#nodes'])) print_tree($node['#nodes'], $current_id); ?>
                </li>
            <? } ?>
        </ul>
    <?
};

$tree = build_tree($rows);

?>

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        a {
            display: block;
        }
        a.active {
            background-color: #ffff00;
        }
    </style>
</head>
<body>
    <div>
        <? print_tree($tree, $current_id); ?>
        <? //print_tree($tree[0]['#nodes'], $current_id); // без главной ветки ?>
    </div>
</body>
</html>
 
Последнее редактирование:
  • Like
Реакции: WMix
Сверху