EE 1.14.2 / CE 1.9.2: รายการอ้างไม่ได้รวมอย่างถูกต้องในการเข้าสู่ระบบ (ผลิตภัณฑ์ที่ซ้ำกันในตะกร้า)


16

ฉันพบข้อผิดพลาดแปลก ๆ ใน Magento EE 1.14.2 (มีผลกับ CE 1.9.2) ด้วยรถเข็น

ขั้นตอนในการทำซ้ำ:

  1. เข้าสู่ระบบในฐานะลูกค้า
  2. เพิ่มผลิตภัณฑ์ X ลงในรถเข็น
  3. เปลี่ยนเป็นเบราว์เซอร์อื่น
  4. เพิ่มผลิตภัณฑ์ X ลงในรถเข็น
  5. เข้าสู่ระบบในฐานะลูกค้า

รถเข็นที่คาดหวัง:

  • 2 x ผลิตภัณฑ์ X

รถเข็นจริง:

  • 1 x ผลิตภัณฑ์ X
  • 1 x ผลิตภัณฑ์ X

นั่นคือผลิตภัณฑ์จะไม่ถูกรวมเข้าด้วยกัน

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

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

เหตุใดสิ่งนี้จึงเกิดขึ้นและฉันจะป้องกันได้อย่างไร

คำตอบ:


18

Nice สรุปข้อผิดพลาดข้างต้น Fabian!

สำหรับผู้ใช้เพิ่มเติมที่จะมาถึงข้อบกพร่องนี้มีแพทช์จาก Magento สำหรับเรื่องนี้แล้ว

ในฐานะลูกค้าองค์กรคุณสามารถขอ / ดาวน์โหลดPATCH_SUPEE-6190_EE_1.14.2.0_v1.shเพื่อแก้ไขปัญหานี้ได้

อัพเดท 24.02.2016:สิ่งนี้ได้รับการแก้ไขใน SUPEE-7405 v 1.1 patch ล่าสุดด้วย ตามที่เฟเบียนพูดเบาและรวดเร็ว (ดูทวีตนี้และทวีตถัดไป ) มีโอกาสที่จะยังไม่ได้รับการแก้ไขอย่างสมบูรณ์ กรุณาทดสอบด้วยตัวเอง

สำหรับ EE 1.14.2.0 การแก้ปัญหาคือ:

diff --git a/app/code/core/Mage/Sales/Model/Quote/Item.php b/app/code/core/Mage/Sales/Model/Quote/Item.php
index 3554faa..d759249 100644
--- a/app/code/core/Mage/Sales/Model/Quote/Item.php
+++ b/app/code/core/Mage/Sales/Model/Quote/Item.php
@@ -502,8 +502,8 @@ class Mage_Sales_Model_Quote_Item extends Mage_Sales_Model_Quote_Item_Abstract
                         $itemOptionValue = $_itemOptionValue;
                         $optionValue = $_optionValue;
                         // looks like it does not break bundle selection qty
-                        unset($itemOptionValue['qty'], $itemOptionValue['uenc']);
-                        unset($optionValue['qty'], $optionValue['uenc']);
+                        unset($itemOptionValue['qty'], $itemOptionValue['uenc'], $itemOptionValue['form_key']);
+                        unset($optionValue['qty'], $optionValue['uenc'], $optionValue['form_key']);
                     }
                 }

หมายเหตุ: โดยปกติฉันจะไม่โพสต์รหัส EE ที่นี่ แต่เนื่องจากปัญหา / ไฟล์เหมือนกับใน CE และไม่ส่งผลกระทบต่อฟีเจอร์ EE-only ฉันหวังว่ามันจะโอเค


4
ฉันเห็นด้วยกับสิ่งนี้
philwinkle

5
เราจะปล่อยให้มันเลื่อน
benmarks

1
เลื่อนดูแล้ว
Marius

วิธีนี้ใช้งานได้ดีกว่าการแก้ไขซึ่งทำให้เกิดปัญหากับชุดผลิตภัณฑ์ ขอบคุณสำหรับการแบ่งปัน!
Fabian Schmengler

