GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Branch dev (231e41)
by Liuta
03:38
created

Xcloner_Api::download_backup_by_name()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 20
nc 2
nop 0
dl 0
loc 31
rs 9.6
c 0
b 0
f 0
1
<?php
2
/**
3
 * XCloner - Backup and Restore backup plugin for Wordpress
4
 *
5
 * class-xcloner-api.php
6
 * @author Liuta Ovidiu <[email protected]>
7
 *
8
 *        This program is free software; you can redistribute it and/or modify
9
 *        it under the terms of the GNU General Public License as published by
10
 *        the Free Software Foundation; either version 2 of the License, or
11
 *        (at your option) any later version.
12
 *
13
 *        This program is distributed in the hope that it will be useful,
14
 *        but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *        GNU General Public License for more details.
17
 *
18
 *        You should have received a copy of the GNU General Public License
19
 *        along with this program; if not, write to the Free Software
20
 *        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21
 *        MA 02110-1301, USA.
22
 *
23
 * @link https://github.com/ovidiul/XCloner-Wordpress
24
 *
25
 * @modified 7/31/18 3:00 PM
26
 *
27
 */
28
29
use League\Flysystem\Config;
30
use League\Flysystem\Filesystem;
31
use League\Flysystem\Util;
32
use League\Flysystem\Adapter\Local;
33
34
use splitbrain\PHPArchive\Tar;
35
use splitbrain\PHPArchive\Zip;
36
use splitbrain\PHPArchive\Archive;
37
use splitbrain\PHPArchive\FileInfo;
38
39
40
/**
41
 * XCloner Api Class
42
 */
43
class Xcloner_Api
44
{
45
46
	private $xcloner_database;
47
	private $xcloner_settings;
48
	private $xcloner_file_system;
49
	private $xcloner_requirements;
50
	private $xcloner_sanitization;
51
	private $xcloner_encryption;
52
	private $xcloner_remote_storage;
53
	private $archive_system;
54
	private $form_params;
55
	private $logger;
56
	private $xcloner_container;
57
58
	/**
59
	 * XCloner_Api construct class
60
	 *
61
	 * @param Xcloner $xcloner_container [description]
62
	 */
63
	public function __construct(Xcloner $xcloner_container)
64
	{
65
		global $wpdb;
66
67
		if (WP_DEBUG) {
0 ignored issues
show
Bug introduced by
The constant WP_DEBUG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
68
			error_reporting(0);
69
		}
70
71
		if (ob_get_length()) {
72
			ob_end_clean();
73
		}
74
		ob_start();
75
76
		$wpdb->show_errors = false;
77
78
		$this->xcloner_container = $xcloner_container;
79
80
		$this->xcloner_settings         = $xcloner_container->get_xcloner_settings();
81
		$this->logger                   = $xcloner_container->get_xcloner_logger()->withName("xcloner_api");
82
		$this->xcloner_file_system      = $xcloner_container->get_xcloner_filesystem();
83
		$this->xcloner_sanitization     = $xcloner_container->get_xcloner_sanitization();
84
		$this->xcloner_requirements     = $xcloner_container->get_xcloner_requirements();
85
		$this->archive_system           = $xcloner_container->get_archive_system();
86
		$this->xcloner_database         = $xcloner_container->get_xcloner_database();
87
		$this->xcloner_scheduler        = $xcloner_container->get_xcloner_scheduler();
0 ignored issues
show
Bug Best Practice introduced by
The property xcloner_scheduler does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
88
		$this->xcloner_encryption       = $xcloner_container->get_xcloner_encryption();
89
		$this->xcloner_remote_storage   = $xcloner_container->get_xcloner_remote_storage();
90
91
		if (isset($_POST['API_ID'])) {
92
			$this->logger->info("Processing ajax request ID " . substr($this->xcloner_sanitization->sanitize_input_as_string($_POST['API_ID']),
93
					0, 15));
94
		}
95
96
	}
97
98
	/**
99
	 * Get XCloner Container
100
	 * @return XCloner return the XCloner container
101
	 */
102
	public function get_xcloner_container()
103
	{
104
		return $this->xcloner_container;
105
	}
106
107
	/**
108
	 * Check if user has access to this class
109
	 * @return die() returns die() if user is not allowed
0 ignored issues
show
Bug introduced by
The type die was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
110
	 * @link http://www.wordpress.org
111
	 */
112
	private function check_access()
113
	{
114
		if (function_exists('current_user_can') && !current_user_can('manage_options')) {
115
			die("Not allowed access here!");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
116
		}
117
	}
118
119
	/**
120
	 * Initialize the database connection
121
	 */
122
	public function init_db()
123
	{
124
		return;
125
126
127
		$data['dbHostname'] = $this->xcloner_settings->get_db_hostname();
0 ignored issues
show
Unused Code introduced by
$data['dbHostname'] = $t...ings->get_db_hostname() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
128
		$data['dbUsername'] = $this->xcloner_settings->get_db_username();
129
		$data['dbPassword'] = $this->xcloner_settings->get_db_password();
130
		$data['dbDatabase'] = $this->xcloner_settings->get_db_database();
131
132
133
		$data['recordsPerSession'] = $this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request');
134
		$data['TEMP_DBPROCESS_FILE'] = $this->xcloner_settings->get_xcloner_tmp_path() . DS . ".database";
135
		$data['TEMP_DUMP_FILE'] = $this->xcloner_settings->get_xcloner_tmp_path() . DS . "database-sql.sql";
136
137
		try {
138
			$this->xcloner_database->init($data);
139
140
		} catch (Exception $e) {
141
142
			$this->send_response($e->getMessage());
143
			$this->logger->error($e->getMessage());
144
145
		}
146
147
		return $this->xcloner_database;
148
149
150
	}
151
152
	/*
153
     * Save Schedule API
154
     */
155
	public function save_schedule()
156
	{
157
		global $wpdb;
158
159
		$this->check_access();
160
161
		$scheduler = $this->xcloner_scheduler;
162
		$params = array();
163
		$schedule = array();
164
		$response = array();
165
166
		if (isset($_POST['data'])) {
167
			$params = json_decode(stripslashes($_POST['data']));
168
		}
169
170
		$this->process_params($params);
171
172
		if (isset($_POST['id'])) {
173
174
			$this->form_params['backup_params']['backup_name'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['backup_name']);
175
			$this->form_params['backup_params']['email_notification'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['email_notification']);
176
			if ($_POST['diff_start_date']) {
177
				$this->form_params['backup_params']['diff_start_date'] = strtotime($this->xcloner_sanitization->sanitize_input_as_string($_POST['diff_start_date']));
178
			} else {
179
				$this->form_params['backup_params']['diff_start_date'] = "";
180
			}
181
			$this->form_params['backup_params']['schedule_name'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['schedule_name']);
182
			$this->form_params['backup_params']['backup_encrypt'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['backup_encrypt']);
183
			$this->form_params['backup_params']['start_at'] = strtotime($_POST['schedule_start_date']);
184
			$this->form_params['backup_params']['schedule_frequency'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['schedule_frequency']);
185
			$this->form_params['backup_params']['schedule_storage'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['schedule_storage']);
186
			$this->form_params['database'] = (stripslashes($this->xcloner_sanitization->sanitize_input_as_raw($_POST['table_params'])));
187
			$this->form_params['excluded_files'] = (stripslashes($this->xcloner_sanitization->sanitize_input_as_raw($_POST['excluded_files'])));
188
189
			//$this->form_params['backup_params']['backup_type'] = $this->xcloner_sanitization->sanitize_input_as_string($_POST['backup_type']);
190
191
			$tables = explode(PHP_EOL, $this->form_params['database']);
192
			$return = array();
193
194
			foreach ($tables as $table) {
195
				$table = str_replace("\r", "", $table);
196
				$data = explode(".", $table);
197
				if (isset($data[1])) {
198
					$return[$data[0]][] = $data[1];
199
				}
200
			}
201
202
			$this->form_params['database'] = ($return);
203
204
			$excluded_files = explode(PHP_EOL, $this->form_params['excluded_files']);
205
			$return = array();
206
207
			foreach ($excluded_files as $file) {
208
				$file = str_replace("\r", "", $file);
209
				if ($file) {
210
					$return[] = $file;
211
				}
212
			}
213
214
			$this->form_params['excluded_files'] = ($return);
215
216
			$schedule['start_at'] = $this->form_params['backup_params']['start_at'];
217
218
			if (!isset($_POST['status'])) {
219
				$schedule['status'] = 0;
220
			} else {
221
				$schedule['status'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['status']);
222
			}
223
		} else {
224
225
			$schedule['status'] = 1;
226
			$schedule['start_at'] = strtotime($this->form_params['backup_params']['schedule_start_date'] .
227
				" " . $this->form_params['backup_params']['schedule_start_time']);
228
229
			if ($schedule['start_at'] <= time()) {
230
				$schedule['start_at'] = "";
231
			}
232
		}
233
234
		if (!$schedule['start_at']) {
235
			$schedule['start_at'] = date('Y-m-d H:i:s', time());
236
		} else {
237
			$schedule['start_at'] = date('Y-m-d H:i:s',
238
				$schedule['start_at'] - (get_option('gmt_offset') * HOUR_IN_SECONDS));
0 ignored issues
show
Bug introduced by
The constant HOUR_IN_SECONDS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

238
				$schedule['start_at'] - (/** @scrutinizer ignore-call */ get_option('gmt_offset') * HOUR_IN_SECONDS));
Loading history...
239
		}
240
241
		$schedule['name'] = $this->form_params['backup_params']['schedule_name'];
242
		$schedule['recurrence'] = $this->form_params['backup_params']['schedule_frequency'];
243
		if (!isset($this->form_params['backup_params']['schedule_storage'])) {
244
			$this->form_params['backup_params']['schedule_storage'] = "";
245
		}
246
		$schedule['remote_storage'] = $this->form_params['backup_params']['schedule_storage'];
247
		//$schedule['backup_type'] = $this->form_params['backup_params']['backup_type'];
248
		$schedule['params'] = json_encode($this->form_params);
249
250
		if (!isset($_POST['id'])) {
251
			$wpdb->insert(
252
				$wpdb->prefix . 'xcloner_scheduler',
253
				$schedule,
254
				array(
255
					'%s',
256
					'%s'
257
				)
258
			);
259
		} else {
260
			$wpdb->update(
261
				$wpdb->prefix . 'xcloner_scheduler',
262
				$schedule,
263
				array('id' => $_POST['id']),
264
				array(
265
					'%s',
266
					'%s'
267
				)
268
			);
269
		}
270
		if (isset($_POST['id'])) {
271
			$scheduler->update_cron_hook($_POST['id']);
272
		}
273
274
		if ($wpdb->last_error) {
275
			$response['error'] = 1;
276
			$response['error_message'] = $wpdb->last_error/*."--".$wpdb->last_query*/
277
			;
278
279
		}
280
281
		$scheduler->update_wp_cron_hooks();
282
		$response['finished'] = 1;
283
284
		$this->send_response($response);
285
	}
