Сортировка по параметрам

#
Сортировка по параметрам
Здравствуйте! Хочу форму с параметрами для сортировки вывести на главную страницу сайта. Будет ли корректно, если я воспользуюсь методом ShowShop и при этом укажу id группы, в которой необходимо производить подбор по параметрам? Или есть какой-то другой способ вывода такой формы. более корректный?
Модератор
#
Re: Сортировка по параметрам
tomweb,
Вполне корректно, указывайте, показывайте и проверяйте работу.
#
Re: Сортировка по параметрам
А как можно реализовать следующий функционал:
Имеется интернет магазин со структурой:
Группа1
   Подгруппа11 (перый уровень вложенности)
      Подгруппа21(второй уровень вложенности)
         Товар1
         Товар2
      Подгруппа22
         Товар1
         Товар2
      ...
      Подгруппа2N
   Подгруппа12
      Подгруппа21
      Подгруппа22
      ...
      Подгруппа2N
   ...
   Подгруппа1N
Группа2
   Подгруппа11
      Подгруппа21
      Подгруппа22
      ...
      Подгруппа2N
   Подгруппа12
   ...
   Подгруппа1N
   
Как можно сделать так, чтобы когда заходишь в Группу, то выводились только названия подгрупп (как сейчас и есть).
Но при отправке данных формы сортировки с главной страницы выводились все товары данной группы, удовлетворяющие критериям сортировки
#
Re: Сортировка по параметрам
Есть вариант. если была нажата кнопка сортировки на главной странице, то перенаправлять, например, в группу1 с соответствующими критериями сортировки, но при этом надо выводить товары всех вложенных подгрупп. А товары имеются только в конечной подгруппе. Попробовал много способов отображения товаров из вложенных подгрупп, предлагаемых на форуме, но почему-то не получается. Можете посоветовать что-то?
Модератор
#
Re: Сортировка по параметрам
tomweb писал(а):
Но при отправке данных формы сортировки с главной страницы выводились все товары данной группы, удовлетворяющие критериям сортировки

Давайте начнем с начала - формы сортировки (по убыванию, по возрастанию) или фильтрации по параметрам?
tomweb писал(а):
но при этом надо выводить товары всех вложенных подгрупп

посмотрите форум, примеры выборки товаров из вложенных подгрупп уже предоставлялись.
#
Re: Сортировка по параметрам
HostCMS писал(а):
Давайте начнем с начала — формы сортировки (по убыванию, по возрастанию) или фильтрации по параметрам?

Фильтрация по параметрам.
HostCMS писал(а):
посмотрите форум, примеры выборки товаров из вложенных подгрупп уже предоставлялись.

Пробовал уже много примеров из форума, ни один пример не помог к сожалению.
Модератор
#
Re: Сортировка по параметрам
tomweb,
Покажите, пожалуйста, фрагменты, которые Вы вносили для реализации задачи и что не получилось.
Логика следующая - если применен фильтр, то нужно в качестве группы указать false и через доп. условия выборки указать что группа IN (массив подгрупп, включая текущую)
#
Re: Сортировка по параметрам
Вот весь код магазина, жирным выделено то, что вносил я:
<?php

function SetGroups($mas_groups, $set)
{
   $mas_groups = to_array($mas_groups);
   foreach ($mas_groups as $key=>$value)
   {

      foreach ($value as $key1=>$value1)
      {
         $set[] = $value1['shop_groups_id'];
         if ($value1['shop_groups_id'] == $key)
         {
            $set[] = $key;
            SetGroups($mas_groups, $set);
         }
      }

   }
   return $set;
}

$xsl_catalog = to_str($GLOBALS['LA']['xsl_catalog']);
$xsl_item = to_str($GLOBALS['LA']['xsl_item']);
$current_shop_id = to_int($GLOBALS['LA']['shop_id']);

$param = array();

$shop = & singleton('shop');

