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.
Completed
Branch dev (953bb6)
by Liuta
01:57
created

Xcloner_Api::list_backup_files()   C

Complexity

Conditions 10
Paths 128

Size

Total Lines 68

Duplication

Lines 20
Ratio 29.41 %

Importance

Changes 0
Metric Value
cc 10
nc 128
nop 0
dl 20
loc 68
rs 6.6448
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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) {
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();
0 ignored issues
show
Bug introduced by
The method get_xcloner_settings() does not seem to exist on object<Xcloner>.

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.

Loading history...
81
        $this->logger                   = $xcloner_container->get_xcloner_logger()->withName("xcloner_api");
0 ignored issues
show
Bug introduced by
The method get_xcloner_logger() does not seem to exist on object<Xcloner>.

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.

Loading history...
82
        $this->xcloner_file_system      = $xcloner_container->get_xcloner_filesystem();
0 ignored issues
show
Bug introduced by
The method get_xcloner_filesystem() does not seem to exist on object<Xcloner>.

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.

Loading history...
83
        $this->xcloner_sanitization     = $xcloner_container->get_xcloner_sanitization();
0 ignored issues
show
Bug introduced by
The method get_xcloner_sanitization() does not seem to exist on object<Xcloner>.

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.

Loading history...
84
        $this->xcloner_requirements     = $xcloner_container->get_xcloner_requirements();
0 ignored issues
show
Bug introduced by
The method get_xcloner_requirements() does not seem to exist on object<Xcloner>.

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.

Loading history...
85
        $this->archive_system           = $xcloner_container->get_archive_system();
0 ignored issues
show
Bug introduced by
The method get_archive_system() does not seem to exist on object<Xcloner>.

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.

Loading history...
86
        $this->xcloner_database         = $xcloner_container->get_xcloner_database();
0 ignored issues
show
Bug introduced by
The method get_xcloner_database() does not seem to exist on object<Xcloner>.

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.

Loading history...
87
        $this->xcloner_scheduler        = $xcloner_container->get_xcloner_scheduler();
0 ignored issues
show
Bug introduced by
The property xcloner_scheduler does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The method get_xcloner_scheduler() does not seem to exist on object<Xcloner>.

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.

Loading history...
88
        $this->xcloner_encryption       = $xcloner_container->get_xcloner_encryption();
0 ignored issues
show
Bug introduced by
The method get_xcloner_encryption() does not seem to exist on object<Xcloner>.

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.

Loading history...
89
        $this->xcloner_remote_storage   = $xcloner_container->get_xcloner_remote_storage();
0 ignored issues
show
Bug introduced by
The method get_xcloner_remote_storage() does not seem to exist on object<Xcloner>.

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.

Loading history...
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
Documentation introduced by
The doc-type die() could not be parsed: Expected "|" or "end of type", but got "(" at position 3. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

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!");
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...ngs->get_db_hostname(); does not seem to be 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));
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"}');
302
        }
303
304
        $this->process_params($params);
305
306
        $return['finished'] = 1;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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 View Code Duplication
            if ($this->xcloner_file_system->is_part($this->archive_system->get_archive_name_with_extension())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
Coding Style Comprehensibility introduced by
$additional was never initialized. Although not strictly required by PHP, it is generally a good practice to add $additional = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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"}');
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 View Code Duplication
        if (isset($return['error']) and $return['error']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
373
            $data['finished'] = 1;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
374
        } else {
375
            $data['finished'] = $return['finished'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
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"}');
397
        }
398
399
        $hash = $this->process_params($params);
0 ignored issues
show
Unused Code introduced by
$hash is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

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
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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 View Code Duplication
        if (isset($params->backup_params)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
        if (isset($params->table_params)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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"
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"
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));
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
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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));
689
690
            $next_run = date(get_option('date_format') . " " . get_option('time_format'), $next_run_time);
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));
701
702
                if ($next_run_time >= time()) {
703
                    $next_run = "in " . human_time_diff($next_run_time, time());
704
                } else {
705
                    $next_run = __("executed", 'xcloner-backup-and-restore');
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));
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();
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
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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 View Code Duplication
            if(isset($this->form_params['extra']['start'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
799
                $start = $this->xcloner_sanitization->sanitize_input_as_int($this->form_params['extra']['start']);
800
            }else{
801
                $start = 0;
802
            }
803
804 View Code Duplication
            if(isset($this->form_params['extra']['iv'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
805
                $iv = $this->xcloner_sanitization->sanitize_input_as_raw($this->form_params['extra']['iv']);
806
            }else{
807
                $iv = "";
808
            }
809
810 View Code Duplication
            if(isset($this->form_params['extra']['part'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
        if ($this->xcloner_file_system->is_multipart($backup_file)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
        if ($this->xcloner_file_system->is_multipart($backup_file)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
        if (isset($_GET['storage_selection']) and $_GET['storage_selection']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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",
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]) ?>)
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 View Code Duplication
                                            <?php if($this->xcloner_encryption->is_encrypted_file($child[0])) :?>
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
                            <?php if($this->xcloner_encryption->is_encrypted_file($basename)) :?>
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1105
1106
        $backup_file = $source_backup_file;
1107
1108 View Code Duplication
        if ($this->xcloner_file_system->is_multipart($backup_file)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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");
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);
0 ignored issues
show
Unused Code introduced by
The call to Tar::open() has too many arguments starting with $start.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1122
1123
            $data = $tar->contents(get_option('xcloner_files_to_process_per_request'));
0 ignored issues
show
Unused Code introduced by
The call to Tar::contents() has too many arguments starting with get_option('xcloner_file...o_process_per_request').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

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 View Code Duplication
        if (isset($data['start'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    public function copy_backup_remote_to_local()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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();
0 ignored issues
show
Bug introduced by
The method get_xcloner_remote_storage() does not seem to exist on object<Xcloner>.

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.

Loading history...
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 View Code Duplication
    public function upload_backup_to_remote()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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();
0 ignored issues
show
Bug introduced by
The method get_xcloner_remote_storage() does not seem to exist on object<Xcloner>.

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.

Loading history...
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();
0 ignored issues
show
Bug introduced by
The method get_xcloner_remote_storage() does not seem to exist on object<Xcloner>.

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.

Loading history...
1252
1253
        $return['finished'] = $xcloner_remote_storage->change_storage_status($_POST['id'], $_POST['value']);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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 here. This can introduce security issues, and is generally not recommended.

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 here. This can introduce security issues, and is generally not recommended.

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;
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 here. This can introduce security issues, and is generally not recommended.

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();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
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;
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
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

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 View Code Duplication
            if ($return['part'] and isset($backup_parts[$return['part'] - 1])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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();
0 ignored issues
show
Bug introduced by
The method get_xcloner_file_transfer() does not seem to exist on object<Xcloner>.

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.

Loading history...
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);
1457
1458
        die();
1459
    }
1460
}
1461