Skip to content

Load SQLite for phpMyAdmin and Adminer using WP configuration - #3420

Merged
JanJakes merged 1 commit into
trunkfrom
sql-admin-driver-load-path
Mar 28, 2026
Merged

JanJakes merged 1 commit into
trunkfrom
sql-admin-driver-load-path

Conversation

@JanJakes

@JanJakes JanJakes commented Mar 20, 2026 •

Copy link
Copy Markdown
Member

Motivation for the change, related issues

The phpMyAdmin and Adminer integration previously hardcoded the SQLite-related paths:

  • /internal/shared/sqlite-database-integration/wp-pdo-mysql-on-sqlite.php
  • /wordpress/wp-content/database/.ht.sqlite

This was not universal for situations when the paths differ from the defaults. This PR implements loading these paths from WordPress configuration.

Implementation details

  • A mu-plugin (0-playground.php) now writes the database configuration (type, path, driver path) to /internal/shared/wp-env.php.
  • The phpMyAdmin and Adminer integration read this file at runtime instead of using hardcoded paths.
  • For the internally preloaded SQLite integration, the SQLITE_MAIN_FILE constant is set to the actual plugin path instead of a dummy '1' value, so the driver path can be derived from it.

Testing Instructions (or ideally a Blueprint)

  • npx nx dev playground-website -> verify that phpMyAdmin and Adminer work.
  • npx nx dev playground-cli server --phpmyadmin -> verify that Adminer works.

@JanJakes
JanJakes force-pushed the sql-admin-driver-load-path branch from f161e71 to cb144fc Compare March 20, 2026 14:25
@JanJakes JanJakes changed the title Load SQLite for phpMyAdmin using WP configuration Load SQLite for phpMyAdmin and Adminer using WP configuration Mar 20, 2026
@JanJakes
JanJakes marked this pull request as ready for review March 20, 2026 14:32
@JanJakes
JanJakes requested review from a team, ashfame and Copilot March 20, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the phpMyAdmin/Adminer SQLite integration to read database/driver paths from WordPress runtime configuration instead of hardcoded defaults, improving compatibility with non-standard setups.

Changes:

  • Write DB engine/path/driver metadata to /internal/shared/wp-env.php from a platform mu-plugin.
  • Update Adminer and phpMyAdmin integrations to load the SQLite driver and DB path via wp-env.php.
  • Set SQLITE_MAIN_FILE to the actual SQLite integration loader path so the driver path can be derived reliably.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
packages/playground/wordpress/src/index.ts Writes wp-env.php and sets SQLITE_MAIN_FILE to a real path for correct driver derivation
packages/playground/website/src/components/site-manager/site-database-panel/adminer-extensions/adminer-mysql-on-sqlite-driver.php Loads driver/DB path from wp-env.php instead of hardcoded SQLite locations
packages/playground/tools/src/phpmyadmin/DbiMysqli.php Loads driver/DB path from wp-env.php instead of hardcoded SQLite locations
packages/playground/personal-wp/src/components/site-manager/site-database-panel/adminer-extensions/adminer-mysql-on-sqlite-driver.php Mirrors the Adminer change to use wp-env.php for driver/DB path

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +16 to +22
global $wp_env;
$wp_env = require '/internal/shared/wp-env.php';
if ($wp_env['db']['type'] === 'sqlite') {
require_once $wp_env['db']['driver_path'];
} else {
die('Error: Unsupported database type: ' . $wp_env['db']['type']);
}

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require '/internal/shared/wp-env.php' will fatal if the file is missing/unreadable, and $wp_env['db']['type'] will raise notices if the expected keys aren’t present. Please add a deterministic guard (e.g., check is_file() / validate array shape) and fail with a controlled error path; apply the same fix to the other Adminer/phpMyAdmin integration file(s) with the same pattern.

