Özel sayfada özel koleksiyon için katmanlı gezinti - magento2


12

Özel bir ürün koleksiyonu için magento2'de katmanlı gezinme getirmeye çalışıyorum. Katmanlı gezinmeyi göstermek için özel sayfada zaten özel koleksiyon alıyorum. Bu magento1 çözümünü adapte etmeye çalıştım, ancak uzaklaşamadı.

Magento2 ile nasıl başarabilirim. Şimdiye kadar yaptığım aşağıdaki gibidir:

Özel sayfamdaki özel ürün listesi için Katalog ListesiÜrün bloğunu genişletti.

class View extends \Magento\Catalog\Block\Product\ListProduct
{


    public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver,
    CategoryRepositoryInterface $categoryRepository,
    \Magento\Framework\Url\Helper\Data $urlHelper,
    array $data = [],
    \Custom\LayerNavigation\Model\Layer $testlayerobj
    ) {
        parent::__construct($context,$postDataHelper,$layerResolver,
        $categoryRepository,$urlHelper,$data);
        $this->_coreRegistry = $context->getRegistry();
        $this->_testlayer = $testlayerobj;
    }

    protected function _getProductCollection()
    {
        if ($this->_productCollection === null) {
          $this->_productCollection = $this->getLayer()->getProductCollection();
        }
        return $this->_productCollection;
     }

    public function getLayer()
    {

       $layer = $this->_coreRegistry->registry('current_layer');
       if ($layer) {
          return $layer;
        }
        return $this->_testlayer;
     }

}

Düzen dosyasında katmanlı gezinme için temel Arama bloğunu kullandı

<referenceContainer name="sidebar.main">
        <block class="Magento\LayeredNavigation\Block\Navigation\Search" name="catalogsearch.leftnav" before="-" template="layer/view.phtml">
            <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalogsearch.navigation.state" as="state" />
            <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalogsearch.navigation.renderer" as="renderer" template="layer/filter.phtml"/>
        </block>
</referenceContainer>

Koleksiyonu değiştirmek için Genişletilmiş Çekirdek katman modeli.

class Layer extends \Magento\Catalog\Model\Layer
{
    public function __construct(
      optionStoreFactory  $optionstoreFactory,
      Attrhelper $attrhelper,
      productCollectionFactory $productCollectionFactory,
      AttributevalueFactory $attributevalueFactory,
      CategoryRepositoryInterface $categoryRepository,
      \Magento\Store\Model\StoreManagerInterface $storeManager,
      \Magento\Framework\App\Request\Http $request,
      \Magento\Framework\Registry $registry,
      \Magento\Catalog\Model\Layer\Search\CollectionFilter $filter,
      array $data = []
    ) {
       $this->optionstoreFactory       = $optionstoreFactory;
       $this->attributevalueFactory    = $attributevalueFactory;
       $this->_attrhelper              = $attrhelper;
       $this->request                  = $request;
       $this->productCollectionFactory = $productCollectionFactory;
       $this->categoryRepository = $categoryRepository;
       $this->_storeManager = $storeManager;
       $this->filter = $filter;
       $this->registry = $registry;
    }

    public function getProductCollection()
    {
        $attributevalue = $this->getAttributeValue(); //eg: Manufacturer Attribute details
        $attr_code = $attributevalue->getAttributeCode();
        $attr_option_value = $attributevalue->getOptionId();
        $collection = $this->productCollectionFactory->create();
        $store_id = $this->request->getParam('store_id');
        $collection->addAttributeToSelect('*')
               ->addAttributeToFilter($attr_code , ['finset'=>$attr_option_value ])
               ->addAttributeToFilter('visibility','4')
               ->setStore($store_id)
               ->addFieldToFilter('status', array('eq' => 1))
               ->setOrder('id', 'DESC');
        $this->prepareProductCollection($collection);
        return $collection;
    }

