diff --git a/features/core.feature b/features/core.feature index e5740b93..653e377c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -23,6 +23,7 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 + And STDERR should match /WordPress is not installed[\s\S]*Missing tables:.*\b[^\s_]+_/ When I try `wp core is-installed --network` Then the return code should be 1 diff --git a/src/Core_Command.php b/src/Core_Command.php index 3dd85bf6..d5b28c0b 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -2,7 +2,7 @@ use Composer\Semver\Comparator; use WP_CLI\Extractor; -use WP_CLI\Iterators\Table as TableIterator; +use WP_CLI\Iterators\Table; use WP_CLI\Utils; use WP_CLI\Formatter; use WP_CLI\WpOrgApi; @@ -393,11 +393,89 @@ function () use ( $temp ) { * @param array{network?: bool} $assoc_args Associative arguments. */ public function is_installed( $args, $assoc_args ) { - if ( is_blog_installed() && ( ! Utils\get_flag_value( $assoc_args, 'network' ) || is_multisite() ) ) { + try { + if ( ! is_blog_installed() ) { + WP_CLI::halt( 1 ); + } + + if ( Utils\get_flag_value( $assoc_args, 'network' ) && ! is_multisite() ) { + WP_CLI::halt( 1 ); + } + + global $wpdb; + + // Get all tables including multisite if needed + $tables = $wpdb->tables( 'all', true ); + $missing_tables = []; + + // Check if we're using SQLite - check multiple possible indicators + $is_sqlite = ( + ( isset( $wpdb->dbdriver ) && 'sqlite' === $wpdb->dbdriver ) || + ( defined( 'DB_DRIVER' ) && 'sqlite' === DB_DRIVER ) || + ( defined( 'DB_ENGINE' ) && 'sqlite' === DB_ENGINE ) || + ( is_string( DB_HOST ) && ( strpos( DB_HOST, 'sqlite' ) !== false ) ) + ); + + if ( defined( 'WP_CLI_TEST' ) && WP_CLI_TEST ) { + WP_CLI::debug( 'Database type: ' . ( $is_sqlite ? 'SQLite' : 'MySQL/MariaDB' ) ); + } + + foreach ( $tables as $table ) { + $table_name = $wpdb->prefix . $table; + + try { + try { + if ( $is_sqlite ) { + // SQLite uses a simpler table existence check + $result = $wpdb->get_var( + $wpdb->prepare( + "SELECT name FROM sqlite_master WHERE type='table' AND name=%s", + $table_name + ) + ); + } else { + // Standard MySQL/MariaDB check + $result = $wpdb->get_var( + $wpdb->prepare( + 'SHOW TABLES LIKE %s', + $table_name + ) + ); + } + } catch ( Exception $e ) { + // If there's an error, assume the table doesn't exist + $result = null; + } + + if ( defined( 'WP_CLI_TEST' ) && WP_CLI_TEST ) { + WP_CLI::debug( sprintf( 'Table %s: %s', $table_name, $result ? 'exists' : 'missing' ) ); + } + + if ( $result !== $table_name ) { + $missing_tables[] = $table_name; + } + } catch ( Exception $e ) { + WP_CLI::debug( sprintf( 'Error checking table %s: %s', $table_name, $e->getMessage() ) ); + $missing_tables[] = $table_name; + } + } + + if ( ! empty( $missing_tables ) ) { + WP_CLI::error( + sprintf( + 'WordPress is not installed. Missing tables: %s', + implode( ', ', $missing_tables ) + ), + 1 + ); + } + WP_CLI::halt( 0 ); - } - WP_CLI::halt( 1 ); + } catch ( Exception $e ) { + WP_CLI::debug( 'Error in is_installed: ' . $e->getMessage() ); + WP_CLI::halt( 1 ); + } } /** diff --git a/wp-cli.phar b/wp-cli.phar new file mode 100644 index 00000000..4432e71d Binary files /dev/null and b/wp-cli.phar differ