286
287
	/*
288
     *
289
     * Backup Files API
290
     *
291
     */
292
	public function backup_files()
293
	{
294
		$this->check_access();
295
296
		$params = json_decode(stripslashes($_POST['data']));
297
298
		$init = (int)$_POST['init'];
299
300
		if ($params === null) {
301
			die('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
302
		}
303
304
		$this->process_params($params);
305
306
		$return['finished'] = 1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
307
308
		//$return = $this->archive_system->start_incremental_backup($this->form_params['backup_params'], $this->form_params['extra'], $init);
309
		try {
310
			$return = $this->archive_system->start_incremental_backup($this->form_params['backup_params'],
311
				$this->form_params['extra'], $init);
312
		} catch (Exception $e) {
313
			$return = array();
314
			$return['error'] = true;
315
			$return['status'] = 500;
316
			$return['error_message'] = $e->getMessage();
317
318
			return $this->send_response($return, $hash = 1);
319
		}
320
321
		if ($return['finished']) {
322
			$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_with_extension();
323
			if ($this->xcloner_file_system->is_part($this->archive_system->get_archive_name_with_extension())) {
324
				$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_multipart();
325
			}
326
		}
327
328
		$data = $return;
329
330
		//check if backup is finished
331
		if ($return['finished']) {
332
			if (isset($this->form_params['backup_params']['email_notification']) and $to = $this->form_params['backup_params']['email_notification']) {
333
				try {
334
					$from = "";
335
					$subject = "";
336
					$additional['lines_total'] = $return['extra']['lines_total'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$additional was never initialized. Although not strictly required by PHP, it is generally a good practice to add $additional = array(); before regardless.
Loading history...
337
					$this->archive_system->send_notification($to, $from, $subject, $return['extra']['backup_parent'],
338
						$this->form_params, "", $additional);
339
				} catch (Exception $e) {
340
					$this->logger->error($e->getMessage());
341
				}
342
			}
343
			$this->xcloner_file_system->remove_tmp_filesystem();
344
		}
345
346
		return $this->send_response($data, $hash = 1);
347
	}
348
349
	/*
350
     *
351
     * Backup Database API
352
     *
353
     */
354
	public function backup_database()
355
	{
356
		$this->check_access();
357
358
		$params = json_decode(stripslashes($_POST['data']));
359
360
		$init = (int)$_POST['init'];
361
362
		if ($params === null) {
363
			die('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
364
		}
365
366
		$this->process_params($params);
367
368
		//$xcloner_database = $this->init_db();
369
		$return = $this->xcloner_database->start_database_recursion($this->form_params['database'],
370
			$this->form_params['extra'], $init);
371
372
		if (isset($return['error']) and $return['error']) {
373
			$data['finished'] = 1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
374
		} else {
375
			$data['finished'] = $return['finished'];
376
		}
377
378
		$data['extra'] = $return;
379
380
		return $this->send_response($data, $hash = 1);
381
	}
382
383
	/*
384
     *
385
     * Scan Filesystem API
386
     *
387
     */
388
	public function scan_filesystem()
389
	{
390
		$this->check_access();
391
392
		$params = json_decode(stripslashes($_POST['data']));
393
		$init = (int)$_POST['init'];
394
395
		if ($params === null) {
396
			die('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
397
		}
398
399
		$hash = $this->process_params($params);
0 ignored issues
show
Unused Code introduced by
The assignment to $hash is dead and can be removed.
Loading history...
400
401
		$this->xcloner_file_system->set_excluded_files($this->form_params['excluded_files']);
402
403
		$return = $this->xcloner_file_system->start_file_recursion($init);
404
405
		$data["finished"] = !$return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
406
		$data["total_files_num"] = $this->xcloner_file_system->get_scanned_files_num();
407
		$data["last_logged_file"] = $this->xcloner_file_system->last_logged_file();
408
		$data["total_files_size"] = sprintf("%.2f",
409
			$this->xcloner_file_system->get_scanned_files_total_size() / (1024 * 1024));
410
411
		return $this->send_response($data, $hash = 1);
412
	}
413
414
	/*
415
     *
416
     * Process params sent by the user
417
     *
418
     */
419
	private function process_params($params)
420
	{
421
		if (isset($params->hash)) {
422
			$this->xcloner_settings->set_hash($params->hash);
423
		}
424
425
		$this->form_params['extra'] = array();
426
		$this->form_params['backup_params'] = array();
427
428
		$this->form_params['database'] = array();
429
430
		if (isset($params->backup_params)) {
431
			foreach ($params->backup_params as $param) {
432
				$this->form_params['backup_params'][$param->name] = $this->xcloner_sanitization->sanitize_input_as_string($param->value);
433
				$this->logger->debug("Adding form parameter " . $param->name . "." . $param->value . "\n", array(
434
					'POST',
435
					'fields filter'
436
				));
437
			}
438
		}
439
440
		$this->form_params['database'] = array();
441
442
		if (isset($params->table_params)) {
443
			foreach ($params->table_params as $param) {
444
				$this->form_params['database'][$param->parent][] = $this->xcloner_sanitization->sanitize_input_as_raw($param->id);
445
				$this->logger->debug("Adding database filter " . $param->parent . "." . $param->id . "\n", array(
446
					'POST',
447
					'database filter'
448
				));
449
			}
450
		}
451
452
		$this->form_params['excluded_files'] = array();
453
		if (isset($params->files_params)) {
454
			foreach ($params->files_params as $param) {
455
				$this->form_params['excluded_files'][] = $this->xcloner_sanitization->sanitize_input_as_relative_path($param->id);
456
			}
457
458
			$unique_exclude_files = array();
459
460
			foreach ($params->files_params as $key => $param) {
461
				if (!in_array($param->parent, $this->form_params['excluded_files'])) {
462
					//$this->form_params['excluded_files'][] = $this->xcloner_sanitization->sanitize_input_as_relative_path($param->id);
463
					$unique_exclude_files[] = $param->id;
464
					$this->logger->debug("Adding file filter " . $param->id . "\n", array(
465
						'POST',
466
						'exclude files filter'
467
					));
468
				}
469
			}
470
			$this->form_params['excluded_files'] = (array)$unique_exclude_files;
471
472
		}
473
474
		//$this->form_params['excluded_files'] =  array_merge($this->form_params['excluded_files'], $this->exclude_files_by_default);
475
476
		if (isset($params->extra)) {
477
			foreach ($params->extra as $key => $value) {
478
				$this->form_params['extra'][$key] = $this->xcloner_sanitization->sanitize_input_as_raw($value);
479
			}
480
		}
481
482
		if (isset($this->form_params['backup_params']['diff_start_date']) and $this->form_params['backup_params']['diff_start_date']) {
483
			$this->form_params['backup_params']['diff_start_date'] = strtotime($this->form_params['backup_params']['diff_start_date']);
484
			$this->xcloner_file_system->set_diff_timestamp_start($this->form_params['backup_params']['diff_start_date']);
485
		}
486
487
		return $this->xcloner_settings->get_hash();
488
	}
489
490
	/*
491
     *
492
     * Get file list for tree view API
493
     *
494
     */
495
	public function get_file_system_action()
496
	{
497
		$this->check_access();
498
499
		$folder = $this->xcloner_sanitization->sanitize_input_as_relative_path($_POST['id']);
500
501
		$data = array();
502
503
		if ($folder == "#") {
504
505
			$folder = "/";
506
			$data[] = array(
507
				'id' => $folder,
508
				'parent' => '#',
509
				'text' => $this->xcloner_settings->get_xcloner_start_path(),
510
				//'children' => true,
511
				'state' => array('selected' => false, 'opened' => true),
512
				'icon' => plugin_dir_url(dirname(__FILE__)) . "/admin/assets/file-icon-root.png"
0 ignored issues
show
Bug introduced by
The function plugin_dir_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

512
				'icon' => /** @scrutinizer ignore-call */ plugin_dir_url(dirname(__FILE__)) . "/admin/assets/file-icon-root.png"
Loading history...
513
			);
514
		}
515
516
		try {
517
			$files = $this->xcloner_file_system->list_directory($folder);
518
		} catch (Exception $e) {
519
520
			print $e->getMessage();
521
			$this->logger->error($e->getMessage());
522
523
			return;
524
		}
525
526
		$type = array();
527
		foreach ($files as $key => $row) {
528
			$type[$key] = $row['type'];
529
		}
530
		array_multisort($type, SORT_ASC, $files);
531
532
		foreach ($files as $file) {
533
			$children = false;
534
			$text = $file['basename'];
535
536
			if ($file['type'] == "dir") {
537
				$children = true;
538
			} else {
539
				$text .= " (" . $this->xcloner_requirements->file_format_size($file['size']) . ")";
540
			}
541
542
			if ($this->xcloner_file_system->is_excluded($file)) {
543
				$selected = true;
544
			} else {
545
				$selected = false;
546
			}
547
548
			$data[] = array(
549
				'id' => $file['path'],
550
				'parent' => $folder,
551
				'text' => $text,
552
				//'title' => "test",
553
				'children' => $children,
554
				'state' => array('selected' => $selected, 'opened' => false, "checkbox_disabled" => $selected),
555
				'icon' => plugin_dir_url(dirname(__FILE__)) . "/admin/assets/file-icon-" . strtolower(substr($file['type'],
556
						0, 1)) . ".png"
557
			);
558
		}
559
560
561
		return $this->send_response($data, 0);
562
	}
563
564
	/*
565
     *
566
     * Get databases/tables list for frontend tree display API
567
     *
568
     */
569
	public function get_database_tables_action()
570
	{
571
		$this->check_access();
572
573
		$database = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['id']);
574
575
		$data = array();
576
577
		$xcloner_backup_only_wp_tables = $this->xcloner_settings->get_xcloner_option('xcloner_backup_only_wp_tables');
578
579
		if ($database == "#") {
580
			try {
581
				$return = $this->xcloner_database->get_all_databases();
582
			} catch (Exception $e) {
583
				$this->logger->error($e->getMessage());
584
			}
585
586
			foreach ($return as $database) {
587
				if ($xcloner_backup_only_wp_tables and $database['name'] != $this->xcloner_settings->get_db_database()) {
588
					continue;
589
				}
590
591
				$state = array();
592
593
				if ($database['name'] == $this->xcloner_settings->get_db_database()) {
594
					$state['selected'] = true;
595
					if ($database['num_tables'] < 25) {
596
						$state['opened'] = false;
597
					}
598
				}
599
600
				$data[] = array(
601
					'id' => $database['name'],
602
					'parent' => '#',
603
					'text' => $database['name'] . " (" . (int)$database['num_tables'] . ")",
604
					'children' => true,
605
					'state' => $state,
606
					'icon' => plugin_dir_url(dirname(__FILE__)) . "/admin/assets/database-icon.png"
0 ignored issues
show
Bug introduced by
The function plugin_dir_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

606
					'icon' => /** @scrutinizer ignore-call */ plugin_dir_url(dirname(__FILE__)) . "/admin/assets/database-icon.png"
Loading history...
607
				);
608
			}
609
610
		} else {
611
612
			try {
613
				$return = $this->xcloner_database->list_tables($database, "", 1);
614
			} catch (Exception $e) {
615
				$this->logger->error($e->getMessage());
616
			}
617
618
			foreach ($return as $table) {
619
				$state = array();
620
621
				if ($xcloner_backup_only_wp_tables and !stristr($table['name'],
622
						$this->xcloner_settings->get_table_prefix())) {
623
					continue;
624
				}
625
626
				if (isset($database['name']) and $database['name'] == $this->xcloner_settings->get_db_database()) {
627
					$state = array('selected' => true);
628
				}
629
630
				$data[] = array(
631
					'id' => $database . "." . $table['name'],
632
					'parent' => $database,
633
					'text' => $table['name'] . " (" . (int)$table['records'] . ")",
634
					'children' => false,
635
					'state' => $state,
636
					'icon' => plugin_dir_url(dirname(__FILE__)) . "/admin/assets/table-icon.png"
637
				);
638
			}
639
		}
640
641
		return $this->send_response($data, 0);
642
	}
643
644
	/*
645
     *
646
     * Get schedule by id API
647
     *
648
     */
649
	public function get_schedule_by_id()
650
	{
651
		$this->check_access();
652
653
		$schedule_id = $this->xcloner_sanitization->sanitize_input_as_int($_GET['id']);
654
		$scheduler = $this->xcloner_scheduler;
655
		$data = $scheduler->get_schedule_by_id($schedule_id);
656
657
		$data['start_at'] = date("Y-m-d H:i",
658
			strtotime($data['start_at']) + (get_option('gmt_offset') * HOUR_IN_SECONDS));
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

658
			strtotime($data['start_at']) + (/** @scrutinizer ignore-call */ get_option('gmt_offset') * HOUR_IN_SECONDS));
Loading history...
Bug introduced by
The constant HOUR_IN_SECONDS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
659
		if (isset($data['backup_params']->diff_start_date) && $data['backup_params']->diff_start_date != "") {
660
			$data['backup_params']->diff_start_date = date("Y-m-d", ($data['backup_params']->diff_start_date));
661
		}
662
663
		return $this->send_response($data);
664
	}
665
666
	/*
667
     *
668
     * Get Schedule list API
669
     *
670
     */
671
	public function get_scheduler_list()
672
	{
673
		$this->check_access();
674
675
		$scheduler = $this->xcloner_scheduler;
676
		$data = $scheduler->get_scheduler_list();
677
		$return['data'] = array();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
678
679
		foreach ($data as $res) {
680
			$action = "<a href=\"#" . $res->id . "\" class=\"edit\" title='Edit'> <i class=\"material-icons \">edit</i></a>
681
					<a href=\"#" . $res->id . "\" class=\"delete\" title='Delete'><i class=\"material-icons  \">delete</i></a>";
682
			if ($res->status) {
683
				$status = '<i class="material-icons active status">timer</i>';
684
			} else {
685
				$status = '<i class="material-icons status inactive">timer_off</i>';
686
			}
687
688
			$next_run_time = wp_next_scheduled('xcloner_scheduler_' . $res->id, array($res->id));
0 ignored issues
show
Bug introduced by
The function wp_next_scheduled was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

688
			$next_run_time = /** @scrutinizer ignore-call */ wp_next_scheduled('xcloner_scheduler_' . $res->id, array($res->id));
Loading history...
689
690
			$next_run = date(get_option('date_format') . " " . get_option('time_format'), $next_run_time);
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

690
			$next_run = date(/** @scrutinizer ignore-call */ get_option('date_format') . " " . get_option('time_format'), $next_run_time);
Loading history...
691
692
			$remote_storage = $res->remote_storage;
693
694
			if (!$next_run_time >= time()) {
695
				$next_run = " ";
696
			}
697
698
			if (trim($next_run)) {
699
				$date_text = date(get_option('date_format') . " " . get_option('time_format'),
700
					$next_run_time + (get_option('gmt_offset') * HOUR_IN_SECONDS));
0 ignored issues
show
Bug introduced by
The constant HOUR_IN_SECONDS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
701
702
				if ($next_run_time >= time()) {
703
					$next_run = "in " . human_time_diff($next_run_time, time());
0 ignored issues
show
Bug introduced by
The function human_time_diff was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

703
					$next_run = "in " . /** @scrutinizer ignore-call */ human_time_diff($next_run_time, time());
Loading history...
704
				} else {
705
					$next_run = __("executed", 'xcloner-backup-and-restore');
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

705
					$next_run = /** @scrutinizer ignore-call */ __("executed", 'xcloner-backup-and-restore');
Loading history...
706
				}
707
708
				$next_run = "<a href='#' title='" . $date_text . "'>" . $next_run . "</a>";
709
				//$next_run .=" ($date_text)";
710
			}
711
712
			$backup_text = "";
713
			$backup_size = "";
714
			$backup_time = "";
715
716
			if ($res->last_backup) {
717
				if ($this->xcloner_file_system->get_storage_filesystem()->has($res->last_backup)) {
718
					$metadata = $this->xcloner_file_system->get_storage_filesystem()->getMetadata($res->last_backup);
719
					$backup_size = size_format($this->xcloner_file_system->get_backup_size($res->last_backup));
0 ignored issues
show
Bug introduced by
The function size_format was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

719
					$backup_size = /** @scrutinizer ignore-call */ size_format($this->xcloner_file_system->get_backup_size($res->last_backup));
Loading history...
720
					$backup_time = date(get_option('date_format') . " " . get_option('time_format'),
721
						$metadata['timestamp'] + (get_option('gmt_offset') * HOUR_IN_SECONDS));
722
				}
723
724
				$backup_text = "<span title='" . $backup_time . "' class='shorten_string'>" . $res->last_backup . " (" . $backup_size . ")</span>";
725
			}
726
727
			$schedules = wp_get_schedules();
0 ignored issues
show
Bug introduced by
The function wp_get_schedules was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

727
			$schedules = /** @scrutinizer ignore-call */ wp_get_schedules();
Loading history...
728
729
			if (isset($schedules[$res->recurrence])) {
730
				$res->recurrence = $schedules[$res->recurrence]['display'];
731
			}
732
733
			$return['data'][] = array(
734
				$res->id,
735
				$res->name,
736
				$res->recurrence,/*$res->start_at,*/
737
				$next_run,
738
				$remote_storage,
739
				$backup_text,
740
				$status,
741
				$action
742
			);
743
		}
744
745
		return $this->send_response($return, 0);
746
	}
747
748
	/*
749
     *
750
     * Delete Schedule by ID API
751
     *
752
     */
753
	public function delete_schedule_by_id()
754
	{
755
		$this->check_access();
756
757
		$schedule_id = $this->xcloner_sanitization->sanitize_input_as_int($_GET['id']);
758
		$scheduler = $this->xcloner_scheduler;
759
		$data['finished'] = $scheduler->delete_schedule_by_id($schedule_id);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
760
761
		return $this->send_response($data);
762
	}
763
764
	/*
765
     *
766
     * Delete backup by name from the storage path
767
     *
768
     */
769
	public function delete_backup_by_name()
770
	{
771
		$this->check_access();
772
773
		$backup_name = $this->xcloner_sanitization->sanitize_input_as_string($_POST['name']);
774
		$storage_selection = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_selection']);
775
776
		$data['finished'] = $this->xcloner_file_system->delete_backup_by_name($backup_name, $storage_selection);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
777
778
		return $this->send_response($data);
779
	}
780
781
	/**
782
	 *  API Incremental Backup Encryption Method
783
	 */
784
	public function backup_encryption()
785
	{
786
		$this->check_access();
787
788
		$backup_parts = array();
789
		$return = array();
790
791
792
		if (isset($_POST['data'])) {
793
			$params = json_decode(stripslashes($_POST['data']));
794
795
			$this->process_params($params);
796
			$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($this->form_params['extra']['backup_parent']);
797
798
			if(isset($this->form_params['extra']['start'])) {
799
				$start = $this->xcloner_sanitization->sanitize_input_as_int($this->form_params['extra']['start']);
800
			}else{
801
				$start = 0;
802
			}
803
804
			if(isset($this->form_params['extra']['iv'])) {
805
				$iv = $this->xcloner_sanitization->sanitize_input_as_raw($this->form_params['extra']['iv']);
806
			}else{
807
				$iv = "";
808
			}
809
810
			if(isset($this->form_params['extra']['part'])) {
811
				$return['part'] = (int)$this->xcloner_sanitization->sanitize_input_as_int($this->form_params['extra']['part']);
812
			}else{
813
				$return['part'] = 0;
814
			}
815
816
		}else{
817
			$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
818
			$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
819
			$iv = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['iv']);
820
			$return['part'] = (int)$this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
821
		}
822
823
		$backup_file = $source_backup_file;
824
825
		if ($this->xcloner_file_system->is_multipart($backup_file)) {
826
			$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
827
			$backup_file = $backup_parts[$return['part']];
828
		}
829
830
		$return['processing_file'] = $backup_file;
831
		$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path() . DS . $backup_file);
832
833
		try {
834
			$this->logger->info(json_encode($_POST));
835
			$this->logger->info($iv);
836
			$return = array_merge($return,
837
				$this->xcloner_encryption->encrypt_file($backup_file, "", "", $start, base64_decode($iv)));
838
		}catch(\Exception $e){
839
			$return['error'] = true;
840
			$return['message'] = $e->getMessage();
841
			$return['error_message'] = $e->getMessage();
842
		}
843
844
		//echo strlen($return['iv']);exit;
845
846
		if($return['finished']) {
847
			if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
848
				$return['start'] = 0;
849
850
				++$return['part'];
851
852
				if ($return['part'] < sizeof($backup_parts)) {
853
					$return['finished'] = 0;
854
				}
855
856
			}
857
		}
