0) {
$can_show_restore = true;
$should_skip_to_user = true;
} else {
// If DB exists but doesn't have user table yet, maybe still allow restore
$all_tables = mysqli_query($mysqli, "SHOW TABLES");
if ($all_tables && mysqli_num_rows($all_tables) > 0) {
$can_show_restore = true;
}
}
}
include_once "../includes/settings_localization_array.php";
$errorLog = ini_get('error_log') ?: "Debian/Ubuntu default is usually /var/log/apache2/error.log";
// Get a list of all available timezones
$timezones = DateTimeZone::listIdentifiers();
if (isset($_POST['add_database'])) {
// Check if database has been set up already. If it has, direct user to edit directly instead.
if (file_exists('../config.php')) {
$_SESSION['alert_message'] = "Database already configured. Any further changes should be made by editing the config.php file.";
header("Location: ?user");
exit;
}
$host = filter_var(trim($_POST['host']), FILTER_SANITIZE_STRING);
$database = filter_var(trim($_POST['database']), FILTER_SANITIZE_STRING);
$username = filter_var(trim($_POST['username']), FILTER_SANITIZE_STRING);
$password = filter_var(trim($_POST['password']), FILTER_SANITIZE_STRING);
$config_base_url = $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']);
$config_base_url = rtrim($config_base_url, '/');
$installation_id = randomString(32);
// Ensure variables meet specific criteria (very basic examples)
if (!preg_match('/^[a-zA-Z0-9.-]+$/', $host)) {
die('Invalid host format.');
}
// Test database connection before writing it to config.php
$conn = mysqli_connect($host, $username, $password, $database);
if (!$conn) {
exit("Database connection failed - please check and try again
" . mysqli_connect_error());
}
$new_config = "\s*$/', $cfg)) {
$cfg = preg_replace('/\?>\s*$/', "\n$line\n?>\n", $cfg, 1);
} else {
if ($cfg !== '' && substr($cfg, -1) !== "\n") $cfg .= "\n";
$cfg .= $line . "\n";
}
}
$dir = dirname($file);
$tmp = tempnam($dir, 'cfg_');
if ($tmp === false) throw new RuntimeException("Failed to create temp file in $dir");
if (file_put_contents($tmp, $cfg, LOCK_EX) === false) {
@unlink($tmp);
throw new RuntimeException("Failed to write temp config");
}
$perms = @fileperms($file);
if ($perms !== false) @chmod($tmp, $perms & 0777);
if (!@rename($tmp, $file)) {
@unlink($tmp);
throw new RuntimeException("Failed to atomically replace config.php");
}
if (function_exists('opcache_invalidate')) {
@opcache_invalidate($file, true);
}
}
}
if (!function_exists('setConfigFlag')) {
function setConfigFlag(string $file, string $key, $value): void {
$cfg = @file_get_contents($file);
if ($cfg === false) throw new RuntimeException("Cannot read $file");
$cfg = str_replace("\r\n", "\n", $cfg);
$pattern = '/^\s*\$' . preg_quote($key, '/') . '\s*=\s*.*?;\s*$/m';
$line = '$' . $key . ' = ' . (is_bool($value) ? ($value ? 'true' : 'false') : var_export($value, true)) . ';';
if (preg_match($pattern, $cfg)) {
$cfg = preg_replace($pattern, $line, $cfg, 1);
} else {
if (preg_match('/\?>\s*$/', $cfg)) {
$cfg = preg_replace('/\?>\s*$/', "\n$line\n?>\n", $cfg, 1);
} else {
if ($cfg !== '' && substr($cfg, -1) !== "\n") $cfg .= "\n";
$cfg .= $line . "\n";
}
}
if (file_put_contents($file, $cfg, LOCK_EX) === false) {
throw new RuntimeException("Failed to update $file");
}
if (function_exists('opcache_invalidate')) {
@opcache_invalidate($file, true);
}
}
}
// ---------- Environment guards ----------
@set_time_limit(0);
if (function_exists('ini_set')) { @ini_set('memory_limit', '1024M'); }
// ---------- 1) Validate uploaded file ----------
if (!isset($_FILES['backup_zip']) || $_FILES['backup_zip']['error'] !== UPLOAD_ERR_OK) {
die("No backup file uploaded or upload failed.");
}
$file = $_FILES['backup_zip'];
if ($file['size'] > 4 * 1024 * 1024 * 1024) {
die("Backup archive is too large.");
}
$fi = new finfo(FILEINFO_MIME_TYPE);
$mime = $fi->file($file['tmp_name']);
if ($mime !== 'application/zip' && $mime !== 'application/x-zip-compressed') {
die("Invalid archive type; only .zip is supported.");
}
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if ($ext !== 'zip') {
die("Only .zip files are allowed.");
}
// ---------- 2) Save outer zip to temp ----------
$timestamp = date('YmdHis');
$tempZip = tempnam(sys_get_temp_dir(), "restore_{$timestamp}_");
if (!move_uploaded_file($file["tmp_name"], $tempZip)) {
die("Failed to save uploaded backup file.");
}
@chmod($tempZip, 0600);
// ---------- 3) Extract OUTER backup zip ----------
$tempDir = sys_get_temp_dir() . "/restore_temp_" . bin2hex(random_bytes(6));
if (!mkdir($tempDir, 0700, true)) {
@unlink($tempZip);
die("Failed to create temp directory.");
}
$zip = new ZipArchive;
if ($zip->open($tempZip) !== TRUE) {
@unlink($tempZip);
deleteDir($tempDir);
die("Failed to open backup zip file.");
}
try {
safeExtractZip($zip, $tempDir); // helper (safe extraction)
} catch (Throwable $e) {
$zip->close();
@unlink($tempZip);
deleteDir($tempDir);
die("Invalid backup archive: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'));
}
$zip->close();
@unlink($tempZip);
$sqlPath = $tempDir . "/db.sql";
$uploadsZip = $tempDir . "/uploads.zip"; // inner uploads zip
$versionTxt = $tempDir . "/version.txt";
if (!is_file($sqlPath) || !is_readable($sqlPath)) {
deleteDir($tempDir);
die("Missing db.sql in the backup archive.");
}
if (!is_file($uploadsZip) || !is_readable($uploadsZip)) {
deleteDir($tempDir);
die("Missing uploads.zip in the backup archive.");
}
// ---------- 4) Optional: version compatibility ----------
if (defined('LATEST_DATABASE_VERSION') && is_file($versionTxt)) {
$txt = @file_get_contents($versionTxt) ?: '';
if (preg_match('/^Database Version:\s*(.+)$/mi', $txt, $m)) {
$backupVersion = trim($m[1]);
$running = LATEST_DATABASE_VERSION;
if (version_compare($backupVersion, $running, '>')) {
deleteDir($tempDir);
die("Backup schema ($backupVersion) is newer than this app ($running). Please upgrade ITFlow first, then retry restore.");
}
}
}
// ---------- 5) Restore SQL ----------
mysqli_query($mysqli, "SET FOREIGN_KEY_CHECKS = 0");
$tables = mysqli_query($mysqli, "SHOW TABLES");
if ($tables) {
while ($row = mysqli_fetch_array($tables)) {
$tbl = $row[0];
mysqli_query($mysqli, "DROP TABLE IF EXISTS `".$mysqli->real_escape_string($tbl)."`");
}
}
mysqli_query($mysqli, "SET FOREIGN_KEY_CHECKS = 1");
try {
importSqlFile($mysqli, $sqlPath); // helper
} catch (Throwable $e) {
deleteDir($tempDir);
die("SQL import failed: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'));
}
// ---------- 6) Restore UPLOADS: DELETE existing, then REPLACE ----------
$appRoot = realpath(__DIR__ . "/..");
if ($appRoot === false) {
deleteDir($tempDir);
die("Failed to resolve app root.");
}
$uploadDir = $appRoot . "/uploads";
// Extract inner uploads.zip to staging (with validation & scan report)
$staging = $appRoot . "/uploads_restoring_" . bin2hex(random_bytes(4));
if (!mkdir($staging, 0700, true)) {
deleteDir($tempDir);
die("Failed to create staging directory.");
}
$uz = new ZipArchive;
if ($uz->open($uploadsZip) !== TRUE) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to open uploads.zip in backup.");
}
$scan = extractUploadsZipWithValidationReport($uz, $staging, [
'max_file_bytes' => 200 * 1024 * 1024,
'blocked_exts' => [
'php','php3','php4','php5','php7','php8','phtml','phar',
'cgi','pl','sh','bash','zsh','exe','dll','bat','cmd','com',
'ps1','vbs','vb','jar','jsp','asp','aspx','so','dylib','bin'
],
]);
$uz->close();
if (!$scan['ok']) {
$lines = ["Unsafe file(s) detected in uploads.zip:"];
foreach ($scan['issues'] as $issue) {
$p = htmlspecialchars($issue['path'], ENT_QUOTES, 'UTF-8');
$r = htmlspecialchars($issue['reason'], ENT_QUOTES, 'UTF-8');
$lines[] = "• {$p} — {$r}";
}
deleteDir($staging);
deleteDir($tempDir);
$_SESSION['alert_message'] = nl2br(implode("\n", $lines));
header("Location: ?restore");
exit;
}
// If inner zip has a single "uploads/" folder, promote its contents
$roots = [];
if ($dh = opendir($staging)) {
while (($e = readdir($dh)) !== false) {
if ($e === '.' || $e === '..') continue;
$roots[] = $e;
}
closedir($dh);
}
sort($roots);
if (count($roots) === 1) {
$candidate = $staging . DIRECTORY_SEPARATOR . $roots[0];
if (is_dir($candidate)) {
$promoted = $staging . "_promoted";
if (!@rename($candidate, $promoted)) {
// fallback to copy
$rit = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($candidate, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
if (!mkdir($promoted, 0700, true)) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create promoted staging directory.");
}
foreach ($rit as $it) {
$rel = substr($it->getPathname(), strlen($candidate) + 1);
$dst = $promoted . DIRECTORY_SEPARATOR . $rel;
if ($it->isDir()) {
if (!is_dir($dst) && !mkdir($dst, 0700, true)) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create $dst");
}
} else {
$pdir = dirname($dst);
if (!is_dir($pdir) && !mkdir($pdir, 0700, true)) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create $pdir");
}
if (!copy($it->getPathname(), $dst)) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to copy $rel into promoted staging");
}
@chmod($dst, 0640);
}
}
}
deleteDir($staging);
$staging = isset($promoted) ? $promoted : $staging;
}
}
// Sanity: staging must contain files
$hasFiles = false;
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($staging, FilesystemIterator::SKIP_DOTS)
);
foreach ($it as $f) { if ($f->isFile()) { $hasFiles = true; break; } }
if (!$hasFiles) {
deleteDir($staging);
deleteDir($tempDir);
die("Uploads restore failed: staging is empty (inner uploads.zip may be malformed or fully blocked).");
}
// --- DELETE existing /uploads first, then REPLACE with staging ---
if (is_dir($uploadDir)) {
deleteDir($uploadDir, $appRoot); // guarded delete (under app root)
}
if (!@rename($staging, $uploadDir)) {
// fallback: copy
if (!mkdir($uploadDir, 0750, true)) {
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create uploads directory for placement.");
}
$rit = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($staging, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($rit as $it) {
$rel = substr($it->getPathname(), strlen($staging) + 1);
$dst = $uploadDir . DIRECTORY_SEPARATOR . $rel;
if ($it->isDir()) {
if (!is_dir($dst) && !mkdir($dst, 0750, true)) {
deleteDir($uploadDir);
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create uploads subdir: $dst");
}
} else {
$pdir = dirname($dst);
if (!is_dir($pdir) && !mkdir($pdir, 0750, true)) {
deleteDir($uploadDir);
deleteDir($staging);
deleteDir($tempDir);
die("Failed to create uploads parent dir: $pdir");
}
if (!copy($it->getPathname(), $dst)) {
deleteDir($uploadDir);
deleteDir($staging);
deleteDir($tempDir);
die("Failed to place file into uploads: $rel");
}
@chmod($dst, 0640);
}
}
deleteDir($staging);
}
// Verify uploads has files
$okFiles = false;
$it2 = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($uploadDir, FilesystemIterator::SKIP_DOTS)
);
foreach ($it2 as $f) { if ($f->isFile()) { $okFiles = true; break; } }
if (!$okFiles) {
deleteDir($uploadDir);
deleteDir($tempDir);
die("Uploads replace failed: resulting directory is empty.");
}
// ---------- 7) Log version info (optional) ----------
if (is_file($versionTxt)) {
$versionInfo = @file_get_contents($versionTxt);
if ($versionInfo !== false) {
logAction("Backup Restore", "Version Info", $versionInfo);
}
}
// ---------- 8) Cleanup temp ----------
deleteDir($tempDir);
// ---------- 9) Finalize setup flag ----------
try {
setConfigFlagAtomic(__DIR__ . "/../config.php", "config_enable_setup", 0);
} catch (Throwable $e) {
try {
setConfigFlag(__DIR__ . "/../config.php", "config_enable_setup", 0);
if (function_exists('opcache_invalidate')) {
@opcache_invalidate(__DIR__ . "/../config.php", true);
}
} catch (\Throwable $e2) {
$_SESSION['alert_message'] =
"Restore completed, but couldn’t finalize setup flag automatically: " .
htmlspecialchars($e2->getMessage(), ENT_QUOTES, 'UTF-8');
header("Location: ../login.php");
exit;
}
}
// ---------- 10) Done ----------
$_SESSION['alert_message'] = "Full backup restored successfully. Uploads directory was replaced.";
header("Location: ../login.php");
exit;
}
if (isset($_POST['add_user'])) {
$user_count = mysqli_num_rows(mysqli_query($mysqli,"SELECT COUNT(*) FROM users"));
if ($user_count < 0) {
$_SESSION['alert_message'] = "Users already exist in the database. Clear them to reconfigure here.";
header("Location: ?company");
exit;
}
$name = sanitizeInput($_POST['name']);
$email = sanitizeInput($_POST['email']);
$password = password_hash(trim($_POST['password']), PASSWORD_DEFAULT);
//Generate master encryption key
$site_encryption_master_key = randomString();
//Generate user specific key
$user_specific_encryption_ciphertext = setupFirstUserSpecificKey(trim($_POST['password']), $site_encryption_master_key);
mysqli_query($mysqli,"INSERT INTO users SET user_name = '$name', user_email = '$email', user_password = '$password', user_specific_encryption_ciphertext = '$user_specific_encryption_ciphertext', user_role_id = 3");
mkdirMissing("../uploads/users/1");
//Check to see if a file is attached
if ($_FILES['file']['tmp_name'] != '') {
// get details of the uploaded file
$file_error = 0;
$file_tmp_path = $_FILES['file']['tmp_name'];
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_type = $_FILES['file']['type'];
$file_extension = strtolower(end(explode('.',$_FILES['file']['name'])));
// sanitize file-name
$new_file_name = md5(time() . $file_name) . '.' . $file_extension;
// check if file has one of the following extensions
$allowed_file_extensions = array('jpg', 'jpeg', 'gif', 'png', 'webp');
if (in_array($file_extension,$allowed_file_extensions) === false) {
$file_error = 1;
}
//Check File Size
if ($file_size > 2097152) {
$file_error = 1;
}
if ($file_error == 0) {
// directory in which the uploaded file will be moved
$upload_file_dir = "../uploads/users/1/";
$dest_path = $upload_file_dir . $new_file_name;
move_uploaded_file($file_tmp_path, $dest_path);
//Set Avatar
mysqli_query($mysqli,"UPDATE users SET user_avatar = '$new_file_name' WHERE user_id = 1");
$_SESSION['alert_message'] = 'File successfully uploaded.';
} else {
$_SESSION['alert_message'] = 'There was an error moving the file to upload directory. Please make sure the upload directory is writable by web server.';
}
}
//Create Settings
mysqli_query($mysqli,"INSERT INTO user_settings SET user_id = 1");
$_SESSION['alert_message'] = "User $name created";
header("Location: ?company");
exit;
}
if (isset($_POST['add_company_settings'])) {
$name = sanitizeInput($_POST['name']);
$country = sanitizeInput($_POST['country']);
$address = sanitizeInput($_POST['address']);
$city = sanitizeInput($_POST['city']);
$state = sanitizeInput($_POST['state']);
$zip = sanitizeInput($_POST['zip']);
$phone = preg_replace("/[^0-9]/", '',$_POST['phone']);
$email = sanitizeInput($_POST['email']);
$website = sanitizeInput($_POST['website']);
$tax_id = sanitizeInput($_POST['tax_id']);
mysqli_query($mysqli,"INSERT INTO companies SET company_name = '$name', company_address = '$address', company_city = '$city', company_state = '$state', company_zip = '$zip', company_country = '$country', company_phone = '$phone', company_email = '$email', company_website = '$website', company_tax_id = '$tax_id'");
//Check to see if a file is attached
if ($_FILES['file']['tmp_name'] != '') {
// get details of the uploaded file
$file_error = 0;
$file_tmp_path = $_FILES['file']['tmp_name'];
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_type = $_FILES['file']['type'];
$file_extension = strtolower(end(explode('.',$_FILES['file']['name'])));
// sanitize file-name
$new_file_name = md5(time() . $file_name) . '.' . $file_extension;
// check if file has one of the following extensions
$allowed_file_extensions = array('jpg', 'jpeg', 'png');
if (in_array($file_extension,$allowed_file_extensions) === false) {
$file_error = 1;
}
//Check File Size
if ($file_size > 2097152) {
$file_error = 1;
}
if ($file_error == 0) {
// directory in which the uploaded file will be moved
$upload_file_dir = "../uploads/settings/";
$dest_path = $upload_file_dir . $new_file_name;
move_uploaded_file($file_tmp_path, $dest_path);
mysqli_query($mysqli,"UPDATE companies SET company_logo = '$new_file_name' WHERE company_id = 1");
$_SESSION['alert_message'] = 'File successfully uploaded.';
} else {
$_SESSION['alert_message'] = 'There was an error moving the file to upload directory. Please make sure the upload directory is writable by web server.';
}
}
$latest_database_version = LATEST_DATABASE_VERSION;
mysqli_query($mysqli,"INSERT INTO settings SET company_id = 1, config_current_database_version = '$latest_database_version', config_invoice_prefix = 'INV-', config_invoice_next_number = 1, config_recurring_invoice_prefix = 'REC-', config_invoice_overdue_reminders = '1,3,7', config_quote_prefix = 'QUO-', config_quote_next_number = 1, config_default_net_terms = 30, config_ticket_next_number = 1, config_ticket_prefix = 'TCK-'");
// Create Categories
// Expense Categories Examples
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Office Supplies', category_type = 'Expense', category_color = 'blue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Travel', category_type = 'Expense', category_color = 'purple'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Advertising', category_type = 'Expense', category_color = 'orange'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Processing Fee', category_type = 'Expense', category_color = 'gray'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Shipping and Postage', category_type = 'Expense', category_color = 'teal'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Software', category_type = 'Expense', category_color = 'lightblue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Bank Fees', category_type = 'Expense', category_color = 'yellow'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Payroll', category_type = 'Expense', category_color = 'green'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Professional Services', category_type = 'Expense', category_color = 'darkblue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Contractor', category_type = 'Expense', category_color = 'brown'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Insurance', category_type = 'Expense', category_color = 'red'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Infrastructure', category_type = 'Expense', category_color = 'darkgreen'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Equipment', category_type = 'Expense', category_color = 'gray'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Education', category_type = 'Expense', category_color = 'lightyellow'");
// Income Categories Examples
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Managed Services', category_type = 'Income', category_color = 'green'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Consulting', category_type = 'Income', category_color = 'blue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Projects', category_type = 'Income', category_color = 'purple'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Hardware Sales', category_type = 'Income', category_color = 'silver'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Software Sales', category_type = 'Income', category_color = 'lightblue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Cloud Services', category_type = 'Income', category_color = 'skyblue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Support', category_type = 'Income', category_color = 'yellow'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Training', category_type = 'Income', category_color = 'lightyellow'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Telecom Services', category_type = 'Income', category_color = 'orange'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Backup', category_type = 'Income', category_color = 'darkblue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Security', category_type = 'Income', category_color = 'red'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Licensing', category_type = 'Income', category_color = 'green'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Monitoring', category_type = 'Income', category_color = 'teal'");
// Referral Examples
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Friend', category_type = 'Referral', category_color = 'blue'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Search', category_type = 'Referral', category_color = 'orange'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Social Media', category_type = 'Referral', category_color = 'green'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Email', category_type = 'Referral', category_color = 'yellow'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Partner', category_type = 'Referral', category_color = 'purple'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Event', category_type = 'Referral', category_color = 'red'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Affiliate', category_type = 'Referral', category_color = 'pink'");
mysqli_query($mysqli,"INSERT INTO categories SET category_name = 'Client', category_type = 'Referral', category_color = 'lightblue'");
// Payment Methods
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = 'Cash'");
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = 'Check'");
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = 'Bank Transfer'");
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = 'Credit Card'");
// Default Calendar
mysqli_query($mysqli,"INSERT INTO calendars SET calendar_name = 'Default', calendar_color = 'blue'");
// Add default ticket statuses
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'New', ticket_status_color = '#dc3545'"); // Default ID for new tickets is 1
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Open', ticket_status_color = '#007bff'"); // 2
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'On Hold', ticket_status_color = '#28a745'"); // 3
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Resolved', ticket_status_color = '#343a40'"); // 4 (was auto-close)
mysqli_query($mysqli, "INSERT INTO ticket_statuses SET ticket_status_name = 'Closed', ticket_status_color = '#343a40'"); // 5
// Add default modules
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_client', module_description = 'General client & contact management'");
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_support', module_description = 'Access to ticketing, assets and documentation'");
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_credential', module_description = 'Access to client credentials - usernames, passwords and 2FA codes'");
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_sales', module_description = 'Access to quotes, invoices and products'");
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_financial', module_description = 'Access to payments, accounts, expenses and budgets'");
mysqli_query($mysqli, "INSERT INTO modules SET module_name = 'module_reporting', module_description = 'Access to all reports'");
// Add default roles
mysqli_query($mysqli, "INSERT INTO user_roles SET role_id = 1, role_name = 'Accountant', role_description = 'Built-in - Limited access to financial-focused modules'");
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 1, module_id = 1, user_role_permission_level = 1"); // Read clients
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 1, module_id = 2, user_role_permission_level = 1"); // Read support
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 1, module_id = 4, user_role_permission_level = 1"); // Read sales
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 1, module_id = 5, user_role_permission_level = 2"); // Modify financial
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 1, module_id = 6, user_role_permission_level = 1"); // Read reports
mysqli_query($mysqli, "INSERT INTO user_roles SET role_id = 2, role_name = 'Technician', role_description = 'Built-in - Limited access to technical-focused modules'");
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 2, module_id = 1, user_role_permission_level = 2"); // Modify clients
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 2, module_id = 2, user_role_permission_level = 2"); // Modify support
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 2, module_id = 3, user_role_permission_level = 2"); // Modify credentials
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = 2, module_id = 4, user_role_permission_level = 2"); // Modify sales
mysqli_query($mysqli, "INSERT INTO user_roles SET role_id = 3, role_name = 'Administrator', role_description = 'Built-in - Full administrative access to all modules (including user management)', role_is_admin = 1");
// Custom Links
mysqli_query($mysqli,"INSERT INTO custom_links SET custom_link_name = 'Docs', custom_link_uri = 'https://docs.itflow.org', custom_link_new_tab = 1, custom_link_icon = 'question-circle'");
$_SESSION['alert_message'] = "Company $name created";
header("Location: ?localization");
}
if (isset($_POST['add_localization_settings'])) {
$locale = sanitizeInput($_POST['locale']);
$currency_code = sanitizeInput($_POST['currency_code']);
$timezone = sanitizeInput($_POST['timezone']);
mysqli_query($mysqli,"UPDATE companies SET company_locale = '$locale', company_currency = '$currency_code' WHERE company_id = 1");
mysqli_query($mysqli,"UPDATE settings SET config_timezone = '$timezone' WHERE company_id = 1");
// Create Default Cash Account
mysqli_query($mysqli,"INSERT INTO accounts SET account_name = 'Cash', account_currency_code = '$currency_code'");
$_SESSION['alert_message'] = "Localization Info saved";
header("Location: ?telemetry");
}
if (isset($_POST['add_telemetry'])) {
if (isset($_POST['share_data']) && $_POST['share_data'] == 1) {
mysqli_query($mysqli,"UPDATE settings SET config_telemetry = 2");
$comments = sanitizeInput($_POST['comments']);
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
$row = mysqli_fetch_array($sql);
$company_name = $row['company_name'];
$website = $row['company_website'];
$city = $row['company_city'];
$state = $row['company_state'];
$country = $row['company_country'];
$currency = $row['company_currency'];
$postdata = http_build_query(
array(
'installation_id' => "$installation_id",
'company_name' => "$company_name",
'website' => "$website",
'city' => "$city",
'state' => "$state",
'country' => "$country",
'currency' => "$currency",
'comments' => "$comments",
'collection_method' => 1
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('https://telemetry.itflow.org', false, $context);
echo $result;
}
//final setup stages
$myfile = fopen("../config.php", "a");
$txt = "\$config_enable_setup = 0;\n\n";
fwrite($myfile, $txt);
fclose($myfile);
header("Location: ../login.php");
exit;
}
?>
| PHP Extensions | ||
|---|---|---|
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
| PHP Configuration | ||
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
| Shell Commands | ||
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
| SSL Checks | ||
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
| Domain Checks | ||
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
| File Permissions | ||
| = htmlspecialchars($check['name']); ?> | = htmlspecialchars($check['value']); ?> | |
config.php file.";
if (@$mysqli) {
echo "Next Step (User Setup) ";
} else {
echo "config.php.You must configure the database before restoring a backup.
Go to Database SetupThis is the start of your journey towards amazing client management
A few tips:
A database must be created before proceeding - click on the button below to get started.
ITFlow is free software: you can redistribute and/or modify it under the terms of the GNU General Public License.
It is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.