diff --git a/includes/settings.php b/includes/settings.php index fe45749..4479b2e 100644 --- a/includes/settings.php +++ b/includes/settings.php @@ -55,10 +55,41 @@ if (!function_exists('get_settings')) { } } +/** + * Compatibility wrapper for getCharitySettings + * @return array + */ +if (!function_exists('getCharitySettings')) { + function getCharitySettings() { + $settings = get_settings(); + // Return only the keys that might be expected by older code + return [ + 'charity_name' => $settings['site_name'], + 'charity_email' => $settings['site_email'], + 'charity_phone' => $settings['site_phone'], + 'charity_address' => $settings['site_address'], + 'charity_logo' => $settings['site_logo'], + 'charity_favicon' => $settings['site_favicon'], + 'site_maintenance' => $settings['site_maintenance'], + 'site_footer' => $settings['site_footer'], + 'allow_registration' => $settings['allow_registration'] + ]; + } +} + // Global settings variable $sys_settings = get_settings(); -// Maintenance Mode Check -if ($sys_settings['site_maintenance'] && !isAdmin() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'logout.php') { - die("
يرجى المحاولة مرة أخرى في وقت لاحق.
"); -} +// Maintenance Mode Check - only if not admin and not on login/logout +// Assuming isAdmin() exists, if not we should be careful +if ($sys_settings['site_maintenance'] && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'logout.php') { + // If isAdmin is not defined, we might need a fallback or just check session + $is_admin = false; + if (isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin') { + $is_admin = true; + } + + if (!$is_admin) { + die("يرجى المحاولة مرة أخرى في وقت لاحق.
"); + } +} \ No newline at end of file diff --git a/install.php b/install.php index dcd8f42..976f985 100644 --- a/install.php +++ b/install.php @@ -1,279 +1,253 @@ = 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='), + 'PDO Extension' => extension_loaded('pdo'), + 'PDO MySQL Extension' => extension_loaded('pdo_mysql'), + 'Config Directory Writable' => is_writable(__DIR__ . '/db/'), + 'Uploads Directory Writable' => is_writable(__DIR__ . '/uploads/') || (mkdir(__DIR__ . '/uploads/', 0777, true) && is_writable(__DIR__ . '/uploads/')), +]; + +$all_requirements_met = !in_array(false, $requirements, true); + +// Current step $step = isset($_GET['step']) ? (int)$_GET['step'] : 1; + +// Handle form submissions $error = ''; $success = ''; -// Path to config file -$config_file = __DIR__ . '/db/config.php'; +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + if ($step === 2) { + // Save database configuration + $host = $_POST['db_host'] ?? '127.0.0.1'; + $name = $_POST['db_name'] ?? 'app_database'; + $user = $_POST['db_user'] ?? 'root'; + $pass = $_POST['db_pass'] ?? ''; -// Helper to update config file -function update_config($host, $name, $user, $pass) { - $content = " PDO::ERRMODE_EXCEPTION, -"; - $content .= " PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, -"; - $content .= " ]);\n"; - $content .= " } catch (PDOException $e) {\n"; - $content .= " die('Database connection failed: ' . $e->getMessage());\n"; - $content .= " }\n"; - $content .= " }\n"; - $content .= " return $pdo; -"; - $content .= "}\n\n"; - - // Include existing helpers if needed, or keep it clean - $content .= "/** - * Generates the next reference number - */\n"; - $content .= "function generateRefNo($type) {\n"; - $content .= " $prefix = 'IN'; -"; - $content .= " if ($type === 'outbound') $prefix = 'OUT'; -"; - $content .= " if ($type === 'internal') $prefix = 'INT'; - -"; - $content .= " $year = date('Y'); -"; - $content .= " $pattern = $prefix . '-' . $year . '-%'; - -"; - $content .= " $stmt = db()->prepare(\"SELECT ref_no FROM mailbox WHERE type = ? AND ref_no LIKE ? ORDER BY id DESC LIMIT 1\"); -"; - $content .= " $stmt->execute([$type, $pattern]); -"; - $content .= " $last_ref = $stmt->fetchColumn(); - -"; - $content .= " $serial = 1; -"; - $content .= " if ($last_ref) {\n"; - $content .= " $parts = explode('-', $last_ref); -"; - $content .= " if (count($parts) === 3) {\n"; - $content .= " $serial = (int)$parts[2] + 1; -"; - $content .= " } -"; - $content .= " } - -"; - $content .= " return $prefix . '-' . $year . '-' . str_pad($serial, 3, '0', STR_PAD_LEFT); -"; - $content .= "} -"; + // Test connection + try { + $pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $pass); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - return file_put_contents(__DIR__ . '/db/config.php', $content); -} + // Generate config file content + $content = "setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n"; + $content .= " $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);\n"; + $content .= " } catch (PDOException $e) {\n"; + $content .= " die('Connection failed: ' . $e->getMessage());\n"; + $content .= " }\n"; + $content .= " }\n"; + $content .= " return $pdo;\n"; + $content .= " }\n"; + $content .= "}\n"; -// Step 2: Database Connection Test & Save -if ($step == 2 && $_SERVER['REQUEST_METHOD'] == 'POST') { - $host = $_POST['db_host'] ?? ''; - $name = $_POST['db_name'] ?? ''; - $user = $_POST['db_user'] ?? ''; - $pass = $_POST['db_pass'] ?? ''; - - try { - $pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $pass); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - - if (update_config($host, $name, $user, $pass)) { - header('Location: install.php?step=3'); - exit; - } else { - $error = "Failed to write to db/config.php. Check permissions."; + if (file_put_contents($config_file, $content)) { + header('Location: install.php?step=3'); + exit; + } else { + $error = "Failed to write configuration file to $config_file. Please check permissions."; + } + } catch (PDOException $e) { + $error = "Connection failed: " . $e->getMessage(); } - } catch (PDOException $e) { - $error = "Connection failed: " . $e->getMessage(); - } -} + } elseif ($step === 3) { + // Run migrations + if (!file_exists($config_file)) { + $error = "Configuration file not found. Please go back to Step 2."; + } else { + try { + require_once $config_file; + if (!function_exists('db')) { + throw new Exception("The 'db()' function is not defined in your config file."); + } + $pdo = db(); + $migrations_dir = __DIR__ . '/db/migrations/'; + $files = glob($migrations_dir . '*.sql'); + sort($files); -// Step 3: Run Migrations -if ($step == 3 && isset($_POST['run_migrations'])) { - try { + $applied = 0; + $errors = []; + + foreach ($files as $file) { + $sql = file_get_contents($file); + if (empty($sql)) continue; + + try { + // PDO::exec might fail if there's an error in the SQL, + // but we want to continue if it's "column already exists" or "table already exists" + $pdo->exec($sql); + $applied++; + } catch (Throwable $e) { + $msg = $e->getMessage(); + // Check if it's a common "already exists" error which we can safely ignore + if (strpos($msg, 'Duplicate column name') !== false || + strpos($msg, 'Duplicate key name') !== false || + strpos($msg, 'already exists') !== false) { + $applied++; + } else { + $errors[] = basename($file) . ": " . $msg; + } + } + } + + if (empty($errors)) { + $success = "Successfully applied $applied migrations."; + header('Location: install.php?step=4'); + exit; + } else { + $error = "Applied $applied migrations, but some errors occurred:Ready to set up the database tables and initial data.
+We will now run the SQL scripts to set up your database tables.
- -The system is ready to use. For security, please delete install.php or rename it.
+ -The application has been installed successfully.
-install.php file from your server.
-