858
859
		if (isset($_POST['data'])) {
860
			$return['extra'] = array_merge($this->form_params['extra'],  $return);
861
		}
862
863
		$this->send_response($return, 0);
864
	}
865
866
	/**
867
	 *  API Incremental Backup Decryption Method
868
	 */
869
	public function backup_decryption()
870
	{
871
		$this->check_access();
872
873
		$backup_parts = array();
874
		$return = array();
875
876
		$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
877
		$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
878
		$iv = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['iv']);
879
		$decryption_key = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['decryption_key']);;
880
		$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
881
882
		$backup_file = $source_backup_file;
883
884
		if ($this->xcloner_file_system->is_multipart($backup_file)) {
885
			$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
886
			$backup_file = $backup_parts[$return['part']];
887
		}
888
889
		$return['processing_file'] = $backup_file;
890
		$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path() . DS . $backup_file);
891
892
		try {
893
			$return = array_merge($return,
894
				$this->xcloner_encryption->decrypt_file($backup_file, "", $decryption_key, $start, base64_decode($iv)));
895
		}catch(\Exception $e){
896
			$return['error'] = true;
897
			$return['message'] = $e->getMessage();
898
		}
899
900
		if($return['finished']) {
901
			if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
902
				$return['start'] = 0;
903
904
				++$return['part'];
905
906
				if ($return['part'] < sizeof($backup_parts)) {
907
					$return['finished'] = 0;
908
				}
909
910
			}
