Курс 2016 года “Разработка на UMI.CMS от 0 до готового сайта”

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

*

cybermax

  • *
  • 16
  • +1/-0
    • Просмотр профиля
Дерево каталога товаров
« : 15 Ноября 2013, 20:37:23 »
Приветствую, народ, кто-нибудь писал модуль, который за один запрос позволяет получить всё дерево каталога, как вот тут http://key.ru/udata/catalog/category_list_xml ?
Если да, поделитесь пожалуйста.

*

admin

  • *****
  • 2444
  • +172/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #1 : 18 Ноября 2013, 09:57:03 »
Конкретно такой макрос не писал. По сути, макрос представляет из себя рекурсивный перебор всех страниц с соответствующей проверкой типа страницы (раздел или товары) и формирование соответствующего xml узла (массива).

P.S. Если у вас большой каталог, то формирование такого xml может замедлить загрузки страниц, на которой используется данный макрос. Так что, тут стоит помнить о нагрузке. Как варианты решения данного вопроса с нагрузкой может быть варианты с частичной подгрузкой, с сохранением результата в файл (кеширующий механизм) и т.п.

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #2 : 18 Ноября 2013, 16:48:42 »
То же не отказался бы от такого решения, но не нашел его!
Здесь скорее всего сформировано с помощью кэша, иначе создать такую выборку на лету в приницпе не реально, тк нагрзука будет грандиозная!

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #3 : 18 Ноября 2013, 17:07:12 »
Я бы одним запросом забрал все категории, а затем пробежался по ним и построил дерево. Делал подобное на symfony - практически никакой нагрузки на базу. Если интересно, на выходных могу набросать скрипт.
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #4 : 19 Ноября 2013, 12:47:10 »
Я бы одним запросом забрал все категории, а затем пробежался по ним и построил дерево. Делал подобное на symfony - практически никакой нагрузки на базу. Если интересно, на выходных могу набросать скрипт.
Конечно инетересно, выкладывайте!

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #5 : 20 Ноября 2013, 13:31:29 »
Набросал такой код. Местами сыроват, можно написать оптимальнее.

public function getRubricTree() {
           $sel = new selector('pages');
           $sel->types('hierarchy-type')->name('catalog', 'category');

           $arTree = array();
           $arRoots = array();
           $arCategories = array();

           $hierarchy = umiHierarchy::getInstance();

           foreach($sel as $category) {
               if(!$category instanceof umiHierarchyElement)
                   continue;

               $parent_id = $category->getParentId();

               $category_id = $category->getId();

               if($parent_id == 0) {
                   $arRoots[] = $category_id;
               }

               if(!isset($arTree[$parent_id])) {
                   $arTree[$parent_id] = array();
               }

               $arTree[$parent_id][] = $category_id;

               $arCategory = $this->prepareCategory($category, $hierarchy);

               $arCategories[$category_id] = $arCategory;
           }

           $return = array();

           foreach($arRoots as $root_id) {
               $return[] = $this->renderCategory($root_id, $arTree, $arCategories);
           }

           return array(
               'items' => array('nodes:item' => $return)
           );
       }

       public function prepareCategory($category, $hierarchy) {
           $category_id = $category->getId();

           $arCategory = array(
               'attribute:id' => $category_id,
               'attribute:name' => $category->getName(),
               'attribute:link' => $hierarchy->getPathById($category_id),
           );

           return $arCategory;
       }

       public function renderCategory($id, $arTree, $arCategories) {
           $items = array();
           $line = isset($arCategories[$id]) ? $arCategories[$id] : array();

           if(count($arTree[$id]) > 0) {
               foreach($arTree[$id] as $child_id) {
                   $items[] = $this->renderCategory($child_id, $arTree, $arCategories);
               }
           }

           if(count($items) > 0)
               $line['items'] = array('nodes:item' => $items);

           return self::parseTemplate('default', $line);
       }
           }

           if(count($items) > 0)
               $line['items'] = array('nodes:item' => $items);

           return self::parseTemplate('default', $line);
       }

Работает только в xslt-шаблонизаторе.

Пример работы макроса - http://demo.umispec.ru/udata://custom/getRubricTree/
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #6 : 20 Ноября 2013, 21:49:16 »
Макрос хороший, отилично работает, но вот проблема если категории не находятся в общем каталоге - shop?
А располагаются отдельно?
Тогда их вообще получается ни как не разделить?

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #7 : 20 Ноября 2013, 22:14:21 »
Макрос хороший, отилично работает, но вот проблема если категории не находятся в общем каталоге - shop?
А располагаются отдельно?
Тогда их вообще получается ни как не разделить?

