Skip to content

Commit 1b3b26a

Browse files
CopilotswissspidyCopilot
authored
Fix incorrect home/siteurl when WP-CLI runs from root filesystem (#307)
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Pascal Birchler <pascalb@google.com>
1 parent 300001f commit 1b3b26a

2 files changed

Lines changed: 123 additions & 6 deletions

File tree

features/core-install.feature

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,78 @@ Feature: Install WordPress core
177177
"""
178178
And the return code should be 0
179179
180+
Scenario: Verify correct siteurl and home when URL has no path
181+
Given an empty directory
182+
And WP files
183+
And wp-config.php
184+
And a database
185+
186+
When I run `wp core install --url=example.com --title=Test --admin_user=wpcli --admin_email=wpcli@example.org --admin_password=password --skip-email`
187+
Then STDOUT should contain:
188+
"""
189+
Success: WordPress installed successfully.
190+
"""
191+
192+
When I run `wp option get home`
193+
Then STDOUT should be:
194+
"""
195+
http://example.com
196+
"""
197+
198+
When I run `wp option get siteurl`
199+
Then STDOUT should be:
200+
"""
201+
http://example.com
202+
"""
203+
204+
Scenario: Verify correct siteurl and home when URL has a path
205+
Given an empty directory
206+
And WP files
207+
And wp-config.php
208+
And a database
209+
210+
When I run `wp core install --url=example.com/subdir --title=Test --admin_user=wpcli --admin_email=wpcli@example.org --admin_password=password --skip-email`
211+
Then STDOUT should contain:
212+
"""
213+
Success: WordPress installed successfully.
214+
"""
215+
216+
When I run `wp option get home`
217+
Then STDOUT should be:
218+
"""
219+
http://example.com/subdir
220+
"""
221+
222+
When I run `wp option get siteurl`
223+
Then STDOUT should be:
224+
"""
225+
http://example.com/subdir
226+
"""
227+
228+
Scenario: Install ensures correct siteurl and home regardless of PHP_SELF
229+
Given an empty directory
230+
And WP files
231+
And wp-config.php
232+
And a database
233+
234+
When I run `wp core install --url=https://example.com --title=Test --admin_user=wpcli --admin_email=wpcli@example.org --admin_password=password --skip-email`
235+
Then STDOUT should contain:
236+
"""
237+
Success: WordPress installed successfully.
238+
"""
239+
240+
When I run `wp option get home`
241+
Then STDOUT should be:
242+
"""
243+
https://example.com
244+
"""
245+
246+
When I run `wp option get siteurl`
247+
Then STDOUT should be:
248+
"""
249+
https://example.com
250+
"""
251+
180252
Scenario: Install WordPress with special characters in the admin password
181253
Given an empty directory
182254
And WP files

src/Core_Command.php

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,12 @@ public function is_installed( $args, $assoc_args ) {
474474
* @param array{url: string, title: string, admin_user: string, admin_password?: string, admin_email: string, locale?: string, 'skip-email'?: bool} $assoc_args Associative arguments.
475475
*/
476476
public function install( $args, $assoc_args ) {
477+
// Fix $_SERVER variables early to prevent incorrect URL detection.
478+
// See set_server_url_vars() for details.
479+
if ( isset( $assoc_args['url'] ) ) {
480+
$this->set_server_url_vars( $assoc_args['url'] );
481+
}
482+
477483
if ( $this->do_install( $assoc_args ) ) {
478484
WP_CLI::success( 'WordPress installed successfully.' );
479485
} else {
@@ -606,6 +612,12 @@ public function multisite_convert( $args, $assoc_args ) {
606612
* @param array{url?: string, base: string, subdomains?: bool, title: string, admin_user: string, admin_password?: string, admin_email: string, 'skip-email'?: bool, 'skip-config'?: bool} $assoc_args Associative arguments.
607613
*/
608614
public function multisite_install( $args, $assoc_args ) {
615+
// Fix $_SERVER variables early to prevent incorrect URL detection.
616+
// See set_server_url_vars() for details.
617+
if ( isset( $assoc_args['url'] ) ) {
618+
$this->set_server_url_vars( $assoc_args['url'] );
619+
}
620+
609621
if ( $this->do_install( $assoc_args ) ) {
610622
WP_CLI::log( 'Created single site database tables.' );
611623
} else {
@@ -664,6 +676,38 @@ private static function set_multisite_defaults( $assoc_args ) {
664676
return array_merge( $defaults, $assoc_args );
665677
}
666678

679+
/**
680+
* Fix $_SERVER variables to prevent incorrect URL detection during installation.
681+
*
682+
* When WP-CLI is executed from the root of the filesystem (e.g., /wp), PHP_SELF
683+
* and SCRIPT_NAME contain the WP-CLI executable path rather than the WordPress
684+
* installation path. This causes WordPress's wp_guess_url() to construct incorrect
685+
* URLs. This method overrides these variables based on the provided URL to ensure
686+
* correct home/siteurl values during installation.
687+
*
688+
* @param string $url The URL to use for setting server variables.
689+
*/
690+
private function set_server_url_vars( $url ) {
691+
$url_parts = Utils\parse_url( $url );
692+
$path = isset( $url_parts['path'] ) ? $url_parts['path'] : '/';
693+
694+
// Ensure path represents a PHP script for proper WordPress URL detection.
695+
$path = rtrim( $path, '/' );
696+
if ( empty( $path ) ) {
697+
$path = '/index.php';
698+
} elseif ( '' === pathinfo( $path, PATHINFO_EXTENSION ) ) {
699+
$path .= '/index.php';
700+
}
701+
702+
$_SERVER['PHP_SELF'] = $path;
703+
$_SERVER['SCRIPT_NAME'] = $path;
704+
705+
// Set SCRIPT_FILENAME to the actual WordPress index.php if available.
706+
if ( file_exists( Utils\trailingslashit( ABSPATH ) . 'index.php' ) ) {
707+
$_SERVER['SCRIPT_FILENAME'] = Utils\trailingslashit( ABSPATH ) . 'index.php';
708+
}
709+
}
710+
667711
private function do_install( $assoc_args ) {
668712
/**
669713
* @var \wpdb $wpdb
@@ -673,6 +717,13 @@ private function do_install( $assoc_args ) {
673717
return false;
674718
}
675719

720+
// Fix $_SERVER variables early to prevent incorrect URL detection.
721+
// This must be done before loading any WordPress files. See set_server_url_vars().
722+
if ( isset( $assoc_args['url'] ) ) {
723+
WP_CLI::set_url( $assoc_args['url'] );
724+
$this->set_server_url_vars( $assoc_args['url'] );
725+
}
726+
676727
if ( true === Utils\get_flag_value( $assoc_args, 'skip-email' ) ) {
677728
if ( ! function_exists( 'wp_new_blog_notification' ) ) {
678729
// @phpstan-ignore function.inner
@@ -697,12 +748,6 @@ function wp_new_blog_notification() {
697748

698749
$args = wp_parse_args( $assoc_args, $defaults );
699750

700-
// Support prompting for the `--url=<url>`,
701-
// which is normally a runtime argument
702-
if ( isset( $assoc_args['url'] ) ) {
703-
WP_CLI::set_url( $assoc_args['url'] );
704-
}
705-
706751
$public = true;
707752
$password = wp_slash( $args['admin_password'] );
708753

0 commit comments

Comments
 (0)