How To: Вывод товаров из текущей группы и ее подгрупп

Для вывода товаров из подгрупп достаточно указать контроллеру опцию ->subgroups(TRUE)

$Shop_Controller_Show->subgroups(TRUE);

Использование subgroups(TRUE) доступно при указании в group() идентификатора родительской группы, если в group() будет указан массив, subgroups(TRUE) не будет иметь действия.

Для версии до 6.9.5

В коде настроек типовой динамической страницы интернет-магазина объявим Hostcms_Subgroups и через метод fillShopGroup() будем получать все подгруппы заданной группы. Затем после parseUrl() проверим, в какой группе находимся, если в корневой, то установим ->group(FALSE), чтобы выборка шла без учета групп, если же внутри определенной группы, то выберем подгруппы этой группы в массив и передадим массив контроллеру показа в ->group.

class Hostcms_Subgroups
{
	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;
	}
}

// ...

// Root group
if ($Shop_Controller_Show->group == 0)
{
	$Shop_Controller_Show->group(FALSE);
}
else
{
	// Get all subgroups
	$oHostcms_Subgroups = new Hostcms_Subgroups();
	$aSubGroupsID = $oHostcms_Subgroups->fillShopGroup($oShop->id, $Shop_Controller_Show->group);
	// Set first ID as current group
	array_unshift($aSubGroupsID, $Shop_Controller_Show->group);

	$Shop_Controller_Show->group = $aSubGroupsID;
}

Для версии < 6.9.1

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

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 Shop_Controller_Show($oShop);

заменяется на

$Shop_Controller_Show = new My_Shop_Controller_Show($oShop);

Не нашли ответ на свой вопрос в документации? Направьте обращение в службу поддержки или онлайн чат.

Комментарии

  • подсчитать количество товаров из подгрупп

    есть строка // получаем все товары из подгрупп ->where('shop_items.shop_group_id', 'IN', $aSubGroupsID); А как подсчитать эти найденные товары? Мне надо для условия, если их меньше 3, то рандомно прибавляем вывод еще из другой группы.

    05.09.2019 14:52:48
    lyubaaa

    Без темы

    До выполнения метода ->show() количество товаров не сможет быть подсчитано, после получить массив с идентификаторами показанных товаров можно методом getShownIDs()

    05.09.2019 15:09:04
    hostcms
  • Без темы

    Есть решение?

    22.07.2015 11:26:54

    Без темы

    Решение чего?

    22.07.2015 11:46:57
    hostcms
  • При таком выводе товаров не работает фильтр товаров

    Фильтр корректно работает только если находишься в последней подгруппе!
    Как исправить?

    12.06.2015 12:51:38
    xelaxela13
    xelaxela13

    Re: При таком выводе товаров не работает фильтр товаров

    В макете где вызывается фильтр надо исправить Shop_Controller_Show на My_Shop_Controller_Show

    28.01.2016 10:26:02
    MaxNeh