จะโคลนชุดสะสมใน Magento ได้อย่างไร?


12

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

$collectionเพื่อให้ง่ายนี้สมมติว่าผมมีคอลเลกชันวัตถุที่เรียกว่า

ตอนนี้ฉันกำลังลองด้วยการโคลนนิ่ง PHP เพราะฉันไม่รู้ว่ามีการเก็บรวบรวมวีโอไอพีที่มีการโคลน inbuilt หรือไม่

$coll1 = clone $collection;
$coll2 = clone $collection;

ตอนนี้ฉันกำลังพยายามทำการดำเนินการที่แตกต่างกันในทั้งสองโคลนแยกของคอลเลกชันดั้งเดิมบางอย่างเช่น

$coll1->getSelect()->where('some where condition');
$coll2->getSelect()->where('some different where condition');
if($coll1->count() == 0) {
    $collection = $coll2;
} else {
    $collection = $coll1;
}

แต่สิ่งที่แปลกก็คือทั้งคอลเล็กชั่นโคลนเหล่านี้มีทั้งเงื่อนไขที่กำหนด! เงื่อนไข $ coll1 ถูกนำไปใช้กับ $ coll2 พร้อมกับเงื่อนไขของ $ coll2 และในทางกลับกัน

ไม่มีใครรู้วิธีการบรรลุเป้าหมายนี้หรือไม่?

ขอบคุณ!

คำตอบ:


14

การใช้ตัวดำเนินการโคลน PHP ที่ต้องการการโคลนนิ่งลึกต้องใช้คลาสที่เก็บวัตถุบนคุณสมบัติใช้เมธอด __clone เพื่อคัดลอกวัตถุ หากพวกเขาไม่ได้กำหนดคุณสมบัติของทั้งสองอินสแตนซ์จะอ้างอิงวัตถุเดียวกัน

Magento ไม่ได้ใช้ __clone กับบทคัดย่อชุดสะสมของมันและดังนั้นจึงไม่สนับสนุนการโคลนแบบลึกตามที่คุณต้องการ

คำแนะนำของฉันคือมองหาวิธีอื่น ๆ ในการทำสิ่งที่คุณต้องการให้สำเร็จเนื่องจากการโคลนคอลเล็กชันอาจมีราคาค่อนข้างสูง

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

แก้ไข:ข้อมูลต่อไปนี้สาธิตวิธีการนับจำนวนโดยไม่ต้องโหลดหรือแก้ไขคอลเล็กชันจริง ๆ

$collection = Mage::getModel(...)->getCollection();

$count = $collection->getSelectCountSql();
$count->where('some where condition');
if ($count->query()->fetchColumn() == 0) {
    ...
} else {
    ...
}

เป็นเพียงรายละเอียดเล็ก ๆ น้อย ๆ : ข้อมูลสถานที่ที่ถูกบันทึกไว้$collection->getSelect()และไม่ได้อยู่ในการรวบรวม
เฟเบียน Blechschmidt

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

อัปเดตคำตอบพร้อมกับตัวอย่างโค้ด ตามที่ @FabianBlechschmidt ชี้ให้เห็นว่าที่ไหนอยู่ในตัวเลือกซึ่งเป็นที่ที่ปัญหาเฉพาะของคุณมาจากการที่มันไม่ได้ถูกโคลนเมื่อวัตถุการรวบรวมถูกโคลนและทั้งคู่จบลงด้วยการอ้างถึงวัตถุอินสแตนซ์ที่เลือกเดียวกัน
davidalger

ขอบคุณสำหรับการอัพเดท ฉันไม่ได้ลองสิ่งนี้เพราะฉันมีวิธีแก้ปัญหาแบบนั้นอยู่แล้ว
MagExt

ที่จริงแล้วหากมีปัญหาในการโคลนการรวบรวมซีเรียลไลซ์เซชั่นและไม่เป็นจริงจะมีประโยชน์ในกระบวนการ นอกจากนี้ยังมีทางเลือกอื่น ๆ ในการโคลนใน PHP ที่ค่อนข้างดี แต่ทั้งหมดในทุกดาวิดนั้นถูกต้อง ... โดยทั่วไปเมื่อคุณทำการโคลนนิ่งวัตถุที่คุณกำลังทำการพอยน์เตอร์พอยน์เตอร์ไปยังวัตถุที่ซ้อนกันที่แนบมาด้วยเช่นกันถึงแม้ว่าคำตอบของเขาจะไม่ได้กล่าวถึงปัญหาพื้นฐาน
mprototype

1

หากต้องการขยายคำตอบของ @ davidalger คุณสามารถรีเซ็ตตัวเลือกหากคุณต้องการดำเนินการที่แตกต่างจากการนับเช่น:

$select= $collection->getSelectCountSql()->reset();

$select
    ->from('newsletter_subscriber', array('some_column'))
    ->distinct();

โปรดใช้ความระมัดระวังแม้ว่าสิ่งนี้อาจมีผลเสียในภายหลังเนื่องจากกระบวนการนี้แก้ไขการรวบรวม

วิธีที่ดีกว่าคือการคัดลอกตัวเลือกอย่างใดอย่างหนึ่ง แต่สำเนาตื้น ๆ จะไม่ถูกตัดเนื่องจากวัตถุมีชนิดที่ซับซ้อน (Varien_Db_Select หรือ Zend_Db_Select มี__cloneวิธีการ)

วิธีหนึ่งในการหลีกเลี่ยงสิ่งนี้คือการบันทึกข้อมูลที่เลือกแก้ไขเรียกใช้แบบสอบถามของคุณจากนั้นนำข้อมูลที่เลือกดั้งเดิมกลับมา

ดูตัวอย่างได้ที่นี่: https://ka.lpe.sh/2013/05/23/magento-clone-collection-how-to-clone-collection-in-magento/

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