Làm thế nào để do_action và nhận được giá trị trả về?


10

Vì vậy, có kịch bản sau đây.

Tôi thêm một hành động để xóa nhật ký từ cơ sở dữ liệu:

add_action( 'myplugin_clean_logs', array( 'MyPlugin_Logs', 'clean_logs' ) );

Bây giờ tôi muốn chạy hành động này định kỳ:

wp_schedule_event( current_time( 'timestamp' ), 'daily', 'myplugin_clean_logs' );

và thực hiện nó bằng tay:

do_action( 'myplugin_clean_logs' );

Phương thức MyPlugin_Logs::clean_logstrả về số lượng hàng bị ảnh hưởng hoặc sai nếu có thứ gì đó đi theo hướng khác.

Bây giờ tôi muốn hiển thị số lượng hàng đã bị xóa. Tôi sẽ tưởng tượng một cái gì đó như thế này:

$affected_rows = do_action( 'myplugin_clean_logs' );
echo $affected_rows . ' entries have been deleted.';

Nhưng vì do_actionsẽ không trả lại bất kỳ giá trị nào, tôi không biết làm thế nào để có được giá trị trả về.

Tôi có nên thực hiện phương thức trực tiếp khi chạy thủ công không, nhưng sử dụng hành động theo lịch sự kiện?


1
Bạn không muốn lặp lại bất cứ điều gì trong một sự kiện theo lịch trình, vì vậy, tôi sẽ thực hiện phương pháp trực tiếp khi chạy thủ công (tôi giả sử quản trị viên sẽ kích hoạt điều này và bạn muốn cho họ thấy đầu ra).
Tim Malone

Câu trả lời:


11

Điều thú vị là một bộ lọc giống như một hành động, chỉ có nó trả về một giá trị, vì vậy chỉ cần thiết lập nó làm bộ lọc thay thế:

add_filter( 'myplugin_clean_logs', array( 'MyPlugin_Logs', 'clean_logs' ) );

Sau đó, một cái gì đó như:

$affected_rows = '';
$affected_rows = apply_filters( 'myplugin_clean_logs', $affected_rows );

nên chuyển $affected_rowsđến clean_logs()(và bất kỳ chức năng nào khác mà bạn có thể đã nối vào myplugin_clean_logs) và gán giá trị trả về $affected_rows.


4
hạ cấp vì đây là mã hack thay vì phát triển phần mềm. Nếu các hành động chỉ là một tập hợp con của các bộ lọc thì sẽ không có nhu cầu nào về chúng. Cron không thể vượt qua giá trị vì nó không nên được nối như một bộ lọc ngay cả khi mã lõi lỗi cho phép bạn thực hiện các shemigans như vậy :)
Mark Kaplun

1
Điểm lấy. Tôi hiểu ý định của hai thứ khác nhau, nhưng nhìn vào mã cốt lõi ở đây, toàn bộ do_action()không có gì khác hơn là một bản hack công phu của apply_filters():)
Caspar

không phải là thiết kế tồi duy nhất trong cốt lõi mà một phần là nguyên nhân dẫn đến sự nhầm lẫn dẫn đến những câu hỏi như thế này
Mark Kaplun

1
Chúng ta cần phải làm việc với những gì chúng ta có, vì vậy trong khi tôi hiểu quan điểm của Mark, tôi vẫn nghĩ đây là một câu trả lời hợp pháp - trừ khi tất nhiên cốt lõi thay đổi cách tiếp cận này trong tương lai, nhưng tôi nghĩ rằng điều đó không thể xảy ra do các vấn đề tương thích ngược lớn nó sẽ giới thiệu.
Tim Malone

3
Cảm ơn, @TimMopol. Tôi đánh giá cao sự phản đối của @ mark-kaplun. Câu trả lời của tôi mô tả cách làm việc xung quanh do_action()không trả về giá trị hơn là cách thiết kế giải pháp phù hợp với do_action()ý định của s. Nếu ai đó có thể làm những gì anh ta yêu cầu, câu trả lời đó xứng đáng là câu trả lời được chấp nhận. Suy nghĩ đầu tiên của tôi là sử dụng phương thức hooked (giả sử OP đang sử dụng thiết kế OOP cho plugin này) thả kết quả của nó vào một thuộc tính được bảo vệ của lớp plugin và sau đó viết một getter nhanh để rút nó ra sau đó. Nhưng đó chỉ là một ý tưởng hoang dã!
Caspar

-1

Chưa bao giờ sử dụng chức năng này và chưa thử nghiệm chức năng này, nhưng nó có thể hoạt động không? do_action_Vf_array () .

function myplugin_clean_logs_fn() {
    $args = array(
        'param1'        => 'val1',
        'param2'        => 'val2',
        'affected_rows' => 0,
    );
    do_action_ref_array( 'myplugin_clean_logs', &$args );
    return $args['affected_rows'];
}

// CALL IT
$affected_rows = my_plugin_clean_logs();
echo $affected_rows .' entr'. ($args['affected_rows']*1===1?'y':'ies') .' deleted.';

// SCHEDULE IT
add_action('myplugin_clean_logs_call_fn', 'myplugin_clean_logs_fn');
wp_schedule_event( current_time( 'timestamp' ), 'daily', 'myplugin_clean_logs_call_fn' );

// A SAMPLE FILTER
add_action('myplugin_clean_logs', function($args) {
    // Cleaning process
    // For each log affected, increment $args['affected_rows'] accordingly
}, 10, 3);

Nếu điều đó không hiệu quả, tại sao không chỉ lọc những thứ như Caspar đề xuất? Ý tôi là, đó là mục đích của bộ lọc và trong trường hợp này, số lượng hàng bị ảnh hưởng là thứ được lọc. (Tôi nhớ MortCore cũ. Có ai nhớ cách nó xử lý các giá trị trả về, tham chiếu qua và tham số chỉ với một hàm ba tham số không?)


Đây là một câu trả lời khủng khiếp, vì truyền vào và sửa đổi các giá trị bằng cách tham chiếu là thực tế xấu. Thành thật mà nói, câu trả lời này thực sự không cung cấp giá trị trong ngữ cảnh của câu hỏi và có thể sẽ bị xóa hoặc thay đổi thành một nhận xét. Ngoài ra, sử dụng các hàm ẩn danh với các hook cũng là một cách làm không tốt, vì nó khiến chúng không thể mở khóa.
Lai Web Dev

Tôi đồng ý với các lý do tương tự đã đề cập ở trên, rằng đây không phải là một con đường được đề xuất. Nếu bạn vì một lý do nào đó cần nhận được giá trị trả về từ một hành động và cần một cái gì đó nhanh chóng và bẩn thỉu, tôi sẽ thích giải pháp Caspars hơn. Nếu bạn đang phát triển một cái gì đó với vòng đời phía trước, tôi sẽ tìm kiếm một cách mạnh mẽ hơn. Nghĩ đến, làm thế nào về thông báo quản trị? developer.wordpress.org/reference/hooks/admin_notices
jgangso
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.