PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.4.6
Backup Migration v1.4.6
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
234 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 if (is_string($md5summary)) {
94 @unlink($md5_file_summary_path);
95 }
96
97 $md5s = [];
98 $cached_md5 = false;
99 if (isset($md5summary[$zip_name])) {
100
101 $md5s = $md5summary[$zip_name];
102 $latest = 0;
103 $latest_md5 = false;
104 for ($i = 0; $i < sizeof($md5s); ++$i) {
105 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $md5s[$i] . '.json';
106 if (file_exists($md5_file_path)) {
107 $ftime = filemtime($md5_file_path);
108 if ($ftime > $latest) {
109 $latest = $ftime;
110 $latest_md5 = $md5s[$i];
111 }
112 }
113 }
114
115 if ($latest_md5 != false) {
116 $cached_md5 = $latest_md5;
117 }
118
119 } else {
120
121 if ($zip_name) $md5summary[$zip_name] = [];
122 else return false;
123
124 }
125
126 if ($cached_md5 != false) {
127 $zip_md5 = $cached_md5;
128 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. $cached_md5 . '.json';
129 } else {
130 $zip_md5 = md5_file($zip_path);
131 $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. $zip_md5 . '.json';
132 if (!in_array($zip_md5, $md5summary[$zip_name])) {
133 $md5summary[$zip_name][] = $zip_md5;
134 }
135 }
136
137 $res = array();
138 if (file_exists($md5_file_path)) {
139 $manifest = json_decode(file_get_contents($md5_file_path));
140 } else {
141 $manifest = $zipper->getZipFileContent($zip_path, 'bmi_backup_manifest.json');
142 }
143
144 if ($manifest) {
145
146 $res[] = $manifest->name . '#%&' . $zip_name;
147 $res[] = $manifest->date;
148 $res[] = $manifest->files;
149 $res[] = $manifest->manifest;
150 $res[] = @filesize($zip_path);
151 if (!isset($manifest->is_locked)) {
152 $manifest->is_locked = $zipper->is_locked_zip($zip_path) ? 'locked' : 'unlocked';
153 $res[] = $manifest->is_locked;
154 } else {
155 $res[] = $manifest->is_locked;
156 }
157 $res[] = $manifest->cron;
158 $res[] = $zip_md5;
159 $res[] = sanitize_text_field($manifest->domain);
160
161 if (!file_exists($md5_file_path)) {
162 $manifest->abspath = $manifest->config->ABSPATH;
163 $manifest->table_prefix = $manifest->config->table_prefix;
164 unset($manifest->config);
165 file_put_contents($md5_file_path, json_encode($manifest));
166 } else touch($md5_file_path);
167
168 $cacheMd5String = "<?php exit; \$x = '" . serialize($md5summary) . "';";
169 file_put_contents($md5_file_summary_path, $cacheMd5String);
170
171 return $res;
172
173 } else return false;
174
175 }
176
177 public function getAvailableBackups() {
178
179 // Require Universal Zip Library
180 require_once BMI_INCLUDES . '/zipper/zipping.php';
181 $zipper = new Zipper();
182
183 // Scan for manifests
184 $manifests = array();
185 $backups = array();
186 $external = array();
187 $ongoing = get_option('bmip_to_be_uploaded', [
188 'current_upload' => [],
189 'queue' => [],
190 'failed' => []
191 ]);
192
193 if (file_exists(BMI_BACKUPS))
194 $backups = $this->scanBackupDir(BMI_BACKUPS);
195
196 // $start = time();
197 // $maxTime = ini_get('max_execution_time');
198
199 for ($i = 0; $i < sizeof($backups); ++$i) {
200
201 // $filestart = time();
202
203 $backup = $backups[$i];
204 if (!file_exists($backup['path'])) continue;
205 $path = $backup['path'] . '/' . $backup['filename'];
206
207 $manifest = $this->getManifestFromZip($path, $zipper);
208 if ($manifest) $manifests[$backup['filename']] = $manifest;
209 else @unlink($path);
210
211 // $fileend = $filestart - time();
212 // $totalTime = $start - time();
213
214 // if ($totalTime + $fileend > $maxTime) break;
215
216 }
217
218 if (defined('BMI_BACKUP_PRO') && defined('BMI_PRO_INC')) {
219 $proPath = BMI_PRO_INC . 'external/controller.php';
220 if (file_exists($proPath)) {
221 require_once $proPath;
222 $externalStorage = new ExternalStorage();
223 $external = $externalStorage->getExternalBackups();
224 }
225 }
226
227 $this->removeOldCache();
228
229 return [ 'local' => $manifests, 'external' => $external, 'ongoing' => $ongoing ];
230
231 }
232
233 }
234