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.
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 Properties
tab,
Use in Layered Navigation
diatur keFilterable (with results)
Pada gambar ini kita melihat bahwa untuk filter harga, kita melihat rentang dari 50.00-59.99
berisi 10
hasil, 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 __construct
dari Price
is
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 $filter
array terdiri dari dua elemen: [0 => 40, 1 => 50]
Setelah baris ini dieksekusi
list($from, $to) = $filter;
Jelas, $from
variabelnya sekarang 40, dan $to
variabelnya 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.