    public function prepareProductCollection($collection)
    {
        $this->filter->filter($collection, $this->getCurrentCategory());
       return $this;
    }

    public function getCurrentCategory()
    {
       $category = $this->registry->registry('current_category');
       if ($category) {
           $this->setData('current_category', $category);
       } else {
           $category = $this->categoryRepository->get($this->getCurrentStore()->getRootCategoryId());
       $this->setData('current_category', $category);
       }
      return $category;
    }

    public function getCurrentStore()
    {
        return $this->_storeManager->getStore();
    }

}

Şu andan itibaren katman gezinmesini görüntülüyorum ancak özel koleksiyonuma özgü değil. Hata ayıklama göre koleksiyon kök kategoriden (tüm ürün kataloğunu içerir) tamamen filtrelenir ve buna göre katmanlar getirilir.


Herhangi bir öneri çok takdir edilecektir ..!
mp196

Bunun için bir çözüm buldunuz mu? Eğer öyleyse, lütfen cevabınızı paylaşın
Nalin Savaliya

Çocuklar bu konuda herhangi bir ipucu var ??
aton1004

Özel koleksiyonum için katmanlı sayfada gezinmeyi elde etmeyi başardım ... Çok uzun olduğu için çözümü buraya göndermek için biraz zamana ihtiyacım olacak (Muhtemelen bir veya iki gün içinde çözümü
göndereceğim

Yanıtlar:


3

Aşağıdaki değişikliklerle navigasyonu başarabildim, bu çözümle tam olarak doğru olmayabilirim, bu yüzden yorum ve önerilerinizi bekliyoruz.

1) Ön uç bölümü için di.xml dosyasını aşağıdaki gibi hazırlayın:

<!-- Magento only includes 2 type of layer resolvers i.e Category and search whereas our custom page is neither a category page nor a search page so we need to add a new layer resolver on our custom page-->
<type name="Magento\Catalog\Model\Layer\Resolver">
    <arguments>
        <argument name="layersPool" xsi:type="array">
            <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Category</item>
            <item name="search" xsi:type="string">Magento\Catalog\Model\Layer\Search</item>
            <item name="customlayer" xsi:type="string">Custom\Navigation\Model\Layer</item>
        </argument>
    </arguments>
</type>

<!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
<virtualType name="customFilterList" type="Custom\Navigation\Model\Layer\FilterList">
    <arguments>
        <argument name="filterableAttributes" xsi:type="object">Custom\Navigation\Model\Layer\FilterableAttributeList</argument>
        <argument name="filters" xsi:type="array">
            <item name="attribute" xsi:type="string">Custom\Navigation\Model\Layer\Filter\Attribute</item>
            <item name="category" xsi:type="string">Custom\Navigation\Model\Layer\Filter\Category</item>
        </argument>
    </arguments>
</virtualType>

<!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
<virtualType name="Custom\Navigation\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
    <arguments>
        <argument name="filterList" xsi:type="object">customFilterList</argument>
    </arguments>
</virtualType>

<!-- As we will be modifying the layer model collection we will need to extend the core model layer, Below virtual type will be required to extend the Catalog model layer else it will throw error for the context in construct method-->
<virtualType name="Custom\Navigation\Model\Layer\Context" type="Magento\Catalog\Model\Layer\Context">
    <arguments>
        <argument name="collectionProvider" xsi:type="object">Custom\Navigation\Model\Layer\ItemCollectionProvider</argument>
        <argument name="stateKey" xsi:type="object">Custom\Navigation\Model\Layer\StateKey</argument>
        <argument name="collectionFilter" xsi:type="object">Custom\Navigation\Model\Layer\CollectionFilter</argument>
    </arguments>
</virtualType>
<type name="Custom\Navigation\Model\Layer">
    <arguments>
        <argument name="context" xsi:type="object">Custom\Navigation\Model\Layer\Context</argument>
    </arguments>
</type>

