Total Complexity | 190 |
Total Lines | 1048 |
Duplicated Lines | 0 % |
Changes | 23 | ||
Bugs | 11 | Features | 0 |
Complex classes like Xcloner_File_System often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Xcloner_File_System, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class Xcloner_File_System |
||
38 | { |
||
39 | |||
40 | private $excluded_files = ""; |
||
41 | private $additional_regex_patterns = array(); |
||
42 | private $excluded_files_by_default = array("administrator/backups", "wp-content/backups"); |
||
43 | private $included_files_handler = "backup_files.csv"; |
||
44 | private $temp_dir_handler = ".dir"; |
||
45 | public $filesystem; |
||
46 | public $tmp_filesystem; |
||
47 | public $storage_filesystem; |
||
48 | private $xcloner_container; |
||
49 | private $diff_timestamp_start = ""; |
||
50 | |||
51 | private $logger; |
||
52 | private $start_adapter; |
||
53 | private $tmp_adapter; |
||
54 | private $storage_adapter; |
||
55 | private $xcloner_settings; |
||
56 | private $start_filesystem; |
||
57 | private $tmp_filesystem_append; |
||
58 | private $storage_filesystem_append; |
||
59 | |||
60 | private $files_counter; |
||
61 | private $files_size; |
||
62 | private $last_logged_file; |
||
63 | private $folders_to_process_per_session = 25; |
||
64 | private $backup_archive_extensions = array("tar", "tgz", "tar.gz", "gz", "csv", "encrypted", "decrypted"); |
||
65 | private $backup_name_tags = array('[time]', '[hostname]', '[domain]'); |
||
66 | |||
67 | /** |
||
68 | * Xcloner_File_System constructor. |
||
69 | * @param Xcloner $xcloner_container |
||
70 | * @param string $hash |
||
71 | */ |
||
72 | public function __construct(Xcloner $xcloner_container, $hash = "") |
||
73 | { |
||
74 | $this->xcloner_container = $xcloner_container; |
||
75 | |||
76 | $this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_file_system"); |
||
77 | $this->xcloner_settings = $xcloner_container->get_xcloner_settings(); |
||
78 | |||
79 | try { |
||
80 | |||
81 | $this->start_adapter = new Local($this->xcloner_settings->get_xcloner_start_path(), LOCK_EX, '0001'); |
||
|
|||
82 | $this->start_filesystem = new Filesystem($this->start_adapter, new Config([ |
||
83 | 'disable_asserts' => true, |
||
84 | ])); |
||
85 | |||
86 | $this->tmp_adapter = new Local($this->xcloner_settings->get_xcloner_tmp_path(), LOCK_EX, '0001'); |
||
87 | $this->tmp_filesystem = new Filesystem($this->tmp_adapter, new Config([ |
||
88 | 'disable_asserts' => true, |
||
89 | ])); |
||
90 | $adapter = new Local($this->xcloner_settings->get_xcloner_tmp_path(), LOCK_EX | FILE_APPEND, '0001'); |
||
91 | $this->tmp_filesystem_append = new Filesystem($adapter, new Config([ |
||
92 | 'disable_asserts' => true, |
||
93 | ])); |
||
94 | |||
95 | $adapter = new Local($this->xcloner_settings->get_xcloner_store_path(), LOCK_EX, '0001'); |
||
96 | $this->storage_filesystem = new Filesystem($adapter, new Config([ |
||
97 | 'disable_asserts' => true, |
||
98 | ])); |
||
99 | |||
100 | $this->storage_adapter = new Local($this->xcloner_settings->get_xcloner_store_path(), FILE_APPEND, |
||
101 | '0001'); |
||
102 | $this->storage_filesystem_append = new Filesystem($this->storage_adapter, new Config([ |
||
103 | 'disable_asserts' => true, |
||
104 | ])); |
||
105 | }catch (Exception $e) { |
||
106 | $this->logger->error("Filesystem Initialization Error: ".$e->getMessage()); |
||
107 | } |
||
108 | |||
109 | |||
110 | if ($value = get_option('xcloner_directories_to_scan_per_request')) { |
||
111 | $this->folders_to_process_per_session = $value; |
||
112 | } |
||
113 | |||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Set differential timestamp date |
||
118 | * @param string $timestamp |
||
119 | */ |
||
120 | public function set_diff_timestamp_start($timestamp = "") |
||
121 | { |
||
122 | if ($timestamp) { |
||
123 | $this->logger->info(sprintf("Setting Differential Timestamp To %s", date("Y-m-d", $timestamp)), array( |
||
124 | "FILESYSTEM", |
||
125 | "DIFF" |
||
126 | )); |
||
127 | $this->diff_timestamp_start = $timestamp; |
||
128 | } |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Gets the differential timestamp date |
||
133 | * @return string |
||
134 | */ |
||
135 | public function get_diff_timestamp_start() |
||
136 | { |
||
137 | return $this->diff_timestamp_start; |
||
138 | } |
||
139 | |||
140 | private function get_xcloner_container() |
||
141 | { |
||
142 | return $this->xcloner_container; |
||
143 | } |
||
144 | |||
145 | public function set_hash($hash) |
||
146 | { |
||
147 | $this->xcloner_settings->set_hash($hash); |
||
148 | } |
||
149 | |||
150 | public function get_hash($hash) |
||
151 | { |
||
152 | $this->xcloner_settings->get_hash(); |
||
153 | } |
||
154 | |||
155 | public function get_tmp_filesystem() |
||
156 | { |
||
157 | return $this->tmp_filesystem; |
||
158 | } |
||
159 | |||
160 | public function get_storage_filesystem($remote_storage_selection = "") |
||
161 | { |
||
162 | if ($remote_storage_selection != "") { |
||
163 | $remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage(); |
||
164 | $method = "get_".$remote_storage_selection."_filesystem"; |
||
165 | |||
166 | if (!method_exists($remote_storage, $method)) { |
||
167 | return false; |
||
168 | } |
||
169 | |||
170 | list($adapter, $filesystem) = $remote_storage->$method(); |
||
171 | |||
172 | return $filesystem; |
||
173 | } |
||
174 | |||
175 | return $this->storage_filesystem; |
||
176 | } |
||
177 | |||
178 | public function get_tmp_filesystem_adapter() |
||
179 | { |
||
180 | return $this->tmp_adapter; |
||
181 | } |
||
182 | |||
183 | public function get_tmp_filesystem_append() |
||
184 | { |
||
185 | return $this->tmp_filesystem_append; |
||
186 | } |
||
187 | |||
188 | public function get_start_adapter() |
||
189 | { |
||
190 | return $this->start_adapter; |
||
191 | } |
||
192 | |||
193 | public function get_start_filesystem() |
||
194 | { |
||
195 | return $this->start_filesystem; |
||
196 | } |
||
197 | |||
198 | public function get_logger() |
||
199 | { |
||
200 | return $this->logger; |
||
201 | } |
||
202 | |||
203 | public function get_start_path_file_info($file) |
||
204 | { |
||
205 | $info = $this->getMetadataFull('start_adapter', $file); |
||
206 | |||
207 | return $this->start_filesystem->normalizeFileInfo($info); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * @param string $file |
||
212 | */ |
||
213 | public function get_storage_path_file_info($file) |
||
214 | { |
||
215 | return $this->getMetadataFull('storage_adapter', $file); |
||
216 | } |
||
217 | |||
218 | public function get_included_files_handler($metadata = 0) |
||
219 | { |
||
220 | $path = $this->included_files_handler; |
||
221 | if (!$metadata) { |
||
222 | return $path; |
||
223 | } |
||
224 | |||
225 | $spl_info = $this->getMetadataFull('tmp_adapter', $path); |
||
226 | |||
227 | return $spl_info; |
||
228 | |||
229 | } |
||
230 | |||
231 | public function get_temp_dir_handler() |
||
232 | { |
||
233 | return $this->temp_dir_handler; |
||
234 | } |
||
235 | |||
236 | public function get_latest_backup() |
||
237 | { |
||
238 | $files = $this->get_backup_archives_list(); |
||
239 | |||
240 | if (is_array($files)) { |
||
241 | $this->sort_by($files, "timestamp", "desc"); |
||
242 | } |
||
243 | |||
244 | $new_list = array(); |
||
245 | |||
246 | foreach ($files as $key => $file) { |
||
247 | if (!isset($file['parent'])) { |
||
248 | $new_list[] = ($files[$key]); |
||
249 | } |
||
250 | } |
||
251 | |||
252 | if (isset($new_list[0])) { |
||
253 | return $new_list[0]; |
||
254 | } |
||
255 | } |
||
256 | |||
257 | public function get_latest_backups() |
||
258 | { |
||
259 | $files = $this->get_backup_archives_list(); |
||
260 | |||
261 | if (is_array($files)) { |
||
262 | $this->sort_by($files, "timestamp", "desc"); |
||
263 | } |
||
264 | |||
265 | $new_list = array(); |
||
266 | |||
267 | foreach ($files as $key => $file) { |
||
268 | if (!isset($file['parent'])) { |
||
269 | $new_list[] = ($files[$key]); |
||
270 | } |
||
271 | } |
||
272 | |||
273 | return $new_list; |
||
274 | } |
||
275 | |||
276 | public function get_storage_usage() |
||
277 | { |
||
278 | $files = $this->get_backup_archives_list(); |
||
279 | $total = 0; |
||
280 | |||
281 | if (is_array($files)) { |
||
282 | foreach ($files as $file) { |
||
283 | $total += $file['size']; |
||
284 | } |
||
285 | } |
||
286 | |||
287 | return $total; |
||
288 | } |
||
289 | |||
290 | public function is_part($backup_name) |
||
291 | { |
||
292 | if (stristr($backup_name, "-part")) { |
||
293 | return true; |
||
294 | } |
||
295 | |||
296 | return false; |
||
297 | } |
||
298 | |||
299 | public function is_multipart($backup_name) |
||
306 | } |
||
307 | |||
308 | public function get_backup_size($backup_name) |
||
309 | { |
||
310 | $backup_size = $this->get_storage_filesystem()->getSize($backup_name); |
||
311 | if ($this->is_multipart($backup_name)) { |
||
312 | $backup_parts = $this->get_multipart_files($backup_name); |
||
313 | foreach ($backup_parts as $part_file) { |
||
314 | $backup_size += $this->get_storage_filesystem()->getSize($part_file); |
||
315 | } |
||
316 | } |
||
317 | |||
318 | return $backup_size; |
||
319 | } |
||
320 | |||
321 | public function get_multipart_files($backup_name, $storage_selection = "") |
||
322 | { |
||
323 | $files = array(); |
||
324 | |||
325 | if ($this->is_multipart($backup_name)) { |
||
326 | $lines = explode(PHP_EOL, $this->get_storage_filesystem($storage_selection)->read($backup_name)); |
||
327 | foreach ($lines as $line) { |
||
328 | if ($line) { |
||
329 | $data = str_getcsv($line); |
||
330 | $files[] = $data[0]; |
||
331 | } |
||
332 | } |
||
333 | } |
||
334 | |||
335 | return $files; |
||
336 | } |
||
337 | |||
338 | public function delete_backup_by_name($backup_name, $storage_selection = "") |
||
339 | { |
||
340 | if ($this->is_multipart($backup_name)) { |
||
341 | $lines = explode(PHP_EOL, $this->get_storage_filesystem($storage_selection)->read($backup_name)); |
||
342 | foreach ($lines as $line) { |
||
343 | if ($line) { |
||
344 | $data = str_getcsv($line); |
||
345 | $this->get_storage_filesystem($storage_selection)->delete($data[0]); |
||
346 | } |
||
347 | } |
||
348 | } |
||
349 | |||
350 | if ($this->get_storage_filesystem($storage_selection)->delete($backup_name)) { |
||
351 | $return = true; |
||
352 | } else { |
||
353 | $return = false; |
||
354 | } |
||
355 | |||
356 | return $return; |
||
357 | } |
||
358 | |||
359 | public function getMetadataFull($adapter = "storage_adapter", $path) |
||
360 | { |
||
361 | $location = $this->$adapter->applyPathPrefix($path); |
||
362 | $spl_info = new SplFileInfo($location); |
||
363 | |||
364 | return ($spl_info); |
||
365 | } |
||
366 | |||
367 | |||
368 | public function get_backup_archives_list($storage_selection = "") |
||
369 | { |
||
370 | $list = array(); |
||
371 | |||
372 | |||
373 | if (method_exists($this->get_storage_filesystem($storage_selection), "listContents")) { |
||
374 | $list = $this->get_storage_filesystem($storage_selection)->listContents(); |
||
375 | } |
||
376 | |||
377 | $backup_files = array(); |
||
378 | $parents = array(); |
||
379 | |||
380 | foreach ($list as $file_info) { |
||
381 | if (isset($file_info['extension']) and $file_info['extension'] == "csv") { |
||
382 | $data = array(); |
||
383 | |||
384 | $lines = explode(PHP_EOL, $this->get_storage_filesystem($storage_selection)->read($file_info['path'])); |
||
385 | foreach ($lines as $line) { |
||
386 | if ($line) { |
||
387 | $data = str_getcsv($line); |
||
388 | if (is_array($data)) { |
||
389 | $parents[$data[0]] = $file_info['basename']; |
||
390 | $file_info['childs'][] = $data; |
||
391 | $file_info['size'] += $data[2]; |
||
392 | } |
||
393 | } |
||
394 | } |
||
395 | |||
396 | } |
||
397 | |||
398 | if ($file_info['type'] == 'file' and isset($file_info['extension']) and in_array($file_info['extension'], |
||
399 | $this->backup_archive_extensions)) { |
||
400 | $backup_files[$file_info['path']] = $file_info; |
||
401 | } |
||
402 | } |
||
403 | |||
404 | foreach ($backup_files as $key => $file_info) { |
||
405 | if (!isset($backup_files[$key]['timestamp'])) { |
||
406 | //$backup_files[$key]['timestamp'] = $this->get_storage_filesystem($storage_selection)->getTimestamp($file_info['path']); |
||
407 | } |
||
408 | |||
409 | if (isset($parents[$file_info['basename']])) { |
||
410 | $backup_files[$key]['parent'] = $parents[$file_info['basename']]; |
||
411 | } |
||
412 | } |
||
413 | |||
414 | return $backup_files; |
||
415 | } |
||
416 | |||
417 | public function start_file_recursion($init = 0) |
||
418 | { |
||
419 | if ($init) { |
||
420 | $this->logger->info(sprintf(__("Starting the filesystem scanner on root folder %s"), |
||
421 | $this->xcloner_settings->get_xcloner_start_path())); |
||
422 | $this->do_system_init(); |
||
423 | } |
||
424 | |||
425 | if ($this->tmp_filesystem->has($this->get_temp_dir_handler())) { |
||
426 | //.dir exists, we presume we have files to iterate |
||
427 | $content = $this->tmp_filesystem->read($this->get_temp_dir_handler()); |
||
428 | $files = array_filter(explode("\n", $content)); |
||
429 | $this->tmp_filesystem->delete($this->get_temp_dir_handler()); |
||
430 | |||
431 | $counter = 0; |
||
432 | foreach ($files as $file) { |
||
433 | if ($counter < $this->folders_to_process_per_session) { |
||
434 | $this->build_files_list($file); |
||
435 | $counter++; |
||
436 | } else { |
||
437 | $this->tmp_filesystem_append->write($this->get_temp_dir_handler(), $file."\n"); |
||
438 | } |
||
439 | } |
||
440 | } else { |
||
441 | $this->build_files_list(); |
||
442 | } |
||
443 | |||
444 | if ($this->scan_finished()) { |
||
445 | $metadata_dumpfile = $this->get_tmp_filesystem()->getMetadata("index.html"); |
||
446 | $this->store_file($metadata_dumpfile, 'tmp_filesystem'); |
||
447 | $this->files_counter++; |
||
448 | |||
449 | //adding included dump file to the included files list |
||
450 | if ($this->get_tmp_filesystem()->has($this->get_included_files_handler())) { |
||
451 | $metadata_dumpfile = $this->get_tmp_filesystem()->getMetadata($this->get_included_files_handler()); |
||
452 | $this->store_file($metadata_dumpfile, 'tmp_filesystem'); |
||
453 | $this->files_counter++; |
||
454 | } |
||
455 | |||
456 | //adding a default index.html to the temp xcloner folder |
||
457 | if (!$this->get_tmp_filesystem()->has("index.html")) { |
||
458 | $this->get_tmp_filesystem()->write("index.html", ""); |
||
459 | } |
||
460 | |||
461 | //adding the default log file |
||
462 | if ($this->get_tmp_filesystem()->has($this->xcloner_settings->get_logger_filename(1))) { |
||
463 | $metadata_dumpfile = $this->get_tmp_filesystem()->getMetadata($this->xcloner_settings->get_logger_filename(1)); |
||
464 | $this->store_file($metadata_dumpfile, 'tmp_filesystem'); |
||
465 | $this->files_counter++; |
||
466 | } |
||
467 | |||
468 | return false; |
||
469 | } |
||
470 | |||
471 | return true; |
||
472 | } |
||
473 | |||
474 | public function get_backup_attachments() |
||
495 | } |
||
496 | |||
497 | public function remove_tmp_filesystem() |
||
498 | { |
||
499 | //delete the temporary folder |
||
500 | $this->logger->debug(sprintf("Deleting the temporary storage folder %s", |
||
501 | $this->xcloner_settings->get_xcloner_tmp_path())); |
||
502 | |||
503 | $contents = $this->get_tmp_filesystem()->listContents(); |
||
504 | |||
505 | if (is_array($contents)) { |
||
506 | foreach ($contents as $file_info) { |
||
507 | $this->get_tmp_filesystem()->delete($file_info['path']); |
||
508 | } |
||
509 | } |
||
510 | |||
511 | try { |
||
512 | rmdir($this->xcloner_settings->get_xcloner_tmp_path()); |
||
513 | }catch (Exception $e) { |
||
514 | //silent continue |
||
515 | } |
||
516 | |||
517 | return; |
||
518 | } |
||
519 | |||
520 | public function cleanup_tmp_directories() |
||
521 | { |
||
522 | $this->logger->info(sprintf(("Cleaning up the temporary directories"))); |
||
523 | |||
524 | $adapter = new Local($this->xcloner_settings->get_xcloner_tmp_path(false), LOCK_EX, '0001'); |
||
525 | $tmp_filesystem = new Filesystem($adapter, new Config([ |
||
526 | 'disable_asserts' => true, |
||
527 | ])); |
||
528 | |||
529 | $contents = $tmp_filesystem->listContents(); |
||
530 | |||
531 | foreach ($contents as $file) { |
||
532 | |||
533 | if (preg_match("/.xcloner-(.*)/", $file['path'])) { |
||
534 | if ($file['timestamp'] < strtotime("-1days")) { |
||
535 | $tmp_filesystem->deleteDir($file['path']); |
||
536 | $this->logger->debug(sprintf("Delete temporary directory %s", $file['path'])); |
||
537 | } |
||
538 | } |
||
539 | } |
||
540 | |||
541 | return true; |
||
542 | } |
||
543 | |||
544 | private function do_system_init() |
||
545 | { |
||
546 | $this->files_counter = 0; |
||
547 | |||
548 | if (!$this->storage_filesystem->has("index.html")) { |
||
549 | $this->storage_filesystem->write("index.html", ""); |
||
550 | } |
||
551 | |||
552 | if (!$this->tmp_filesystem->has("index.html")) { |
||
553 | $this->tmp_filesystem->write("index.html", ""); |
||
554 | } |
||
555 | |||
556 | if ($this->tmp_filesystem->has($this->get_included_files_handler())) { |
||
557 | $this->tmp_filesystem->delete($this->get_included_files_handler()); |
||
558 | } |
||
559 | |||
560 | if ($this->tmp_filesystem->has($this->get_temp_dir_handler())) { |
||
561 | $this->tmp_filesystem->delete($this->get_temp_dir_handler()); |
||
562 | } |
||
563 | } |
||
564 | |||
565 | public function get_scanned_files_num() |
||
566 | { |
||
567 | return $this->files_counter; |
||
568 | } |
||
569 | |||
570 | public function get_scanned_files_total_size() |
||
571 | { |
||
572 | return $this->files_size; |
||
573 | } |
||
574 | |||
575 | public function last_logged_file() |
||
576 | { |
||
577 | return $this->last_logged_file; |
||
578 | } |
||
579 | |||
580 | public static function is_regex($regex) |
||
581 | { |
||
582 | return preg_match("/^\^(.*)\$$/i", $regex); |
||
583 | } |
||
584 | |||
585 | public function set_excluded_files($excluded_files = array()) |
||
586 | { |
||
587 | if (!is_array($excluded_files)) { |
||
588 | $excluded_files = array(); |
||
589 | } |
||
590 | |||
591 | foreach ($excluded_files as $excl) { |
||
592 | |||
593 | if ($this->is_regex($excl)) { |
||
594 | $this->additional_regex_patterns[] = $excl; |
||
595 | } |
||
596 | } |
||
597 | |||
598 | $this->excluded_files = array_merge($excluded_files, $this->excluded_files_by_default); |
||
599 | |||
600 | return $this->excluded_files; |
||
601 | } |
||
602 | |||
603 | public function get_excluded_files() |
||
604 | { |
||
605 | return $this->excluded_files_by_default; |
||
606 | } |
||
607 | |||
608 | public function list_directory($path) |
||
609 | { |
||
610 | return $this->start_filesystem->listContents($path); |
||
611 | } |
||
612 | |||
613 | public function build_files_list($folder = "") |
||
614 | { |
||
615 | $this->logger->debug(sprintf(("Building the files system list"))); |
||
616 | |||
617 | //if we start with the root folder(empty value), we initializa the file system |
||
618 | if (!$folder) { |
||
619 | |||
620 | } |
||
621 | |||
622 | try { |
||
623 | |||
624 | $files = $this->start_filesystem->listContents($folder); |
||
625 | foreach ($files as $file) { |
||
626 | if (!is_readable($this->xcloner_settings->get_xcloner_start_path().DS.$file['path'])) { |
||
627 | $this->logger->info(sprintf(__("Excluding %s from the filesystem list, file not readable"), |
||
628 | $file['path']), array( |
||
629 | "FILESYSTEM SCAN", |
||
630 | "NOT READABLE" |
||
631 | )); |
||
632 | } elseif (!$matching_pattern = $this->is_excluded($file)) { |
||
633 | $this->logger->info(sprintf(__("Adding %s to the filesystem list"), $file['path']), array( |
||
634 | "FILESYSTEM SCAN", |
||
635 | "INCLUDE" |
||
636 | )); |
||
637 | $file['visibility'] = $this->start_filesystem->getVisibility($file['path']); |
||
638 | if ($this->store_file($file)) { |
||
639 | $this->files_counter++; |
||
640 | } |
||
641 | if (isset($file['size'])) { |
||
642 | $this->files_size += $file['size']; |
||
643 | } |
||
644 | |||
645 | } else { |
||
646 | $this->logger->info(sprintf(__("Excluding %s from the filesystem list, matching pattern %s"), |
||
647 | $file['path'], $matching_pattern), array( |
||
648 | "FILESYSTEM SCAN", |
||
649 | "EXCLUDE" |
||
650 | )); |
||
651 | } |
||
652 | } |
||
653 | |||
654 | }catch (Exception $e) { |
||
655 | |||
656 | $this->logger->error($e->getMessage()); |
||
657 | |||
658 | } |
||
659 | |||
660 | } |
||
661 | |||
662 | public function estimate_read_write_time() |
||
663 | { |
||
664 | $tmp_file = ".xcloner".substr(md5(time()), 0, 5); |
||
665 | |||
666 | $start_time = microtime(true); |
||
667 | |||
668 | $data = str_repeat(rand(0, 9), 1024 * 1024); //write 1MB data |
||
669 | |||
670 | try { |
||
671 | $this->tmp_filesystem->write($tmp_file, $data); |
||
672 | |||
673 | $end_time = microtime(true) - $start_time; |
||
674 | |||
675 | $return['writing_time'] = $end_time; |
||
676 | |||
677 | $return['reading_time'] = $this->estimate_reading_time($tmp_file); |
||
678 | |||
679 | $this->tmp_filesystem->delete($tmp_file); |
||
680 | |||
681 | }catch (Exception $e) { |
||
682 | |||
683 | $this->logger->error($e->getMessage()); |
||
684 | |||
685 | } |
||
686 | |||
687 | return $return; |
||
688 | } |
||
689 | |||
690 | public function backup_storage_cleanup() |
||
691 | { |
||
692 | $this->logger->info(sprintf(("Cleaning the backup storage on matching rules"))); |
||
693 | |||
694 | $_storage_size = 0; |
||
695 | $_backup_files_list = array(); |
||
696 | |||
697 | //rule date limit |
||
698 | $current_timestamp = strtotime("-".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days')." days"); |
||
699 | |||
700 | $files = $this->storage_filesystem->listContents(); |
||
701 | |||
702 | if (is_array($files)) { |
||
703 | foreach ($files as $file) { |
||
704 | if (isset($file['extension']) and in_array($file['extension'], $this->backup_archive_extensions)) { |
||
705 | $_storage_size += $file['size']; //bytes |
||
706 | $_backup_files_list[] = $file; |
||
707 | } |
||
708 | } |
||
709 | } |
||
710 | |||
711 | |||
712 | $this->sort_by($_backup_files_list, "timestamp", "asc"); |
||
713 | |||
714 | $_backups_counter = sizeof($_backup_files_list); |
||
715 | |||
716 | foreach ($_backup_files_list as $file) { |
||
717 | //processing rule folder capacity |
||
718 | if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_capacity_limit') && |
||
719 | $_storage_size >= ($set_storage_limit = 1024 * 1024 * $this->xcloner_settings->get_xcloner_option('xcloner_cleanup_capacity_limit'))) //bytes |
||
720 | { |
||
721 | $this->storage_filesystem->delete($file['path']); |
||
722 | $_storage_size -= $file['size']; |
||
723 | $this->logger->info("Deleting backup ".$file['path']." matching rule", array( |
||
724 | "STORAGE SIZE LIMIT", |
||
725 | $_storage_size." >= ".$set_storage_limit |
||
726 | )); |
||
727 | } |
||
728 | |||
729 | //processing rule days limit |
||
730 | if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days') && $current_timestamp >= $file['timestamp']) { |
||
731 | $this->storage_filesystem->delete($file['path']); |
||
732 | $this->logger->info("Deleting backup ".$file['path']." matching rule", array( |
||
733 | "RETENTION LIMIT TIMESTAMP", |
||
734 | $file['timestamp']." =< ".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days') |
||
735 | )); |
||
736 | } |
||
737 | |||
738 | //processing backup countert limit |
||
739 | if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives') && $_backups_counter >= $this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives')) { |
||
740 | $this->storage_filesystem->delete($file['path']); |
||
741 | $_backups_counter--; |
||
742 | $this->logger->info("Deleting backup ".$file['path']." matching rule", array( |
||
743 | "BACKUP QUANTITY LIMIT", |
||
744 | $_backups_counter." >= ".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives') |
||
745 | )); |
||
746 | } |
||
747 | |||
748 | |||
749 | } |
||
750 | |||
751 | } |
||
752 | |||
753 | /** |
||
754 | * @param string $tmp_file |
||
755 | */ |
||
756 | public function estimate_reading_time($tmp_file) |
||
757 | { |
||
758 | $this->logger->debug(sprintf(("Estimating file system reading time"))); |
||
759 | |||
760 | $start_time = microtime(true); |
||
761 | |||
762 | if ($this->tmp_filesystem->has($tmp_file)) { |
||
763 | $this->tmp_filesystem->read($tmp_file); |
||
764 | } |
||
765 | |||
766 | $end_time = microtime(true) - $start_time; |
||
767 | |||
768 | return $end_time; |
||
769 | |||
770 | } |
||
771 | |||
772 | public function process_backup_name($name = "", $max_length = 100) |
||
773 | { |
||
774 | if (!$name) { |
||
775 | $name = $this->xcloner_settings->get_default_backup_name(); |
||
776 | } |
||
777 | |||
778 | foreach ($this->backup_name_tags as $tag) { |
||
779 | if ($tag == '[time]') { |
||
780 | $name = str_replace($tag, date("Y-m-d_H-i"), $name); |
||
781 | } elseif ($tag == '[hostname]') { |
||
782 | $name = str_replace($tag, gethostname(), $name); |
||
783 | } elseif ($tag == '[domain]') { |
||
784 | $domain = parse_url(admin_url(), PHP_URL_HOST); |
||
785 | $name = str_replace($tag, $domain, $name); |
||
786 | } |
||
787 | } |
||
788 | |||
789 | if ($max_length) { |
||
790 | $name = substr($name, 0, $max_length); |
||
791 | } |
||
792 | |||
793 | return $name; |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * @param string $field |
||
798 | */ |
||
799 | public function sort_by(&$array, $field, $direction = 'asc') |
||
800 | { |
||
801 | if (strtolower($direction) == "desc" || $direction == SORT_DESC) { |
||
802 | $direction = SORT_DESC; |
||
803 | } else { |
||
804 | $direction = SORT_ASC; |
||
805 | } |
||
806 | |||
807 | $array = $this->array_orderby($array, $field, $direction); |
||
808 | |||
809 | return true; |
||
810 | } |
||
811 | |||
812 | private function array_orderby() |
||
813 | { |
||
814 | $args = func_get_args(); |
||
815 | $data = array_shift($args); |
||
816 | |||
817 | foreach ($args as $n => $field) { |
||
818 | if (is_string($field)) { |
||
819 | $tmp = array(); |
||
820 | foreach ($data as $key => $row) { |
||
821 | if (is_array($row)) { |
||
822 | $tmp[$key] = $row[$field]; |
||
823 | } else { |
||
824 | $tmp[$key] = $row->$field; |
||
825 | } |
||
826 | } |
||
827 | $args[$n] = $tmp; |
||
828 | } |
||
829 | } |
||
830 | $args[] = &$data; |
||
831 | |||
832 | call_user_func_array('array_multisort', $args); |
||
833 | |||
834 | return array_pop($args); |
||
835 | } |
||
836 | |||
837 | private function check_file_diff_time($file) |
||
852 | } |
||
853 | |||
854 | public function is_excluded($file) |
||
855 | { |
||
856 | $this->logger->debug(sprintf(("Checking if %s is excluded"), $file['path'])); |
||
857 | |||
858 | if ($xcloner_exclude_files_larger_than_mb = $this->xcloner_settings->get_xcloner_option('xcloner_exclude_files_larger_than_mb')) { |
||
859 | if (isset($file['size']) && $file['size'] > $this->calc_to_bytes($xcloner_exclude_files_larger_than_mb)) { |
||
860 | return "> ".$xcloner_exclude_files_larger_than_mb."MB"; |
||
861 | } |
||
862 | } |
||
863 | |||
864 | if (!is_array($this->excluded_files) || !sizeof($this->excluded_files)) { |
||
865 | $this->set_excluded_files(); |
||
866 | } |
||
867 | |||
868 | if (is_array($this->excluded_files)) { |
||
869 | foreach ($this->excluded_files as $excluded_file_pattern) { |
||
870 | if ($excluded_file_pattern == "/") { |
||
871 | $needle = "$"; |
||
872 | } else { |
||
873 | $needle = "$".$excluded_file_pattern; |
||
874 | } |
||
875 | |||
876 | if (strstr("$".$file['path'], $needle)) { |
||
877 | return $excluded_file_pattern; |
||
878 | } |
||
879 | } |
||
880 | } |
||
881 | |||
882 | if ($regex = $this->is_excluded_regex($file)) { |
||
883 | return $regex; |
||
884 | } |
||
885 | |||
886 | if ($file['type'] == "file") { |
||
887 | $check_file_diff_timestamp = $this->check_file_diff_time($file); |
||
888 | if ($check_file_diff_timestamp) { |
||
889 | return $check_file_diff_timestamp; |
||
890 | } |
||
891 | } |
||
892 | |||
893 | return false; |
||
894 | } |
||
895 | |||
896 | /*REGEX examples |
||
897 | * |
||
898 | * exclude all except .php file |
||
899 | * PATTERN: ^(.*)\.(.+)$(?<!(php)) |
||
900 | * |
||
901 | * exclude all except .php and .txt |
||
902 | * PATTERN: ^(.*)\.(.+)$(?<!(php|txt))"; |
||
903 | * |
||
904 | * exclude all .svn and .git |
||
905 | * PATTERN: ^(.*)\.(svn|git)(.*)$"; |
||
906 | * |
||
907 | * exclude root directory /test |
||
908 | * PATTERN: "^\/test(.*)$"; |
||
909 | * |
||
910 | * exclude the wp-admin folder |
||
911 | * PATTERN: ^(\/wp-admin)(.*)$"; |
||
912 | * |
||
913 | * exclude the wp-admin, wp-includes and wp-config.php |
||
914 | * PATTERN: ^\/(wp-admin|wp-includes|wp-config.php)(.*)$"; |
||
915 | * |
||
916 | * exclude all .avi files |
||
917 | * PATTERN: ^(.*)$(?<=(avi))"; |
||
918 | * |
||
919 | * exclude all .jpg and gif files |
||
920 | * PATTERN: ^(.*)$(?<=(gif|jpg))"; |
||
921 | * |
||
922 | * exclude all cache folders from wp-content/ |
||
923 | * PATTERN: ^\/wp-content(.*)\/cache($|\/)(.*)"; |
||
924 | * |
||
925 | * exclude the backup folders |
||
926 | * PATTERN: (^|^\/)(wp-content\/backups|administrator\/backups)(.*)$"; |
||
927 | */ |
||
928 | private function is_excluded_regex($file) |
||
966 | } |
||
967 | |||
968 | public function store_file($file, $storage = 'start_filesystem') |
||
969 | { |
||
970 | $this->logger->debug(sprintf("Storing %s in the backup list", $file['path'])); |
||
971 | |||
972 | if (!isset($file['size'])) { |
||
973 | $file['size'] = 0; |
||
974 | } |
||
975 | if (!isset($file['visibility'])) { |
||
976 | $file['visibility'] = "private"; |
||
977 | } |
||
978 | |||
979 | $csv_filename = str_replace('"', '""', $file['path']); |
||
980 | |||
981 | $line = '"'.($csv_filename).'","'.$file['timestamp'].'","'.$file['size'].'","'.$file['visibility'].'","'.$storage.'"'.PHP_EOL; |
||
982 | |||
983 | $this->last_logged_file = $file['path']; |
||
984 | |||
985 | if ($file['type'] == "dir") { |
||
986 | try { |
||
987 | $this->tmp_filesystem_append->write($this->get_temp_dir_handler(), $file['path']."\n"); |
||
988 | }catch (Exception $e) { |
||
989 | $this->logger->error($e->getMessage()); |
||
990 | } |
||
991 | } |
||
992 | |||
993 | if ($this->get_diff_timestamp_start()) { |
||
994 | if ($file['type'] != "file" && $response = $this->check_file_diff_time($file)) { |
||
995 | $this->logger->info(sprintf("Directory %s archiving skipped on differential backup %s", $file['path'], |
||
996 | $response), array( |
||
997 | "FILESYSTEM SCAN", |
||
998 | "DIR DIFF" |
||
999 | )); |
||
1000 | |||
1001 | return false; |
||
1002 | } |
||
1003 | } |
||
1004 | |||
1005 | try { |
||
1006 | if (!$this->tmp_filesystem_append->has($this->get_included_files_handler())) { |
||
1007 | //adding fix for UTF-8 CSV preview |
||
1008 | $start_line = "\xEF\xBB\xBF".'"Filename","Timestamp","Size","Visibility","Storage"'.PHP_EOL; |
||
1009 | $this->tmp_filesystem_append->write($this->get_included_files_handler(), $start_line); |
||
1010 | } |
||
1011 | |||
1012 | $this->tmp_filesystem_append->write($this->get_included_files_handler(), $line); |
||
1013 | |||
1014 | }catch (Exception $e) { |
||
1015 | |||
1016 | $this->logger->error($e->getMessage()); |
||
1017 | } |
||
1018 | |||
1019 | return true; |
||
1020 | } |
||
1021 | |||
1022 | public function get_fileystem_handler() |
||
1023 | { |
||
1024 | return $this; |
||
1025 | } |
||
1026 | |||
1027 | public function get_filesystem($system = "") |
||
1028 | { |
||
1029 | if ($system == "storage_filesystem_append") { |
||
1030 | return $this->storage_filesystem_append; |
||
1031 | } elseif ($system == "tmp_filesystem_append") { |
||
1032 | return $this->tmp_filesystem_append; |
||
1033 | } elseif ($system == "tmp_filesystem") { |
||
1034 | return $this->tmp_filesystem; |
||
1035 | } elseif ($system == "storage_filesystem") { |
||
1036 | return $this->storage_filesystem; |
||
1037 | } else { |
||
1038 | return $this->start_filesystem; |
||
1039 | } |
||
1040 | } |
||
1041 | |||
1042 | public function get_adapter($system) |
||
1043 | { |
||
1044 | if ($system == "tmp_filesystem") { |
||
1045 | return $this->tmp_adapter; |
||
1046 | } elseif ($system == "storage_filesystem") { |
||
1047 | return $this->storage_adapter; |
||
1048 | } else { |
||
1049 | return $this->start_adapter; |
||
1050 | } |
||
1051 | } |
||
1052 | |||
1053 | /** |
||
1054 | * File scan finished |
||
1055 | * Method called when file scan is finished |
||
1056 | * |
||
1057 | * @return bool |
||
1058 | */ |
||
1059 | private function scan_finished() |
||
1060 | { |
||
1061 | if ($this->tmp_filesystem_append->has($this->get_temp_dir_handler()) && |
||
1062 | $this->tmp_filesystem_append->getSize($this->get_temp_dir_handler())) { |
||
1063 | return false; |
||
1064 | } |
||
1065 | |||
1066 | if ($this->tmp_filesystem->has($this->get_temp_dir_handler())) { |
||
1067 | $this->tmp_filesystem->delete($this->get_temp_dir_handler()); |
||
1068 | } |
||
1069 | |||
1070 | $this->logger->debug(sprintf(("File scan finished"))); |
||
1071 | |||
1072 | return true; |
||
1073 | } |
||
1074 | |||
1075 | /** |
||
1076 | * Calculate bytes from MB value |
||
1077 | * |
||
1078 | * @param int $mb_size |
||
1079 | * |
||
1080 | * @return float|int |
||
1081 | */ |
||
1082 | private function calc_to_bytes($mb_size) |
||
1085 | } |
||
1086 | |||
1087 | } |
||
1088 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.