1
น่าเสียดายที่นี่ยังสามารถข้ามได้หากคุณเพิ่มผลิตภัณฑ์หนึ่งครั้งผ่านรายการผลิตภัณฑ์และอีกครั้งผ่านทางหน้ารายละเอียดผลิตภัณฑ์เนื่องจากพารามิเตอร์ "related_products" มีเฉพาะในกรณีหลังเท่านั้น คุณสามารถเพิ่ม "related_products" ให้กับการunset()โทรได้เช่นกัน แต่ก็ยังไม่ปลอดภัยเนื่องจากมีการเพิ่มพารามิเตอร์ POST ใด ๆ ลงในตัวเลือก buyRequest เช่นกัน ฉันจะไม่สนใจตัวเลือกนี้อย่างสมบูรณ์แทน
Fabian Schmengler

15

ปรากฎว่านี่เป็นข้อบกพร่อง Mage_Sales_Model_Quote_Item::compare()ที่ได้รับการแนะนำใน Magento CE 1.9.2 / EE 1.14.2 วิธีนี้ใช้ในการเปรียบเทียบสินค้าเพื่อตัดสินใจว่าเป็นสินค้าเดียวกันและสามารถรวมกันได้หรือไม่ (ระหว่างการเข้าสู่ระบบและเมื่อเพิ่มสินค้าลงในตะกร้า)

เมื่อเปรียบเทียบตัวเลือกที่กำหนดเองทั้งหมดควรข้ามตัวเลือกที่ไม่ได้รับการตอบกลับ ( _notRepresentOptions) คือตัวเลือกinfo_buyRequest

ในเวอร์ชันวีโอไอพีรุ่นก่อนหน้าดูเหมือนว่า:

