Ghi đè chức năng của một mô-đun trong một mô-đun khác


7

Module1 có chức năng có tên 'function1'. 'function1' không phải là một loại hook, nhưng nó là một hàm gọi lại menu hoặc được gọi bên trong hook.

Module2 muốn ghi đè 'function1' bằng cách sử dụng tất cả các biến có sẵn cho function1 bên trong Module1.

Tôi có thể gọi hàm1 bằng cách sử dụng module_load_include(), nhưng tôi cần ghi đè hàm được gọi.

Làm thế nào tôi có thể đạt được điều này?


bạn nên chọn câu trả lời đúng
vishal

Câu trả lời:


7

Nếu bạn muốn sử dụng một hàm gọi lại menu khác, bạn có thể triển khai hook_menu_alter () để thay đổi gọi lại menu. Giả sử bạn muốn ghi đè trình đơn gọi lại menu Drupal xác định cho tìm kiếm , bạn có thể sử dụng mã sau đây.

function mymodule_menu_alter(&$items) {
  if (isset($items['search'])) {
    $items['search']['page callback'] = 'mymodule_search_view';
  }
}

Từ mymodule_search_view()bạn có thể gọi search_view () mà không cần bao gồm tệp chứa tệp đó, vì điều đó được thực hiện từ Drupal trước khi gọi lại menu gọi lại.

Mã tương tự có thể được thực hiện nếu gọi lại menu đang trả về một biểu mẫu, ngoại trừ việc thay vì gọi lại trang (có lẽ là drupal_get_form () ), bạn sẽ thay đổi đối số trang để sử dụng làm đối số đầu tiên cho tên gọi lại của Hàm trả về mảng mẫu. Thay vì làm điều này, bạn nên triển khai hook_form_alter () và để ẩn các phần tử biểu mẫu không cần thiết bằng $form['element']['#access'] = FALSE', and not withunset ($ form ['Element']) `.

Đối với việc thay thế một chức năng được gọi từ một hook, những gì có thể được thực hiện là loại bỏ việc thực hiện hook gọi chức năng đó và thay thế nó bằng một triển khai khác. Chỉ có thể với Drupal 7, và nó phải được thực hiện cẩn thận. (Tôi sẽ giải thích lý do đúng.)
Giả sử bạn muốn thay đổi hàm được gọi trong menu_node_update () (việc triển khai hook_node_update () ) từ menu_node_save () thành mymodule_node_save(). Bạn có thể sử dụng mã sau đây.

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'node_update') {
    $group = $implementations['mymodule'];
    unset($implementations['mymodule']);
    unset($implementations['menu']);

    $implementations = array('mymodule' => group) + $implementations;
  }
}

function mymodule_node_update($node) {
  mymodule_node_save();
}

Theo cách này, menu_node_update()sẽ không được gọi nữa, nhưng mymodule_node_update()sẽ.

Thông thường, các mô-đun phụ thuộc từ một hook được thực hiện bởi một mô-đun khác không kiểm tra xem hook đó có được thực thi hay không; họ kiểm tra mô-đun được kích hoạt (và giả sử hook được gọi) hoặc họ thêm mô-đun đó làm phụ thuộc. Tránh một hook được thực thi có thể gây ra vấn đề cho các mô-đun khác có thể khó theo dõi. Nếu thực sự cần thiết để tránh một hook được thực hiện bởi một mô-đun khác được thực thi, trước tiên bạn nên kiểm tra trên một trang web thử nghiệm rằng tất cả đang hoạt động như mong đợi. Hãy nhớ rằng phiên bản Drupal trong tương lai có thể phá vỡ mã của bạn và mã bạn đang viết cũng nên được kiểm tra trên phiên bản Drupal trong tương lai (khi chúng có sẵn).


2

Bạn nên thử một module_invoke_all

Giả sử mô-đun của bạn Một cuộc gọi lại trả về biến $ output như thế này:

function module_a_callback($args){
$output =... your calculs ...
return $output;
}

Thêm cái này: module_invoke_all ('module_a_alter');

function module_a_callback($args){
$output = ... your calculs ...

// call all module implementing your 'module_a_alter' hook
$alter =  module_invoke_all('module_a_alter', $args);

//if there is an answer, 
$final_output = isset($alter[0]) ? $alter[0] : $output;
return $output;
}

