1 | <?php |
||||||
2 | /** |
||||||
3 | * XCloner - Backup and Restore backup plugin for Wordpress |
||||||
4 | * |
||||||
5 | * class-xcloner-remote-storage.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/25/18 2:15 PM |
||||||
26 | * |
||||||
27 | */ |
||||||
28 | |||||||
29 | use League\Flysystem\Config; |
||||||
30 | use League\Flysystem\Filesystem; |
||||||
31 | |||||||
32 | use League\Flysystem\Adapter\Ftp as Adapter; |
||||||
33 | |||||||
34 | use League\Flysystem\Sftp\SftpAdapter; |
||||||
35 | |||||||
36 | use Srmklive\Dropbox\Client\DropboxClient; |
||||||
37 | use Srmklive\Dropbox\Adapter\DropboxAdapter; |
||||||
38 | |||||||
39 | use MicrosoftAzure\Storage\Common\ServicesBuilder; |
||||||
40 | use League\Flysystem\Azure\AzureAdapter; |
||||||
41 | |||||||
42 | use Aws\S3\S3Client; |
||||||
43 | use League\Flysystem\AwsS3v3\AwsS3Adapter; |
||||||
44 | |||||||
45 | use Mhetreramesh\Flysystem\BackblazeAdapter; |
||||||
46 | use BackblazeB2\Client as B2Client; |
||||||
47 | |||||||
48 | use Sabre\DAV\Client as SabreClient; |
||||||
49 | use League\Flysystem\WebDAV\WebDAVAdapter; |
||||||
50 | |||||||
51 | /** |
||||||
52 | * Class Xcloner_Remote_Storage |
||||||
53 | */ |
||||||
54 | class Xcloner_Remote_Storage |
||||||
55 | { |
||||||
56 | |||||||
57 | private $gdrive_app_name = "XCloner Backup and Restore"; |
||||||
58 | |||||||
59 | private $storage_fields = array( |
||||||
60 | "option_prefix" => "xcloner_", |
||||||
61 | "ftp" => array( |
||||||
62 | "text" => "FTP", |
||||||
63 | "ftp_enable" => "int", |
||||||
64 | "ftp_hostname" => "string", |
||||||
65 | "ftp_port" => "int", |
||||||
66 | "ftp_username" => "string", |
||||||
67 | "ftp_password" => "raw", |
||||||
68 | "ftp_path" => "path", |
||||||
69 | "ftp_transfer_mode" => "int", |
||||||
70 | "ftp_ssl_mode" => "int", |
||||||
71 | "ftp_timeout" => "int", |
||||||
72 | "ftp_cleanup_days" => "float", |
||||||
73 | ), |
||||||
74 | "sftp" => array( |
||||||
75 | "text" => "SFTP", |
||||||
76 | "sftp_enable" => "int", |
||||||
77 | "sftp_hostname" => "string", |
||||||
78 | "sftp_port" => "int", |
||||||
79 | "sftp_username" => "string", |
||||||
80 | "sftp_password" => "raw", |
||||||
81 | "sftp_path" => "path", |
||||||
82 | "sftp_private_key" => "raw", |
||||||
83 | "sftp_timeout" => "int", |
||||||
84 | "sftp_cleanup_days" => "float", |
||||||
85 | ), |
||||||
86 | "aws" => array( |
||||||
87 | "text" => "S3", |
||||||
88 | "aws_enable" => "int", |
||||||
89 | "aws_key" => "string", |
||||||
90 | "aws_secret" => "raw", |
||||||
91 | "aws_endpoint" => "string", |
||||||
92 | "aws_region" => "string", |
||||||
93 | "aws_bucket_name" => "string", |
||||||
94 | "aws_prefix" => "string", |
||||||
95 | "aws_cleanup_days" => "float", |
||||||
96 | ), |
||||||
97 | "dropbox" => array( |
||||||
98 | "text" => "Dropbox", |
||||||
99 | "dropbox_enable" => "int", |
||||||
100 | "dropbox_access_token" => "string", |
||||||
101 | "dropbox_app_secret" => "raw", |
||||||
102 | "dropbox_prefix" => "string", |
||||||
103 | "dropbox_cleanup_days" => "float", |
||||||
104 | ), |
||||||
105 | "azure" => array( |
||||||
106 | "text" => "Azure BLOB", |
||||||
107 | "azure_enable" => "int", |
||||||
108 | "azure_account_name" => "string", |
||||||
109 | "azure_api_key" => "string", |
||||||
110 | "azure_container" => "string", |
||||||
111 | "azure_cleanup_days" => "float", |
||||||
112 | ), |
||||||
113 | "backblaze" => array( |
||||||
114 | "text" => "Backblaze", |
||||||
115 | "backblaze_enable" => "int", |
||||||
116 | "backblaze_account_id" => "string", |
||||||
117 | "backblaze_application_key" => "string", |
||||||
118 | "backblaze_bucket_name" => "string", |
||||||
119 | "backblaze_cleanup_days" => "float", |
||||||
120 | ), |
||||||
121 | |||||||
122 | "webdav" => array( |
||||||
123 | "text" => "WebDAV", |
||||||
124 | "webdav_enable" => "int", |
||||||
125 | "webdav_url" => "string", |
||||||
126 | "webdav_username" => "string", |
||||||
127 | "webdav_password" => "raw", |
||||||
128 | "webdav_target_folder" => "string", |
||||||
129 | "webdav_cleanup_days" => "float", |
||||||
130 | ), |
||||||
131 | |||||||
132 | "gdrive" => array( |
||||||
133 | "text" => "Google Drive", |
||||||
134 | "gdrive_enable" => "int", |
||||||
135 | "gdrive_access_code" => "string", |
||||||
136 | "gdrive_client_id" => "string", |
||||||
137 | "gdrive_client_secret" => "raw", |
||||||
138 | "gdrive_target_folder" => "string", |
||||||
139 | "gdrive_cleanup_days" => "float", |
||||||
140 | "gdrive_empty_trash" => "int", |
||||||
141 | ), |
||||||
142 | ); |
||||||
143 | |||||||
144 | private $aws_regions = array( |
||||||
145 | 'us-east-1' => 'US East (N. Virginia)', |
||||||
146 | 'us-east-2' => 'US East (Ohio)', |
||||||
147 | 'us-west-1' => 'US West (N. California)', |
||||||
148 | 'us-west-2' => 'US West (Oregon)', |
||||||
149 | 'ca-central-1' => 'Canada (Central)', |
||||||
150 | 'eu-west-1' => 'EU (Ireland)', |
||||||
151 | 'eu-central-1' => 'EU (Frankfurt)', |
||||||
152 | 'eu-west-2' => 'EU (London)', |
||||||
153 | 'ap-northeast-1' => 'Asia Pacific (Tokyo)', |
||||||
154 | 'ap-northeast-2' => 'Asia Pacific (Seoul)', |
||||||
155 | 'ap-southeast-1' => 'Asia Pacific (Singapore)', |
||||||
156 | 'ap-southeast-2' => 'Asia Pacific (Sydney)', |
||||||
157 | 'ap-south-1' => 'Asia Pacific (Mumbai)', |
||||||
158 | 'sa-east-1' => 'South America (São Paulo)' |
||||||
159 | ); |
||||||
160 | |||||||
161 | private $xcloner_sanitization; |
||||||
162 | private $xcloner_file_system; |
||||||
163 | private $logger; |
||||||
164 | private $xcloner; |
||||||
165 | |||||||
166 | /** |
||||||
167 | * Xcloner_Remote_Storage constructor. |
||||||
168 | * @param Xcloner $xcloner_container |
||||||
169 | */ |
||||||
170 | public function __construct(Xcloner $xcloner_container) |
||||||
171 | { |
||||||
172 | $this->xcloner_sanitization = $xcloner_container->get_xcloner_sanitization(); |
||||||
173 | $this->xcloner_file_system = $xcloner_container->get_xcloner_filesystem(); |
||||||
174 | $this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_remote_storage"); |
||||||
175 | $this->xcloner = $xcloner_container; |
||||||
176 | |||||||
177 | foreach ($this->storage_fields as $main_key => $array) { |
||||||
178 | |||||||
179 | if (is_array($array)) { |
||||||
180 | foreach ($array as $key => $type) { |
||||||
181 | |||||||
182 | if ($type == "raw") { |
||||||
183 | add_filter("pre_update_option_" . $this->storage_fields['option_prefix'] . $key, |
||||||
184 | function ($value) { |
||||||
185 | |||||||
186 | return $this->simple_crypt($value, 'e'); |
||||||
187 | |||||||
188 | }, 10, 1); |
||||||
189 | |||||||
190 | add_filter("option_" . $this->storage_fields['option_prefix'] . $key, function ($value) { |
||||||
191 | |||||||
192 | return $this->simple_crypt($value, 'd'); |
||||||
193 | |||||||
194 | }, 10, 1); |
||||||
195 | } |
||||||
196 | |||||||
197 | } |
||||||
198 | } |
||||||
199 | } |
||||||
200 | |||||||
201 | } |
||||||
202 | |||||||
203 | /** |
||||||
204 | * Encrypts and Decrypt a string based on openssl lib |
||||||
205 | * |
||||||
206 | * @param $string |
||||||
207 | * @param string $action |
||||||
208 | * @return string |
||||||
209 | */ |
||||||
210 | private function simple_crypt($string, $action = 'e') |
||||||
211 | { |
||||||
212 | // you may change these values to your own |
||||||
213 | $secret_key = NONCE_KEY; |
||||||
214 | $secret_iv = NONCE_SALT; |
||||||
215 | |||||||
216 | if (!$string) { |
||||||
217 | //we do no encryption for empty data |
||||||
218 | return $string; |
||||||
219 | } |
||||||
220 | |||||||
221 | $output = $string; |
||||||
222 | $encrypt_method = "AES-256-CBC"; |
||||||
223 | $key = hash('sha256', $secret_key); |
||||||
224 | $iv = substr(hash('sha256', $secret_iv), 0, 16); |
||||||
225 | |||||||
226 | if ($action == 'e' && function_exists('openssl_encrypt')) { |
||||||
227 | $output = base64_encode(openssl_encrypt($string, $encrypt_method, $key, 0, $iv)); |
||||||
228 | } else { |
||||||
229 | if ($action == 'd' && function_exists('openssl_decrypt') && base64_decode($string)) { |
||||||
230 | $decrypt = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv); |
||||||
231 | if ($decrypt) { |
||||||
232 | //we check if decrypt was succesful |
||||||
233 | $output = $decrypt; |
||||||
234 | } |
||||||
235 | } |
||||||
236 | } |
||||||
237 | |||||||
238 | return $output; |
||||||
239 | } |
||||||
240 | |||||||
241 | private function get_xcloner_container() |
||||||
242 | { |
||||||
243 | return $this->xcloner; |
||||||
244 | } |
||||||
245 | |||||||
246 | public function get_available_storages() |
||||||
247 | { |
||||||
248 | $return = array(); |
||||||
249 | foreach ($this->storage_fields as $storage => $data) { |
||||||
250 | $check_field = $this->storage_fields["option_prefix"] . $storage . "_enable"; |
||||||
251 | if (get_option($check_field)) { |
||||||
252 | $return[$storage] = $data['text']; |
||||||
253 | } |
||||||
254 | } |
||||||
255 | |||||||
256 | return $return; |
||||||
257 | } |
||||||
258 | |||||||
259 | public function save($action = "ftp") |
||||||
260 | { |
||||||
261 | if (!$action) { |
||||||
262 | return false; |
||||||
263 | } |
||||||
264 | |||||||
265 | $storage = $this->xcloner_sanitization->sanitize_input_as_string($action); |
||||||
0 ignored issues
–
show
|
|||||||
266 | $this->logger->debug(sprintf("Saving the remote storage %s options", strtoupper($action))); |
||||||
267 | |||||||
268 | if (is_array($this->storage_fields[$storage])) { |
||||||
269 | foreach ($this->storage_fields[$storage] as $field => $validation) { |
||||||
270 | $check_field = $this->storage_fields["option_prefix"] . $field; |
||||||
271 | $sanitize_method = "sanitize_input_as_" . $validation; |
||||||
272 | |||||||
273 | if (!isset($_POST[$check_field])) { |
||||||
274 | $_POST[$check_field] = 0; |
||||||
275 | } |
||||||
276 | |||||||
277 | if (!method_exists($this->xcloner_sanitization, $sanitize_method)) { |
||||||
278 | $sanitize_method = "sanitize_input_as_string"; |
||||||
279 | } |
||||||
280 | |||||||
281 | $sanitized_value = $this->xcloner_sanitization->$sanitize_method(stripslashes($_POST[$check_field])); |
||||||
282 | update_option($check_field, $sanitized_value); |
||||||
283 | } |
||||||
284 | |||||||
285 | $this->xcloner->trigger_message(__("%s storage settings saved.", 'xcloner-backup-and-restore'), "success", |
||||||
286 | $this->storage_fields[$action]['text']); |
||||||
287 | } |
||||||
288 | |||||||
289 | } |
||||||
290 | |||||||
291 | public function check($action = "ftp") |
||||||
292 | { |
||||||
293 | try { |
||||||
294 | $this->verify_filesystem($action); |
||||||
295 | $this->xcloner->trigger_message(__("%s connection is valid.", 'xcloner-backup-and-restore'), "success", |
||||||
296 | $this->storage_fields[$action]['text']); |
||||||
297 | $this->logger->debug(sprintf("Connection to remote storage %s is valid", strtoupper($action))); |
||||||
298 | } catch (Exception $e) { |
||||||
299 | $this->xcloner->trigger_message("%s connection error: " . $e->getMessage(), "error", |
||||||
300 | $this->storage_fields[$action]['text']); |
||||||
301 | } |
||||||
302 | } |
||||||
303 | |||||||
304 | /** |
||||||
305 | * @param string $storage_type |
||||||
306 | */ |
||||||
307 | public function verify_filesystem($storage_type) |
||||||
308 | { |
||||||
309 | $method = "get_" . $storage_type . "_filesystem"; |
||||||
310 | |||||||
311 | $this->logger->info(sprintf("Checking validity of the remote storage %s filesystem", |
||||||
312 | strtoupper($storage_type))); |
||||||
313 | |||||||
314 | if (!method_exists($this, $method)) { |
||||||
315 | return false; |
||||||
316 | } |
||||||
317 | |||||||
318 | list($adapter, $filesystem) = $this->$method(); |
||||||
319 | |||||||
320 | $test_file = substr(".xcloner_" . md5(time()), 0, 15); |
||||||
321 | |||||||
322 | if ($storage_type == "gdrive") { |
||||||
323 | if (!is_array($filesystem->listContents())) { |
||||||
324 | throw new Exception(__("Could not read data", 'xcloner-backup-and-restore')); |
||||||
325 | } |
||||||
326 | $this->logger->debug(sprintf("I can list data from remote storage %s", strtoupper($storage_type))); |
||||||
327 | |||||||
328 | return true; |
||||||
329 | } |
||||||
330 | |||||||
331 | //testing write access |
||||||
332 | if (!$filesystem->write($test_file, "data")) { |
||||||
333 | throw new Exception(__("Could not write data", 'xcloner-backup-and-restore')); |
||||||
334 | } |
||||||
335 | $this->logger->debug(sprintf("I can write data to remote storage %s", strtoupper($storage_type))); |
||||||
336 | |||||||
337 | //testing read access |
||||||
338 | if (!$filesystem->has($test_file)) { |
||||||
339 | throw new Exception(__("Could not read data", 'xcloner-backup-and-restore')); |
||||||
340 | } |
||||||
341 | $this->logger->debug(sprintf("I can read data to remote storage %s", strtoupper($storage_type))); |
||||||
342 | |||||||
343 | //delete test file |
||||||
344 | if (!$filesystem->delete($test_file)) { |
||||||
345 | throw new Exception(__("Could not delete data", 'xcloner-backup-and-restore')); |
||||||
346 | } |
||||||
347 | $this->logger->debug(sprintf("I can delete data to remote storage %s", strtoupper($storage_type))); |
||||||
348 | |||||||
349 | return true; |
||||||
350 | } |
||||||
351 | |||||||
352 | public function upload_backup_to_storage($file, $storage) |
||||||
353 | { |
||||||
354 | if (!$this->xcloner_file_system->get_storage_filesystem()->has($file)) { |
||||||
0 ignored issues
–
show
The method
get_storage_filesystem() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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. ![]() |
|||||||
355 | $this->logger->info(sprintf("File not found %s in local storage", $file)); |
||||||
356 | |||||||
357 | return false; |
||||||
358 | } |
||||||
359 | |||||||
360 | $method = "get_" . $storage . "_filesystem"; |
||||||
361 | |||||||
362 | if (!method_exists($this, $method)) { |
||||||
363 | return false; |
||||||
364 | } |
||||||
365 | |||||||
366 | list($remote_storage_adapter, $remote_storage_filesystem) = $this->$method(); |
||||||
367 | |||||||
368 | //doing remote storage cleaning here |
||||||
369 | $this->clean_remote_storage($storage, $remote_storage_filesystem); |
||||||
370 | |||||||
371 | $this->logger->info(sprintf("Transferring backup %s to remote storage %s", $file, strtoupper($storage)), |
||||||
372 | array("")); |
||||||
373 | |||||||
374 | /*if(!$this->xcloner_file_system->get_storage_filesystem()->has($file)) |
||||||
375 | { |
||||||
376 | $this->logger->info(sprintf("File not found %s in local storage", $file)); |
||||||
377 | return false; |
||||||
378 | }*/ |
||||||
379 | |||||||
380 | $backup_file_stream = $this->xcloner_file_system->get_storage_filesystem()->readStream($file); |
||||||
381 | |||||||
382 | if (!$remote_storage_filesystem->writeStream($file, $backup_file_stream)) { |
||||||
383 | $this->logger->info(sprintf("Could not transfer file %s", $file)); |
||||||
384 | |||||||
385 | return false; |
||||||
386 | } |
||||||
387 | |||||||
388 | if ($this->xcloner_file_system->is_multipart($file)) { |
||||||
389 | $parts = $this->xcloner_file_system->get_multipart_files($file); |
||||||
390 | if (is_array($parts)) { |
||||||
391 | foreach ($parts as $part_file) { |
||||||
392 | $this->logger->info(sprintf("Transferring backup %s to remote storage %s", $part_file, |
||||||
393 | strtoupper($storage)), array("")); |
||||||
394 | |||||||
395 | $backup_file_stream = $this->xcloner_file_system->get_storage_filesystem()->readStream($part_file); |
||||||
396 | if (!$remote_storage_filesystem->writeStream($part_file, $backup_file_stream)) { |
||||||
397 | return false; |
||||||
398 | } |
||||||
399 | } |
||||||
400 | } |
||||||
401 | } |
||||||
402 | |||||||
403 | $this->logger->info(sprintf("Upload done, disconnecting from remote storage %s", strtoupper($storage))); |
||||||
404 | |||||||
405 | return true; |
||||||
406 | |||||||
407 | } |
||||||
408 | |||||||
409 | public function copy_backup_remote_to_local($file, $storage) |
||||||
410 | { |
||||||
411 | $method = "get_" . $storage . "_filesystem"; |
||||||
412 | |||||||
413 | $target_filename = $file; |
||||||
414 | |||||||
415 | if (!method_exists($this, $method)) { |
||||||
416 | return false; |
||||||
417 | } |
||||||
418 | |||||||
419 | list($remote_storage_adapter, $remote_storage_filesystem) = $this->$method(); |
||||||
420 | |||||||
421 | if (!$remote_storage_filesystem->has($file)) { |
||||||
422 | $this->logger->info(sprintf("File not found %s in remote storage %s", $file, strtoupper($storage))); |
||||||
423 | |||||||
424 | return false; |
||||||
425 | } |
||||||
426 | |||||||
427 | if ($storage == "gdrive") { |
||||||
428 | $metadata = $remote_storage_filesystem->getMetadata($file); |
||||||
429 | $target_filename = $metadata['filename'] . "." . $metadata['extension']; |
||||||
430 | } |
||||||
431 | |||||||
432 | $this->logger->info(sprintf("Transferring backup %s to local storage from %s storage", $file, |
||||||
433 | strtoupper($storage)), array("")); |
||||||
434 | |||||||
435 | $backup_file_stream = $remote_storage_filesystem->readStream($file); |
||||||
436 | |||||||
437 | if (!$this->xcloner_file_system->get_storage_filesystem()->writeStream($target_filename, $backup_file_stream)) { |
||||||
438 | $this->logger->info(sprintf("Could not transfer file %s", $file)); |
||||||
439 | |||||||
440 | return false; |
||||||
441 | } |
||||||
442 | |||||||
443 | if ($this->xcloner_file_system->is_multipart($target_filename)) { |
||||||
444 | $parts = $this->xcloner_file_system->get_multipart_files($file, $storage); |
||||||
445 | if (is_array($parts)) { |
||||||
446 | foreach ($parts as $part_file) { |
||||||
447 | $this->logger->info(sprintf("Transferring backup %s to local storage from %s storage", $part_file, |
||||||
448 | strtoupper($storage)), array("")); |
||||||
449 | |||||||
450 | $backup_file_stream = $remote_storage_filesystem->readStream($part_file); |
||||||
451 | if (!$this->xcloner_file_system->get_storage_filesystem()->writeStream($part_file, |
||||||
452 | $backup_file_stream)) { |
||||||
453 | return false; |
||||||
454 | } |
||||||
455 | } |
||||||
456 | } |
||||||
457 | } |
||||||
458 | |||||||
459 | $this->logger->info(sprintf("Upload done, disconnecting from remote storage %s", strtoupper($storage))); |
||||||
460 | |||||||
461 | return true; |
||||||
462 | |||||||
463 | } |
||||||
464 | |||||||
465 | public function clean_remote_storage($storage, $remote_storage_filesystem) |
||||||
466 | { |
||||||
467 | $check_field = $this->storage_fields["option_prefix"] . $storage . "_cleanup_days"; |
||||||
468 | if ($expire_days = get_option($check_field)) { |
||||||
469 | $this->logger->info(sprintf("Doing %s remote storage cleanup for %s days limit", strtoupper($storage), |
||||||
470 | $expire_days)); |
||||||
471 | $files = $remote_storage_filesystem->listContents(); |
||||||
472 | |||||||
473 | $current_timestamp = strtotime("-" . $expire_days . " days"); |
||||||
474 | |||||||
475 | if (is_array($files)) { |
||||||
476 | foreach ($files as $file) { |
||||||
477 | $file['timestamp'] = $remote_storage_filesystem->getTimestamp($file['path']); |
||||||
478 | |||||||
479 | if ($current_timestamp >= $file['timestamp']) { |
||||||
480 | $remote_storage_filesystem->delete($file['path']); |
||||||
481 | $this->logger->info("Deleting remote file " . $file['path'] . " matching rule", array( |
||||||
482 | "RETENTION LIMIT TIMESTAMP", |
||||||
483 | $file['timestamp'] . " =< " . $expire_days |
||||||
484 | )); |
||||||
485 | } |
||||||
486 | |||||||
487 | } |
||||||
488 | } |
||||||
489 | } |
||||||
490 | } |
||||||
491 | |||||||
492 | public function get_azure_filesystem() |
||||||
493 | { |
||||||
494 | $this->logger->info(sprintf("Creating the AZURE BLOB remote storage connection"), array("")); |
||||||
495 | |||||||
496 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
497 | throw new Exception("AZURE BLOB requires PHP 5.6 to be installed!"); |
||||||
498 | } |
||||||
499 | |||||||
500 | if (!class_exists('XmlWriter')) { |
||||||
501 | throw new Exception("AZURE BLOB requires libxml PHP module to be installed with XmlWriter class enabled!"); |
||||||
502 | } |
||||||
503 | |||||||
504 | $endpoint = sprintf( |
||||||
505 | 'DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s', |
||||||
506 | get_option("xcloner_azure_account_name"), |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_azure_account_name') can also be of type false ; however, parameter $args of sprintf() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
507 | get_option("xcloner_azure_api_key") |
||||||
508 | ); |
||||||
509 | |||||||
510 | $blobRestProxy = ServicesBuilder::getInstance()->createBlobService($endpoint); |
||||||
511 | |||||||
512 | $adapter = new AzureAdapter($blobRestProxy, get_option("xcloner_azure_container")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_azure_container') can also be of type false ; however, parameter $container of League\Flysystem\Azure\AzureAdapter::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
513 | |||||||
514 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
515 | 'disable_asserts' => true, |
||||||
516 | ])); |
||||||
517 | |||||||
518 | return array($adapter, $filesystem); |
||||||
519 | } |
||||||
520 | |||||||
521 | public function get_dropbox_filesystem() |
||||||
522 | { |
||||||
523 | $this->logger->info(sprintf("Creating the DROPBOX remote storage connection"), array("")); |
||||||
524 | |||||||
525 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
526 | throw new Exception("DROPBOX requires PHP 5.6 to be installed!"); |
||||||
527 | } |
||||||
528 | |||||||
529 | $client = new DropboxClient(get_option("xcloner_dropbox_access_token")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_dropbox_access_token') can also be of type false ; however, parameter $token of Srmklive\Dropbox\Client\...oxClient::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
530 | $adapter = new DropboxAdapter($client, get_option("xcloner_dropbox_prefix")); |
||||||
531 | |||||||
532 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
533 | 'disable_asserts' => true, |
||||||
534 | ])); |
||||||
535 | |||||||
536 | return array($adapter, $filesystem); |
||||||
537 | } |
||||||
538 | |||||||
539 | public function get_aws_filesystem() |
||||||
540 | { |
||||||
541 | $this->logger->info(sprintf("Creating the S3 remote storage connection"), array("")); |
||||||
542 | |||||||
543 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
544 | throw new Exception("S3 class requires PHP 5.6 to be installed!"); |
||||||
545 | } |
||||||
546 | |||||||
547 | if (!class_exists('XmlWriter')) { |
||||||
548 | throw new Exception("AZURE BLOB requires libxml PHP module to be installed with XmlWriter class enabled!"); |
||||||
549 | } |
||||||
550 | |||||||
551 | |||||||
552 | $credentials = array( |
||||||
553 | 'credentials' => array( |
||||||
554 | 'key' => get_option("xcloner_aws_key"), |
||||||
555 | 'secret' => get_option("xcloner_aws_secret") |
||||||
556 | ), |
||||||
557 | 'region' => get_option("xcloner_aws_region"), |
||||||
558 | 'version' => 'latest', |
||||||
559 | ); |
||||||
560 | |||||||
561 | if (get_option('xcloner_aws_endpoint') != "" && !get_option("xcloner_aws_region")) { |
||||||
562 | |||||||
563 | $credentials['endpoint'] = get_option('xcloner_aws_endpoint'); |
||||||
564 | #$credentials['use_path_style_endpoint'] = true; |
||||||
565 | #$credentials['bucket_endpoint'] = false; |
||||||
566 | |||||||
567 | |||||||
568 | } |
||||||
569 | |||||||
570 | $client = new S3Client($credentials); |
||||||
571 | |||||||
572 | $adapter = new AwsS3Adapter($client, get_option("xcloner_aws_bucket_name"), get_option("xcloner_aws_prefix")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_aws_bucket_name') can also be of type false ; however, parameter $bucket of League\Flysystem\AwsS3v3...3Adapter::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
get_option('xcloner_aws_prefix') can also be of type false ; however, parameter $prefix of League\Flysystem\AwsS3v3...3Adapter::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
573 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
574 | 'disable_asserts' => true, |
||||||
575 | ])); |
||||||
576 | |||||||
577 | return array($adapter, $filesystem); |
||||||
578 | } |
||||||
579 | |||||||
580 | public function get_backblaze_filesystem() |
||||||
581 | { |
||||||
582 | $this->logger->info(sprintf("Creating the BACKBLAZE remote storage connection"), array("")); |
||||||
583 | |||||||
584 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
585 | throw new Exception("BACKBLAZE API requires PHP 5.6 to be installed!"); |
||||||
586 | } |
||||||
587 | |||||||
588 | |||||||
589 | $client = new B2Client(get_option("xcloner_backblaze_account_id"), |
||||||
590 | get_option("xcloner_backblaze_application_key")); |
||||||
591 | $adapter = new BackblazeAdapter($client, get_option("xcloner_backblaze_bucket_name")); |
||||||
592 | |||||||
593 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
594 | 'disable_asserts' => true, |
||||||
595 | ])); |
||||||
596 | |||||||
597 | return array($adapter, $filesystem); |
||||||
598 | } |
||||||
599 | |||||||
600 | public function get_webdav_filesystem() |
||||||
601 | { |
||||||
602 | $this->logger->info(sprintf("Creating the WEBDAV remote storage connection"), array("")); |
||||||
603 | |||||||
604 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
605 | throw new Exception("WEBDAV API requires PHP 5.6 to be installed!"); |
||||||
606 | } |
||||||
607 | |||||||
608 | $settings = array( |
||||||
609 | 'baseUri' => get_option("xcloner_webdav_url"), |
||||||
610 | 'userName' => get_option("xcloner_webdav_username"), |
||||||
611 | 'password' => get_option("xcloner_webdav_password"), |
||||||
612 | //'proxy' => 'locahost:8888', |
||||||
613 | ); |
||||||
614 | |||||||
615 | |||||||
616 | $client = new SabreClient($settings); |
||||||
617 | $adapter = new WebDAVAdapter($client, get_option("xcloner_webdav_target_folder")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_webdav_target_folder') can also be of type false ; however, parameter $prefix of League\Flysystem\WebDAV\...VAdapter::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
618 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
619 | 'disable_asserts' => true, |
||||||
620 | ])); |
||||||
621 | |||||||
622 | return array($adapter, $filesystem); |
||||||
623 | } |
||||||
624 | |||||||
625 | |||||||
626 | public function gdrive_construct() |
||||||
627 | { |
||||||
628 | |||||||
629 | //if((function_exists("is_plugin_active") && !is_plugin_active("xcloner-google-drive/xcloner-google-drive.php")) || !file_exists(__DIR__ . "/../../xcloner-google-drive/vendor/autoload.php")) |
||||||
630 | if (!class_exists('Google_Client')) { |
||||||
631 | return false; |
||||||
632 | } |
||||||
633 | |||||||
634 | //require_once(__DIR__ . "/../../xcloner-google-drive/vendor/autoload.php"); |
||||||
635 | |||||||
636 | $client = new \Google_Client(); |
||||||
637 | $client->setApplicationName($this->gdrive_app_name); |
||||||
638 | $client->setClientId(get_option("xcloner_gdrive_client_id")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_gdrive_client_id') can also be of type false ; however, parameter $clientId of Google_Client::setClientId() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
639 | $client->setClientSecret(get_option("xcloner_gdrive_client_secret")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_gdrive_client_secret') can also be of type false ; however, parameter $clientSecret of Google_Client::setClientSecret() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
640 | |||||||
641 | //$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']."?page=xcloner_remote_storage_page&action=set_gdrive_code"; |
||||||
642 | $redirect_uri = "urn:ietf:wg:oauth:2.0:oob"; |
||||||
643 | |||||||
644 | $client->setRedirectUri($redirect_uri); //urn:ietf:wg:oauth:2.0:oob |
||||||
645 | $client->addScope("https://www.googleapis.com/auth/drive"); |
||||||
646 | $client->setAccessType('offline'); |
||||||
647 | |||||||
648 | return $client; |
||||||
649 | } |
||||||
650 | |||||||
651 | public function get_gdrive_auth_url() |
||||||
652 | { |
||||||
653 | $client = $this->gdrive_construct(); |
||||||
654 | |||||||
655 | if (!$client) { |
||||||
656 | return false; |
||||||
657 | } |
||||||
658 | |||||||
659 | return $authUrl = $client->createAuthUrl(); |
||||||
0 ignored issues
–
show
|
|||||||
660 | } |
||||||
661 | |||||||
662 | public function set_access_token($code) |
||||||
663 | { |
||||||
664 | $client = $this->gdrive_construct(); |
||||||
665 | |||||||
666 | if (!$client) { |
||||||
667 | $error_msg = "Could not initialize the Google Drive Class, please check that the xcloner-google-drive plugin is enabled..."; |
||||||
668 | $this->logger->error($error_msg); |
||||||
669 | |||||||
670 | return false; |
||||||
671 | } |
||||||
672 | |||||||
673 | $token = $client->fetchAccessTokenWithAuthCode($code); |
||||||
674 | $client->setAccessToken($token); |
||||||
675 | |||||||
676 | update_option("xcloner_gdrive_access_token", $token['access_token']); |
||||||
677 | update_option("xcloner_gdrive_refresh_token", $token['refresh_token']); |
||||||
678 | |||||||
679 | $redirect_url = ('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . "?page=xcloner_remote_storage_page#gdrive"); |
||||||
680 | |||||||
681 | ?> |
||||||
682 | <script> |
||||||
683 | window.location = '<?php echo $redirect_url?>'; |
||||||
684 | </script> |
||||||
685 | <?php |
||||||
686 | |||||||
687 | } |
||||||
688 | |||||||
689 | /* |
||||||
690 | * php composer.phar remove nao-pon/flysystem-google-drive |
||||||
691 | * |
||||||
692 | */ |
||||||
693 | public function get_gdrive_filesystem() |
||||||
694 | { |
||||||
695 | |||||||
696 | if (version_compare(phpversion(), '5.6.0', '<')) { |
||||||
697 | throw new Exception("Google Drive API requires PHP 5.6 to be installed!"); |
||||||
698 | } |
||||||
699 | |||||||
700 | $this->logger->info(sprintf("Creating the Google Drive remote storage connection"), array("")); |
||||||
701 | |||||||
702 | $client = $this->gdrive_construct(); |
||||||
703 | |||||||
704 | if (!$client) { |
||||||
705 | $error_msg = "Could not initialize the Google Drive Class, please check that the xcloner-google-drive plugin is enabled..."; |
||||||
706 | $this->logger->error($error_msg); |
||||||
707 | throw new Exception($error_msg); |
||||||
708 | } |
||||||
709 | |||||||
710 | $client->refreshToken(get_option("xcloner_gdrive_refresh_token")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_gdrive_refresh_token') can also be of type false ; however, parameter $refreshToken of Google_Client::refreshToken() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
711 | |||||||
712 | $service = new \Google_Service_Drive($client); |
||||||
713 | |||||||
714 | if (get_option("xcloner_gdrive_empty_trash", 0)) { |
||||||
715 | $this->logger->info(sprintf("Doing a Google Drive emptyTrash call"), array("")); |
||||||
716 | $service->files->emptyTrash(); |
||||||
717 | } |
||||||
718 | |||||||
719 | $parent = 'root'; |
||||||
720 | $dir = basename(get_option("xcloner_gdrive_target_folder")); |
||||||
0 ignored issues
–
show
It seems like
get_option('xcloner_gdrive_target_folder') can also be of type false ; however, parameter $path of basename() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
721 | |||||||
722 | $folderID = get_option("xcloner_gdrive_target_folder"); |
||||||
723 | |||||||
724 | $tmp = parse_url($folderID); |
||||||
0 ignored issues
–
show
It seems like
$folderID can also be of type false ; however, parameter $url of parse_url() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
725 | |||||||
726 | if (isset($tmp['query'])) { |
||||||
727 | $folderID = str_replace("id=", "", $tmp['query']); |
||||||
728 | } |
||||||
729 | |||||||
730 | if (stristr($folderID, "/")) { |
||||||
731 | $query = sprintf('mimeType = \'application/vnd.google-apps.folder\' and \'%s\' in parents and name contains \'%s\'', |
||||||
732 | $parent, $dir); |
||||||
733 | $response = $service->files->listFiles([ |
||||||
734 | 'pageSize' => 1, |
||||||
735 | 'q' => $query |
||||||
736 | ]); |
||||||
737 | |||||||
738 | if (sizeof($response)) { |
||||||
739 | foreach ($response as $obj) { |
||||||
740 | $folderID = $obj->getId(); |
||||||
741 | } |
||||||
742 | } else { |
||||||
743 | $this->xcloner->trigger_message(sprintf(__("Could not find folder ID by name %s", |
||||||
744 | 'xcloner-backup-and-restore'), $folderID), "error"); |
||||||
745 | } |
||||||
746 | } |
||||||
747 | |||||||
748 | $this->logger->info(sprintf("Using target folder with ID %s on the remote storage", $folderID)); |
||||||
749 | |||||||
750 | if (class_exists('XCloner_Google_Drive_Adapter')) { |
||||||
751 | $adapter = new XCloner_Google_Drive_Adapter($service, $folderID); |
||||||
0 ignored issues
–
show
The type
XCloner_Google_Drive_Adapter 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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||
752 | } else { |
||||||
753 | $adapter = new \Hypweb\Flysystem\GoogleDrive\GoogleDriveAdapter($service, $folderID); |
||||||
754 | } |
||||||
755 | |||||||
756 | $filesystem = new \League\Flysystem\Filesystem($adapter, new Config([ |
||||||
757 | 'disable_asserts' => true, |
||||||
758 | ])); |
||||||
759 | |||||||
760 | |||||||
761 | return array($adapter, $filesystem); |
||||||
762 | } |
||||||
763 | |||||||
764 | public function get_ftp_filesystem() |
||||||
765 | { |
||||||
766 | $this->logger->info(sprintf("Creating the FTP remote storage connection"), array("")); |
||||||
767 | |||||||
768 | $adapter = new Adapter([ |
||||||
769 | 'host' => get_option("xcloner_ftp_hostname"), |
||||||
770 | 'username' => get_option("xcloner_ftp_username"), |
||||||
771 | 'password' => get_option("xcloner_ftp_password"), |
||||||
772 | |||||||
773 | /** optional config settings */ |
||||||
774 | 'port' => get_option("xcloner_ftp_port", 21), |
||||||
775 | 'root' => get_option("xcloner_ftp_path"), |
||||||
776 | 'passive' => get_option("xcloner_ftp_transfer_mode"), |
||||||
777 | 'ssl' => get_option("xcloner_ftp_ssl_mode"), |
||||||
778 | 'timeout' => get_option("xcloner_ftp_timeout", 30), |
||||||
779 | ]); |
||||||
780 | |||||||
781 | $adapter->connect(); |
||||||
782 | |||||||
783 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
784 | 'disable_asserts' => true, |
||||||
785 | ])); |
||||||
786 | |||||||
787 | return array($adapter, $filesystem); |
||||||
788 | } |
||||||
789 | |||||||
790 | public function get_sftp_filesystem() |
||||||
791 | { |
||||||
792 | $this->logger->info(sprintf("Creating the SFTP remote storage connection"), array("")); |
||||||
793 | |||||||
794 | $adapter = new SftpAdapter([ |
||||||
795 | 'host' => get_option("xcloner_sftp_hostname"), |
||||||
796 | 'username' => get_option("xcloner_sftp_username"), |
||||||
797 | 'password' => get_option("xcloner_sftp_password"), |
||||||
798 | |||||||
799 | /** optional config settings */ |
||||||
800 | 'port' => get_option("xcloner_sftp_port", 22), |
||||||
801 | 'root' => (get_option("xcloner_sftp_path")?get_option("xcloner_sftp_path"):'./'), |
||||||
802 | 'privateKey' => get_option("xcloner_sftp_private_key"), |
||||||
803 | 'timeout' => get_option("xcloner_ftp_timeout", 30), |
||||||
804 | ]); |
||||||
805 | |||||||
806 | $adapter->connect(); |
||||||
807 | |||||||
808 | $filesystem = new Filesystem($adapter, new Config([ |
||||||
809 | 'disable_asserts' => true, |
||||||
810 | ])); |
||||||
811 | |||||||
812 | return array($adapter, $filesystem); |
||||||
813 | } |
||||||
814 | |||||||
815 | public function change_storage_status($field, $value) |
||||||
816 | { |
||||||
817 | $field = $this->xcloner_sanitization->sanitize_input_as_string($field); |
||||||
818 | $value = $this->xcloner_sanitization->sanitize_input_as_int($value); |
||||||
819 | |||||||
820 | return update_option($field, $value); |
||||||
821 | } |
||||||
822 | |||||||
823 | public function get_aws_regions() |
||||||
824 | { |
||||||
825 | return $this->aws_regions; |
||||||
826 | } |
||||||
827 | |||||||
828 | } |
||||||
829 |
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.