[], 'warnings' => [], 'errors' => [], 'steps' => 0 ]; function logStep($message) { global $setup; $setup['steps']++; echo "[$setup[steps]] $message\n"; } function logSuccess($message) { echo " โœ… $message\n"; } function logWarning($message) { global $setup; $setup['warnings'][] = $message; echo " โš ๏ธ $message\n"; } function logError($message) { global $setup; $setup['errors'][] = $message; echo " โŒ $message\n"; } function checkRequirement($name, $check, $required = true) { logStep("Checking $name..."); try { $result = $check(); if ($result['status']) { logSuccess($result['message']); return true; } else { if ($required) { logError($result['message']); return false; } else { logWarning($result['message']); return true; } } } catch (Exception $e) { logError("Exception: " . $e->getMessage()); return false; } } // System Requirements Check echo "๐Ÿ”ง SYSTEM REQUIREMENTS CHECK\n"; echo str_repeat("-", 30) . "\n"; checkRequirement("PHP Version", function() { $version = PHP_VERSION; if (version_compare($version, '8.1.0', '>=')) { return ['status' => true, 'message' => "PHP $version - Excellent!"]; } elseif (version_compare($version, '7.4.0', '>=')) { return ['status' => true, 'message' => "PHP $version - Compatible but consider upgrading"]; } else { return ['status' => false, 'message' => "PHP $version - Must be 8.1+ for optimal security"]; } }); checkRequirement("PDO Extension", function() { if (extension_loaded('pdo')) { return ['status' => true, 'message' => "PDO extension loaded"]; } return ['status' => false, 'message' => "PDO extension required for database operations"]; }); checkRequirement("SQLite PDO Driver", function() { if (extension_loaded('pdo_sqlite')) { return ['status' => true, 'message' => "SQLite PDO driver loaded"]; } return ['status' => false, 'message' => "SQLite PDO driver required for database"]; }); checkRequirement("MBString Extension", function() { if (extension_loaded('mbstring')) { return ['status' => true, 'message' => "MBString extension loaded"]; } return ['status' => false, 'message' => "MBString extension recommended for UTF-8 support"]; }); checkRequirement("JSON Extension", function() { if (extension_loaded('json')) { return ['status' => true, 'message' => "JSON extension loaded"]; } return ['status' => false, 'message' => "JSON extension required"]; }); checkRequirement("File Permissions", function() { $tests = [ '.' => 'read', 'logs/' => 'write', 'data/' => 'write', 'migrations/' => 'read' ]; foreach ($tests as $path => $permission) { if ($permission === 'read' && !is_readable($path)) { return ['status' => false, 'message' => "$path is not readable"]; } if ($permission === 'write' && !is_writable($path)) { if (!is_dir($path)) { mkdir($path, 0755, true); if (!is_writable($path)) { return ['status' => false, 'message' => "$path is not writable (could not create)"]; } } else { return ['status' => false, 'message' => "$path is not writable"]; } } } return ['status' => true, 'message' => "All required files/directories have proper permissions"]; }); checkRequirement("Composer Dependencies", function() { if (file_exists('vendor/autoload.php')) { return ['status' => true, 'message' => "Composer dependencies installed"]; } return ['status' => false, 'message' => "Run 'composer install' to install dependencies"]; }, false); // Configuration File Check echo "\n๐Ÿ“ CONFIGURATION CHECK\n"; echo str_repeat("-", 30) . "\n"; checkRequirement("Environment Configuration", function() { if (file_exists('.env')) { return ['status' => true, 'message' => ".env file exists"]; } return ['status' => false, 'message' => ".env file missing - copy .env.example"]; }, false); // Database Setup echo "\n๐Ÿ—„๏ธ DATABASE SETUP\n"; echo str_repeat("-", 30) . "\n"; // Include autoloader to load all classes if (file_exists('includes/autoloader.php')) { require_once 'includes/autoloader.php'; } checkRequirement(" Database Initialization", function() { try { // Test database connection - Database class should now be auto-loaded $db = Database::getInstance(); // Check if tables exist $tables = ['users', 'chat_messages', 'active_viewers']; $stmt = $db->query("SELECT name FROM sqlite_master WHERE type='table'"); $existingTables = $stmt->fetchAll(PDO::FETCH_COLUMN); $missingTables = array_diff($tables, $existingTables); if (empty($missingTables)) { return ['status' => true, 'message' => "All database tables exist"]; } else { return ['status' => false, 'message' => "Missing tables: " . implode(', ', $missingTables) . " - run database migrations"]; } } catch (Exception $e) { return ['status' => false, 'message' => "Database connection failed: " . $e->getMessage() . " - check Database.php configuration"]; } }, false); // Test Core Classes echo "\n๐Ÿงช CORE CLASSES TEST\n"; echo str_repeat("-", 30) . "\n"; $classes = [ 'Config' => 'includes/Config.php', 'Security' => 'utils/Security.php', 'Validation' => 'utils/Validation.php', 'Database' => 'includes/Database.php', 'UserModel' => 'models/UserModel.php', 'ChatMessageModel' => 'models/ChatMessageModel.php', 'ActiveViewerModel' => 'models/ActiveViewerModel.php', 'ErrorHandler' => 'includes/ErrorHandler.php', 'ChatServer' => 'services/ChatServer.php' ]; foreach ($classes as $className => $file) { checkRequirement("$className Class", function() use ($className, $file) { if (!file_exists($file)) { return ['status' => false, 'message' => "$file not found"]; } try { require_once $file; if (class_exists($className)) { return ['status' => true, 'message' => "Class loaded successfully"]; } else { return ['status' => false, 'message' => "Class $className not found in $file"]; } } catch (Exception $e) { return ['status' => false, 'message' => "Failed to load class: " . $e->getMessage()]; } }); } // Functional Tests echo "\nโš™๏ธ FUNCTIONAL TESTS\n"; echo str_repeat("-", 30) . "\n"; checkRequirement("Security Functions", function() { if (!class_exists('Security')) return ['status' => false, 'message' => "Security class not loaded"]; try { // Test token generation $token = Security::generateSecureToken(16); if (strlen($token) !== 32) { return ['status' => false, 'message' => "Token generation failed (wrong length)"]; } // Test user ID generation $userId = Security::generateSecureUserId(); if (strlen($userId) !== 32) { return ['status' => false, 'message' => "User ID generation failed"]; } // Test validation $validation = Validation::validateUserId($userId); if (!$validation['valid']) { return ['status' => false, 'message' => "User ID validation failed"]; } return ['status' => true, 'message' => "Security and validation functions working"]; } catch (Exception $e) { return ['status' => false, 'message' => "Error testing functions: " . $e->getMessage()]; } }); checkRequirement("Admin Password Generation", function() { // Check if generate_hash.php exists and is executable if (!file_exists('generate_hash.php')) { return ['status' => false, 'message' => "generate_hash.php script missing"]; } // Test basic admin functionality if (!class_exists('Security')) return ['status' => false, 'message' => "Cannot test admin functions"]; try { // Test admin authentication check (should fail without setup) $auth = Security::isAdminAuthenticated(); // This might be false (expected for new setup) return ['status' => true, 'message' => "Admin authentication system loaded (not yet configured)"]; } catch (Exception $e) { return ['status' => false, 'message' => "Error testing admin functions: " . $e->getMessage()]; } }, false); // Configuration Generation echo "\n๐Ÿ”ง CONFIGURATION ASSISTANT\n"; echo str_repeat("-", 30) . "\n"; if (!file_exists('.env')) { echo "Creating .env configuration file...\n"; $envTemplate = <<<'EOT' # Dodgers IPTV Environment Configuration # Generated by setup.php # Environment Settings APP_ENV=development SECRET_KEY=%SECRET_KEY% # Database Configuration DB_DATABASE=data/app.db # Admin Credentials (configure these!) ADMIN_USERNAME=admin ADMIN_PASSWORD_HASH=%ADMIN_HASH% # Stream Configuration STREAM_BASE_URL=http://127.0.0.1:8080 STREAM_ALLOWED_IPS=127.0.0.1,localhost # Security Settings RATE_LIMIT_REQUESTS=100 RATE_LIMIT_WINDOW=60 SESSION_TIMEOUT=3600 # Logging LOG_LEVEL=DEBUG LOG_FILE=logs/app.log # Cache Settings CACHE_ENABLED=true CACHE_TTL=3600 EOT; // Generate secure defaults $secretKey = bin2hex(random_bytes(32)); $adminHash = password_hash('changeme', PASSWORD_ARGON2I); $envContent = str_replace( ['%SECRET_KEY%', '%ADMIN_HASH%'], [$secretKey, $adminHash], $envTemplate ); $result = file_put_contents('.env', $envContent); if ($result !== false) { logSuccess("Created .env file with secure defaults"); logWarning("IMPORTANT: Change the default admin password!"); echo "\n Run: php generate_hash.php\n"; echo " Then copy the hash to ADMIN_PASSWORD_HASH in .env\n\n"; } else { logError("Failed to create .env file"); } } else { logSuccess(".env file already exists"); } // Final Summary echo "\n๐ŸŽฏ SETUP SUMMARY\n"; echo str_repeat("=", 50) . "\n"; echo "\nโœ… Completed Checks: " . count(array_filter($setup['checks'])) . "\n"; echo "โš ๏ธ Warnings: " . count($setup['warnings']) . "\n"; echo "โŒ Errors: " . count($setup['errors']) . "\n\n"; if (!empty($setup['warnings'])) { echo "WARNINGS:\n"; foreach ($setup['warnings'] as $warning) { echo " โ€ข $warning\n"; } echo "\n"; } if (!empty($setup['errors'])) { echo "CRITICAL ERRORS (must fix):\n"; foreach ($setup['errors'] as $error) { echo " โ€ข $error\n"; } echo "\n"; echo "๐Ÿšจ SETUP INCOMPLETE - Please resolve the errors above\n\n"; exit(1); } // Success Message echo "๐ŸŽ‰ SETUP COMPLETE! Your Dodgers IPTV system is ready!\n\n"; echo "Next Steps:\n"; echo " 1. Configure admin credentials: php generate_hash.php\n"; echo " 2. Set up your web server (see DEPLOYMENT.md)\n"; echo " 3. Access your application and test the features\n"; echo " 4. Run tests: make test\n"; echo " 5. Deploy to production (see DEPLOYMENT.md)\n\n"; echo "๐Ÿš€ Happy Streaming!\n"; echo str_repeat("=", 50) . "\n\n"; ?>