Bạn vừa tạo hook hook_module_a_alter ($ args). Trong mô-đun B của bạn, tạo triển khai hook tương ứng

function module_b_module_a_alter($args){
 $output =... your calculs from module B ...
return $output;
}

Ở đây một methode thứ hai, nhanh hơn, sử dụng các biến được truyền bởi tham chiếu:

 function module_a_callback($args){
 $output = ... your calculs ...

// call all module implementing your 'module_a_alter' hook
module_invoke_all('module_a_alter', $output,  $args);

return $output;
}

Trong mô-đun B của bạn, tạo triển khai hook tương ứng

function module_b_module_a_alter(&$output, $args){
 $output =... your calculs from module B ...
}

Có một cái nhìn về điều này cho một tuto nhỏ. Bạn cũng có thể sử dụng module_invoke cho phép bạn chỉ định mô-đun nghe cuộc gọi hook của bạn.


1
Các móc thay đổi Drupal được gọi với drupal_alter () . Tôi giả sử câu hỏi được đặt ra cho trường hợp chung, khi OP không phát triển Module1. Nếu OP phát triển Module1, thì tốt hơn là hỗ trợ hook thay đổi từ mô-đun đó.
kiamlaluno

0

Đây là một vấn đề ngôn ngữ php hơn là về Drupal mỗi se ....

Bạn không thể xác định lại một chức năng trong php theo mặc định. Bạn có thể thử sử dụng tiện ích mở rộng runkit cho phép bạn làm điều đó, nhưng theo tôi biết việc sử dụng runkit trên các máy chủ sản xuất không được khuyến nghị vì nó có thể khá nặng.

Trong trường hợp bạn thực sự cần thay đổi chức năng của một mô-đun khác, một bản vá được duy trì tốt có lẽ phù hợp hơn.

Trong Drupal 8, vấn đề này tôi sẽ ít gặp phải vấn đề hơn vì trọng tâm đang chuyển hướng nhiều hơn sang lõi OO (tất nhiên là rất tuyệt vời) nhưng hiện tại chúng tôi đang gặp khó khăn với các loại tình huống này.


OP đang hỏi làm thế nào để thay thế một cuộc gọi lại menu, hoặc một chức năng được gọi từ một hook. Cả hai trường hợp không phải là vấn đề ngôn ngữ PHP.
kiamlaluno

@kiam Lúc đầu tôi cũng nghĩ vậy, nhưng OP nói không phải là một loại hook, mà nó là một cuộc gọi lại menu, hoặc được gọi bên trong một hook. hook_menu_alter()sẽ tốt cho gọi lại menu, nhưng đối với một hàm ngẫu nhiên được gọi bên trong hook, bạn sẽ phải ghi đè thực hiện hook để thay đổi hàm được gọi (nghe có vẻ quen thuộc;)) ... hoặc thay thế hàm hiện tại bằng hàm khác, sẽ xuất hiện xuống nhiều hơn một vấn đề ngôn ngữ IMO. Mặc dù vậy, tôi có thể đã hiểu nhầm, thật khó khi không có ví dụ mã để làm việc từ
Clive

1
Sẽ tốt hơn nếu câu hỏi yêu cầu một trường hợp cụ thể; theo cách đó, chúng tôi sẽ không đưa ra một lý luận trừu tượng.
kiamlaluno

-2

Hãy thử ghi đè đầu ra của chức năng này bằng một chức năng khác, nơi cả hai gặp nhau trong bất kỳ hook nào khác (như bạn đã đề cập đến chức năng đang được gọi bên trong hook).


1
Tôi đã không bỏ phiếu, nhưng câu trả lời này không hữu ích. Ý bạn là gì khi "ghi đè đầu ra của chức năng này bằng chức năng khác"? Nếu hook đang gọi function1(), làm thế nào để bạn gọi nó function2()thay thế?
kiamlaluno

bằng cách áp dụng hook bổ sung bên trong chức năng của bạn, thực thi sau cái đầu tiên.
Ashish

OP đang nói về một chức năng được gọi từ một hook được thực hiện từ một mô-đun khác. Anh ta muốn thay thế chức năng được gọi từ cái móc đó bằng một cái khác.
kiamlaluno
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.