Magento 2: ข้อมูลประกอบการทำงานของการนำทางแบบเลเยอร์เป็นอย่างไร


10

ฉันได้สร้างโมดูลสำหรับตัวกรองที่กำหนดเองในหน้าหมวดหมู่ทุกสิ่งทำงานได้ดียกเว้นช่วงราคาในการนำทางแบบเลเยอร์

โปรดใครก็ได้อธิบายให้ฉันฟังว่า getFacetedData ('price') ทำงานอย่างไรใน magento2

$productCollection->getFacetedData('price');

ฟังก์ชั่นนี้ให้ช่วงราคาตามคอลเล็กชันผลิตภัณฑ์เริ่มต้นที่ไม่อิงคอลเลกชันที่กรองของฉัน

FYI: ฉันได้รวบรวมคอลเล็กชันดังต่อไปนี้

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

คำตอบ:


7

รหัสด้านล่างนี้ใช้กับ Magento 2.2.5

ก่อนอื่นในแถบด้านข้างต้องสร้างช่วงที่เป็นไปได้ทั้งหมดสำหรับตัวกรองที่เป็นไปได้ทั้งหมด นอกจากนี้คุณจะมีภาพรวมของจำนวนผลิตภัณฑ์ที่พบภายในช่วงที่กำหนด

ป้อนคำอธิบายรูปภาพที่นี่

ตัวอย่างเช่นฉันจะเน้นไปที่การใช้ตัวกรองเดียว: ราคา

ก่อนอื่นเพื่อให้แอททริบิวผลิตภัณฑ์ที่ระบุมีสิทธิ์ได้รับการนำทางแบบเลเยอร์ควรกำหนดค่าอย่างเหมาะสม

หากต้องการตรวจสอบให้เรียกดูในผู้ดูแลระบบถึงStores -> Attribute -> Productจากนั้นเลือกคุณลักษณะราคาและสังเกตว่าในStorefront Propertiesแท็บ Use in Layered Navigationตั้งค่าเป็นFilterable (with results)

ภาพนี้เราจะเห็นว่าสำหรับตัวกรองราคาที่เราเห็นช่วงตั้งแต่50.00-59.99มี10ผลและสำหรับเท่านั้น80+1

มุมมองนี้ผลิตขึ้นภายใน

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

มีรหัสคล้ายกับ

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

ซึ่งในที่สุดก็สแตกถึง

private function prepareData($key, $count)

และนี่คือวิธีการจาก

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

ดังนั้นเราจึงระบุคลาสที่รับผิดชอบการกรองราคาและเราเห็นว่ามีการใช้ในการผลิตช่วงที่มีอยู่แล้ว


สแต็คที่สำคัญกว่านั้นคือการตรวจสอบว่าเกิดอะไรขึ้นเมื่อเลือกช่วงเฉพาะ

ตัวอย่างเช่นฉันจะคลิกที่ช่วง 40.00-49.99 ซึ่งคาดว่าจะส่งคืนผลลัพธ์ 4 รายการ

ขึ้นเป็นครั้งแรกเป็นวิธีการ_prepareLayout()จาก

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

รหัสคือ

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

ในสาระสำคัญนี้กล่าวว่าได้รับฉันฟิลเตอร์และ foreach applyของพวกเขา

ตอนนี้ getFilters () เพียงอย่างเดียวในที่สุดก็นำไปสู่การสร้างวัตถุจาก

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

ขั้นตอนการเรียกร้องที่นำไปสู่__constructการPriceมี

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;
}

และนี่คือรหัสจาก

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

อย่างไรก็ตามถ้าเรามุ่งกลับไปที่$filter->apply($this->getRequest());รหัสจากด้านบนนี่หมายความว่ารหัสนี้จะถูกเรียกใช้งาน

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;
}

และอีกครั้งรหัสนี้มาจาก

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

หากฉันติดตามค่าตัวแปรอย่างใกล้ชิดอีกครั้งเนื่องจากฉันได้เลือกช่วง 40.00-49.99 ดังนั้น$filterอาร์เรย์ที่ประกอบด้วยองค์ประกอบสองอย่างคือ: [0 => 40, 1 => 50]

หลังจากรันบรรทัดนี้แล้ว

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

เห็นได้ชัดว่า$fromตอนนี้ตัวแปรอยู่ที่ 40 และ$toตอนนี้ก็คือตัวแปร 50

บรรทัดถัดไปเป็นสิ่งสำคัญ

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

addFieldToFilter()นี่คือที่คอลเลกชันอยู่แล้วที่เกี่ยวข้องกับชั้นที่ได้รับลดลงต่อไปโดยการเรียก

บางทีนี่อาจเป็นที่ที่ควรให้ความสนใจเพื่อตรวจจับข้อบกพร่องถ้ามี

ในที่สุดโปรแกรมเรียกใช้ getLoadedProductCollection () จาก

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

ซึ่งใน efect ส่งกลับคอลเลกชันที่มีการป้องกันที่วัตถุนี้แค็ปซูล


Magento เป็นแอพพลิเคชั่นที่ซับซ้อน

ในคลิกเดียวที่เลือกราคาเดียวช่วงนี้เราเห็นโค้ดจากโมดูลที่แตกต่างกันสามโมดูลที่โต้ตอบกัน

  • โมดูลแคตตาล็อก
  • โมดูลแคตตาล็อกการค้นหา
  • โมดูลชั้นนำทาง

มันอาจรู้สึกท่วมท้นในบางช่วงเวลา แต่ดูเหมือนว่าสำหรับฉันมันมีการทำงานร่วมกันที่ดีระหว่างโมดูลนี้

ขอบคุณสำหรับการอ่าน. ฉันหวังว่าสิ่งนี้จะอธิบายได้และตอนนี้คุณก็มีความเข้าใจที่ดีขึ้นเล็กน้อยเกี่ยวกับการนำทางแบบเลเยอร์


+1 สำหรับคำตอบที่ละเอียดและอธิบายได้ดีมาก อย่างไรก็ตามคุณไม่ได้อธิบายว่าข้อมูลประกอบเป็นอย่างไร ... ข้อมูลประกอบถูกนำมาใช้เพื่อสร้างจำนวนตัวกรอง
Yonn Trimoreau

สวัสดี @Marjan ในกรณีของฉันหมวดหมู่ระดับที่สามไม่แสดงในตัวกรองนี่คือคำถามของฉันmagento.stackexchange.com/questions/270442/…
jafar pinjar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.