PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.4.5
Backup Migration v1.4.5
2.1.7 2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / scanner / backups.php
backup-backup / includes / scanner Last commit date
backups.php 2 years ago files.php 2 years ago
backups.php
229 lines
1 <?php
2
3 // Namespace
4 namespace BMI\Plugin\Scanner;
5
6 // Use
7 use BMI\Plugin\BMI_Logger AS Logger;
8 use BMI\Plugin\Zipper\BMI_Zipper AS Zipper;
9 use BMI\Plugin\Zipper\Zip AS Zip;
10 use BMI\Plugin\External\BMI_External_Storage as ExternalStorage;
11
12 // Exit on direct access
13 if (!defined('ABSPATH')) exit;
14
15 /**
16 * Main Backup Scanner Logic
17 */
18 class BMI_BackupsScanner {
19
20 public function scanBackupDir($path) {
21
22 $files = [];
23 foreach (new \DirectoryIterator($path) as $fileInfo) {
24
25 if ($fileInfo->isDot()) continue;
26 if ($fileInfo->isFile()) {
27 if (in_array($fileInfo->getExtension(), ['zip', 'tar', 'tar.gz', 'gz', 'rar', '7zip', '7z'])) {
28
29 $files[] = array(
30 'filename' => $fileInfo->getFilename(),
31 'path' => $path,
32 'size' => $fileInfo->getSize()
33 );
34
35 }
36 }
37
38 }
39
40 return $files;
41
42 }
43
44 public function removeOldCache() {
45 $md5_file_summary_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. 'md5summary.php';
46
47 $md5summary = [];
48 if (file_exists($md5_file_summary_path)) {
49 $md5summary = file_get_contents($md5_file_summary_path);
50 $md5summary = substr($md5summary, 18, -2);
51 if (is_serialized($md5summary)) {
52 $md5summary = maybe_unserialize($md5summary);
53 }
54 }
55
56 foreach ($md5summary as $backupName => $md5files) {
57 foreach ($md5files as $index => $md5) {
58 if (!file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupName)) {
59 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . $md5 . '.json')) {
60 @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . $md5 . '.json');
61 }
62 unset($md5summary[$backupName][$index]);
63 }
64 }
65
66 if (sizeof($md5summary[$backupName]) == 0) {
67 unset($md5summary[$backupName]);
68 }
69 }
70
71 $cacheMd5String = "<?php exit; \$x = '" . serialize($md5summary) . "';";
72 file_put_contents($md5_file_summary_path, $cacheMd5String);
73 }
74
75 public function getManifestFromZip($zip_path, &$zipper) {
76
77 if (!file_exists($zip_path)) return false;
78
79 // Get manifest content
80 $md5_file_summary_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. 'md5summary.php';
81 $zip_modification_time = filemtime($zip_path);
82 $zip_name = basename($zip_path);
83
84 $md5summary = [];
85 if (file_exists($md5_file_summary_path)) {
86 $md5summary = file_get_contents($md5_file_summary_path);
87 $md5summary = substr($md5summary, 18, -2);
88 if (is_serialized($md5summary)) {
89 $md5summary = maybe_unserialize($md5summary);
90 }
91 }
92
93 $md5s = [];
94 $cached_md5 = false;
95 if (isset($md5summary[$zip_name])) {
96
97 $md5s = $md5summary[$zip_name];
98 $latest = 0;
99 $latest_md5 = false;
100 for ($i = 0; $i < sizeof($md5s); ++$i) {
101 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $md5s[$i] . '.json';
102 if (file_exists($md5_file_path)) {
103 $ftime = filemtime($md5_file_path);
104 if ($ftime > $latest) {
105 $latest = $ftime;
106 $latest_md5 = $md5s[$i];
107 }
108 }
109 }
110
111 if ($latest_md5 != false) {
112 $cached_md5 = $latest_md5;
113 }
114
115 } else {
116
117 $md5summary[$zip_name] = [];
118
119 }
120
121 if ($cached_md5 != false) {
122 $zip_md5 = $cached_md5;
123 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. $cached_md5 . '.json';
124 } else {
125 $zip_md5 = md5_file($zip_path);
126 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. $zip_md5 . '.json';
127 if (!in_array($zip_md5, $md5summary[$zip_name])) {
128 $md5summary[$zip_name][] = $zip_md5;
129 }
130 }
131
132 $res = array();
133 if (file_exists($md5_file_path)) {
134 $manifest = json_decode(file_get_contents($md5_file_path));
135 } else {
136 $manifest = $zipper->getZipFileContent($zip_path, 'bmi_backup_manifest.json');
137 }
138
139 if ($manifest) {
140
141 $res[] = $manifest->name . '#%&' . $zip_name;
142 $res[] = $manifest->date;
143 $res[] = $manifest->files;
144 $res[] = $manifest->manifest;
145 $res[] = @filesize($zip_path);
146 if (!isset($manifest->is_locked)) {
147 $manifest->is_locked = $zipper->is_locked_zip($zip_path) ? 'locked' : 'unlocked';
148 $res[] = $manifest->is_locked;
149 } else {
150 $res[] = $manifest->is_locked;
151 }
152 $res[] = $manifest->cron;
153 $res[] = $zip_md5;
154 $res[] = sanitize_text_field($manifest->domain);
155
156 if (!file_exists($md5_file_path)) {
157 $manifest->abspath = $manifest->config->ABSPATH;
158 $manifest->table_prefix = $manifest->config->table_prefix;
159 unset($manifest->config);
160 file_put_contents($md5_file_path, json_encode($manifest));
161 } else touch($md5_file_path);
162
163 $cacheMd5String = "<?php exit; \$x = '" . serialize($md5summary) . "';";
164 file_put_contents($md5_file_summary_path, $cacheMd5String);
165
166 return $res;
167
168 } else return false;
169
170 }
171
172 public function getAvailableBackups() {
173
174 // Require Universal Zip Library
175 require_once BMI_INCLUDES . '/zipper/zipping.php';
176 $zipper = new Zipper();
177
178 // Scan for manifests
179 $manifests = array();
180 $backups = array();
181 $external = array();
182 $ongoing = get_option('bmip_to_be_uploaded', [
183 'current_upload' => [],
184 'queue' => [],
185 'failed' => []
186 ]);
187
188 if (file_exists(BMI_BACKUPS))
189 $backups = $this->scanBackupDir(BMI_BACKUPS);
190
191 // $start = time();
192 // $maxTime = ini_get('max_execution_time');
193
194 for ($i = 0; $i < sizeof($backups); ++$i) {
195
196 // $filestart = time();
197
198 $backup = $backups[$i];
199 if (!file_exists($backup['path'])) continue;
200 $path = $backup['path'] . '/' . $backup['filename'];
201
202 $manifest = $this->getManifestFromZip($path, $zipper);
203 if ($manifest) $manifests[$backup['filename']] = $manifest;
204 else @unlink($path);
205
206 // $fileend = $filestart - time();
207 // $totalTime = $start - time();
208
209 // if ($totalTime + $fileend > $maxTime) break;
210
211 }
212
213 if (defined('BMI_BACKUP_PRO') && defined('BMI_PRO_INC')) {
214 $proPath = BMI_PRO_INC . 'external/controller.php';
215 if (file_exists($proPath)) {
216 require_once $proPath;
217 $externalStorage = new ExternalStorage();
218 $external = $externalStorage->getExternalBackups();
219 }
220 }
221
222 $this->removeOldCache();
223
224 return [ 'local' => $manifests, 'external' => $external, 'ongoing' => $ongoing ];
225
226 }
227
228 }
229