Magento 1: làm thế nào để ghi đè / ghi lại một lớp trình điều khiển lõi?


7

Lưu ý : Đây là một câu hỏi chính tắc giải thích đầy đủ cách thức bộ điều khiển viết lạ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 đè bộ điều khiển 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 lớp trình điều khiển lõi trong 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?


1
Bạn có nghĩ rằng đã có nhiều Câu trả lời toàn diện cho Magento 1 không? Tái bút: Bạn có thể xem câu hỏi mới nhất của tôi không :)
Vishwas Bhatnagar

2
Không chắc tôi cảm thấy thế nào về điều này. (Đó không phải là sự lên án cũng không phải sự ngưỡng mộ.)
benmark

1
@VishwasBhatnagar vui lòng kiểm tra liên kết trong câu hỏi để hiểu đầy đủ lý do tại sao câu hỏi đó được hỏi;)
Raphael tại Digital Pianism

@benmark vui lòng liên hệ với tôi nếu bạn muốn có một cuộc thảo luận về điều này. Có lẽ Fabian cũng nên ở đó
Raphael tại Digital Pianism

Câu trả lời:


11

Có nhiều cách tiếp cận nhưng tôi sẽ bắt đầu với cách nó không được thực hiện để làm rõ một số quan niệm sai lầm phổ biến:

  1. Đó là không thể thực hiện để ghi đè lên lớp điều khiển bằng cách sao chép chúng app/code/local. Điều này là do các lớp trình điều khiển không được tải bởi Varien_Autoload, thay vào đó các tệp được bao gồm rõ ràng.
  2. Không nên sử dụng <rewrite><controller><to>cú pháp nữa. Đây là một kỹ thuật cũ đã lỗi thời kể từ Magento 1.3 (xem: Bộ điều khiển ghi đè so với yêu cầu bộ điều khiển hành động ghi đè )

Thêm / ghi đè hành động của bộ điều khiển

Để thêm các hành động của bộ điều khiển vào một bộ điều khiển hiện có, hãy sử dụng các thao tác sau trong tệp config.xml của bạn:

<frontend>             <--- area (adminhtml or frontend)
    <routers>
        <checkout>     <--- front name (in admin always "adminhtml")
            <args>
                <modules>
                    <stack_checkout before="Mage_Checkout">Stack_Checkout</stack_checkout>
                                                  ^                ^
                                                  |                |
                                           module to override      |
                </modules>                 (in admin always        |
            </args>                        "Mage_Adminhtml")   your module
        </checkout>
    </routers>
</frontend>

Sau đó tạo một bộ điều khiển trong mô-đun của bạn, chẳng hạn như

class Stack_Checkout_OnepageController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
        // here you override checkout/onepage/index
    }
    public function helloAction()
    {
        // here you create a new action checkout/onepage/hello
    }
}

Bạn không cần phải mở rộng lớp trình điều khiển gốc vì Magento sẽ tìm trong cả hai lớp, theo thứ tự được xác định bởi before="..."

Nếu bạn cần mở rộng lớp ban đầu vì bạn muốn sử dụng lại các phương thức khác từ nó, bạn phải bao gồm nó (hãy nhớ rằng, bộ điều khiển không được tự động tải):

require_once(Mage::getModuleDir('controllers','Mage_Checkout') . DS . 'OnepageController.php');

Sử dụng trình quan sát để sửa đổi hành động của bộ điều khiển

Nếu bạn không thêm hành động mới , một cách khác là sử dụng người quan sát để sửa đổi hành vi của hành động hiện có. Mọi hành động của bộ điều khiển đều kích hoạt một sự kiện "preispatch" động trong biểu mẫu controller_action_predispatch_$FRONTNAME_$CONTROLLER_$ACTION, ví dụcontroller_action_predispatch_checkout_onepage_index

Trong trình quan sát, bạn có quyền truy cập vào chính lớp điều khiển bằng cách sử dụng

$controller = $observer->getControllerAction();

Nếu bạn không muốn phương thức ban đầu được kích hoạt, hãy nói với Magento để không tiếp tục gửi hành động:

$controller->setFlag('', Mage_Core_Controller_Front_Action::FLAG_NO_DISPATCH, true);

Để hoàn thiện: Bạn cũng có thể ngăn các sự kiện "postdispatch" theo cách tương tự, nhưng điều này thường không cần thiết (đây là một ví dụ hữu ích: XML có thêm nội dung ):

$controller->setFlag('', Mage_Core_Controller_Front_Action::FLAG_NO_POST_DISPATCH);

Nói về điều này, bạn cũng có thể thêm một người quan sát controller_action_postdispatch_$FRONTNAME_$CONTROLLER_$ACTIONnếu bạn muốn thực hiện các hành động bổ sung hoặc sửa đổi phản hồi sau khi hành động ban đầu được thực thi.


3

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ề Viết lại: Khi viết lại, bạn phải tạo lớp riêng của mình và cần mở rộng lớp lõi và bạn có thể viết lại các hàm lõi magento hoặc hàm và logic của riêng bạn ở đó

Trong tập tin cấu hình của bạn

<config>
<frontend>
    <routers>
        <tag>
            <args>
                <modules>
                    <inchoo_tag before="Mage_Tag">Inchoo_Tag</inchoo_tag>
                </modules>
            </args>
        </tag>
    </routers>
</frontend>

Trong tập tin điều khiển của bạn

require_once(Mage::getModuleDir('controllers','Mage_Tag').DS.'TagController.php');


class Inchoo_Tag_TagController extends Mage_Tag_TagController
{
// some code
}

Tại adminhtml

trong tệp cấu hình của bạn phải là

<config>
<admin>
    <routers>
        <adminhtml>
            <args>
                <modules>
                    <inchoo_tag before="Mage_Adminhtml">Inchoo_Tag_Adminhtml</inchoo_tag>
                </modules>
            </args>
        </adminhtml>
    </routers>
</admin>

và lớp trình điều khiển của bạn phải là

require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'TagController.php');


class Inchoo_Tag_Adminhtml_TagController extends Mage_Adminhtml_TagController
{
// some code
}

Cảm ơn bạn cho nhóm Inchoo cho bài viết tốt đẹp này

http://inchoo.net/magento/overriding-magento-blocks-models-helpers-and-controllers/


1
Đã được một lúc, nhưng tôi nghĩ bạn không thể ghi đè các định nghĩa lớp của trình điều khiển thông qua nhóm mã.
đánh dấu

Ok tôi sẽ cập nhật câu trả lời của tôi
Murtuza Zabuawala
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.