2) Model Katman dosyası: Model katman dosyasını özel modelinizle genişletin ve koleksiyonu değiştirin.

namespace Custom\Navigation\Model;
class Layer extends \Magento\Catalog\Model\Layer
{

//Apart from the default construct argument you need to add your model from which your product collection is fetched.

    public function __construct(
        \Magento\Catalog\Model\Layer\ContextInterface $context,
        \Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
        AttributeCollectionFactory $attributeCollectionFactory,
        \Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Registry $registry,
        CategoryRepositoryInterface $categoryRepository,
        array $data = []
    ) {
    parent::__construct(
            $context,
            $layerStateFactory,
            $attributeCollectionFactory,
            $catalogProduct,
            $storeManager,
            $registry,
            $categoryRepository,
            $data
        );
    }

    public function getProductCollection()
    {

        /*Unique id is needed so that when product is loaded /filtered in the custom listing page it will be set in the
         $this->_productCollections array with unique key else you will not get the updated or proper collection.
        */

        if (isset($this->_productCollections['some_uinique_id'])) {
            $collection = $this->_productCollections['some_uinique_id'];
        } else {
            //$collection = Your logic to get your custom collection.
            $this->prepareProductCollection($collection);
            $this->_productCollections['some_unique_id'] = $collection;
        }

        return $collection;
    }

3) Ben di.xml kullanılan dosyaları aşağıda genişletilmiş (sadece genişleterek dosyayı tuttum yaptım eğer bu dosyada herhangi bir değişiklik gerekmediği gibi yapı yöntemi somutlaştırmadım eğer genişletilmiş dosyadaki belirli işlevi değiştirebilirsiniz buna göre), Şu anda uyguladığım çözüm kategori filtresi sorununu çözemedi, yine de kök kategori filtrelerini içeriyor, bu yüzden yönlü verileri (4. noktada belirtilen geçici çözüm) dahil etmek için bir geçici çözüm yapmak zorunda kaldı

- Custom\Navigation\Model\Layer\FilterList extends
           \Magento\Catalog\Model\Layer\FilterList



 - Custom\Navigation\Model\Layer\FilterableAttributeList extends
   \Magento\Catalog\Model\Layer\Category\FilterableAttributeList



 - Custom\Navigation\Model\Layer\Filter\Attribute extends
   \Magento\Catalog\Model\Layer\Filter\Attribute



 - Custom\Navigation\Model\Layer\Filter\Category extends
   \Magento\CatalogSearch\Model\Layer\Filter\Category (Why catalog
           search is used i have mentioned the same in 4th point)



 - Custom\Navigation\Model\Layer\ItemCollectionProvider extends
   \Magento\Catalog\Model\Layer\Category\ItemCollectionProvider



 - Custom\Navigation\Model\Layer\StateKey extends
   \Magento\Catalog\Model\Layer\Category\StateKey



 - Custom\Navigation\Model\Layer\CollectionFilter extends
   \Magento\Catalog\Model\Layer\Category\CollectionFilter

4) Katmanlı navigasyonda filtre kategorisine yönelik bir geçici çözüm yapmak zorundaydı, çünkü filtrelenmiş koleksiyona göre seçenek göstermiyordu, herhangi biri çözümü bulursa lütfen güncelleyin. Aşağıda benim customfilterlist kategoriye dahil ederken karşı karşıya faceteddata hata düzeltmek için kullandığınız kodu, Bu yama uygulamak nedeniyle kategori seçeneği benim gezinti filtreler geri kalanı benim koleksiyonuna göre uygun değildi.

namespace Custom\Navigation\Model\Layer\Filter;

/**
 * Layer category filter
 */
class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category
{
     /**
      * @var \Magento\Framework\Escaper
      */
    private $escaper;

    /**
     * @var CategoryDataProvider
     */
    private $dataProvider;

