diff --git a/features/config-create.feature b/features/config-create.feature index c93bb604..9f13c192 100644 --- a/features/config-create.feature +++ b/features/config-create.feature @@ -163,6 +163,27 @@ Feature: Create a wp-config file Error: Database connection error """ + @require-mysql + Scenario: Missing --dbname or --dbuser without SQLite integration + Given an empty directory + And WP files + + When I try `wp config create --skip-check --dbuser=someuser` + Then the return code should be 1 + And STDERR should contain: + """ + Error: Parameter errors: + missing --dbname parameter (Set the database name.) + """ + + When I try `wp config create --skip-check --dbname=somedb` + Then the return code should be 1 + And STDERR should contain: + """ + Error: Parameter errors: + missing --dbuser parameter (Set the database user.) + """ + @require-mysql Scenario: Configure with database credentials using socket path Given an empty directory @@ -290,6 +311,23 @@ Feature: Create a wp-config file Then the return code should be 0 And the subdir/wp-config.php file should exist + @require-sqlite + Scenario: Configure without --dbname and --dbuser when SQLite integration is active + Given an empty directory + And WP files + And a wp-content/db.php file: + """ + - * : Set the database name. + * [--dbname=] + * : Set the database name. Required unless the SQLite integration drop-in is detected. * - * --dbuser= - * : Set the database user. + * [--dbuser=] + * : Set the database user. Required unless the SQLite integration drop-in is detected. * * [--dbpass=] * : Set the database user password. @@ -219,6 +219,22 @@ public function create( $_, $assoc_args ) { 'ssl' => false, ]; $assoc_args = array_merge( $defaults, $assoc_args ); + + $is_sqlite = self::is_sqlite_integration_active(); + + if ( ! $is_sqlite ) { + $errors = []; + if ( empty( $assoc_args['dbname'] ) ) { + $errors[] = 'missing --dbname parameter (Set the database name.)'; + } + if ( empty( $assoc_args['dbuser'] ) ) { + $errors[] = 'missing --dbuser parameter (Set the database user.)'; + } + if ( ! empty( $errors ) ) { + WP_CLI::error( 'Parameter errors:' . PHP_EOL . implode( PHP_EOL, $errors ) ); + } + } + if ( empty( $assoc_args['dbprefix'] ) ) { WP_CLI::error( '--dbprefix cannot be empty' ); } @@ -228,7 +244,7 @@ public function create( $_, $assoc_args ) { // Check DB connection. To make command more portable, we are not using MySQL CLI and using // mysqli directly instead, as $wpdb is not accessible in this context. - if ( ! Utils\get_flag_value( $assoc_args, 'skip-check' ) ) { + if ( ! $is_sqlite && ! Utils\get_flag_value( $assoc_args, 'skip-check' ) ) { // phpcs:disable WordPress.DB.RestrictedFunctions $mysql = mysqli_init(); @@ -1480,6 +1496,30 @@ private function print_dotenv( array $value ) { WP_CLI::line( "{$name}={$variable_value}" ); } + /** + * Check if the SQLite integration drop-in is active. + * + * @return bool True if SQLite integration is detected, false otherwise. + */ + private static function is_sqlite_integration_active() { + $wp_content_dir = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR : ABSPATH . 'wp-content'; + $db_dropin_path = $wp_content_dir . '/db.php'; + + if ( ! is_file( $db_dropin_path ) || ! is_readable( $db_dropin_path ) ) { + return false; + } + + $db_dropin_contents = file_get_contents( $db_dropin_path, false, null, 0, 8192 ); + if ( false === $db_dropin_contents ) { + return false; + } + + return 1 === preg_match( + '/\b(?:define\s*\(\s*[\'"]SQLITE_DB_DROPIN_VERSION[\'"]|const\s+SQLITE_DB_DROPIN_VERSION\b)/', + $db_dropin_contents + ); + } + /** * Escape a config value so it can be safely used within single quotes. *