Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 18 Ответов
  • 1000 Просмотров
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Всем привет, спецы PHP вопрос к вам, я написал небольшой скрипт, который выводит иерархию категорий с вложенностью (это нужно для вывода меню), вопрос в том, что никак не могу добавить CSS класс к той категории, у которой есть потомки. Структура таблицы в БД следующая:
id title url parent_id

сам код
Код
<?php
$data_menu // сюда получаю массив категорий из базы

//рекурсивная функция для постороения меню

$cats = array();
foreach($data_menu as $cat){
        $cats_ID[$cat['id']][] = $cat;
        $cats[$cat['parent_id']][$cat['id']] =  $cat;
      }
 
  function build_tree($cats,$parent_id,$only_parent = false){
    if(is_array($cats) and isset($cats[$parent_id])){
        $tree = '<ul>';
        if($only_parent==false){
            foreach($cats[$parent_id] as $cat){

if(is_numeric($parent_id)){
  $tree .= '<li>';
  $tree .= '<a href="'.$cat['url'].'">'.$cat['title'].' #'.$cat['id'].'</a>';
                  $tree .=  build_tree($cats,$cat['id']);
                  $tree .= '</li>';

} elseif($parent_id == false) {
 
                  $tree .= '<li>';
  $tree .= '<a href="'.$cat['url'].'">'.$cat['title'].' #'.$cat['id'].'</a>';
                  $tree .= '</li>';

}
            }
        } elseif(is_numeric($only_parent)){
            $cat = $cats[$parent_id][$only_parent];
            $tree .= '<li>'.$cat['title'].' #'.$cat['id'];
            $tree .=  build_tree($cats,$cat['id']);
            $tree .= '</li>';
        }
        $tree .= '</ul>';
    }
    else return null;
    return $tree;
}

echo build_tree($cats,0); //так вывожу дерево категорий с вложенностью

echo build_tree($cats,$parent_id = false); // а так только родителей

// то есть нужна вот такая структура, если у родителя есть потомки, у <li> должен быть класс "dropdown"

?>

Я пока решил проблему добавлением в БД поля level, у которого если 0 то потомков нет, если 1 то первый уровень вложенности, если 2 то второй и т.д но мне такой подход не нравится, хотелось бы без него обойтись. Подскажите решение, заранее очень благодарен!
« Последнее редактирование: 17.01.2020, 13:06:10 от Шмайсер »
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #1 : 16.01.2020, 10:54:10 »
Проблема только в том, что не знаете как добавить класс? А чем вам помогает в этом знание уровня вложенности, которое в вашем решении хранится в БД?
И для чего нужен отдельный вывод дерева категорий и только родителей? Покажите пример того, что должно получиться на выходе (фрагмент хтмл-кода).
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #2 : 16.01.2020, 11:06:15 »
Не совсем если честно вас понял. Я не знаю как добавить класс той категории, у которой есть потомки. Знание уровней вложенности помогает в том, что

Код
<?php
if($cat['level'] == 1) {
 $dropdown = ' class="dropdown"';
} else {
 $dropdown = '';
}
?>

// HTML структура, которая должна быть на выходе

<ul>
    <li><a href="#!">Это категория без потомков</a></li>
    <li class="dropdown"><a href="#!">Это категория с потомками</a>
         <ul>
              <li><a href="#!">Это потомок первый</a></li>
              <li><a href="#!">Это потомок второй</a></li>
         </ul>
    </li>
</ul>




И для чего нужен отдельный вывод дерева категорий и только родителей?
Это я скопировал просто из файла, к теме не относится, а вообще для вывода меню без вложенности в футере (чтобы одной функцией делать 2 разных вывода меню)
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #3 : 16.01.2020, 11:20:49 »
Код
<?php
if($cat['level'] == 1) {
 $dropdown = ' class="dropdown"';
} else {
 $dropdown = '';
}
?>

Это б сработало, если у вас фиксированное количество уровней (а не "и т.д."). А так даже на первом уровне может и не быть вложенностей, а на втором и третьем - могут оказаться. Но в целом понятно теперь.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #4 : 16.01.2020, 11:41:51 »
Обычно делаю примерно так:
Код
<?php
$data_menu // сюда получаю массив категорий из базы

//рекурсивная функция для постороения меню

$cats = array(); // Массив категорий с индексами-ИДами. Можно было его сразу получить в $data_menu, если использовать запрос, вида $data_menu = $db->setQuery(...)->loadAssocList('id');
$tree = array(); // А это будет карта вашего дерева
foreach($data_menu as $cat){
    $cats[$cat['id']] = $cat;
    if(!isset($tree[$cat['parent_id']])) $tree[$cat['parent_id']] = array();
    $tree[$cat['id']] = array();
    $tree[$cat['parent_id']][$cat['id']] = &$tree[$cat['id']];
}
// Здесь можно посмотреть что получилось в $tree, если интересно print_r($tree);

