Các hàm không dùng trong lớp plugin


8

Tôi đang cập nhật một trong các plugin của mình và tôi hơi bị mắc kẹt với các chức năng không dùng nữa.

Ban đầu, plugin của tôi có một biến toàn cục và lớp chính của plugin đã được khởi tạo và lưu trữ trong biến toàn cục. Bằng cách này, người dùng có thể sử dụng toàn cầu để truy cập các chức năng trong lớp plugin.

$GLOBALS['my_custom_plugin'] = new my_custom_plugin();

Sau đó, ví dụ, trong Câu hỏi thường gặp của tôi, tôi có mã chỉ ra cách loại bỏ một trong các hàm của lớp khỏi một hook cụ thể và thêm vào một hook khác:

function move_input(){ 
    global $my_custom_plugin;
    remove_action( 'before_main_content', array( $my_custom_plugin, 'display_input') );
    add_action( 'after_main_content', array( $my_custom_plugin, 'display_input' ) );
}
add_action( 'wp_head' , 'move_input' );

Bây giờ, trong bản cập nhật của tôi, display_input()chức năng đã được chuyển sang một lớp khác và tôi muốn cho mọi người biết cách truy cập nó. Tôi đã thử thay thế chức năng ban đầu (trong lớp plugin chính) bằng thông báo phản đối sau:

public function display_input() { 
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
    return $this->display->display_input();
}

Tuy nhiên, add_actionvà các remove_actionchức năng dường như không kích hoạt thông báo khấu hao. Thật kỳ lạ, loại bỏ hoàn toàn chức năng không gây ra lỗi dù array( $my_custom_plugin, 'display_input')không tồn tại.

Nếu ai đó cố gắng truy cập chức năng trực tiếp:

$my_custom_plugin->display_input();

Sau đó, tôi thấy các thông báo gỡ lỗi. Đây có phải là kết quả mong đợi cho _deprecated_function()? hoặc tôi đang thiếu một cái gì đó? Có thể hiển thị thông báo gỡ lỗi khi ai đó cố gắng xóa hoặc thêm một hành động bằng cách sử dụng chức năng không dùng nữa không?

Cập nhật

Tôi nhận ra rằng tôi chỉ đơn giản là không thấy thông báo gỡ lỗi add_actionvì tôi đã thêm nó khá thấp trên trang. #facepalm! Tuy nhiên, tôi vẫn không thấy bất kỳ thông báo gỡ lỗi nào cho remove_action.


Hoạt call_user_func(function(){trigger_error('hello?');});động thú vị , nhưng nó thất bại trong một cuộc gọi lại được đăng ký cho mỗi add_action.
fuxia

Chuẩn bị cho facepalm, nhưng đó là một câu hỏi hoặc một tuyên bố?
xe đạp vào

Chỉ là một kết quả kiểm tra. Tôi cũng ngạc nhiên.
fuxia

Ok, vì vậy tôi đã không thực sự bỏ qua bất cứ điều gì, đó chỉ là cách nó ?
xe đạp vào

2
Oh, Query Monitor đã ẩn thông báo trong thiết lập của tôi. Thông điệp cho add_action()đã thực sự ở đó. remove_action()không thể bị xử lý như thế.
fuxia

Câu trả lời:


2

Cuộc gọi lại không tồn tại

Một trong những điều tốt đẹp là, không do_action(), cũng apply_filters()không gây ra lỗi nếu không có cuộc gọi lại. Điều này có nghĩa là cách an toàn nhất để chèn dữ liệu plugin vào các mẫu: Nếu một plugin bị tắt và do_action()/ apply_filters()không tìm thấy cuộc gọi lại trong $wp_filtersmảng toàn cầu , không có gì xảy ra.

Lỗi đầu ra

Bây giờ khi bạn đang gọi remove_filter()hàm / phương thức ban đầu đã gọi lại cuộc gọi, cuộc gọi lại đơn giản sẽ bị xóa khỏi mảng toàn cầu, điều đó có nghĩa là cuộc gọi lại sẽ không bao giờ được thực hiện vì nó không được đăng ký nữa.

Giải pháp rất đơn giản: Loại bỏ cuộc gọi lại sau khi nó được kích hoạt, bằng cách loại bỏ nó từ bên trong chính cuộc gọi lại.

Xóa cuộc gọi lại

Chúng ta đều biết rằng "API" plugin WPs là một nỗi đau khi gỡ bỏ. Vấn đề chủ yếu là cấu trúc lạ để thêm tên "duy nhất" vào các khóa trong global $wp_filter;mảng. Một giải pháp rất đơn giản là chỉ sử dụng __METHOD__và gọi các bộ lọc mà bạn muốn loại bỏ trong ngữ cảnh tĩnh:

class FOoooo
{
    public function __construct()
    {
        add_filter( 'hook', array( __CLASS__, 'bar' ) );
    }
    public static function bar( $baz )
    {
        remove_filter( current_filter(), __METHOD__ );

        return $baz;
    }
}

Mặc dù điều này không tốt, nhưng ... đây là một giải pháp cho một số trường hợp sử dụng. Nhưng thậm chí không nghĩ về việc loại bỏ một đóng cửa.

Ở trên chỉ cần loại bỏ cuộc gọi lại, vẫn thực hiện nó. Tuy nhiên, bạn có thể đi xa hơn và sử dụng remove_all_actions()(hoặc remove_all_filters()).

// Check if a callback is attached and tell about the deprecated stuff
if ( has_action( 'before_main_content' ) )
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
// Remove the callback
remove_all_actions( 'before_main_content' );

Bạn thậm chí có thể đi xa hơn, trích xuất cuộc gọi lại từ mảng bộ lọc toàn cầu và gắn lại nó vào hook / bộ lọc mới (nếu chúng tương thích).


Cảm ơn Kaiser! Đây là một câu trả lời tuyệt vời và chi tiết. Tôi sẽ cố gắng kiểm tra nó vào ngày mai.
xe đạp
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.