diff --git a/src/Database/Eloquent.php b/src/Database/Eloquent.php index 338f673..2158b7f 100644 --- a/src/Database/Eloquent.php +++ b/src/Database/Eloquent.php @@ -15,16 +15,7 @@ public static function init() if (class_exists($eloquent)) { $capsule = new $eloquent(); - $capsule->addConnection([ - 'driver' => 'mysql', - 'host' => DB_HOST, - 'database' => DB_NAME, - 'username' => DB_USER, - 'password' => DB_PASSWORD, - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - ]); + $capsule->addConnection(self::connection()); // Set the event dispatcher used by Eloquent models... (optional) // use Illuminate\Events\Dispatcher; @@ -38,4 +29,35 @@ public static function init() $capsule->bootEloquent(); } } + + /** + * The connection to WordPress's own database: MySQL, unless WordPress runs on SQLite. + * + * That is WordPress Playground, WordPress Studio, or any site with the SQLite Database + * Integration plugin, which defines DB_ENGINE and FQDB. Its tables are plain SQLite tables + * under their MySQL names, in the file FQDB points at, so Eloquent can query them directly. + * + * @return array + */ + public static function connection(): array + { + if (defined('DB_ENGINE') && DB_ENGINE === 'sqlite' && defined('FQDB')) { + return [ + 'driver' => 'sqlite', + 'database' => FQDB, + 'prefix' => '', + ]; + } + + return [ + 'driver' => 'mysql', + 'host' => DB_HOST, + 'database' => DB_NAME, + 'username' => DB_USER, + 'password' => DB_PASSWORD, + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ]; + } } diff --git a/tests/Unit/EloquentTest.php b/tests/Unit/EloquentTest.php new file mode 100644 index 0000000..a7a1f84 --- /dev/null +++ b/tests/Unit/EloquentTest.php @@ -0,0 +1,90 @@ + 'mysql', + 'host' => 'db.example', + 'database' => 'wordpress', + 'username' => 'wp', + 'password' => 'secret', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ]; + + private function defineMysqlConstants(): void + { + define('DB_HOST', 'db.example'); + define('DB_NAME', 'wordpress'); + define('DB_USER', 'wp'); + define('DB_PASSWORD', 'secret'); + } + + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] + public function test_mysql_is_the_default_and_unchanged(): void + { + $this->defineMysqlConstants(); + + $this->assertSame(self::MYSQL, Eloquent::connection()); + } + + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] + public function test_db_engine_mysql_keeps_mysql(): void + { + // What the SQLite Database Integration plugin defines when its drop-in is not loaded. + define('DB_ENGINE', 'mysql'); + define('FQDB', '/site/wp-content/database/.ht.sqlite'); + $this->defineMysqlConstants(); + + $this->assertSame(self::MYSQL, Eloquent::connection()); + } + + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] + public function test_sqlite_uses_the_file_wordpress_uses(): void + { + // WordPress Playground, measured on 2026-09-25 (SQLite Database Integration 3.0.2). + define('DB_ENGINE', 'sqlite'); + define('FQDB', '/wordpress/wp-content/database/.ht.sqlite'); + // Playground's wp-config still carries the sample MySQL values: they must not be used. + define('DB_HOST', 'localhost'); + define('DB_NAME', 'database_name_here'); + define('DB_USER', 'username_here'); + define('DB_PASSWORD', 'password_here'); + + $this->assertSame( + [ + 'driver' => 'sqlite', + 'database' => '/wordpress/wp-content/database/.ht.sqlite', + 'prefix' => '', + ], + Eloquent::connection() + ); + } + + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] + public function test_sqlite_without_a_database_file_falls_back_to_mysql(): void + { + define('DB_ENGINE', 'sqlite'); + $this->defineMysqlConstants(); + + $this->assertSame(self::MYSQL, Eloquent::connection()); + } +}