diff --git a/.gitignore b/.gitignore index 719628aa..b1bc7e5e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ svn /WARP.md /AGENTS.md /tsconfig.tsbuildinfo +.agents +/CLAUDE.md \ No newline at end of file diff --git a/modules/wordpress.php b/modules/wordpress.php index 68ff1126..bd47e60c 100644 --- a/modules/wordpress.php +++ b/modules/wordpress.php @@ -304,6 +304,13 @@ public function get_canonical_target() { * @return void */ public function canonical_domain() { + // In a plain PHP CLI bootstrap (e.g. a cron script that loads wp-load.php) + // there is no real HTTP request to redirect. Running die() here would + // silently terminate the CLI process before user code can execute. + if ( red_is_cli() ) { + return; + } + $target = $this->get_canonical_target(); if ( $target !== false ) { @@ -323,6 +330,12 @@ public function init() { return; } + // Skip the redirect loop in a plain PHP CLI bootstrap. A matched rule + // would call wp_redirect()+die() and silently terminate the CLI process. + if ( red_is_cli() ) { + return; + } + $request = new Red_Url_Request( Redirection_Request::get_request_url() ); // Make sure we don't try and redirect something essential diff --git a/redirection.php b/redirection.php index 005b16c7..9f864a15 100644 --- a/redirection.php +++ b/redirection.php @@ -98,6 +98,18 @@ function red_is_wpcli() { return false; } +/** + * Detect a plain PHP CLI context (e.g., a cron script that loads wp-load.php + * directly). Distinct from red_is_wpcli(), which is only true under WP-CLI. + * Used to skip front-end redirect enforcement that would otherwise call die() + * and silently terminate the CLI process. + * + * @return bool + */ +function red_is_cli() { + return PHP_SAPI === 'cli'; +} + /** * @return bool */