// $parent_id - указывает начиная с какого родителя делать вывод
// $level - показывает сколько уровней вложенности выводить. -1 - все
function build_tree(&$cats, &$tree, $parent_id = 0, $level = -1){
    if(empty($tree[$parent_id])) return false;
    $html = '<ul>';
    foreach($tree[$parent_id] as $catid){
        $cat = $cats[$catid];
        $class = !empty($tree[$catid])? ' class="dropdown"' : '';
        $html .= '<li'.$class.'>';
        $html .= '<a href="'.$cat['url'].'">'.$cat['title'].' #'.$cat['id'].'</a>';
        if($level != 0) $html .= build_tree($cats, $tree, $catid, $level-1);
        $html .= '</li>';
    }
    $html .= '</ul>';
    return $html;
}

// теперь поле level в БД не требуется

echo build_tree($cats, $tree); //так выведется полное дерево
echo build_tree($cats, $tree, 4); //так выведется дерево потомков категории id=4
echo build_tree($cats, $tree, 0, 2); //так выведется 2 уровня категорий, начиная с верхней

Код не тестил, поэтому напишите, если что-то не заработает как надо.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #5 : 16.01.2020, 12:20:54 »
Спасибо, сейчас попробую, отпишусь по результатам))
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #6 : 16.01.2020, 12:36:56 »
Код не тестил, поэтому напишите, если что-то не заработает как надо.
К сожалению что-то не работает, ошибки такие:
 Illegal offset type в строке $cat = $cats[$catid];

и  Illegal offset type in isset or empty в строках if(empty($tree[$parent_id])) return false; и $class = !empty($tree[$catid])? ' class="dropdown"' : '';

Да, я забыл написать, этот код не на Joomla, простенькая самописочка для небольшого проекта. Обычный php+html+css, так что loadAssocList тут не актуально

« Последнее редактирование: 16.01.2020, 12:40:58 от Шмайсер »
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Re: Разобраться с небольшим кодом PHP
« Ответ #7 : 16.01.2020, 14:09:28 »
Если дело только в выявлении существования потомков, то намного проще:
Код
$has_children = [];

foreach ($cats as $cat) {
if (!empty($cat['PARENT_ID']) && !in_array($cat['PARENT_ID'], $has_children)) {
$has_children[] = $cat['PARENT_ID'];
}
}

foreach ($cats as $cat) {
$class = in_array($cat['ID'], $has_children)? 'dropdown' : '';
echo '<li class="' . $class.  '"><a href="#!">' . $cat['TITLE'] . '</a></li>';
}
Не будь паразитом, сделай что-нибудь самостоятельно!
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #8 : 16.01.2020, 14:14:35 »
К сожалению что-то не работает, ошибки такие:
Кусок исходного массива сможете приложить? У вас в одном месте индексы указаны большими буквами, а в другом - маленькими. надо знать точно. Да и протестировать тогда смогу.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #9 : 16.01.2020, 14:51:19 »
Кусок исходного массива сможете приложить? У вас в одном месте индексы указаны большими буквами, а в другом - маленькими. надо знать точно. Да и протестировать тогда смогу.

Вот та часть, где родитель с потомками, на publish и position не обращайте внимания, это отключалка и сортировка
Код
Array
(
    [0] => Array
        (
            [id] => 1
            [publish] => 1
            [url] => test1.html
            [title] => ГЛАВНАЯ
            [parent_id] => 0
            [position] => 1
        )

    [1] => Array
        (
            [id] => 2
            [publish] => 1
            [url] => test2.html
            [title] => ССЫЛКА ПОДМЕНЮ 1
            [parent_id] => 1
            [position] => 2
        )

    [2] => Array
        (
            [id] => 3
            [publish] => 1
            [url] => test3.html
            [title] => ССЫЛКА ПОДМЕНЮ 2
            [parent_id] => 1
            [position] => 3
        )
)

У вас в одном месте индексы указаны большими буквами, а в другом - маленькими
это не у меня, это у robert-а, у меня везде маленькими
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #10 : 16.01.2020, 15:08:57 »
Если дело только в выявлении существования потомков, то намного проще:
Код
$has_children = [];

foreach ($cats as $cat) {
if (!empty($cat['PARENT_ID']) && !in_array($cat['PARENT_ID'], $has_children)) {
$has_children[] = $cat['PARENT_ID'];
}
}

foreach ($cats as $cat) {
$class = in_array($cat['ID'], $has_children)? 'dropdown' : '';
echo '<li class="' . $class.  '"><a href="#!">' . $cat['TITLE'] . '</a></li>';
}
К сожалению не работает, добавляет пустой class="" всем категориям первого уровня, в том числе и тем у кого нет потомков. И не выводит title, то есть просто пустые <li> с пустым классом
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #11 : 16.01.2020, 15:21:06 »
Да, у меня там ошибка была в цикле. Попробуйте вот этот исправленный код (у меня отработало правильно):
Спойлер
[свернуть]
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Re: Разобраться с небольшим кодом PHP
« Ответ #12 : 16.01.2020, 15:25:27 »
это не у меня, это у robert-а, у меня везде маленькими
А это кто написал
Структура таблицы в БД следующая:
ID TITLE URL PARENT_ID
?
К сожалению не работает
Ясно, что нет - у вас же маленькими буквами, могли бы сами  догадаться их поменять.
« Последнее редактирование: 16.01.2020, 15:29:35 от robert »
Не будь паразитом, сделай что-нибудь самостоятельно!
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #13 : 16.01.2020, 15:43:37 »
Цитировать
Ясно, что нет - у вас же маленькими буквами, могли бы сами  догадаться их поменять.