foreach ($this->getOptions() as $option) {
    if (in_array($option->getCode(), $this->_notRepresentOptions)) {
        continue;
    }

และทำงานอย่างถูกต้อง ตอนนี้ดูเหมือนว่านี้:

foreach ($this->getOptions() as $option) {
    if (in_array($option->getCode(), $this->_notRepresentOptions)
        && !$item->getProduct()->hasCustomOptions()
    ) {
        continue;
    }

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

อย่างไรก็ตาม$item->getProduct()->hasCustomOptions()จะส่งกลับค่าจริงสำหรับรายการคำพูดเสมอ!

นี่คือวิธีการ:

public function hasCustomOptions()
{
    if (count($this->_customOptions)) {
        return true;
    } else {
        return false;
    }
}

แต่$this->_customOptionsยังมีinfo_buyRequestตัวเลือกจากรายการอ้างอิง

สำหรับวิธีการที่ไม่เป็นการรบกวนฉันพยายามลบinfo_buyRequestตัวเลือกออกจากผลิตภัณฑ์ทั้งหมดในผู้สังเกตการณ์sales_quote_merge_beforeโดยไม่ประสบความสำเร็จ

เหตุผลอยู่Mage_Sales_Model_Quote_Item_Abstract::getProduct()ที่ตัวเลือกจะถูกคัดลอกอีกครั้งจากรายการอ้างอิง:

public function getProduct()
{
    $product = $this->_getData('product');

    [...]

    if (is_array($this->_optionsByCode)) {
        $product->setCustomOptions($this->_optionsByCode);
    }
    return $product;
}

วิธีการแก้

ฉันสร้าง rewrite สำหรับMage_Sales_Model_Quote_Itemโดยแทนที่สำหรับที่getProduct()จะไม่รวมinfo_buyRequestตัวเลือก ณ จุดนี้:

public function getProduct() { $product = parent::getProduct(); $options = $product->getCustomOptions(); if (isset($options['info_buyRequest'])) { unset($options['info_buyRequest']); $product->setCustomOptions($options); } return $product; }

ปัญหานี้ทำให้เกิดปัญหากับชุดผลิตภัณฑ์ทางเลือกด้านล่างหรือแพทช์อย่างเป็นทางการตามที่อธิบายโดย @ AnnaVölklเป็นทางออกที่ดีกว่า

ทางเลือก

นอกจากนี้คุณยังสามารถลบการละเมิด&& !$item->getProduct()->hasCustomOptions()ในcompare()วิธีการถ้าคุณเขียนโมเดลรายการต่อไป ฉันไม่ทราบว่าจะพยายามแก้ปัญหาอะไร แต่มันสร้างเพิ่มเติม ...

อัปเดต 29 มกราคม 2559

ฉันรายงานเรื่องนี้กับ Magento และได้รับการตอบกลับว่าพวกเขาไม่สามารถทำซ้ำปัญหาได้ดังนั้นโปรแกรมแก้ไขจะไม่ทำให้เป็นฉบับชุมชน (การส่ง APPSEC-1321)

ซึ่งหมายความว่าหากคุณมีปัญหาคุณต้องใช้แพตช์องค์กร SUPEE-6190 หลังจากการอัพเดทแต่ละครั้งหรือใช้การเขียนคลาสแทน


However, $item->getProduct()->hasCustomOptions() always returns true for quote items!มันคือการตรวจสอบข้อมูลผลิตภัณฑ์สำหรับตัวเลือกที่กำหนดเองไม่ได้เป็นรายการที่อ้าง :)
kanevbgbe

1
@kanevbgbe ไม่น่าแปลกใจเลย Magento "เตรียม" อินสแตนซ์ของผลิตภัณฑ์ที่เกี่ยวข้องกับรายการราคาและเพิ่มค่าตัวเลือกที่กำหนดเอง
Fabian Schmengler

ฉันรู้ว่าในการเพิ่มการกระทำของรถเข็นอินสแตนซ์ของผลิตภัณฑ์จะถูกโหลดอย่างเต็มที่ (เทียบกับโหลดของใบเสนอราคา) ดังนั้นจึงถูกตั้งค่าจากนอกอัลกอริทึมของใบเสนอราคาโดยตรงไปยังอินสแตนซ์ .
kanevbgbe

1

ตามที่ฉันเห็นคำตอบข้างต้นมีอยู่แล้วใน Magento เวอร์ชันล่าสุด แต่เรายังคงได้รับปัญหา มันไม่ทำงานเพราะเราทำการปรับแต่งเป็นจำนวนมาก คิดว่าจะแบ่งปันวิธีแก้ปัญหา

สำหรับเรามันง่ายมากเพราะเราใช้ผลิตภัณฑ์ที่เรียบง่ายเท่านั้น ดังนั้นเราจึงขยายฟังก์ชันการเปรียบเทียบอัญประกาศเป็นสิ่งนี้:

NS_Module_Model_Sales_Quote_Item ขยาย Mage_Sales_Model_Quote_Item {

public function compare($item) {
    if ($this->getProductId() == $item->getProductId()) {
        return true;
    }
    return parent::compare($item);
}

}

และเพิ่ม

<models>
   <sales>
      <rewrite>
         <quote_item>NS_Module_Model_Sales_Quote_Item</quote_item>
      </rewrite>
   </sales>
</models>

แต่. สำหรับผู้ที่ใช้ผลิตภัณฑ์ที่กำหนดค่าได้เช่นกันอาจไม่เป็นประโยชน์สำหรับคุณ ในกรณีนั้นคุณสามารถพิมพ์ทั้งอาร์เรย์: $ itemOptionValue และ $ optionValue และดูความแตกต่าง ยกเลิกการตั้งค่าคีย์เพิ่มเติมทั้งหมดซึ่งไม่เหมือนกันในทั้งสองอาร์เรย์ ที่ควรแก้ปัญหา


-1

คุณสามารถเพิ่มตัวเลือกให้กับผลิตภัณฑ์ใน event sales_quote_add_item:

$data['microtime'] = microtime(true);
$product->addCustomOption('do_not_merge', serialize($data));
$item->addOption($product->getCustomOption('do_not_merge'));

ลิงค์อ้างอิง: ปิดการรวมตำแหน่งรถเข็นหรือไม่


นั่นเป็นวิธีแก้ไขปัญหา แต่การปิดใช้งานการรวมรายการอย่างสมบูรณ์มักไม่เป็นที่ต้องการ
Fabian Schmengler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.