loadDatabaseConnection(); $this->config = []; } private function loadDatabaseConnection() { try { $db_host = getenv('DB_HOST') ?: 'db'; $db_name = getenv('DB_NAME') ?: 'easystream'; $db_user = getenv('DB_USER') ?: 'easystream'; $db_pass = getenv('DB_PASS') ?: 'easystream'; $this->pdo = new PDO( "mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ] ); } catch (PDOException $e) { error_log("Setup Wizard DB Connection Error: " . $e->getMessage()); throw new Exception("Database connection failed. Please check your configuration."); } } public function testDatabaseConnection($data) { try { // Test if tables exist $stmt = $this->pdo->query("SHOW TABLES"); $tables = $stmt->fetchAll(PDO::FETCH_COLUMN); $tableCount = count($tables); // Check if db_settings table exists $hasSettings = in_array('db_settings', $tables); return [ 'success' => true, 'message' => "Database connected successfully", 'tableCount' => $tableCount, 'hasSettings' => $hasSettings ]; } catch (Exception $e) { return [ 'success' => false, 'error' => $e->getMessage() ]; } } public function saveConfiguration($data) { try { // Validate required fields $required = ['platformName', 'domainName', 'contactEmail']; foreach ($required as $field) { if (empty($data[$field])) { throw new Exception("Missing required field: $field"); } } // Save configuration to database $settings = [ 'site_name' => $data['platformName'], 'site_tagline' => $data['platformTagline'] ?? '', 'site_url' => $data['domainName'], 'site_email' => $data['contactEmail'], 'site_timezone' => $data['timezone'] ?? 'UTC', // Branding 'theme_primary_color' => $data['primaryColor'] ?? '#667eea', 'theme_secondary_color' => $data['secondaryColor'] ?? '#764ba2', 'theme_default' => $data['defaultTheme'] ?? 'light', 'theme_allow_switching' => !empty($data['enableTheming']) ? '1' : '0', // Membership tiers 'tier_free_name' => $data['tier1Name'] ?? 'Free', 'tier_free_upload_limit' => $data['tier1Upload'] ?? 100, 'tier_free_storage_limit' => $data['tier1Storage'] ?? 5, 'tier_premium_name' => $data['tier2Name'] ?? 'Premium', 'tier_premium_upload_limit' => $data['tier2Upload'] ?? 500, 'tier_premium_storage_limit' => $data['tier2Storage'] ?? 50, 'tier_premium_price' => $data['tier2Price'] ?? 9.99, 'tier_enterprise_name' => $data['tier3Name'] ?? 'Enterprise', 'tier_enterprise_upload_limit' => $data['tier3Upload'] ?? 2048, 'tier_enterprise_storage_limit' => $data['tier3Storage'] ?? 500, 'tier_enterprise_price' => $data['tier3Price'] ?? 49.99, // Features 'feature_registration' => !empty($data['enableRegistration']) ? '1' : '0', 'feature_email_verification' => !empty($data['enableEmailVerification']) ? '1' : '0', 'feature_live_streaming' => !empty($data['enableLiveStreaming']) ? '1' : '0', 'feature_comments' => !empty($data['enableComments']) ? '1' : '0', 'feature_downloads' => !empty($data['enableDownloads']) ? '1' : '0', 'feature_monetization' => !empty($data['enableMonetization']) ? '1' : '0', 'feature_template_builder' => !empty($data['enableTemplateBuilder']) ? '1' : '0', 'feature_analytics' => !empty($data['enableAnalytics']) ? '1' : '0', // Meta 'setup_completed' => '1', 'setup_date' => date('Y-m-d H:i:s'), 'setup_version' => '2.0' ]; // Check if db_settings table exists $stmt = $this->pdo->query("SHOW TABLES LIKE 'db_settings'"); if ($stmt->rowCount() === 0) { // Table doesn't exist yet, create it $this->createSettingsTable(); } // Insert or update settings foreach ($settings as $key => $value) { $stmt = $this->pdo->prepare(" INSERT INTO db_settings (cfg_name, cfg_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE cfg_value = VALUES(cfg_value) "); $stmt->execute([$key, $value]); } // Also write to config file for quick access $this->writeConfigFile($settings); return [ 'success' => true, 'message' => 'Configuration saved successfully' ]; } catch (Exception $e) { error_log("Setup Wizard Save Config Error: " . $e->getMessage()); return [ 'success' => false, 'error' => $e->getMessage() ]; } } public function createAdminUser($data) { try { // Validate required fields if (empty($data['adminUsername']) || empty($data['adminEmail']) || empty($data['adminPassword'])) { throw new Exception("All admin fields are required"); } // Validate password match if ($data['adminPassword'] !== $data['adminPasswordConfirm']) { throw new Exception("Passwords do not match"); } // Validate password strength if (strlen($data['adminPassword']) < 8) { throw new Exception("Password must be at least 8 characters long"); } // Hash password $passwordHash = password_hash($data['adminPassword'], PASSWORD_BCRYPT); // Check if db_accountuser table exists $stmt = $this->pdo->query("SHOW TABLES LIKE 'db_accountuser'"); if ($stmt->rowCount() === 0) { throw new Exception("User table not found. Database may not be properly initialized."); } // Check if admin already exists $stmt = $this->pdo->prepare("SELECT usr_id FROM db_accountuser WHERE usr_user = :username OR usr_email = :email"); $stmt->execute([ 'username' => $data['adminUsername'], 'email' => $data['adminEmail'] ]); if ($stmt->rowCount() > 0) { // Update existing admin $stmt = $this->pdo->prepare(" UPDATE db_accountuser SET usr_password = :password, usr_email = :email, usr_dname = :displayname, usr_role = 'admin', usr_status = 1, usr_verified = 1 WHERE usr_user = :username OR usr_email = :email "); } else { // Insert new admin - use SET sql_mode to allow more flexible inserts $this->pdo->exec("SET sql_mode=''"); $stmt = $this->pdo->prepare(" INSERT INTO db_accountuser ( usr_key, usr_user, usr_password, usr_email, usr_dname, usr_role, usr_status, usr_verified, usr_IP, usr_logins, usr_lastlogin, usr_joindate, live_key ) VALUES ( 1, :username, :password, :email, :displayname, 'admin', 1, 1, '127.0.0.1', 0, NOW(), NOW(), '' ) "); } $stmt->execute([ 'username' => $data['adminUsername'], 'password' => $passwordHash, 'email' => $data['adminEmail'], 'displayname' => $data['adminDisplayName'] ?? 'Administrator' ]); return [ 'success' => true, 'message' => 'Admin user created successfully' ]; } catch (Exception $e) { error_log("Setup Wizard Create Admin Error: " . $e->getMessage()); return [ 'success' => false, 'error' => $e->getMessage() ]; } } public function finalizeSetup($data) { try { // Create .setup_complete file to prevent re-running setup file_put_contents('.setup_complete', json_encode([ 'completed_at' => date('Y-m-d H:i:s'), 'platform_name' => $data['platformName'] ?? 'EasyStream', 'domain' => $data['domainName'] ?? 'localhost', 'version' => '2.0' ])); // Update Caddyfile with domain if (!empty($data['domainName']) && $data['domainName'] !== 'localhost') { $this->updateCaddyfile($data['domainName']); } // Clear any cached config if (function_exists('opcache_reset')) { opcache_reset(); } return [ 'success' => true, 'message' => 'Setup completed successfully', 'redirect' => '/' ]; } catch (Exception $e) { error_log("Setup Wizard Finalize Error: " . $e->getMessage()); return [ 'success' => false, 'error' => $e->getMessage() ]; } } private function createSettingsTable() { $sql = "CREATE TABLE IF NOT EXISTS `db_settings` ( `cfg_name` VARCHAR(100) NOT NULL PRIMARY KEY, `cfg_value` TEXT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $this->pdo->exec($sql); } private function writeConfigFile($settings) { $configContent = " $value) { $safeValue = addslashes($value); $constantName = 'SETUP_' . strtoupper($key); $configContent .= "define('$constantName', '$safeValue');\n"; } // Write to f_core/config.setup.php $configFile = __DIR__ . '/f_core/config.setup.php'; @file_put_contents($configFile, $configContent); } private function updateCaddyfile($domain) { $caddyfile = __DIR__ . '/Caddyfile'; if (file_exists($caddyfile)) { $content = @file_get_contents($caddyfile); // Replace localhost with actual domain $content = preg_replace('/http:\/\/localhost:\d+/', "https://$domain", $content); $content = preg_replace('/^:80\s*\{/', "$domain {\n encode gzip", $content); @file_put_contents($caddyfile, $content); } } } ?>