не не, все маленькими везде, и я в вашем коде поменял на маленькие, в первом посте заглавными написал для наглядности, надо кстати заменить там, а то все путаются.
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #14 : 16.01.2020, 21:13:31 »
Да, у меня там ошибка была в цикле. Попробуйте вот этот исправленный код (у меня отработало правильно):
Спойлер
[свернуть]
Вот теперь то что нужно, спасибо огромное и плюс в репу)))
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #15 : 16.01.2020, 21:18:14 »
sivers,  вопрос чисто теоретически, такой скрипт будет сильно тормозить при, допустим, 10 000 категорий (включая вложенные)? Это я не для сейчас, просто на будущее, чисто потому что для вывода допустим разделов магазина очень на мой взгляд лаконичное и простое решение.
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #16 : 16.01.2020, 21:28:34 »
Не думаю, что будет удобным меню из 10 тыс пунктов. Даже разделы магазина лучше ограничивать парой уровней, иначе пользователю будет тяжело в них разобраться.

Это решение по выводу дерева обкатано мной многократно - проблем не наблюдается. Само дерево (карта) строится ссылками и потому лишнюю память не использует. Передача в рекурсии тоже ссылочная. Поэтому основной тормоз - это сам запрос к БД и (в некоторых случаях) - формирование ссылок. Это если их формируют на ходу (у вас из базы готовые берутся).

Ну и не забывайте про возможность кэширования хтмл-кода, полученного на выходе.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

Шмайсер

  • Давно я тут
  • 801
  • 35 / 3
Re: Разобраться с небольшим кодом PHP
« Ответ #17 : 16.01.2020, 21:40:54 »
Не думаю, что будет удобным меню из 10 тыс пунктов. Даже разделы магазина лучше ограничивать парой уровней, иначе пользователю будет тяжело в них разобраться.

Это решение по выводу дерева обкатано мной многократно - проблем не наблюдается. Само дерево (карта) строится ссылками и потому лишнюю память не использует. Передача в рекурсии тоже ссылочная. Поэтому основной тормоз - это сам запрос к БД и (в некоторых случаях) - формирование ссылок. Это если их формируют на ходу (у вас из базы готовые берутся).

Ну и не забывайте про возможность кэширования хтмл-кода, полученного на выходе.
Понял, спасибо! Про 10К категорий имелось ввиду не для меню, а для вывода категорий каталога ИМ, как вариант. По поводу запроса к БД так он же элементарный, без JOIN -ов, ну и PDO само собой. Кэширование разумеется то-же.
Разработка сайтов любой сложности, на Joomla 3.9-4.x и не только на ней. Пишу компоненты, модули и плагины на заказ. Переношу сайты с ветки 2.5.х на 4-ю версию Joomla. Пишу любые скрипты и интерфейсы.
*

sivers

  • Живу я здесь
  • 2489
  • 338 / 0
Re: Разобраться с небольшим кодом PHP
« Ответ #18 : 16.01.2020, 21:47:56 »
Понял, спасибо! Про 10К категорий имелось ввиду не для меню, а для вывода категорий каталога ИМ, как вариант. По поводу запроса к БД так он же элементарный, без JOIN -ов, ну и PDO само собой. Кэширование разумеется то-же.

Пожалуйста. И да, пособ годится для любых древовидных структур. Но при очень большой глубине вложенности можно достичь переполнения стека рекурсии (явно не в каталогах ИМ). Еще замечал, что когда количество проходов в цикле становится очень большим (100к и больше), то задержка выполнения тоже становится ощутимой. Если же у вас не более 50 тыс записей, то можно даже без кэширования обходиться.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Переход по ссылки и запуск функции? [РЕШЕНО]

Автор warlocksp

Ответов: 19
Просмотров: 1007
Последний ответ 21.02.2020, 12:06:24
от warlocksp
[РЕШЕНО] Скроллинг страницы вниз?

Автор warlocksp

Ответов: 3
Просмотров: 674
Последний ответ 02.02.2020, 15:56:55
от warlocksp
Как изнутри iframe вызвать внешнюю функцию? [РЕШЕНО]

Автор dm-krv

Ответов: 6
Просмотров: 912
Последний ответ 25.08.2019, 20:41:07
от dm-krv
Как получить объект с полной информацией о материале через API Joomla? [РЕШЕНО]

Автор dm-krv

Ответов: 4
Просмотров: 940
Последний ответ 03.08.2019, 16:30:51
от dm-krv
Скрытое определение e-mail адреса посетителя [РЕШЕНО]

Автор dm-krv

Ответов: 2
Просмотров: 536
Последний ответ 15.04.2019, 19:37:21
от dm-krv