We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26709
    • 4 Posts
    Здравствуйте!

    Возник нестандартный вопрос. Есть дерево каталога товаров:

    Каталог товаров
    Новая техника
    Экскаваторы
    Колесные
    Товар 1
    Товар 2
    Товар 3

    Как в скрипте получить ИД товара 1, товара 2 и товара 3. Т.е. нужно получить в документе КАТАЛОГ ТОВАРОВ значение ИД дочернего документа 4 уровня. Я знаю, как получить для ближайшего дочернего, а вот как для 4 уровня? Да и еще без громоздкого кода, ума не приложу. Подскажите, пожалуйста. Очень нужно.
      • 1611
      • 591 Posts
      Можно заюзать wayfinder, но это изврат.

      Можно самому выбрать детей "каталога" их детей, и так далее четыре раза, а потом вывести требуемые id. Т.е. использовать рекурсию или хитрый цикл.
        • 785
        • 2,113 Posts
        Не совсем то, но похоже (я кусок кода вырвал из программы и кое-что убрал, может случайно добавились ошибки). Из этого можно дальше дорабатывать:
        function getids ($parent, $allids) {
        global $modx;
        $query = "SELECT id, isfolder FROM ".$modx->getFullTableName("site_content")." WHERE `parent` =$parent";
        $result= $modx->db->query($query);
        while ($row = $modx->db->getRow($result)) {
        	if ($row['isfolder']) {
        		$allids = getids ($row['id'], $allids);
        	} 
        	else { 
        		$allids[]=$row['id'];
        	}
        }
        return $allids;
        }



        Можно без обращения к базе, но так проще, да и если не только ID нужен, а еще и другие параметры, к базе все равно придется обращаться.
          Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
          Статьи о MODx, регулярно новые публикации
          • 1611
          • 591 Posts
          $allids похоже глобальным нужно объявить? и эта функция как раз вытащит id всеx листьев дерева, начинающегося в текущем документе.
            • 785
            • 2,113 Posts
            Quote from: Andrey at May 27, 2009, 10:11 AM

            $allids похоже глобальным нужно объявить?
            Нет, $allids передается как параметр при рекурсивном вызове и возвращается как результат функции. Вызов функции примерно такой:
            $allids = array ();
            $startid = (isset($startid)) ? $startid : $modx->documentIdentifier ;
            $allids = getids ($startid, $allids);
              Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
              Статьи о MODx, регулярно новые публикации
              • 31309
              • 70 Posts
              Если задача в том чтобы не отображать листья , а только ветки, то для wayfinder есть немного брутальное решение.. Папки значит шаблон каталог, а товары шаблон товар.. задал tv  - isproduct, по умолчанию product, назначил его шаблону "товар".  в rowTpl  такая штука <li class="[+wf.classnames+] [+isproduct+]"> .........</li>.. ну и в css  .product{display:none;}
                • 26709
                • 4 Posts
                Quote from: variable at May 27, 2009, 10:47 AM

                Если задача в том чтобы не отображать листья , а только ветки, то для wayfinder есть немного брутальное решение.. Папки значит шаблон каталог, а товары шаблон товар.. задал tv  - isproduct, по умолчанию product, назначил его шаблону "товар".  в rowTpl  такая штука <li class="[+wf.classnames+] [+isproduct+]"> .........</li>.. ну и в css  .product{display:none;}

                Собственно, задача, которую я пытаюсь решить, довольно непроста. Попытаюсь обрисовать ситуацию, может так будет легче определить способ решения.

                Как уже упомянул вначале, имеется каталог продукции с 4-мя уровнями вложенности. (не буду повторять структуру еще раз).
                Есть также в отдельной папке документы, которые представляют собой каталог брендов:

                Каталог брендов
                  бренд 1
                  бренд 2
                  бренд 3
                  бренд 4
                  и т.д.

                Т.е. всего есть 2 структуры: каталог продукции и каталог брендов, которые между собой никак не связаны.

                Каждому товару в каталоге с помощью ТВ присвоен бренд.

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

                Бренд 1
                  Новая техника
                      Экскаваторы
                        Колесные
                            Товар 1
                            Товар 3
                Бренд 2
                  Новая техника
                      Экскаваторы
                        Колесные
                            Товар 2
                и т.д.

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

                Хух. вроде понятно объяснил. smiley Если что, спрашивайте - уточню.

                Я сделал скрипт, который сначала считывает один бренд из папки брендов, потом берет из каталога продукции самую верхнюю папку, напр. НОВАЯ ТЕХНИКА, потом циклом докапывается до списка товаров(товар1, товар2, товар3) и определяет производителя у каждого их них. Если хоть один товар имеет производителя, соответсвующего текущему, то вся ветка документов отображается. И так цикл повторяется для каждой категории и для каждого бренда.

                НО! Когда я запустил этот скрипт, сервер сразу же сдох от нагрузки.  undecided Понятное дело, что большое количество циклов ему не понравилось.

                Как посоветуете решить эту задачу? Помучиться дальше  с рекурсией и циклами или же по-другому оргнизовать стуктуру сайта? Хотелось бы, чтобы каталог брендов и каталог товаров были независимымы, не мешали друг другу во время добавления товаров.

                И еще. Я выбрал такую структуру потому, что помимо вышеупомянутого меню на сайте выводится обычное меню, который использует только каталога товаров в том виде, в каком он есть - без брендов. И если объеденить оба каталога(бренды и товары) в один, то тогда решится вопрос номер 1. но возникнет проблема с обычным меню каталога. Так что я выбрал 2 независимых каталога.
                  • 31309
                  • 70 Posts
                  Хм., достойная задача.. Кроме как написать плагин, повесить его на OnDocFormSave, который во время записи товара запишет в дополнительный tv цепочку ид родителей до корня каталога, а потом через дитто по фильтрации по tv, по имени бренда, выводить эту цепочку дополнительным сниппетом , - решений пока не вижу..

                  UPD: а еще лучше записать эту цепочку(до папки в которй список товаров) в tv бренда, и оттуда уже выводить сниппетами.. т.е. в бренде будут все цепочки до родительских папок в которых лежат "их" товары..
                    • 29487
                    • 385 Posts
                    А если развить предложенный выше "брутальный" вариант:
                    1) Получить из базы список брендов. Один запрос к базе.
                    2) В переменную вывести меню каталога продукции со всеми товарами и значениями tv с брендом (например title="[+brend+]"): $all=$modx->runSnippet(’Wayfinder’, array(...)); Таким образом Wayfinder выполняется только один раз.
                    3) Для каждого бренда из списка циклом вывести его название + $all предварительно обработанный preg_replace, который удалит все лишние строки, ориентируясь на название бренда в пунктах меню. Думаю несколько вызовов preg_replace сервер потянет.
                      • 24489
                      • 60 Posts
                      [[UltimateParent? &topLevel=`4` &id=`каталог товаров`]]
                      а стандартный сниппет не решает проблему?
                        Плагин для ресайза картинок AutoResizer
                        Сниппет для вывода полей документа DocInfo

                        Создание ТВ типа checkbox/dropdown из списка дочерних документов tvsLinks