911
		}
912
913
		$this->send_response($return, 0);
914
	}
915
916
	public function get_manage_backups_list() {
917
918
		$storage_selection = "";
919
920
		if (isset($_GET['storage_selection']) and $_GET['storage_selection']) {
921
			$storage_selection = $this->xcloner_sanitization->sanitize_input_as_string($_GET['storage_selection']);
922
		}
923
		$available_storages = $this->xcloner_remote_storage->get_available_storages();
924
925
		$backup_list = $this->xcloner_file_system->get_backup_archives_list($storage_selection);
926
		$return = array();
927
928
		$i = -1;
929
		foreach ($backup_list as $file_info):?>
930
            <?php
931
			if ($storage_selection == "gdrive") {
932
				$file_info['path'] = $file_info['filename'] . "." . $file_info['extension'];
933
			}
934
			$file_exists_on_local_storage = true;
935
936
			if ($storage_selection) {
937
				if (!$this->xcloner_file_system->get_storage_filesystem()->has($file_info['path'])) {
938
					$file_exists_on_local_storage = false;
939
				}
940
			}
941
942
			?>
943
            <?php if (!isset($file_info['parent'])): ?>
944
945
                <?php ob_start(); ?>
946
                        <p>
947
                            <input name="backup[]" value="<?php echo $file_info['basename'] ?>" type="checkbox"
948
                                   id="checkbox_<?php echo ++$i ?>">
949
                            <label for="checkbox_<?php echo $i ?>">&nbsp;</label>
950
                        </p>
951
                <?php
952
				$return['data'][$i][] = ob_get_contents();
953
				ob_end_clean();
954
				?>
955
956
                <?php ob_start(); ?>
957
                        <span class=""><?php echo $file_info['path'] ?></span>
958
                        <?php if (!$file_exists_on_local_storage): ?>
959
                            <a href="#"
960
                               title="<?php echo __("File does not exists on local storage",
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

960
                               title="<?php echo /** @scrutinizer ignore-call */ __("File does not exists on local storage",
Loading history...
961
								   "xcloner-backup-and-restore") ?>"><i
