logger = VLogger::getInstance(); $this->db = VDatabase::getInstance(); } /** * Run complete production setup */ public function setup() { echo "EasyStream Production Setup\n"; echo str_repeat("=", 40) . "\n\n"; $steps = [ 'checkRequirements' => 'Checking system requirements', 'createDirectories' => 'Creating required directories', 'setupDatabase' => 'Setting up database tables', 'configurePermissions' => 'Configuring file permissions', 'setupCronJobs' => 'Setting up cron jobs', 'testComponents' => 'Testing core components', 'generateConfig' => 'Generating production config' ]; $totalSteps = count($steps); $currentStep = 0; foreach ($steps as $method => $description) { $currentStep++; echo "[{$currentStep}/{$totalSteps}] {$description}...\n"; try { $result = $this->$method(); if ($result['success']) { echo " ✓ " . $result['message'] . "\n"; } else { echo " ✗ " . $result['message'] . "\n"; if (isset($result['details'])) { foreach ($result['details'] as $detail) { echo " - {$detail}\n"; } } } } catch (Exception $e) { echo " ✗ Error: " . $e->getMessage() . "\n"; } echo "\n"; } echo "Production setup completed!\n\n"; echo "Next steps:\n"; echo "1. Start queue workers: php start-workers.php\n"; echo "2. Monitor system: php f_core/f_workers/queue-monitor.php monitor\n"; echo "3. Check logs in: logs/\n\n"; } /** * Check system requirements */ private function checkRequirements() { $requirements = [ 'PHP version >= 8.0' => version_compare(PHP_VERSION, '8.0.0', '>='), 'FFmpeg installed' => $this->checkFFmpeg(), 'Redis available' => $this->checkRedis(), 'Database connection' => $this->checkDatabase(), 'GD extension' => extension_loaded('gd'), 'JSON extension' => extension_loaded('json'), 'cURL extension' => extension_loaded('curl'), 'OpenSSL extension' => extension_loaded('openssl') ]; $passed = 0; $failed = []; foreach ($requirements as $requirement => $status) { if ($status) { $passed++; } else { $failed[] = $requirement; } } if (empty($failed)) { return [ 'success' => true, 'message' => "All {$passed} requirements met" ]; } else { return [ 'success' => false, 'message' => count($failed) . ' requirements failed', 'details' => $failed ]; } } /** * Create required directories */ private function createDirectories() { $directories = [ 'f_data/temp', 'f_data/processed', 'f_data/media', 'f_data/thumbnails', 'f_data/logs', 'logs' ]; $created = 0; $errors = []; foreach ($directories as $dir) { $fullPath = _FPATH . $dir; if (!is_dir($fullPath)) { if (mkdir($fullPath, 0755, true)) { $created++; } else { $errors[] = "Failed to create: {$dir}"; } } } if (empty($errors)) { return [ 'success' => true, 'message' => "Created {$created} directories" ]; } else { return [ 'success' => false, 'message' => 'Directory creation failed', 'details' => $errors ]; } } /** * Setup database tables */ private function setupDatabase() { try { // Check if new tables exist $newTables = [ 'db_votes', 'db_comments', 'db_social_shares', 'db_video_views', 'db_video_analytics', 'db_watch_progress', 'db_notifications', 'db_queue_jobs', 'db_live_streams', 'db_stream_chat', 'db_admin_logs', 'db_user_follows', 'db_content_categories', 'db_content_tags', 'db_content_category_relations' ]; $existingTables = []; $missingTables = []; foreach ($newTables as $table) { $query = "SHOW TABLES LIKE '{$table}'"; $result = $this->db->doQuery($query); if ($this->db->doFetch($result)) { $existingTables[] = $table; } else { $missingTables[] = $table; } } if (empty($missingTables)) { return [ 'success' => true, 'message' => 'All database tables exist' ]; } else { return [ 'success' => false, 'message' => count($missingTables) . ' tables missing', 'details' => array_merge( ['Run: mysql -u username -p database < __install/easystream.sql'], ['Missing tables: ' . implode(', ', $missingTables)] ) ]; } } catch (Exception $e) { return [ 'success' => false, 'message' => 'Database check failed: ' . $e->getMessage() ]; } } /** * Configure file permissions */ private function configurePermissions() { $paths = [ 'f_data' => 0755, 'logs' => 0755, 'f_templates' => 0644 ]; $configured = 0; $errors = []; foreach ($paths as $path => $permission) { $fullPath = _FPATH . $path; if (file_exists($fullPath)) { if (chmod($fullPath, $permission)) { $configured++; } else { $errors[] = "Failed to set permissions on: {$path}"; } } } return [ 'success' => empty($errors), 'message' => empty($errors) ? "Configured permissions for {$configured} paths" : 'Permission configuration failed', 'details' => $errors ]; } /** * Setup cron jobs */ private function setupCronJobs() { $cronJobs = [ '0 2 * * * cd ' . _FPATH . ' && php -f start-workers.php >/dev/null 2>&1', '*/5 * * * * cd ' . _FPATH . ' && php -f f_core/f_workers/queue-monitor.php >/dev/null 2>&1' ]; $cronFile = _FPATH . 'easystream-cron.txt'; $cronContent = "# EasyStream Cron Jobs\n"; $cronContent .= "# Add these to your crontab with: crontab easystream-cron.txt\n\n"; foreach ($cronJobs as $job) { $cronContent .= $job . "\n"; } if (file_put_contents($cronFile, $cronContent)) { return [ 'success' => true, 'message' => 'Cron jobs file created: easystream-cron.txt', 'details' => ['Run: crontab easystream-cron.txt'] ]; } else { return [ 'success' => false, 'message' => 'Failed to create cron jobs file' ]; } } /** * Test core components */ private function testComponents() { $tests = [ 'Video Processor' => $this->testVideoProcessor(), 'Queue System' => $this->testQueueSystem(), 'Social Features' => $this->testSocialFeatures(), 'Streaming System' => $this->testStreamingSystem(), 'Live Streaming' => $this->testLiveStreaming(), 'Admin System' => $this->testAdminSystem(), 'Content Manager' => $this->testContentManager() ]; $passed = 0; $failed = []; foreach ($tests as $component => $result) { if ($result) { $passed++; } else { $failed[] = $component; } } return [ 'success' => empty($failed), 'message' => empty($failed) ? "All {$passed} components working" : count($failed) . ' components failed', 'details' => $failed ]; } /** * Generate production configuration */ private function generateConfig() { $config = [ 'production' => true, 'debug' => false, 'log_level' => 'info', 'queue_workers' => [ 'video_processing' => 2, 'general' => 1 ], 'cleanup_schedule' => [ 'logs_retention_days' => 30, 'temp_files_max_age_hours' => 24, 'analytics_retention_days' => 90 ], 'video_processing' => [ 'default_formats' => ['1080p', '720p', '480p', '360p'], 'generate_hls' => true, 'generate_thumbnails' => true ] ]; $configFile = _FPATH . 'production-config.json'; if (file_put_contents($configFile, json_encode($config, JSON_PRETTY_PRINT))) { return [ 'success' => true, 'message' => 'Production config created: production-config.json' ]; } else { return [ 'success' => false, 'message' => 'Failed to create production config' ]; } } /** * Helper methods for testing */ private function checkFFmpeg() { $output = shell_exec('ffmpeg -version 2>&1'); return strpos($output, 'ffmpeg version') !== false; } private function checkRedis() { try { $redis = VRedis::getInstance(); return $redis->isConnected(); } catch (Exception $e) { return false; } } private function checkDatabase() { try { $query = "SELECT 1"; $result = $this->db->doQuery($query); return $result !== false; } catch (Exception $e) { return false; } } private function testVideoProcessor() { try { $processor = new VVideoProcessor(); return true; } catch (Exception $e) { return false; } } private function testQueueSystem() { try { $queueManager = new VQueueManager(); $health = $queueManager->healthCheck(); return $health['status'] !== 'unhealthy'; } catch (Exception $e) { return false; } } private function testSocialFeatures() { try { $social = VSocial::getInstance(); return true; } catch (Exception $e) { return false; } } private function testStreamingSystem() { try { $streaming = new VStreaming(); return true; } catch (Exception $e) { return false; } } private function testLiveStreaming() { try { $liveStreaming = new VLiveStreaming(); return true; } catch (Exception $e) { return false; } } private function testAdminSystem() { try { $admin = VAdmin::getInstance(); return true; } catch (Exception $e) { return false; } } private function testContentManager() { try { $contentManager = VContentManager::getInstance(); return true; } catch (Exception $e) { return false; } } } // CLI execution if (php_sapi_name() === 'cli') { $setup = new ProductionSetup(); $setup->setup(); } else { echo "This script must be run from command line\n"; } ?>