Вывод групп магазина с товарами в группах

#
Вывод групп магазина с товарами в группах
Нужно сделать одностраничный интернет магазин. Таким образом, чтобы выводилась группа, товары из группы, группа, товары. В таком виде:
- Группа 1 (только название)
  - товар 1.1
  - товар 1.2
  - товар 1.3
- Группа 2 (только название)
  - товар 2.1
  - товар 2.2
  - товар 2.3
И покупка осуществлялась в 1 клик, без перехода в магазин.
Поставил стандартный вывод в шаблоне и стандартный xsl-шаблон. Сейчас выводятся сперва группы, а потом все товары.
Искал на форуме поиском. Есть что-то похожее, но не совсем то что надо.
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
Вывод товаров из текущей группы и ее подгрупп
Посмотрите как реализовано в готовом шаблоне, дни недели это группы.
E-mail: info@syrbek.ru / телега: @syrbek /skype: activexm / syrbek.ru / Поддержка сайтов / г. Москва [HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, Git, SVN, Redmine]
#
Re: Вывод групп магазина с товарами в группах
Так же получается, сперва группы, потом товары. Вот такой код настроек у меня получился:
<?php

$oShop = Core_Entity::factory('Shop', Core_Array::get(Core_Page::instance()->libParams, 'shopId'));

/********************/

class My_Shop_Controller_Show extends Shop_Controller_Show
{
    protected function _groupCondition()
    {
        $oShop = $this->getEntity();

        if ($this->parentItem == 0)
        {
            // Отключаем выбор модификаций
            //!$this->_selectModifications && $this->forbidSelectModifications();
        
            $this->shopItems()
                ->queryBuilder()
                ->open();
        
            if ($this->group)
            {
                // если ID группы не 0, т.е. не корневая группа
                // получаем подгруппы
                $aSubGroupsID = $this->fillShopGroup($oShop->id, $this->group); // добавляем текущую группу в массив
                $aSubGroupsID[] = $this->group;

                $this->shopItems()
                    ->queryBuilder()
                    // получаем все товары из подгрупп
                    ->where('shop_items.shop_group_id', 'IN', $aSubGroupsID);
            }
            else
            {
                $this->shopItems()
                    ->queryBuilder()
                    ->where('shop_items.modification_id', '=', 0);
                    
                /*$this->shopItems()
                    ->queryBuilder()
                    ->where('shop_items.shop_group_id', '=', 0)
                    ;*/
            }
            
            $shop_group_id = !$this->parentItem
                ? intval($this->group)
                : 0;
            
            // Вывод модификаций на одном уровне в списке товаров
            if (!$this->item && $this->modificationsList)
            {
                $oCore_QueryBuilder_Select_Modifications = Core_QueryBuilder::select('shop_items.id')
                    ->from('shop_items')
                    ->where('shop_items.shop_id', '=', $oShop->id)
                    ->where('shop_items.deleted', '=', 0)
                    ->where('shop_items.active', '=', 1);

                if ($this->group)
                {
                    $oCore_QueryBuilder_Select_Modifications
                        ->where('shop_items.shop_group_id', 'IN', $aSubGroupsID); // получаем все товары из подгрупп
                }
                    
                // Стандартные ограничения для товаров
                $this->_applyItemConditionsQueryBuilder($oCore_QueryBuilder_Select_Modifications);

                Core_Event::notify(get_class($this) . '.onBeforeSelectModifications', $this, array($oCore_QueryBuilder_Select_Modifications));
                
                $this->_Shop_Items
                    ->queryBuilder()
                    ->setOr()
                    ->where('shop_items.shop_group_id', '=', 0)
                    ->where('shop_items.modification_id', 'IN', $oCore_QueryBuilder_Select_Modifications);
                    
                // Совместное modificationsList + filterShortcuts
                if ($this->filterShortcuts)
                {
                    $oCore_QueryBuilder_Select_Shortcuts_For_Modifications = Core_QueryBuilder::select('shop_items.shortcut_id')
                        ->from('shop_items')
                        ->where('shop_items.shop_id', '=', $oShop->id)
                        ->where('shop_items.deleted', '=', 0)
                        ->where('shop_items.active', '=', 1)
                        ->where('shop_items.shop_group_id', '=', $shop_group_id)
                        ->where('shop_items.shortcut_id', '>', 0);
                        
                    $this->_Shop_Items
                        ->queryBuilder()
                        ->setOr()
                        ->where('shop_items.shop_group_id', '=', 0)
                        ->where('shop_items.modification_id', 'IN', $oCore_QueryBuilder_Select_Shortcuts_For_Modifications);
                }
            }

            if ($this->filterShortcuts)
            {
                $oCore_QueryBuilder_Select_Shortcuts = Core_QueryBuilder::select('shop_items.shortcut_id')
                    ->from('shop_items')
                    ->where('shop_items.deleted', '=', 0)
                    ->where('shop_items.active', '=', 1)
                    ->where('shop_items.shop_group_id', '=', $shop_group_id)
                    ->where('shop_items.shortcut_id', '>', 0);

                // Стандартные ограничения для товаров
                $this->_applyItemConditionsQueryBuilder($oCore_QueryBuilder_Select_Shortcuts);

                $this->_Shop_Items
                    ->queryBuilder()
                    ->setOr()
                    ->where('shop_items.id', 'IN', $oCore_QueryBuilder_Select_Shortcuts);
            }

            $this->_Shop_Items
                ->queryBuilder()
                ->close();
        }
        else
        {
            parent::_groupCondition();
        }

        return $this;
    }