Copilot uses AI. Check for mistakes.
if ($wp_env['db']['type'] === 'sqlite') {
require_once $wp_env['db']['driver_path'];
} else {
die('Error: Unsupported database type: ' . $wp_env['db']['type']);

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using die() inside an integration library makes failures hard to handle/format in phpMyAdmin and prevents graceful error handling. Prefer throwing an exception (or returning an error in a way phpMyAdmin can surface) so the caller/UI can render a consistent error message; mirror the same approach in the Adminer extension(s).

Suggested change
die('Error: Unsupported database type: ' . $wp_env['db']['type']);
throw new Exception('Error: Unsupported database type: ' . $wp_env['db']['type']);

Copilot uses AI. Check for mistakes.
Comment on lines +279 to +282
file_put_contents(
'/internal/shared/wp-env.php',
sprintf('<?php return %s;', var_export($wp_env, true))
);

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mu-plugin writes /internal/shared/wp-env.php on every request, which adds repeated I/O and can become a bottleneck under higher request volume. Consider writing only when the file is missing or when the computed content differs from the existing file (read + compare), or write once during bootstrap/setup rather than per-request.

Suggested change
file_put_contents(
'/internal/shared/wp-env.php',
sprintf('<?php return %s;', var_export($wp_env, true))
);
$wp_env_php = sprintf('<?php return %s;', var_export($wp_env, true));
$wp_env_file = '/internal/shared/wp-env.php';
if ( ! file_exists( $wp_env_file ) || file_get_contents( $wp_env_file ) !== $wp_env_php ) {
file_put_contents( $wp_env_file, $wp_env_php );
}

Copilot uses AI. Check for mistakes.
Comment on lines +267 to +271
$db_info = array(
'type' => 'sqlite',
'path' => FQDB,
'driver_path' => dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',
);

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside the DB_ENGINE === 'sqlite' branch, FQDB and SQLITE_MAIN_FILE are used without checking they are defined. If a sqlite-backed setup defines DB_ENGINE but not SQLITE_MAIN_FILE (or FQDB) at this point, this will emit notices and produce an invalid driver_path. Add defined('SQLITE_MAIN_FILE') / defined('FQDB') guards and provide a clear fallback (or fail early with a controlled error message).

Suggested change
$db_info = array(
'type' => 'sqlite',
'path' => FQDB,
'driver_path' => dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',
);
if (defined('FQDB') && defined('SQLITE_MAIN_FILE')) {
$db_info = array(
'type' => 'sqlite',
'path' => FQDB,
'driver_path' => dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',
);
} else {
// Fallback when required sqlite constants are missing.
$db_info = array(
'type' => 'sqlite',
'error' => 'Missing FQDB or SQLITE_MAIN_FILE for sqlite database configuration.',
);
}

Copilot uses AI. Check for mistakes.
@JanJakes
JanJakes requested review from adamziel and wojtekn and removed request for ashfame March 20, 2026 14:33
$db_info = array(
'type' => 'sqlite',
'path' => FQDB,
'driver_path' => dirname(SQLITE_MAIN_FILE) . '/wp-pdo-mysql-on-sqlite.php',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it in Studio, and it fails as it gets the path as /wordpress/wp-content/wp-pdo-mysql-on-sqlite.php.

SQLITE_MAIN_FILE is defined in db.php, which is placed in /wordpress/wp-content/,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wojtekn SQLite only defines it in load.php: https://github.com/WordPress/sqlite-database-integration/blob/7be6b9c6dafef117d28ef03381ba18c6f549158d/load.php#L21

Is Studio using something else? Actually, looking closer, the constant appears to be plugin-specific rather than driver-specific, so it's not a good one to use anyway. These constants will probably need some refactoring as well, but I wonder what we could use in the meantime 🤔

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it may be the db.copy->db.php setup script, which incorrectly sets this constant. I will check it more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wojtekn It might be the wrong constant to use anyway, though. The SQLite driver should probably define its root path even when only the driver is loaded.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, after fixing the db.copy script, it threw an undefined constant error - the 0-playground.php loads before the drop-in init.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wojtekn Ah, right. That should be easy to fix. I just need to hook it to sth like wp-loaded I guess.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not enough - the load.php is not getting loaded for mu-plugins, and this constant is defined in SQLite’s plugin load.php. Should we define a constant specifically for that, in wp-includes/sqlite/db.php that is loaded in db.php drop-in?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wojtekn I repushed this using the new SQLite constant. Please, try again if it works now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I manually applied the changes to the SQLite driver, the phpMyAdmin loader, and the playground/wordpres package in Studio, and it worked fine. The path was correctly set in the SQLite driver, and later was available in phpMyAdmin loader via $wp_env.

@JanJakes
JanJakes force-pushed the sql-admin-driver-load-path branch from cb144fc to 98cd7fa Compare March 23, 2026 12:06
@wojtekn wojtekn mentioned this pull request Mar 24, 2026
1 task done
@JanJakes
JanJakes force-pushed the sql-admin-driver-load-path branch 2 times, most recently from 81c4e52 to c8db9ae Compare March 24, 2026 10:35
phpMyAdmin and Adminer previously hardcoded the SQLite driver path and
database file path. This breaks when the paths differ from the defaults
(e.g. different WordPress document root or SQLite plugin location).

Instead, write the database configuration (type, path, driver path) to
/internal/shared/wp-env.php from a mu-plugin that has access to the WP
constants, and read it from the database tools at runtime.
@JanJakes

Copy link
Copy Markdown
Member Author

I rebased this on the latest trunk. Let's get it in.

@JanJakes
JanJakes merged commit 94459e2 into trunk Mar 28, 2026
77 of 93 checks passed
@JanJakes
JanJakes deleted the sql-admin-driver-load-path branch March 28, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants