Come fare_azione e ottenere un valore di ritorno?


10

Quindi c'è il seguente scenario.

Aggiungo un'azione per pulire i registri dal database:

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

Ora voglio eseguire questa azione periodicamente:

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

ed eseguirlo manualmente:

do_action( 'myplugin_clean_logs' );

Il metodo MyPlugin_Logs::clean_logsrestituisce il conteggio delle righe interessate o false se qualcosa è andato nella direzione opposta.

Ora voglio visualizzare il numero di righe che sono state eliminate. Immaginerei qualcosa del genere:

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

Ma poiché do_actionnon restituirà alcun valore, non ho idea di come ottenere il valore restituito.

Devo eseguire il metodo direttamente su un'esecuzione manuale, ma utilizzare l'azione sugli eventi di pianificazione?


1
Non si desidera echeggiare nulla su un evento programmato, quindi sì, eseguirò il metodo direttamente su un'esecuzione manuale (suppongo che l'amministratore lo attiverà e si desidera mostrare loro l'output).
Tim Malone,

Risposte:


13

La cosa interessante è che un filtro è lo stesso di un'azione, solo che restituisce un valore, quindi basta impostarlo come filtro:

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

Quindi qualcosa come:

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

dovrebbe passare $affected_rowsa clean_logs()(e qualunque altra funzione tu possa aver collegato myplugin_clean_logs) e assegnare il valore di ritorno a $affected_rows.


4
sottovalutato poiché si tratta di hacking del codice anziché dello sviluppo di software. Se le azioni fossero solo un sottoinsieme di filtri non ce ne sarebbe stato bisogno. Cron non può passare valore per questo non dovrebbe essere agganciato come filtro anche se il codice core buggy ti consente di fare tali transessuali :)
Mark Kaplun,

1
Punto preso. Capisco che l' intento delle due cose diverse, ma per guardare qui il codice di base, il tutto do_action()non è altro che un elaborato hack di apply_filters():)
Caspar

non l'unico cattivo design nel nucleo che in parte è ciò che porta alla confusione che porta a domande come questa
Mark Kaplun,

1
Dobbiamo lavorare con quello che abbiamo, quindi mentre capisco il punto di vista di Mark penso ancora che questa sia una risposta legittima - a meno che ovviamente il nucleo non cambi questo approccio in futuro, ma penso che sia improbabile a causa dei massicci problemi di compatibilità con le versioni precedenti introdurrebbe.
Tim Malone,

3
Grazie, @TimMalone. Apprezzo l'obiezione di @ mark-kaplun. La mia risposta descrive come aggirare il do_action()non restituire un valore piuttosto che come progettare una soluzione in accordo con l' do_action()intento. Se qualcuno è in grado di fare ciò che sta chiedendo, quella risposta merita di essere la risposta accettata. Il mio primo pensiero sarebbe di avere il metodo hook (supponendo che l'OP stia usando un design OOP per questo plugin) rilasciare il risultato in una proprietà protetta della classe plugin e quindi scrivere un getter rapido per estrarlo in un momento successivo. Ma è solo un capello selvaggio di un'idea!
Caspar,

-1

Non hai mai usato questa funzione e non l'ho ancora provata, ma potrebbe funzionare? do_action_ref_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);

Se ciò non funziona, perché non filtrare semplicemente ciò che Caspar ha suggerito? Voglio dire, quello è lo scopo di un filtro, e in questo caso il numero di righe interessate è l'elemento che viene filtrato. (Mi manca il vecchio MortCore. Qualcuno ricorda come ha gestito i valori di ritorno, il riferimento pass-by e gli argomenti con una sola funzione a tre parametri?)


Questa è una risposta orribile, in quanto passare e modificare i valori per riferimento è davvero una cattiva pratica. Onestamente, questa risposta in realtà non fornisce valore nel contesto della domanda e dovrebbe probabilmente essere rimossa o modificata in un commento. Inoltre, l'uso di funzioni anonime con hook è anche una cattiva pratica, in quanto li rende impossibili da sganciare.
Hybrid Web Dev,

Concordo per le stesse ragioni sopra menzionate, che questo non è un percorso raccomandato. Se per qualche motivo hai bisogno di ottenere un valore di ritorno da un'azione e hai bisogno di qualcosa di rapido e sporco, preferirei la soluzione Caspars. Se stai sviluppando qualcosa con un ciclo di vita avanti, cercherei un modo più robusto. Venendo a pensare, che ne dici di avvisi di amministrazione? developer.wordpress.org/reference/hooks/admin_notices
jgangso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.