ฉันจะแทนที่ / เขียนคลาสบล็อกใน Magento 1 ได้อย่างไร


12

หมายเหตุ:คำถามนี้มีวัตถุประสงค์เพื่อเป็นคำถามมาตรฐานที่อธิบายการทำงานของการเขียนบล็อกใหม่อย่างสมบูรณ์และสามารถใช้เป็นเป้าหมายที่ซ้ำกันสำหรับคำถาม "ฉันจะเขียนทับบล็อก X" ได้อย่างไรหรือคำถาม "ทำไมการเขียนซ้ำของฉันไม่ทำงาน"

ดูเพิ่มเติม: ค้นหาคำถามที่เป็นที่ยอมรับเกี่ยวกับการแทนที่ Magento 1

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

คำตอบ:


23

ทุก ๆ บล็อกหรือกลุ่มของบล็อกถูกประกาศในconfig.xmlไฟล์ของโมดูลเช่นนี้ (ภายใน<global>แท็ก)
นี่คือตัวอย่างจากโมดูลแคตตาล็อก

    <blocks><!-- marks definition of a block group -->
        <catalog><!-- unique alias for blocks in the module -->
            <class>Mage_Catalog_Block</class><!-- class prefix for all blocks -->
        </catalog>
    </blocks>

ซึ่งหมายความว่าบล็อกสามารถสร้างอินสแตนซ์ได้โดยใช้นามแฝงcatalog/class_name_hereซึ่งclass_name_hereเป็นส่วนที่เหลือของคลาสพา ธ เริ่มต้นจากคำนำหน้า
วิธีการนี้จะถูกแมปโดยค่าเริ่มต้น catalog/class_name_hereMage_Catalog_Block_Class_Name_Here

ในการเขียนบล็อกใหม่คุณต้องสร้างโมดูลที่ขึ้นอยู่กับโมดูลที่คุณพยายามเปลี่ยน ( Magento_Catalog) ในตัวอย่างของฉัน
และคุณต้องเพิ่มสิ่งนี้ในconfig.xmlใต้<global>แท็ก

<blocks>
    <catalog><!-- alias of the block group you are rewriting -->
        <rewrite><!-- reserved tag: specify that you are rewriting something -->
             <class_name_here>YourNamespace_YourModule_Block_Your_New_Class_Here</class_name_here> <!-- tag: the rest of the alias of the class you are rewriting. value: the name of your class that rewrites the core class -->
        </rewrite>
    </catalog>
</blocks>

จากนั้นสร้างคลาสYourNamespace_YourModule_Block_Your_New_Class_Here(ตามโครงสร้างโฟลเดอร์ ZF) และทำให้คลาสนี้ขยายคลาสดั้งเดิม

class YourNamespace_YourModule_Block_Your_New_Class_Here extends Mage_Catalog_Block_Class_Name_Here
{
    //your awesome code here
}

เมื่อเสร็จแล้วให้ปิดการรวบรวมและเปิดใช้งานอีกครั้ง (ถ้าจำเป็น) และล้างแคช

สิ่งนี้จะไม่ทำงานสำหรับบล็อกนามธรรม
ใช้งานได้เฉพาะคลาสที่ได้รับอินสแตนซ์

ตัวอย่าง

สมมติว่าคุณต้องการที่จะเขียนไฟล์แอป \ รหัส \ หลัก \ Mage \ แคตตาล็อก \ บล็อก \ สินค้า \ ดู \ Options \ ประเภท \ Select.phpซึ่งมีชั้นเรียนMage_Catalog_Block_Product_View_Options_Type_SelectในโมดูลของคุณเองMarius_Test

จากนั้นคุณจะต้องมีรายการนี้ในconfig.xml:

<blocks>
    <catalog>
        <rewrite>
            <product_view_options_type_select>Marius_Test_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>
        </rewrite>
    </catalog>
</blocks>

แอพ \ code \ local \ Marius \ Test \ Block \ Catalog \ Product \ View \ Options \ Type \ Select.php :

class Marius_Test_Block_Catalog_Product_View_Options_Type_Select extends Mage_Catalog_Block_Product_View_Options_Type_Select
{
    //your awesome code here
}

