Як виконати керування та отримати повернене значення?


10

Тож є такий сценарій.

Я додаю дію для очищення журналів із бази даних:

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

Тепер я хочу періодично запускати цю дію:

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

і виконати його вручну:

do_action( 'myplugin_clean_logs' );

Метод MyPlugin_Logs::clean_logsповертає кількість уражених рядків або помилкових, якщо щось пішло в іншому напрямку.

Тепер я хочу показати кількість рядків, які були видалені. Я б уявив щось подібне:

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

Але оскільки do_actionне поверне жодне значення, я не маю уявлення, як отримати повернене значення.

Чи слід виконувати метод безпосередньо в ручному виконанні, але використовувати дію на графіку подій?


1
Ви не хочете, щоб щось повторювалося на запланованій події, так що так, я би застосував метод безпосередньо під час запуску вручну (я припускаю, що адміністратор запустив би це, і ви хочете показати їм вихід).
Тім Малоун

Відповіді:


13

Класна річ - фільтр - це те саме, що і дія, тільки він повертає значення, тому просто встановіть його як фільтр:

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

Тоді щось на кшталт:

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

має перейти $affected_rowsдо clean_logs()(і будь-яких інших функцій, які ви, можливо, підключили myplugin_clean_logs) і присвоїти повернене значення назад $affected_rows.


4
тому що це хакерський код замість розробки програмного забезпечення. Якби дії були лише підмножиною фільтрів, у них не було б потреби. Cron не може передавати значення для нього, його не слід зачіпати як фільтр, навіть якщо баггі-код основного коду дозволяє вам робити такі шмігани :)
Марк Каплун

1
Точка взята. Я розумію, що наміри двох різних речей, але щоб подивитися на основний код тут, вся do_action()справа - це не що інше, як детальний злом apply_filters():)
Caspar,

не єдиний поганий дизайн в основі, який частково - це те, що призводить до плутанини, що призводить до таких питань
Марк Каплун

1
Нам потрібно працювати з тим, що у нас є, тому, хоча я розумію точку зору Марка, я все ще думаю, що це законна відповідь - якщо, звичайно, ядро ​​не змінить цей підхід у майбутньому, але я вважаю, що це малоймовірно через масивні проблеми з сумісністю назад це запровадило б.
Тім Малоун

3
Дякую, @TimMalone Я ціную заперечення @ mark-kaplun. У моїй відповіді описано, як обійти do_action()не повернення значення, а не як створити рішення у відповідності з do_action()наміром s. Якщо хтось здатний зробити те, що він просить, ця відповідь заслуговує на прийняту відповідь. Першою моєю думкою було б, щоб метод гачок (припустимо, що ОП використовує дизайн OOP для цього плагіна) перенести його результат у захищену властивість класу плагінів, а потім записати швидкий геть, щоб витягнути його в якийсь пізній момент. Але це просто дике волосся ідеї!
Каспар

-1

Ніколи не використовував цю функцію і не перевіряв її, але чи може вона працювати? dogery_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);

Якщо це не працює, чому б не просто відфільтрувати те, як запропонував Каспар? Я маю на увазі, що це мета фільтра, і в цьому випадку кількість уражених рядків - це те, що фільтрується. (Я сумую за старим MortCore. Хтось пам’ятає, як він обробляв значення повернення, пропускний посилання та аргументи лише з однією функцією трьох параметрів?)


Це жахлива відповідь, оскільки передача та зміна значень за посиланням - це дійсно погана практика. Чесно кажучи, ця відповідь дійсно не надає значення в контексті питання, і, ймовірно, її слід видалити або змінити на коментар. Крім того, використання анонімних функцій з гачками також є поганою практикою, оскільки унеможливлює їх зняття.
Hybrid Web Dev

Я погоджуюся з тих же вищезгаданих причин, що це не рекомендований шлях. Якщо вам з якихось причин потрібно отримати повернене значення від дії, і вам потрібне щось швидке і брудне, я вважаю за краще рішення Caspars. Якщо ви розробляєте щось із життєвим циклом попереду, я б шукав більш надійний спосіб. Подумайте, як щодо сповіщень адміністратора? developer.wordpress.org/reference/hooks/admin_notices
jgangso
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.