Questions around the TYPO3 integration and plugins as well as Flow and NeosCMS
Forum rules: Always add your TYPO3/Flow, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
#6189 by Alex K
02 Jun 2018, 14:16
Hi) I cant find any information how to get Categories list of Product. I checked default templates and documentation for class Item.. but failed. Please, can you show me right way?) I want to show product category to some products.
#6191 by aimeos
02 Jun 2018, 20:46
Do you want to show the current category of the product or all product categories if the product is in several categories?

The categories are not retrieved by default for each product, so you have to create a decorator for the catalog lists HTML client that fetches the categories for the products shown: https://aimeos.org/docs/Developers/Html_frontend/Extend_existing_components

To get the categories use something like this:
Code: Select all$listManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog/lists' );
$search = $listManager->createSearch( true );
$expr = [
    $search->compare( '==', 'catalog.lists.refid', array_keys( $view->listProductItems ) ),
    $search->compare(  '==, 'catalog.lists.domain', 'product' ),
    $search->getConditions()
];
$search->setConditions( $search->combine( '&&', $expr ) );

$map = [];
foreach( $listManager->searchItems( $search ) as $listItem ) {
    $map[$listItem->getRefId()] = $listItem->getParentId();
}

$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog' );
$search = $manager->createSearch( true );
$expr = [
    $search->compare( '==', 'catalog.id', $map ),
    $search->getConditions(),
];
$search->setConditions( $search->combine( '&&', $expr ) );

$view->listListMap = $map;
$view->listCategories = $manager->searchItems( $search );
#6199 by Alex K
04 Jun 2018, 14:06
Thanks again for help! I finnaly got my categories for each product with help of decorator. I hope it's not forbiden, i'll give my result as example, if someone need it.

Thi is my Decorator for List, it's fast solution.
Code: Select all<?php
namespace Aimeos\Client\Html\Common\Decorator;

class CategoryListsDecorator
    extends \Aimeos\Client\Html\Common\Decorator\Base
    implements \Aimeos\Client\Html\Common\Decorator\Iface
{
   /**
    * Adds the data to the view object required by the templates
    *
    * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
    * @param array &$tags Result array for the list of tags that are associated to the output
    * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
    * @return \Aimeos\MW\View\Iface The view object with the data required by the templates
    * @since 2018.01
    */
   public function addData( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
   {
      $view = parent::addData( $view, $tags, $expire );
      if(count($view->get( 'listProductItems' )) > 0){
         $productsList = $view->get( 'listProductItems' );
         $productsList = $this->reachProducts($productsList);
         $view->listProductItems = $productsList;
      } else {
         $productsList = $view->get( 'promoItems' );
         $productsList = $this->reachProducts($productsList);
         $view->promoItems = $productsList;
      }
      return $view;
   }

   protected function reachProducts($productsList){
      foreach ($productsList as $id => $item) {
            $res = $this->getCategories($item);
            $productsList[$id]->listCategories = $res;
      }
      return $productsList;
   }


   protected function getCategories($product){
      $listManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog/lists' );
      $search = $listManager->createSearch( true );
      $expr = [
          $search->compare( '==', 'catalog.lists.refid', $product->getId() ),
          $search->compare(  '==', 'catalog.lists.domain', 'product' ),
          $search->getConditions()
      ];
      $search->setConditions( $search->combine( '&&', $expr ) );
      $map = [];
      foreach( $listManager->searchItems( $search ) as $listItem ) {
          $map[] = $listItem->getParentId();
      }
      $manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog' );
      $search = $manager->createSearch( true );
      $expr = [
          $search->compare( '==', 'catalog.id', $map ),
          $search->getConditions(),
      ];
      $search->setConditions( $search->combine( '&&', $expr ) );
      return $manager->searchItems( $search );
   }

}
#6200 by Alex K
04 Jun 2018, 14:12
And also simple decorator for detail product

Code: Select all<?php
namespace Aimeos\Client\Html\Common\Decorator;

class CategoryDetailDecorator
    extends \Aimeos\Client\Html\Common\Decorator\Base
    implements \Aimeos\Client\Html\Common\Decorator\Iface
{

   /**
    * Adds the data to the view object required by the templates
    *
    * @param \Aimeos\MW\View\Iface $view The view object which generates the HTML output
    * @param array &$tags Result array for the list of tags that are associated to the output
    * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry)
    * @return \Aimeos\MW\View\Iface The view object with the data required by the templates
    * @since 2018.01
    */
   public function addData( \Aimeos\MW\View\Iface $view, array &$tags = array(), &$expire = null )
   {
      $view = parent::addData( $view, $tags, $expire );
      $listManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog/lists' );
      $search = $listManager->createSearch( true );

      $expr = [
          $search->compare( '==', 'catalog.lists.refid', $view->get( 'detailProductItem' )->getId() ),
          $search->compare(  '==', 'catalog.lists.domain', 'product' ),
          $search->getConditions()
      ];

      $search->setConditions( $search->combine( '&&', $expr ) );
      $map = [];
      foreach( $listManager->searchItems( $search ) as $listItem ) {
          $map[] = $listItem->getParentId();
      }

      $manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'catalog' );
      $search = $manager->createSearch( true );
      $expr = [
          $search->compare( '==', 'catalog.id', $map ),
          $search->getConditions(),
      ];
      $search->setConditions( $search->combine( '&&', $expr ) );
      $view->listCategories = $manager->searchItems( $search );      
      return $view;
   }
}
#6202 by aimeos
04 Jun 2018, 16:28
Your decorator for the list slows down your application because you fetch the categories for each product separately. Instead, you should retrieve all catalog<->product references and catalog items once and map them afterwards. This will be much faster.