isFile() && strtolower($fileInfo->getExtension()) === 'xml') { $availableFiles[] = $fileInfo->getFilename(); } } sort($availableFiles, SORT_NATURAL | SORT_FLAG_CASE); $selectedFile = ''; $fileContents = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $postedFile = $_POST['file'] ?? ''; $postedFile = basename(trim((string)$postedFile)); if ($postedFile === '' || !in_array($postedFile, $availableFiles, true)) { $errors[] = 'Invalid file selected.'; } else { $fullPath = $serverConfigDir . DIRECTORY_SEPARATOR . $postedFile; if (!is_file($fullPath) || !is_readable($fullPath)) { $errors[] = 'Selected file is missing or unreadable.'; } elseif (!is_writable($fullPath)) { $errors[] = 'Selected file is not writable.'; } else { $newContents = $_POST['xml_contents'] ?? ''; $backupDir = $serverConfigDir . DIRECTORY_SEPARATOR . '_backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } $timestamp = date('Ymd-His'); $backupPath = $backupDir . DIRECTORY_SEPARATOR . $postedFile . '.' . $timestamp . '.bak'; $original = file_get_contents($fullPath); if ($original === false) { $errors[] = 'Unable to read original file for backup.'; } elseif (@file_put_contents($backupPath, $original) === false) { $errors[] = 'Failed to create backup copy before saving.'; } elseif (@file_put_contents($fullPath, $newContents) === false) { $errors[] = 'Failed to write new XML contents.'; } else { $messages[] = 'Saved changes to ' . htmlspecialchars($postedFile, ENT_QUOTES, 'UTF-8') . ' (backup: ' . basename($backupPath) . ').'; $selectedFile = $postedFile; $fileContents = $newContents; } } } } if ($selectedFile === '') { $queryFile = $_GET['file'] ?? ''; $queryFile = basename(trim((string)$queryFile)); if ($queryFile !== '' && in_array($queryFile, $availableFiles, true)) { $selectedFile = $queryFile; } } if ($selectedFile !== '' && $fileContents === '') { $fullPath = $serverConfigDir . DIRECTORY_SEPARATOR . $selectedFile; if (is_file($fullPath) && is_readable($fullPath)) { $fileContents = file_get_contents($fullPath); if ($fileContents === false) { $errors[] = 'Unable to read the selected file.'; $fileContents = ''; } } else { $errors[] = 'Selected file is missing or unreadable.'; $selectedFile = ''; } } function billing_render_flash(array $items, string $cssClass): void { if (!$items) { return; } echo '
'; foreach ((array)$items as $item) { echo '
' . $item . '
'; } echo '
'; } ?> Admin — XML Config Editor

XML Config Editor

Editing files in . Each save creates a backup under _backups/.

Server Config XML Files

No XML files found.

Select an XML file from the list to begin editing.

Backup created before each save.