Макрос "подбирает" все категории, которые есть на сайте. Специально для теста добавлял категорию рядом с /shop/ - макрос отлично работал.
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #8 : 20 Ноября 2013, 22:25:46 »
А как тогда разделение происходит?
Например есть 10 категорий, и 5 из них должны быть объеденены одной, не изменяя их размещение в структуре, и последние пять так же!?

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #9 : 20 Ноября 2013, 22:28:55 »
А как тогда разделение происходит?
Например есть 10 категорий, и 5 из них должны быть объеденены одной, не изменяя их размещение в структуре, и последние пять так же!?

В смысле разделение? Макрос выводит дерево категорий в том порядке, в котором они занесены в модуле "Структура". Если у Вас своя архитектура категорий, нужно изменить логику работы макроса.

Повторюсь, макрос решает следующую задачу - "за один запрос позволяет получить всё дерево каталога".
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #10 : 29 Января 2014, 16:34:44 »
Почему не работает?
Выводит только второй уровень, категорий а третий почему то нет(!

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #11 : 31 Января 2014, 09:24:16 »
public function getRubricTree($root_category_id, $i_need_deep = 1) {
            if((string) $root_category_id != '0') $root_category_id = $this->analyzeRequiredPath($root_category_id);

            if (!$i_need_deep) $i_need_deep = intval(getRequest('param2'));
            if (!$i_need_deep) $i_need_deep = 0;
            $i_need_deep = intval($i_need_deep);
            if ($i_need_deep === -1) $i_need_deep = 100;

            $sel = new selector('pages');
            $sel->types('hierarchy-type')->name('catalog', 'category');
            $sel->where('hierarchy')->page($root_category_id)->childs($i_need_deep);

            $arTree = array();
            $arRoots = array();
            $arCategories = array();

            $hierarchy = umiHierarchy::getInstance();

            foreach($sel as $category) {
                if(!$category instanceof umiHierarchyElement)
                    continue;

                $parent_id = $category->getParentId();

                $category_id = $category->getId();

                if($parent_id == $root_category_id) {
                    $arRoots[] = $category_id;
                }

                if(!isset($arTree[$parent_id])) {
                    $arTree[$parent_id] = array();
                }

                $arTree[$parent_id][] = $category_id;

                $arCategory = $this->prepareCategory($category, $hierarchy);

                $arCategories[$category_id] = $arCategory;
            }

            $return = array();

            foreach($arRoots as $root_id) {
                $return[] = $this->renderCategory($root_id, $arTree, $arCategories);
            }

            return array(
                'items' => array('nodes:item' => $return)
            );
        }

        public function prepareCategory($category, $hierarchy) {
            $category_id = $category->getId();

            $arCategory = array(
                'attribute:id' => $category_id,
                'attribute:name' => $category->getName(),
                'attribute:link' => $hierarchy->getPathById($category_id),
            );

            return $arCategory;
        }

        public function renderCategory($id, $arTree, $arCategories) {
            $items = array();
            $line = isset($arCategories[$id]) ? $arCategories[$id] : array();

            if(count($arTree[$id]) > 0) {
                foreach($arTree[$id] as $child_id) {
                    $items[] = $this->renderCategory($child_id, $arTree, $arCategories);
                }
            }

            if(count($items) > 0)
                $line['items'] = array('nodes:item' => $items);

            return self::parseTemplate('default', $line);
        }

Версия 2.0 с возможностью выбора начального уровня и глубины. Оптимально сочетается с custom/xsltCache для построения меню на сайте. За примерами -  в ЛС,
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/

*

muldy

  • ***
  • 222
  • +9/-1
    • Просмотр профиля
Re:Дерево каталога товаров
« Ответ #12 : 03 Февраля 2014, 14:24:58 »
Странная история!
Вызываю в браузере через udata:custom все работает, а вот использую в xslt, то все тихо!
<xsl:apply-templates select="document('udata://custom/getRubricTree/')/udata" mode="main_menu_2" />

С чем может быть связано подобное?

*

e.ioffe

  • ****
  • 369
  • +81/-2
  • Профессиональная разработка на UMI.CMS.
    • Просмотр профиля
    • Fullspace - Лучший хостинг для UMI.CMS
Re:Дерево каталога товаров
« Ответ #13 : 03 Февраля 2014, 14:37:20 »
Странная история!
Вызываю в браузере через udata:custom все работает, а вот использую в xslt, то все тихо!
<xsl:apply-templates select="document('udata://custom/getRubricTree/')/udata" mode="main_menu_2" />

С чем может быть связано подобное?

Как минимум с тем, что у 2-го скрипта обязательный параметр root_category_id
Ускорение сайта на UMI.CMS - http://speed.umispec.ru/