    protected $_aGroupTree = array();

    public function fillShopGroup($iShopId, $iShopGroupParentId = 0, $iLevel = 0)
    {
       $iShopId = intval($iShopId);
       $iShopGroupParentId = intval($iShopGroupParentId);
       $iLevel = intval($iLevel);

       if ($iLevel == 0)
       {
          $aTmp = Core_QueryBuilder::select('id', 'parent_id')
             ->from('shop_groups')
             ->where('shop_id', '=', $iShopId)
             ->where('deleted', '=', 0)
             ->execute()->asAssoc()->result();

          foreach ($aTmp as $aGroup)
          {
             $this->_aGroupTree[$aGroup['parent_id']][] = $aGroup;
          }
       }

       $aReturn = array();

       if (isset($this->_aGroupTree[$iShopGroupParentId]))
       {
          foreach ($this->_aGroupTree[$iShopGroupParentId] as $childrenGroup)
          {
             $aReturn[] = $childrenGroup['id'];
             $aReturn = array_merge($aReturn, $this->fillShopGroup($iShopId, $childrenGroup['id'], $iLevel + 1));
          }
       }

       $iLevel == 0 && $this->_aGroupTree = array();

       return $aReturn;
    }
}

/********************/

//$Shop_Controller_Show = new Shop_Controller_Show($oShop);
$Shop_Controller_Show = new My_Shop_Controller_Show($oShop);

/* Количество */
$on_page = intval(Core_Array::getGet('on_page'));
if ($on_page > 0 && $on_page < 150)
{
   $limit = $on_page;

   $Shop_Controller_Show->addEntity(
      Core::factory('Core_Xml_Entity')
         ->name('on_page')->value($on_page)
   );
}
else
{
   $limit = $oShop->items_on_page;
}

$Shop_Controller_Show
   ->limit($limit)
   ->parseUrl();

// Обработка скачивания файла электронного товара
$guid = Core_Array::getGet('download_file');
if (strlen($guid))
{
   $oShop_Order_Item_Digital = Core_Entity::factory('Shop_Order_Item_Digital')->getByGuid($guid);

   if (!is_null($oShop_Order_Item_Digital) && $oShop_Order_Item_Digital->Shop_Order_Item->Shop_Order->shop_id == $oShop->id)
   {
      $iDay = 7;

      // Проверяем, доступна ли ссылка (Ссылка доступна в течение недели после оплаты)
      if (Core_Date::sql2timestamp($oShop_Order_Item_Digital->Shop_Order_Item->Shop_Order->payment_datetime) > time() - 24 * 60 * 60 * $iDay)
      {
         $oShop_Item_Digital = $oShop_Order_Item_Digital->Shop_Item_Digital;
         if ($oShop_Item_Digital->filename != '')
         {
            Core_File::download($oShop_Item_Digital->getFullFilePath(), $oShop_Item_Digital->filename);
            exit();
         }
      }
      else
      {
         Core_Message::show(Core::_('Shop_Order_Item_Digital.time_is_up', $iDay));
      }
   }

   Core_Page::instance()->response->status(404)->sendHeaders()->showBody();
   exit();
}

