#!/usr/bin/env php true, 'run_benchmarks' => true, 'validate_optimizations' => true, 'rollback_on_failure' => true, 'performance_threshold' => 5.0, // 5% minimum improvement required 'max_regression_tolerance' => 2.0 // 2% maximum regression allowed ]; public function __construct() { $this->project_root = dirname(dirname(__FILE__)); $this->backup_dir = $this->project_root . '/backups/performance_optimization_' . date('Y-m-d_H-i-s'); echo "=== DESK-MOLONI PERFORMANCE OPTIMIZATION DEPLOYMENT - T023 ===\n"; echo "Project Root: {$this->project_root}\n"; echo "Deployment Time: " . date('Y-m-d H:i:s') . "\n"; echo "PHP Version: " . PHP_VERSION . "\n\n"; // Verify environment $this->verifyEnvironment(); } /** * Main deployment process */ public function deploy($options = []) { try { // Merge options with defaults $this->config = array_merge($this->config, $options); echo "๐Ÿš€ Starting Performance Optimization Deployment...\n\n"; // Step 1: Environment validation $this->validateEnvironment(); // Step 2: Create backup if enabled if ($this->config['backup_enabled']) { $this->createBackup(); } // Step 3: Deploy optimized classes $this->deployOptimizedClasses(); // Step 4: Run benchmarks if enabled if ($this->config['run_benchmarks']) { $this->runPerformanceBenchmarks(); } // Step 5: Validate optimizations if ($this->config['validate_optimizations']) { $this->validateOptimizations(); } // Step 6: Generate deployment report $this->generateDeploymentReport(); echo "โœ… Performance Optimization Deployment Completed Successfully!\n\n"; // Display final results $this->displayFinalResults(); return true; } catch (Exception $e) { echo "โŒ Deployment Failed: " . $e->getMessage() . "\n\n"; // Attempt rollback if configured if ($this->config['rollback_on_failure'] && $this->config['backup_enabled']) { $this->attemptRollback(); } throw $e; } } /** * Verify basic environment requirements */ private function verifyEnvironment() { $requirements = [ 'php_version' => '8.3.0', 'extensions' => [ 'json' => true, // Required 'pdo' => false, // Recommended 'mysqli' => false, // Recommended 'curl' => false // Recommended ], 'functions' => ['file_get_contents', 'file_put_contents'], 'directories' => ['modules/desk_moloni/libraries', 'scripts'] ]; // Check PHP version if (version_compare(PHP_VERSION, $requirements['php_version'], '<')) { throw new Exception("PHP {$requirements['php_version']} or higher required. Current: " . PHP_VERSION); } // Check extensions foreach ($requirements['extensions'] as $extension => $required) { if (!extension_loaded($extension)) { if ($required) { throw new Exception("Required PHP extension '{$extension}' not loaded"); } else { echo "โš ๏ธ Recommended PHP extension '{$extension}' not available (performance may be affected)\n"; } } } // Check functions foreach ($requirements['functions'] as $function) { if (!function_exists($function)) { throw new Exception("Required PHP function '{$function}' not available"); } } // Check directories foreach ($requirements['directories'] as $directory) { $full_path = $this->project_root . '/' . $directory; if (!is_dir($full_path)) { throw new Exception("Required directory '{$directory}' not found"); } } echo "โœ… Environment verification passed\n"; } /** * Validate deployment environment */ private function validateEnvironment() { echo "๐Ÿ” Validating deployment environment...\n"; // Check if this is PHP 8.4 ready $version_file = $this->project_root . '/VERSION'; if (file_exists($version_file)) { $version_content = trim(file_get_contents($version_file)); if (strpos($version_content, 'PHP84-READY') !== false) { echo "โœ… Codebase is PHP 8.4 ready\n"; $this->optimization_status['php84_ready'] = true; } else { echo "โš ๏ธ PHP 8.4 readiness not confirmed in VERSION file\n"; $this->optimization_status['php84_ready'] = false; } } // Check for existing optimized files $optimized_files = [ 'modules/desk_moloni/libraries/OptimizedMoloniApiClient.php', 'modules/desk_moloni/libraries/OptimizedDatabaseOperations.php', 'modules/desk_moloni/libraries/StreamingInvoiceSyncService.php', 'modules/desk_moloni/libraries/PerformanceBenchmarkSuite.php' ]; $existing_files = 0; foreach ($optimized_files as $file) { if (file_exists($this->project_root . '/' . $file)) { $existing_files++; } } echo "๐Ÿ“ Found {$existing_files}/" . count($optimized_files) . " optimization files\n"; $this->optimization_status['optimization_files_present'] = $existing_files === count($optimized_files); // Validate composer autoloader optimization $composer_file = $this->project_root . '/composer.json'; if (file_exists($composer_file)) { $composer_data = json_decode(file_get_contents($composer_file), true); if (isset($composer_data['config']['optimize-autoloader']) && $composer_data['config']['optimize-autoloader']) { echo "โœ… Composer autoloader optimization enabled\n"; $this->optimization_status['autoloader_optimized'] = true; } else { echo "โš ๏ธ Composer autoloader optimization not enabled\n"; $this->optimization_status['autoloader_optimized'] = false; } } } /** * Create backup of existing files */ private function createBackup() { echo "๐Ÿ’พ Creating backup...\n"; // Create backup directory if (!is_dir($this->backup_dir)) { mkdir($this->backup_dir, 0755, true); } // Files to backup $backup_files = [ 'modules/desk_moloni/libraries/MoloniApiClient.php', 'modules/desk_moloni/libraries/InvoiceSyncService.php', 'modules/desk_moloni/libraries/ClientSyncService.php', 'desk_moloni.php', 'composer.json' ]; foreach ($backup_files as $file) { $source = $this->project_root . '/' . $file; $destination = $this->backup_dir . '/' . $file; if (file_exists($source)) { // Create destination directory if needed $dest_dir = dirname($destination); if (!is_dir($dest_dir)) { mkdir($dest_dir, 0755, true); } copy($source, $destination); echo " ๐Ÿ“„ Backed up: {$file}\n"; } } // Create backup manifest $manifest = [ 'backup_time' => date('Y-m-d H:i:s'), 'php_version' => PHP_VERSION, 'project_version' => $this->getProjectVersion(), 'files_backed_up' => $backup_files ]; file_put_contents( $this->backup_dir . '/backup_manifest.json', json_encode($manifest, JSON_PRETTY_PRINT) ); echo "โœ… Backup created at: {$this->backup_dir}\n"; $this->deployment_log[] = "Backup created successfully"; } /** * Deploy optimized classes */ private function deployOptimizedClasses() { echo "๐Ÿ”ง Deploying optimized classes...\n"; // Update main module file to include optimized classes $this->updateMainModuleFile(); // Configure optimized autoloading $this->configureOptimizedAutoloading(); // Update composer.json for optimal performance $this->optimizeComposerConfiguration(); // Regenerate composer autoloader $this->regenerateComposerAutoloader(); echo "โœ… Optimized classes deployed\n"; $this->deployment_log[] = "Optimized classes deployed successfully"; } /** * Update main module file */ private function updateMainModuleFile() { $main_file = $this->project_root . '/desk_moloni.php'; if (!file_exists($main_file)) { throw new Exception("Main module file not found: {$main_file}"); } $content = file_get_contents($main_file); // Add optimization indicator $optimization_comment = "// T023 PERFORMANCE OPTIMIZATIONS ACTIVE\n"; if (strpos($content, $optimization_comment) === false) { // Insert after the version definition $version_pattern = "/(define\('DESK_MOLONI_VERSION', '[^']+'\);)/"; $replacement = "$1\n\n" . $optimization_comment; $content = preg_replace($version_pattern, $replacement, $content); file_put_contents($main_file, $content); echo " ๐Ÿ“ Updated main module file with optimization markers\n"; } } /** * Configure optimized autoloading */ private function configureOptimizedAutoloading() { // Create autoloader configuration for optimized classes $autoload_config = $this->project_root . '/modules/desk_moloni/config/optimized_autoload.php'; $config_content = 'project_root . '/composer.json'; if (!file_exists($composer_file)) { echo " โš ๏ธ composer.json not found, skipping composer optimization\n"; return; } $composer_data = json_decode(file_get_contents($composer_file), true); // Enable performance optimizations if (!isset($composer_data['config'])) { $composer_data['config'] = []; } $composer_data['config']['optimize-autoloader'] = true; $composer_data['config']['classmap-authoritative'] = true; $composer_data['config']['apcu-autoloader'] = true; $composer_data['config']['sort-packages'] = true; file_put_contents($composer_file, json_encode($composer_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); echo " ๐ŸŽฏ Optimized composer.json configuration\n"; } /** * Regenerate composer autoloader */ private function regenerateComposerAutoloader() { if (!file_exists($this->project_root . '/composer.json')) { return; } // Change to project directory $old_cwd = getcwd(); chdir($this->project_root); try { // Run composer dump-autoload with optimization $command = 'composer dump-autoload --optimize --classmap-authoritative'; $output = []; $return_code = 0; exec($command . ' 2>&1', $output, $return_code); if ($return_code === 0) { echo " ๐Ÿ”„ Regenerated optimized composer autoloader\n"; } else { echo " โš ๏ธ Composer autoloader regeneration warning: " . implode("\n", $output) . "\n"; } } finally { chdir($old_cwd); } } /** * Run performance benchmarks */ private function runPerformanceBenchmarks() { echo "๐Ÿ“Š Running performance benchmarks...\n"; // Load benchmark suite require_once $this->project_root . '/modules/desk_moloni/libraries/PerformanceBenchmarkSuite.php'; try { $benchmark_suite = new PerformanceBenchmarkSuite(); // Configure benchmark options $benchmark_options = [ 'api_iterations' => 50, // Reduced for deployment speed 'db_iterations' => 500, 'memory_test_size' => 5000, 'statistical_runs' => 3 ]; echo " ๐Ÿƒ Executing benchmark suite (this may take a few minutes)...\n"; $benchmark_results = $benchmark_suite->executeBenchmarkSuite($benchmark_options); // Store benchmark results $this->optimization_status['benchmark_results'] = $benchmark_results; // Display key results $executive_summary = $benchmark_results['executive_summary']; echo " ๐Ÿ“ˆ Performance improvement achieved: {$executive_summary['overall_improvement_achieved']}%\n"; echo " ๐ŸŽฏ Target performance met: " . ($executive_summary['target_performance_met'] ? 'YES' : 'NO') . "\n"; echo " ๐Ÿ“Š Total expected improvement (with PHP 8.4): {$executive_summary['total_expected_improvement']}%\n"; if ($executive_summary['target_performance_met']) { echo "โœ… Benchmark validation passed\n"; $this->deployment_log[] = "Performance benchmarks passed - Target achieved"; } else { echo "โš ๏ธ Benchmark validation warning - Target not fully met\n"; $this->deployment_log[] = "Performance benchmarks completed with warnings"; } } catch (Exception $e) { echo " โŒ Benchmark execution error: " . $e->getMessage() . "\n"; $this->optimization_status['benchmark_error'] = $e->getMessage(); if ($this->config['rollback_on_failure']) { throw new Exception("Benchmark validation failed: " . $e->getMessage()); } } } /** * Validate optimizations */ private function validateOptimizations() { echo "๐Ÿ” Validating optimizations...\n"; $validation_results = []; // Test 1: Class loading validation $validation_results['class_loading'] = $this->validateClassLoading(); // Test 2: Memory usage validation $validation_results['memory_usage'] = $this->validateMemoryUsage(); // Test 3: API optimization validation $validation_results['api_optimization'] = $this->validateApiOptimization(); // Test 4: Database optimization validation $validation_results['database_optimization'] = $this->validateDatabaseOptimization(); // Test 5: Integration validation $validation_results['integration'] = $this->validateIntegration(); $this->optimization_status['validation_results'] = $validation_results; // Count passed validations $passed_validations = array_filter($validation_results); $total_validations = count($validation_results); echo " โœ… Validation results: " . count($passed_validations) . "/{$total_validations} tests passed\n"; if (count($passed_validations) === $total_validations) { echo "โœ… All optimization validations passed\n"; $this->deployment_log[] = "All optimization validations passed"; } else { echo "โš ๏ธ Some optimization validations failed\n"; $this->deployment_log[] = "Optimization validation completed with warnings"; if ($this->config['rollback_on_failure']) { throw new Exception("Optimization validation failed"); } } } /** * Validate class loading */ private function validateClassLoading() { // Load CLI bootstrap first require_once dirname(__FILE__) . '/cli_bootstrap.php'; $classes_to_test = [ 'OptimizedMoloniApiClient', 'OptimizedDatabaseOperations', 'StreamingInvoiceSyncService', 'PerformanceBenchmarkSuite' ]; $loaded_classes = 0; foreach ($classes_to_test as $class) { // Try to include the file directly $class_file = $this->project_root . '/modules/desk_moloni/libraries/' . $class . '.php'; if (file_exists($class_file)) { try { require_once $class_file; if (class_exists($class)) { $loaded_classes++; } else { echo " โŒ Class file exists but class not defined: {$class}\n"; } } catch (Exception $e) { echo " โŒ Error loading class {$class}: " . $e->getMessage() . "\n"; } } else { echo " โŒ Class file not found: {$class}\n"; } } $success = $loaded_classes === count($classes_to_test); if ($success) { echo " โœ… All optimization classes loadable ({$loaded_classes}/" . count($classes_to_test) . ")\n"; } else { echo " โš ๏ธ Only {$loaded_classes}/" . count($classes_to_test) . " classes loaded successfully\n"; } return $success; } /** * Validate memory usage */ private function validateMemoryUsage() { $memory_start = memory_get_usage(true); // Create objects to test memory usage try { $objects = []; for ($i = 0; $i < 100; $i++) { $objects[] = ['test_data' => str_repeat('x', 1000)]; } $memory_used = memory_get_usage(true) - $memory_start; $memory_per_object = $memory_used / 100; // Objects should use reasonable memory (less than 2KB each) $success = $memory_per_object < 2048; if ($success) { echo " โœ… Memory usage validation passed\n"; } else { echo " โŒ Memory usage too high: " . round($memory_per_object) . " bytes per object\n"; } return $success; } catch (Exception $e) { echo " โŒ Memory validation error: " . $e->getMessage() . "\n"; return false; } } /** * Validate API optimization */ private function validateApiOptimization() { try { // Load the class file if not already loaded $class_file = $this->project_root . '/modules/desk_moloni/libraries/OptimizedMoloniApiClient.php'; if (file_exists($class_file)) { require_once $class_file; } // Test if optimized API client can be instantiated if (class_exists('OptimizedMoloniApiClient')) { // Just test if the class can be instantiated without dependencies $reflection = new ReflectionClass('OptimizedMoloniApiClient'); // Test if performance methods exist $required_methods = ['getPerformanceStats', 'clearCaches', 'batch_requests']; $methods_exist = 0; foreach ($required_methods as $method) { if ($reflection->hasMethod($method)) { $methods_exist++; } } $success = $methods_exist === count($required_methods); if ($success) { echo " โœ… API optimization validation passed ({$methods_exist}/" . count($required_methods) . " methods)\n"; } else { echo " โš ๏ธ API optimization partial validation ({$methods_exist}/" . count($required_methods) . " methods)\n"; } return $success; } else { echo " โŒ OptimizedMoloniApiClient class not available\n"; return false; } } catch (Exception $e) { echo " โŒ API optimization validation error: " . $e->getMessage() . "\n"; return false; } } /** * Validate database optimization */ private function validateDatabaseOptimization() { try { // Load the class file if not already loaded $class_file = $this->project_root . '/modules/desk_moloni/libraries/OptimizedDatabaseOperations.php'; if (file_exists($class_file)) { require_once $class_file; } if (class_exists('OptimizedDatabaseOperations')) { // Use reflection to test methods without instantiation $reflection = new ReflectionClass('OptimizedDatabaseOperations'); // Test if optimization methods exist $required_methods = ['batchInsert', 'batchUpdate', 'getPerformanceMetrics']; $methods_exist = 0; foreach ($required_methods as $method) { if ($reflection->hasMethod($method)) { $methods_exist++; } } $success = $methods_exist === count($required_methods); if ($success) { echo " โœ… Database optimization validation passed ({$methods_exist}/" . count($required_methods) . " methods)\n"; } else { echo " โš ๏ธ Database optimization partial validation ({$methods_exist}/" . count($required_methods) . " methods)\n"; } return $success; } else { echo " โŒ OptimizedDatabaseOperations class not available\n"; return false; } } catch (Exception $e) { echo " โŒ Database optimization validation error: " . $e->getMessage() . "\n"; return false; } } /** * Validate integration */ private function validateIntegration() { try { // Load the class file if not already loaded $class_file = $this->project_root . '/modules/desk_moloni/libraries/StreamingInvoiceSyncService.php'; if (file_exists($class_file)) { require_once $class_file; } // Test if streaming service integrates with optimized components if (class_exists('StreamingInvoiceSyncService')) { // Use reflection to test methods without instantiation $reflection = new ReflectionClass('StreamingInvoiceSyncService'); // Test basic functionality $methods_exist = $reflection->hasMethod('streamingBulkSync') && $reflection->hasMethod('getStreamingMetrics'); if ($methods_exist) { echo " โœ… Integration validation passed\n"; return true; } else { echo " โŒ Integration methods missing\n"; return false; } } else { echo " โŒ StreamingInvoiceSyncService class not available\n"; return false; } } catch (Exception $e) { echo " โŒ Integration validation error: " . $e->getMessage() . "\n"; return false; } } /** * Generate deployment report */ private function generateDeploymentReport() { echo "๐Ÿ“‹ Generating deployment report...\n"; $report = [ 'deployment_info' => [ 'timestamp' => date('Y-m-d H:i:s'), 'php_version' => PHP_VERSION, 'project_version' => $this->getProjectVersion(), 'deployment_directory' => $this->project_root, 'backup_directory' => $this->config['backup_enabled'] ? $this->backup_dir : null ], 'optimization_status' => $this->optimization_status, 'deployment_log' => $this->deployment_log, 'performance_summary' => $this->generatePerformanceSummary(), 'recommendations' => $this->generateRecommendations(), 'next_steps' => $this->generateNextSteps() ]; // Save report $report_file = $this->project_root . '/PERFORMANCE_DEPLOYMENT_REPORT_' . date('Y-m-d_H-i-s') . '.json'; file_put_contents($report_file, json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); echo " ๐Ÿ“„ Deployment report saved: " . basename($report_file) . "\n"; } /** * Generate performance summary */ private function generatePerformanceSummary() { if (!isset($this->optimization_status['benchmark_results'])) { return ['benchmarks_not_run' => true]; } $results = $this->optimization_status['benchmark_results']; $executive = $results['executive_summary']; return [ 'overall_improvement' => $executive['overall_improvement_achieved'], 'target_achieved' => $executive['target_performance_met'], 'php_84_benefit' => $executive['php_84_baseline_benefit'], 'total_improvement' => $executive['total_expected_improvement'], 'certification_status' => $executive['certification_status'], 'key_improvements' => $executive['key_improvements'] ]; } /** * Generate recommendations */ private function generateRecommendations() { $recommendations = []; // PHP 8.4 upgrade recommendation if (version_compare(PHP_VERSION, '8.4.0', '<')) { $recommendations[] = [ 'priority' => 'high', 'category' => 'PHP Upgrade', 'recommendation' => 'Upgrade to PHP 8.4 to realize the full 20%+ performance improvement', 'benefit' => '15% additional performance gain' ]; } // OPcache recommendation if (!extension_loaded('Zend OPcache') || !ini_get('opcache.enable')) { $recommendations[] = [ 'priority' => 'high', 'category' => 'OPcache', 'recommendation' => 'Enable and configure OPcache for additional performance benefits', 'benefit' => '5-10% additional performance gain' ]; } // APCu recommendation if (!extension_loaded('apcu')) { $recommendations[] = [ 'priority' => 'medium', 'category' => 'Caching', 'recommendation' => 'Install APCu extension for enhanced autoloader caching', 'benefit' => '2-3% additional performance gain' ]; } // Monitoring recommendation $recommendations[] = [ 'priority' => 'medium', 'category' => 'Monitoring', 'recommendation' => 'Implement performance monitoring to track optimization benefits in production', 'benefit' => 'Ongoing performance visibility' ]; return $recommendations; } /** * Generate next steps */ private function generateNextSteps() { $next_steps = []; if (isset($this->optimization_status['benchmark_results'])) { $target_met = $this->optimization_status['benchmark_results']['executive_summary']['target_performance_met']; if ($target_met) { $next_steps[] = 'Deploy to production environment with monitoring'; $next_steps[] = 'Configure performance alerting and dashboards'; $next_steps[] = 'Plan PHP 8.4 upgrade to realize full 20%+ improvement'; $next_steps[] = 'Document optimization techniques for team training'; } else { $next_steps[] = 'Review benchmark results and identify additional optimization opportunities'; $next_steps[] = 'Consider infrastructure optimizations (database tuning, server configuration)'; $next_steps[] = 'Re-run benchmarks after addressing optimization gaps'; } } else { $next_steps[] = 'Run performance benchmarks to validate optimization effectiveness'; $next_steps[] = 'Review validation results and address any issues'; } return $next_steps; } /** * Display final results */ private function displayFinalResults() { echo "=== FINAL DEPLOYMENT RESULTS ===\n\n"; // Performance summary if (isset($this->optimization_status['benchmark_results'])) { $performance = $this->generatePerformanceSummary(); echo "๐Ÿ“Š PERFORMANCE RESULTS:\n"; echo " โ€ข Overall Improvement: {$performance['overall_improvement']}%\n"; echo " โ€ข Target Achieved: " . ($performance['target_achieved'] ? 'YES โœ…' : 'NO โŒ') . "\n"; echo " โ€ข PHP 8.4 Additional Benefit: {$performance['php_84_benefit']}%\n"; echo " โ€ข Total Expected Improvement: {$performance['total_improvement']}%\n"; echo " โ€ข Certification Status: {$performance['certification_status']}\n\n"; } // Optimization status echo "๐Ÿ”ง OPTIMIZATION STATUS:\n"; foreach ($this->optimization_status as $key => $value) { if (is_bool($value)) { echo " โ€ข " . ucfirst(str_replace('_', ' ', $key)) . ": " . ($value ? 'YES โœ…' : 'NO โŒ') . "\n"; } } echo "\n"; // Next steps $next_steps = $this->generateNextSteps(); echo "๐Ÿš€ NEXT STEPS:\n"; foreach ($next_steps as $step) { echo " โ€ข {$step}\n"; } echo "\n"; if ($this->config['backup_enabled']) { echo "๐Ÿ’พ BACKUP: Created at {$this->backup_dir}\n"; } echo "๐Ÿ“„ REPORT: Check project directory for detailed deployment report\n\n"; } /** * Get project version */ private function getProjectVersion() { $version_file = $this->project_root . '/VERSION'; if (file_exists($version_file)) { return trim(file_get_contents($version_file)); } return 'Unknown'; } /** * Attempt rollback on failure */ private function attemptRollback() { echo "๐Ÿ”„ Attempting rollback...\n"; if (!is_dir($this->backup_dir)) { echo " โŒ Backup directory not found, cannot rollback\n"; return false; } $manifest_file = $this->backup_dir . '/backup_manifest.json'; if (!file_exists($manifest_file)) { echo " โŒ Backup manifest not found, cannot rollback\n"; return false; } $manifest = json_decode(file_get_contents($manifest_file), true); $restored_files = 0; foreach ($manifest['files_backed_up'] as $file) { $backup_file = $this->backup_dir . '/' . $file; $target_file = $this->project_root . '/' . $file; if (file_exists($backup_file)) { copy($backup_file, $target_file); $restored_files++; echo " ๐Ÿ“„ Restored: {$file}\n"; } } echo "โœ… Rollback completed - {$restored_files} files restored\n"; return true; } } // Main execution if (php_sapi_name() === 'cli') { try { $deployment = new PerformanceOptimizationDeployment(); // Parse command line options $options = []; // Check for --no-backup option if (in_array('--no-backup', $argv)) { $options['backup_enabled'] = false; } // Check for --no-benchmarks option if (in_array('--no-benchmarks', $argv)) { $options['run_benchmarks'] = false; } // Check for --no-rollback option if (in_array('--no-rollback', $argv)) { $options['rollback_on_failure'] = false; } // Run deployment $result = $deployment->deploy($options); exit($result ? 0 : 1); } catch (Exception $e) { echo "\nโŒ DEPLOYMENT FAILED: " . $e->getMessage() . "\n\n"; exit(1); } }