Làm cách nào để ghi đè / viết lại một lớp khối trong Magento 1?


11

Lưu ý: Đây là một câu hỏi chính tắc giải thích đầy đủ cách thức viết lại khối hoạt động và có thể được sử dụng làm mục tiêu trùng lặp cho các câu hỏi "Làm cách nào để ghi đè khối X" hoặc "Tại sao tôi viết lại không hoạt động".

Xem thêm: Tìm kiếm các câu hỏi kinh điển về phần ghi đè Magento 1

Giả sử, tôi phải thay đổi một lớp khối lõi trong một mô-đun tùy chỉnh (thay đổi phương thức hoặc thêm phương thức). Làm thế nào để tôi làm điều này, từng bước một?

Câu trả lời:


22

Mỗi khối hoặc nhóm khối được khai báo trong config.xmltệp của một mô-đun như thế này (bên trong <global>thẻ).
Dưới đây là một ví dụ từ mô-đun danh mục

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

Điều này có nghĩa là một khối có thể được khởi tạo bằng cách sử dụng bí danh catalog/class_name_heretrong đó class_name_herephần còn lại của đường dẫn lớp bắt đầu từ tiền tố.
Điều này có nghĩa là catalog/class_name_heresẽ được ánh xạ theo mặc định Mage_Catalog_Block_Class_Name_Here.

Để viết lại một khối, bạn cần tạo một mô-đun phụ thuộc vào mô-đun mà bạn đang cố gắng thay đổi ( Magento_Catalog) trong ví dụ của tôi.
Và bạn cần thêm cái này vào config.xmldưới <global>thẻ.

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

Sau đó tạo lớp YourNamespace_YourModule_Block_Your_New_Class_Here(theo cấu trúc thư mục ZF) và làm cho lớp này mở rộng lớp ban đầu.

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

Khi bạn đã hoàn tất, tắt chức năng biên dịch và bật lại (nếu cần) và xóa bộ đệm.

Điều này sẽ không làm việc cho các khối trừu tượng.
Nó chỉ hoạt động cho các lớp được khởi tạo.

Thí dụ

Giả sử rằng bạn muốn viết lại ứng dụng tệp \ code \ core \ Mage \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php có lớp Mage_Catalog_Block_Product_View_Options_Type_Selecttrong mô-đun Marius_Test của riêng bạn .

Sau đó, bạn sẽ cần mục này trong 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>

ứng dụng \ 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
}

Không hoạt động. Tôi cố gắng ghi đè lớp Mage_Catalog_Block_Product_View_Options_Type_Selecttrong ứng dụng \ code \ local \ WR \ EPO \ Block \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php . Tôi đã thử nó như thế này: codepen.io/anon/pen/WYOqBr
Black

Và nếu nó không hoạt động, bạn nghĩ rằng câu trả lời của tôi là sai nên bạn hạ thấp nó thay vì nghĩ rằng có thể bạn đang làm gì đó sai. Dù sao ... thay thế điều này <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>bằng <product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>và đảm bảo rằng không có khoảng trống bên trongproduct_view_options_type_select
Marius

Tôi đã từ chối vì câu trả lời của bạn không chính xác và mặc dù tôi đã làm theo từng bước không mang lại kết quả đúng. Bạn đã viết rằng chúng ta phải sử dụng tên lớp, vì vậy tôi đã sử dụng nó và nó không hoạt động. Chúng ta phải sử dụng product_view_options_type_selectthay vì tên lớp thực Mage_Catalog_Block_Product_View_Options_Type_Select. Nếu bạn thay đổi câu trả lời của bạn cho phù hợp thì tôi sẽ upvote.
Đen

Nếu bạn đọc nó từng bước bạn đã bỏ lỡ một bước. Một trong đó tôi giải thích bí danh của lớp là gì. Nếu bạn chỉ sao chép dán thay thế, bạn sẽ làm cho nó hoạt động. 17 người hiểu. Tôi nghĩ rằng tôi đã giải thích nó đúng
Marius

Có, nhưng thiếu một ví dụ tốt để chúng tôi có thể đảm bảo rằng chúng tôi đã hiểu chính xác lý thuyết của bạn
Black

4

Đối với quan điểm của tôi, ghi đè và viết lại hai điều này là những điều khác nhau,

Ghi đè:

Khi chúng ta sử dụng cơ chế dự phòng thiết kế thì chúng ta sẽ ghi đè

Viết lại:

Khi chúng ta viết lại các lớp Magento Core trong lớp thì chúng ta sẽ viết lại.

1) Ví dụ về ghi đè:

Nếu tôi cần ghi đè app/code/core/Mage/Catalog/Block/Product/List.phptập tin thì tôi sao chép trong mô-đun cục bộ của mình với cùng một đường dẫn được hiển thị bên dướiapp/code/local/Mage/Catalog/Block/Product/List.php

Điều này không được đề xuất bởi magento Nhưng bạn có thể làm theo cách đó.

2) Ví dụ về Viết lại:

Nếu tôi muốn viết lại lớp khối này Mage_Adminhtml_Block_Sales_Order_Createthì tôi viết mã trong mô-đun cấu hình của mình.

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

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

Và trong lớp học của tôi Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

Tôi mã như dưới đây

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

Điều quan trọng cần thêm ở đây là việc viết lại khối (cũng như tất cả các lần viết lại khác của các mô-đun Magento) ngụ ý nỗ lực bảo trì cao hơn và do đó nên được coi là cơ hội cuối cùng để mở rộng chức năng sau khi thao tác cấu hình, sự kiện và tùy chỉnh chủ đề.

Vấn đề tiềm ẩn 1: Mẫu viết lại sẽ không được cập nhật khi bạn hoặc người bảo trì khác sẽ cập nhật các tệp nguồn của Magento. Có nghĩa là sửa chữa hoặc cải tiến bảo mật sẽ không được áp dụng cho mã của bạn. Áp dụng tương tự cho các lớp viết lại khác bao gồm Khối, nhưng phụ thuộc vào mức độ viết lại đã được thực hiện (xem bên dưới).

Vấn đề tiềm ẩn 2: Khối viết lại (hoặc lớp khác) có thể được viết lại bởi một phần mở rộng khác mà bạn hoặc người bảo trì khác sẽ cố gắng cài đặt. Sau đó, bạn sẽ phải giải quyết xung đột này.

Phương án 1: Sử dụng các sự kiện, tức là tìm hiểu mã bạn sắp viết lại và kiểm tra xem có sự kiện nào có thể được sử dụng để đạt được chức năng mong muốn hay không.

Cách thay thế 2: Viết lại thông minh, tức là nhìn xung quanh: có thể kiểm tra nơi mà lớp bạn sẽ viết lại được khởi tạo và kiểm tra xem bạn có thể ảnh hưởng đến lớp nào được chọn thông qua cấu hình hoặc sự kiện hay không; có thể có một lớp xung quanh cho phép bạn ghi đè phương thức 3 dòng để thay thế tên lớp thay vì sao chép phương thức 30 dòng từ lớp gốc sang lớp được viết lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.