Skip to content

Commit 17b862a

Browse files
authored
Fix the problem of creating backup
Added functionality for manual database backup and zip file creation. Enhanced error handling and notification for backup operations.
1 parent fbb34c5 commit 17b862a

1 file changed

Lines changed: 177 additions & 74 deletions

File tree

cronbot/backupbot.php

Lines changed: 177 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,106 +3,209 @@
33
require_once __DIR__ . '/../function.php';
44
require_once __DIR__ . '/../botapi.php';
55

6-
function addPathToZip(ZipArchive $zip, $path, $basePath)
7-
{
8-
$normalizedBase = rtrim($basePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
9-
10-
if (is_dir($path)) {
11-
$files = new RecursiveIteratorIterator(
12-
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
13-
RecursiveIteratorIterator::SELF_FIRST
14-
);
15-
16-
foreach ($files as $file) {
17-
$filePath = (string) $file;
18-
$relativePath = ltrim(str_replace($normalizedBase, '', $filePath), DIRECTORY_SEPARATOR);
19-
20-
if ($file->isDir()) {
21-
$zip->addEmptyDir($relativePath);
22-
} elseif ($file->isFile()) {
23-
$zip->addFile($filePath, $relativePath);
6+
function manualDbBackup($host, $user, $pass, $dbname, $filename) {
7+
$mysqli = new mysqli($host, $user, $pass, $dbname);
8+
if ($mysqli->connect_error) {
9+
throw new Exception("اتصال به دیتابیس شکست خورد: " . $mysqli->connect_error);
10+
}
11+
$mysqli->set_charset("utf8mb4");
12+
13+
$tables = [];
14+
$result = $mysqli->query("SHOW TABLES");
15+
while ($row = $result->fetch_row()) {
16+
$tables[] = $row[0];
17+
}
18+
19+
$sql = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\n";
20+
$sql .= "START TRANSACTION;\n";
21+
$sql .= "SET time_zone = \"+00:00\";\n\n";
22+
23+
foreach ($tables as $table) {
24+
$sql .= "DROP TABLE IF EXISTS `$table`;\n";
25+
$create = $mysqli->query("SHOW CREATE TABLE `$table`");
26+
$createRow = $create->fetch_row();
27+
$sql .= $createRow[1] . ";\n\n";
28+
29+
$data = $mysqli->query("SELECT * FROM `$table`");
30+
$numFields = $data->field_count;
31+
32+
for ($i = 0; $i < $data->num_rows; $i++) {
33+
$row = $data->fetch_row();
34+
$sql .= "INSERT INTO `$table` VALUES(";
35+
for ($j = 0; $j < $numFields; $j++) {
36+
$row[$j] = isset($row[$j]) ? addslashes($row[$j]) : 'NULL';
37+
$row[$j] = str_replace("\n", "\\n", $row[$j]);
38+
if (!isset($row[$j]) || $row[$j] == 'NULL') {
39+
$sql .= "NULL";
40+
} else {
41+
$sql .= "'" . $row[$j] . "'";
42+
}
43+
if ($j < ($numFields - 1)) {
44+
$sql .= ',';
45+
}
2446
}
47+
$sql .= ");\n";
48+
}
49+
$sql .= "\n\n";
50+
}
51+
52+
$sql .= "COMMIT;\n";
53+
54+
if (file_put_contents($filename, $sql) === false) {
55+
throw new Exception("خطا در ذخیره فایل بکاپ: $filename");
56+
}
57+
58+
$mysqli->close();
59+
return true;
60+
}
61+
62+
function createAndSendZip($filePath, $caption, $chatId, $threadId) {
63+
if (!file_exists($filePath)) return false;
64+
65+
$zipPath = $filePath . '.zip';
66+
67+
if (class_exists('ZipArchive')) {
68+
$zip = new ZipArchive();
69+
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
70+
$zip->addFile($filePath, basename($filePath));
71+
$zip->close();
72+
$sendFile = $zipPath;
73+
} else {
74+
$sendFile = $filePath;
2575
}
26-
} elseif (is_file($path)) {
27-
$relativePath = ltrim(str_replace($normalizedBase, '', $path), DIRECTORY_SEPARATOR);
28-
$zip->addFile($path, $relativePath);
76+
} else {
77+
$sendFile = $filePath;
78+
}
79+
80+
try {
81+
telegram('sendDocument', [
82+
'chat_id' => $chatId,
83+
'message_thread_id' => $threadId,
84+
'document' => new CURLFile(realpath($sendFile)),
85+
'caption' => $caption,
86+
]);
87+
88+
if (file_exists($sendFile)) unlink($sendFile);
89+
if (file_exists($filePath)) unlink($filePath);
90+
} catch (Exception $e) {
91+
error_log("خطا در ارسال فایل: " . $e->getMessage());
92+
return false;
2993
}
94+
95+
return true;
3096
}
3197

32-
$reportbackup = select("topicid","idreport","report","backupfile","select")['idreport'];
98+
99+
$reportbackup = select("topicid", "idreport", "report", "backupfile", "select")['idreport'];
33100
$destination = getcwd();
34101
$setting = select("setting", "*");
35102
$sourcefir = dirname($destination);
36-
$botlist = select("botsaz","*",null,null,"fetchAll");
103+
$botlist = select("botsaz", "*", null, null, "fetchAll");
104+
105+
37106
if ($botlist) {
38107
foreach ($botlist as $bot) {
39108
$folderName = $bot['id_user'] . $bot['username'];
40109
$botBasePath = $sourcefir . '/vpnbot/' . $folderName;
41110
$zipFilePath = $destination . '/file_' . $folderName . '.zip';
42-
$zip = new ZipArchive();
43111

44-
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
45-
$pathsToBackup = [
46-
$botBasePath . '/data',
47-
$botBasePath . '/product.json',
48-
$botBasePath . '/product_name.json',
49-
];
112+
if (!is_dir($botBasePath)) continue;
50113

51-
foreach ($pathsToBackup as $path) {
52-
if (file_exists($path)) {
53-
addPathToZip($zip, $path, $botBasePath . '/');
54-
} else {
55-
error_log('Backup path not found for bot archive: ' . $path);
56-
}
114+
$filesToZip = [];
115+
foreach (['data', 'product.json', 'product_name.json'] as $item) {
116+
$fullPath = $botBasePath . '/' . $item;
117+
if (file_exists($fullPath)) {
118+
$filesToZip[] = $fullPath;
57119
}
58-
$zip->close();
120+
}
59121

60-
telegram('sendDocument', [
61-
'chat_id' => $setting['Channel_Report'],
62-
'message_thread_id' => $reportbackup,
63-
'document' => new CURLFile($zipFilePath),
64-
'caption' => "@{$bot['username']} | {$bot['id_user']}",
65-
]);
122+
if (empty($filesToZip)) continue;
123+
124+
if (class_exists('ZipArchive')) {
125+
$zip = new ZipArchive();
126+
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
127+
foreach ($filesToZip as $path) {
128+
if (is_dir($path)) {
129+
$iterator = new RecursiveIteratorIterator(
130+
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
131+
RecursiveIteratorIterator::SELF_FIRST
132+
);
133+
foreach ($iterator as $file) {
134+
$relative = str_replace($botBasePath . DIRECTORY_SEPARATOR, '', $file);
135+
if ($file->isDir()) {
136+
$zip->addEmptyDir($relative);
137+
} else {
138+
$zip->addFile($file, $relative);
139+
}
140+
}
141+
} else {
142+
$relative = basename($path);
143+
$zip->addFile($path, $relative);
144+
}
145+
}
146+
$zip->close();
147+
148+
telegram('sendDocument', [
149+
'chat_id' => $setting['Channel_Report'],
150+
'message_thread_id' => $reportbackup,
151+
'document' => new CURLFile(realpath($zipFilePath)),
152+
'caption' => "@{$bot['username']} | {$bot['id_user']}",
153+
]);
66154

67-
if (file_exists($zipFilePath)) {
68-
unlink($zipFilePath);
155+
if (file_exists($zipFilePath)) unlink($zipFilePath);
69156
}
70157
} else {
71-
error_log('Unable to create zip archive for bot directory: ' . $botBasePath);
158+
telegram('sendMessage', [
159+
'chat_id' => $setting['Channel_Report'],
160+
'message_thread_id' => $reportbackup,
161+
'text' => "⚠️ نمی‌توان بکاپ ربات @{$bot['username']} را فشرده‌سازی کرد (ZipArchive غیرفعال است).",
162+
]);
72163
}
73164
}
74165
}
75166

76167

168+
$backup_file_name = 'backup_' . date("Y-m-d") . '.sql';
169+
$success = false;
77170

171+
$db_host = 'localhost';
78172

79-
$backup_file_name = 'backup_' . date("Y-m-d") . '.sql';
80-
$zip_file_name = 'backup_' . date("Y-m-d") . '.zip';
81-
82-
$command = "mysqldump -h localhost -u $usernamedb -p'$passworddb' --no-tablespaces $dbname > $backup_file_name";
83-
84-
$output = [];
85-
$return_var = 0;
86-
exec($command, $output, $return_var);
87-
if ($return_var !== 0) {
88-
telegram('sendmessage', [
89-
'chat_id' => $setting['Channel_Report'],
90-
'message_thread_id' => $reportbackup,
91-
'text' => "❌❌❌❌❌❌خطا در بکاپ گرفتن لطفا به پشتیبانی اطلاع دهید",
92-
]);
93-
} else {
94-
$zip = new ZipArchive();
95-
if ($zip->open($zip_file_name, ZipArchive::CREATE) === TRUE) {
96-
$zip->addFile($backup_file_name, basename($backup_file_name));
97-
$zip->close();
98-
99-
telegram('sendDocument', [
100-
'chat_id' => $setting['Channel_Report'],
101-
'message_thread_id' => $reportbackup,
102-
'document' => new CURLFile($zip_file_name),
103-
'caption' => "📌 خروجی دیتابیس ربات اصلی",
104-
]);
105-
unlink($zip_file_name);
106-
unlink($backup_file_name);
173+
174+
if (function_exists('exec') && !ini_get('safe_mode')) {
175+
$command = "mysqldump -h " . escapeshellarg($db_host) .
176+
" -u " . escapeshellarg($usernamedb) .
177+
" -p" . escapeshellarg($passworddb) .
178+
" --no-tablespaces " . escapeshellarg($dbname) .
179+
" > " . escapeshellarg($backup_file_name);
180+
181+
$output = [];
182+
$return_var = 0;
183+
@exec($command, $output, $return_var);
184+
if ($return_var === 0 && file_exists($backup_file_name)) {
185+
$success = true;
186+
}
187+
}
188+
189+
if (!$success) {
190+
try {
191+
manualDbBackup($db_host, $usernamedb, $passworddb, $dbname, $backup_file_name);
192+
$success = true;
193+
} catch (Exception $e) {
194+
error_log("خطا در بکاپ دستی: " . $e->getMessage());
195+
telegram('sendMessage', [
196+
'chat_id' => $setting['Channel_Report'],
197+
'message_thread_id' => $reportbackup,
198+
'text' => "❌❌❌❌❌❌\nخطا در بکاپ دیتابیس:\n" . $e->getMessage(),
199+
]);
200+
$success = false;
201+
}
107202
}
203+
204+
if ($success) {
205+
createAndSendZip(
206+
$backup_file_name,
207+
"📌 خروجی دیتابیس ربات اصلی",
208+
$setting['Channel_Report'],
209+
$reportbackup
210+
);
108211
}

0 commit comments

Comments
 (0)