if ($GLOBALS['shop_item_path'] != false)
{
   $external_propertys = array();

   if (class_exists("SiteUsers"))
   {
      /* Получаем id текущего пользователя сайта */
      $SiteUsers = & singleton('SiteUsers');
      $site_user_id = $SiteUsers->GetCurrentSiteUser();
      $param['user_id'] = $site_user_id;
      $external_propertys['user_id'] = $SiteUsers->GetCurrentSiteUser();
   }
   else
   {
      $site_user_id = 0;
      $external_propertys['user_id'] = 0;
   }

   // Если добавление комментария
   if (isset($_POST['submit_comment']) && !empty($GLOBALS['shop_item_path']['item']))
   {
      /* Проверяем CAPCHA*/
      $Captcha = new Captcha();

      $xmlData = '<?xml version="1.0" encoding="' . SITE_CODING . '"?>' . "\n";
      $xmlData .= '<document>' . "\n";

      if ($site_user_id > 0
      || $Captcha->ValidCaptcha(to_str($_POST['captcha_key']), to_str($_POST['captcha_keystring'])))
      {
         $param['shop_items_catalog_item_id'] = $GLOBALS['shop_item_path']['item'];
         $param['shop_comment_user_name'] = to_str($_REQUEST['shop_comment_user_name']);

         $param['shop_comment_user_email'] = to_str($_REQUEST['shop_comment_user_email']);
         $param['shop_comment_subject'] = to_str($_REQUEST['shop_comment_subject']);
         $param['shop_comment_text'] = to_str($_REQUEST['shop_comment_text']);
         $param['shop_comment_grade'] = to_int($_REQUEST['shop_comment_grade']);
         $param['shop_comment_date_time'] = date("Y-m-d H:i:s");

         /* Активность/неактивность комментария */
         $shop_row = $shop->GetShop($current_shop_id);

         if ($shop_row)
         {
            $param['shop_comment_active'] = to_int($shop_row['shop_comment_active']);
         }
         else
         {
            $param['shop_comment_active'] = false;
         }

         $external_propertys['comment_is_active'] = $param['shop_comment_active'];

         // Если есть модуль "Пользователи сайта", получим текущего пользователя
         if (class_exists('SiteUsers'))
         {
            $SiteUsers = & singleton('SiteUsers');
            $param['site_users_id'] = $SiteUsers->GetCurrentSiteUser();
         }
         else
         {
            $param['site_users_id'] = 0;
         }

         $shop_comment_id = $shop->InsertComment($param);

         // Задан XSL для формирования письма администратору о добавлении комментария к товару
         if (to_str($GLOBALS['LA']['xsl_add_comment_letter_to_admin']) != '')
         {
            // Формируем XML для комментария
            $xmlData .= $shop->GenXml4Comment($shop_comment_id);
            $xmlData .= '</document>' . "\n";

            $xsl = new xsl();
            // Формируем текст письма администратору
            $message = $xsl->build($xmlData, $GLOBALS['LA']['xsl_add_comment_letter_to_admin']);

            // Формат письма - текст
            if (to_int($GLOBALS['LA']['comment_mail_type']) == 0)
            {
               $comment_mail_type = 'text/plain';
            }
            else
            {
               $comment_mail_type = 'text/html';
            }

            $subject = $GLOBALS['MSG_shops']['subject_report_for_comment'];

            $kernel = & singleton('kernel');
            $kernel->SendMailWithFile(EMAIL_TO, EMAIL_TO, $subject, $message, array(), $comment_mail_type);
         }
      }
      else
      {
         /* Неправильно введен код изображенный на картинке */
         $external_propertys['error'] = 1;

         /* Запоминаем значения */
         $external_propertys['shop_comment_user_name'] = strip_tags(to_str($_REQUEST['shop_comment_user_name']));
         $external_propertys['shop_comment_user_email'] = strip_tags(to_str($_REQUEST['shop_comment_user_email']));
         $external_propertys['shop_comment_subject'] = strip_tags(to_str($_REQUEST['shop_comment_subject']));
         $external_propertys['shop_comment_text'] = strip_tags(to_str($_REQUEST['shop_comment_text']));
         $external_propertys['shop_comment_grade'] = to_int($_REQUEST['shop_comment_grade']);
         $external_propertys['shop_comment_date_time'] = date("Y-m-d H:i:s");
      }
   }

   /* Вывод списка */
   if (!$GLOBALS['shop_item_path']['item'])
   {
      $param['current_group_id'] = $GLOBALS['shop_item_path']['group']; // корневая группа
      
      $groups = $GLOBALS['URL_ARRAY'];
      
      //Если находимся в корне дисков
      if($param['current_group_id'] == 589){
         $xsl_catalog = 'МагазинКаталогДисков';
      }
      
      //Если находимся в одной из подгрупп категорий магазина
      if(isset($groups[2])){
         //Если находимся в шинах
         if($groups[1] == "tyres"){
            $xsl_catalog = 'МагазинКаталогШин';
         }
         //Если находимся в дисках
         else if($groups[1] == "wheels"){
            $xsl_catalog = 'КаталогДисков';
         }
      }
                        
      /* Определяем номер элемента, с которого начинается показ в текущей группе */
      $page = end($GLOBALS['URL_ARRAY']);
      $page = to_str($page);

      $shop_row = $shop->GetShop($current_shop_id);
      if ($shop_row)
      {
         $items_on_page = $shop_row['shop_items_on_page'];
      }
      else
      {
         $items_on_page = 10;
      }

      /*
       Порядок сортировки ('Asc' - по возрастанию, 'Desc' - по убыванию, 'Rand' - произвольный порядок)
       $param['items_order']='Asc';
       Поле, по которому сортируем (наименование элемента)
       $param['items_field_order']='shop_items_catalog_name';
       */

      /* Ограничиваем по производителю */
      if (to_int($_GET['producer_id']) > 0)
      {
         $element['type'] = 0; // 0 - основное св-во, 1 - дополнительное
         $element['name'] = 'shop_producers_list_id';
         $element['prefix'] = 'AND'; // префикс
         $element['if'] = '='; // Условие
         $element['value'] = to_int($_GET['producer_id']);
         $element['sufix'] = '';
         $param['select'][] = $element;

         $external_propertys['producer_id'] = to_int($_GET['producer_id']);

         /* Применять фильтр */
         $external_propertys['apply_filter'] = true;
      }

      /* Ограничиваем по продавцу */
      if (to_int($_GET['saller_id']) > 0)
      {
         $element['type'] = 0; // 0 - основное св-во, 1 - дополнительное
         $element['name'] = 'shop_sallers_id';
         $element['prefix'] = 'AND'; // префикс
         $element['if'] = '='; // Условие
         $element['value'] = to_int($_GET['saller_id']);
         $element['sufix'] = '';
         $param['select'][] = $element;

         $external_propertys['saller_id'] = to_int($_GET['saller_id']);

         /* Применять фильтр */
         $external_propertys['apply_filter'] = true;
      }
      
      $price_from = str_replace(',', '.', to_float($_GET['price_from']));

      /* Ограничиваем по цене ОТ */
      if ($price_from > 0)
      {
         $external_propertys['price_from'] = $price_from;

         /* Применять фильтр */
         $external_propertys['apply_filter'] = true;
      }

      $price_to = str_replace(',', '.', to_float($_GET['price_to']));

      /* Ограничиваем по цене ДО */
      if ($price_to > 0)
      {
         $external_propertys['price_to'] = $price_to;

         /* Применять фильтр */
         $external_propertys['apply_filter'] = true;
      }

      /* Число элементов на странице */
      $on_page = to_int($_GET['on_page']);
      if ($on_page > 0 && $on_page < 150)
      {
         $param['items_on_page'] = $on_page;
         $external_propertys['on_page'] = $on_page;

         /* Применять фильтр */
         $external_propertys['apply_filter'] = true;
      }

      // Определяем номер страницы.
      if ($on_page)
      {
         $items_on_page = $on_page;
      }
      if (ereg("^page-([0-9]*)$", $page, $regs) && to_int($regs[1]) > 1)
      {
         /* Страница умножается на кол-во элементов, выводимых на страницу */
         $items_begin = ($regs[1] - 1) * $items_on_page;
      }
      else
      {
         $items_begin = 0;
      }

      $param['items_begin'] = $items_begin;

      /* Направление сортировки, 0 - по-возрастанию, 1 - по-убыванию */
      $order_direction = to_int($_GET['order_direction']);
      switch ($order_direction)
      {
         case 1: /* По-возрастанию */
            {
               $order_direction = 'ASC';
               break;
            }
         case 2: /* По-убыванию */
            {
               $order_direction = 'DESC';
               break;
            }
         default: /* По-умолчанию */
            {
               $order_direction = 'ASC';
               break;
            }
      }

      /* Поле сортировки */
      $sort_field = to_int($_GET['sort_by_field']);
      switch ($sort_field)
      {
         case 1: /* По имени */
            {
               $param['items_field_order'] = 'shop_items_catalog_name';
               $param['items_order'] = $order_direction;
               $external_propertys['sort_by_field'] = $sort_field;
               $external_propertys['order_direction'] = $order_direction;
               break;
            }
         case 2: /* По цене */
            {
               //$param['items_field_order'] = 'shop_items_catalog_price';
               $param['items_field_order'] = 'item_price_absolute';
               $param['items_order'] = $order_direction;
               $external_propertys['sort_by_field'] = $sort_field;
               $external_propertys['order_direction'] = $order_direction;
               break;
            }
         case 3:  /* По оценке*/
            {
               $param['items_field_order'] = 'shop_comment_grade';
               $param['items_order'] = $order_direction;
               $external_propertys['sort_by_field'] = $sort_field;
               $external_propertys['order_direction'] = $order_direction;
               break;
            }
      }

      // Задан фильтр и/или сортировка по цене
      if ($price_from > 0 || $price_to > 0 || $sort_field == 2)
      {
         // Получаем список валют магазина
         $currency_result = $shop->GetAllCurrency();

         $query_currency_switch = 'shop_items_catalog_price';

         // Цикл по валютам магазина
         while ($currency_row = mysql_fetch_assoc($currency_result))
         {
            // Получаем коэффициент пересчета для каждой валюты
            $currency_coefficient = $shop->GetCurrencyCoefficientToShopCurrency($currency_row['shop_currency_id'], $shop_row['shop_currency_id']);

            $query_currency_switch = "IF (shop_items_catalog_table.shop_currency_id = {$currency_row['shop_currency_id']}, shop_items_catalog_table.shop_items_catalog_price * $currency_coefficient, $query_currency_switch)";
         }

         $param['sql_external_select'] = ' ,' . $query_currency_switch . ' AS item_price_absolute';
      }

      /* Обработка дополнительных свойств.
       Получаем список свойств, разрешенных для отображения в данной группе и в фильтре */
      $resource_properties = $shop->GetPropertiesOfGroupForXml($current_shop_id, $param['current_group_id']);

      if ($resource_properties)
      {
         $element['type'] = 0; /* 0 - основное св-во, 1 - дополнительное */

         /* Префикс, если нужен. */
         $element['prefix'] = ' and ('; // префикс

         /* ОСТАВЛЯЕТЕ БЕЗ ИЗМЕНЕНИЙ, ЭТО НУЖНО ДЛЯ СОРТИРОВКИ */
         $element['name'] = ''; // Имя

         /* поля для основного св-ва, если тип = 1, то не указывается */
         $element['if'] = ''; // Условие

         /* Вот здесь передается ID доп. св-ва, по которому производится сортировка.
          ID ВАШЕГО ПОЛЯ УКАЗЫВАЕТЕ ЗДЕСЬ */
         $element['value'] = ''; /* Значение поля (или параметра) */
         $element['sufix']=' ';

         /* Добавляем в общий список условий */
         $param['select'][] = $element;
         $count_condition = 0;         
         $property_xml = '';

         $count_properties = mysql_num_rows($resource_properties);

         for ($i = 0; $i < $count_properties; $i++)
         {
            $row = mysql_fetch_assoc($resource_properties);

            $element['value'] = 0;

            foreach ($_GET as $key => $value)
            {
               if (preg_match("/property_id_{$row['shop_list_of_properties_id']}_item_id_(\d*)/", $key, $matches))
               {
                  $get_param = 'property_id_'.$row['shop_list_of_properties_id'].'_item_id_'.$matches[1];
                  if (isset($_GET[$get_param]) > 0 && to_int($matches[1]) > 0)
                  {
                     $element['value'] = to_int($matches[1]);
                     $external_propertys['property_id_'.to_int($row['shop_list_of_properties_id']).'_item_id_'.$element['value']] = $element['value'];
                     $property_xml .= '&property_id_'.to_int($row['shop_list_of_properties_id']).'_item_id_'.$element['value'].'='.$element['value'];
                  }
               }
            }

            /* Выбираем режим отображения */
            $get_param = 'property_id_'.$row['shop_list_of_properties_id'];
            if (isset($_GET[$get_param]))
            {
               if ($row['shop_list_of_properties_type'] == 0 || $row['shop_list_of_properties_show_kind'] == 1)
               {
                  if (to_str($_GET[$get_param]) ==! "")
                  {
                     $element['value'] = quote_smart(to_str($_GET[$get_param]));
                     $external_propertys['property_id_'.to_int($row['shop_list_of_properties_id'])] = $element['value'];
                     $property_xml .= '&property_id_'.to_int($row['shop_list_of_properties_id']).'='.$element['value'];
                  }
               }
               // Флажок
               elseif($row['shop_list_of_properties_type'] == 7)
               {
                  $element['value'] = 1;
                  $external_propertys['property_id_'.to_int($row['shop_list_of_properties_id'])] = $element['value'];
                  $property_xml .= '&property_id_'.to_int($row['shop_list_of_properties_id']).'='.$element['value'];
               }
               else
               {
                  if (to_int($_GET[$get_param]) > 0)
                  {
                     $element['value'] = to_int($_GET[$get_param]);
                     $external_propertys['property_id_'.to_int($row['shop_list_of_properties_id'])] = $element['value'];
                     $property_xml .= '&property_id_'.to_int($row['shop_list_of_properties_id']).'='.$element['value'];
                  }
               }
            }
            if ($element['value'])
            {
               /* Применять фильтр */
               $external_propertys['apply_filter'] = true;

               $element['property_id'] = to_int($row['shop_list_of_properties_id']);
               $element['type'] = 1; /* 0 - основное св-во, 1 - дополнительное */
               //$element['prefix'] = 'AND'; /* префикс */
               $element['if'] = '='; /* Условие */
               $element['sufix'] = '';
               if ($count_condition)
               {
                  $element['prefix'] = ' or '; /* префикс */
               }
               else
               {
                  $element['prefix'] = ' '; /* префикс */
               }

               $count_condition++;
               $param['select'][] = $element;
            }
         }

         if (!$count_condition)
         {
            $element['prefix'] = ' 1'; /* префикс */
         }
         else
         {
            $element['prefix'] = ''; // префикс
         }
         /* добавляем конечный элемент, содержащий HAVING */
         $element['type'] = 0; /* 0 - основное св-во, 1 - дополнительное */

         /* ОСТАВЛЯЕТЕ БЕЗ ИЗМЕНЕНИЙ, ЭТО НУЖНО ДЛЯ СОРТИРОВКИ */
         $element['name'] = ''; /* Имя */

         /* поля для основного св-ва, если тип = 1, то не указывается */
         $element['if'] = ''; /* Условие */

         /* Вот здесь передается ID доп. св-ва, по которому производится сортировка.
          ID ВАШЕГО ПОЛЯ УКАЗЫВАЕТЕ ЗДЕСЬ */
         $element['value'] = ''; // Значение поля (или параметра)

         if ($count_condition != 0 && ($price_from > 0 || $price_to >0))
         {
            $param['sql_group_by'] = 'GROUP BY shop_items_catalog_table.shop_items_catalog_item_id';
               
            $param['sql_having'] = "HAVING COUNT(shop_properties_items_table.shop_properties_items_id) = {$count_condition}";
         }
         else
         {
            $param['sql_having'] = 'HAVING 1 ';
         }

         $element['sufix'] = ' ) ';

         /* Добавляем в общий список условий */
         $param['select'][] = $element;
      }
      else
      {
         $param['sql_having'] = 'HAVING 1 ';
         //$having_count = 'HAVING 1 ';
      }

      if ($price_from > 0)
      {
         $param['sql_having'] .= ' AND item_price_absolute >=' . $price_from;
         //$having_count .= ' AND item_price_absolute >=' . $price_from;
      }

      if ($price_to > 0)
      {
         $param['sql_having'] .= ' AND item_price_absolute <=' . $price_to;
         //$having_count .= ' AND item_price_absolute <=' . $price_to;
      }
         
      /* добавляем конечный элемент, содержащий HAVING */
      $element['type'] = 0; /* 0 - основное св-во, 1 - дополнительное */
      $element['prefix'] = ' AND';
      $element['name'] = 'shop_items_catalog_table.shop_shops_id'; /* Имя */
      $element['if'] = '='; /* Условие */
      $element['value'] = $current_shop_id; // Значение поля (или параметра)
      $element['sufix'] = '';
      //$element['sufix'] = $having_count;
      /* Добавляем в общий список условий */
      $param['select'][] = $element;

      if (!empty($property_xml))
      {
         $external_propertys['property_xml'] = $property_xml;
      }

      // Если передано имя тэга - фильтруем
      if (isset($GLOBALS['shop_item_path']['tag_name']))
      {
         if (class_exists('Tag'))
         {
            $oTag = & singleton('Tag');

            $tag_row = $oTag->GetTagByName($GLOBALS['shop_item_path']['tag_name']);

            $param['tags'] = array($tag_row['tag_id']);

            // При выводе тэгов вывод элементов ведется из всех групп
            $param['current_group_id'] = false;
         }
      }

      // При выводе списка товаров получать подробное описание каждого товара не нужно
      $param['show_text'] = false;

      // При выводе списка товаров получать сопутствующие товары не нужно
      $param['xml_show_tying_products'] = false;

      // Разрешаем передачу в XML свойств групп
      $param['xml_show_group_property'] = true;
      
      $mas_group = array();
      $mas_group = $shop->GetGroupsTree($GLOBALS['shop_item_path']['group'], $current_shop_id, $mas_group);
      $set = array();
      $set = SetGroups($mas_group, $set);
      $elements = array();

      $in = $GLOBALS['shop_item_path']['group'];

      foreach ($set as $key => $value)
      {
         $in .= ','.$value;
      }

      $elements['type']=0;
      $elements['prefix'] = ' and (';
      $elements['name'] = 'shop_items_catalog_table.shop_groups_id';
      $elements['if'] = ' IN ('.$in.') ';
      $elements['value'] = '';
      $elements['sufix']=')';
      $param['select'][]=$elements;
      $param['current_group_id']=false;


      $shop->ShowShop($current_shop_id, $xsl_catalog, $param, $external_propertys);
   }
   else
   {
      /* Вывод конкретного элемент */
      $shop->ShowItem($GLOBALS['shop_item_path']['item'], $xsl_item, $param, $external_propertys);
   }
}
?>
Модератор
#
Re: Сортировка по параметрам
tomweb,
Весьма неплохо. Небольшие изменения внес код (добавил условие):
/********/
      if (isset($_REQUEST['apply_filter']))
      {
         $mas_group = array();
         $mas_group = $shop->GetGroupsTree($GLOBALS['shop_item_path']['group'], $current_shop_id, $mas_group);
         $set = array();
         $set = SetGroups($mas_group, $set);
         $elements = array();

         $in = $GLOBALS['shop_item_path']['group'];

         foreach ($set as $key => $value)
         {
            $in .= ','.$value;
         }

         $elements['type'] = 0;
         $elements['prefix'] = ' and (';
         $elements['name'] = 'shop_items_catalog_table.shop_groups_id';
         $elements['if'] = ' IN ('.$in.') ';
         $elements['value'] = '';
         $elements['sufix'] = ')';
         $param['select'][] = $elements;
         
         // Выбираем из всех групп, ограниченных вышеуказанным условием
         $param['current_group_id'] = false;

         /* Отображать фильтр */
         $external_propertys['apply_filter'] = true;
      }
      /********/

в остальном проблем не вижу, у нас проверил указанное добавление - все отлично работает.
#
Re: Сортировка по параметрам
Да, все казалось бы прекрасно, но вот что мне возвращает функция SetGroups():
Array ( [0] => 5 [1] => 6 [2] => 6 [3] => 6 [4] => 6 [5] => 6 [6] => 6 [7] => 6 [8] => 6 [9] => 6 [10] => 6 [11] => 6 [12] => 6 [13] => 6 [14] => 6 [15] => 6 [16] => 6 )
Хотя групп с такими идентификаторами у меня нету!

А GetGroupsTree() выдает те, что нужно, но массив многомерный.
Авторизация