From 68cc7ebc055f443b10b7c27fe2e8b756dcc7a4e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:04:27 +0000 Subject: [PATCH 1/4] Initial plan From 15f206bedcad2d0b48b939d67c3030afcaaca3a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:09:14 +0000 Subject: [PATCH 2/4] Add --hook flag to eval and eval-file commands with tests Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/eval.feature | 85 ++++++++++++++++++++++++++++++++++++++++ src/EvalFile_Command.php | 28 ++++++++++++- src/Eval_Command.php | 30 +++++++++++++- 3 files changed, 139 insertions(+), 4 deletions(-) diff --git a/features/eval.feature b/features/eval.feature index 82169214..ba4f2f29 100644 --- a/features/eval.feature +++ b/features/eval.feature @@ -248,3 +248,88 @@ Feature: Evaluating PHP code and files. """ eval()'d code """ + + Scenario: Eval with --hook flag + Given a WP install + + When I run `wp eval 'echo "Hook: " . current_action();' --hook=init` + Then STDOUT should contain: + """ + Hook: init + """ + + When I run `wp eval 'echo "Hook: " . current_action();' --hook=wp_loaded` + Then STDOUT should contain: + """ + Hook: wp_loaded + """ + + Scenario: Eval-file with --hook flag + Given a WP install + And a hook-script.php file: + """ + ] + * : Execute file after a specific WordPress hook has fired. + * * @when before_wp_load * * ## EXAMPLES @@ -38,6 +41,9 @@ class EvalFile_Command extends WP_CLI_Command { * # Execute file my-code.php and pass value1 and value2 arguments. * # Access arguments in $args array ($args[0] = value1, $args[1] = value2). * $ wp eval-file my-code.php value1 value2 + * + * # Execute file after the 'init' hook. + * $ wp eval-file my-code.php --hook=init */ public function __invoke( $args, $assoc_args ) { $file = array_shift( $args ); @@ -52,11 +58,29 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( '"-" and "--use-include" parameters cannot be used at the same time' ); } - if ( null === Utils\get_flag_value( $assoc_args, 'skip-wordpress' ) ) { + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); + $skip_wordpress = Utils\get_flag_value( $assoc_args, 'skip-wordpress' ); + + if ( $hook && null !== $skip_wordpress ) { + WP_CLI::error( 'The --hook parameter cannot be used with --skip-wordpress.' ); + } + + if ( $hook ) { + add_action( + $hook, + function () use ( $file, $args, $use_include ) { + self::execute_eval( $file, $args, $use_include ); + } + ); + } + + if ( null === $skip_wordpress ) { WP_CLI::get_runner()->load_wordpress(); } - self::execute_eval( $file, $args, $use_include ); + if ( ! $hook ) { + self::execute_eval( $file, $args, $use_include ); + } } /** diff --git a/src/Eval_Command.php b/src/Eval_Command.php index 2029680e..c3d5b89a 100644 --- a/src/Eval_Command.php +++ b/src/Eval_Command.php @@ -18,6 +18,9 @@ class Eval_Command extends WP_CLI_Command { * [--skip-wordpress] * : Execute code without loading WordPress. * + * [--hook=] + * : Execute code after a specific WordPress hook has fired. + * * ## EXAMPLES * * # Display WordPress content directory. @@ -28,14 +31,37 @@ class Eval_Command extends WP_CLI_Command { * $ wp eval 'echo rand();' --skip-wordpress * 479620423 * + * # Execute code after WordPress is fully loaded. + * $ wp eval 'echo "Current user: " . wp_get_current_user()->user_login;' --hook=wp_loaded + * Current user: admin + * * @when before_wp_load */ public function __invoke( $args, $assoc_args ) { - if ( null === Utils\get_flag_value( $assoc_args, 'skip-wordpress' ) ) { + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); + $skip_wordpress = Utils\get_flag_value( $assoc_args, 'skip-wordpress' ); + + if ( $hook && null !== $skip_wordpress ) { + WP_CLI::error( 'The --hook parameter cannot be used with --skip-wordpress.' ); + } + + if ( $hook ) { + $code = $args[0]; + add_action( + $hook, + function () use ( $code ) { + eval( $code ); + } + ); + } + + if ( null === $skip_wordpress ) { WP_CLI::get_runner()->load_wordpress(); } - eval( $args[0] ); + if ( ! $hook ) { + eval( $args[0] ); + } } } From a929acb829482a1d430058cc9f75386dfbc3c266 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sun, 1 Feb 2026 20:45:08 -0500 Subject: [PATCH 3/4] Apply suggestions from code review --- src/EvalFile_Command.php | 2 +- src/Eval_Command.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EvalFile_Command.php b/src/EvalFile_Command.php index 3bdeade1..90074f25 100644 --- a/src/EvalFile_Command.php +++ b/src/EvalFile_Command.php @@ -66,7 +66,7 @@ public function __invoke( $args, $assoc_args ) { } if ( $hook ) { - add_action( + WP_CLI::add_wp_hook( $hook, function () use ( $file, $args, $use_include ) { self::execute_eval( $file, $args, $use_include ); diff --git a/src/Eval_Command.php b/src/Eval_Command.php index c3d5b89a..8d59ca27 100644 --- a/src/Eval_Command.php +++ b/src/Eval_Command.php @@ -48,7 +48,7 @@ public function __invoke( $args, $assoc_args ) { if ( $hook ) { $code = $args[0]; - add_action( + WP_CLI::add_wp_hook( $hook, function () use ( $code ) { eval( $code ); From 33d7538530a7d4c95a72b3dd5483adfac259cd7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:26:12 +0000 Subject: [PATCH 4/4] Refactor to use closure pattern for improved readability Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/EvalFile_Command.php | 13 ++++++------- src/Eval_Command.php | 14 ++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/EvalFile_Command.php b/src/EvalFile_Command.php index 90074f25..e83da319 100644 --- a/src/EvalFile_Command.php +++ b/src/EvalFile_Command.php @@ -58,6 +58,10 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( '"-" and "--use-include" parameters cannot be used at the same time' ); } + $execute_closure = function () use ( $file, $args, $use_include ) { + self::execute_eval( $file, $args, $use_include ); + }; + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); $skip_wordpress = Utils\get_flag_value( $assoc_args, 'skip-wordpress' ); @@ -66,12 +70,7 @@ public function __invoke( $args, $assoc_args ) { } if ( $hook ) { - WP_CLI::add_wp_hook( - $hook, - function () use ( $file, $args, $use_include ) { - self::execute_eval( $file, $args, $use_include ); - } - ); + WP_CLI::add_wp_hook( $hook, $execute_closure ); } if ( null === $skip_wordpress ) { @@ -79,7 +78,7 @@ function () use ( $file, $args, $use_include ) { } if ( ! $hook ) { - self::execute_eval( $file, $args, $use_include ); + $execute_closure(); } } diff --git a/src/Eval_Command.php b/src/Eval_Command.php index 8d59ca27..1c94a853 100644 --- a/src/Eval_Command.php +++ b/src/Eval_Command.php @@ -39,6 +39,10 @@ class Eval_Command extends WP_CLI_Command { */ public function __invoke( $args, $assoc_args ) { + $execute_closure = function () use ( $args ) { + eval( $args[0] ); + }; + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); $skip_wordpress = Utils\get_flag_value( $assoc_args, 'skip-wordpress' ); @@ -47,13 +51,7 @@ public function __invoke( $args, $assoc_args ) { } if ( $hook ) { - $code = $args[0]; - WP_CLI::add_wp_hook( - $hook, - function () use ( $code ) { - eval( $code ); - } - ); + WP_CLI::add_wp_hook( $hook, $execute_closure ); } if ( null === $skip_wordpress ) { @@ -61,7 +59,7 @@ function () use ( $code ) { } if ( ! $hook ) { - eval( $args[0] ); + $execute_closure(); } } }