// Быстрый фильтр
if (Core_Array::getRequest('fast_filter'))
{
   $aJson = array();

   if ($oShop->filter)
   {
      // В корне выводим из всех групп
      /*if ($Shop_Controller_Show->group == 0)
      {
         $Shop_Controller_Show->group(FALSE);
      }*/

      // Запрещаем выбор модификаций при выключенном modificationsList
      !$Shop_Controller_Show->modificationsList && $Shop_Controller_Show->forbidSelectModifications();

      foreach ($_POST as $key => $value)
      {
         if (strpos($key, 'property_') === 0)
         {
            $Shop_Controller_Show->removeFilter('property', substr($key, 9));
         }
         elseif (strpos($key, 'price_') === 0)
         {
            $Shop_Controller_Show->removeFilter('price');
         }
      }

      // Prices
      $Shop_Controller_Show->setFilterPricesConditions($_POST);

      // Additional properties
      $Shop_Controller_Show->setFilterPropertiesConditions($_POST);

      if (Core_Array::getPost('producer_id'))
      {
         $iProducerId = intval(Core_Array::getPost('producer_id'));
         $Shop_Controller_Show->producer($iProducerId);
      }

      $Shop_Controller_Show->applyItemCondition();

      $Shop_Controller_Show->group !== FALSE && $Shop_Controller_Show->applyGroupCondition();

      $Shop_Controller_Show->applyFilter();

      $Shop_Controller_Show
         ->shopItems()
         ->queryBuilder()
         ->where('shortcut_id', '=', 0)
         ->clearGroupBy()
         ->clearOrderBy();

      $aJson['count'] = intval($Shop_Controller_Show->shopItems()->getCount(FALSE, 'shop_items.id', TRUE));
   }

   Core::showJson($aJson);
}

// Сравнение товаров
if (Core_Array::getRequest('compare'))
{
   $shop_item_id = intval(Core_Array::getRequest('compare'));

   if (Core_Entity::factory('Shop_Item', $shop_item_id)->shop_id == $oShop->id)
   {
      Core_Session::start();
      if (isset($_SESSION['hostcmsCompare'][$oShop->id][$shop_item_id]))
      {
         unset($_SESSION['hostcmsCompare'][$oShop->id][$shop_item_id]);
      }
      else
      {
         $_SESSION['hostcmsCompare'][$oShop->id][$shop_item_id] = 1;
      }
   }

   Core_Page::instance()->response
      ->status(200)
      ->header('Pragma', "no-cache")
      ->header('Cache-Control', "private, no-cache")
      ->header('Vary', "Accept")
      ->header('Last-Modified', gmdate('D, d M Y H:i:s', time()) . ' GMT')
      ->header('X-Powered-By', 'HostCMS')
      ->header('Content-Disposition', 'inline; filename="files.json"');

   Core_Page::instance()->response
      ->body(json_encode('OK'))
      ->header('Content-type', 'application/json; charset=utf-8');

   Core_Page::instance()->response
      ->sendHeaders()
      ->showBody();

   exit();
}

// Избранное
if (Core_Array::getRequest('favorite'))
{
   $shop_item_id = intval(Core_Array::getRequest('favorite'));

   if (Core_Entity::factory('Shop_Item', $shop_item_id)->shop_id == $oShop->id)
   {
      Core_Session::start();
      Core_Session::setMaxLifeTime(86400 * 30);
      if (isset($_SESSION['hostcmsFavorite'][$oShop->id]) && in_array($shop_item_id, $_SESSION['hostcmsFavorite'][$oShop->id]))
      {
         unset($_SESSION['hostcmsFavorite'][$oShop->id][
            array_search($shop_item_id, $_SESSION['hostcmsFavorite'][$oShop->id])
         ]);
      }
      else
      {
         $_SESSION['hostcmsFavorite'][$oShop->id][] = $shop_item_id;
      }
   }

   Core_Page::instance()->response
      ->status(200)
      ->header('Pragma', "no-cache")
      ->header('Cache-Control', "private, no-cache")
      ->header('Vary', "Accept")
      ->header('Last-Modified', gmdate('D, d M Y H:i:s', time()) . ' GMT')
      ->header('X-Powered-By', 'HostCMS')
      ->header('Content-Disposition', 'inline; filename="files.json"');

   Core_Page::instance()->response
      ->body(json_encode('OK'))
      ->header('Content-type', 'application/json; charset=utf-8');

   Core_Page::instance()->response
      ->sendHeaders()
      ->showBody();

   exit();
}

