Magento 2: Bagaimana cara kerja data faceted untuk navigasi berlapis?

10

Saya telah membuat modul untuk filter khusus pada halaman kategori semuanya berfungsi dengan baik kecuali kisaran harga dalam navigasi berlapis.

Tolong siapa pun bisa menjelaskan padaku bagaimana getFacetedData ('price') bekerja di magento2

$productCollection->getFacetedData('price');

Fungsi ini memberi saya kisaran harga berdasarkan pada koleksi produk default bukan berdasarkan pada koleksi saya yang difilter.

FYI: Saya telah memfilter koleksi seperti di bawah ini,

$productCollection = $layer->getProductCollection()
->clear()
->addAttributeToSelect(['name','price'])
->addAttributeToFilter('sku', array('in' => ['sku1','sku2']));
Nalin Savaliya
sumber

Jawaban:

7

Kode di bawah ini berlaku untuk Magento 2.2.5.

Pertama, di bilah sisi, semua rentang yang mungkin untuk semua filter yang mungkin perlu diproduksi. Selain itu, untuk ini, Anda akan memiliki gambaran umum jumlah produk yang ditemukan dalam rentang yang diberikan.

masukkan deskripsi gambar di sini

Misalnya, saya akan fokus menggunakan satu filter: harga.

Sebelum hal lain, agar atribut produk yang diberikan memenuhi syarat untuk navigasi berlapis, itu harus dikonfigurasi dengan benar.

Untuk memeriksa, telusuri di admin Stores -> Attribute -> Product, lalu pilih atribut harga dan amati bahwa di Storefront Propertiestab, Use in Layered Navigationdiatur keFilterable (with results)

Pada gambar ini kita melihat bahwa untuk filter harga, kita melihat rentang dari 50.00-59.99berisi 10hasil, dan 80+hanya untuk 1.

Pandangan ini dihasilkan di dalam

/vendor/magento/theme-frontend-luma/Magento_LayeredNavigation/templates/layer/view.phtml

Ada kode yang mirip dengan

<?php foreach ($block->getFilters() as $filter): ?>
    <?php if ($filter->getItemsCount()): ?>

Yang akhirnya menumpuk

private function prepareData($key, $count)

dan ini adalah metode dari

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Jadi, kami telah mengidentifikasi kelas yang bertanggung jawab untuk pemfilteran harga, dan kami melihatnya telah digunakan untuk menghasilkan rentang yang tersedia.


Tumpukan yang lebih penting adalah untuk memeriksa apa yang terjadi ketika rentang tertentu dipilih.

Misalnya, saya akan mengklik rentang 40.00-49.99, yang diharapkan menghasilkan 4 hasil.

Pertama adalah metode _prepareLayout()dari

/vendor/magento/module-layered-navigation/Block/Navigation.php

Kodenya adalah

protected function _prepareLayout()
{
    foreach ($this->filterList->getFilters($this->_catalogLayer) as $filter) {
        $filter->apply($this->getRequest());
    }
    $this->getLayer()->apply();
    return parent::_prepareLayout();
}

Intinya, ini mengatakan, dapatkan saya semua filter dan foreach mereka lakukan apply.

Sekarang, getFilters () sendirian, akhirnya mengarah untuk membangun objek

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Langkah menyebut bahwa mengarah ke __constructdari Priceis

protected function createAttributeFilter(
    \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute,
    \Magento\Catalog\Model\Layer $layer
) {
    $filterClassName = $this->getAttributeFilterClass($attribute);

    $filter = $this->objectManager->create(
        $filterClassName,
        ['data' => ['attribute_model' => $attribute], 'layer' => $layer]
    );
    return $filter;
}

Dan ini adalah kode dari

vendor/module-catalog/Model/Layer/FilterList.php

Bagaimanapun, jika kita fokus kembali ke $filter->apply($this->getRequest());kode dari atas, ini berarti bahwa kode ini akan dieksekusi

public function apply(\Magento\Framework\App\RequestInterface $request)
{
    /**
     * Filter must be string: $fromPrice-$toPrice
     */
    $filter = $request->getParam($this->getRequestVar());
    if (!$filter || is_array($filter)) {
        return $this;
    }

    $filterParams = explode(',', $filter);
    $filter = $this->dataProvider->validateFilter($filterParams[0]);
    if (!$filter) {
        return $this;
    }

    $this->dataProvider->setInterval($filter);
    $priorFilters = $this->dataProvider->getPriorFilters($filterParams);
    if ($priorFilters) {
        $this->dataProvider->setPriorIntervals($priorFilters);
    }

    list($from, $to) = $filter;

    $this->getLayer()->getProductCollection()->addFieldToFilter(
        'price',
        ['from' => $from, 'to' =>  empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
    );

    $this->getLayer()->getState()->addFilter(
        $this->_createItem($this->_renderRangeLabel(empty($from) ? 0 : $from, $to), $filter)
    );

    return $this;
}

dan sekali lagi, kode ini dari

vendor/magento/module-catalog-search/Model/Layer/Filter/Price.php

Jika saya mengikuti dengan cermat nilai variabel, sekali lagi, mengingat saya telah memilih rentang 40.00-49.99, maka $filterarray terdiri dari dua elemen: [0 => 40, 1 => 50]

Setelah baris ini dieksekusi

list($from, $to) = $filter;

Jelas, $fromvariabelnya sekarang 40, dan $tovariabelnya sekarang 50.

Baris berikutnya sangat penting

    $this->getLayer()->getProductCollection()->addFieldToFilter(
        'price',
        ['from' => $from, 'to' =>  empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA]
    );

Di sinilah koleksi yang sudah ada terkait dengan Layer, semakin dikurangi dengan memanggil addFieldToFilter().

Mungkin, di sinilah perhatian harus ditempatkan untuk mendeteksi bug, jika ada.

Akhirnya, program memanggil getLoadedProductCollection () dari

vendor/magento/module-catalog/Block/Product/ListProduct.php

yang pada dasarnya mengembalikan koleksi yang dilindungi yang diringkas oleh objek ini.


Magento adalah aplikasi yang kompleks.

Dalam satu klik ini yang memilih satu kisaran harga tunggal, kami melihat kode dari tiga modul yang berbeda berinteraksi

  • modul-katalog
  • modul-katalog-pencarian
  • module-layered-navigation

Mungkin terasa luar biasa saat ini, tetapi bagi saya, ada sinergi yang bagus antara modul-modul ini.

Terima kasih telah membaca. Saya harap ini menjelaskan dan Anda sekarang dilengkapi dengan pemahaman sedikit lebih baik tentang navigasi berlapis.

Marjan
sumber
+1 untuk jawaban yang sangat terperinci dan dijelaskan dengan baik. Namun, Anda tidak menjelaskan cara kerja data faceted ... Data faceted digunakan untuk menghasilkan jumlah filter.
Yonn Trimoreau
hai @ Marjan, dalam kasus saya kategori tingkat ketiga tidak muncul di filter, ini pertanyaan saya, magento.stackexchange.com/questions/270442/…
jafar pinjar