962
                                        class="material-icons backup_warning">warning</i></a>
963
                        <?php endif ?>
964
                        <?php
965
						if (isset($file_info['childs']) and is_array($file_info['childs'])):
966
							?>
967
                            <a href="#" title="expand" class="expand-multipart add"><i
968
                                        class="material-icons">add</i></a>
969
                            <a href="#" title="collapse" class="expand-multipart remove"><i class="material-icons">remove</i></a>
970
                            <ul class="multipart">
971
                                <?php foreach ($file_info['childs'] as $child): ?>
972
                                    <li>
973
                                        <?php echo $child[0] ?> (<?php echo size_format($child[2]) ?>)
0 ignored issues
show
Bug introduced by
The function size_format was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

973
                                        <?php echo $child[0] ?> (<?php echo /** @scrutinizer ignore-call */ size_format($child[2]) ?>)
Loading history...
974
                                        <?php
975
										$child_exists_on_local_storage = true;
976
										if ($storage_selection) {
977
											if (!$this->xcloner_file_system->get_storage_filesystem()->has($child[0])) {
978
												$child_exists_on_local_storage = false;
979
											}
980
										}
981
										?>
982
                                        <?php if (!$child_exists_on_local_storage): ?>
983
                                            <a href="#"
984
                                               title="<?php echo __("File does not exists on local storage",
