diff --git a/composer.json b/composer.json index 6a3fe712..926bb85b 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,8 @@ "core multisite-install", "core update", "core update-db", - "core version" + "core version", + "core version-db-actual" ] }, "autoload": { diff --git a/features/core-version.feature b/features/core-version.feature index b46b47c3..ec983892 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -37,3 +37,73 @@ Feature: Find version for WordPress install TinyMCE version: 4.208 (4208-20151113) Package language: de_DE """ + + # This test downgrades to an older WordPress version, but the SQLite plugin requires 6.0+ + @require-mysql + Scenario: Verify actual database version shows correct values + Given a WP install + And I run `wp core download --version=6.6 --force` + And I run `wp option update db_version 45805` + + # Without --actual, should show expected version from version.php + When I run `wp core version --extra` + Then STDOUT should contain: + """ + Database revision: 47018 + """ + + # With --actual, should show actual database version + When I run `wp core version --extra --actual` + Then STDOUT should contain: + """ + Database revision: 45805 + """ + + # This test downgrades to an older WordPress version, but the SQLite plugin requires 6.0+ + @require-mysql + Scenario: Verify actual database version in multisite subsite + Given a WP multisite install + And I run `wp core download --version=6.6 --force` + And I run `wp option update db_version 47018` + And I run `wp site create --slug=subsite --porcelain` + And save STDOUT as {SUBSITE_ID} + And I run `wp option update db_version 45805 --url=example.com/subsite` + + # Main site shows expected version from version.php without --actual + When I run `wp core version --extra` + Then STDOUT should contain: + """ + Database revision: 47018 + """ + + # Main site shows actual database version with --actual + When I run `wp core version --extra --actual` + Then STDOUT should contain: + """ + Database revision: 47018 + """ + + # Subsite shows expected version from version.php without --actual + When I run `wp core version --extra --url=example.com/subsite` + Then STDOUT should contain: + """ + Database revision: 47018 + """ + + # Subsite shows its own actual database version with --actual + When I run `wp core version --extra --actual --url=example.com/subsite` + Then STDOUT should contain: + """ + Database revision: 45805 + """ + + Scenario: Error when using --actual without --extra + Given a WP install + + When I try `wp core version --actual` + Then STDERR should contain: + """ + Error: The --actual flag can only be used with --extra. + """ + And the return code should be 1 + diff --git a/src/Core_Command.php b/src/Core_Command.php index 18d340f9..89468996 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -903,6 +903,9 @@ private static function get_clean_basedomain() { * [--extra] * : Show extended version information. * + * [--actual] + * : Show the actual database version from the database. This requires WordPress to be loaded and only works with --extra flag. Useful for checking the database version of a specific site in a multisite installation using --url. + * * ## EXAMPLES * * # Display the WordPress version @@ -916,12 +919,51 @@ private static function get_clean_basedomain() { * TinyMCE version: 4.310 (4310-20160418) * Package language: en_US * + * # Display actual database version for a multisite subsite + * $ wp core version --extra --actual --url=example.com/subsite + * WordPress version: 4.5.2 + * Database revision: 35700 + * TinyMCE version: 4.310 (4310-20160418) + * Package language: en_US + * * @when before_wp_load * * @param string[] $args Positional arguments. Unused. - * @param array{extra?: bool} $assoc_args Associative arguments. + * @param array{extra?: bool, actual?: bool} $assoc_args Associative arguments. */ public function version( $args = [], $assoc_args = [] ) { + $use_actual_db_version = Utils\get_flag_value( $assoc_args, 'actual' ); + + // If --actual flag is used, delegate to a command that runs after WP load + if ( $use_actual_db_version ) { + if ( ! Utils\get_flag_value( $assoc_args, 'extra' ) ) { + WP_CLI::error( 'The --actual flag can only be used with --extra.' ); + } + + // Build the command to run after WP load + $cmd_args = []; + foreach ( $assoc_args as $key => $value ) { + if ( 'actual' !== $key ) { + if ( true === $value ) { + $cmd_args[] = '--' . $key; + } elseif ( is_string( $value ) ) { + // Escape the value to prevent command injection + $cmd_args[] = '--' . $key . '=' . escapeshellarg( $value ); + } + } + } + $cmd = 'core version-db-actual ' . implode( ' ', $cmd_args ); + + WP_CLI::runcommand( + $cmd, + [ + 'launch' => true, + 'exit_error' => true, + ] + ); + return; + } + $details = self::get_wp_details(); if ( ! Utils\get_flag_value( $assoc_args, 'extra' ) ) { @@ -929,10 +971,6 @@ public function version( $args = [], $assoc_args = [] ) { return; } - $match = []; - $found_version = preg_match( '/(\d)(\d+)-/', $details['tinymce_version'], $match ); - $human_readable_tiny_mce = $found_version ? "{$match[1]}.{$match[2]}" : ''; - echo Utils\mustache_render( self::get_template_path( 'versions.mustache' ), [ @@ -941,13 +979,59 @@ public function version( $args = [], $assoc_args = [] ) { 'local-package' => empty( $details['wp_local_package'] ) ? 'en_US' : $details['wp_local_package'], - 'mce-version' => $human_readable_tiny_mce - ? "{$human_readable_tiny_mce} ({$details['tinymce_version']})" - : $details['tinymce_version'], + 'mce-version' => self::format_tinymce_version( $details['tinymce_version'] ), + ] + ); + } + + /** + * Helper command to display actual database version (runs after WP load). + * + * This is an internal command called by 'core version --actual'. + * + * @subcommand version-db-actual + * @when after_wp_load + * + * @param string[] $args Positional arguments. Unused. + * @param array{extra?: bool} $assoc_args Associative arguments passed through from version command. + */ + public function version_db_actual( $args = [], $assoc_args = [] ) { + $details = self::get_wp_details(); + + // Get the actual database version from the options table + $actual_db_version = get_option( 'db_version' ); + + echo Utils\mustache_render( + self::get_template_path( 'versions.mustache' ), + [ + 'wp-version' => $details['wp_version'], + 'db-version' => $actual_db_version, + 'local-package' => empty( $details['wp_local_package'] ) + ? 'en_US' + : $details['wp_local_package'], + 'mce-version' => self::format_tinymce_version( $details['tinymce_version'] ), ] ); } + /** + * Formats the TinyMCE version for display. + * + * @param string $tinymce_version The TinyMCE version string. + * @return string Formatted TinyMCE version. + */ + private static function format_tinymce_version( $tinymce_version ) { + $match = []; + $found_version = preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); + $human_readable_tiny_mce = $found_version ? "{$match[1]}.{$match[2]}" : ''; + + if ( $human_readable_tiny_mce ) { + return "{$human_readable_tiny_mce} ({$tinymce_version})"; + } + + return $tinymce_version; + } + /** * Gets version information from `wp-includes/version.php`. *