// Viewed items
if ($Shop_Controller_Show->item && $Shop_Controller_Show->viewed)
{
   $Shop_Controller_Show->addIntoViewed();
}

if (!is_null(Core_Array::getGet('vote')))
{
   $oSiteuser = Core_Entity::factory('Siteuser')->getCurrent();
   $entity_id = intval(Core_Array::getGet('id'));

   if ($entity_id && !is_null($oSiteuser))
   {
      $entity_type = strval(Core_Array::getGet('entity_type'));
      $vote = intval(Core_Array::getGet('vote'));

      $oObject = Vote_Controller::instance()->getVotedObject($entity_type, $entity_id);

      if (!is_null($oObject))
      {
         $oVote = $oObject->Votes->getBySiteuser_Id($oSiteuser->id);

         $vote_value = $vote ? 1 : -1;

         $deleteVote = 0;
         // Пользователь не голосовал ранее
         if (is_null($oVote))
         {
            $oVote = Core_Entity::factory('Vote');
            $oVote->siteuser_id = $oSiteuser->id;
            $oVote->value = $vote_value;

            $oObject->add($oVote);
         }
         // Пользователь голосовал ранее, но поставил противоположную оценку
         elseif ($oVote->value != $vote_value)
         {
            $oVote->value = $vote_value;
            $oVote->save();
         }
         // Пользователь голосовал ранее и поставил такую же оценку как и ранее, обнуляем его голосование, как будто он вообще не голосовал
         else
         {
            $deleteVote = 1;
            $oVote->delete();
         }

         $aVotingStatistic = Vote_Controller::instance()->getRate($entity_type, $entity_id);

         Core_Page::instance()->response
         ->body(
            json_encode(array('value' => $oVote->value, 'item' => $oObject->id, 'entity_type' => $entity_type,
               'likes' => $aVotingStatistic['likes'], 'dislikes' => $aVotingStatistic['dislikes'],
               'rate' => $aVotingStatistic['rate'], 'delete_vote' => $deleteVote)
            )
         );
      }
   }

   Core_Page::instance()->response
         ->status(200)
         ->header('Pragma', "no-cache")
         ->header('Cache-Control', "private, no-cache")
         ->header('Vary', "Accept")
         ->header('Last-Modified', gmdate('D, d M Y H:i:s', time()) . ' GMT')
         ->header('X-Powered-By', 'HostCMS')
         ->header('Content-Disposition', 'inline; filename="files.json"');

   if (strpos(Core_Array::get($_SERVER, 'HTTP_ACCEPT', ''), 'application/json') !== FALSE)
   {
      Core_Page::instance()->response->header('Content-type', 'application/json; charset=utf-8');
   }
   else
   {
      Core_Page::instance()->response
         ->header('X-Content-Type-Options', 'nosniff')
         ->header('Content-type', 'text/plain; charset=utf-8');
   }

   if(Core_Array::getRequest('_'))
   {
      Core_Page::instance()->response
         ->sendHeaders()
         ->showBody();
      exit();
   }
}

Core_Page::instance()->object = $Shop_Controller_Show;
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
Можете дать свои ТДС и XSL?
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
Разобрался.
В XSL-шаблоне в выводе групп добавил строку
<xsl:apply-templates select="/shop/shop_item[shop_group_id = $gropupId]"/>

И все заработало как надо!
Спасибо за помощь!
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
Зато теперь перестала работать корзина, т.к. эта строка
<xsl:apply-templates select="/shop/shop_item[shop_group_id = $gropupId]"/>
была в форме
<form method="get" action="{$path}{$form_tag_url}">
                <!-- Выводим товары магазина-->
                <div class="row products-grid" id="gallery">
                    <xsl:apply-templates select="shop_item" />
                </div>
            </form>
, а теперь я ее переместил в вывод групп
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
Цитата:
Посмотрите как реализовано в готовом шаблоне, дни недели это группы.

Что-то я не понял сразу... Спасибо, взял шаблон и все получилось
www.dsaleks.ru - создание сайтов и интернет-магазинов
#
Re: Вывод групп магазина с товарами в группах
DS Aleks,
Всегда пожалуйста.
E-mail: info@syrbek.ru / телега: @syrbek /skype: activexm / syrbek.ru / Поддержка сайтов / г. Москва [HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, Git, SVN, Redmine]
Авторизация