985
												   "xcloner-backup-and-restore") ?>"><i
986
                                                        class="material-icons backup_warning">warning</i></a>
987
                                        <?php endif ?>
988
                                        <?php if (!$storage_selection) : ?>
989
                                            <a href="#<?php echo $child[0]; ?>" class="download"
990
                                               title="Download Backup"><i class="material-icons">file_download</i></a>
991
992
                                            <?php if ($this->xcloner_encryption->is_encrypted_file($child[0])) :?>
993
                                                <a href="#<?php echo $child[0] ?>" class="backup-decryption"
994
                                                   title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
995
                                                    <i class="material-icons">enhanced_encryption</i>
996
                                                </a>
997
                                            <?php else: ?>
998
                                                <a href="#<?php echo $child[0] ?>" class="list-backup-content"
999
                                                   title="<?php echo __('List Backup Content',
1000
													   'xcloner-backup-and-restore') ?>"><i
1001
                                                            class="material-icons">folder_open</i></a>
1002
1003
                                                <a href="#<?php echo $child[0] ?>" class="backup-encryption"
1004
                                                   title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
1005
                                                    <i class="material-icons">no_encryption</i>
1006
                                                </a>
1007
                                            <?php endif?>
1008
1009
                                        <?php elseif ($storage_selection != "gdrive" && !$this->xcloner_file_system->get_storage_filesystem()->has($child[0])): ?>
1010
                                            <a href="#<?php echo $child[0] ?>" class="copy-remote-to-local"
1011
                                               title="<?php echo __('Push Backup To Local Storage',
1012
												   'xcloner-backup-and-restore') ?>"><i
1013
                                                        class="material-icons">file_upload</i></a>
1014
                                        <?php endif ?>
1015
                                    </li>
1016
                                <?php endforeach; ?>
1017
                            </ul>
1018
                        <?php endif; ?>
1019
                <?php
1020
				$return['data'][$i][] = ob_get_contents();
1021
				ob_end_clean();
1022
				?>
1023
                    <?php ob_start(); ?>
1024
                        <?php if (isset($file_info['timestamp']))
1025
							echo date("Y-m-d H:i", $file_info['timestamp'])
1026
						?>
1027
                    <?php
1028
						$return['data'][$i][] = ob_get_contents();
1029
						ob_end_clean();
1030
						?>
1031
1032
                    <?php ob_start(); ?>
1033
                        <?php echo size_format($file_info['size']) ?>
1034
                    <?php
1035
						$return['data'][$i][] = ob_get_contents();
1036
						ob_end_clean();
1037
					?>
1038
1039
                    <?php ob_start(); ?>
1040
                        <?php if (!$storage_selection): ?>
1041
                            <a href="#<?php echo $file_info['basename']; ?>" class="download"
1042
                               title="<?php echo __('Download Backup', 'xcloner-backup-and-restore') ?>"><i
1043
                                        class="material-icons">file_download</i></a>
1044
1045
                            <?php if (sizeof($available_storages)): ?>
1046
                                <a href="#<?php echo $file_info['basename'] ?>" class="cloud-upload"
1047
                                   title="<?php echo __('Send Backup To Remote Storage',
1048
									   'xcloner-backup-and-restore') ?>"><i
1049
                                            class="material-icons">cloud_upload</i></a>
1050
                            <?php endif ?>
1051
                            <?php
1052
							$basename = $file_info['basename'];
1053
							if(isset($file_info['childs']) and sizeof($file_info['childs']))
1054
								$basename = $file_info['childs'][0][0];
1055
							?>
1056
                            <?php if($this->xcloner_encryption->is_encrypted_file($basename)) :?>
1057
                                <a href="#<?php echo $file_info['basename'] ?>" class="backup-decryption"
1058
                                   title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
1059
                                    <i class="material-icons">enhanced_encryption</i>
1060
                                </a>
1061
                            <?php else: ?>
1062
                                <a href="#<?php echo $file_info['basename'] ?>" class="list-backup-content"
1063
                                    title="<?php echo __('List Backup Content', 'xcloner-backup-and-restore') ?>"><i
1064
                                    class="material-icons">folder_open</i></a>
1065
1066
                                <a href="#<?php echo $file_info['basename'] ?>" class="backup-encryption"
1067
                                   title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
1068
                                    <i class="material-icons">no_encryption</i>
1069
                                </a>
1070
                            <?php endif?>
1071
                        <?php endif; ?>
1072
1073
                        <a href="#<?php echo $file_info['basename'] ?>" class="delete"