ไม่สำเร็จ. ฉันพยายามที่จะเขียนทับชั้นMage_Catalog_Block_Product_View_Options_Type_Selectในแอปพลิเค \ รหัส \ ท้องถิ่น \ WR \ EPO \ บล็อก \ แคตตาล็อก \ บล็อก \ สินค้า \ ดู \ Options \ ประเภท \ Select.php ฉันลองแบบนี้: codepen.io/anon/pen/WYOqBr
Black

และถ้ามันไม่ทำงานคุณคิดว่าคำตอบของฉันผิดดังนั้นคุณลงคะแนนแทนที่จะคิดว่าบางทีคุณอาจทำอะไรผิด อย่างไรก็ตาม ... แทนที่สิ่งนี้<Mage_Catalog_Block_Product_View_Options_Type_Select> WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select </Mage_Catalog_Block_Product_View_Options_Type_Select>ด้วย<product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>และตรวจสอบให้แน่ใจว่าไม่มีที่ว่างภายในproduct_view_options_type_select
Marius

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

หากคุณอ่านทีละขั้นตอนคุณพลาดขั้นตอน ที่ที่ฉันอธิบายว่านามแฝงของชั้นเรียนคืออะไร หากคุณเพียงแค่คัดลอกวางแทนที่คุณจะได้มันทำงาน 17 คนเข้าใจ ฉันคิดว่าฉันอธิบายถูกต้อง
Marius

ใช่ แต่ตัวอย่างที่ดีหายไปเพื่อให้เรามั่นใจได้ว่าเราเข้าใจทฤษฎีของคุณอย่างถูกต้อง
ดำ

4

สำหรับมุมมองการแทนที่ของฉันและเขียนสองสิ่งนี้ใหม่เป็นสิ่งที่แตกต่างกัน

แทนที่:

เมื่อเราใช้กลไกทางเลือกการออกแบบแล้วเราจะทำการแทนที่

เขียน:

เมื่อเราทำการเขียน magento Core ในชั้นเรียนของเราเราจะทำการเขียนใหม่

1) ตัวอย่างการแทนที่:

ถ้าฉันต้องการแทนที่app/code/core/Mage/Catalog/Block/Product/List.phpไฟล์ฉันก็อปปี้โมดูลโลคัลของฉันด้วยพา ธ เดียวกันที่แสดงด้านล่างapp/code/local/Mage/Catalog/Block/Product/List.php

นี่ไม่ใช่การแนะนำโดย magento แต่คุณสามารถทำเช่นนั้นได้

2) ตัวอย่างการเขียนซ้ำ:

ถ้าฉันต้องการที่จะเขียนคลาสบล็อกนี้ใหม่Mage_Adminhtml_Block_Sales_Order_Createแล้วฉันรหัสในโมดูล config.xml ของฉันเหมือนด้านล่าง

    <global>
        <blocks>
            <adminhtml>
                <rewrite>

                    <sales_order_create>Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create</sales_order_create>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>

และในชั้นเรียนของฉัน Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

ฉันรหัส Like ด้านล่าง

class Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create extends Mage_Adminhtml_Block_Sales_Order_Create {
      My Function Or funcions That I want to Rewrite..
}

2

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

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

ปัญหาที่อาจเกิดขึ้น 2: Rewritten Block (หรือคลาสอื่น ๆ ) อาจถูกเขียนใหม่โดยส่วนขยายอื่นซึ่งคุณหรือผู้ดูแลคนอื่นจะพยายามติดตั้ง จากนั้นคุณจะต้องแก้ไขข้อขัดแย้งนี้

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

ทางเลือกที่ 2:เขียนซ้ำอย่างชาญฉลาดเช่นมองไปรอบ ๆ : อาจตรวจสอบสถานที่ที่คุณจะเขียนชั้นเรียนใหม่และตรวจสอบว่าคุณสามารถส่งผลกระทบต่อชั้นเรียนที่เลือกผ่านการกำหนดค่าหรือเหตุการณ์ อาจมีคลาสที่ให้คุณแทนที่เมธอด 3 บรรทัดเพื่อแทนที่ classname แทนการคัดลอกเมธอด 30 บรรทัดจากคลาสดั้งเดิมไปเป็น rewritten

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