Total Complexity | 78 |
Total Lines | 704 |
Duplicated Lines | 0 % |
Changes | 13 | ||
Bugs | 6 | Features | 0 |
Complex classes like Xcloner_Archive 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_Archive, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class Xcloner_Archive extends Tar |
||
38 | { |
||
39 | /** |
||
40 | * Process file size per API request |
||
41 | * @var float|int |
||
42 | */ |
||
43 | private $file_size_per_request_limit = 52428800; //50MB = 52428800; 1MB = 1048576 |
||
44 | /** |
||
45 | * Files count to process per API request |
||
46 | * @var int |
||
47 | */ |
||
48 | private $files_to_process_per_request = 250; //block of 512 bytes |
||
49 | /** |
||
50 | * Compression level, 0-uncompressed, 9-maximum compression |
||
51 | * @var int |
||
52 | */ |
||
53 | private $compression_level = 0; //0-9 , 0 uncompressed |
||
54 | /** |
||
55 | * Split backup size limit |
||
56 | * Create a new backup archive file once the set size is reached |
||
57 | * @var float|int |
||
58 | */ |
||
59 | private $xcloner_split_backup_limit = 2048; //2048MB |
||
60 | /** |
||
61 | * Number of processed bytes |
||
62 | * @var int |
||
63 | */ |
||
64 | private $processed_size_bytes = 0; |
||
65 | |||
66 | /** |
||
67 | * The backup name encryption suffix |
||
68 | * @var string |
||
69 | */ |
||
70 | private $encrypt_suffix = "-enc"; |
||
71 | |||
72 | /** |
||
73 | * Archive name |
||
74 | * @var string |
||
75 | */ |
||
76 | private $archive_name; |
||
77 | /** |
||
78 | * @var Tar |
||
79 | */ |
||
80 | private $backup_archive; |
||
81 | /** |
||
82 | * @var Xcloner_File_System |
||
83 | */ |
||
84 | private $filesystem; |
||
85 | /** |
||
86 | * @var Xcloner_Logger |
||
87 | */ |
||
88 | private $logger; |
||
89 | /** |
||
90 | * @var Xcloner_Settings |
||
91 | */ |
||
92 | private $xcloner_settings; |
||
93 | |||
94 | /** |
||
95 | * [__construct description] |
||
96 | * @param Xcloner $xcloner_container XCloner Container |
||
97 | * @param string $archive_name Achive Name |
||
98 | */ |
||
99 | public function __construct(Xcloner $xcloner_container, $archive_name = "") |
||
100 | { |
||
101 | $this->filesystem = $xcloner_container->get_xcloner_filesystem(); |
||
102 | $this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_archive"); |
||
103 | $this->xcloner_settings = $xcloner_container->get_xcloner_settings(); |
||
104 | |||
105 | if ($value = $this->xcloner_settings->get_xcloner_option('xcloner_size_limit_per_request')) { |
||
|
|||
106 | $this->file_size_per_request_limit = $value * 1024 * 1024; |
||
107 | } //MB |
||
108 | |||
109 | if ($value = $this->xcloner_settings->get_xcloner_option('xcloner_files_to_process_per_request')) { |
||
110 | $this->files_to_process_per_request = $value; |
||
111 | } |
||
112 | |||
113 | if ($value = get_option('xcloner_backup_compression_level')) { |
||
114 | $this->compression_level = $value; |
||
115 | } |
||
116 | |||
117 | if ($value = get_option('xcloner_split_backup_limit')) { |
||
118 | $this->xcloner_split_backup_limit = $value; |
||
119 | } |
||
120 | |||
121 | $this->xcloner_split_backup_limit = $this->xcloner_split_backup_limit * 1024 * 1024; //transform to bytes |
||
122 | |||
123 | if (isset($archive_name) && $archive_name) { |
||
124 | $this->set_archive_name($archive_name); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | /* |
||
129 | * Rename backup archive |
||
130 | * |
||
131 | * @param string $old_name |
||
132 | * @param string $new_name |
||
133 | * |
||
134 | */ |
||
135 | public function rename_archive($old_name, $new_name) |
||
136 | { |
||
137 | $this->logger->info(sprintf("Renaming backup archive %s to %s", $old_name, $new_name)); |
||
138 | $storage_filesystem = $this->filesystem->get_storage_filesystem(); |
||
139 | $storage_filesystem->rename($old_name, $new_name); |
||
140 | } |
||
141 | |||
142 | /* |
||
143 | * |
||
144 | * Set the backup archive name |
||
145 | * |
||
146 | */ |
||
147 | public function set_archive_name($name = "", $part = 0, $encrypt_prefix = false) |
||
148 | { |
||
149 | |||
150 | $this->archive_name = $this->filesystem->process_backup_name($name); |
||
151 | |||
152 | if($encrypt_prefix) { |
||
153 | $this->archive_name .= $this->encrypt_suffix; |
||
154 | } |
||
155 | |||
156 | if ($diff_timestamp_start = $this->filesystem->get_diff_timestamp_start()) { |
||
157 | //$this->archive_name = $this->archive_name."-diff-".date("Y-m-d_H-i",$diff_timestamp_start); |
||
158 | $new_name = $this->archive_name; |
||
159 | |||
160 | if (!stristr($new_name, "-diff")) { |
||
161 | $new_name = $this->archive_name."-diff".date("Y-m-d_H-i", $diff_timestamp_start); |
||
162 | } |
||
163 | |||
164 | $this->archive_name = $new_name; |
||
165 | |||
166 | } |
||
167 | |||
168 | if (isset($part) and $part) { |
||
169 | $new_name = preg_replace('/-part(\d*)/', "-part".$part, $this->archive_name); |
||
170 | if (!stristr($new_name, "-part")) { |
||
171 | $new_name = $this->archive_name."-part".$part; |
||
172 | } |
||
173 | |||
174 | $this->archive_name = $new_name; |
||
175 | } |
||
176 | |||
177 | return $this; |
||
178 | } |
||
179 | |||
180 | /* |
||
181 | * |
||
182 | * Returns the backup archive name |
||
183 | * |
||
184 | * @return string archive name |
||
185 | */ |
||
186 | public function get_archive_name() |
||
187 | { |
||
188 | return $this->archive_name; |
||
189 | } |
||
190 | |||
191 | /* |
||
192 | * |
||
193 | * Returns the multipart naming for the backup archive |
||
194 | * |
||
195 | * @return string multi-part backup name |
||
196 | */ |
||
197 | public function get_archive_name_multipart() |
||
198 | { |
||
199 | $new_name = preg_replace('/-part(\d*)/', "", $this->archive_name); |
||
200 | return $new_name."-multipart".$this->xcloner_settings->get_backup_extension_name(".csv"); |
||
201 | } |
||
202 | |||
203 | /* |
||
204 | * |
||
205 | * Returns the full backup name including extension |
||
206 | * |
||
207 | */ |
||
208 | public function get_archive_name_with_extension() |
||
209 | { |
||
210 | return $this->archive_name.$this->xcloner_settings->get_backup_extension_name(); |
||
211 | } |
||
212 | |||
213 | /* |
||
214 | * |
||
215 | * Send notification error by E-Mail |
||
216 | * |
||
217 | * @param $to |
||
218 | * @param $from |
||
219 | * @param $subject |
||
220 | * @param $backup_name |
||
221 | * @param $params |
||
222 | * @param $error_message |
||
223 | * |
||
224 | * @return bool |
||
225 | */ |
||
226 | |||
227 | /** |
||
228 | * @param string $error_message |
||
229 | */ |
||
230 | public function send_notification_error($to, $from, $subject, $backup_name, $params, $error_message) |
||
231 | { |
||
232 | |||
233 | $body = ""; |
||
234 | $body .= sprintf(__("Backup Site Url: %s"), get_site_url()); |
||
235 | $body .= "<br /><>"; |
||
236 | |||
237 | $body .= sprintf(__("Error Message: %s"), $error_message); |
||
238 | |||
239 | $this->logger->info(sprintf("Sending backup error notification to %s", $to)); |
||
240 | |||
241 | $admin_email = get_option("admin_email"); |
||
242 | |||
243 | $headers = array('Content-Type: text/html; charset=UTF-8'); |
||
244 | |||
245 | if ($admin_email and $from) { |
||
246 | $headers[] = 'From: '.$from.' <'.$admin_email.'>'; |
||
247 | } |
||
248 | |||
249 | $return = wp_mail($to, $subject, $body, $headers); |
||
250 | |||
251 | return $return; |
||
252 | } |
||
253 | |||
254 | /* |
||
255 | * |
||
256 | * Send backup archive notfication by E-Mail |
||
257 | * |
||
258 | * @param $to |
||
259 | * @param $from |
||
260 | * @param $subject |
||
261 | * @param $backup_name |
||
262 | * @param $params |
||
263 | * @param string $error_message |
||
264 | * @param array $additional |
||
265 | * |
||
266 | * @return bool |
||
267 | */ |
||
268 | public function send_notification( |
||
269 | $to, |
||
270 | $from, |
||
271 | $subject, |
||
272 | $backup_name, |
||
273 | $params, |
||
274 | $error_message = "", |
||
275 | $additional = array() |
||
276 | ) { |
||
277 | if (!$from) { |
||
278 | $from = "XCloner Backup"; |
||
279 | } |
||
280 | |||
281 | if (($error_message)) { |
||
282 | return $this->send_notification_error($to, $from, $subject, $backup_name, $params, $error_message); |
||
283 | } |
||
284 | |||
285 | $params = (array)$params; |
||
286 | |||
287 | if (!$subject) { |
||
288 | $subject = sprintf(__("New backup generated %s"), $backup_name); |
||
289 | } |
||
290 | |||
291 | $body = sprintf(__("Generated Backup Size: %s"), size_format($this->filesystem->get_backup_size($backup_name))); |
||
292 | $body .= "<br /><br />"; |
||
293 | |||
294 | if (isset($additional['lines_total'])) { |
||
295 | $body .= sprintf(__("Total files added: %s"), $additional['lines_total']); |
||
296 | $body .= "<br /><br />"; |
||
297 | } |
||
298 | |||
299 | $backup_parts = $this->filesystem->get_multipart_files($backup_name); |
||
300 | |||
301 | if (!$backups_counter = sizeof($backup_parts)) { |
||
302 | $backups_counter = 1; |
||
303 | } |
||
304 | |||
305 | $body .= sprintf(__("Backup Parts: %s"), $backups_counter); |
||
306 | $body .= "<br />"; |
||
307 | |||
308 | if (sizeof($backup_parts)) { |
||
309 | $body .= implode("<br />", $backup_parts); |
||
310 | $body .= "<br />"; |
||
311 | } |
||
312 | |||
313 | $body .= "<br />"; |
||
314 | |||
315 | $body .= sprintf(__("Backup Site Url: %s"), get_site_url()); |
||
316 | $body .= "<br />"; |
||
317 | |||
318 | if (isset($params['backup_params']->backup_comments)) { |
||
319 | $body .= __("Backup Comments: ").$params['backup_params']->backup_comments; |
||
320 | $body .= "<br /><br />"; |
||
321 | } |
||
322 | |||
323 | if ($this->xcloner_settings->get_xcloner_option('xcloner_enable_log')) { |
||
324 | $body .= __("Latest 50 Log Lines: ")."<br />".implode("<br />\n", |
||
325 | $this->logger->getLastDebugLines(50)); |
||
326 | } |
||
327 | |||
328 | $attachments = $this->filesystem->get_backup_attachments(); |
||
329 | |||
330 | $attachments_archive = $this->xcloner_settings->get_xcloner_tmp_path().DS."info.tgz"; |
||
331 | |||
332 | $tar = new Tar(); |
||
333 | $tar->create($attachments_archive); |
||
334 | |||
335 | foreach ($attachments as $key => $file) { |
||
336 | $tar->addFile($file, basename($file)); |
||
337 | } |
||
338 | $tar->close(); |
||
339 | |||
340 | $this->logger->info(sprintf("Sending backup notification to %s", $to)); |
||
341 | |||
342 | $admin_email = get_option("admin_email"); |
||
343 | |||
344 | $headers = array('Content-Type: text/html; charset=UTF-8', 'From: '.$from.' <'.$admin_email.'>'); |
||
345 | |||
346 | $return = wp_mail($to, $subject, $body, $headers, array($attachments_archive)); |
||
347 | |||
348 | return $return; |
||
349 | } |
||
350 | |||
351 | /* |
||
352 | * |
||
353 | * Incremental Backup method |
||
354 | * |
||
355 | */ |
||
356 | public function start_incremental_backup($backup_params, $extra_params, $init) |
||
590 | } |
||
591 | |||
592 | /* |
||
593 | * |
||
594 | * Write multipart file components |
||
595 | * |
||
596 | */ |
||
597 | private function write_multipart_file($path = "") |
||
598 | { |
||
599 | if (!$path) { |
||
600 | $path = $this->get_archive_name_with_extension(); |
||
601 | } |
||
602 | |||
603 | $file = $this->filesystem->get_filesystem("storage_filesystem_append")->getMetadata($path); |
||
604 | //print_r($file_info); |
||
605 | $line = '"'.$file['path'].'","'.$file['timestamp'].'","'.$file['size'].'"'.PHP_EOL; |
||
606 | |||
607 | |||
608 | $this->filesystem->get_filesystem("storage_filesystem_append") |
||
609 | ->write($this->get_archive_name_multipart(), $line); |
||
610 | } |
||
611 | |||
612 | /* |
||
613 | * |
||
614 | * Create a new backup part |
||
615 | * |
||
616 | */ |
||
617 | private function create_new_backup_part($part = 0) |
||
618 | { |
||
619 | //close the backup archive by adding 2*512 blocks of zero bytes |
||
620 | $this->logger->info(sprintf("Closing the backup archive %s with 2*512 zero bytes blocks.", |
||
621 | $this->get_archive_name_with_extension())); |
||
622 | $this->backup_archive->close(); |
||
623 | |||
624 | if (!$part) { |
||
625 | $old_name = $this->get_archive_name_with_extension(); |
||
626 | $this->set_archive_name($this->get_archive_name(), ++$part); |
||
627 | $this->rename_archive($old_name, $this->get_archive_name_with_extension()); |
||
628 | |||
629 | if ($this->filesystem->get_storage_filesystem()->has($this->get_archive_name_multipart())) { |
||
630 | $this->filesystem->get_storage_filesystem()->delete($this->get_archive_name_multipart()); |
||
631 | } |
||
632 | |||
633 | $this->write_multipart_file($this->get_archive_name_with_extension()); |
||
634 | |||
635 | } else { |
||
636 | $this->logger->info(sprintf("Creating new multipart info file %s", |
||
637 | $this->get_archive_name_with_extension())); |
||
638 | $this->write_multipart_file($this->get_archive_name_with_extension()); |
||
639 | } |
||
640 | |||
641 | $this->set_archive_name($this->get_archive_name(), ++$part); |
||
642 | |||
643 | $this->logger->info(sprintf("Creating new backup archive part %s", $this->get_archive_name_with_extension())); |
||
644 | |||
645 | $this->backup_archive = new Tar(); |
||
646 | $this->backup_archive->setCompression($this->compression_level); |
||
647 | $archive_info = $this->filesystem->get_storage_path_file_info($this->get_archive_name_with_extension()); |
||
648 | $this->backup_archive->create($archive_info->getPath().DS.$archive_info->getFilename()); |
||
649 | |||
650 | return array($archive_info, $part); |
||
651 | |||
652 | } |
||
653 | |||
654 | /* |
||
655 | * |
||
656 | * Add file to archive |
||
657 | * |
||
658 | */ |
||
659 | |||
660 | /** |
||
661 | * @param integer $append |
||
662 | */ |
||
663 | public function add_file_to_archive($file_info, $start_at_byte, $byte_limit = 0, $append, $filesystem) |
||
741 | } |
||
742 | |||
743 | /** |
||
744 | * Open a TAR archive and put the file cursor at the end for data appending |
||
745 | * |
||
746 | * If $file is empty, the tar file will be created in memory |
||
747 | * |
||
748 | * @param string $file |
||
749 | * @throws ArchiveIOException |
||
750 | */ |
||
751 | /* |
||
863 |
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.