    /**
     * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Catalog\Model\Layer $layer
     * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder
     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
     * @param \Magento\Framework\Escaper $escaper
     * @param CategoryManagerFactory $categoryManager
     * @param array $data
     */
    public function __construct(
        \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\Layer $layer,
        \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder,
        \Magento\Framework\Escaper $escaper,
        \Magento\Catalog\Model\Layer\Filter\DataProvider\CategoryFactory $categoryDataProviderFactory,
        array $data = []
    ) {
        parent::__construct(
            $filterItemFactory,
            $storeManager,
            $layer,
            $itemDataBuilder,
            $escaper,
            $categoryDataProviderFactory,
            $data
        );
        $this->_escaper = $escaper;
        $this->_requestVar = 'cat';
        $this->dataProvider = $categoryDataProviderFactory->create(['layer' => $this->getLayer()]);
    }

    /**
     * Get data array for building category filter items
     *
     * @return array
     */
    protected function _getItemsData()
    {
        /** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
        $productCollection = $this->getLayer()->getProductCollection();

        $optionsFacetedData = '' ;// $productCollection->getFacetedData('category'); (Here i have set $optionsFacetedData as blank so that category option will not be included in layered navigation)
        $category = $this->dataProvider->getCategory();
        $categories = $category->getChildrenCategories();

        $collectionSize = $productCollection->getSize();

        if ($category->getIsActive()) {
            foreach ($categories as $category) {
                if ($category->getIsActive()
                    && isset($optionsFacetedData[$category->getId()])
                    && $this->isOptionReducesResults($optionsFacetedData[$category->getId()]['count'], $collectionSize)
                ) {
                    $this->itemDataBuilder->addItemData(
                        $this->escaper->escapeHtml($category->getName()),
                        $category->getId(),
                        $optionsFacetedData[$category->getId()]['count']
                    );
                }
            }
        }
        return $this->itemDataBuilder->build();
    }
}

5) Özel sayfanız denetleyici yürütme yönteminizin içine yüklendiğinde, di.xml dosyasına eklediğimiz özel katmanınızı kategori ve arama katmanıyla birlikte ayarlamanız gerekir.

 - include the below argument in your controller construct method.

     "\Magento\Catalog\Model\Layer\Resolver $layerResolver",

 - inside execute method set your custom layer resolver for your module.

    $this->layerResolver->create('customlayer');

6) Özel sayfanın düzen xml dosyasında gövde bölümüne aşağıdaki kodu ekleyin.

<attribute name="class" value="page-with-filter"/>

<referenceContainer name="sidebar.main">
<!-- below is the virtual type of the core navigation we created -->
    <block class="Custom\Navigation\Block\Navigation\Custnavigation" name="custom.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
        <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" />
        <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/>
    </block>
</referenceContainer>

Kodunuzu magento 2.1.7'de özel koleksiyonla kullanıyorum. ama boş sayfa alıyorum. Yukarıdaki kodlarda Custom \ Navigation \ Block \ Navigation \ Custnavigation eksik olduğunu düşünüyorum. Bana tam kod verebilir misiniz?
Magecode

hayır böyle bir blok yerine bunun için sanal bir tür oluşturmuştu di.xml kodunu kontrol edebilirsiniz ve burada yayınlanan kod tam kod kendisi.
mp196

Tamam bana tüm kodun zip gönderebilir misiniz?
Magecode

Üzgünüz, yukarıdaki yanıtlanan kod, geliştirdiğimiz ücretli uzantının sadece küçük bir kısmı olduğu için zip'i gönderemez.
mp196

1
$ this-> layerResolver = $ layerResolver ekleyip eklemediğinizi kontrol edin; dosya yapıcısına eklenen sınıfın yapısında. \ Magento \ Katalog \ Model \ Katman \ Çözümleyici $ layerResolver
mp196

2

Özel ürün koleksiyonumu kategori sayfasının katmanlı gezinme ve araç çubuğuna başarıyla uyguladım.

Örneğin, fiyatı 100'den az olan ürünlerin koleksiyonunu getiriyorum.

1. Adım: Aşağıdaki kod snippet'ini ekleyin

Uygulamanın / kod / Satıcı / Modül / etc / di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Catalog\Model\Layer">
        <plugin name="custom_product_model_layer" type="Vendor\Module\Plugin\Layer" />
    </type>

    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="custom_product_toolbar" type="Vendor\Module\Plugin\Toolbar" />
    </type>

    <virtualType name="categoryFilterList" type="Magento\Catalog\Model\Layer\FilterList">
        <arguments>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Attribute</item>
                <item name="price" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Price</item>
                <item name="decimal" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Decimal</item>
                <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

</config>

2. Adım: Ürün toplama için eklenti oluşturma

Uygulamanın / kod / Satıcı / Modül / Eklenti / Layer.php

<?php
namespace Vendor\Module\Plugin;
class Layer
{
  public function aroundGetProductCollection(
    \Magento\Catalog\Model\Layer $subject,
    \Closure $proceed
  ) {

    $result = $proceed();
    $result->addAttributeToFilter('price', array('lt' => 100));
    return $result;
  }
}

3. Adım: Araç çubuğu için eklenti oluşturma

Uygulamanın / kod / Satıcı / Modül / Eklenti / Toolbar.php

<?php
namespace Vendor\Module\Plugin;
class Toolbar
{

  protected $_objectManager;
  protected $request;

  public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    \Magento\Framework\App\Request\Http $request
  ) {
    $this->_objectManager = $objectmanager;
    $this->request = $request;
  }

  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
    \Closure $proceed,
    $request
  ) {
    $result = $proceed($request);

    $this->_collection = $request;
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    if($category)
    {
      $page = $this->request->getParam('p');
      if($page == '')
      {
        $page = 1;
      }
      $this->_collection->getCurPage();
      $this->_collection->setCurPage($page);  
    }
    //else
    //{
    //  $this->_collection->setCurPage($this->getCurrentPage());
    //}

    return $result;
  }

}

Merhaba, Kodunuzu Kullantım Ürün Toplama Güncelliğini Güncelliyorum Ama Kategori, Fiyat, Nitelikler ve Ayrıca Ürünlerinin sayısı gibi FIlterList'i güncellemiyor. Bunun için yardım edebilir misin, benim için acil ?? @DineshYadav
Sujeet Pandit

çözümünüz mükemmel çalıştı. Belirli kategorileri dinlemek için ekstra çan ve ıslık ekledim ve koleksiyonlarını tamamen yeniden yazdım.
pixiemedia

@pixiemedia Eğer senin için çalıştıysa cevabımı oylayabilirsin ☺️
Dinesh Yadav

i zaten var;) Bu arada küçük bir sorun buldunuz - eklenti kodunda, son başka son bölüm arama sonuçlarını kırar. bu biti yorum
pixiemedia

M2.2 üzerinde çalışmayı durdurdu - sql hatası SQLSTATE [42S22]: Sütun bulunamadı: 1054 'Alan listesinde' bilinmeyen sütun 'e.min_price' - çözümü çalışma
pixiemedia

0

Katmanlı gezinmeyi çoğunlukla özel bir sayfada özel bir ürün koleksiyonu için çalıştırabildim. Modülümün kaynak kodunu buraya yükledim . Tek sorun Fiyat filtresinin doğru ürün sayısını göstermemesidir. Bu nedenle, Fiyat filtresini gizlemek için katmanlı gezinme görünümünü değiştirdim. Ancak özel bir görünüm dosyası kullandığım için, nedense kenar çubuğundaki filtreler artık daraltılamıyor.

Birisi bu sorunu çözebilirse, çekme isteği yapmaktan çekinmeyin. Ben de xml ile manuel olarak oluşturulan bir sayfa yerine, Magento 2 arka ucuyla oluşturulan bir CMS sayfası için nasıl bu anlamaya çalışıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.