1074
                           title="<?php echo __('Delete Backup', 'xcloner-backup-and-restore') ?>">
1075
                            <i class="material-icons">delete</i>
1076
                        </a>
1077
                        <?php if ($storage_selection and !$file_exists_on_local_storage): ?>
1078
                            <a href="#<?php echo $file_info['basename']; ?>" class="copy-remote-to-local"
1079
                               title="<?php echo __('Push Backup To Local Storage', 'xcloner-backup-and-restore') ?>"><i
1080
                                        class="material-icons">file_upload</i></a>
1081
                        <?php endif ?>
1082
1083
                    <?php
1084
						$return['data'][$i][] = ob_get_contents();
1085
						ob_end_clean(); ?>
1086
1087
            <?php endif ?>
1088
        <?php endforeach ?>
1089
    <?php
1090
		$this->send_response($return, 0);
1091
	}
1092
1093
	/**
1094
	 * API method to list internal backup files
1095
	 */
1096
	public function list_backup_files()
1097
	{
1098
		$this->check_access();
1099
1100
		$backup_parts = array();
1101
1102
		$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
1103
		$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
1104
		$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
1105
1106
		$backup_file = $source_backup_file;
1107
1108
		if ($this->xcloner_file_system->is_multipart($backup_file)) {
1109
			$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
1110
			$backup_file = $backup_parts[$return['part']];
1111
		}
1112
1113
		if($this->xcloner_encryption->is_encrypted_file($backup_file)) {
1114
			$return['error'] = true;
1115
			$return['message'] = __("Backup archive is encrypted, please decrypt it first before you can list it's content.", "xcloner-backup-and-restore");
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1115
			$return['message'] = /** @scrutinizer ignore-call */ __("Backup archive is encrypted, please decrypt it first before you can list it's content.", "xcloner-backup-and-restore");
Loading history...
1116
			$this->send_response($return, 0);
1117
		}
1118
1119
		try {
1120
			$tar = new Tar();
1121
			$tar->open($this->xcloner_settings->get_xcloner_store_path() . DS . $backup_file, $start);
1122
1123
			$data = $tar->contents(get_option('xcloner_files_to_process_per_request'));
0 ignored issues
show
Bug introduced by
The function get_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1123
			$data = $tar->contents(/** @scrutinizer ignore-call */ get_option('xcloner_files_to_process_per_request'));
Loading history...
1124
		} catch (Exception $e) {
1125
			$return['error'] = true;
1126
			$return['message'] = $e->getMessage();
1127
			$this->send_response($return, 0);
1128
		}
1129
1130
		$return['files'] = array();
1131
		$return['finished'] = 1;
1132
		$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path() . DS . $backup_file);
1133
		$i = 0;
1134
1135
		if (isset($data['extracted_files']) and is_array($data['extracted_files'])) {
1136
			foreach ($data['extracted_files'] as $file) {
1137
				$return['files'][$i]['path'] = $file->getPath();
1138
				$return['files'][$i]['size'] = $file->getSize();
1139
				$return['files'][$i]['mtime'] = date(get_option('date_format') . " " . get_option('time_format'),
1140
					$file->getMtime());
1141
1142
				$i++;
1143
			}
1144
		}
1145
1146
		if (isset($data['start'])) {
1147
			$return['start'] = $data['start'];
1148
			$return['finished'] = 0;
1149
		} else {
1150
			if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
1151
				$return['start'] = 0;
1152
1153
				++$return['part'];
1154
1155
				if ($return['part'] < sizeof($backup_parts)) {
1156
					$return['finished'] = 0;
1157
				}
1158
1159
			}
1160
		}
1161
1162
		$this->send_response($return, 0);
1163
	}
1164
1165
	/*
1166
     * Copy remote backup to local storage
1167
     */
1168
	public function copy_backup_remote_to_local()
1169
	{
1170
1171
		$this->check_access();
1172
1173
		$backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
1174
		$storage_type = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_type']);
1175
1176
		$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
1177
1178
		$return = array();
1179
1180
		try {
1181
			if (method_exists($xcloner_remote_storage, "copy_backup_remote_to_local")) {
1182
				$return = call_user_func_array(array(
1183
					$xcloner_remote_storage,
1184
					"copy_backup_remote_to_local"
1185
				), array($backup_file, $storage_type));
1186
			}
1187
		} catch (Exception $e) {
1188
1189
			$return['error'] = 1;
1190
			$return['message'] = $e->getMessage();
1191
		}
1192
1193
		if (!$return) {
1194
			$return['error'] = 1;
1195
			$return['message'] = "Upload failed, please check the error log for more information!";
1196
		}
1197
1198
1199
		$this->send_response($return, 0);
1200
1201
	}
1202
1203
	/*
1204
     *
1205
     * Upload backup to remote API
1206
     *
1207
     */
1208
	public function upload_backup_to_remote()
1209
	{
1210
		$this->check_access();
1211
1212
		$backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
1213
		$storage_type = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_type']);
1214
1215
		$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
1216
1217
		$return = array();
1218
1219
		try {
1220
			if (method_exists($xcloner_remote_storage, "upload_backup_to_storage")) {
1221
				$return = call_user_func_array(array(
1222
					$xcloner_remote_storage,
1223
					"upload_backup_to_storage"
1224
				), array($backup_file, $storage_type));
1225
			}
1226
		} catch (Exception $e) {
1227
1228
			$return['error'] = 1;
1229
			$return['message'] = $e->getMessage();
1230
		}
1231
1232
		if (!$return) {
1233
			$return['error'] = 1;
1234
			$return['message'] = "Upload failed, please check the error log for more information!";
1235
		}
1236
1237
1238
		$this->send_response($return, 0);
1239
1240
	}
1241
1242
	/*
1243
     *
1244
     * Remote Storage Status Save
1245
     *
1246
     */
1247
	public function remote_storage_save_status()
