From 05ae8f03d26d2d31fc69a7ab9dc9fe65b89b4439 Mon Sep 17 00:00:00 2001 From: rajch_ales Date: Wed, 5 Aug 2026 22:31:06 +0200 Subject: [PATCH] Enable Adminer MariaDB PHP extensions --- scripts/start-adminer.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/scripts/start-adminer.ts b/scripts/start-adminer.ts index 743b32a..23a58c0 100644 --- a/scripts/start-adminer.ts +++ b/scripts/start-adminer.ts @@ -1,4 +1,4 @@ -import { createWriteStream, existsSync, mkdirSync } from "node:fs"; +import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { get } from "node:https"; import { dirname, resolve } from "node:path"; import { spawn, spawnSync } from "node:child_process"; @@ -9,12 +9,17 @@ const host = process.env.ADMINER_HOST || "127.0.0.1"; const port = process.env.ADMINER_PORT || "8080"; const adminerDownloadUrl = process.env.ADMINER_DOWNLOAD_URL || "https://www.adminer.org/latest.php"; const phpCommand = existsSync(localPhp) ? localPhp : "php"; +const usesLocalPhp = existsSync(localPhp); if (!commandExists(phpCommand)) { console.error("Adminer needs PHP CLI. Install PHP first, then run npm run adminer again."); process.exit(1); } +if (usesLocalPhp) { + ensureLocalPhpMysqlExtensions(); +} + if (!existsSync(adminerFile)) { mkdirSync(dirname(adminerFile), { recursive: true }); await downloadFile(adminerDownloadUrl, adminerFile); @@ -39,6 +44,29 @@ function commandExists(command: string): boolean { return result.status === 0; } +function ensureLocalPhpMysqlExtensions(): void { + const phpDir = dirname(localPhp); + const phpIni = resolve(phpDir, "php.ini"); + const template = resolve(phpDir, "php.ini-production"); + const source = existsSync(phpIni) ? phpIni : template; + + if (!existsSync(source)) { + console.warn("Local PHP is missing php.ini-production; Adminer may not have MariaDB extensions enabled."); + return; + } + + let contents = readFileSync(source, "utf8"); + contents = ensureIniLine(contents, /^;?\s*extension_dir\s*=.*$/m, 'extension_dir = "ext"'); + contents = ensureIniLine(contents, /^;?\s*extension\s*=\s*mysqli\s*$/m, "extension=mysqli"); + contents = ensureIniLine(contents, /^;?\s*extension\s*=\s*pdo_mysql\s*$/m, "extension=pdo_mysql"); + writeFileSync(phpIni, contents); +} + +function ensureIniLine(contents: string, pattern: RegExp, line: string): string { + if (pattern.test(contents)) return contents.replace(pattern, line); + return `${contents.trimEnd()}\n${line}\n`; +} + function downloadFile(url: string, target: string): Promise { return new Promise((resolveDownload, rejectDownload) => { const request = get(url, (response) => {