1248
	{
1249
		$this->check_access();
1250
1251
		$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
1252
1253
		$return['finished'] = $xcloner_remote_storage->change_storage_status($_POST['id'], $_POST['value']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
1254
1255
		$this->send_response($return, 0);
1256
	}
1257
1258
1259
	public function download_restore_script()
1260
	{
1261
		$this->check_access();
1262
1263
		@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ob_end_clean(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

1263
		/** @scrutinizer ignore-unhandled */ @ob_end_clean();

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1264
1265
		$adapter = new Local(dirname(__DIR__), LOCK_EX, 'SKIP_LINKS');
1266
		$xcloner_plugin_filesystem = new Filesystem($adapter, new Config([
1267
			'disable_asserts' => true,
1268
		]));
1269
1270
		/* Generate PHAR FILE
1271
        $file = 'restore/vendor.built';
1272
1273
        if(file_exists($file))
1274
            unlink($file);
1275
        $phar2 = new Phar($file, 0, 'vendor.phar');
1276
1277
        // add all files in the project, only include php files
1278
        $phar2->buildFromIterator(
1279
            new RecursiveIteratorIterator(
1280
             new RecursiveDirectoryIterator(__DIR__.'/vendor/')),
1281
            __DIR__);
1282
1283
        $phar2->setStub($phar2->createDefaultStub('vendor/autoload.php', 'vendor/autoload.php'));
1284
         * */
1285
1286
		$tmp_file = $this->xcloner_settings->get_xcloner_tmp_path() . DS . "xcloner-restore.tgz";
1287
1288
		$tar = new Tar();
1289
		$tar->create($tmp_file);
1290
1291
		$tar->addFile(dirname(__DIR__) . "/restore/vendor.build.txt", "vendor.phar");
1292
		//$tar->addFile(dirname(__DIR__)."/restore/vendor.tgz", "vendor.tgz");
1293
1294
		$files = $xcloner_plugin_filesystem->listContents("vendor/", true);
1295
		foreach ($files as $file) {
1296
			$tar->addFile(dirname(__DIR__) . DS . $file['path'], $file['path']);
1297
		}
1298
1299
		$content = file_get_contents(dirname(__DIR__) . "/restore/xcloner_restore.php");
1300
		$content = str_replace("define('AUTH_KEY', '');", "define('AUTH_KEY', '" . md5(AUTH_KEY) . "');", $content);
1301
1302
		$tar->addData("xcloner_restore.php", $content);
1303
1304
		$tar->close();
1305
1306
		if (file_exists($tmp_file)) {
1307
			header('Content-Description: File Transfer');
1308
			header('Content-Type: application/octet-stream');
1309
			header('Content-Disposition: attachment; filename="' . basename($tmp_file) . '"');
1310
			header('Expires: 0');
1311
			header('Cache-Control: must-revalidate');
1312
			header('Pragma: public');
1313
			header('Content-Length: ' . filesize($tmp_file));
1314
			readfile($tmp_file);
1315
1316
		}
1317
1318
		@unlink($tmp_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

1318
		/** @scrutinizer ignore-unhandled */ @unlink($tmp_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1319
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1320
	}
1321
1322
	/*
1323
     *
1324
     * Download backup by Name from the Storage Path
1325
     *
1326
     */
1327
	public function download_backup_by_name()
1328
	{
1329
		$this->check_access();
1330
1331
		@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ob_end_clean(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

1331
		/** @scrutinizer ignore-unhandled */ @ob_end_clean();

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1332
1333
		$backup_name = $this->xcloner_sanitization->sanitize_input_as_string($_GET['name']);
1334
1335
1336
		$metadata = $this->xcloner_file_system->get_storage_filesystem()->getMetadata($backup_name);
1337
		$read_stream = $this->xcloner_file_system->get_storage_filesystem()->readStream($backup_name);
1338
1339
1340
		header('Pragma: public');
1341
		header('Expires: 0');
1342
		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1343
		header('Cache-Control: private', false);
1344
		header('Content-Transfer-Encoding: binary');
1345
		header('Content-Disposition: attachment; filename="' . $metadata['path'] . '";');
1346
		header('Content-Type: application/octet-stream');
1347
		header('Content-Length: ' . $metadata['size']);
1348
1349
		@ob_end_clean();
1350
1351
		$chunkSize = 1024 * 1024;
1352
		while (!feof($read_stream)) {
1353
			$buffer = fread($read_stream, $chunkSize);
1354
			echo $buffer;
1355
		}
1356
		fclose($read_stream);
1357
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1358
1359
	}
1360
1361
	/*
1362
     * Restore upload backup
1363
     */
1364
	public function restore_upload_backup()
1365
	{
1366
		$this->check_access();
1367
1368
		$return['part'] = 0;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
1369
		$return['total_parts'] = 0;
1370
		$return['uploaded_size'] = 0;
1371
		$is_multipart = 0;
1372
1373
		$file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
1374
		$hash = $this->xcloner_sanitization->sanitize_input_as_string($_POST['hash']);
1375
1376
		if (isset($_POST['part'])) {
1377
			$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
1378
		}
1379
1380
		if (isset($_POST['uploaded_size'])) {
1381
			$return['uploaded_size'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['uploaded_size']);
1382
		}
1383
1384
		$start = $this->xcloner_sanitization->sanitize_input_as_string($_POST['start']);
1385
		$target_url = $this->xcloner_sanitization->sanitize_input_as_string($_POST['target_url']);
1386
1387
		$return['total_size'] = $this->xcloner_file_system->get_backup_size($file);
1388
1389
		if ($this->xcloner_file_system->is_multipart($file)) {
1390
			$backup_parts = $this->xcloner_file_system->get_multipart_files($file);
1391
1392
			$return['total_parts'] = sizeof($backup_parts) + 1;
1393
1394
			if ($return['part'] and isset($backup_parts[$return['part'] - 1])) {
1395
				$file = $backup_parts[$return['part'] - 1];
1396
			}
1397
1398
			$is_multipart = 1;
1399
		}
1400
1401
		try {
1402
1403
			$xcloner_file_transfer = $this->get_xcloner_container()->get_xcloner_file_transfer();
1404
			$xcloner_file_transfer->set_target($target_url);
1405
			$return['start'] = $xcloner_file_transfer->transfer_file($file, $start, $hash);
1406
1407
		} catch (Exception $e) {
1408
1409
			$return = array();
1410
			$return['error'] = true;
1411
			$return['status'] = 500;
1412
			$return['message'] = "CURL communication error with the restore host. " . $e->getMessage();
1413
			$this->send_response($return, 0);
1414
1415
		}
1416
1417
		$return['status'] = 200;
1418
1419
		//we have finished the upload
1420
		if (!$return['start'] and $is_multipart) {
1421
			$return['part']++;
1422
			$return['uploaded_size'] += $this->xcloner_file_system->get_storage_filesystem()->getSize($file);
1423
		}
1424
1425
		$this->send_response($return, 0);
1426
	}
1427
1428
	/*
1429
     * Restore backup
1430
     */
1431
	public function restore_backup()
1432
	{
1433
		$this->check_access();
1434
1435
		define("XCLONER_PLUGIN_ACCESS", 1);
1436
		include_once(dirname(__DIR__) . DS . "restore" . DS . "xcloner_restore.php");
1437
1438
		return;
1439
	}
1440
1441
	/*
1442
     *
1443
     * Send the json response back
1444
     *
1445
     */
1446
	private function send_response($data, $attach_hash = 1)
1447
	{
1448
1449
		if ($attach_hash and null !== $this->xcloner_settings->get_hash()) {
1450
			$data['hash'] = $this->xcloner_settings->get_hash();
1451
		}
1452
1453
		if (ob_get_length()) {
1454
			ob_clean();
1455
		}
1456
		wp_send_json($data);
0 ignored issues
show
Bug introduced by
The function wp_send_json was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1456
		/** @scrutinizer ignore-call */ 
1457
  wp_send_json($data);
Loading history...
1457
1458
		die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1459
	}
1460
}
1461