Version Description
- added AES-128-CBC backup encryption and decryption option
- manage backup fixes
- scheduled backup screen fixes and addon backup encryption option
- automated backups encryption option addon
- generate backups encrypt option addon
Download this release
Release Info
Developer | xcloner |
Plugin | XCloner – Backup and Restore |
Version | 4.1.0 |
Comparing to | |
See all releases |
Code changes from version 4.0.9 to 4.1.0
- README.md +4 -1
- README.txt +12 -3
- admin/class-xcloner-admin.php +79 -72
- admin/css/xcloner-admin.css +18 -1
- admin/js/xcloner-backup-class.js +55 -0
- admin/js/xcloner-manage-backups-class.js +433 -311
- admin/js/xcloner-scheduler-class.js +7 -0
- admin/partials/xcloner_console_page.php +4 -4
- admin/partials/xcloner_generate_backups_page.php +106 -67
- admin/partials/xcloner_init_page.php +64 -64
- admin/partials/xcloner_manage_backups_page.php +92 -10
- admin/partials/xcloner_remote_storage_page.php +197 -197
- admin/partials/xcloner_restore_page.php +75 -75
- admin/partials/xcloner_scheduled_backups_page.php +56 -45
- composer.json +4 -3
- composer.lock +20 -137
- includes/class-xcloner-activator.php +42 -38
- includes/class-xcloner-api.php +1249 -898
- includes/class-xcloner-archive.php +532 -508
- includes/class-xcloner-database.php +103 -98
- includes/class-xcloner-deactivator.php +3 -3
- includes/class-xcloner-encryption.php +394 -0
- includes/class-xcloner-file-system.php +195 -182
- includes/class-xcloner-file-transfer.php +100 -99
- includes/class-xcloner-i18n.php +13 -13
- includes/class-xcloner-loader.php +162 -149
- includes/class-xcloner-logger.php +43 -30
- includes/class-xcloner-remote-storage.php +586 -536
- includes/class-xcloner-requirements.php +40 -40
- includes/class-xcloner-sanitization.php +22 -22
- includes/class-xcloner-scheduler.php +180 -114
- includes/class-xcloner-settings.php +294 -228
- includes/class-xcloner.php +161 -119
- public/class-xcloner-public.php +3 -5
- restore/xcloner_restore.php +508 -271
- uninstall.php +1 -1
- vendor/composer/ClassLoader.php +2 -2
- vendor/composer/autoload_files.php +0 -1
- vendor/composer/autoload_psr4.php +0 -1
- vendor/composer/autoload_static.php +0 -9
- vendor/composer/installed.json +22 -143
- vendor/defuse/php-encryption/.gitignore +0 -11
- vendor/defuse/php-encryption/.php_cs +0 -60
- vendor/defuse/php-encryption/LICENSE +0 -21
- vendor/defuse/php-encryption/README.md +0 -102
- vendor/defuse/php-encryption/bin/generate-defuse-key +0 -14
- vendor/defuse/php-encryption/composer.json +0 -35
- vendor/defuse/php-encryption/dist/Makefile +0 -37
- vendor/defuse/php-encryption/dist/box.json +0 -25
- vendor/defuse/php-encryption/dist/signingkey.asc +0 -52
- vendor/defuse/php-encryption/docs/CryptoDetails.md +0 -64
- vendor/defuse/php-encryption/docs/FAQ.md +0 -51
- vendor/defuse/php-encryption/docs/InstallingAndVerifying.md +0 -53
- vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md +0 -166
- vendor/defuse/php-encryption/docs/Tutorial.md +0 -314
- vendor/defuse/php-encryption/docs/UpgradingFromV1.2.md +0 -51
- vendor/defuse/php-encryption/docs/classes/Crypto.md +0 -280
- vendor/defuse/php-encryption/docs/classes/File.md +0 -486
- vendor/defuse/php-encryption/docs/classes/Key.md +0 -117
- vendor/defuse/php-encryption/docs/classes/KeyProtectedByPassword.md +0 -259
- vendor/defuse/php-encryption/psalm.xml +0 -12
- vendor/defuse/php-encryption/src/Core.php +0 -448
- vendor/defuse/php-encryption/src/Crypto.php +0 -445
- vendor/defuse/php-encryption/src/DerivedKeys.php +0 -50
- vendor/defuse/php-encryption/src/Encoding.php +0 -268
- vendor/defuse/php-encryption/src/Exception/BadFormatException.php +0 -7
- vendor/defuse/php-encryption/src/Exception/CryptoException.php +0 -7
- vendor/defuse/php-encryption/src/Exception/EnvironmentIsBrokenException.php +0 -7
- vendor/defuse/php-encryption/src/Exception/IOException.php +0 -7
- vendor/defuse/php-encryption/src/Exception/WrongKeyOrModifiedCiphertextException.php +0 -7
- vendor/defuse/php-encryption/src/File.php +0 -762
- vendor/defuse/php-encryption/src/Key.php +0 -94
- vendor/defuse/php-encryption/src/KeyOrPassword.php +0 -149
- vendor/defuse/php-encryption/src/KeyProtectedByPassword.php +0 -145
- vendor/defuse/php-encryption/src/RuntimeTests.php +0 -228
- vendor/gliterd/backblaze-b2/.gitignore +7 -0
- vendor/gliterd/backblaze-b2/.scrutinizer.yml +33 -0
- vendor/gliterd/backblaze-b2/.travis.yml +9 -0
- vendor/league/flysystem-sftp/.travis.yml +1 -5
- vendor/league/flysystem-sftp/changelog.md +21 -0
- vendor/league/flysystem-sftp/composer.json +3 -8
- vendor/league/flysystem-sftp/phpunit.xml +0 -1
- vendor/league/flysystem-sftp/readme.md +5 -0
- vendor/league/flysystem-sftp/src/SftpAdapter.php +13 -6
- vendor/league/flysystem-sftp/tests/SftpAdapterTests.php +54 -10
- vendor/league/flysystem/.travis.yml +1 -1
- vendor/league/flysystem/README.md +4 -1
- vendor/league/flysystem/changelog.md +21 -0
- vendor/league/flysystem/composer.json +3 -3
- vendor/league/flysystem/docs/_data/menu.yml +1 -0
- vendor/league/flysystem/docs/_data/project.yml +1 -1
- vendor/league/flysystem/docs/_includes/carbon.html +1 -1
- vendor/league/flysystem/docs/_layouts/default.html +19 -19
- vendor/league/flysystem/docs/adapter/azure.md +17 -11
- vendor/league/flysystem/docs/adapter/phpcr.md +17 -1
- vendor/league/flysystem/docs/adapter/sftp.md +1 -1
- vendor/league/flysystem/docs/advanced/caching.md +1 -1
- vendor/league/flysystem/docs/advanced/mount-manager.md +2 -2
- vendor/league/flysystem/docs/advanced/performance.md +1 -1
- vendor/league/flysystem/docs/advanced/provided-plugins.md +1 -1
- vendor/league/flysystem/docs/advanced/upgrade-to-1.0.0.md +1 -1
- vendor/league/flysystem/docs/api.md +4 -4
- vendor/league/flysystem/docs/architecture.md +1 -1
- vendor/league/flysystem/docs/dist/styles.css +1 -1
- vendor/league/flysystem/docs/github.css +2 -2
- vendor/league/flysystem/docs/guides/deterministic-programming.md +3 -3
- vendor/league/flysystem/docs/img/azure.svg +69 -1
- vendor/league/flysystem/docs/index.css +1 -1
- vendor/league/flysystem/docs/index.md +17 -4
- vendor/league/flysystem/docs/sponsors.md +15 -9
- vendor/league/flysystem/docs/tailwind.js +1 -0
- vendor/league/flysystem/docs/usage/filesystem-api.md +59 -4
- vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php +0 -5
- vendor/league/flysystem/src/Adapter/Local.php +14 -15
- vendor/league/flysystem/src/MountManager.php +351 -23
- vendor/league/flysystem/src/Util/MimeType.php +164 -168
- vendor/league/flysystem/stub/FilesystemSpy.php +354 -0
- vendor/league/flysystem/tests/FtpTests.php +25 -0
- vendor/league/flysystem/tests/LocalAdapterTests.php +11 -0
- vendor/league/flysystem/tests/MountManagerTests.php +55 -15
- vendor/league/flysystem/tests/UtilMimeTests.php +7 -0
- vendor/paragonie/random_compat/LICENSE +0 -22
- vendor/paragonie/random_compat/build-phar.sh +0 -5
- vendor/paragonie/random_compat/composer.json +0 -38
- vendor/paragonie/random_compat/dist/random_compat.phar.pubkey +0 -5
- vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc +0 -11
- vendor/paragonie/random_compat/lib/byte_safe_strings.php +0 -181
- vendor/paragonie/random_compat/lib/cast_to_int.php +0 -75
- vendor/paragonie/random_compat/lib/error_polyfill.php +0 -49
- vendor/paragonie/random_compat/lib/random.php +0 -226
- vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php +0 -88
- vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php +0 -167
- vendor/paragonie/random_compat/lib/random_bytes_libsodium.php +0 -88
- vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php +0 -92
- vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php +0 -77
- vendor/paragonie/random_compat/lib/random_int.php +0 -190
- vendor/paragonie/random_compat/other/build_phar.php +0 -57
- vendor/paragonie/random_compat/psalm-autoload.php +0 -9
- vendor/paragonie/random_compat/psalm.xml +0 -19
- vendor/vakata/jstree/README.md +2 -2
- vendor/vakata/jstree/bower.json +1 -1
- vendor/vakata/jstree/component.json +1 -1
- vendor/vakata/jstree/dist/jstree.js +15 -11
README.md
CHANGED
@@ -2,10 +2,12 @@
|
|
2 |
|
3 |
[![Author](http://img.shields.io/badge/author-@thinkovi-blue.svg?style=flat-square)](https://twitter.com/thinkovi)
|
4 |
[![Software License](https://img.shields.io/badge/license-GPL-brightgreen.svg?style=flat-square)](LICENSE.txt)
|
5 |
-
[![
|
|
|
6 |
|
7 |
Backup your Wordpress site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
|
8 |
|
|
|
9 |
XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
|
10 |
|
11 |
XCloner design was specifically created to Generate custom backups of any LAMP website through custom admin inputs, and to be able to Restore the clone on any other location with the help of the automatic Restore script we provide!
|
@@ -16,6 +18,7 @@ XCloner Backup tool uses Open Source standards like TAR, Mysql and CSV formats s
|
|
16 |
|
17 |
* Backup and Restore your Wordpress site easily
|
18 |
* Create compressed and uncompressed backups using TAR open source format
|
|
|
19 |
* Create automated backups from your Scheduled Backups Section
|
20 |
* Received email notifications of created backups
|
21 |
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
2 |
|
3 |
[![Author](http://img.shields.io/badge/author-@thinkovi-blue.svg?style=flat-square)](https://twitter.com/thinkovi)
|
4 |
[![Software License](https://img.shields.io/badge/license-GPL-brightgreen.svg?style=flat-square)](LICENSE.txt)
|
5 |
+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ovidiul/XCloner-Wordpress/badges/quality-score.png?b=dev)](https://scrutinizer-ci.com/g/ovidiul/XCloner-Wordpress/?branch=master)
|
6 |
+
[![Build Status](https://scrutinizer-ci.com/g/ovidiul/XCloner-Wordpress/badges/build.png?b=dev)](https://scrutinizer-ci.com/g/ovidiul/XCloner-Wordpress/build-status/master)
|
7 |
|
8 |
Backup your Wordpress site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
|
9 |
|
10 |
+
|
11 |
XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
|
12 |
|
13 |
XCloner design was specifically created to Generate custom backups of any LAMP website through custom admin inputs, and to be able to Restore the clone on any other location with the help of the automatic Restore script we provide!
|
18 |
|
19 |
* Backup and Restore your Wordpress site easily
|
20 |
* Create compressed and uncompressed backups using TAR open source format
|
21 |
+
* Create encrypted backups archives with AES-128-CBC algorithm
|
22 |
* Create automated backups from your Scheduled Backups Section
|
23 |
* Received email notifications of created backups
|
24 |
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
README.txt
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
=== XCloner - Backup and Restore===
|
2 |
Contributors: xcloner
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AAPE8PLAE554S
|
4 |
-
Tags: backup plugin, restore plugin, database backup,
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 5.0
|
7 |
-
Stable tag: 4.0
|
8 |
|
9 |
-
Backup your site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP, WebDAV, Google Drive with XCloner plugin.
|
10 |
|
11 |
== Description ==
|
12 |
|
@@ -28,6 +28,7 @@ PHP 5.6+ with mod CURL installed
|
|
28 |
|
29 |
* Backup and Restore your Wordpress site easily
|
30 |
* Create compressed and uncompressed backups using TAR open source format
|
|
|
31 |
* Create automated backups from your Scheduled Backups Section
|
32 |
* Received email notifications of created backups
|
33 |
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
@@ -38,6 +39,7 @@ PHP 5.6+ with mod CURL installed
|
|
38 |
* Ability to split backups into multiple smaller parts if a certain size limit is reached
|
39 |
* Generate Differential Backups so your backup will include only files modified after a certain date, giving you the option to decrease the total backup space disk usage
|
40 |
* Generate automatic backups before a Wordpress automatic update
|
|
|
41 |
|
42 |
== Installation ==
|
43 |
|
@@ -112,6 +114,13 @@ Immigration Attorney Montana <a href="https://www.immigrationlawofmt.com" target
|
|
112 |
|
113 |
== Changelog ==
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
= 4.0.9 =
|
116 |
* remote storage password encryption addon for database
|
117 |
* vendor cleanup packages
|
1 |
=== XCloner - Backup and Restore===
|
2 |
Contributors: xcloner
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AAPE8PLAE554S
|
4 |
+
Tags: backup plugin, restore plugin, database backup, backup encryption, site backup, website cloner, wordpress backup, database restore, webdav, azure, ftp, sftp, amazon s3, dropbox, google drive, differential backup
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 5.0
|
7 |
+
Stable tag: 4.1.0
|
8 |
|
9 |
+
Backup your site, restore to any web location, encrypt and send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP, WebDAV, Google Drive with XCloner plugin.
|
10 |
|
11 |
== Description ==
|
12 |
|
28 |
|
29 |
* Backup and Restore your Wordpress site easily
|
30 |
* Create compressed and uncompressed backups using TAR open source format
|
31 |
+
* Create encrypted backups archives with AES-128-CBC algorithm
|
32 |
* Create automated backups from your Scheduled Backups Section
|
33 |
* Received email notifications of created backups
|
34 |
* Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
|
39 |
* Ability to split backups into multiple smaller parts if a certain size limit is reached
|
40 |
* Generate Differential Backups so your backup will include only files modified after a certain date, giving you the option to decrease the total backup space disk usage
|
41 |
* Generate automatic backups before a Wordpress automatic update
|
42 |
+
* GDPR compliant by added encryption data
|
43 |
|
44 |
== Installation ==
|
45 |
|
114 |
|
115 |
== Changelog ==
|
116 |
|
117 |
+
= 4.1.0 =
|
118 |
+
* added AES-128-CBC backup encryption and decryption option
|
119 |
+
* manage backup fixes
|
120 |
+
* scheduled backup screen fixes and addon backup encryption option
|
121 |
+
* automated backups encryption option addon
|
122 |
+
* generate backups encrypt option addon
|
123 |
+
|
124 |
= 4.0.9 =
|
125 |
* remote storage password encryption addon for database
|
126 |
* vendor cleanup packages
|
admin/class-xcloner-admin.php
CHANGED
@@ -40,23 +40,27 @@ class Xcloner_Admin {
|
|
40 |
*/
|
41 |
private $version;
|
42 |
|
|
|
|
|
|
|
43 |
private $xcloner_container;
|
44 |
|
45 |
/**
|
46 |
* Initialize the class and set its properties.
|
47 |
*
|
48 |
-
*
|
49 |
-
*
|
50 |
-
* @param string $plugin_name The name of this plugin.
|
51 |
-
* @param string $version The version of this plugin.
|
52 |
*/
|
53 |
-
public function __construct(
|
54 |
|
55 |
$this->plugin_name = $xcloner_container->get_plugin_name();
|
56 |
$this->version = $xcloner_container->get_version();
|
57 |
$this->xcloner_container = $xcloner_container;
|
58 |
}
|
59 |
|
|
|
|
|
|
|
60 |
public function get_xcloner_container() {
|
61 |
return $this->xcloner_container;
|
62 |
}
|
@@ -66,9 +70,9 @@ class Xcloner_Admin {
|
|
66 |
*
|
67 |
* @since 1.0.0
|
68 |
*/
|
69 |
-
public function enqueue_styles(
|
70 |
|
71 |
-
if (
|
72 |
return;
|
73 |
}
|
74 |
|
@@ -84,13 +88,13 @@ class Xcloner_Admin {
|
|
84 |
* class.
|
85 |
*/
|
86 |
|
87 |
-
wp_enqueue_style(
|
88 |
-
wp_enqueue_style(
|
89 |
-
wp_enqueue_style(
|
90 |
-
wp_enqueue_style(
|
91 |
-
wp_enqueue_style(
|
92 |
-
wp_enqueue_style(
|
93 |
-
wp_enqueue_style(
|
94 |
|
95 |
}
|
96 |
|
@@ -99,9 +103,9 @@ class Xcloner_Admin {
|
|
99 |
*
|
100 |
* @since 1.0.0
|
101 |
*/
|
102 |
-
public function enqueue_scripts(
|
103 |
|
104 |
-
if (
|
105 |
return;
|
106 |
}
|
107 |
|
@@ -118,97 +122,100 @@ class Xcloner_Admin {
|
|
118 |
*/
|
119 |
|
120 |
add_thickbox();
|
121 |
-
wp_enqueue_script(
|
122 |
-
wp_enqueue_script(
|
123 |
-
wp_enqueue_script(
|
124 |
-
wp_enqueue_script(
|
125 |
-
wp_enqueue_script(
|
126 |
-
wp_enqueue_script(
|
127 |
-
wp_enqueue_script(
|
128 |
-
wp_enqueue_script(
|
129 |
-
wp_enqueue_script(
|
130 |
-
wp_enqueue_script(
|
131 |
-
wp_enqueue_script(
|
132 |
-
wp_enqueue_script(
|
133 |
-
wp_enqueue_script(
|
134 |
|
135 |
|
136 |
}
|
137 |
|
138 |
public function xcloner_init_page() {
|
139 |
-
require_once(
|
140 |
|
141 |
}
|
142 |
|
|
|
|
|
|
|
143 |
public function xcloner_remote_storage_page() {
|
144 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
145 |
$remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
146 |
|
147 |
|
148 |
-
if (
|
149 |
-
$_POST['action'] = $xcloner_sanitization->sanitize_input_as_string(
|
150 |
-
$remote_storage->save(
|
151 |
}
|
152 |
|
153 |
-
if (
|
154 |
-
$_POST['authentification_code'] = $xcloner_sanitization->sanitize_input_as_string(
|
155 |
|
156 |
-
$remote_storage->set_access_token(
|
157 |
}
|
158 |
|
159 |
-
if (
|
160 |
-
$remote_storage->check(
|
161 |
}
|
162 |
|
163 |
-
require_once(
|
164 |
|
165 |
}
|
166 |
|
167 |
public function xcloner_scheduled_backups_page() {
|
168 |
$requirements = $this->xcloner_container->get_xcloner_requirements();
|
169 |
|
170 |
-
if (
|
171 |
-
require_once(
|
172 |
|
173 |
return false;
|
174 |
}
|
175 |
|
176 |
-
require_once(
|
177 |
|
178 |
}
|
179 |
|
180 |
public function xcloner_manage_backups_page() {
|
181 |
-
require_once(
|
182 |
|
183 |
}
|
184 |
|
185 |
public function xcloner_debugger_page() {
|
186 |
-
require_once(
|
187 |
|
188 |
}
|
189 |
|
190 |
public function xcloner_restore_page() {
|
191 |
-
require_once(
|
192 |
|
193 |
}
|
194 |
|
195 |
public function xcloner_generate_backups_page() {
|
196 |
$requirements = $this->xcloner_container->get_xcloner_requirements();
|
197 |
|
198 |
-
if (
|
199 |
-
require_once(
|
200 |
|
201 |
return false;
|
202 |
}
|
203 |
|
204 |
-
require_once(
|
205 |
|
206 |
return;
|
207 |
}
|
208 |
|
209 |
public function xcloner_settings_page() {
|
210 |
// check user capabilities
|
211 |
-
if (
|
212 |
return;
|
213 |
}
|
214 |
|
@@ -216,40 +223,40 @@ class Xcloner_Admin {
|
|
216 |
|
217 |
// check if the user have submitted the settings
|
218 |
// wordpress will add the "settings-updated" $_GET parameter to the url
|
219 |
-
if (
|
220 |
// add settings saved message with the class of "updated"
|
221 |
-
add_settings_error(
|
222 |
}
|
223 |
|
224 |
// show error/update messages
|
225 |
-
settings_errors(
|
226 |
?>
|
227 |
|
228 |
<?php
|
229 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
230 |
|
231 |
-
if (
|
232 |
-
$active_tab = $xcloner_sanitization->sanitize_input_as_string(
|
233 |
} // end if
|
234 |
else {
|
235 |
$active_tab = "general_options";
|
236 |
}
|
237 |
|
238 |
?>
|
239 |
-
<h1><?= esc_html(
|
240 |
|
241 |
<ul class="nav-tab-wrapper row">
|
242 |
<li><a href="?page=xcloner_settings_page&tab=general_options"
|
243 |
-
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'general_options' ? 'nav-tab-active' : ''; ?>"><?php echo __(
|
244 |
</li>
|
245 |
<li><a href="?page=xcloner_settings_page&tab=mysql_options"
|
246 |
-
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'mysql_options' ? 'nav-tab-active' : ''; ?>"><?php echo __(
|
247 |
</li>
|
248 |
<li><a href="?page=xcloner_settings_page&tab=system_options"
|
249 |
-
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'system_options' ? 'nav-tab-active' : ''; ?>"><?php echo __(
|
250 |
</li>
|
251 |
<li><a href="?page=xcloner_settings_page&tab=cleanup_options"
|
252 |
-
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cleanup_options' ? 'nav-tab-active' : ''; ?>"><?php echo __(
|
253 |
</li>
|
254 |
</ul>
|
255 |
|
@@ -258,27 +265,27 @@ class Xcloner_Admin {
|
|
258 |
<form action="options.php" method="post">
|
259 |
<?php
|
260 |
|
261 |
-
if (
|
262 |
|
263 |
-
settings_fields(
|
264 |
-
do_settings_sections(
|
265 |
|
266 |
-
} elseif (
|
267 |
|
268 |
-
settings_fields(
|
269 |
-
do_settings_sections(
|
270 |
-
} elseif (
|
271 |
|
272 |
-
settings_fields(
|
273 |
-
do_settings_sections(
|
274 |
-
} elseif (
|
275 |
|
276 |
-
settings_fields(
|
277 |
-
do_settings_sections(
|
278 |
}
|
279 |
|
280 |
// output save settings button
|
281 |
-
submit_button(
|
282 |
?>
|
283 |
</form>
|
284 |
|
40 |
*/
|
41 |
private $version;
|
42 |
|
43 |
+
/**
|
44 |
+
* @var Xcloner
|
45 |
+
*/
|
46 |
private $xcloner_container;
|
47 |
|
48 |
/**
|
49 |
* Initialize the class and set its properties.
|
50 |
*
|
51 |
+
* Xcloner_Admin constructor.
|
52 |
+
* @param Xcloner $xcloner_container
|
|
|
|
|
53 |
*/
|
54 |
+
public function __construct(Xcloner $xcloner_container) {
|
55 |
|
56 |
$this->plugin_name = $xcloner_container->get_plugin_name();
|
57 |
$this->version = $xcloner_container->get_version();
|
58 |
$this->xcloner_container = $xcloner_container;
|
59 |
}
|
60 |
|
61 |
+
/**
|
62 |
+
* @return Xcloner
|
63 |
+
*/
|
64 |
public function get_xcloner_container() {
|
65 |
return $this->xcloner_container;
|
66 |
}
|
70 |
*
|
71 |
* @since 1.0.0
|
72 |
*/
|
73 |
+
public function enqueue_styles($hook) {
|
74 |
|
75 |
+
if (!stristr($hook, "page_".$this->plugin_name) || (isset($_GET['option']) and $_GET['option'] == "com_cloner")) {
|
76 |
return;
|
77 |
}
|
78 |
|
88 |
* class.
|
89 |
*/
|
90 |
|
91 |
+
wp_enqueue_style($this->plugin_name."_materialize", plugin_dir_url(__FILE__).'css/materialize.min.css', array(), $this->version, 'all');
|
92 |
+
wp_enqueue_style($this->plugin_name."_materialize.clockpicker", plugin_dir_url(__FILE__).'css/materialize.clockpicker.css', array(), $this->version, 'all');
|
93 |
+
wp_enqueue_style($this->plugin_name."_materialize.icons", '//fonts.googleapis.com/icon?family=Material+Icons', array(), $this->version, 'all');
|
94 |
+
wp_enqueue_style($this->plugin_name."_jquery.datatables", plugin_dir_url(__FILE__).'css/jquery.dataTables.min.css', array(), $this->version, 'all');
|
95 |
+
wp_enqueue_style($this->plugin_name."_jquery.datatables.responsive", plugin_dir_url(__FILE__).'css/responsive.dataTables.css', array(), $this->version, 'all');
|
96 |
+
wp_enqueue_style($this->plugin_name."_jstree", dirname(plugin_dir_url(__FILE__)).'/vendor/vakata/jstree/dist/themes/default/style.min.css', array(), '3.3', 'all');
|
97 |
+
wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__).'css/xcloner-admin.css', array(), $this->version, 'all');
|
98 |
|
99 |
}
|
100 |
|
103 |
*
|
104 |
* @since 1.0.0
|
105 |
*/
|
106 |
+
public function enqueue_scripts($hook) {
|
107 |
|
108 |
+
if (!stristr($hook, "page_".$this->plugin_name)) {
|
109 |
return;
|
110 |
}
|
111 |
|
122 |
*/
|
123 |
|
124 |
add_thickbox();
|
125 |
+
wp_enqueue_script('plugin-install');
|
126 |
+
wp_enqueue_script('updates');
|
127 |
+
wp_enqueue_script($this->plugin_name."_materialize", plugin_dir_url(__FILE__).'js/materialize.min.js', array('jquery'), $this->version, false);
|
128 |
+
wp_enqueue_script($this->plugin_name."_materialize.clockpicker", plugin_dir_url(__FILE__).'js/materialize.clockpicker.js', array('jquery'), $this->version, false);
|
129 |
+
wp_enqueue_script($this->plugin_name."_jquery.datatables", plugin_dir_url(__FILE__).'js/jquery.dataTables.min.js', array('jquery'), $this->version, false);
|
130 |
+
wp_enqueue_script($this->plugin_name."_jquery.datatables.respnsive", plugin_dir_url(__FILE__).'js/dataTables.responsive.js', array('jquery'), $this->version, false);
|
131 |
+
wp_enqueue_script($this->plugin_name."_vakata", dirname(plugin_dir_url(__FILE__)).'/vendor/vakata/jstree/dist/jstree.min.js', array('jquery'), '3.3', false);
|
132 |
+
wp_enqueue_script($this->plugin_name."_xcloner-backup-class", plugin_dir_url(__FILE__).'js/xcloner-backup-class.js', array('jquery'), $this->version, false);
|
133 |
+
wp_enqueue_script($this->plugin_name."_xcloner-scheduler-class", plugin_dir_url(__FILE__).'js/xcloner-scheduler-class.js', array('jquery'), $this->version, false);
|
134 |
+
wp_enqueue_script($this->plugin_name."_xcloner-restore-class", plugin_dir_url(__FILE__).'js/xcloner-restore-class.js', array('jquery'), $this->version, false);
|
135 |
+
wp_enqueue_script($this->plugin_name."_xcloner-manage-backups-class", plugin_dir_url(__FILE__).'js/xcloner-manage-backups-class.js', array('jquery'), $this->version, false);
|
136 |
+
wp_enqueue_script($this->plugin_name."_xcloner-remote-storage-class", plugin_dir_url(__FILE__).'js/xcloner-remote-storage-class.js', array('jquery'), $this->version, false);
|
137 |
+
wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__).'js/xcloner-admin.js', array('jquery'), $this->version, false);
|
138 |
|
139 |
|
140 |
}
|
141 |
|
142 |
public function xcloner_init_page() {
|
143 |
+
require_once("partials/xcloner_init_page.php");
|
144 |
|
145 |
}
|
146 |
|
147 |
+
/**
|
148 |
+
* Returns the XCloner Storage Page
|
149 |
+
*/
|
150 |
public function xcloner_remote_storage_page() {
|
151 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
152 |
$remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
153 |
|
154 |
|
155 |
+
if (isset($_POST['action'])) {
|
156 |
+
$_POST['action'] = $xcloner_sanitization->sanitize_input_as_string($_POST['action']);
|
157 |
+
$remote_storage->save($_POST['action']);
|
158 |
}
|
159 |
|
160 |
+
if (isset($_POST['authentification_code']) && $_POST['authentification_code'] != "") {
|
161 |
+
$_POST['authentification_code'] = $xcloner_sanitization->sanitize_input_as_string($_POST['authentification_code']);
|
162 |
|
163 |
+
$remote_storage->set_access_token($_POST['authentification_code']);
|
164 |
}
|
165 |
|
166 |
+
if (isset($_POST['connection_check']) && $_POST['connection_check']) {
|
167 |
+
$remote_storage->check($_POST['action']);
|
168 |
}
|
169 |
|
170 |
+
require_once("partials/xcloner_remote_storage_page.php");
|
171 |
|
172 |
}
|
173 |
|
174 |
public function xcloner_scheduled_backups_page() {
|
175 |
$requirements = $this->xcloner_container->get_xcloner_requirements();
|
176 |
|
177 |
+
if (!$requirements->check_backup_ready_status()) {
|
178 |
+
require_once("partials/xcloner_init_page.php");
|
179 |
|
180 |
return false;
|
181 |
}
|
182 |
|
183 |
+
require_once("partials/xcloner_scheduled_backups_page.php");
|
184 |
|
185 |
}
|
186 |
|
187 |
public function xcloner_manage_backups_page() {
|
188 |
+
require_once("partials/xcloner_manage_backups_page.php");
|
189 |
|
190 |
}
|
191 |
|
192 |
public function xcloner_debugger_page() {
|
193 |
+
require_once("partials/xcloner_console_page.php");
|
194 |
|
195 |
}
|
196 |
|
197 |
public function xcloner_restore_page() {
|
198 |
+
require_once("partials/xcloner_restore_page.php");
|
199 |
|
200 |
}
|
201 |
|
202 |
public function xcloner_generate_backups_page() {
|
203 |
$requirements = $this->xcloner_container->get_xcloner_requirements();
|
204 |
|
205 |
+
if (!$requirements->check_backup_ready_status()) {
|
206 |
+
require_once("partials/xcloner_init_page.php");
|
207 |
|
208 |
return false;
|
209 |
}
|
210 |
|
211 |
+
require_once("partials/xcloner_generate_backups_page.php");
|
212 |
|
213 |
return;
|
214 |
}
|
215 |
|
216 |
public function xcloner_settings_page() {
|
217 |
// check user capabilities
|
218 |
+
if (!current_user_can('manage_options')) {
|
219 |
return;
|
220 |
}
|
221 |
|
223 |
|
224 |
// check if the user have submitted the settings
|
225 |
// wordpress will add the "settings-updated" $_GET parameter to the url
|
226 |
+
if (isset($_GET['settings-updated'])) {
|
227 |
// add settings saved message with the class of "updated"
|
228 |
+
add_settings_error('wporg_messages', 'wporg_message', __('Settings Saved', 'wporg'), 'updated');
|
229 |
}
|
230 |
|
231 |
// show error/update messages
|
232 |
+
settings_errors('wporg_messages');
|
233 |
?>
|
234 |
|
235 |
<?php
|
236 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
237 |
|
238 |
+
if (isset($_GET['tab'])) {
|
239 |
+
$active_tab = $xcloner_sanitization->sanitize_input_as_string($_GET['tab']);
|
240 |
} // end if
|
241 |
else {
|
242 |
$active_tab = "general_options";
|
243 |
}
|
244 |
|
245 |
?>
|
246 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
247 |
|
248 |
<ul class="nav-tab-wrapper row">
|
249 |
<li><a href="?page=xcloner_settings_page&tab=general_options"
|
250 |
+
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'general_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('General Options', 'xcloner-backup-and-restore') ?></a>
|
251 |
</li>
|
252 |
<li><a href="?page=xcloner_settings_page&tab=mysql_options"
|
253 |
+
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'mysql_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Mysql Options', 'xcloner-backup-and-restore') ?></a>
|
254 |
</li>
|
255 |
<li><a href="?page=xcloner_settings_page&tab=system_options"
|
256 |
+
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'system_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('System Options', 'xcloner-backup-and-restore') ?></a>
|
257 |
</li>
|
258 |
<li><a href="?page=xcloner_settings_page&tab=cleanup_options"
|
259 |
+
class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cleanup_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Cleanup Options', 'xcloner-backup-and-restore') ?></a>
|
260 |
</li>
|
261 |
</ul>
|
262 |
|
265 |
<form action="options.php" method="post">
|
266 |
<?php
|
267 |
|
268 |
+
if ($active_tab == 'general_options') {
|
269 |
|
270 |
+
settings_fields('xcloner_general_settings_group');
|
271 |
+
do_settings_sections('xcloner_settings_page');
|
272 |
|
273 |
+
} elseif ($active_tab == 'mysql_options') {
|
274 |
|
275 |
+
settings_fields('xcloner_mysql_settings_group');
|
276 |
+
do_settings_sections('xcloner_mysql_settings_page');
|
277 |
+
} elseif ($active_tab == 'system_options') {
|
278 |
|
279 |
+
settings_fields('xcloner_system_settings_group');
|
280 |
+
do_settings_sections('xcloner_system_settings_page');
|
281 |
+
} elseif ($active_tab == 'cleanup_options') {
|
282 |
|
283 |
+
settings_fields('xcloner_cleanup_settings_group');
|
284 |
+
do_settings_sections('xcloner_cleanup_settings_page');
|
285 |
}
|
286 |
|
287 |
// output save settings button
|
288 |
+
submit_button('Save Settings');
|
289 |
?>
|
290 |
</form>
|
291 |
|
admin/css/xcloner-admin.css
CHANGED
@@ -166,7 +166,8 @@ textarea.materialize-textarea {
|
|
166 |
#scheduled_backups .edit, #scheduled_backups .status.active, #scheduled_backups .delete,
|
167 |
#manage_backups .download, #manage_backups .cloud-upload, #manage_backups .delete, #manage_backups .list-backup-content,
|
168 |
.backup-done .download, .backup-done .cloud-upload, .backup-done .delete, .backup-done .list-backup-content,
|
169 |
-
#manage_backups .copy-remote-to-local, #manage_backups .expand-multipart
|
|
|
170 |
color: #4db6ac;
|
171 |
}
|
172 |
|
@@ -368,6 +369,10 @@ ul.files-list li {
|
|
368 |
white-space: pre;
|
369 |
}
|
370 |
|
|
|
|
|
|
|
|
|
371 |
#manage_backups_wrapper #manage_backups_filter {
|
372 |
min-width: 250px;
|
373 |
}
|
@@ -389,6 +394,18 @@ i.backup_warning {
|
|
389 |
display: none;
|
390 |
}
|
391 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
@media only screen and (min-width: 993px) {
|
393 |
.dashboard .backup-ready {
|
394 |
float: right;
|
166 |
#scheduled_backups .edit, #scheduled_backups .status.active, #scheduled_backups .delete,
|
167 |
#manage_backups .download, #manage_backups .cloud-upload, #manage_backups .delete, #manage_backups .list-backup-content,
|
168 |
.backup-done .download, .backup-done .cloud-upload, .backup-done .delete, .backup-done .list-backup-content,
|
169 |
+
#manage_backups .copy-remote-to-local, #manage_backups .expand-multipart,
|
170 |
+
#manage_backups .backup-encryption, #manage_backups .backup-decryption {
|
171 |
color: #4db6ac;
|
172 |
}
|
173 |
|
369 |
white-space: pre;
|
370 |
}
|
371 |
|
372 |
+
ul.files-list.error{
|
373 |
+
color: red;
|
374 |
+
}
|
375 |
+
|
376 |
#manage_backups_wrapper #manage_backups_filter {
|
377 |
min-width: 250px;
|
378 |
}
|
394 |
display: none;
|
395 |
}
|
396 |
|
397 |
+
.dataTables_wrapper .dataTables_filter input {
|
398 |
+
margin-left: 0px;
|
399 |
+
}
|
400 |
+
|
401 |
+
#backup_options .row{
|
402 |
+
min-height: 30px;
|
403 |
+
}
|
404 |
+
|
405 |
+
.input-field .switch label {
|
406 |
+
color: #000;
|
407 |
+
}
|
408 |
+
|
409 |
@media only screen and (min-width: 993px) {
|
410 |
.dashboard .backup-ready {
|
411 |
float: right;
|
admin/js/xcloner-backup-class.js
CHANGED
@@ -245,6 +245,11 @@ class Xcloner_Backup {
|
|
245 |
jQuery(".backup-done .download").attr("href", "#" + json.extra.backup_parent);
|
246 |
jQuery(".backup-done .list-backup-content").attr("href", "#" + json.extra.backup_parent);
|
247 |
|
|
|
|
|
|
|
|
|
|
|
248 |
//this.restart_backup();
|
249 |
this.do_backup_done()
|
250 |
}
|
@@ -268,6 +273,56 @@ class Xcloner_Backup {
|
|
268 |
this.do_ajax(elem, 'backup_files', 1);
|
269 |
}
|
270 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
do_backup_done() {
|
272 |
var elem = "#generate_backup ul.backup-status li.backup-done";
|
273 |
jQuery(elem).show();
|
245 |
jQuery(".backup-done .download").attr("href", "#" + json.extra.backup_parent);
|
246 |
jQuery(".backup-done .list-backup-content").attr("href", "#" + json.extra.backup_parent);
|
247 |
|
248 |
+
if( jQuery('#backup_options #backup_encrypt').is(':checked')) {
|
249 |
+
this.do_backup_encryption();
|
250 |
+
return;
|
251 |
+
}
|
252 |
+
|
253 |
//this.restart_backup();
|
254 |
this.do_backup_done()
|
255 |
}
|
273 |
this.do_ajax(elem, 'backup_files', 1);
|
274 |
}
|
275 |
|
276 |
+
do_backup_encryption_callback(elem, action, response) {
|
277 |
+
|
278 |
+
if (response.extra) {
|
279 |
+
this.params.extra = response.extra;
|
280 |
+
}
|
281 |
+
|
282 |
+
jQuery(".backup-encryption .last-logged-file").text('encrypting ' + response.processing_file+' ...');
|
283 |
+
|
284 |
+
if (response.total_size !== undefined) {
|
285 |
+
jQuery(".backup-encryption .progress > div").removeClass('indeterminate').addClass("determinate");
|
286 |
+
var percent = parseInt(response.start * 100) / parseInt(response.total_size)
|
287 |
+
jQuery(".backup-encryption .progress .determinate").css('width', parseInt(percent) + "%")
|
288 |
+
}
|
289 |
+
|
290 |
+
if (response.error) {
|
291 |
+
jQuery(".backup-encryption .status-body").show();
|
292 |
+
jQuery(".backup-encryption .status-body").addClass("error").prepend(response.message+" ")
|
293 |
+
jQuery(".backup-encryption .progress > div").addClass("determinate").removeClass("indeterminate").css('width', "100%")
|
294 |
+
return;
|
295 |
+
}
|
296 |
+
|
297 |
+
if (!response.finished /*&& !this.cancel*/) {
|
298 |
+
|
299 |
+
this.do_ajax(elem, action);
|
300 |
+
return false;
|
301 |
+
}
|
302 |
+
|
303 |
+
//finished
|
304 |
+
jQuery(elem).find('.progress > div').css('width', '100%');
|
305 |
+
jQuery(".backup-encryption .last-logged-file").text('done');
|
306 |
+
|
307 |
+
//this.do_backup_database();
|
308 |
+
this.do_backup_done()
|
309 |
+
|
310 |
+
}
|
311 |
+
|
312 |
+
do_backup_encryption() {
|
313 |
+
if (this.cancel)
|
314 |
+
return false;
|
315 |
+
|
316 |
+
var elem = "#generate_backup ul.backup-status li.backup-encryption";
|
317 |
+
jQuery(elem).show();
|
318 |
+
jQuery(elem + ' .status-body').show();
|
319 |
+
jQuery(elem).find('.collapsible-header').trigger('click');
|
320 |
+
|
321 |
+
jQuery(elem).find('.progress .determinate').css('width', '0%');
|
322 |
+
|
323 |
+
this.do_ajax(elem, 'backup_encryption', 1);
|
324 |
+
}
|
325 |
+
|
326 |
do_backup_done() {
|
327 |
var elem = "#generate_backup ul.backup-status li.backup-done";
|
328 |
jQuery(elem).show();
|
admin/js/xcloner-manage-backups-class.js
CHANGED
@@ -1,315 +1,437 @@
|
|
1 |
/** global: ajaxurl */
|
2 |
/** global: Materialize */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
-
class Xcloner_Manage_Backups{
|
5 |
-
|
6 |
-
constructor()
|
7 |
-
{
|
8 |
-
this.file_counter = 0
|
9 |
-
this.storage_selection = "";
|
10 |
-
|
11 |
-
//this.edit_modal = jQuery('.modal').modal();
|
12 |
-
}
|
13 |
-
|
14 |
-
download_backup_by_name(id)
|
15 |
-
{
|
16 |
-
window.open(ajaxurl+"?action=download_backup_by_name&name="+id);
|
17 |
-
return false;
|
18 |
-
}
|
19 |
-
|
20 |
-
delete_backup_by_name(id, elem, dataTable)
|
21 |
-
{
|
22 |
-
var $this = this
|
23 |
-
|
24 |
-
if(id){
|
25 |
-
jQuery.ajax({
|
26 |
-
url: ajaxurl,
|
27 |
-
method: 'post',
|
28 |
-
data: { action : 'delete_backup_by_name', name: id, storage_selection: this.storage_selection},
|
29 |
-
success: function(response){
|
30 |
-
if(response.finished)
|
31 |
-
{
|
32 |
-
dataTable
|
33 |
-
.row( jQuery(elem).parents('tr') )
|
34 |
-
.remove()
|
35 |
-
.draw();
|
36 |
-
}
|
37 |
-
else{
|
38 |
-
alert("There was an error deleting the file");
|
39 |
-
}
|
40 |
-
},
|
41 |
-
dataType: 'json'
|
42 |
-
});
|
43 |
-
}
|
44 |
-
}
|
45 |
-
|
46 |
-
list_backup_content_callback(backup_file, start = 0, part= 0)
|
47 |
-
{
|
48 |
-
var $this = this;
|
49 |
-
|
50 |
-
if(backup_file)
|
51 |
-
{
|
52 |
-
jQuery.ajax({
|
53 |
-
url: ajaxurl,
|
54 |
-
method: 'post',
|
55 |
-
data: { action : 'list_backup_files', file: backup_file, start: start, part: part},
|
56 |
-
success: function(response){
|
57 |
-
|
58 |
-
if(response.error)
|
59 |
-
{
|
60 |
-
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(response.message)
|
61 |
-
jQuery("#backup_cotent_modal .progress > div").addClass("determinate").removeClass(".indeterminate").css('width', "100%")
|
62 |
-
return;
|
63 |
-
}
|
64 |
-
|
65 |
-
var files_text = [];
|
66 |
-
|
67 |
-
for(var i in response.files)
|
68 |
-
{
|
69 |
-
|
70 |
-
if(response.total_size !== undefined)
|
71 |
-
{
|
72 |
-
var percent = parseInt(response.start*100)/parseInt(response.total_size)
|
73 |
-
//jQuery("#backup_cotent_modal .progress .determinate").css('width', percent + "%")
|
74 |
-
}
|
75 |
-
|
76 |
-
$this.file_counter++
|
77 |
-
|
78 |
-
files_text[i] = "<li>"+($this.file_counter +". <span title='"+response.files[i].mtime+"'>"+response.files[i].path+"</span> ("+response.files[i].size+" bytes)")+"</li>";
|
79 |
-
}
|
80 |
-
|
81 |
-
jQuery("#backup_cotent_modal .modal-content .files-list").prepend(files_text.reverse().join("\n"));
|
82 |
-
|
83 |
-
if(!response.finished && jQuery('#backup_cotent_modal').is(':visible'))
|
84 |
-
{
|
85 |
-
$this.list_backup_content_callback(backup_file, response.start, response.part)
|
86 |
-
}
|
87 |
-
else
|
88 |
-
{
|
89 |
-
jQuery("#backup_cotent_modal .progress > div").addClass('determinate').removeClass(".indeterminate").css('width', "100%")
|
90 |
-
}
|
91 |
-
|
92 |
-
},
|
93 |
-
error: function(xhr, textStatus, error){
|
94 |
-
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(textStatus+error)
|
95 |
-
},
|
96 |
-
dataType: 'json'
|
97 |
-
});
|
98 |
-
}
|
99 |
-
|
100 |
-
}
|
101 |
-
|
102 |
-
|
103 |
-
list_backup_content(backup_file)
|
104 |
-
{
|
105 |
-
this.file_counter = 0
|
106 |
-
jQuery("#backup_cotent_modal .modal-content .files-list").text("").removeClass("error");
|
107 |
-
jQuery("#backup_cotent_modal .modal-content .backup-name").text(backup_file);
|
108 |
-
jQuery("#backup_cotent_modal").modal('open');
|
109 |
-
jQuery("#backup_cotent_modal .progress > div").removeClass('determinate').addClass("indeterminate");
|
110 |
-
|
111 |
-
this.list_backup_content_callback(backup_file)
|
112 |
-
}
|
113 |
-
|
114 |
-
cloud_upload(backup_file)
|
115 |
-
{
|
116 |
-
jQuery('#remote_storage_modal').find(".backup_name").text(backup_file)
|
117 |
-
jQuery('#remote_storage_modal').find("input.backup_name").val(backup_file)
|
118 |
-
Materialize.updateTextFields();
|
119 |
-
jQuery('.col select').material_select();
|
120 |
-
jQuery("#remote_storage_modal").modal('open')
|
121 |
-
jQuery("#remote_storage_modal .status").hide();
|
122 |
-
|
123 |
-
jQuery(".remote-storage-form").off("submit").on("submit",function(){
|
124 |
-
jQuery("#remote_storage_modal .status").show();
|
125 |
-
jQuery("#remote_storage_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
|
126 |
-
jQuery("#remote_storage_modal .status-text").removeClass("error").text("");
|
127 |
-
|
128 |
-
var storage_type = jQuery("#remote_storage_modal select").val();
|
129 |
-
|
130 |
-
if(backup_file)
|
131 |
-
{
|
132 |
-
jQuery.ajax({
|
133 |
-
url: ajaxurl,
|
134 |
-
method: 'post',
|
135 |
-
data: { action : 'upload_backup_to_remote', file: backup_file, storage_type: storage_type},
|
136 |
-
success: function(response){
|
137 |
-
if(response.error)
|
138 |
-
{
|
139 |
-
jQuery("#remote_storage_modal .status-text").addClass("error").text(response.message)
|
140 |
-
}else{
|
141 |
-
jQuery("#remote_storage_modal .status-text").removeClass("error").text("done")
|
142 |
-
}
|
143 |
-
|
144 |
-
jQuery("#remote_storage_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
|
145 |
-
},
|
146 |
-
error: function(xhr, textStatus, error){
|
147 |
-
jQuery("#remote_storage_modal .status-text").addClass("error").text(textStatus+error)
|
148 |
-
},
|
149 |
-
dataType: 'json'
|
150 |
-
});
|
151 |
-
}
|
152 |
-
|
153 |
-
return false;
|
154 |
-
})
|
155 |
-
}
|
156 |
-
|
157 |
-
copy_remote_to_local(backup_file)
|
158 |
-
{
|
159 |
-
jQuery("#local_storage_upload_modal").modal('open');
|
160 |
-
jQuery("#local_storage_upload_modal .modal-content .backup-name").text(backup_file);
|
161 |
-
jQuery("#local_storage_upload_modal .status-text").removeClass("error").text("");
|
162 |
-
jQuery("#local_storage_upload_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
|
163 |
-
|
164 |
-
if(backup_file)
|
165 |
-
{
|
166 |
-
jQuery.ajax({
|
167 |
-
url: ajaxurl,
|
168 |
-
method: 'post',
|
169 |
-
data: { action : 'copy_backup_remote_to_local', file: backup_file, storage_type: this.storage_selection},
|
170 |
-
success: function(response){
|
171 |
-
if(response.error)
|
172 |
-
{
|
173 |
-
jQuery("#local_storage_upload_modal .status-text").addClass("error").text(response.message)
|
174 |
-
}else{
|
175 |
-
jQuery("#local_storage_upload_modal .status-text").removeClass("error").text("done")
|
176 |
-
}
|
177 |
-
|
178 |
-
jQuery("#local_storage_upload_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
|
179 |
-
},
|
180 |
-
error: function(xhr, textStatus, error){
|
181 |
-
jQuery("#local_storage_upload_modal .status-text").addClass("error").text(textStatus+error)
|
182 |
-
},
|
183 |
-
dataType: 'json'
|
184 |
-
});
|
185 |
-
}
|
186 |
-
|
187 |
-
}
|
188 |
-
|
189 |
-
//end class
|
190 |
-
}
|
191 |
-
|
192 |
-
jQuery(document).ready(function(){
|
193 |
-
|
194 |
-
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
195 |
-
|
196 |
-
xcloner_manage_backups.storage_selection = getUrlParam('storage_selection');
|
197 |
-
|
198 |
-
jQuery("a.expand-multipart").on("click", function(){
|
199 |
-
jQuery(this).parent().find("ul.multipart").toggle();
|
200 |
-
jQuery(this).parent().find("a.expand-multipart.remove").toggle();
|
201 |
-
jQuery(this).parent().find("a.expand-multipart.add").toggle();
|
202 |
-
})
|
203 |
-
var dataTable = jQuery('#manage_backups').DataTable( {
|
204 |
-
'responsive': true,
|
205 |
-
'bFilter': true,
|
206 |
-
"order": [[ 2, "desc" ]],
|
207 |
-
buttons: [
|
208 |
-
'selectAll',
|
209 |
-
'selectNone'
|
210 |
-
],
|
211 |
-
"language": {
|
212 |
-
"emptyTable": "No backups available",
|
213 |
-
buttons: {
|
214 |
-
selectAll: "Select all items",
|
215 |
-
selectNone: "Select none"
|
216 |
-
}
|
217 |
-
},
|
218 |
-
columnDefs: [
|
219 |
-
{ targets: 'no-sort', orderable: false }
|
220 |
-
],
|
221 |
-
"columns": [
|
222 |
-
{ "width": "1%" },
|
223 |
-
{ "width": "25%" },
|
224 |
-
{ "width": "5%" },
|
225 |
-
{ "width": "5%" },
|
226 |
-
{ "width": "5%" },
|
227 |
-
],
|
228 |
-
"oLanguage": {
|
229 |
-
"sSearch": "",
|
230 |
-
"sSearchPlaceholder" : 'Search Backups',
|
231 |
-
} ,
|
232 |
-
//"ajax": ajaxurl+"?action=get_backup_list",
|
233 |
-
"fnDrawCallback": function( oSettings ) {
|
234 |
-
|
235 |
-
jQuery(this).off("click", ".delete").on("click", ".delete", function(e){
|
236 |
-
|
237 |
-
var hash = jQuery(this).attr('href');
|
238 |
-
var id = hash.substr(1)
|
239 |
-
var data = "";
|
240 |
-
|
241 |
-
if(show_delete_alert)
|
242 |
-
{
|
243 |
-
if(confirm('Are you sure you want to delete it?'))
|
244 |
-
{
|
245 |
-
xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
246 |
-
}
|
247 |
-
}else{
|
248 |
-
xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
249 |
-
}
|
250 |
-
|
251 |
-
|
252 |
-
e.preventDefault();
|
253 |
-
})
|
254 |
-
|
255 |
-
jQuery(this).off("click", ".download").on("click", ".download", function(e){
|
256 |
-
var hash = jQuery(this).attr('href');
|
257 |
-
var id = hash.substr(1)
|
258 |
-
xcloner_manage_backups.download_backup_by_name(id);
|
259 |
-
e.preventDefault();
|
260 |
-
})
|
261 |
-
|
262 |
-
jQuery(this).off("click", ".cloud-upload").on("click", ".cloud-upload", function(e){
|
263 |
-
var hash = jQuery(this).attr('href');
|
264 |
-
var id = hash.substr(1)
|
265 |
-
xcloner_manage_backups.cloud_upload(id);
|
266 |
-
e.preventDefault();
|
267 |
-
})
|
268 |
-
|
269 |
-
jQuery(this).off("click", ".copy-remote-to-local").on("click", ".copy-remote-to-local", function(e){
|
270 |
-
var hash = jQuery(this).attr('href');
|
271 |
-
var id = hash.substr(1)
|
272 |
-
xcloner_manage_backups.copy_remote_to_local(id);
|
273 |
-
e.preventDefault();
|
274 |
-
})
|
275 |
-
|
276 |
-
jQuery(this).off("click", ".list-backup-content").on("click", ".list-backup-content", function(e){
|
277 |
-
var hash = jQuery(this).attr('href');
|
278 |
-
var id = hash.substr(1)
|
279 |
-
xcloner_manage_backups.list_backup_content(id);
|
280 |
-
e.preventDefault();
|
281 |
-
})
|
282 |
-
}
|
283 |
-
});
|
284 |
-
|
285 |
-
jQuery('#select_all').click(function () {
|
286 |
-
jQuery('input:checkbox').prop('checked', this.checked);
|
287 |
-
});
|
288 |
-
|
289 |
-
jQuery(".delete-all").click(function(){
|
290 |
-
if(confirm('Are you sure you want to delete selected items?'))
|
291 |
-
{
|
292 |
-
show_delete_alert = 0;
|
293 |
-
jQuery('input:checkbox').each(function(){
|
294 |
-
if(jQuery(this).is(":checked"))
|
295 |
-
{
|
296 |
-
jQuery(this).parent().parent().parent().find(".delete").trigger('click');
|
297 |
-
}
|
298 |
-
})
|
299 |
-
show_delete_alert = 1;
|
300 |
-
}
|
301 |
-
})
|
302 |
-
|
303 |
-
jQuery("#remote_storage_modal").modal();
|
304 |
-
jQuery("#local_storage_upload_modal").modal();
|
305 |
-
|
306 |
-
jQuery("#storage_selection").on("change", function(){
|
307 |
-
console.log(jQuery(this).val());
|
308 |
-
window.location = window.location.href.split('&storage_selection')[0]+"&storage_selection="+jQuery(this).val();
|
309 |
-
})
|
310 |
-
|
311 |
-
|
312 |
-
var show_delete_alert=1;
|
313 |
-
|
314 |
-
|
315 |
});
|
1 |
/** global: ajaxurl */
|
2 |
/** global: Materialize */
|
3 |
+
var dataTable = "";
|
4 |
+
|
5 |
+
class Xcloner_Manage_Backups {
|
6 |
+
|
7 |
+
constructor() {
|
8 |
+
this.file_counter = 0
|
9 |
+
this.storage_selection = "";
|
10 |
+
this.dataTable = "";
|
11 |
+
//this.edit_modal = jQuery('.modal').modal();
|
12 |
+
}
|
13 |
+
|
14 |
+
download_backup_by_name(id) {
|
15 |
+
window.open(ajaxurl + "?action=download_backup_by_name&name=" + id);
|
16 |
+
return false;
|
17 |
+
}
|
18 |
+
|
19 |
+
delete_backup_by_name(id, elem, dataTable) {
|
20 |
+
var $this = this
|
21 |
+
|
22 |
+
if (id) {
|
23 |
+
jQuery.ajax({
|
24 |
+
url: ajaxurl,
|
25 |
+
method: 'post',
|
26 |
+
data: {action: 'delete_backup_by_name', name: id, storage_selection: this.storage_selection},
|
27 |
+
success: function (response) {
|
28 |
+
if (response.finished) {
|
29 |
+
dataTable
|
30 |
+
.row(jQuery(elem).parents('tr'))
|
31 |
+
.remove()
|
32 |
+
.draw();
|
33 |
+
} else {
|
34 |
+
alert("There was an error deleting the file");
|
35 |
+
}
|
36 |
+
},
|
37 |
+
dataType: 'json'
|
38 |
+
});
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
list_backup_content_callback(backup_file, start = 0, part = 0) {
|
43 |
+
var $this = this;
|
44 |
+
|
45 |
+
if (backup_file) {
|
46 |
+
jQuery.ajax({
|
47 |
+
url: ajaxurl,
|
48 |
+
method: 'post',
|
49 |
+
data: {action: 'list_backup_files', file: backup_file, start: start, part: part},
|
50 |
+
success: function (response) {
|
51 |
+
|
52 |
+
if (response.error) {
|
53 |
+
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(response.message)
|
54 |
+
jQuery("#backup_cotent_modal .progress > div").addClass("determinate").removeClass(".indeterminate").css('width', "100%")
|
55 |
+
return;
|
56 |
+
}
|
57 |
+
|
58 |
+
var files_text = [];
|
59 |
+
|
60 |
+
for (var i in response.files) {
|
61 |
+
|
62 |
+
if (response.total_size !== undefined) {
|
63 |
+
var percent = parseInt(response.start * 100) / parseInt(response.total_size)
|
64 |
+
//jQuery("#backup_cotent_modal .progress .determinate").css('width', percent + "%")
|
65 |
+
}
|
66 |
+
|
67 |
+
$this.file_counter++
|
68 |
+
|
69 |
+
files_text[i] = "<li>" + ($this.file_counter + ". <span title='" + response.files[i].mtime + "'>" + response.files[i].path + "</span> (" + response.files[i].size + " bytes)") + "</li>";
|
70 |
+
}
|
71 |
+
|
72 |
+
jQuery("#backup_cotent_modal .modal-content .files-list").prepend(files_text.reverse().join("\n"));
|
73 |
+
|
74 |
+
if (!response.finished && jQuery('#backup_cotent_modal').is(':visible')) {
|
75 |
+
$this.list_backup_content_callback(backup_file, response.start, response.part)
|
76 |
+
} else {
|
77 |
+
jQuery("#backup_cotent_modal .progress > div").addClass('determinate').removeClass(".indeterminate").css('width', "100%")
|
78 |
+
}
|
79 |
+
|
80 |
+
},
|
81 |
+
error: function (xhr, textStatus, error) {
|
82 |
+
jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(textStatus + error)
|
83 |
+
},
|
84 |
+
dataType: 'json'
|
85 |
+
});
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
list_backup_content(backup_file) {
|
92 |
+
this.file_counter = 0
|
93 |
+
jQuery("#backup_cotent_modal .modal-content .files-list").text("").removeClass("error");
|
94 |
+
jQuery("#backup_cotent_modal .modal-content .backup-name").text(backup_file);
|
95 |
+
jQuery("#backup_cotent_modal").modal('open');
|
96 |
+
jQuery("#backup_cotent_modal .progress > div").removeClass('determinate').addClass("indeterminate");
|
97 |
+
|
98 |
+
this.list_backup_content_callback(backup_file)
|
99 |
+
}
|
100 |
+
|
101 |
+
backup_encryption_callback(backup_file, start = 0, part = 0, iv = 0) {
|
102 |
+
var $this = this;
|
103 |
+
|
104 |
+
if (backup_file) {
|
105 |
+
jQuery.ajax({
|
106 |
+
url: ajaxurl,
|
107 |
+
method: 'post',
|
108 |
+
data: {action: 'backup_encryption', file: backup_file, start: start, part: part, iv: iv},
|
109 |
+
success: function (response) {
|
110 |
+
|
111 |
+
if (response.total_size !== undefined) {
|
112 |
+
jQuery("#backup_encryption_modal .progress > div").removeClass('indeterminate').addClass("determinate");
|
113 |
+
var percent = parseInt(response.start * 100) / parseInt(response.total_size)
|
114 |
+
jQuery("#backup_encryption_modal .progress .determinate").css('width', parseInt(percent) + "%")
|
115 |
+
jQuery("#backup_encryption_modal .modal-content .files-list").text("Encrypting "+response.processing_file+" "+ parseInt(percent) + "%")
|
116 |
+
}
|
117 |
+
|
118 |
+
if (response.error) {
|
119 |
+
jQuery("#backup_encryption_modal .notice").show();
|
120 |
+
jQuery("#backup_encryption_modal .files-list").addClass("error").prepend(response.message+" ")
|
121 |
+
jQuery("#backup_encryption_modal .progress > div").addClass("determinate").removeClass("indeterminate").css('width', "100%")
|
122 |
+
return;
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
if (!response.finished && jQuery('#backup_encryption_modal').is(':visible')) {
|
127 |
+
$this.backup_encryption_callback(backup_file, response.start, response.part, response.iv)
|
128 |
+
} else {
|
129 |
+
jQuery("#backup_encryption_modal .progress > div").addClass('determinate').removeClass("indeterminate").css('width', "100%")
|
130 |
+
jQuery("#backup_encryption_modal .modal-content .files-list").text("Done Encrypting.")
|
131 |
+
dataTable.ajax.reload();
|
132 |
+
}
|
133 |
+
|
134 |
+
},
|
135 |
+
error: function (xhr, textStatus, error) {
|
136 |
+
jQuery("#backup_encryption_modal .files-list").addClass("error").prepend(textStatus + error)
|
137 |
+
},
|
138 |
+
dataType: 'json'
|
139 |
+
});
|
140 |
+
}
|
141 |
+
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
backup_encryption(backup_file, start = 0) {
|
146 |
+
this.file_counter = 0
|
147 |
+
|
148 |
+
jQuery("#backup_encryption_modal .modal-content .backup-name").text(backup_file);
|
149 |
+
jQuery("#backup_encryption_modal").modal('open');
|
150 |
+
jQuery("#backup_encryption_modal .progress > div");
|
151 |
+
jQuery("#backup_encryption_modal .notice").show();
|
152 |
+
|
153 |
+
jQuery("#backup_encryption_modal a.btn").attr('onclick', "var xcloner_manage_backups = new Xcloner_Manage_Backups();xcloner_manage_backups.backup_encryption('"+backup_file+"', true)");
|
154 |
+
jQuery("#backup_encryption_modal .modal-content .files-list").text("").removeClass("error");
|
155 |
+
|
156 |
+
if( start ) {
|
157 |
+
jQuery("#backup_encryption_modal .notice").hide();
|
158 |
+
this.backup_encryption_callback(backup_file)
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
backup_decryption_callback(backup_file, start = 0, part = 0, iv = 0) {
|
163 |
+
var $this = this;
|
164 |
+
|
165 |
+
var decryption_key = jQuery('#backup_decryption_modal #decryption_key').val();
|
166 |
+
|
167 |
+
if (backup_file) {
|
168 |
+
jQuery.ajax({
|
169 |
+
url: ajaxurl,
|
170 |
+
method: 'post',
|
171 |
+
data: {action: 'backup_decryption', file: backup_file, start: start, part: part, iv: iv, decryption_key: decryption_key},
|
172 |
+
success: function (response) {
|
173 |
+
|
174 |
+
if(!response.start){
|
175 |
+
response.start = 0;
|
176 |
+
}
|
177 |
+
if (response.total_size !== undefined) {
|
178 |
+
jQuery("#backup_decryption_modal .progress > div").removeClass('indeterminate').addClass("determinate");
|
179 |
+
var percent = parseInt(response.start * 100) / parseInt(response.total_size)
|
180 |
+
jQuery("#backup_decryption_modal .progress .determinate").css('width', parseInt(percent) + "%")
|
181 |
+
jQuery("#backup_decryption_modal .modal-content .files-list").text("Decrypting "+response.processing_file+" "+ parseInt(percent) + "%")
|
182 |
+
}
|
183 |
+
|
184 |
+
if (response.error) {
|
185 |
+
jQuery("#backup_decryption_modal .files-list").addClass("error").prepend(response.message+" ")
|
186 |
+
jQuery("#backup_decryption_modal .progress > div").addClass("determinate").removeClass("indeterminate").css('width', "100%")
|
187 |
+
jQuery("#backup_decryption_modal .notice").show();
|
188 |
+
return;
|
189 |
+
}
|
190 |
+
|
191 |
+
|
192 |
+
if (!response.finished && jQuery('#backup_decryption_modal').is(':visible')) {
|
193 |
+
$this.backup_decryption_callback(backup_file, response.start, response.part, response.iv)
|
194 |
+
} else {
|
195 |
+
jQuery("#backup_decryption_modal .progress > div").addClass('determinate').removeClass("indeterminate").css('width', "100%")
|
196 |
+
jQuery("#backup_decryption_modal .modal-content .files-list").text("Done Decrypting.")
|
197 |
+
dataTable.ajax.reload();
|
198 |
+
}
|
199 |
+
|
200 |
+
},
|
201 |
+
error: function (xhr, textStatus, error) {
|
202 |
+
jQuery("#backup_decryption_modal .files-list").addClass("error").prepend(textStatus + error)
|
203 |
+
},
|
204 |
+
dataType: 'json'
|
205 |
+
});
|
206 |
+
}
|
207 |
+
|
208 |
+
}
|
209 |
+
|
210 |
+
backup_decryption(backup_file, start = 0) {
|
211 |
+
this.file_counter = 0
|
212 |
+
|
213 |
+
jQuery("#backup_decryption_modal .modal-content .backup-name").text(backup_file);
|
214 |
+
jQuery("#backup_decryption_modal").modal('open');
|
215 |
+
jQuery("#backup_decryption_modal .progress > div");
|
216 |
+
jQuery("#backup_decryption_modal .notice").show();
|
217 |
+
|
218 |
+
jQuery("#backup_decryption_modal a.btn").attr('onclick', "var xcloner_manage_backups = new Xcloner_Manage_Backups();xcloner_manage_backups.backup_decryption('"+backup_file+"', true)");
|
219 |
+
jQuery("#backup_decryption_modal .modal-content .files-list").text("").removeClass("error");
|
220 |
+
|
221 |
+
if( start ) {
|
222 |
+
jQuery("#backup_decryption_modal .notice").hide();
|
223 |
+
this.backup_decryption_callback(backup_file)
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
cloud_upload(backup_file) {
|
228 |
+
jQuery('#remote_storage_modal').find(".backup_name").text(backup_file)
|
229 |
+
jQuery('#remote_storage_modal').find("input.backup_name").val(backup_file)
|
230 |
+
Materialize.updateTextFields();
|
231 |
+
jQuery('.col select').material_select();
|
232 |
+
jQuery("#remote_storage_modal").modal('open')
|
233 |
+
jQuery("#remote_storage_modal .status").hide();
|
234 |
+
|
235 |
+
jQuery(".remote-storage-form").off("submit").on("submit", function () {
|
236 |
+
jQuery("#remote_storage_modal .status").show();
|
237 |
+
jQuery("#remote_storage_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
|
238 |
+
jQuery("#remote_storage_modal .status-text").removeClass("error").text("");
|
239 |
+
|
240 |
+
var storage_type = jQuery("#remote_storage_modal select").val();
|
241 |
+
|
242 |
+
if (backup_file) {
|
243 |
+
jQuery.ajax({
|
244 |
+
url: ajaxurl,
|
245 |
+
method: 'post',
|
246 |
+
data: {action: 'upload_backup_to_remote', file: backup_file, storage_type: storage_type},
|
247 |
+
success: function (response) {
|
248 |
+
if (response.error) {
|
249 |
+
jQuery("#remote_storage_modal .status-text").addClass("error").text(response.message)
|
250 |
+
} else {
|
251 |
+
jQuery("#remote_storage_modal .status-text").removeClass("error").text("done")
|
252 |
+
}
|
253 |
+
|
254 |
+
jQuery("#remote_storage_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
|
255 |
+
},
|
256 |
+
error: function (xhr, textStatus, error) {
|
257 |
+
jQuery("#remote_storage_modal .status-text").addClass("error").text(textStatus + error)
|
258 |
+
},
|
259 |
+
dataType: 'json'
|
260 |
+
});
|
261 |
+
}
|
262 |
+
|
263 |
+
return false;
|
264 |
+
})
|
265 |
+
}
|
266 |
+
|
267 |
+
copy_remote_to_local(backup_file) {
|
268 |
+
jQuery("#local_storage_upload_modal").modal('open');
|
269 |
+
jQuery("#local_storage_upload_modal .modal-content .backup-name").text(backup_file);
|
270 |
+
jQuery("#local_storage_upload_modal .status-text").removeClass("error").text("");
|
271 |
+
jQuery("#local_storage_upload_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
|
272 |
+
|
273 |
+
if (backup_file) {
|
274 |
+
jQuery.ajax({
|
275 |
+
url: ajaxurl,
|
276 |
+
method: 'post',
|
277 |
+
data: {action: 'copy_backup_remote_to_local', file: backup_file, storage_type: this.storage_selection},
|
278 |
+
success: function (response) {
|
279 |
+
if (response.error) {
|
280 |
+
jQuery("#local_storage_upload_modal .status-text").addClass("error").text(response.message)
|
281 |
+
} else {
|
282 |
+
jQuery("#local_storage_upload_modal .status-text").removeClass("error").text("done")
|
283 |
+
}
|
284 |
+
|
285 |
+
jQuery("#local_storage_upload_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
|
286 |
+
},
|
287 |
+
error: function (xhr, textStatus, error) {
|
288 |
+
jQuery("#local_storage_upload_modal .status-text").addClass("error").text(textStatus + error)
|
289 |
+
},
|
290 |
+
dataType: 'json'
|
291 |
+
});
|
292 |
+
}
|
293 |
+
|
294 |
+
}
|
295 |
+
|
296 |
+
//end class
|
297 |
+
}
|
298 |
+
|
299 |
+
jQuery(document).ready(function () {
|
300 |
+
|
301 |
+
var xcloner_manage_backups = new Xcloner_Manage_Backups();
|
302 |
+
|
303 |
+
xcloner_manage_backups.storage_selection = getUrlParam('storage_selection');
|
304 |
+
|
305 |
+
dataTable = jQuery('#manage_backups').DataTable({
|
306 |
+
'responsive': true,
|
307 |
+
'bFilter': true,
|
308 |
+
"order": [[2, "desc"]],
|
309 |
+
buttons: [
|
310 |
+
'selectAll',
|
311 |
+
'selectNone'
|
312 |
+
],
|
313 |
+
"language": {
|
314 |
+
"emptyTable": "No backups available",
|
315 |
+
buttons: {
|
316 |
+
selectAll: "Select all items",
|
317 |
+
selectNone: "Select none"
|
318 |
+
}
|
319 |
+
},
|
320 |
+
columnDefs: [
|
321 |
+
{targets: 'no-sort', orderable: false}
|
322 |
+
],
|
323 |
+
"columns": [
|
324 |
+
{"width": "1%"},
|
325 |
+
{"width": "25%"},
|
326 |
+
{"width": "5%"},
|
327 |
+
{"width": "5%"},
|
328 |
+
{"width": "9%"},
|
329 |
+
],
|
330 |
+
"oLanguage": {
|
331 |
+
"sSearch": "",
|
332 |
+
"sSearchPlaceholder": 'Search Backups',
|
333 |
+
},
|
334 |
+
"ajax": ajaxurl+"?action=get_manage_backups_list&storage_selection="+xcloner_manage_backups.storage_selection,
|
335 |
+
"fnDrawCallback": function (oSettings) {
|
336 |
+
|
337 |
+
jQuery("a.expand-multipart").on("click", function () {
|
338 |
+
jQuery(this).parent().find("ul.multipart").toggle();
|
339 |
+
jQuery(this).parent().find("a.expand-multipart.remove").toggle();
|
340 |
+
jQuery(this).parent().find("a.expand-multipart.add").toggle();
|
341 |
+
})
|
342 |
+
|
343 |
+
jQuery(this).off("click", ".delete").on("click", ".delete", function (e) {
|
344 |
+
|
345 |
+
var hash = jQuery(this).attr('href');
|
346 |
+
var id = hash.substr(1)
|
347 |
+
var data = "";
|
348 |
+
|
349 |
+
if (show_delete_alert) {
|
350 |
+
if (confirm('Are you sure you want to delete it?')) {
|
351 |
+
xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
352 |
+
}
|
353 |
+
} else {
|
354 |
+
xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
|
355 |
+
}
|
356 |
+
|
357 |
+
|
358 |
+
e.preventDefault();
|
359 |
+
})
|
360 |
+
|
361 |
+
jQuery(this).off("click", ".download").on("click", ".download", function (e) {
|
362 |
+
var hash = jQuery(this).attr('href');
|
363 |
+
var id = hash.substr(1)
|
364 |
+
xcloner_manage_backups.download_backup_by_name(id);
|
365 |
+
e.preventDefault();
|
366 |
+
})
|
367 |
+
|
368 |
+
jQuery(this).off("click", ".cloud-upload").on("click", ".cloud-upload", function (e) {
|
369 |
+
var hash = jQuery(this).attr('href');
|
370 |
+
var id = hash.substr(1)
|
371 |
+
xcloner_manage_backups.cloud_upload(id);
|
372 |
+
e.preventDefault();
|
373 |
+
})
|
374 |
+
|
375 |
+
jQuery(this).off("click", ".copy-remote-to-local").on("click", ".copy-remote-to-local", function (e) {
|
376 |
+
var hash = jQuery(this).attr('href');
|
377 |
+
var id = hash.substr(1)
|
378 |
+
xcloner_manage_backups.copy_remote_to_local(id);
|
379 |
+
e.preventDefault();
|
380 |
+
})
|
381 |
+
|
382 |
+
jQuery(this).off("click", ".list-backup-content").on("click", ".list-backup-content", function (e) {
|
383 |
+
var hash = jQuery(this).attr('href');
|
384 |
+
var id = hash.substr(1)
|
385 |
+
xcloner_manage_backups.list_backup_content(id);
|
386 |
+
e.preventDefault();
|
387 |
+
})
|
388 |
+
|
389 |
+
jQuery(this).off("click", ".backup-encryption").on("click", ".backup-encryption", function (e) {
|
390 |
+
var hash = jQuery(this).attr('href');
|
391 |
+
var id = hash.substr(1)
|
392 |
+
xcloner_manage_backups.backup_encryption(id);
|
393 |
+
e.preventDefault();
|
394 |
+
})
|
395 |
+
|
396 |
+
jQuery(this).off("click", ".backup-decryption").on("click", ".backup-decryption", function (e) {
|
397 |
+
var hash = jQuery(this).attr('href');
|
398 |
+
var id = hash.substr(1)
|
399 |
+
xcloner_manage_backups.backup_decryption(id);
|
400 |
+
e.preventDefault();
|
401 |
+
})
|
402 |
+
|
403 |
+
}
|
404 |
+
});
|
405 |
+
|
406 |
+
jQuery('#select_all').click(function () {
|
407 |
+
jQuery('input:checkbox').prop('checked', this.checked);
|
408 |
+
});
|
409 |
+
|
410 |
+
jQuery(".delete-all").click(function () {
|
411 |
+
if (confirm('Are you sure you want to delete selected items?')) {
|
412 |
+
show_delete_alert = 0;
|
413 |
+
jQuery('input:checkbox').each(function () {
|
414 |
+
if (jQuery(this).is(":checked")) {
|
415 |
+
jQuery(this).parent().parent().parent().find(".delete").trigger('click');
|
416 |
+
}
|
417 |
+
})
|
418 |
+
show_delete_alert = 1;
|
419 |
+
}
|
420 |
+
})
|
421 |
+
|
422 |
+
jQuery("#remote_storage_modal").modal();
|
423 |
+
jQuery("#local_storage_upload_modal").modal();
|
424 |
+
|
425 |
+
jQuery("#storage_selection").on("change", function () {
|
426 |
+
window.location = window.location.href.split('&storage_selection')[0] + "&storage_selection=" + jQuery(this).val();
|
427 |
+
})
|
428 |
+
|
429 |
+
jQuery('.modal').on('hide',function(){
|
430 |
+
alert('ok')
|
431 |
+
})
|
432 |
+
|
433 |
+
|
434 |
+
var show_delete_alert = 1;
|
435 |
+
|
436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
});
|
admin/js/xcloner-scheduler-class.js
CHANGED
@@ -45,7 +45,9 @@ jQuery(document).ready(function(){
|
|
45 |
data: { action : 'delete_schedule_by_id', id: id},
|
46 |
success: function(response){
|
47 |
//window.location = "";
|
|
|
48 |
//alert("Schedule deleted");
|
|
|
49 |
dataTable
|
50 |
.row( jQuery(elem).parents('tr') )
|
51 |
.remove()
|
@@ -80,6 +82,11 @@ jQuery(document).ready(function(){
|
|
80 |
this.edit_modal.find('#schedule_storage>option[value="' + response.remote_storage + '"]').prop('selected', true);
|
81 |
//var date = new Date(response.start_at);
|
82 |
this.edit_modal.find("#schedule_start_date").val(response.start_at)
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
var tables = jQuery.parseJSON(response.table_params)
|
85 |
|
45 |
data: { action : 'delete_schedule_by_id', id: id},
|
46 |
success: function(response){
|
47 |
//window.location = "";
|
48 |
+
//console.log('schedule deleted');
|
49 |
//alert("Schedule deleted");
|
50 |
+
jQuery(elem).parents('tr').remove();
|
51 |
dataTable
|
52 |
.row( jQuery(elem).parents('tr') )
|
53 |
.remove()
|
82 |
this.edit_modal.find('#schedule_storage>option[value="' + response.remote_storage + '"]').prop('selected', true);
|
83 |
//var date = new Date(response.start_at);
|
84 |
this.edit_modal.find("#schedule_start_date").val(response.start_at)
|
85 |
+
|
86 |
+
|
87 |
+
if(response.backup_params.backup_encrypt !== undefined && response.backup_params.backup_encrypt == 1) {
|
88 |
+
this.edit_modal.find('#backup_encrypt').attr('checked', 'checked')
|
89 |
+
}
|
90 |
|
91 |
var tables = jQuery.parseJSON(response.table_params)
|
92 |
|
admin/partials/xcloner_console_page.php
CHANGED
@@ -7,17 +7,17 @@ $logger_content = $logger->getLastDebugLines();
|
|
7 |
<div class="col s12 ">
|
8 |
<div>
|
9 |
<h5 class="left-align">
|
10 |
-
<?php echo __(
|
11 |
</h5>
|
12 |
|
13 |
-
<?php if (
|
14 |
<ul class="collapsible xcloner-debugger" data-collapsible="accordion">
|
15 |
<li class="active">
|
16 |
<div class="collapsible-header active"><i class="material-icons">bug_report</i>XCloner Debugger
|
17 |
</div>
|
18 |
<div class="collapsible-body">
|
19 |
-
<div class="console" id="xcloner-console"><?php if (
|
20 |
-
echo implode(
|
21 |
} ?></div>
|
22 |
</div>
|
23 |
</li>
|
7 |
<div class="col s12 ">
|
8 |
<div>
|
9 |
<h5 class="left-align">
|
10 |
+
<?php echo __('XCloner Debugger Dashboard', 'xcloner-backup-and-restore') ?>
|
11 |
</h5>
|
12 |
|
13 |
+
<?php if ($xcloner_settings->get_xcloner_option('xcloner_enable_log')) : ?>
|
14 |
<ul class="collapsible xcloner-debugger" data-collapsible="accordion">
|
15 |
<li class="active">
|
16 |
<div class="collapsible-header active"><i class="material-icons">bug_report</i>XCloner Debugger
|
17 |
</div>
|
18 |
<div class="collapsible-body">
|
19 |
+
<div class="console" id="xcloner-console"><?php if (isset($logger_content)) {
|
20 |
+
echo implode("<br />\n", $logger_content);
|
21 |
} ?></div>
|
22 |
</div>
|
23 |
</li>
|
admin/partials/xcloner_generate_backups_page.php
CHANGED
@@ -8,25 +8,25 @@ $tab = 1;
|
|
8 |
|
9 |
<script>var xcloner_backup = new Xcloner_Backup();</script>
|
10 |
|
11 |
-
<h1><?= esc_html(
|
12 |
|
13 |
<ul class="nav-tab-wrapper content row">
|
14 |
<li><a href="#backup_options"
|
15 |
-
class="nav-tab col s12 m3 l2 nav-tab-active"><?php echo $tab
|
16 |
</li>
|
17 |
-
<?php if (
|
18 |
<li><a href="#database_options"
|
19 |
-
class="nav-tab col s12 m3 l2 "><?php echo
|
20 |
</li>
|
21 |
<?php endif ?>
|
22 |
<li><a href="#files_options"
|
23 |
-
class="nav-tab col s12 m3 l2 "><?php echo
|
24 |
</li>
|
25 |
<li><a href="#generate_backup"
|
26 |
-
class="nav-tab col s12 m3 l2 "><?php echo
|
27 |
</li>
|
28 |
<li><a href="#schedule_backup"
|
29 |
-
class="nav-tab col s12 m3 l2 "><?php echo
|
30 |
</li>
|
31 |
</ul>
|
32 |
|
@@ -39,11 +39,11 @@ $tab = 1;
|
|
39 |
<i class="material-icons prefix">input</i>
|
40 |
<input name="backup_name" id="backup_name" type="text"
|
41 |
value=<?php echo $xcloner_settings->get_default_backup_name() ?>>
|
42 |
-
<label for="backup_name"><?php echo __(
|
43 |
</div>
|
44 |
<div class="hide-on-small-only m2">
|
45 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
46 |
-
data-tooltip="<?php echo __(
|
47 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
48 |
</div>
|
49 |
</div>
|
@@ -52,12 +52,12 @@ $tab = 1;
|
|
52 |
<div class="input-field inline col s12 m10 l6">
|
53 |
<i class="material-icons prefix">email</i>
|
54 |
<input name="email_notification" id="email_notification" type="text"
|
55 |
-
value="<?php echo get_option(
|
56 |
-
<label for="email_notification"><?php echo __(
|
57 |
</div>
|
58 |
<div class="hide-on-small-only m2">
|
59 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
60 |
-
data-tooltip="<?php echo __(
|
61 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
62 |
</div>
|
63 |
</div>
|
@@ -67,24 +67,48 @@ $tab = 1;
|
|
67 |
<i class="material-icons prefix">access_time</i>
|
68 |
<input type="datetime-local" id="diff_start_date" class="datepicker_max_today"
|
69 |
name="diff_start_date">
|
70 |
-
<label for="diff_start_date"><?php echo __(
|
71 |
</div>
|
72 |
<div class="hide-on-small-only m2">
|
73 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50"
|
74 |
-
data-tooltip="<?php echo __(
|
75 |
class="material-icons">help_outline</i></a>
|
76 |
</div>
|
77 |
</div>
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
<div class="row">
|
80 |
<div class="input-field col s12 m10 l6">
|
81 |
<i class="material-icons prefix">input</i>
|
82 |
<textarea name="backup_comments" id="backup_comments" class="materialize-textarea"></textarea>
|
83 |
-
<label for="backup_comments"><?php echo __(
|
84 |
</div>
|
85 |
<div class="hide-on-small-only m2">
|
86 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
87 |
-
data-tooltip="<?php echo __(
|
88 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
89 |
</div>
|
90 |
</div>
|
@@ -97,11 +121,11 @@ $tab = 1;
|
|
97 |
</div>
|
98 |
</div>
|
99 |
|
100 |
-
<?php if (
|
101 |
<div id="database_options" class="tab-content">
|
102 |
-
<h2><?php echo __(
|
103 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
104 |
-
data-tooltip="<?php echo __(
|
105 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
106 |
</h2>
|
107 |
|
@@ -123,10 +147,10 @@ $tab = 1;
|
|
123 |
<?php endif ?>
|
124 |
|
125 |
<div id="files_options" class="tab-content">
|
126 |
-
<h2><?php echo __(
|
127 |
:
|
128 |
<a class="btn-floating tooltipped btn-small" data-position="bottom" data-delay="50" data-html="true"
|
129 |
-
data-tooltip="<?php echo __(
|
130 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
131 |
</h2>
|
132 |
|
@@ -161,9 +185,9 @@ $tab = 1;
|
|
161 |
<ul class="backup-status collapsible" data-collapsible="accordion">
|
162 |
<li class="file-system">
|
163 |
<div class="collapsible-header">
|
164 |
-
<i class="material-icons">folder</i><?php echo __(
|
165 |
|
166 |
-
<p class="right"><?php echo sprintf(
|
167 |
|
168 |
<div>
|
169 |
<p class="right"><span class="last-logged-file"></span></p>
|
@@ -175,12 +199,12 @@ $tab = 1;
|
|
175 |
</div>
|
176 |
<div class="collapsible-body status-body"></div>
|
177 |
</li>
|
178 |
-
<?php if (
|
179 |
<li class="database-backup">
|
180 |
<div class="collapsible-header">
|
181 |
-
<i class="material-icons">storage</i><?php echo __(
|
182 |
|
183 |
-
<p class="right"><?php echo sprintf(
|
184 |
|
185 |
<div>
|
186 |
<p class="right"><span class="last-logged-table"></span></p>
|
@@ -204,9 +228,9 @@ $tab = 1;
|
|
204 |
<?php endif ?>
|
205 |
<li class="files-backup">
|
206 |
<div class="collapsible-header">
|
207 |
-
<i class="material-icons">archive</i><?php echo __(
|
208 |
|
209 |
-
<p class="right"><?php echo sprintf(
|
210 |
|
211 |
<div>
|
212 |
<p class="right"><span class="last-logged-file"></span></p>
|
@@ -219,7 +243,7 @@ $tab = 1;
|
|
219 |
<div class="collapsible-body status-body">
|
220 |
<div class="row">
|
221 |
<div class="col l3 s12">
|
222 |
-
<h2><?php echo __(
|
223 |
</div>
|
224 |
<div class="col l9 s12">
|
225 |
<ul class="backup-name"></ul>
|
@@ -227,21 +251,36 @@ $tab = 1;
|
|
227 |
</div>
|
228 |
</div>
|
229 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
<li class="backup-done">
|
231 |
<div class="collapsible-header">
|
232 |
-
<i class="material-icons">done</i><?php echo __(
|
233 |
|
234 |
<p class="right">
|
235 |
-
<?php if (
|
236 |
<a href="#" class="cloud-upload"
|
237 |
-
title="<?php echo __(
|
238 |
class="material-icons">cloud_upload</i></a>
|
239 |
<?php endif ?>
|
240 |
<a href="#" class="download"
|
241 |
-
title="<?php echo __(
|
242 |
class="material-icons">file_download</i></a>
|
243 |
<a href="#" class="list-backup-content"
|
244 |
-
title="<?php echo __(
|
245 |
class="material-icons">folder_open</i></a>
|
246 |
</p>
|
247 |
|
@@ -252,8 +291,8 @@ $tab = 1;
|
|
252 |
</div>
|
253 |
<div class="collapsible-body center-align">
|
254 |
<div class="row">
|
255 |
-
<h5><?php echo __(
|
256 |
-
<h6><?php echo sprintf(
|
257 |
<a class="twitter-follow-button" href="https://twitter.com/thinkovi"
|
258 |
data-show-count="false">Follow @thinkovi</a>
|
259 |
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
@@ -274,9 +313,9 @@ $tab = 1;
|
|
274 |
|
275 |
<div class="row">
|
276 |
<div id="schedule_backup_success" class="col s12 l6 updated settings-error notice is-dismissible">
|
277 |
-
<p><strong><?php echo __(
|
278 |
<button type="button" class="notice-dismiss"><span
|
279 |
-
class="screen-reader-text"><?php echo __(
|
280 |
</button>
|
281 |
</div>
|
282 |
</div>
|
@@ -284,18 +323,18 @@ $tab = 1;
|
|
284 |
<div class="row">
|
285 |
<div class="input-field inline col s12 l7">
|
286 |
<input type="text" id="schedule_name" class="" name="schedule_name" required>
|
287 |
-
<label for="schedule_name"><?php echo __(
|
288 |
</div>
|
289 |
</div>
|
290 |
|
291 |
<div class="row">
|
292 |
<div class="input-field inline col s12 m8 l4">
|
293 |
<input type="datetime-local" id="datepicker" class="datepicker" name="schedule_start_date">
|
294 |
-
<label for="datepicker"><?php echo __(
|
295 |
</div>
|
296 |
<div class="input-field inline col s12 m4 l3">
|
297 |
<input id="timepicker_ampm_dark" class="timepicker" type="time" name="schedule_start_time">
|
298 |
-
<label for="timepicker_ampm_dark"><?php echo __(
|
299 |
</div>
|
300 |
</div>
|
301 |
|
@@ -303,17 +342,17 @@ $tab = 1;
|
|
303 |
<div class="row">
|
304 |
<div class="input-field inline col s10 m11 l7">
|
305 |
<select id="backup_type" class="" name="backup_type">
|
306 |
-
<option value=""><?php echo __(
|
307 |
-
<option value="diff"><?php echo __(
|
308 |
-
<option value="full_diff"><?php echo __(
|
309 |
</select>
|
310 |
-
<label for="backup_type"><?php echo __(
|
311 |
</div>
|
312 |
<div class="col s2 m1">
|
313 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50" data-tooltip="<ul style='max-width:760px; text-align:left;'>
|
314 |
-
<li><?php echo __(
|
315 |
-
<li><?php echo __(
|
316 |
-
<li><?php echo __(
|
317 |
</ul>"><i class="material-icons">help_outline</i></a>
|
318 |
</div>
|
319 |
</div>
|
@@ -322,38 +361,38 @@ $tab = 1;
|
|
322 |
<div class="input-field col s12 l7">
|
323 |
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
324 |
<option value="" disabled
|
325 |
-
selected><?php echo __(
|
326 |
<?php
|
327 |
$schedules = $xcloner_scheduler->get_available_intervals();
|
328 |
|
329 |
-
foreach (
|
330 |
?>
|
331 |
<option value="<?php echo $key ?>"><?php echo $schedule['display'] ?></option>
|
332 |
<?php
|
333 |
}
|
334 |
?>
|
335 |
</select>
|
336 |
-
<label><?php echo __(
|
337 |
</div>
|
338 |
</div>
|
339 |
|
340 |
-
<?php if (
|
341 |
<div class="row">
|
342 |
<div class="input-field col s12 m12 l7">
|
343 |
<select name="schedule_storage" id="schedule_storage" class="validate">
|
344 |
-
<option value="" selected><?php echo __(
|
345 |
-
<?php foreach (
|
346 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
347 |
<?php endforeach ?>
|
348 |
</select>
|
349 |
-
<label><?php echo __(
|
350 |
</div>
|
351 |
</div>
|
352 |
<?php endif ?>
|
353 |
<div class="row">
|
354 |
<div class="col s12 l7">
|
355 |
<button class="right btn waves-effect waves-light submit_schedule" type="submit"
|
356 |
-
name="action"><?php echo __(
|
357 |
<i class="material-icons right">send</i>
|
358 |
</button>
|
359 |
</div>
|
@@ -368,19 +407,19 @@ $tab = 1;
|
|
368 |
class="material-icons medium right">help</i></a>
|
369 |
<div class="modal-content">
|
370 |
<h4 class="title_line"><span class="title"></span></h4>
|
371 |
-
<!--<h5 class="title_line"><?php echo __(
|
372 |
-
<h5><?php echo __(
|
373 |
<textarea class="body" rows="5"></textarea>
|
374 |
</div>
|
375 |
<div class="modal-footer">
|
376 |
-
<a class=" modal-action modal-close waves-effect waves-green btn-flat red darken-2"><?php echo __(
|
377 |
</div>
|
378 |
</div>
|
379 |
|
380 |
<!-- List Backup Content Modal-->
|
381 |
<div id="backup_cotent_modal" class="modal">
|
382 |
<div class="modal-content">
|
383 |
-
<h4><?php echo sprintf(
|
384 |
<h5 class="backup-name"></h5>
|
385 |
|
386 |
<div class="progress">
|
@@ -395,18 +434,18 @@ $tab = 1;
|
|
395 |
<form method="POST" class="remote-storage-form">
|
396 |
<input type="hidden" name="file" class="backup_name">
|
397 |
<div class="modal-content">
|
398 |
-
<h4><?php echo __(
|
399 |
<p>
|
400 |
-
<?php if (
|
401 |
<div class="row">
|
402 |
<div class="col s12 label">
|
403 |
-
<label><?php echo __(
|
404 |
</div>
|
405 |
<div class="input-field col s8 m10">
|
406 |
<select name="transfer_storage" id="transfer_storage" class="validate" required>
|
407 |
<option value=""
|
408 |
-
selected><?php echo __(
|
409 |
-
<?php foreach (
|
410 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
411 |
<?php endforeach ?>
|
412 |
</select>
|
@@ -418,7 +457,7 @@ $tab = 1;
|
|
418 |
</div>
|
419 |
</div>
|
420 |
<div class="row status">
|
421 |
-
<?php echo __(
|
422 |
<span class="status-text"></span>
|
423 |
<div class="progress">
|
424 |
<div class="indeterminate"></div>
|
@@ -502,7 +541,7 @@ $tab = 1;
|
|
502 |
}
|
503 |
});
|
504 |
|
505 |
-
<?php if($xcloner_settings->get_enable_mysql_backup()):?>
|
506 |
jQuery('#jstree_database_container').jstree({
|
507 |
'core': {
|
508 |
'check_callback': true,
|
8 |
|
9 |
<script>var xcloner_backup = new Xcloner_Backup();</script>
|
10 |
|
11 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
12 |
|
13 |
<ul class="nav-tab-wrapper content row">
|
14 |
<li><a href="#backup_options"
|
15 |
+
class="nav-tab col s12 m3 l2 nav-tab-active"><?php echo $tab.". ".__('Backup Options', 'xcloner-backup-and-restore') ?></a>
|
16 |
</li>
|
17 |
+
<?php if ($xcloner_settings->get_enable_mysql_backup()): ?>
|
18 |
<li><a href="#database_options"
|
19 |
+
class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Database Options', 'xcloner-backup-and-restore') ?></a>
|
20 |
</li>
|
21 |
<?php endif ?>
|
22 |
<li><a href="#files_options"
|
23 |
+
class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Files Options', 'xcloner-backup-and-restore') ?></a>
|
24 |
</li>
|
25 |
<li><a href="#generate_backup"
|
26 |
+
class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Generate Backup', 'xcloner-backup-and-restore') ?></a>
|
27 |
</li>
|
28 |
<li><a href="#schedule_backup"
|
29 |
+
class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Schedule Backup', 'xcloner-backup-and-restore') ?></a>
|
30 |
</li>
|
31 |
</ul>
|
32 |
|
39 |
<i class="material-icons prefix">input</i>
|
40 |
<input name="backup_name" id="backup_name" type="text"
|
41 |
value=<?php echo $xcloner_settings->get_default_backup_name() ?>>
|
42 |
+
<label for="backup_name"><?php echo __('Backup Name', 'xcloner-backup-and-restore') ?></label>
|
43 |
</div>
|
44 |
<div class="hide-on-small-only m2">
|
45 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
46 |
+
data-tooltip="<?php echo __('The default backup name, supported tags [time], [hostname], [domain]', 'xcloner-backup-and-restore') ?>"
|
47 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
48 |
</div>
|
49 |
</div>
|
52 |
<div class="input-field inline col s12 m10 l6">
|
53 |
<i class="material-icons prefix">email</i>
|
54 |
<input name="email_notification" id="email_notification" type="text"
|
55 |
+
value="<?php echo get_option('admin_email'); ?>">
|
56 |
+
<label for="email_notification"><?php echo __('Send Email Notification To', 'xcloner-backup-and-restore') ?></label>
|
57 |
</div>
|
58 |
<div class="hide-on-small-only m2">
|
59 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
60 |
+
data-tooltip="<?php echo __('If left blank, no notification will be sent', 'xcloner-backup-and-restore') ?>"
|
61 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
62 |
</div>
|
63 |
</div>
|
67 |
<i class="material-icons prefix">access_time</i>
|
68 |
<input type="datetime-local" id="diff_start_date" class="datepicker_max_today"
|
69 |
name="diff_start_date">
|
70 |
+
<label for="diff_start_date"><?php echo __('Backup Only Files Modified/Created After', 'xcloner-backup-and-restore') ?></label>
|
71 |
</div>
|
72 |
<div class="hide-on-small-only m2">
|
73 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50"
|
74 |
+
data-tooltip="<?php echo __("This option allows you to create a differential backup that will include only <br> changed files since the set date, leave blank to include all files", "xcloner-backup-and-restore") ?>"><i
|
75 |
class="material-icons">help_outline</i></a>
|
76 |
</div>
|
77 |
</div>
|
78 |
|
79 |
+
<div class="row">
|
80 |
+
<div class="input-field col s6 m5 l4">
|
81 |
+
<i class="material-icons prefix">enhanced_encryption</i>
|
82 |
+
<label for="backup_comments"><?php echo __('Encrypt Backup', 'xcloner-backup-and-restore') ?></label>
|
83 |
+
|
84 |
+
</div>
|
85 |
+
<div class="input-field col s6 m5 l2">
|
86 |
+
<div class="switch">
|
87 |
+
<label>
|
88 |
+
Off
|
89 |
+
<input type="checkbox" name="backup_encrypt" id="backup_encrypt" value="1">
|
90 |
+
<span class="lever"></span>
|
91 |
+
On
|
92 |
+
</label>
|
93 |
+
</div>
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<div class="hide-on-small-only s12 m2">
|
97 |
+
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
98 |
+
data-tooltip="<?php echo __('Enable this option if you want to encrypt the final backup', 'xcloner-backup-and-restore') ?>"
|
99 |
+
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
100 |
+
</div>
|
101 |
+
</div>
|
102 |
+
|
103 |
<div class="row">
|
104 |
<div class="input-field col s12 m10 l6">
|
105 |
<i class="material-icons prefix">input</i>
|
106 |
<textarea name="backup_comments" id="backup_comments" class="materialize-textarea"></textarea>
|
107 |
+
<label for="backup_comments"><?php echo __('Backup Comments', 'xcloner-backup-and-restore') ?></label>
|
108 |
</div>
|
109 |
<div class="hide-on-small-only m2">
|
110 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
111 |
+
data-tooltip="<?php echo __('Some default backup comments that will be stored inside the backup archive', 'xcloner-backup-and-restore') ?>"
|
112 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
113 |
</div>
|
114 |
</div>
|
121 |
</div>
|
122 |
</div>
|
123 |
|
124 |
+
<?php if ($xcloner_settings->get_enable_mysql_backup()): ?>
|
125 |
<div id="database_options" class="tab-content">
|
126 |
+
<h2><?php echo __('Select database data to include in the backup', 'xcloner-backup-and-restore') ?>:
|
127 |
<a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50"
|
128 |
+
data-tooltip="<?php echo __('Enable the \'Backup only WP tables\' setting if you don\'t want to show all other databases and tables not related to this Wordpress install', 'xcloner-backup-and-restore'); ?>"
|
129 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
130 |
</h2>
|
131 |
|
147 |
<?php endif ?>
|
148 |
|
149 |
<div id="files_options" class="tab-content">
|
150 |
+
<h2><?php echo __('Select from below the files/folders you want to exclude from your Backup Archive', 'xcloner-backup-and-restore') ?>
|
151 |
:
|
152 |
<a class="btn-floating tooltipped btn-small" data-position="bottom" data-delay="50" data-html="true"
|
153 |
+
data-tooltip="<?php echo __('You can navigate below through all your site structure(Backup Start Location) to exclude any file/folder you need by clicking the checkbox near it. <br />If the checkobx is disabled, then it matches a Regex Exclude File option and it can\'t be unchecked', 'xcloner-backup-and-restore'); ?>"
|
154 |
data-tooltip-id=""><i class="material-icons">help_outline</i></a>
|
155 |
</h2>
|
156 |
|
185 |
<ul class="backup-status collapsible" data-collapsible="accordion">
|
186 |
<li class="file-system">
|
187 |
<div class="collapsible-header">
|
188 |
+
<i class="material-icons">folder</i><?php echo __('Scanning The File System...', 'xcloner-backup-and-restore') ?>
|
189 |
|
190 |
+
<p class="right"><?php echo sprintf(__('Found %s files (%s)', 'xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span class="file-size-total">0</span>MB') ?></p>
|
191 |
|
192 |
<div>
|
193 |
<p class="right"><span class="last-logged-file"></span></p>
|
199 |
</div>
|
200 |
<div class="collapsible-body status-body"></div>
|
201 |
</li>
|
202 |
+
<?php if ($xcloner_settings->get_enable_mysql_backup()): ?>
|
203 |
<li class="database-backup">
|
204 |
<div class="collapsible-header">
|
205 |
+
<i class="material-icons">storage</i><?php echo __('Generating the Mysql Backup...', 'xcloner-backup-and-restore') ?>
|
206 |
|
207 |
+
<p class="right"><?php echo sprintf(__('Found %s tables in %s databases (%s)', 'xcloner-backup-and-restore'), '<span class="table-counter">0</span>', '<span class="database-counter">0</span>', '<span data-processed="0" class="total-records">0</span> records', 'xcloner-backup-and-restore') ?></p>
|
208 |
|
209 |
<div>
|
210 |
<p class="right"><span class="last-logged-table"></span></p>
|
228 |
<?php endif ?>
|
229 |
<li class="files-backup">
|
230 |
<div class="collapsible-header">
|
231 |
+
<i class="material-icons">archive</i><?php echo __('Adding Files to Archive...', 'xcloner-backup-and-restore') ?>
|
232 |
|
233 |
+
<p class="right"><?php echo sprintf(__('Adding %s files (%s)', 'xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span data-processed="0" class="file-size-total">0</span>MB') ?></p>
|
234 |
|
235 |
<div>
|
236 |
<p class="right"><span class="last-logged-file"></span></p>
|
243 |
<div class="collapsible-body status-body">
|
244 |
<div class="row">
|
245 |
<div class="col l3 s12">
|
246 |
+
<h2><?php echo __("Backup Parts", 'xcloner-backup-and-restore') ?>: </h2>
|
247 |
</div>
|
248 |
<div class="col l9 s12">
|
249 |
<ul class="backup-name"></ul>
|
251 |
</div>
|
252 |
</div>
|
253 |
</li>
|
254 |
+
<li class="backup-encryption">
|
255 |
+
<div class="collapsible-header">
|
256 |
+
<i class="material-icons">enhanced_encryption</i><?php echo __('Encrypting Backup Data...', 'xcloner-backup-and-restore') ?>
|
257 |
+
|
258 |
+
<p class="right"><span class="status"></span></p>
|
259 |
+
|
260 |
+
<div>
|
261 |
+
<p class="right"><span class="last-logged-file"></span></p>
|
262 |
+
</div>
|
263 |
+
|
264 |
+
<div class="progress">
|
265 |
+
<div class="determinate" style="width:0%"></div>
|
266 |
+
</div>
|
267 |
+
</div>
|
268 |
+
</li>
|
269 |
<li class="backup-done">
|
270 |
<div class="collapsible-header">
|
271 |
+
<i class="material-icons">done</i><?php echo __('Backup Done', 'xcloner-backup-and-restore') ?>
|
272 |
|
273 |
<p class="right">
|
274 |
+
<?php if (sizeof($available_storages)): ?>
|
275 |
<a href="#" class="cloud-upload"
|
276 |
+
title="<?php echo __("Send Backup To Remote Storage", 'xcloner-backup-and-restore') ?>"><i
|
277 |
class="material-icons">cloud_upload</i></a>
|
278 |
<?php endif ?>
|
279 |
<a href="#" class="download"
|
280 |
+
title="<?php echo __("Download Backup", 'xcloner-backup-and-restore') ?>"><i
|
281 |
class="material-icons">file_download</i></a>
|
282 |
<a href="#" class="list-backup-content"
|
283 |
+
title="<?php echo __("List Backup Content", 'xcloner-backup-and-restore') ?>"><i
|
284 |
class="material-icons">folder_open</i></a>
|
285 |
</p>
|
286 |
|
291 |
</div>
|
292 |
<div class="collapsible-body center-align">
|
293 |
<div class="row">
|
294 |
+
<h5><?php echo __("Thank you for using XCloner.", 'xcloner-backup-and-restore') ?></h5>
|
295 |
+
<h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'), '<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore/reviews/" target="_blank">Wordpress XCloner Reviews Section</a>') ?></h6>
|
296 |
<a class="twitter-follow-button" href="https://twitter.com/thinkovi"
|
297 |
data-show-count="false">Follow @thinkovi</a>
|
298 |
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
313 |
|
314 |
<div class="row">
|
315 |
<div id="schedule_backup_success" class="col s12 l6 updated settings-error notice is-dismissible">
|
316 |
+
<p><strong><?php echo __('Schedule Saved', 'xcloner-backup-and-restore') ?></strong></p>
|
317 |
<button type="button" class="notice-dismiss"><span
|
318 |
+
class="screen-reader-text"><?php echo __('(Dismiss this notice.', 'xcloner-backup-and-restore') ?></span>
|
319 |
</button>
|
320 |
</div>
|
321 |
</div>
|
323 |
<div class="row">
|
324 |
<div class="input-field inline col s12 l7">
|
325 |
<input type="text" id="schedule_name" class="" name="schedule_name" required>
|
326 |
+
<label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
|
327 |
</div>
|
328 |
</div>
|
329 |
|
330 |
<div class="row">
|
331 |
<div class="input-field inline col s12 m8 l4">
|
332 |
<input type="datetime-local" id="datepicker" class="datepicker" name="schedule_start_date">
|
333 |
+
<label for="datepicker"><?php echo __('Schedule Backup To Start On:', 'xcloner-backup-and-restore') ?></label>
|
334 |
</div>
|
335 |
<div class="input-field inline col s12 m4 l3">
|
336 |
<input id="timepicker_ampm_dark" class="timepicker" type="time" name="schedule_start_time">
|
337 |
+
<label for="timepicker_ampm_dark"><?php echo __('At:', 'xcloner-backup-and-restore') ?></label>
|
338 |
</div>
|
339 |
</div>
|
340 |
|
342 |
<div class="row">
|
343 |
<div class="input-field inline col s10 m11 l7">
|
344 |
<select id="backup_type" class="" name="backup_type">
|
345 |
+
<option value=""><?php echo __("Full Backup", "xcloner-backup-and-restore"); ?></option>
|
346 |
+
<option value="diff"><?php echo __("Differential Backups", "xcloner-backup-and-restore"); ?></option>
|
347 |
+
<option value="full_diff"><?php echo __("Full Backup + Differential Backups", "xcloner-backup-and-restore"); ?></option>
|
348 |
</select>
|
349 |
+
<label for="backup_type"><?php echo __('Scheduled Backup Type', 'xcloner-backup-and-restore') ?></label>
|
350 |
</div>
|
351 |
<div class="col s2 m1">
|
352 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50" data-tooltip="<ul style='max-width:760px; text-align:left;'>
|
353 |
+
<li><?php echo __("Full Backup = it will generate a full backup of all included files each time schedule runs", "xcloner-backup-and-restore"); ?></li>
|
354 |
+
<li><?php echo __("Differentials Backups = backups will include only changed files since the schedule started to run", "xcloner-backup-and-restore"); ?></li>
|
355 |
+
<li><?php echo __("Full Backup + Differential Backups = the first time schedule runs, it will create a full backup and all next scheduled backups will include only files created/modified since that last full backup; a full backup is recreated when the number of changed files is bigger than the 'Differetial Backups Max Days' XCloner option.", "xcloner-backup-and-restore"); ?></li>
|
356 |
</ul>"><i class="material-icons">help_outline</i></a>
|
357 |
</div>
|
358 |
</div>
|
361 |
<div class="input-field col s12 l7">
|
362 |
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
363 |
<option value="" disabled
|
364 |
+
selected><?php echo __('please select', 'xcloner-backup-and-restore') ?></option>
|
365 |
<?php
|
366 |
$schedules = $xcloner_scheduler->get_available_intervals();
|
367 |
|
368 |
+
foreach ($schedules as $key => $schedule) {
|
369 |
?>
|
370 |
<option value="<?php echo $key ?>"><?php echo $schedule['display'] ?></option>
|
371 |
<?php
|
372 |
}
|
373 |
?>
|
374 |
</select>
|
375 |
+
<label><?php echo __('Schedule Frequency', 'xcloner-backup-and-restore') ?></label>
|
376 |
</div>
|
377 |
</div>
|
378 |
|
379 |
+
<?php if (sizeof($available_storages)): ?>
|
380 |
<div class="row">
|
381 |
<div class="input-field col s12 m12 l7">
|
382 |
<select name="schedule_storage" id="schedule_storage" class="validate">
|
383 |
+
<option value="" selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
|
384 |
+
<?php foreach ($available_storages as $storage => $text): ?>
|
385 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
386 |
<?php endforeach ?>
|
387 |
</select>
|
388 |
+
<label><?php echo __('Send To Remote Storage', 'xcloner-backup-and-restore') ?></label>
|
389 |
</div>
|
390 |
</div>
|
391 |
<?php endif ?>
|
392 |
<div class="row">
|
393 |
<div class="col s12 l7">
|
394 |
<button class="right btn waves-effect waves-light submit_schedule" type="submit"
|
395 |
+
name="action"><?php echo __("Submit", 'xcloner-backup-and-restore') ?>
|
396 |
<i class="material-icons right">send</i>
|
397 |
</button>
|
398 |
</div>
|
407 |
class="material-icons medium right">help</i></a>
|
408 |
<div class="modal-content">
|
409 |
<h4 class="title_line"><span class="title"></span></h4>
|
410 |
+
<!--<h5 class="title_line"><?php echo __('Message') ?>: <span class="msg.old"></span></h5>-->
|
411 |
+
<h5><?php echo __('Response Code', 'xcloner-backup-and-restore') ?>: <span class="status"></span></h5>
|
412 |
<textarea class="body" rows="5"></textarea>
|
413 |
</div>
|
414 |
<div class="modal-footer">
|
415 |
+
<a class=" modal-action modal-close waves-effect waves-green btn-flat red darken-2"><?php echo __('Close', 'xcloner-backup-and-restore') ?></a>
|
416 |
</div>
|
417 |
</div>
|
418 |
|
419 |
<!-- List Backup Content Modal-->
|
420 |
<div id="backup_cotent_modal" class="modal">
|
421 |
<div class="modal-content">
|
422 |
+
<h4><?php echo sprintf(__("Listing Backup Content ", 'xcloner-backup-and-restore'), "") ?></h4>
|
423 |
<h5 class="backup-name"></h5>
|
424 |
|
425 |
<div class="progress">
|
434 |
<form method="POST" class="remote-storage-form">
|
435 |
<input type="hidden" name="file" class="backup_name">
|
436 |
<div class="modal-content">
|
437 |
+
<h4><?php echo __("Remote Storage Transfer", 'xcloner-backup-and-restore') ?></h4>
|
438 |
<p>
|
439 |
+
<?php if (sizeof($available_storages)): ?>
|
440 |
<div class="row">
|
441 |
<div class="col s12 label">
|
442 |
+
<label><?php echo __(sprintf('Send %s to remote storage', "<span class='backup_name'></span>"), 'xcloner-backup-and-restore') ?></label>
|
443 |
</div>
|
444 |
<div class="input-field col s8 m10">
|
445 |
<select name="transfer_storage" id="transfer_storage" class="validate" required>
|
446 |
<option value=""
|
447 |
+
selected><?php echo __('please select...', 'xcloner-backup-and-restore') ?></option>
|
448 |
+
<?php foreach ($available_storages as $storage => $text): ?>
|
449 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
450 |
<?php endforeach ?>
|
451 |
</select>
|
457 |
</div>
|
458 |
</div>
|
459 |
<div class="row status">
|
460 |
+
<?php echo __("Uploading backup to the selected remote storage...", 'xcloner-backup-and-restore') ?>
|
461 |
<span class="status-text"></span>
|
462 |
<div class="progress">
|
463 |
<div class="indeterminate"></div>
|
541 |
}
|
542 |
});
|
543 |
|
544 |
+
<?php if ($xcloner_settings->get_enable_mysql_backup()):?>
|
545 |
jQuery('#jstree_database_container').jstree({
|
546 |
'core': {
|
547 |
'check_callback': true,
|
admin/partials/xcloner_init_page.php
CHANGED
@@ -20,12 +20,12 @@ $xcloner_scheduler = $this->get_xcloner_container()->get_xcloner_scheduler();
|
|
20 |
|
21 |
$logger_content = $logger->getLastDebugLines();
|
22 |
|
23 |
-
$date_format = get_option(
|
24 |
-
$time_format = get_option(
|
25 |
|
26 |
//$xcloner_file_system->cleanup_tmp_directories();
|
27 |
|
28 |
-
if (
|
29 |
$latest_backup = $xcloner_file_system->get_latest_backup();
|
30 |
$xcloner_file_system->backup_storage_cleanup();
|
31 |
}
|
@@ -34,15 +34,15 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
34 |
<div class="row">
|
35 |
<div class="col s12">
|
36 |
<h5 class="left-align">
|
37 |
-
<?php echo __(
|
38 |
</h5>
|
39 |
</div>
|
40 |
</div>
|
41 |
|
42 |
-
<?php if (
|
43 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
44 |
<p><strong>
|
45 |
-
<?php echo __(
|
46 |
</strong>
|
47 |
</p>
|
48 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
@@ -50,10 +50,10 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
50 |
</div>
|
51 |
<?php endif ?>
|
52 |
|
53 |
-
<?php if (
|
54 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
55 |
<p><strong>
|
56 |
-
<?php echo __(
|
57 |
</strong>
|
58 |
</p>
|
59 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
@@ -61,10 +61,10 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
61 |
</div>
|
62 |
<?php endif ?>
|
63 |
|
64 |
-
<?php if (
|
65 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
66 |
<p><strong>
|
67 |
-
<?php echo __(
|
68 |
</strong>
|
69 |
</p>
|
70 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
@@ -87,74 +87,74 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
87 |
<div class="collapsible-body">
|
88 |
<div class="" id="backup-status">
|
89 |
<div class="row">
|
90 |
-
<h5><?php echo __(
|
91 |
<blockquote>
|
92 |
-
<?php if (
|
93 |
<div class="item">
|
94 |
-
<div class="title"><?php echo __(
|
95 |
:
|
96 |
</div>
|
97 |
<?php echo $latest_backup['basename'] ?>
|
98 |
</div>
|
99 |
<div class="item">
|
100 |
<div class="title">
|
101 |
-
<?php echo __(
|
102 |
</div>
|
103 |
-
<?php echo size_format(
|
104 |
</div>
|
105 |
<div class="item">
|
106 |
-
<div class="title"><?php echo __(
|
107 |
:
|
108 |
</div>
|
109 |
<?php
|
110 |
-
echo date(
|
111 |
?>
|
112 |
</div>
|
113 |
<?php else: ?>
|
114 |
<div class="item">
|
115 |
-
<div class="title"><?php echo __(
|
116 |
</div>
|
117 |
<?php endif ?>
|
118 |
</blockquote>
|
119 |
<div>
|
120 |
-
<h5><?php echo __(
|
121 |
<blockquote>
|
122 |
<div class="item">
|
123 |
-
<div class="title"><?php echo __(
|
124 |
:
|
125 |
</div>
|
126 |
-
<?php echo size_format(
|
127 |
</div>
|
128 |
</blockquote>
|
129 |
-
<h5><?php echo __(
|
130 |
<blockquote>
|
131 |
<div class="item">
|
132 |
<?php
|
133 |
-
$list = (
|
134 |
|
135 |
-
if (
|
136 |
-
$xcloner_file_system->sort_by(
|
137 |
}
|
138 |
|
139 |
-
if (
|
140 |
$latest_schedule = $list[0];
|
141 |
}
|
142 |
?>
|
143 |
-
<?php if (
|
144 |
-
<div class="title"><?php echo __(
|
145 |
:
|
146 |
</div>
|
147 |
<?php echo $latest_schedule->name; ?>
|
148 |
<?php endif; ?>
|
149 |
</div>
|
150 |
<div class="item">
|
151 |
-
<div class="title"><?php echo __(
|
152 |
:
|
153 |
</div>
|
154 |
-
<?php if (
|
155 |
-
echo date(
|
156 |
} else {
|
157 |
-
echo __(
|
158 |
}
|
159 |
?>
|
160 |
</div>
|
@@ -163,20 +163,20 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
163 |
</div>
|
164 |
</li>
|
165 |
|
166 |
-
<?php if (
|
167 |
<li class="active">
|
168 |
<div class="collapsible-header active">
|
169 |
-
<i class="material-icons">bug_report</i><?php echo __(
|
170 |
<div class="right">
|
171 |
-
<a href="#<?php echo $logger_basename = basename(
|
172 |
class="download-logger" title="<?php echo $logger_basename ?>">
|
173 |
<span class="shorten_string"><?php echo $logger_basename ?> </span>
|
174 |
</a>
|
175 |
</div>
|
176 |
</div>
|
177 |
<div class="collapsible-body">
|
178 |
-
<div class="console" id="xcloner-console"><?php if (
|
179 |
-
echo implode(
|
180 |
} ?></div>
|
181 |
</div>
|
182 |
</li>
|
@@ -201,71 +201,71 @@ if ( $requirements->check_backup_ready_status() ) {
|
|
201 |
|
202 |
<div class="card blue-grey darken-1 z-depth-4 backup-ready">
|
203 |
<div class="card-content white-text">
|
204 |
-
<span class="card-title"><?php echo __(
|
205 |
<ul>
|
206 |
-
<li class="card-panel <?php echo(
|
207 |
-
<?php echo __(
|
208 |
class="shorten_string "><?php echo $requirements->check_xcloner_start_path(); ?></span>
|
209 |
</li>
|
210 |
-
<li class="card-panel <?php echo(
|
211 |
-
<?php echo __(
|
212 |
class="shorten_string"><?php echo $requirements->check_xcloner_store_path(); ?></span>
|
213 |
</li>
|
214 |
-
<li class="card-panel <?php echo(
|
215 |
-
<?php echo __(
|
216 |
class="shorten_string"><?php echo $requirements->check_xcloner_tmp_path(); ?></span>
|
217 |
</li>
|
218 |
|
219 |
-
<li class="card-panel <?php echo(
|
220 |
-
<?php echo __(
|
221 |
: <?php echo $requirements->check_min_php_version(); ?>
|
222 |
-
( >= <?php echo $requirements->get_constant(
|
223 |
</li>
|
224 |
-
<li class="card-panel <?php echo(
|
225 |
-
<?php echo __(
|
226 |
: <?php echo $requirements->check_safe_mode(); ?>
|
227 |
-
( <?php echo $requirements->get_constant(
|
228 |
</li>
|
229 |
-
<li class="card-panel <?php echo(
|
230 |
-
<?php echo(
|
231 |
-
<i class="material-icons right tiny"><?php echo(
|
232 |
</li>
|
233 |
</ul>
|
234 |
<ul class="additional_system_info">
|
235 |
<li class="card-panel grey darken-1">
|
236 |
-
<?php echo __(
|
237 |
: <?php echo $requirements->get_max_execution_time(); ?>
|
238 |
</li>
|
239 |
<li class="card-panel grey darken-1">
|
240 |
-
<?php echo __(
|
241 |
: <?php echo $requirements->get_memory_limit(); ?>
|
242 |
</li>
|
243 |
<li class="card-panel grey darken-1">
|
244 |
-
<?php echo __(
|
245 |
: <?php echo $requirements->get_open_basedir(); ?>
|
246 |
</li>
|
247 |
<?php
|
248 |
$data = array();
|
249 |
-
if (
|
250 |
$data = $xcloner_file_system->estimate_read_write_time();
|
251 |
}
|
252 |
?>
|
253 |
<li class="card-panel grey darken-1">
|
254 |
-
<?php echo __(
|
255 |
-
: <?php echo(
|
256 |
</li>
|
257 |
<li class="card-panel grey darken-1">
|
258 |
-
<?php echo __(
|
259 |
-
: <?php echo(
|
260 |
</li>
|
261 |
<li class="card-panel grey darken-1">
|
262 |
-
<?php echo __(
|
263 |
-
: <?php echo $requirements->get_free_disk_space()
|
264 |
</li>
|
265 |
</ul>
|
266 |
</div>
|
267 |
<div class="card-action">
|
268 |
-
<a class="waves-effect waves-light btn system_info_toggle blue darken-1"><i class="material-icons left">list</i><?php echo __(
|
269 |
</a>
|
270 |
</div>
|
271 |
</div>
|
20 |
|
21 |
$logger_content = $logger->getLastDebugLines();
|
22 |
|
23 |
+
$date_format = get_option('date_format');
|
24 |
+
$time_format = get_option('time_format');
|
25 |
|
26 |
//$xcloner_file_system->cleanup_tmp_directories();
|
27 |
|
28 |
+
if ($requirements->check_backup_ready_status()) {
|
29 |
$latest_backup = $xcloner_file_system->get_latest_backup();
|
30 |
$xcloner_file_system->backup_storage_cleanup();
|
31 |
}
|
34 |
<div class="row">
|
35 |
<div class="col s12">
|
36 |
<h5 class="left-align">
|
37 |
+
<?php echo __('Backup Dashboard', 'xcloner-backup-and-restore') ?>
|
38 |
</h5>
|
39 |
</div>
|
40 |
</div>
|
41 |
|
42 |
+
<?php if (isset($latest_backup['timestamp']) and $latest_backup['timestamp'] < strtotime("-1 day")): ?>
|
43 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
44 |
<p><strong>
|
45 |
+
<?php echo __('Your latest backup is older than 24 hours, please create a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
|
46 |
</strong>
|
47 |
</p>
|
48 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
50 |
</div>
|
51 |
<?php endif ?>
|
52 |
|
53 |
+
<?php if (!isset($latest_backup['timestamp'])): ?>
|
54 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
55 |
<p><strong>
|
56 |
+
<?php echo __('You have no backup that I could find, please generate a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
|
57 |
</strong>
|
58 |
</p>
|
59 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
61 |
</div>
|
62 |
<?php endif ?>
|
63 |
|
64 |
+
<?php if (!$requirements->check_backup_ready_status()): ?>
|
65 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
66 |
<p><strong>
|
67 |
+
<?php echo __('Backup system not ready, please check and fix the issues marked in red', 'xcloner-backup-and-restore') ?>
|
68 |
</strong>
|
69 |
</p>
|
70 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
87 |
<div class="collapsible-body">
|
88 |
<div class="" id="backup-status">
|
89 |
<div class="row">
|
90 |
+
<h5><?php echo __("Latest Backup", 'xcloner-backup-and-restore') ?></h5>
|
91 |
<blockquote>
|
92 |
+
<?php if (isset($latest_backup)): ?>
|
93 |
<div class="item">
|
94 |
+
<div class="title"><?php echo __("Backup Name", 'xcloner-backup-and-restore') ?>
|
95 |
:
|
96 |
</div>
|
97 |
<?php echo $latest_backup['basename'] ?>
|
98 |
</div>
|
99 |
<div class="item">
|
100 |
<div class="title">
|
101 |
+
<?php echo __("Backup Size", 'xcloner-backup-and-restore') ?>:
|
102 |
</div>
|
103 |
+
<?php echo size_format($latest_backup['size']) ?>
|
104 |
</div>
|
105 |
<div class="item">
|
106 |
+
<div class="title"><?php echo __("Backup Date", 'xcloner-backup-and-restore') ?>
|
107 |
:
|
108 |
</div>
|
109 |
<?php
|
110 |
+
echo date($date_format." ".$time_format, $latest_backup['timestamp'] + (get_option('gmt_offset') * HOUR_IN_SECONDS))
|
111 |
?>
|
112 |
</div>
|
113 |
<?php else: ?>
|
114 |
<div class="item">
|
115 |
+
<div class="title"><?php echo __("No Backup Yet", 'xcloner-backup-and-restore') ?></div>
|
116 |
</div>
|
117 |
<?php endif ?>
|
118 |
</blockquote>
|
119 |
<div>
|
120 |
+
<h5><?php echo __("Backup Storage Usage", 'xcloner-backup-and-restore') ?></h5>
|
121 |
<blockquote>
|
122 |
<div class="item">
|
123 |
+
<div class="title"><?php echo __("Total Size", 'xcloner-backup-and-restore') ?>
|
124 |
:
|
125 |
</div>
|
126 |
+
<?php echo size_format($xcloner_file_system->get_storage_usage()); ?>
|
127 |
</div>
|
128 |
</blockquote>
|
129 |
+
<h5><?php echo __("Next Scheduled Backup", 'xcloner-backup-and-restore') ?></h5>
|
130 |
<blockquote>
|
131 |
<div class="item">
|
132 |
<?php
|
133 |
+
$list = ($xcloner_scheduler->get_next_run_schedule());
|
134 |
|
135 |
+
if (is_array($list)) {
|
136 |
+
$xcloner_file_system->sort_by($list, "next_run_time", "asc");
|
137 |
}
|
138 |
|
139 |
+
if (isset($list[0])) {
|
140 |
$latest_schedule = $list[0];
|
141 |
}
|
142 |
?>
|
143 |
+
<?php if (isset($latest_schedule->name)): ?>
|
144 |
+
<div class="title"><?php echo __("Schedule Name", 'xcloner-backup-and-restore') ?>
|
145 |
:
|
146 |
</div>
|
147 |
<?php echo $latest_schedule->name; ?>
|
148 |
<?php endif; ?>
|
149 |
</div>
|
150 |
<div class="item">
|
151 |
+
<div class="title"><?php echo __("Next Call", 'xcloner-backup-and-restore') ?>
|
152 |
:
|
153 |
</div>
|
154 |
+
<?php if (isset($latest_schedule->next_run_time)) {
|
155 |
+
echo date($date_format." ".$time_format, $latest_schedule->next_run_time);
|
156 |
} else {
|
157 |
+
echo __("Unscheduled", 'xcloner-backup-and-restore');
|
158 |
}
|
159 |
?>
|
160 |
</div>
|
163 |
</div>
|
164 |
</li>
|
165 |
|
166 |
+
<?php if ($xcloner_settings->get_xcloner_option('xcloner_enable_log')) : ?>
|
167 |
<li class="active">
|
168 |
<div class="collapsible-header active">
|
169 |
+
<i class="material-icons">bug_report</i><?php echo __('XCloner Debugger', 'xcloner-backup-and-restore') ?>
|
170 |
<div class="right">
|
171 |
+
<a href="#<?php echo $logger_basename = basename($logger->get_main_logger_url()) ?>"
|
172 |
class="download-logger" title="<?php echo $logger_basename ?>">
|
173 |
<span class="shorten_string"><?php echo $logger_basename ?> </span>
|
174 |
</a>
|
175 |
</div>
|
176 |
</div>
|
177 |
<div class="collapsible-body">
|
178 |
+
<div class="console" id="xcloner-console"><?php if ($logger_content) {
|
179 |
+
echo implode("<br />\n", array_reverse($logger_content));
|
180 |
} ?></div>
|
181 |
</div>
|
182 |
</li>
|
201 |
|
202 |
<div class="card blue-grey darken-1 z-depth-4 backup-ready">
|
203 |
<div class="card-content white-text">
|
204 |
+
<span class="card-title"><?php echo __("System Check", 'xcloner-backup-and-restore') ?></span>
|
205 |
<ul>
|
206 |
+
<li class="card-panel <?php echo($requirements->check_xcloner_start_path(1) ? "teal" : "red") ?> lighten-2">
|
207 |
+
<?php echo __('Backup Start Location', 'xcloner-backup-and-restore') ?>: <span
|
208 |
class="shorten_string "><?php echo $requirements->check_xcloner_start_path(); ?></span>
|
209 |
</li>
|
210 |
+
<li class="card-panel <?php echo($requirements->check_xcloner_store_path(1) ? "teal" : "red") ?> lighten-2">
|
211 |
+
<?php echo __('Backup Storage Location', 'xcloner-backup-and-restore') ?>: <span
|
212 |
class="shorten_string"><?php echo $requirements->check_xcloner_store_path(); ?></span>
|
213 |
</li>
|
214 |
+
<li class="card-panel <?php echo($requirements->check_xcloner_tmp_path(1) ? "teal" : "red") ?> lighten-2">
|
215 |
+
<?php echo __('Temporary Location', 'xcloner-backup-and-restore') ?>: <span
|
216 |
class="shorten_string"><?php echo $requirements->check_xcloner_tmp_path(); ?></span>
|
217 |
</li>
|
218 |
|
219 |
+
<li class="card-panel <?php echo($requirements->check_min_php_version(1) ? "teal" : "red") ?> lighten-2">
|
220 |
+
<?php echo __('PHP Version Check', 'xcloner-backup-and-restore') ?>
|
221 |
: <?php echo $requirements->check_min_php_version(); ?>
|
222 |
+
( >= <?php echo $requirements->get_constant('min_php_version') ?>)
|
223 |
</li>
|
224 |
+
<li class="card-panel <?php echo($requirements->check_safe_mode(1) ? "teal" : "orange") ?> lighten-2">
|
225 |
+
<?php echo __('PHP Safe Mode', 'xcloner-backup-and-restore') ?>
|
226 |
: <?php echo $requirements->check_safe_mode(); ?>
|
227 |
+
( <?php echo $requirements->get_constant('safe_mode') ?>)
|
228 |
</li>
|
229 |
+
<li class="card-panel <?php echo($requirements->check_backup_ready_status() ? "teal" : "red") ?> lighten-2">
|
230 |
+
<?php echo($requirements->check_backup_ready_status() ? __('BACKUP READY', 'xcloner-backup-and-restore') : __('Backup not ready, please check above requirements', 'xcloner-backup-and-restore')) ?>
|
231 |
+
<i class="material-icons right tiny"><?php echo($requirements->check_backup_ready_status() ? 'thumb_up' : 'thumb_down') ?></i>
|
232 |
</li>
|
233 |
</ul>
|
234 |
<ul class="additional_system_info">
|
235 |
<li class="card-panel grey darken-1">
|
236 |
+
<?php echo __('PHP max_execution_time', 'xcloner-backup-and-restore') ?>
|
237 |
: <?php echo $requirements->get_max_execution_time(); ?>
|
238 |
</li>
|
239 |
<li class="card-panel grey darken-1">
|
240 |
+
<?php echo __('PHP memory_limit', 'xcloner-backup-and-restore') ?>
|
241 |
: <?php echo $requirements->get_memory_limit(); ?>
|
242 |
</li>
|
243 |
<li class="card-panel grey darken-1">
|
244 |
+
<?php echo __('PHP open_basedir', 'xcloner-backup-and-restore') ?>
|
245 |
: <?php echo $requirements->get_open_basedir(); ?>
|
246 |
</li>
|
247 |
<?php
|
248 |
$data = array();
|
249 |
+
if ($requirements->check_backup_ready_status()) {
|
250 |
$data = $xcloner_file_system->estimate_read_write_time();
|
251 |
}
|
252 |
?>
|
253 |
<li class="card-panel grey darken-1">
|
254 |
+
<?php echo __('Reading Time 1MB Block', 'xcloner-backup-and-restore') ?>
|
255 |
+
: <?php echo(isset($data['reading_time']) ? $data['reading_time'] : __("unknown")); ?>
|
256 |
</li>
|
257 |
<li class="card-panel grey darken-1">
|
258 |
+
<?php echo __('Writing Time 1MB Block', 'xcloner-backup-and-restore') ?>
|
259 |
+
: <?php echo(isset($data['writing_time']) ? $data['writing_time'] : __("unknown")); ?>
|
260 |
</li>
|
261 |
<li class="card-panel grey darken-1">
|
262 |
+
<?php echo __('Free Disk Space', 'xcloner-backup-and-restore') ?>
|
263 |
+
: <?php echo $requirements->get_free_disk_space(); ; ?>
|
264 |
</li>
|
265 |
</ul>
|
266 |
</div>
|
267 |
<div class="card-action">
|
268 |
+
<a class="waves-effect waves-light btn system_info_toggle blue darken-1"><i class="material-icons left">list</i><?php echo __('Toggle Additional System Info', 'xcloner-backup-and-restore') ?>
|
269 |
</a>
|
270 |
</div>
|
271 |
</div>
|
admin/partials/xcloner_manage_backups_page.php
CHANGED
@@ -3,19 +3,23 @@
|
|
3 |
$xcloner_file_system = $this->get_xcloner_container()->get_xcloner_filesystem();
|
4 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
5 |
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
|
|
6 |
$storage_selection = "";
|
7 |
|
8 |
if (isset($_GET['storage_selection']) and $_GET['storage_selection']) {
|
9 |
-
|
10 |
}
|
11 |
|
12 |
-
|
13 |
|
14 |
$available_storages = $xcloner_remote_storage->get_available_storages();
|
15 |
|
16 |
-
|
17 |
?>
|
18 |
|
|
|
|
|
|
|
|
|
19 |
<div class="row">
|
20 |
<div class="col s12 m6 l9">
|
21 |
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
@@ -34,13 +38,13 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
34 |
|
35 |
<?php foreach ($available_storages as $storage => $text): ?>
|
36 |
<option value="<?php echo $storage ?>"<?php if ($storage == $storage_selection)
|
37 |
-
|
38 |
<?php endforeach ?>
|
39 |
</select>
|
40 |
<?php endif ?>
|
41 |
</div>
|
42 |
|
43 |
-
<table id="manage_backups">
|
44 |
<thead>
|
45 |
<tr class="grey lighten-2">
|
46 |
<th class="no-sort">
|
@@ -61,7 +65,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
61 |
|
62 |
|
63 |
<?php
|
64 |
-
|
65 |
foreach ($backup_list as $file_info):?>
|
66 |
<?php
|
67 |
if ($storage_selection == "gdrive") {
|
@@ -125,6 +129,19 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
125 |
title="<?php echo __('List Backup Content',
|
126 |
'xcloner-backup-and-restore') ?>"><i
|
127 |
class="material-icons">folder_open</i></a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
<?php elseif ($storage_selection != "gdrive" && !$xcloner_file_system->get_storage_filesystem()->has($child[0])): ?>
|
129 |
<a href="#<?php echo $child[0] ?>" class="copy-remote-to-local"
|
130 |
title="<?php echo __('Push Backup To Local Storage',
|
@@ -156,9 +173,22 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
156 |
class="material-icons">folder_open</i></a>
|
157 |
<?php endif; ?>
|
158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
<a href="#<?php echo $file_info['basename'] ?>" class="delete"
|
160 |
-
title="<?php echo __('Delete Backup', 'xcloner-backup-and-restore') ?>"
|
161 |
-
|
|
|
162 |
<?php if ($storage_selection and !$file_exists_on_local_storage): ?>
|
163 |
<a href="#<?php echo $file_info['basename']; ?>" class="copy-remote-to-local"
|
164 |
title="<?php echo __('Push Backup To Local Storage', 'xcloner-backup-and-restore') ?>"><i
|
@@ -170,7 +200,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
170 |
</tr>
|
171 |
|
172 |
<?php endif ?>
|
173 |
-
<?php endforeach
|
174 |
|
175 |
</tbody>
|
176 |
</table>
|
@@ -191,6 +221,58 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
191 |
</div>
|
192 |
</div>
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
<!-- Local Transfer Modal-->
|
195 |
<div id="local_storage_upload_modal" class="modal">
|
196 |
<div class="modal-content">
|
@@ -220,7 +302,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
220 |
<div class="row">
|
221 |
<div class="col s12 label">
|
222 |
<label><?php echo sprintf(__('Send %s to remote storage', 'xcloner-backup-and-restore'),
|
223 |
-
|
224 |
</div>
|
225 |
<div class="input-field col s8 m10">
|
226 |
<select name="transfer_storage" id="transfer_storage" class="validate" required>
|
3 |
$xcloner_file_system = $this->get_xcloner_container()->get_xcloner_filesystem();
|
4 |
$xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
5 |
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
6 |
+
$xcloner_encryption = $this->get_xcloner_container()->get_xcloner_encryption();
|
7 |
$storage_selection = "";
|
8 |
|
9 |
if (isset($_GET['storage_selection']) and $_GET['storage_selection']) {
|
10 |
+
$storage_selection = $xcloner_sanitization->sanitize_input_as_string($_GET['storage_selection']);
|
11 |
}
|
12 |
|
13 |
+
//$backup_list = $xcloner_file_system->get_backup_archives_list($storage_selection);
|
14 |
|
15 |
$available_storages = $xcloner_remote_storage->get_available_storages();
|
16 |
|
|
|
17 |
?>
|
18 |
|
19 |
+
<script>
|
20 |
+
var storage_selection = '<?=$storage_selection?>';
|
21 |
+
</script>
|
22 |
+
|
23 |
<div class="row">
|
24 |
<div class="col s12 m6 l9">
|
25 |
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
38 |
|
39 |
<?php foreach ($available_storages as $storage => $text): ?>
|
40 |
<option value="<?php echo $storage ?>"<?php if ($storage == $storage_selection)
|
41 |
+
echo "selected" ?>><?php echo $text ?></option>
|
42 |
<?php endforeach ?>
|
43 |
</select>
|
44 |
<?php endif ?>
|
45 |
</div>
|
46 |
|
47 |
+
<table id="manage_backups" style="width:100%">
|
48 |
<thead>
|
49 |
<tr class="grey lighten-2">
|
50 |
<th class="no-sort">
|
65 |
|
66 |
|
67 |
<?php
|
68 |
+
/*$i = 0;
|
69 |
foreach ($backup_list as $file_info):?>
|
70 |
<?php
|
71 |
if ($storage_selection == "gdrive") {
|
129 |
title="<?php echo __('List Backup Content',
|
130 |
'xcloner-backup-and-restore') ?>"><i
|
131 |
class="material-icons">folder_open</i></a>
|
132 |
+
|
133 |
+
<?php if($xcloner_encryption->is_encrypted_file($child[0])) :?>
|
134 |
+
<a href="#<?php echo $child[0] ?>" class="backup-decryption"
|
135 |
+
title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
|
136 |
+
<i class="material-icons">enhanced_encryption</i>
|
137 |
+
</a>
|
138 |
+
<?php else: ?>
|
139 |
+
<a href="#<?php echo $child[0] ?>" class="backup-encryption"
|
140 |
+
title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
|
141 |
+
<i class="material-icons">no_encryption</i>
|
142 |
+
</a>
|
143 |
+
<?php endif?>
|
144 |
+
|
145 |
<?php elseif ($storage_selection != "gdrive" && !$xcloner_file_system->get_storage_filesystem()->has($child[0])): ?>
|
146 |
<a href="#<?php echo $child[0] ?>" class="copy-remote-to-local"
|
147 |
title="<?php echo __('Push Backup To Local Storage',
|
173 |
class="material-icons">folder_open</i></a>
|
174 |
<?php endif; ?>
|
175 |
|
176 |
+
<?php if($xcloner_encryption->is_encrypted_file($file_info['basename'])) :?>
|
177 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="backup-decryption"
|
178 |
+
title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
|
179 |
+
<i class="material-icons">enhanced_encryption</i>
|
180 |
+
</a>
|
181 |
+
<?php else: ?>
|
182 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="backup-encryption"
|
183 |
+
title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
|
184 |
+
<i class="material-icons">no_encryption</i>
|
185 |
+
</a>
|
186 |
+
<?php endif?>
|
187 |
+
|
188 |
<a href="#<?php echo $file_info['basename'] ?>" class="delete"
|
189 |
+
title="<?php echo __('Delete Backup', 'xcloner-backup-and-restore') ?>">
|
190 |
+
<i class="material-icons">delete</i>
|
191 |
+
</a>
|
192 |
<?php if ($storage_selection and !$file_exists_on_local_storage): ?>
|
193 |
<a href="#<?php echo $file_info['basename']; ?>" class="copy-remote-to-local"
|
194 |
title="<?php echo __('Push Backup To Local Storage', 'xcloner-backup-and-restore') ?>"><i
|
200 |
</tr>
|
201 |
|
202 |
<?php endif ?>
|
203 |
+
<?php endforeach */?>
|
204 |
|
205 |
</tbody>
|
206 |
</table>
|
221 |
</div>
|
222 |
</div>
|
223 |
|
224 |
+
<!-- Backup Encryption Modal-->
|
225 |
+
<div id="backup_encryption_modal" class="modal">
|
226 |
+
<div class="modal-content">
|
227 |
+
<h4><?php echo sprintf(__("Backup Content Encryption", 'xcloner-backup-and-restore'), "") ?></h4>
|
228 |
+
<h5 class="backup-name"></h5>
|
229 |
+
|
230 |
+
<div class="progress">
|
231 |
+
<div class="determinate"></div>
|
232 |
+
</div>
|
233 |
+
<div class="notice">
|
234 |
+
<p>
|
235 |
+
<?php echo __("This option will encrypt your backup archive with your current XCloner Encryption Key.", 'xcloner-backup-and-restore') ?>
|
236 |
+
</p>
|
237 |
+
<p class="center-align">
|
238 |
+
<a class="waves-effect waves-light btn"><?php echo __("START ENCRYPTION", 'xcloner-backup-and-restore') ?></a>
|
239 |
+
</p>
|
240 |
+
</div>
|
241 |
+
<ul class="files-list">
|
242 |
+
</ul>
|
243 |
+
</div>
|
244 |
+
</div>
|
245 |
+
|
246 |
+
<!-- Backup Decryption Modal-->
|
247 |
+
<div id="backup_decryption_modal" class="modal">
|
248 |
+
<div class="modal-content">
|
249 |
+
<h4><?php echo sprintf(__("Backup Content Decryption", 'xcloner-backup-and-restore'), "") ?></h4>
|
250 |
+
<h5 class="backup-name"></h5>
|
251 |
+
|
252 |
+
<div class="progress">
|
253 |
+
<div class="determinate"></div>
|
254 |
+
</div>
|
255 |
+
<div class="notice">
|
256 |
+
<p>
|
257 |
+
<?php echo __("This option will decrypt your backup archive with your current XCloner Encryption Key or the key provided below, requires PHP openssl library installed.", 'xcloner-backup-and-restore') ?>
|
258 |
+
</p>
|
259 |
+
<p>
|
260 |
+
<?=__('Provide Alternative Decryption Key:')?>
|
261 |
+
<input type="text"
|
262 |
+
name="decryption_key"
|
263 |
+
id="decryption_key"
|
264 |
+
placeholder="<?=__('Decryption Key', 'xcloner-backup-and-restore')?>" />
|
265 |
+
</p>
|
266 |
+
<p class="center-align">
|
267 |
+
<a class="waves-effect waves-light btn"><?php echo __("START DECRYPTION", 'xcloner-backup-and-restore') ?></a>
|
268 |
+
</p>
|
269 |
+
</div>
|
270 |
+
<ul class="files-list">
|
271 |
+
|
272 |
+
</ul>
|
273 |
+
</div>
|
274 |
+
</div>
|
275 |
+
|
276 |
<!-- Local Transfer Modal-->
|
277 |
<div id="local_storage_upload_modal" class="modal">
|
278 |
<div class="modal-content">
|
302 |
<div class="row">
|
303 |
<div class="col s12 label">
|
304 |
<label><?php echo sprintf(__('Send %s to remote storage', 'xcloner-backup-and-restore'),
|
305 |
+
"<span class='backup_name'></span>") ?></label>
|
306 |
</div>
|
307 |
<div class="input-field col s8 m10">
|
308 |
<select name="transfer_storage" id="transfer_storage" class="validate" required>
|
admin/partials/xcloner_remote_storage_page.php
CHANGED
@@ -3,13 +3,13 @@ $remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
|
3 |
|
4 |
$gdrive_auth_url = "";
|
5 |
|
6 |
-
if (
|
7 |
$gdrive_auth_url = $remote_storage->get_gdrive_auth_url();
|
8 |
}
|
9 |
|
10 |
$gdrive_construct = $remote_storage->gdrive_construct();
|
11 |
?>
|
12 |
-
<h1><?= esc_html(
|
13 |
|
14 |
<form class="remote-storage-form" method="POST">
|
15 |
|
@@ -21,12 +21,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
21 |
<!-- FTP STORAGE-->
|
22 |
<li id="ftp">
|
23 |
<div class="collapsible-header">
|
24 |
-
<i class="material-icons">computer</i><?php echo __(
|
25 |
<div class="switch right">
|
26 |
<label>
|
27 |
Off
|
28 |
<input type="checkbox" name="xcloner_ftp_enable" class="status"
|
29 |
-
value="1" <?php if (
|
30 |
echo "checked" ?> \>
|
31 |
<span class="lever"></span>
|
32 |
On
|
@@ -36,121 +36,121 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
36 |
<div class="collapsible-body">
|
37 |
<div class="row">
|
38 |
<div class="col s12 m3 label">
|
39 |
-
<label for="ftp_host"><?php echo __(
|
40 |
</div>
|
41 |
<div class="col s12 m6">
|
42 |
-
<input placeholder="<?php echo __(
|
43 |
id="ftp_host" type="text" name="xcloner_ftp_hostname" class="validate"
|
44 |
-
value="<?php echo get_option(
|
45 |
</div>
|
46 |
<div class=" col s12 m2">
|
47 |
-
<input placeholder="<?php echo __(
|
48 |
id="ftp_port" type="text" name="xcloner_ftp_port" class="validate"
|
49 |
-
value="<?php echo get_option(
|
50 |
</div>
|
51 |
</div>
|
52 |
|
53 |
<div class="row">
|
54 |
<div class="col s12 m3 label">
|
55 |
-
<label for="ftp_username"><?php echo __(
|
56 |
</div>
|
57 |
<div class=" col s12 m6">
|
58 |
-
<input placeholder="<?php echo __(
|
59 |
id="ftp_username" type="text" name="xcloner_ftp_username" class="validate"
|
60 |
-
value="<?php echo get_option(
|
61 |
</div>
|
62 |
</div>
|
63 |
|
64 |
|
65 |
<div class="row">
|
66 |
<div class="col s12 m3 label">
|
67 |
-
<label for="ftp_password"><?php echo __(
|
68 |
</div>
|
69 |
<div class=" col s12 m6">
|
70 |
-
<input placeholder="<?php echo __(
|
71 |
id="ftp_password" type="password" name="xcloner_ftp_password" class="validate"
|
72 |
-
value="<?php echo get_option(
|
73 |
</div>
|
74 |
</div>
|
75 |
|
76 |
<div class="row">
|
77 |
<div class="col s12 m3 label">
|
78 |
-
<label for="ftp_root"><?php echo __(
|
79 |
</div>
|
80 |
<div class=" col s12 m6">
|
81 |
-
<input placeholder="<?php echo __(
|
82 |
id="ftp_root" type="text" name="xcloner_ftp_path" class="validate"
|
83 |
-
value="<?php echo get_option(
|
84 |
</div>
|
85 |
</div>
|
86 |
|
87 |
<div class="row">
|
88 |
<div class="col s12 m3 label">
|
89 |
-
<label for="ftp_root"><?php echo __(
|
90 |
</div>
|
91 |
<div class=" col s12 m6 input-field inline">
|
92 |
<input name="xcloner_ftp_transfer_mode" type="radio" id="passive"
|
93 |
-
value="1" <?php if (
|
94 |
echo "checked" ?> />
|
95 |
-
<label for="passive"><?php echo __(
|
96 |
|
97 |
<input name="xcloner_ftp_transfer_mode" type="radio" id="active"
|
98 |
-
value="0" <?php if (
|
99 |
echo "checked" ?> />
|
100 |
-
<label for="active"><?php echo __(
|
101 |
</div>
|
102 |
</div>
|
103 |
|
104 |
<div class="row">
|
105 |
<div class="col s12 m3 label">
|
106 |
-
<label for="ftp_ssl_mode"><?php echo __(
|
107 |
</div>
|
108 |
<div class=" col s12 m6 input-field inline">
|
109 |
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_inactive"
|
110 |
-
value="0" <?php if (
|
111 |
echo "checked" ?> />
|
112 |
-
<label for="ftp_ssl_mode_inactive"><?php echo __(
|
113 |
|
114 |
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_active"
|
115 |
-
value="1" <?php if (
|
116 |
echo "checked" ?> />
|
117 |
-
<label for="ftp_ssl_mode_active"><?php echo __(
|
118 |
</div>
|
119 |
</div>
|
120 |
|
121 |
<div class="row">
|
122 |
<div class="col s12 m3 label">
|
123 |
-
<label for="ftp_timeout"><?php echo __(
|
124 |
</div>
|
125 |
<div class=" col s12 m2">
|
126 |
-
<input placeholder="<?php echo __(
|
127 |
id="ftp_timeout" type="text" name="xcloner_ftp_timeout" class="validate"
|
128 |
-
value="<?php echo get_option(
|
129 |
</div>
|
130 |
</div>
|
131 |
|
132 |
<div class="row">
|
133 |
<div class="col s12 m3 label">
|
134 |
-
<label for="ftp_cleanup_days"><?php echo __(
|
135 |
</div>
|
136 |
<div class=" col s12 m6">
|
137 |
-
<input placeholder="<?php echo __(
|
138 |
id="ftp_cleanup_days" type="text" name="xcloner_ftp_cleanup_days"
|
139 |
-
class="validate" value="<?php echo get_option(
|
140 |
</div>
|
141 |
</div>
|
142 |
|
143 |
<div class="row">
|
144 |
<div class="col s6 m4">
|
145 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
146 |
-
value="ftp"><?php echo __(
|
147 |
<i class="material-icons right">save</i>
|
148 |
</button>
|
149 |
</div>
|
150 |
<div class="col s6 m4">
|
151 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
152 |
id="action" value="ftp"
|
153 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
154 |
<i class="material-icons right">import_export</i>
|
155 |
</button>
|
156 |
</div>
|
@@ -161,12 +161,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
161 |
<!-- SFTP STORAGE-->
|
162 |
<li id="sftp">
|
163 |
<div class="collapsible-header">
|
164 |
-
<i class="material-icons">computer</i><?php echo __(
|
165 |
<div class="switch right">
|
166 |
<label>
|
167 |
Off
|
168 |
<input type="checkbox" name="xcloner_sftp_enable" class="status"
|
169 |
-
value="1" <?php if (
|
170 |
echo "checked" ?> \>
|
171 |
<span class="lever"></span>
|
172 |
On
|
@@ -176,100 +176,100 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
176 |
<div class="collapsible-body">
|
177 |
<div class="row">
|
178 |
<div class="col s12 m3 label">
|
179 |
-
<label for="sftp_host"><?php echo __(
|
180 |
</div>
|
181 |
<div class="col s12 m6">
|
182 |
-
<input placeholder="<?php echo __(
|
183 |
id="sftp_host" type="text" name="xcloner_sftp_hostname" class="validate"
|
184 |
-
value="<?php echo get_option(
|
185 |
</div>
|
186 |
<div class=" col s12 m2">
|
187 |
-
<input placeholder="<?php echo __(
|
188 |
id="sftp_port" type="text" name="xcloner_sftp_port" class="validate"
|
189 |
-
value="<?php echo get_option(
|
190 |
</div>
|
191 |
</div>
|
192 |
|
193 |
<div class="row">
|
194 |
<div class="col s12 m3 label">
|
195 |
-
<label for="sftp_username"><?php echo __(
|
196 |
</div>
|
197 |
<div class=" col s12 m6">
|
198 |
-
<input placeholder="<?php echo __(
|
199 |
id="sftp_username" type="text" name="xcloner_sftp_username" class="validate"
|
200 |
-
value="<?php echo get_option(
|
201 |
</div>
|
202 |
</div>
|
203 |
|
204 |
|
205 |
<div class="row">
|
206 |
<div class="col s12 m3 label">
|
207 |
-
<label for="sftp_password"><?php echo __(
|
208 |
</div>
|
209 |
<div class=" col s12 m6">
|
210 |
-
<input placeholder="<?php echo __(
|
211 |
id="ftp_spassword" type="password" name="xcloner_sftp_password" class="validate"
|
212 |
-
value="<?php echo get_option(
|
213 |
</div>
|
214 |
</div>
|
215 |
|
216 |
<div class="row">
|
217 |
<div class="col s12 m3 label">
|
218 |
-
<label for="sftp_private_key"><?php echo __(
|
219 |
</div>
|
220 |
<div class=" col s12 m6">
|
221 |
<textarea rows="5"
|
222 |
-
placeholder="<?php echo __(
|
223 |
id="sftp_private_key" type="text" name="xcloner_sftp_private_key"
|
224 |
class="validate"
|
225 |
-
value=""><?php echo get_option(
|
226 |
</div>
|
227 |
</div>
|
228 |
|
229 |
<div class="row">
|
230 |
<div class="col s12 m3 label">
|
231 |
-
<label for="sftp_root"><?php echo __(
|
232 |
</div>
|
233 |
<div class=" col s12 m6">
|
234 |
-
<input placeholder="<?php echo __(
|
235 |
id="sftp_root" type="text" name="xcloner_sftp_path" class="validate"
|
236 |
-
value="<?php echo get_option(
|
237 |
</div>
|
238 |
</div>
|
239 |
|
240 |
<div class="row">
|
241 |
<div class="col s12 m3 label">
|
242 |
-
<label for="sftp_timeout"><?php echo __(
|
243 |
</div>
|
244 |
<div class=" col s12 m2">
|
245 |
-
<input placeholder="<?php echo __(
|
246 |
id="sftp_timeout" type="text" name="xcloner_sftp_timeout" class="validate"
|
247 |
-
value="<?php echo get_option(
|
248 |
</div>
|
249 |
</div>
|
250 |
|
251 |
<div class="row">
|
252 |
<div class="col s12 m3 label">
|
253 |
-
<label for="sftp_cleanup_days"><?php echo __(
|
254 |
</div>
|
255 |
<div class=" col s12 m6">
|
256 |
-
<input placeholder="<?php echo __(
|
257 |
id="sftp_cleanup_days" type="text" name="xcloner_sftp_cleanup_days"
|
258 |
-
class="validate" value="<?php echo get_option(
|
259 |
</div>
|
260 |
</div>
|
261 |
|
262 |
<div class="row">
|
263 |
<div class="col s6 m4">
|
264 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
265 |
-
value="sftp"><?php echo __(
|
266 |
<i class="material-icons right">save</i>
|
267 |
</button>
|
268 |
</div>
|
269 |
<div class="col s6 m4">
|
270 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
271 |
id="action" value="sftp"
|
272 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
273 |
<i class="material-icons right">import_export</i>
|
274 |
</button>
|
275 |
</div>
|
@@ -281,12 +281,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
281 |
<!-- AWS STORAGE-->
|
282 |
<li id="aws">
|
283 |
<div class="collapsible-header">
|
284 |
-
<i class="material-icons">computer</i><?php echo __(
|
285 |
<div class="switch right">
|
286 |
<label>
|
287 |
Off
|
288 |
<input type="checkbox" name="xcloner_aws_enable" class="status"
|
289 |
-
value="1" <?php if (
|
290 |
echo "checked" ?> \>
|
291 |
<span class="lever"></span>
|
292 |
On
|
@@ -301,49 +301,49 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
301 |
</div>
|
302 |
<div class=" col s12 m6">
|
303 |
<p>
|
304 |
-
<?php echo sprintf(
|
305 |
</p>
|
306 |
</div>
|
307 |
</div>
|
308 |
|
309 |
<div class="row">
|
310 |
<div class="col s12 m3 label">
|
311 |
-
<label for="aws_key"><?php echo __(
|
312 |
</div>
|
313 |
<div class=" col s12 m6">
|
314 |
-
<input placeholder="<?php echo __(
|
315 |
id="aws_key" type="text" name="xcloner_aws_key" class="validate"
|
316 |
-
value="<?php echo get_option(
|
317 |
</div>
|
318 |
</div>
|
319 |
|
320 |
<div class="row">
|
321 |
<div class="col s12 m3 label">
|
322 |
-
<label for="aws_secret"><?php echo __(
|
323 |
</div>
|
324 |
<div class=" col s12 m6">
|
325 |
-
<input placeholder="<?php echo __(
|
326 |
id="aws_secret" type="text" name="xcloner_aws_secret" class="validate"
|
327 |
-
value="<?php echo get_option(
|
328 |
</div>
|
329 |
</div>
|
330 |
|
331 |
<div class="row">
|
332 |
<div class="col s12 m3 label">
|
333 |
-
<label for="aws_region"><?php echo __(
|
334 |
</div>
|
335 |
<div class=" col s12 m6">
|
336 |
-
<select placeholder="<?php echo __(
|
337 |
id="aws_region" type="text" name="xcloner_aws_region" class="validate"
|
338 |
-
value="<?php echo get_option(
|
339 |
<option readonly
|
340 |
-
value=""><?php echo __(
|
341 |
<?php
|
342 |
$aws_regions = $remote_storage->get_aws_regions();
|
343 |
|
344 |
-
foreach (
|
345 |
?>
|
346 |
-
<option value="<?php echo $key ?>" <?php echo(
|
347 |
= <?php echo $key ?></option>
|
348 |
<?php
|
349 |
}
|
@@ -354,59 +354,59 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
354 |
|
355 |
<div class="row">
|
356 |
<div class="col s12 m3 label">
|
357 |
-
<label for="aws_endpoint"><?php echo __(
|
358 |
</div>
|
359 |
<div class=" col s12 m6">
|
360 |
-
<input placeholder="<?php echo __(
|
361 |
id="aws_endpoint" type="text" name="xcloner_aws_endpoint" class="validate"
|
362 |
-
value="<?php echo get_option(
|
363 |
</div>
|
364 |
</div>
|
365 |
|
366 |
<div class="row">
|
367 |
<div class="col s12 m3 label">
|
368 |
-
<label for="aws_bucket_name"><?php echo __(
|
369 |
</div>
|
370 |
<div class=" col s12 m6">
|
371 |
-
<input placeholder="<?php echo __(
|
372 |
id="aws_bucket_name" type="text" name="xcloner_aws_bucket_name" class="validate"
|
373 |
-
value="<?php echo get_option(
|
374 |
</div>
|
375 |
</div>
|
376 |
|
377 |
<div class="row">
|
378 |
<div class="col s12 m3 label">
|
379 |
-
<label for="aws_prefix"><?php echo __(
|
380 |
</div>
|
381 |
<div class=" col s12 m6">
|
382 |
-
<input placeholder="<?php echo __(
|
383 |
id="aws_prefix" type="text" name="xcloner_aws_prefix" class="validate"
|
384 |
-
value="<?php echo get_option(
|
385 |
</div>
|
386 |
</div>
|
387 |
|
388 |
<div class="row">
|
389 |
<div class="col s12 m3 label">
|
390 |
-
<label for="aws_cleanup_days"><?php echo __(
|
391 |
</div>
|
392 |
<div class=" col s12 m6">
|
393 |
-
<input placeholder="<?php echo __(
|
394 |
id="aws_cleanup_days" type="text" name="xcloner_aws_cleanup_days"
|
395 |
-
class="validate" value="<?php echo get_option(
|
396 |
</div>
|
397 |
</div>
|
398 |
|
399 |
<div class="row">
|
400 |
<div class="col s6 m4">
|
401 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
402 |
-
value="aws"><?php echo __(
|
403 |
<i class="material-icons right">save</i>
|
404 |
</button>
|
405 |
</div>
|
406 |
<div class="col s6 m4">
|
407 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
408 |
id="action" value="aws"
|
409 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
410 |
<i class="material-icons right">import_export</i>
|
411 |
</button>
|
412 |
</div>
|
@@ -418,12 +418,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
418 |
<!-- DROPBOX STORAGE-->
|
419 |
<li id="dropbox">
|
420 |
<div class="collapsible-header">
|
421 |
-
<i class="material-icons">computer</i><?php echo __(
|
422 |
<div class="switch right">
|
423 |
<label>
|
424 |
Off
|
425 |
<input type="checkbox" name="xcloner_dropbox_enable" class="status"
|
426 |
-
value="1" <?php if (
|
427 |
echo "checked" ?> \>
|
428 |
<span class="lever"></span>
|
429 |
On
|
@@ -438,20 +438,20 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
438 |
</div>
|
439 |
<div class=" col s12 m6">
|
440 |
<p>
|
441 |
-
<?php echo sprintf(
|
442 |
</p>
|
443 |
</div>
|
444 |
</div>
|
445 |
|
446 |
<div class="row">
|
447 |
<div class="col s12 m3 label">
|
448 |
-
<label for="dropbox_access_token"><?php echo __(
|
449 |
</div>
|
450 |
<div class=" col s12 m6">
|
451 |
-
<input placeholder="<?php echo __(
|
452 |
id="dropbox_access_token" type="text" name="xcloner_dropbox_access_token"
|
453 |
class="validate"
|
454 |
-
value="<?php echo get_option(
|
455 |
autocomplete="off">
|
456 |
</div>
|
457 |
</div>
|
@@ -459,50 +459,50 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
459 |
|
460 |
<div class="row">
|
461 |
<div class="col s12 m3 label">
|
462 |
-
<label for="dropbox_app_secret"><?php echo __(
|
463 |
</div>
|
464 |
<div class=" col s12 m6">
|
465 |
-
<input placeholder="<?php echo __(
|
466 |
id="dropbox_app_secret" type="text" name="xcloner_dropbox_app_secret"
|
467 |
-
class="validate" value="<?php echo get_option(
|
468 |
autocomplete="off">
|
469 |
</div>
|
470 |
</div>
|
471 |
|
472 |
<div class="row">
|
473 |
<div class="col s12 m3 label">
|
474 |
-
<label for="dropbox_prefix"><?php echo __(
|
475 |
</div>
|
476 |
<div class=" col s12 m6">
|
477 |
-
<input placeholder="<?php echo __(
|
478 |
id="dropbox_prefix" type="text" name="xcloner_dropbox_prefix" class="validate"
|
479 |
-
value="<?php echo get_option(
|
480 |
</div>
|
481 |
</div>
|
482 |
|
483 |
<div class="row">
|
484 |
<div class="col s12 m3 label">
|
485 |
-
<label for="dropbox_cleanup_days"><?php echo __(
|
486 |
</div>
|
487 |
<div class=" col s12 m6">
|
488 |
-
<input placeholder="<?php echo __(
|
489 |
id="dropbox_cleanup_days" type="text" name="xcloner_dropbox_cleanup_days"
|
490 |
class="validate"
|
491 |
-
value="<?php echo get_option(
|
492 |
</div>
|
493 |
</div>
|
494 |
|
495 |
<div class="row">
|
496 |
<div class="col s6 m4">
|
497 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
498 |
-
value="dropbox"><?php echo __(
|
499 |
<i class="material-icons right">save</i>
|
500 |
</button>
|
501 |
</div>
|
502 |
<div class="col s6 m4">
|
503 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
504 |
id="action" value="dropbox"
|
505 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
506 |
<i class="material-icons right">import_export</i>
|
507 |
</button>
|
508 |
</div>
|
@@ -514,12 +514,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
514 |
<!-- AZURE STORAGE-->
|
515 |
<li id="azure">
|
516 |
<div class="collapsible-header">
|
517 |
-
<i class="material-icons">computer</i><?php echo __(
|
518 |
<div class="switch right">
|
519 |
<label>
|
520 |
Off
|
521 |
<input type="checkbox" name="xcloner_azure_enable" class="status"
|
522 |
-
value="1" <?php if (
|
523 |
echo "checked" ?> \>
|
524 |
<span class="lever"></span>
|
525 |
On
|
@@ -534,19 +534,19 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
534 |
</div>
|
535 |
<div class=" col s12 m6">
|
536 |
<p>
|
537 |
-
<?php echo sprintf(
|
538 |
</p>
|
539 |
</div>
|
540 |
</div>
|
541 |
|
542 |
<div class="row">
|
543 |
<div class="col s12 m3 label">
|
544 |
-
<label for="azure_account_name"><?php echo __(
|
545 |
</div>
|
546 |
<div class=" col s12 m6">
|
547 |
-
<input placeholder="<?php echo __(
|
548 |
id="azure_account_name" type="text" name="xcloner_azure_account_name"
|
549 |
-
class="validate" value="<?php echo get_option(
|
550 |
autocomplete="off">
|
551 |
</div>
|
552 |
</div>
|
@@ -554,49 +554,49 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
554 |
|
555 |
<div class="row">
|
556 |
<div class="col s12 m3 label">
|
557 |
-
<label for="azure_api_key"><?php echo __(
|
558 |
</div>
|
559 |
<div class=" col s12 m6">
|
560 |
-
<input placeholder="<?php echo __(
|
561 |
id="azure_api_key" type="text" name="xcloner_azure_api_key" class="validate"
|
562 |
-
value="<?php echo get_option(
|
563 |
</div>
|
564 |
</div>
|
565 |
|
566 |
<div class="row">
|
567 |
<div class="col s12 m3 label">
|
568 |
-
<label for="azure_container"><?php echo __(
|
569 |
</div>
|
570 |
<div class=" col s12 m6">
|
571 |
-
<input placeholder="<?php echo __(
|
572 |
id="azure_container" type="text" name="xcloner_azure_container" class="validate"
|
573 |
-
value="<?php echo get_option(
|
574 |
</div>
|
575 |
</div>
|
576 |
|
577 |
<div class="row">
|
578 |
<div class="col s12 m3 label">
|
579 |
-
<label for="azure_cleanup_days"><?php echo __(
|
580 |
</div>
|
581 |
<div class=" col s12 m6">
|
582 |
-
<input placeholder="<?php echo __(
|
583 |
id="azure_cleanup_days" type="text" name="xcloner_azure_cleanup_days"
|
584 |
class="validate"
|
585 |
-
value="<?php echo get_option(
|
586 |
</div>
|
587 |
</div>
|
588 |
|
589 |
<div class="row">
|
590 |
<div class="col s6 m4">
|
591 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
592 |
-
value="azure"><?php echo __(
|
593 |
<i class="material-icons right">save</i>
|
594 |
</button>
|
595 |
</div>
|
596 |
<div class="col s6 m4">
|
597 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
598 |
id="action" value="azure"
|
599 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
600 |
<i class="material-icons right">import_export</i>
|
601 |
</button>
|
602 |
</div>
|
@@ -608,12 +608,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
608 |
<!-- BACKBLAZE STORAGE-->
|
609 |
<li id="backblaze">
|
610 |
<div class="collapsible-header">
|
611 |
-
<i class="material-icons">computer</i><?php echo __(
|
612 |
<div class="switch right">
|
613 |
<label>
|
614 |
Off
|
615 |
<input type="checkbox" name="xcloner_backblaze_enable" class="status"
|
616 |
-
value="1" <?php if (
|
617 |
echo "checked" ?> \>
|
618 |
<span class="lever"></span>
|
619 |
On
|
@@ -628,20 +628,20 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
628 |
</div>
|
629 |
<div class=" col s12 m6">
|
630 |
<p>
|
631 |
-
<?php echo sprintf(
|
632 |
</p>
|
633 |
</div>
|
634 |
</div>
|
635 |
|
636 |
<div class="row">
|
637 |
<div class="col s12 m3 label">
|
638 |
-
<label for="backblaze_account_id"><?php echo __(
|
639 |
</div>
|
640 |
<div class=" col s12 m6">
|
641 |
-
<input placeholder="<?php echo __(
|
642 |
id="backblaze_account_id" type="text" name="xcloner_backblaze_account_id"
|
643 |
class="validate"
|
644 |
-
value="<?php echo get_option(
|
645 |
autocomplete="off">
|
646 |
</div>
|
647 |
</div>
|
@@ -649,53 +649,53 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
649 |
|
650 |
<div class="row">
|
651 |
<div class="col s12 m3 label">
|
652 |
-
<label for="backblaze_application_key"><?php echo __(
|
653 |
</div>
|
654 |
<div class=" col s12 m6">
|
655 |
-
<input placeholder="<?php echo __(
|
656 |
id="backblaze_application_key" type="text"
|
657 |
name="xcloner_backblaze_application_key" class="validate"
|
658 |
-
value="<?php echo get_option(
|
659 |
autocomplete="off">
|
660 |
</div>
|
661 |
</div>
|
662 |
|
663 |
<div class="row">
|
664 |
<div class="col s12 m3 label">
|
665 |
-
<label for="backblaze_bucket_name"><?php echo __(
|
666 |
</div>
|
667 |
<div class=" col s12 m6">
|
668 |
-
<input placeholder="<?php echo __(
|
669 |
id="backblaze_bucket_name" type="text" name="xcloner_backblaze_bucket_name"
|
670 |
class="validate"
|
671 |
-
value="<?php echo get_option(
|
672 |
autocomplete="off">
|
673 |
</div>
|
674 |
</div>
|
675 |
|
676 |
<div class="row">
|
677 |
<div class="col s12 m3 label">
|
678 |
-
<label for="backblaze_cleanup_days"><?php echo __(
|
679 |
</div>
|
680 |
<div class=" col s12 m6">
|
681 |
-
<input placeholder="<?php echo __(
|
682 |
id="backblaze_cleanup_days" type="text" name="xcloner_backblaze_cleanup_days"
|
683 |
class="validate"
|
684 |
-
value="<?php echo get_option(
|
685 |
</div>
|
686 |
</div>
|
687 |
|
688 |
<div class="row">
|
689 |
<div class="col s6 m4">
|
690 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
691 |
-
value="backblaze"><?php echo __(
|
692 |
<i class="material-icons right">save</i>
|
693 |
</button>
|
694 |
</div>
|
695 |
<div class="col s6 m4">
|
696 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
697 |
id="action" value="backblaze"
|
698 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
699 |
<i class="material-icons right">import_export</i>
|
700 |
</button>
|
701 |
</div>
|
@@ -707,12 +707,12 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
707 |
<!-- WEBDAV STORAGE-->
|
708 |
<li id="webdav">
|
709 |
<div class="collapsible-header">
|
710 |
-
<i class="material-icons">computer</i><?php echo __(
|
711 |
<div class="switch right">
|
712 |
<label>
|
713 |
Off
|
714 |
<input type="checkbox" name="xcloner_webdav_enable" class="status"
|
715 |
-
value="1" <?php if (
|
716 |
echo "checked" ?> \>
|
717 |
<span class="lever"></span>
|
718 |
On
|
@@ -734,74 +734,74 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
734 |
|
735 |
<div class="row">
|
736 |
<div class="col s12 m3 label">
|
737 |
-
<label for="webdav_url"><?php echo __(
|
738 |
</div>
|
739 |
<div class=" col s12 m6">
|
740 |
-
<input placeholder="<?php echo __(
|
741 |
id="webdav_url" type="text" name="xcloner_webdav_url" class="validate"
|
742 |
-
value="<?php echo get_option(
|
743 |
</div>
|
744 |
</div>
|
745 |
|
746 |
<div class="row">
|
747 |
<div class="col s12 m3 label">
|
748 |
-
<label for="webdav_username"><?php echo __(
|
749 |
</div>
|
750 |
<div class=" col s12 m6">
|
751 |
-
<input placeholder="<?php echo __(
|
752 |
id="webdav_username" type="text" name="xcloner_webdav_username" class="validate"
|
753 |
-
value="<?php echo get_option(
|
754 |
</div>
|
755 |
</div>
|
756 |
|
757 |
<div class="row">
|
758 |
<div class="col s12 m3 label">
|
759 |
-
<label for="webdav_password"><?php echo __(
|
760 |
</div>
|
761 |
<div class=" col s12 m6">
|
762 |
-
<input placeholder="<?php echo __(
|
763 |
id="webdav_password" type="password" name="xcloner_webdav_password"
|
764 |
-
class="validate" value="<?php echo get_option(
|
765 |
autocomplete="off">
|
766 |
</div>
|
767 |
</div>
|
768 |
|
769 |
<div class="row">
|
770 |
<div class="col s12 m3 label">
|
771 |
-
<label for="webdav_target_folder"><?php echo __(
|
772 |
</div>
|
773 |
<div class=" col s12 m6">
|
774 |
-
<input placeholder="<?php echo __(
|
775 |
id="webdav_target_folder" type="text" name="xcloner_webdav_target_folder"
|
776 |
class="validate"
|
777 |
-
value="<?php echo get_option(
|
778 |
autocomplete="off">
|
779 |
</div>
|
780 |
</div>
|
781 |
|
782 |
<div class="row">
|
783 |
<div class="col s12 m3 label">
|
784 |
-
<label for="webdav_cleanup_days"><?php echo __(
|
785 |
</div>
|
786 |
<div class=" col s12 m6">
|
787 |
-
<input placeholder="<?php echo __(
|
788 |
id="webdav_cleanup_days" type="text" name="xcloner_webdav_cleanup_days"
|
789 |
class="validate"
|
790 |
-
value="<?php echo get_option(
|
791 |
</div>
|
792 |
</div>
|
793 |
|
794 |
<div class="row">
|
795 |
<div class="col s6 m4">
|
796 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
797 |
-
value="webdav"><?php echo __(
|
798 |
<i class="material-icons right">save</i>
|
799 |
</button>
|
800 |
</div>
|
801 |
<div class="col s6 m4">
|
802 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
803 |
id="action" value="webdav"
|
804 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
805 |
<i class="material-icons right">import_export</i>
|
806 |
</button>
|
807 |
</div>
|
@@ -813,13 +813,13 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
813 |
<!-- Google DRIVE STORAGE-->
|
814 |
<li id="gdrive">
|
815 |
<div class="collapsible-header">
|
816 |
-
<i class="material-icons">computer</i><?php echo __(
|
817 |
-
<?php if (
|
818 |
<div class="switch right">
|
819 |
<label>
|
820 |
Off
|
821 |
<input type="checkbox" name="xcloner_gdrive_enable" class="status"
|
822 |
-
value="1" <?php if (
|
823 |
echo "checked" ?> \>
|
824 |
<span class="lever"></span>
|
825 |
On
|
@@ -829,7 +829,7 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
829 |
</div>
|
830 |
<div class="collapsible-body">
|
831 |
|
832 |
-
<?php if (
|
833 |
|
834 |
<div class="row">
|
835 |
<div class="col s12 m3 label">
|
@@ -837,11 +837,11 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
837 |
</div>
|
838 |
<div class=" col s12 m9">
|
839 |
<p>
|
840 |
-
<?php echo sprintf(
|
841 |
<a href="https://youtu.be/YXUVPUVgG8k" target="_blank"
|
842 |
class="btn-floating tooltipped btn-small" data-position="right"
|
843 |
data-delay="50" data-html="true"
|
844 |
-
data-tooltip="<?php echo sprintf(
|
845 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i
|
846 |
class="material-icons">help_outline</i></a>
|
847 |
</p>
|
@@ -850,25 +850,25 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
850 |
|
851 |
<div class="row">
|
852 |
<div class="col s12 m3 label">
|
853 |
-
<label for="gdrive_client_id"><?php echo __(
|
854 |
</div>
|
855 |
<div class=" col s12 m6">
|
856 |
-
<input placeholder="<?php echo __(
|
857 |
id="gdrive_client_id" type="text" name="xcloner_gdrive_client_id"
|
858 |
class="validate"
|
859 |
-
value="<?php echo get_option(
|
860 |
</div>
|
861 |
</div>
|
862 |
|
863 |
<div class="row">
|
864 |
<div class="col s12 m3 label">
|
865 |
-
<label for="gdrive_client_secret"><?php echo __(
|
866 |
</div>
|
867 |
<div class=" col s12 m6">
|
868 |
-
<input placeholder="<?php echo __(
|
869 |
id="gdrive_client_secret" type="text" name="xcloner_gdrive_client_secret"
|
870 |
class="validate"
|
871 |
-
value="<?php echo get_option(
|
872 |
</div>
|
873 |
</div>
|
874 |
|
@@ -880,72 +880,72 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
880 |
<div class=" col s12 m6">
|
881 |
<a class="btn" target="_blank" id="gdrive_authorization_click"
|
882 |
onclick="jQuery('#authentification_code').show()"
|
883 |
-
href="<?php echo $gdrive_auth_url ?>"><?php echo sprintf(
|
884 |
<input type="text" name="authentification_code" id="authentification_code"
|
885 |
-
placeholder="<?php echo __(
|
886 |
</div>
|
887 |
</div>
|
888 |
|
889 |
<div class="row">
|
890 |
<div class="col s12 m3 label">
|
891 |
-
<label for="gdrive_target_folder"><?php echo __(
|
892 |
<a class="btn-floating tooltipped btn-small" data-position="right"
|
893 |
data-delay="50" data-html="true" \
|
894 |
-
data-tooltip="<?php echo __(
|
895 |
-
If you supply a folder name, it has to exists in the drive root and start with / , example /backups.xcloner.com/', 'xcloner-backup-and-restore'
|
896 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i
|
897 |
class="material-icons">help_outline</i></a>
|
898 |
</label>
|
899 |
</div>
|
900 |
<div class=" col s12 m6">
|
901 |
-
<input placeholder="<?php echo __(
|
902 |
id="gdrive_target_folder" type="text" name="xcloner_gdrive_target_folder"
|
903 |
class="validate"
|
904 |
-
value="<?php echo get_option(
|
905 |
autocomplete="off">
|
906 |
</div>
|
907 |
</div>
|
908 |
|
909 |
<div class="row">
|
910 |
<div class="col s12 m3 label">
|
911 |
-
<label for="gdrive_cleanup_days"><?php echo __(
|
912 |
</div>
|
913 |
<div class=" col s12 m6">
|
914 |
-
<input placeholder="<?php echo __(
|
915 |
id="gdrive_cleanup_days" type="text" name="xcloner_gdrive_cleanup_days"
|
916 |
class="validate"
|
917 |
-
value="<?php echo get_option(
|
918 |
</div>
|
919 |
</div>
|
920 |
|
921 |
<div class="row">
|
922 |
<div class="col s12 m3 label">
|
923 |
-
<label for="gdrive_empty_trash"><?php echo __(
|
924 |
</div>
|
925 |
<div class=" col s12 m6 input-field inline">
|
926 |
<input name="xcloner_gdrive_empty_trash" type="radio" value="0"
|
927 |
-
id="gdrive_empty_trash_off" <?php if (
|
928 |
echo "checked" ?> />
|
929 |
-
<label for="gdrive_empty_trash_off"><?php echo __(
|
930 |
|
931 |
<input name="xcloner_gdrive_empty_trash" type="radio" value="1"
|
932 |
-
id="gdrive_empty_trash_on" <?php if (
|
933 |
echo "checked" ?> />
|
934 |
-
<label for="gdrive_empty_trash_on"><?php echo __(
|
935 |
</div>
|
936 |
</div>
|
937 |
|
938 |
<div class="row">
|
939 |
<div class="col s6 m4">
|
940 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
941 |
-
value="gdrive"><?php echo __(
|
942 |
<i class="material-icons right">save</i>
|
943 |
</button>
|
944 |
</div>
|
945 |
<div class="col s6 m4">
|
946 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
947 |
id="action" value="gdrive"
|
948 |
-
onclick="jQuery('#connection_check').val('1')"><?php echo __(
|
949 |
<i class="material-icons right">import_export</i>
|
950 |
</button>
|
951 |
</div>
|
@@ -956,26 +956,26 @@ $gdrive_construct = $remote_storage->gdrive_construct();
|
|
956 |
<div class=" col s12">
|
957 |
<div class="center">
|
958 |
<?php
|
959 |
-
$url = wp_nonce_url(
|
960 |
?>
|
961 |
-
<h6><?php echo __(
|
962 |
-
<h6><?php echo __(
|
963 |
<br/>
|
964 |
<a class="install-now btn" data-slug="xcloner-google-drive"
|
965 |
href="<?php echo $url; ?>"
|
966 |
aria-label="Install XCloner Google Drive 1.0.0 now"
|
967 |
data-name="XCloner Google Drive 1.0.0">
|
968 |
-
<?php echo sprintf(
|
969 |
</a>
|
970 |
|
971 |
-
<a href="<?php echo admin_url(
|
972 |
class="btn thickbox open-plugin-details-modal"
|
973 |
aria-label="More information about Theme Check 20160523.1"
|
974 |
data-title="Theme Check 20160523.1">
|
975 |
<!--
|
976 |
<a class="btn" href="https://github.com/ovidiul/XCloner-Google-Drive/archive/master.zip">
|
977 |
-->
|
978 |
-
<?php echo sprintf(
|
979 |
</a>
|
980 |
</div>
|
981 |
</div>
|
3 |
|
4 |
$gdrive_auth_url = "";
|
5 |
|
6 |
+
if (method_exists($remote_storage, "get_gdrive_auth_url")) {
|
7 |
$gdrive_auth_url = $remote_storage->get_gdrive_auth_url();
|
8 |
}
|
9 |
|
10 |
$gdrive_construct = $remote_storage->gdrive_construct();
|
11 |
?>
|
12 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
13 |
|
14 |
<form class="remote-storage-form" method="POST">
|
15 |
|
21 |
<!-- FTP STORAGE-->
|
22 |
<li id="ftp">
|
23 |
<div class="collapsible-header">
|
24 |
+
<i class="material-icons">computer</i><?php echo __("FTP Storage", 'xcloner-backup-and-restore') ?>
|
25 |
<div class="switch right">
|
26 |
<label>
|
27 |
Off
|
28 |
<input type="checkbox" name="xcloner_ftp_enable" class="status"
|
29 |
+
value="1" <?php if (get_option("xcloner_ftp_enable"))
|
30 |
echo "checked" ?> \>
|
31 |
<span class="lever"></span>
|
32 |
On
|
36 |
<div class="collapsible-body">
|
37 |
<div class="row">
|
38 |
<div class="col s12 m3 label">
|
39 |
+
<label for="ftp_host"><?php echo __("Ftp Hostname", 'xcloner-backup-and-restore') ?></label>
|
40 |
</div>
|
41 |
<div class="col s12 m6">
|
42 |
+
<input placeholder="<?php echo __("Ftp Hostname", 'xcloner-backup-and-restore') ?>"
|
43 |
id="ftp_host" type="text" name="xcloner_ftp_hostname" class="validate"
|
44 |
+
value="<?php echo get_option("xcloner_ftp_hostname") ?>">
|
45 |
</div>
|
46 |
<div class=" col s12 m2">
|
47 |
+
<input placeholder="<?php echo __("Ftp Port", 'xcloner-backup-and-restore') ?>"
|
48 |
id="ftp_port" type="text" name="xcloner_ftp_port" class="validate"
|
49 |
+
value="<?php echo get_option("xcloner_ftp_port", 21) ?>">
|
50 |
</div>
|
51 |
</div>
|
52 |
|
53 |
<div class="row">
|
54 |
<div class="col s12 m3 label">
|
55 |
+
<label for="ftp_username"><?php echo __("Ftp Username", 'xcloner-backup-and-restore') ?></label>
|
56 |
</div>
|
57 |
<div class=" col s12 m6">
|
58 |
+
<input placeholder="<?php echo __("Ftp Username", 'xcloner-backup-and-restore') ?>"
|
59 |
id="ftp_username" type="text" name="xcloner_ftp_username" class="validate"
|
60 |
+
value="<?php echo get_option("xcloner_ftp_username") ?>" autocomplete="off">
|
61 |
</div>
|
62 |
</div>
|
63 |
|
64 |
|
65 |
<div class="row">
|
66 |
<div class="col s12 m3 label">
|
67 |
+
<label for="ftp_password"><?php echo __("Ftp Password", 'xcloner-backup-and-restore') ?></label>
|
68 |
</div>
|
69 |
<div class=" col s12 m6">
|
70 |
+
<input placeholder="<?php echo __("Ftp Password", 'xcloner-backup-and-restore') ?>"
|
71 |
id="ftp_password" type="password" name="xcloner_ftp_password" class="validate"
|
72 |
+
value="<?php echo get_option("xcloner_ftp_password") ?>" autocomplete="off">
|
73 |
</div>
|
74 |
</div>
|
75 |
|
76 |
<div class="row">
|
77 |
<div class="col s12 m3 label">
|
78 |
+
<label for="ftp_root"><?php echo __("Ftp Storage Folder", 'xcloner-backup-and-restore') ?></label>
|
79 |
</div>
|
80 |
<div class=" col s12 m6">
|
81 |
+
<input placeholder="<?php echo __("Ftp Storage Folder", 'xcloner-backup-and-restore') ?>"
|
82 |
id="ftp_root" type="text" name="xcloner_ftp_path" class="validate"
|
83 |
+
value="<?php echo get_option("xcloner_ftp_path") ?>">
|
84 |
</div>
|
85 |
</div>
|
86 |
|
87 |
<div class="row">
|
88 |
<div class="col s12 m3 label">
|
89 |
+
<label for="ftp_root"><?php echo __("Ftp Transfer Mode", 'xcloner-backup-and-restore') ?></label>
|
90 |
</div>
|
91 |
<div class=" col s12 m6 input-field inline">
|
92 |
<input name="xcloner_ftp_transfer_mode" type="radio" id="passive"
|
93 |
+
value="1" <?php if (get_option("xcloner_ftp_transfer_mode", 1))
|
94 |
echo "checked" ?> />
|
95 |
+
<label for="passive"><?php echo __("Passive", 'xcloner-backup-and-restore') ?></label>
|
96 |
|
97 |
<input name="xcloner_ftp_transfer_mode" type="radio" id="active"
|
98 |
+
value="0" <?php if (!get_option("xcloner_ftp_transfer_mode", 1))
|
99 |
echo "checked" ?> />
|
100 |
+
<label for="active"><?php echo __("Active", 'xcloner-backup-and-restore') ?></label>
|
101 |
</div>
|
102 |
</div>
|
103 |
|
104 |
<div class="row">
|
105 |
<div class="col s12 m3 label">
|
106 |
+
<label for="ftp_ssl_mode"><?php echo __("Ftp Secure Connection", 'xcloner-backup-and-restore') ?></label>
|
107 |
</div>
|
108 |
<div class=" col s12 m6 input-field inline">
|
109 |
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_inactive"
|
110 |
+
value="0" <?php if (!get_option("xcloner_ftp_ssl_mode"))
|
111 |
echo "checked" ?> />
|
112 |
+
<label for="ftp_ssl_mode_inactive"><?php echo __("Disable", 'xcloner-backup-and-restore') ?></label>
|
113 |
|
114 |
<input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_active"
|
115 |
+
value="1" <?php if (get_option("xcloner_ftp_ssl_mode"))
|
116 |
echo "checked" ?> />
|
117 |
+
<label for="ftp_ssl_mode_active"><?php echo __("Enable", 'xcloner-backup-and-restore') ?></label>
|
118 |
</div>
|
119 |
</div>
|
120 |
|
121 |
<div class="row">
|
122 |
<div class="col s12 m3 label">
|
123 |
+
<label for="ftp_timeout"><?php echo __("Ftp Timeout", 'xcloner-backup-and-restore') ?></label>
|
124 |
</div>
|
125 |
<div class=" col s12 m2">
|
126 |
+
<input placeholder="<?php echo __("Ftp Timeout", 'xcloner-backup-and-restore') ?>"
|
127 |
id="ftp_timeout" type="text" name="xcloner_ftp_timeout" class="validate"
|
128 |
+
value="<?php echo get_option("xcloner_ftp_timeout", 30) ?>">
|
129 |
</div>
|
130 |
</div>
|
131 |
|
132 |
<div class="row">
|
133 |
<div class="col s12 m3 label">
|
134 |
+
<label for="ftp_cleanup_days"><?php echo __("Ftp Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
135 |
</div>
|
136 |
<div class=" col s12 m6">
|
137 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
138 |
id="ftp_cleanup_days" type="text" name="xcloner_ftp_cleanup_days"
|
139 |
+
class="validate" value="<?php echo get_option("xcloner_ftp_cleanup_days") ?>">
|
140 |
</div>
|
141 |
</div>
|
142 |
|
143 |
<div class="row">
|
144 |
<div class="col s6 m4">
|
145 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
146 |
+
value="ftp"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
147 |
<i class="material-icons right">save</i>
|
148 |
</button>
|
149 |
</div>
|
150 |
<div class="col s6 m4">
|
151 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
152 |
id="action" value="ftp"
|
153 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
154 |
<i class="material-icons right">import_export</i>
|
155 |
</button>
|
156 |
</div>
|
161 |
<!-- SFTP STORAGE-->
|
162 |
<li id="sftp">
|
163 |
<div class="collapsible-header">
|
164 |
+
<i class="material-icons">computer</i><?php echo __("SFTP Storage", 'xcloner-backup-and-restore') ?>
|
165 |
<div class="switch right">
|
166 |
<label>
|
167 |
Off
|
168 |
<input type="checkbox" name="xcloner_sftp_enable" class="status"
|
169 |
+
value="1" <?php if (get_option("xcloner_sftp_enable"))
|
170 |
echo "checked" ?> \>
|
171 |
<span class="lever"></span>
|
172 |
On
|
176 |
<div class="collapsible-body">
|
177 |
<div class="row">
|
178 |
<div class="col s12 m3 label">
|
179 |
+
<label for="sftp_host"><?php echo __("SFTP Hostname", 'xcloner-backup-and-restore') ?></label>
|
180 |
</div>
|
181 |
<div class="col s12 m6">
|
182 |
+
<input placeholder="<?php echo __("SFTP Hostname", 'xcloner-backup-and-restore') ?>"
|
183 |
id="sftp_host" type="text" name="xcloner_sftp_hostname" class="validate"
|
184 |
+
value="<?php echo get_option("xcloner_sftp_hostname") ?>">
|
185 |
</div>
|
186 |
<div class=" col s12 m2">
|
187 |
+
<input placeholder="<?php echo __("SFTP Port", 'xcloner-backup-and-restore') ?>"
|
188 |
id="sftp_port" type="text" name="xcloner_sftp_port" class="validate"
|
189 |
+
value="<?php echo get_option("xcloner_sftp_port", 22) ?>">
|
190 |
</div>
|
191 |
</div>
|
192 |
|
193 |
<div class="row">
|
194 |
<div class="col s12 m3 label">
|
195 |
+
<label for="sftp_username"><?php echo __("SFTP Username", 'xcloner-backup-and-restore') ?></label>
|
196 |
</div>
|
197 |
<div class=" col s12 m6">
|
198 |
+
<input placeholder="<?php echo __("SFTP Username", 'xcloner-backup-and-restore') ?>"
|
199 |
id="sftp_username" type="text" name="xcloner_sftp_username" class="validate"
|
200 |
+
value="<?php echo get_option("xcloner_sftp_username") ?>" autocomplete="off">
|
201 |
</div>
|
202 |
</div>
|
203 |
|
204 |
|
205 |
<div class="row">
|
206 |
<div class="col s12 m3 label">
|
207 |
+
<label for="sftp_password"><?php echo __("SFTP or Private Key Password", 'xcloner-backup-and-restore') ?></label>
|
208 |
</div>
|
209 |
<div class=" col s12 m6">
|
210 |
+
<input placeholder="<?php echo __("SFTP or Private Key Password", 'xcloner-backup-and-restore') ?>"
|
211 |
id="ftp_spassword" type="password" name="xcloner_sftp_password" class="validate"
|
212 |
+
value="<?php echo get_option("xcloner_sftp_password") ?>" autocomplete="off">
|
213 |
</div>
|
214 |
</div>
|
215 |
|
216 |
<div class="row">
|
217 |
<div class="col s12 m3 label">
|
218 |
+
<label for="sftp_private_key"><?php echo __("SFTP Private Key(RSA)", 'xcloner-backup-and-restore') ?></label>
|
219 |
</div>
|
220 |
<div class=" col s12 m6">
|
221 |
<textarea rows="5"
|
222 |
+
placeholder="<?php echo __("Local Server Path or Contents of the SFTP Private Key RSA File", 'xcloner-backup-and-restore') ?>"
|
223 |
id="sftp_private_key" type="text" name="xcloner_sftp_private_key"
|
224 |
class="validate"
|
225 |
+
value=""><?php echo get_option("xcloner_sftp_private_key") ?></textarea>
|
226 |
</div>
|
227 |
</div>
|
228 |
|
229 |
<div class="row">
|
230 |
<div class="col s12 m3 label">
|
231 |
+
<label for="sftp_root"><?php echo __("SFTP Storage Folder", 'xcloner-backup-and-restore') ?></label>
|
232 |
</div>
|
233 |
<div class=" col s12 m6">
|
234 |
+
<input placeholder="<?php echo __("SFTP Storage Folder", 'xcloner-backup-and-restore') ?>"
|
235 |
id="sftp_root" type="text" name="xcloner_sftp_path" class="validate"
|
236 |
+
value="<?php echo get_option("xcloner_sftp_path") ?>">
|
237 |
</div>
|
238 |
</div>
|
239 |
|
240 |
<div class="row">
|
241 |
<div class="col s12 m3 label">
|
242 |
+
<label for="sftp_timeout"><?php echo __("SFTP Timeout", 'xcloner-backup-and-restore') ?></label>
|
243 |
</div>
|
244 |
<div class=" col s12 m2">
|
245 |
+
<input placeholder="<?php echo __("SFTP Timeout", 'xcloner-backup-and-restore') ?>"
|
246 |
id="sftp_timeout" type="text" name="xcloner_sftp_timeout" class="validate"
|
247 |
+
value="<?php echo get_option("xcloner_sftp_timeout", 30) ?>">
|
248 |
</div>
|
249 |
</div>
|
250 |
|
251 |
<div class="row">
|
252 |
<div class="col s12 m3 label">
|
253 |
+
<label for="sftp_cleanup_days"><?php echo __("SFTP Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
254 |
</div>
|
255 |
<div class=" col s12 m6">
|
256 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
257 |
id="sftp_cleanup_days" type="text" name="xcloner_sftp_cleanup_days"
|
258 |
+
class="validate" value="<?php echo get_option("xcloner_sftp_cleanup_days") ?>">
|
259 |
</div>
|
260 |
</div>
|
261 |
|
262 |
<div class="row">
|
263 |
<div class="col s6 m4">
|
264 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
265 |
+
value="sftp"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
266 |
<i class="material-icons right">save</i>
|
267 |
</button>
|
268 |
</div>
|
269 |
<div class="col s6 m4">
|
270 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
271 |
id="action" value="sftp"
|
272 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
273 |
<i class="material-icons right">import_export</i>
|
274 |
</button>
|
275 |
</div>
|
281 |
<!-- AWS STORAGE-->
|
282 |
<li id="aws">
|
283 |
<div class="collapsible-header">
|
284 |
+
<i class="material-icons">computer</i><?php echo __("S3 Storage", 'xcloner-backup-and-restore') ?>
|
285 |
<div class="switch right">
|
286 |
<label>
|
287 |
Off
|
288 |
<input type="checkbox" name="xcloner_aws_enable" class="status"
|
289 |
+
value="1" <?php if (get_option("xcloner_aws_enable"))
|
290 |
echo "checked" ?> \>
|
291 |
<span class="lever"></span>
|
292 |
On
|
301 |
</div>
|
302 |
<div class=" col s12 m6">
|
303 |
<p>
|
304 |
+
<?php echo sprintf(__('Visit %s and get your "Key" and "Secret <br />Visit %s to install your own S3 like service.'), "<a href='https://aws.amazon.com/s3/' target='_blank'>https://aws.amazon.com/s3/</a>", "<a href='https://minio.io/' target='_blank'>https://minio.io/</a>") ?>
|
305 |
</p>
|
306 |
</div>
|
307 |
</div>
|
308 |
|
309 |
<div class="row">
|
310 |
<div class="col s12 m3 label">
|
311 |
+
<label for="aws_key"><?php echo __("S3 Key", 'xcloner-backup-and-restore') ?></label>
|
312 |
</div>
|
313 |
<div class=" col s12 m6">
|
314 |
+
<input placeholder="<?php echo __("S3 Key", 'xcloner-backup-and-restore') ?>"
|
315 |
id="aws_key" type="text" name="xcloner_aws_key" class="validate"
|
316 |
+
value="<?php echo get_option("xcloner_aws_key") ?>" autocomplete="off">
|
317 |
</div>
|
318 |
</div>
|
319 |
|
320 |
<div class="row">
|
321 |
<div class="col s12 m3 label">
|
322 |
+
<label for="aws_secret"><?php echo __("S3 Secret", 'xcloner-backup-and-restore') ?></label>
|
323 |
</div>
|
324 |
<div class=" col s12 m6">
|
325 |
+
<input placeholder="<?php echo __("S3 Secret", 'xcloner-backup-and-restore') ?>"
|
326 |
id="aws_secret" type="text" name="xcloner_aws_secret" class="validate"
|
327 |
+
value="<?php echo get_option("xcloner_aws_secret") ?>" autocomplete="off">
|
328 |
</div>
|
329 |
</div>
|
330 |
|
331 |
<div class="row">
|
332 |
<div class="col s12 m3 label">
|
333 |
+
<label for="aws_region"><?php echo __("S3 Region", 'xcloner-backup-and-restore') ?></label>
|
334 |
</div>
|
335 |
<div class=" col s12 m6">
|
336 |
+
<select placeholder="<?php echo __("example: us-east-1", 'xcloner-backup-and-restore') ?>"
|
337 |
id="aws_region" type="text" name="xcloner_aws_region" class="validate"
|
338 |
+
value="<?php echo get_option("xcloner_aws_region") ?>" autocomplete="off">
|
339 |
<option readonly
|
340 |
+
value=""><?php echo __("Please Select AWS S3 Region or Leave Unselected for Custom Endpoint") ?></option>
|
341 |
<?php
|
342 |
$aws_regions = $remote_storage->get_aws_regions();
|
343 |
|
344 |
+
foreach ($aws_regions as $key => $region) {
|
345 |
?>
|
346 |
+
<option value="<?php echo $key ?>" <?php echo($key == get_option('xcloner_aws_region') ? "selected" : "") ?>><?php echo $region ?>
|
347 |
= <?php echo $key ?></option>
|
348 |
<?php
|
349 |
}
|
354 |
|
355 |
<div class="row">
|
356 |
<div class="col s12 m3 label">
|
357 |
+
<label for="aws_endpoint"><?php echo __("S3 EndPoint", 'xcloner-backup-and-restore') ?></label>
|
358 |
</div>
|
359 |
<div class=" col s12 m6">
|
360 |
+
<input placeholder="<?php echo __("S3 EndPoint, leave blank if you want to use the default Amazon AWS Service", 'xcloner-backup-and-restore') ?>"
|
361 |
id="aws_endpoint" type="text" name="xcloner_aws_endpoint" class="validate"
|
362 |
+
value="<?php echo get_option("xcloner_aws_endpoint") ?>" autocomplete="off">
|
363 |
</div>
|
364 |
</div>
|
365 |
|
366 |
<div class="row">
|
367 |
<div class="col s12 m3 label">
|
368 |
+
<label for="aws_bucket_name"><?php echo __("S3 Bucket Name", 'xcloner-backup-and-restore') ?></label>
|
369 |
</div>
|
370 |
<div class=" col s12 m6">
|
371 |
+
<input placeholder="<?php echo __("S3 Bucket Name", 'xcloner-backup-and-restore') ?>"
|
372 |
id="aws_bucket_name" type="text" name="xcloner_aws_bucket_name" class="validate"
|
373 |
+
value="<?php echo get_option("xcloner_aws_bucket_name") ?>" autocomplete="off">
|
374 |
</div>
|
375 |
</div>
|
376 |
|
377 |
<div class="row">
|
378 |
<div class="col s12 m3 label">
|
379 |
+
<label for="aws_prefix"><?php echo __("S3 Prefix", 'xcloner-backup-and-restore') ?></label>
|
380 |
</div>
|
381 |
<div class=" col s12 m6">
|
382 |
+
<input placeholder="<?php echo __("S3 Prefix, use / ending to define a folder", 'xcloner-backup-and-restore') ?>"
|
383 |
id="aws_prefix" type="text" name="xcloner_aws_prefix" class="validate"
|
384 |
+
value="<?php echo get_option("xcloner_aws_prefix") ?>" autocomplete="off">
|
385 |
</div>
|
386 |
</div>
|
387 |
|
388 |
<div class="row">
|
389 |
<div class="col s12 m3 label">
|
390 |
+
<label for="aws_cleanup_days"><?php echo __("S3 Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
391 |
</div>
|
392 |
<div class=" col s12 m6">
|
393 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
394 |
id="aws_cleanup_days" type="text" name="xcloner_aws_cleanup_days"
|
395 |
+
class="validate" value="<?php echo get_option("xcloner_aws_cleanup_days") ?>">
|
396 |
</div>
|
397 |
</div>
|
398 |
|
399 |
<div class="row">
|
400 |
<div class="col s6 m4">
|
401 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
402 |
+
value="aws"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
403 |
<i class="material-icons right">save</i>
|
404 |
</button>
|
405 |
</div>
|
406 |
<div class="col s6 m4">
|
407 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
408 |
id="action" value="aws"
|
409 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
410 |
<i class="material-icons right">import_export</i>
|
411 |
</button>
|
412 |
</div>
|
418 |
<!-- DROPBOX STORAGE-->
|
419 |
<li id="dropbox">
|
420 |
<div class="collapsible-header">
|
421 |
+
<i class="material-icons">computer</i><?php echo __("Dropbox Storage", 'xcloner-backup-and-restore') ?>
|
422 |
<div class="switch right">
|
423 |
<label>
|
424 |
Off
|
425 |
<input type="checkbox" name="xcloner_dropbox_enable" class="status"
|
426 |
+
value="1" <?php if (get_option("xcloner_dropbox_enable"))
|
427 |
echo "checked" ?> \>
|
428 |
<span class="lever"></span>
|
429 |
On
|
438 |
</div>
|
439 |
<div class=" col s12 m6">
|
440 |
<p>
|
441 |
+
<?php echo sprintf(__('Visit %s and get your "App secret".'), "<a href='https://www.dropbox.com/developers/apps' target='_blank'>https://www.dropbox.com/developers/apps</a>") ?>
|
442 |
</p>
|
443 |
</div>
|
444 |
</div>
|
445 |
|
446 |
<div class="row">
|
447 |
<div class="col s12 m3 label">
|
448 |
+
<label for="dropbox_access_token"><?php echo __("Dropbox Access Token", 'xcloner-backup-and-restore') ?></label>
|
449 |
</div>
|
450 |
<div class=" col s12 m6">
|
451 |
+
<input placeholder="<?php echo __("Dropbox Access Token", 'xcloner-backup-and-restore') ?>"
|
452 |
id="dropbox_access_token" type="text" name="xcloner_dropbox_access_token"
|
453 |
class="validate"
|
454 |
+
value="<?php echo get_option("xcloner_dropbox_access_token") ?>"
|
455 |
autocomplete="off">
|
456 |
</div>
|
457 |
</div>
|
459 |
|
460 |
<div class="row">
|
461 |
<div class="col s12 m3 label">
|
462 |
+
<label for="dropbox_app_secret"><?php echo __("Dropbox App Secret", 'xcloner-backup-and-restore') ?></label>
|
463 |
</div>
|
464 |
<div class=" col s12 m6">
|
465 |
+
<input placeholder="<?php echo __("Dropbox App Secret", 'xcloner-backup-and-restore') ?>"
|
466 |
id="dropbox_app_secret" type="text" name="xcloner_dropbox_app_secret"
|
467 |
+
class="validate" value="<?php echo get_option("xcloner_dropbox_app_secret") ?>"
|
468 |
autocomplete="off">
|
469 |
</div>
|
470 |
</div>
|
471 |
|
472 |
<div class="row">
|
473 |
<div class="col s12 m3 label">
|
474 |
+
<label for="dropbox_prefix"><?php echo __("Dropbox Prefix", 'xcloner-backup-and-restore') ?></label>
|
475 |
</div>
|
476 |
<div class=" col s12 m6">
|
477 |
+
<input placeholder="<?php echo __("Dropbox Prefix", 'xcloner-backup-and-restore') ?>"
|
478 |
id="dropbox_prefix" type="text" name="xcloner_dropbox_prefix" class="validate"
|
479 |
+
value="<?php echo get_option("xcloner_dropbox_prefix") ?>">
|
480 |
</div>
|
481 |
</div>
|
482 |
|
483 |
<div class="row">
|
484 |
<div class="col s12 m3 label">
|
485 |
+
<label for="dropbox_cleanup_days"><?php echo __("Dropbox Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
486 |
</div>
|
487 |
<div class=" col s12 m6">
|
488 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
489 |
id="dropbox_cleanup_days" type="text" name="xcloner_dropbox_cleanup_days"
|
490 |
class="validate"
|
491 |
+
value="<?php echo get_option("xcloner_dropbox_cleanup_days") ?>">
|
492 |
</div>
|
493 |
</div>
|
494 |
|
495 |
<div class="row">
|
496 |
<div class="col s6 m4">
|
497 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
498 |
+
value="dropbox"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
499 |
<i class="material-icons right">save</i>
|
500 |
</button>
|
501 |
</div>
|
502 |
<div class="col s6 m4">
|
503 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
504 |
id="action" value="dropbox"
|
505 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
506 |
<i class="material-icons right">import_export</i>
|
507 |
</button>
|
508 |
</div>
|
514 |
<!-- AZURE STORAGE-->
|
515 |
<li id="azure">
|
516 |
<div class="collapsible-header">
|
517 |
+
<i class="material-icons">computer</i><?php echo __("Azure Blob Storage", 'xcloner-backup-and-restore') ?>
|
518 |
<div class="switch right">
|
519 |
<label>
|
520 |
Off
|
521 |
<input type="checkbox" name="xcloner_azure_enable" class="status"
|
522 |
+
value="1" <?php if (get_option("xcloner_azure_enable"))
|
523 |
echo "checked" ?> \>
|
524 |
<span class="lever"></span>
|
525 |
On
|
534 |
</div>
|
535 |
<div class=" col s12 m6">
|
536 |
<p>
|
537 |
+
<?php echo sprintf(__('Visit %s and get your "Api Key".', 'xcloner-backup-and-restore'), '<a href="https://azure.microsoft.com/en-us/services/storage/blobs/" target="_blank">https://azure.microsoft.com/en-us/services/storage/blobs/</a>') ?>
|
538 |
</p>
|
539 |
</div>
|
540 |
</div>
|
541 |
|
542 |
<div class="row">
|
543 |
<div class="col s12 m3 label">
|
544 |
+
<label for="azure_account_name"><?php echo __("Azure Account Name", 'xcloner-backup-and-restore') ?></label>
|
545 |
</div>
|
546 |
<div class=" col s12 m6">
|
547 |
+
<input placeholder="<?php echo __("Azure Account Name", 'xcloner-backup-and-restore') ?>"
|
548 |
id="azure_account_name" type="text" name="xcloner_azure_account_name"
|
549 |
+
class="validate" value="<?php echo get_option("xcloner_azure_account_name") ?>"
|
550 |
autocomplete="off">
|
551 |
</div>
|
552 |
</div>
|
554 |
|
555 |
<div class="row">
|
556 |
<div class="col s12 m3 label">
|
557 |
+
<label for="azure_api_key"><?php echo __("Azure Api Key", 'xcloner-backup-and-restore') ?></label>
|
558 |
</div>
|
559 |
<div class=" col s12 m6">
|
560 |
+
<input placeholder="<?php echo __("Azure Api Key", 'xcloner-backup-and-restore') ?>"
|
561 |
id="azure_api_key" type="text" name="xcloner_azure_api_key" class="validate"
|
562 |
+
value="<?php echo get_option("xcloner_azure_api_key") ?>" autocomplete="off">
|
563 |
</div>
|
564 |
</div>
|
565 |
|
566 |
<div class="row">
|
567 |
<div class="col s12 m3 label">
|
568 |
+
<label for="azure_container"><?php echo __("Azure Container", 'xcloner-backup-and-restore') ?></label>
|
569 |
</div>
|
570 |
<div class=" col s12 m6">
|
571 |
+
<input placeholder="<?php echo __("Azure Container", 'xcloner-backup-and-restore') ?>"
|
572 |
id="azure_container" type="text" name="xcloner_azure_container" class="validate"
|
573 |
+
value="<?php echo get_option("xcloner_azure_container") ?>">
|
574 |
</div>
|
575 |
</div>
|
576 |
|
577 |
<div class="row">
|
578 |
<div class="col s12 m3 label">
|
579 |
+
<label for="azure_cleanup_days"><?php echo __("Azure Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
580 |
</div>
|
581 |
<div class=" col s12 m6">
|
582 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
583 |
id="azure_cleanup_days" type="text" name="xcloner_azure_cleanup_days"
|
584 |
class="validate"
|
585 |
+
value="<?php echo get_option("xcloner_azure_cleanup_days") ?>">
|
586 |
</div>
|
587 |
</div>
|
588 |
|
589 |
<div class="row">
|
590 |
<div class="col s6 m4">
|
591 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
592 |
+
value="azure"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
593 |
<i class="material-icons right">save</i>
|
594 |
</button>
|
595 |
</div>
|
596 |
<div class="col s6 m4">
|
597 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
598 |
id="action" value="azure"
|
599 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
600 |
<i class="material-icons right">import_export</i>
|
601 |
</button>
|
602 |
</div>
|
608 |
<!-- BACKBLAZE STORAGE-->
|
609 |
<li id="backblaze">
|
610 |
<div class="collapsible-header">
|
611 |
+
<i class="material-icons">computer</i><?php echo __("Backblaze Storage", 'xcloner-backup-and-restore') ?>
|
612 |
<div class="switch right">
|
613 |
<label>
|
614 |
Off
|
615 |
<input type="checkbox" name="xcloner_backblaze_enable" class="status"
|
616 |
+
value="1" <?php if (get_option("xcloner_backblaze_enable"))
|
617 |
echo "checked" ?> \>
|
618 |
<span class="lever"></span>
|
619 |
On
|
628 |
</div>
|
629 |
<div class=" col s12 m6">
|
630 |
<p>
|
631 |
+
<?php echo sprintf(__('Visit %s and get your Account Id and Application Key.', 'xcloner-backup-and-restore'), '<a href="https://secure.backblaze.com/b2_buckets.htm" target="_blank">https://secure.backblaze.com/b2_buckets.htm</a>') ?>
|
632 |
</p>
|
633 |
</div>
|
634 |
</div>
|
635 |
|
636 |
<div class="row">
|
637 |
<div class="col s12 m3 label">
|
638 |
+
<label for="backblaze_account_id"><?php echo __("Backblaze Account Id", 'xcloner-backup-and-restore') ?></label>
|
639 |
</div>
|
640 |
<div class=" col s12 m6">
|
641 |
+
<input placeholder="<?php echo __("Backblaze Account Id", 'xcloner-backup-and-restore') ?>"
|
642 |
id="backblaze_account_id" type="text" name="xcloner_backblaze_account_id"
|
643 |
class="validate"
|
644 |
+
value="<?php echo get_option("xcloner_backblaze_account_id") ?>"
|
645 |
autocomplete="off">
|
646 |
</div>
|
647 |
</div>
|
649 |
|
650 |
<div class="row">
|
651 |
<div class="col s12 m3 label">
|
652 |
+
<label for="backblaze_application_key"><?php echo __("Backblaze Application Key", 'xcloner-backup-and-restore') ?></label>
|
653 |
</div>
|
654 |
<div class=" col s12 m6">
|
655 |
+
<input placeholder="<?php echo __("Backblaze Application Key", 'xcloner-backup-and-restore') ?>"
|
656 |
id="backblaze_application_key" type="text"
|
657 |
name="xcloner_backblaze_application_key" class="validate"
|
658 |
+
value="<?php echo get_option("xcloner_backblaze_application_key") ?>"
|
659 |
autocomplete="off">
|
660 |
</div>
|
661 |
</div>
|
662 |
|
663 |
<div class="row">
|
664 |
<div class="col s12 m3 label">
|
665 |
+
<label for="backblaze_bucket_name"><?php echo __("Backblaze Bucket Name", 'xcloner-backup-and-restore') ?></label>
|
666 |
</div>
|
667 |
<div class=" col s12 m6">
|
668 |
+
<input placeholder="<?php echo __("Backblaze Bucket Name", 'xcloner-backup-and-restore') ?>"
|
669 |
id="backblaze_bucket_name" type="text" name="xcloner_backblaze_bucket_name"
|
670 |
class="validate"
|
671 |
+
value="<?php echo get_option("xcloner_backblaze_bucket_name") ?>"
|
672 |
autocomplete="off">
|
673 |
</div>
|
674 |
</div>
|
675 |
|
676 |
<div class="row">
|
677 |
<div class="col s12 m3 label">
|
678 |
+
<label for="backblaze_cleanup_days"><?php echo __("Backblaze Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
679 |
</div>
|
680 |
<div class=" col s12 m6">
|
681 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
682 |
id="backblaze_cleanup_days" type="text" name="xcloner_backblaze_cleanup_days"
|
683 |
class="validate"
|
684 |
+
value="<?php echo get_option("xcloner_backblaze_cleanup_days") ?>">
|
685 |
</div>
|
686 |
</div>
|
687 |
|
688 |
<div class="row">
|
689 |
<div class="col s6 m4">
|
690 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
691 |
+
value="backblaze"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
692 |
<i class="material-icons right">save</i>
|
693 |
</button>
|
694 |
</div>
|
695 |
<div class="col s6 m4">
|
696 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
697 |
id="action" value="backblaze"
|
698 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
699 |
<i class="material-icons right">import_export</i>
|
700 |
</button>
|
701 |
</div>
|
707 |
<!-- WEBDAV STORAGE-->
|
708 |
<li id="webdav">
|
709 |
<div class="collapsible-header">
|
710 |
+
<i class="material-icons">computer</i><?php echo __("WebDAV Storage", 'xcloner-backup-and-restore') ?>
|
711 |
<div class="switch right">
|
712 |
<label>
|
713 |
Off
|
714 |
<input type="checkbox" name="xcloner_webdav_enable" class="status"
|
715 |
+
value="1" <?php if (get_option("xcloner_webdav_enable"))
|
716 |
echo "checked" ?> \>
|
717 |
<span class="lever"></span>
|
718 |
On
|
734 |
|
735 |
<div class="row">
|
736 |
<div class="col s12 m3 label">
|
737 |
+
<label for="webdav_url"><?php echo __("WebDAV Base Url", 'xcloner-backup-and-restore') ?></label>
|
738 |
</div>
|
739 |
<div class=" col s12 m6">
|
740 |
+
<input placeholder="<?php echo __("WebDAV Base Url", 'xcloner-backup-and-restore') ?>"
|
741 |
id="webdav_url" type="text" name="xcloner_webdav_url" class="validate"
|
742 |
+
value="<?php echo get_option("xcloner_webdav_url") ?>" autocomplete="off">
|
743 |
</div>
|
744 |
</div>
|
745 |
|
746 |
<div class="row">
|
747 |
<div class="col s12 m3 label">
|
748 |
+
<label for="webdav_username"><?php echo __("WebDAV Username", 'xcloner-backup-and-restore') ?></label>
|
749 |
</div>
|
750 |
<div class=" col s12 m6">
|
751 |
+
<input placeholder="<?php echo __("WebDAV Username", 'xcloner-backup-and-restore') ?>"
|
752 |
id="webdav_username" type="text" name="xcloner_webdav_username" class="validate"
|
753 |
+
value="<?php echo get_option("xcloner_webdav_username") ?>" autocomplete="off">
|
754 |
</div>
|
755 |
</div>
|
756 |
|
757 |
<div class="row">
|
758 |
<div class="col s12 m3 label">
|
759 |
+
<label for="webdav_password"><?php echo __("WebDAV Password", 'xcloner-backup-and-restore') ?></label>
|
760 |
</div>
|
761 |
<div class=" col s12 m6">
|
762 |
+
<input placeholder="<?php echo __("WebDAV Password", 'xcloner-backup-and-restore') ?>"
|
763 |
id="webdav_password" type="password" name="xcloner_webdav_password"
|
764 |
+
class="validate" value="<?php echo get_option("xcloner_webdav_password") ?>"
|
765 |
autocomplete="off">
|
766 |
</div>
|
767 |
</div>
|
768 |
|
769 |
<div class="row">
|
770 |
<div class="col s12 m3 label">
|
771 |
+
<label for="webdav_target_folder"><?php echo __("WebDAV Target Folder", 'xcloner-backup-and-restore') ?></label>
|
772 |
</div>
|
773 |
<div class=" col s12 m6">
|
774 |
+
<input placeholder="<?php echo __("WebDAV Target Folder", 'xcloner-backup-and-restore') ?>"
|
775 |
id="webdav_target_folder" type="text" name="xcloner_webdav_target_folder"
|
776 |
class="validate"
|
777 |
+
value="<?php echo get_option("xcloner_webdav_target_folder") ?>"
|
778 |
autocomplete="off">
|
779 |
</div>
|
780 |
</div>
|
781 |
|
782 |
<div class="row">
|
783 |
<div class="col s12 m3 label">
|
784 |
+
<label for="webdav_cleanup_days"><?php echo __("WebDAV Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
785 |
</div>
|
786 |
<div class=" col s12 m6">
|
787 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
788 |
id="webdav_cleanup_days" type="text" name="xcloner_webdav_cleanup_days"
|
789 |
class="validate"
|
790 |
+
value="<?php echo get_option("xcloner_webdav_cleanup_days") ?>">
|
791 |
</div>
|
792 |
</div>
|
793 |
|
794 |
<div class="row">
|
795 |
<div class="col s6 m4">
|
796 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
797 |
+
value="webdav"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
798 |
<i class="material-icons right">save</i>
|
799 |
</button>
|
800 |
</div>
|
801 |
<div class="col s6 m4">
|
802 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
803 |
id="action" value="webdav"
|
804 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
805 |
<i class="material-icons right">import_export</i>
|
806 |
</button>
|
807 |
</div>
|
813 |
<!-- Google DRIVE STORAGE-->
|
814 |
<li id="gdrive">
|
815 |
<div class="collapsible-header">
|
816 |
+
<i class="material-icons">computer</i><?php echo __("Google Drive Storage", 'xcloner-backup-and-restore') ?>
|
817 |
+
<?php if ($gdrive_construct): ?>
|
818 |
<div class="switch right">
|
819 |
<label>
|
820 |
Off
|
821 |
<input type="checkbox" name="xcloner_gdrive_enable" class="status"
|
822 |
+
value="1" <?php if (get_option("xcloner_gdrive_enable"))
|
823 |
echo "checked" ?> \>
|
824 |
<span class="lever"></span>
|
825 |
On
|
829 |
</div>
|
830 |
<div class="collapsible-body">
|
831 |
|
832 |
+
<?php if ($gdrive_construct) : ?>
|
833 |
|
834 |
<div class="row">
|
835 |
<div class="col s12 m3 label">
|
837 |
</div>
|
838 |
<div class=" col s12 m9">
|
839 |
<p>
|
840 |
+
<?php echo sprintf(__('Visit %s to create a new application and get your Client ID and Client Secret.', 'xcloner-backup-and-restore'), '<a href="https://console.developers.google.com" target="_blank">https://console.developers.google.com</a>') ?>
|
841 |
<a href="https://youtu.be/YXUVPUVgG8k" target="_blank"
|
842 |
class="btn-floating tooltipped btn-small" data-position="right"
|
843 |
data-delay="50" data-html="true"
|
844 |
+
data-tooltip="<?php echo sprintf(__('Click here to view a short video explaining how to create the Client ID and Client Secret as well as connecting XCloner with the Google Drive API %s', 'xcloner-backup-and-restore'), "<br />https://youtu.be/YXUVPUVgG8k") ?>"
|
845 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i
|
846 |
class="material-icons">help_outline</i></a>
|
847 |
</p>
|
850 |
|
851 |
<div class="row">
|
852 |
<div class="col s12 m3 label">
|
853 |
+
<label for="gdrive_client_id"><?php echo __("Client ID", 'xcloner-backup-and-restore') ?></label>
|
854 |
</div>
|
855 |
<div class=" col s12 m6">
|
856 |
+
<input placeholder="<?php echo __("Google Client ID", 'xcloner-backup-and-restore') ?>"
|
857 |
id="gdrive_client_id" type="text" name="xcloner_gdrive_client_id"
|
858 |
class="validate"
|
859 |
+
value="<?php echo get_option("xcloner_gdrive_client_id") ?>">
|
860 |
</div>
|
861 |
</div>
|
862 |
|
863 |
<div class="row">
|
864 |
<div class="col s12 m3 label">
|
865 |
+
<label for="gdrive_client_secret"><?php echo __("Client Secret", 'xcloner-backup-and-restore') ?></label>
|
866 |
</div>
|
867 |
<div class=" col s12 m6">
|
868 |
+
<input placeholder="<?php echo __("Google Client Secret", 'xcloner-backup-and-restore') ?>"
|
869 |
id="gdrive_client_secret" type="text" name="xcloner_gdrive_client_secret"
|
870 |
class="validate"
|
871 |
+
value="<?php echo get_option("xcloner_gdrive_client_secret") ?>">
|
872 |
</div>
|
873 |
</div>
|
874 |
|
880 |
<div class=" col s12 m6">
|
881 |
<a class="btn" target="_blank" id="gdrive_authorization_click"
|
882 |
onclick="jQuery('#authentification_code').show()"
|
883 |
+
href="<?php echo $gdrive_auth_url ?>"><?php echo sprintf(__('Authorize Google Drive', 'xcloner-backup-and-restore')) ?></a>
|
884 |
<input type="text" name="authentification_code" id="authentification_code"
|
885 |
+
placeholder="<?php echo __("Paste Authorization Code Here", "xcloner-backup-and-restore") ?>">
|
886 |
</div>
|
887 |
</div>
|
888 |
|
889 |
<div class="row">
|
890 |
<div class="col s12 m3 label">
|
891 |
+
<label for="gdrive_target_folder"><?php echo __("Folder ID or Root Path", 'xcloner-backup-and-restore') ?>
|
892 |
<a class="btn-floating tooltipped btn-small" data-position="right"
|
893 |
data-delay="50" data-html="true" \
|
894 |
+
data-tooltip="<?php echo __('Folder ID can be found by right clicking on the folder name and selecting \'Get shareable link\' menu, format https://drive.google.com/open?id={FOLDER_ID}<br />
|
895 |
+
If you supply a folder name, it has to exists in the drive root and start with / , example /backups.xcloner.com/', 'xcloner-backup-and-restore') ?>"
|
896 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i
|
897 |
class="material-icons">help_outline</i></a>
|
898 |
</label>
|
899 |
</div>
|
900 |
<div class=" col s12 m6">
|
901 |
+
<input placeholder="<?php echo __("Target Folder ID or Root Path", 'xcloner-backup-and-restore') ?>"
|
902 |
id="gdrive_target_folder" type="text" name="xcloner_gdrive_target_folder"
|
903 |
class="validate"
|
904 |
+
value="<?php echo get_option("xcloner_gdrive_target_folder") ?>"
|
905 |
autocomplete="off">
|
906 |
</div>
|
907 |
</div>
|
908 |
|
909 |
<div class="row">
|
910 |
<div class="col s12 m3 label">
|
911 |
+
<label for="gdrive_cleanup_days"><?php echo __("Google Drive Cleanup (days)", 'xcloner-backup-and-restore') ?></label>
|
912 |
</div>
|
913 |
<div class=" col s12 m6">
|
914 |
+
<input placeholder="<?php echo __("how many days to keep the backups for", 'xcloner-backup-and-restore') ?>"
|
915 |
id="gdrive_cleanup_days" type="text" name="xcloner_gdrive_cleanup_days"
|
916 |
class="validate"
|
917 |
+
value="<?php echo get_option("xcloner_gdrive_cleanup_days") ?>">
|
918 |
</div>
|
919 |
</div>
|
920 |
|
921 |
<div class="row">
|
922 |
<div class="col s12 m3 label">
|
923 |
+
<label for="gdrive_empty_trash"><?php echo __("Automatically Empty Trash?", 'xcloner-backup-and-restore') ?></label>
|
924 |
</div>
|
925 |
<div class=" col s12 m6 input-field inline">
|
926 |
<input name="xcloner_gdrive_empty_trash" type="radio" value="0"
|
927 |
+
id="gdrive_empty_trash_off" <?php if (!get_option("xcloner_gdrive_empty_trash", 0))
|
928 |
echo "checked" ?> />
|
929 |
+
<label for="gdrive_empty_trash_off"><?php echo __("Disabled", 'xcloner-backup-and-restore') ?></label>
|
930 |
|
931 |
<input name="xcloner_gdrive_empty_trash" type="radio" value="1"
|
932 |
+
id="gdrive_empty_trash_on" <?php if (get_option("xcloner_gdrive_empty_trash", 0))
|
933 |
echo "checked" ?> />
|
934 |
+
<label for="gdrive_empty_trash_on"><?php echo __("Enabled", 'xcloner-backup-and-restore') ?></label>
|
935 |
</div>
|
936 |
</div>
|
937 |
|
938 |
<div class="row">
|
939 |
<div class="col s6 m4">
|
940 |
<button class="btn waves-effect waves-light" type="submit" name="action" id="action"
|
941 |
+
value="gdrive"><?php echo __("Save Settings", 'xcloner-backup-and-restore') ?>
|
942 |
<i class="material-icons right">save</i>
|
943 |
</button>
|
944 |
</div>
|
945 |
<div class="col s6 m4">
|
946 |
<button class="btn waves-effect waves-light orange" type="submit" name="action"
|
947 |
id="action" value="gdrive"
|
948 |
+
onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify", 'xcloner-backup-and-restore') ?>
|
949 |
<i class="material-icons right">import_export</i>
|
950 |
</button>
|
951 |
</div>
|
956 |
<div class=" col s12">
|
957 |
<div class="center">
|
958 |
<?php
|
959 |
+
$url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=xcloner-google-drive'), 'install-plugin_xcloner-google-drive');
|
960 |
?>
|
961 |
+
<h6><?php echo __("This storage option requires the XCloner-Google-Drive Wordpress Plugin to be installed and activated.") ?></h6>
|
962 |
+
<h6><?php echo __("PHP 5.5 minimum version is required.") ?></h6>
|
963 |
<br/>
|
964 |
<a class="install-now btn" data-slug="xcloner-google-drive"
|
965 |
href="<?php echo $url; ?>"
|
966 |
aria-label="Install XCloner Google Drive 1.0.0 now"
|
967 |
data-name="XCloner Google Drive 1.0.0">
|
968 |
+
<?php echo sprintf(__('Install Now', 'xcloner-backup-and-restore')) ?>
|
969 |
</a>
|
970 |
|
971 |
+
<a href="<?php echo admin_url("plugin-install.php") ?>?tab=plugin-information&plugin=xcloner-google-drive&TB_iframe=true&width=772&height=499"
|
972 |
class="btn thickbox open-plugin-details-modal"
|
973 |
aria-label="More information about Theme Check 20160523.1"
|
974 |
data-title="Theme Check 20160523.1">
|
975 |
<!--
|
976 |
<a class="btn" href="https://github.com/ovidiul/XCloner-Google-Drive/archive/master.zip">
|
977 |
-->
|
978 |
+
<?php echo sprintf(__('More Details', 'xcloner-backup-and-restore')) ?>
|
979 |
</a>
|
980 |
</div>
|
981 |
</div>
|
admin/partials/xcloner_restore_page.php
CHANGED
@@ -11,10 +11,10 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
11 |
|
12 |
?>
|
13 |
|
14 |
-
<h1><?= esc_html(
|
15 |
|
16 |
<script>
|
17 |
-
var xcloner_auth_key = '<?php echo md5(
|
18 |
</script>
|
19 |
|
20 |
<div class="row xcloner-restore">
|
@@ -22,36 +22,36 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
22 |
<ul class="collapsible xcloner-restore " data-collapsible="accordion">
|
23 |
<li data-step="1" class="restore-script-upload-step steps active show">
|
24 |
<div class="collapsible-header active"><i
|
25 |
-
class="material-icons">settings_remote</i><?php echo __(
|
26 |
</div>
|
27 |
<div class="collapsible-body row">
|
28 |
|
29 |
<ul class="text-steps">
|
30 |
-
<li><?php echo __(
|
31 |
</li>
|
32 |
-
<li><?php echo __(
|
33 |
<a href='#'
|
34 |
-
onclick="window.location=ajaxurl+'?action=download_restore_script&phar=true'"><strong><?php echo __(
|
35 |
</li>
|
36 |
<li>
|
37 |
-
<?php echo __(
|
38 |
</li>
|
39 |
<li>
|
40 |
-
<?php echo __(
|
41 |
</li>
|
42 |
<li>
|
43 |
-
<?php echo __(
|
44 |
</li>
|
45 |
-
<?php if (
|
46 |
<li class="warning">
|
47 |
-
<?php echo __(
|
48 |
</li>
|
49 |
<?php endif ?>
|
50 |
|
51 |
</ul>
|
52 |
|
53 |
<div class="input-field col l9 s12">
|
54 |
-
<input value="<?php echo (
|
55 |
class="validate"
|
56 |
placeholder="Url to XCloner Restore Script, example http://myddns.com/xcloner/xcloner_restore.php">
|
57 |
<label for="restore_script_url"></label>
|
@@ -59,7 +59,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
59 |
</div>
|
60 |
<div class="col l3 s12 right-align">
|
61 |
<button class="btn waves-effect waves-light" type="submit" id="validate_url"
|
62 |
-
name="action"><?php echo __(
|
63 |
<i class="material-icons right">send</i>
|
64 |
</button>
|
65 |
</div>
|
@@ -68,18 +68,18 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
68 |
|
69 |
<li data-step="2" class="backup-upload-step steps">
|
70 |
<div class="collapsible-header active"><i
|
71 |
-
class="material-icons">file_upload</i><?php echo __(
|
72 |
</div>
|
73 |
<div class="collapsible-body row">
|
74 |
-
<p><?php echo __(
|
75 |
<div class="input-field col s12 l7">
|
76 |
<select id="backup_file" name="backup_file" class="browser-default">
|
77 |
<option value="" disabled
|
78 |
-
selected><?php echo __(
|
79 |
-
<?php if (
|
80 |
-
<?php foreach (
|
81 |
<option value="<?php echo $file['basename'] ?>">
|
82 |
-
<?php echo $file['basename'] ?> (<?php echo size_format(
|
83 |
</option>
|
84 |
<?php endforeach ?>
|
85 |
<?php endif ?>
|
@@ -94,18 +94,18 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
94 |
<div class="col s12 l5 right-align">
|
95 |
<div class="toggler">
|
96 |
<button class="btn waves-effect waves-light upload-backup normal" type="submit" id=""
|
97 |
-
name="action"><?php echo __(
|
98 |
<i class="material-icons left">navigate_before</i>
|
99 |
</button>
|
100 |
<button class="btn waves-effect waves-light red upload-backup cancel" type="submit" id=""
|
101 |
-
name="action"><?php echo __(
|
102 |
<i class="material-icons right">close</i>
|
103 |
</button>
|
104 |
</div>
|
105 |
<button class="btn waves-effect waves-light grey" type="submit"
|
106 |
-
title="<?php echo __(
|
107 |
id="skip_upload_backup"
|
108 |
-
name="action"><?php echo __(
|
109 |
<i class="material-icons right">navigate_next</i>
|
110 |
</button>
|
111 |
</div>
|
@@ -114,13 +114,13 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
114 |
|
115 |
<li data-step="3" class="restore-remote-backup-step steps active">
|
116 |
<div class="collapsible-header"><i
|
117 |
-
class="material-icons">folder_open</i><?php echo __(
|
118 |
<i class="material-icons right" title="Refresh Target Backup Files List"
|
119 |
id="refresh_remote_backup_file">cached</i>
|
120 |
|
121 |
<div class="switch right">
|
122 |
<label>
|
123 |
-
<?php echo __(
|
124 |
<input type="checkbox" id="toggle_file_restore_display" name="toggle_file_restore_display"
|
125 |
class="" checked value="1">
|
126 |
<span class="lever"></span>
|
@@ -135,11 +135,11 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
135 |
<div class="col s12">
|
136 |
<a class="btn-floating tooltipped btn-small right" data-html="true" data-position="left"
|
137 |
data-delay="50"
|
138 |
-
data-tooltip="<?php echo __(
|
139 |
-
Please use this with caution when restoring to a live site.", 'xcloner-backup-and-restore'
|
140 |
class="material-icons">help_outline</i>
|
141 |
</a>
|
142 |
-
<h5><?php echo __(
|
143 |
<input type="text" name="remote_restore_path" id="remote_restore_path" class="validate"
|
144 |
placeholder="Restore Target Path">
|
145 |
<label></label>
|
@@ -151,13 +151,13 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
151 |
<div class="col s12">
|
152 |
<a href="#backup_localhost-2017-04-03_10-58-sql-diff2017-03-22_00-00-5b6c4.tgz"
|
153 |
class="list-backup-content btn-floating tooltipped btn-small right"
|
154 |
-
data-tooltip="<?php echo __(
|
155 |
<i class="material-icons">folder_open</i>
|
156 |
</a>
|
157 |
-
<h5><?php echo __(
|
158 |
<select id="remote_backup_file" name="remote_backup_file" class="browser-default">
|
159 |
<option value="" disabled
|
160 |
-
selected><?php echo __(
|
161 |
</select>
|
162 |
<label></label>
|
163 |
</div>
|
@@ -166,41 +166,41 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
166 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_all" checked
|
167 |
value="" disabled/>
|
168 |
<label for="filter_files_all" class="tooltipped" data-position="right"
|
169 |
-
data-tooltip="<?php echo __(
|
170 |
|
171 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_wp_content"
|
172 |
value="/^wp-content\/(.*)/"/>
|
173 |
<label for="filter_files_wp_content" class="tooltipped"
|
174 |
-
data-tooltip="<?php echo __(
|
175 |
-
<?php echo __(
|
176 |
</label>
|
177 |
|
178 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_plugins"
|
179 |
value="/^wp-content\/plugins(.*)/"/>
|
180 |
<label for="filter_files_plugins" class="tooltipped"
|
181 |
-
data-tooltip="<?php echo __(
|
182 |
-
<?php echo __(
|
183 |
</label>
|
184 |
|
185 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_uploads"
|
186 |
value="/^wp-content\/uploads(.*)/"/>
|
187 |
<label for="filter_files_uploads" class="tooltipped"
|
188 |
-
data-tooltip="<?php echo __(
|
189 |
-
<?php echo __(
|
190 |
</label>
|
191 |
|
192 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_themes"
|
193 |
value="/^wp-content\/themes(.*)/"/>
|
194 |
<label for="filter_files_themes" class="tooltipped"
|
195 |
-
data-tooltip="<?php echo __(
|
196 |
-
<?php echo __(
|
197 |
</label>
|
198 |
|
199 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_database"
|
200 |
value="/^xcloner-(.*)\/(.*)\.sql/"/>
|
201 |
<label for="filter_files_database" class="tooltipped"
|
202 |
-
data-tooltip="<?php echo __(
|
203 |
-
<?php echo __(
|
204 |
</label>
|
205 |
</div>
|
206 |
</div>
|
@@ -216,18 +216,18 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
216 |
<div class="col s12 l5 right-align">
|
217 |
<div class="toggler">
|
218 |
<button class="btn waves-effect waves-light restore_remote_backup normal " type="submit"
|
219 |
-
id="" name="action"><?php echo __(
|
220 |
<i class="material-icons left">navigate_before</i>
|
221 |
</button>
|
222 |
<button class="btn waves-effect waves-light red restore_remote_backup cancel" type="submit"
|
223 |
-
id="" name="action"><?php echo __(
|
224 |
<i class="material-icons right">close</i>
|
225 |
</button>
|
226 |
</div>
|
227 |
<button class="btn waves-effect waves-light grey" type="submit"
|
228 |
-
title="<?php echo __(
|
229 |
id="skip_remote_backup_step"
|
230 |
-
name="action"><?php echo __(
|
231 |
<i class="material-icons right">navigate_next</i>
|
232 |
</button>
|
233 |
</div>
|
@@ -236,7 +236,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
236 |
|
237 |
<li data-step="4" class="restore-remote-database-step steps active">
|
238 |
<div class="collapsible-header"><i
|
239 |
-
class="material-icons">list</i><?php echo __(
|
240 |
<i class="material-icons right" title="Refresh Database Backup Files List"
|
241 |
id="refresh_database_file">cached</i>
|
242 |
</div>
|
@@ -246,68 +246,68 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
246 |
<div class="col s12">
|
247 |
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50"
|
248 |
data-html="true"
|
249 |
-
data-tooltip="<?php echo __(
|
250 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
251 |
-
<h5><?php echo __(
|
252 |
</div>
|
253 |
<div class=" col s12">
|
254 |
<div class="input-field col s12 m6">
|
255 |
<input type="text" name="remote_mysql_host" id="remote_mysql_host" class="validate"
|
256 |
placeholder="Target Mysql Hostname">
|
257 |
-
<label><?php echo __(
|
258 |
</div>
|
259 |
|
260 |
<div class="input-field col s12 m6">
|
261 |
<input type="text" name="remote_mysql_db" id="remote_mysql_db" class="validate"
|
262 |
placeholder="Target Mysql Database">
|
263 |
-
<label><?php echo __(
|
264 |
</div>
|
265 |
|
266 |
<div class="input-field col s12 m6">
|
267 |
<input type="text" name="remote_mysql_user" id="remote_mysql_user" class="validate"
|
268 |
placeholder="Target Mysql Username">
|
269 |
-
<label><?php echo __(
|
270 |
</div>
|
271 |
|
272 |
|
273 |
<div class="input-field col s12 m6">
|
274 |
<input type="text" name="remote_mysql_pass" id="remote_mysql_pass" class="validate"
|
275 |
placeholder="Target Mysql Password">
|
276 |
-
<label><?php echo __(
|
277 |
</div>
|
278 |
|
279 |
</div>
|
280 |
<div class="col s12">
|
281 |
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50"
|
282 |
data-html="true"
|
283 |
-
data-tooltip="<?php echo __(
|
284 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
285 |
-
<h5><?php echo __(
|
286 |
</div>
|
287 |
<div class="col s12">
|
288 |
<div class="input-field col s12 m6 ">
|
289 |
<input type="text" name="wp_home_url" id="wp_home_url" class="validate"
|
290 |
placeholder="WP Home Url" value="<?php echo home_url(); ?>">
|
291 |
-
<label><?php echo __(
|
292 |
</div>
|
293 |
|
294 |
<div class="input-field col s12 m6 ">
|
295 |
<input type="text" name="remote_restore_url" id="remote_restore_url" class="validate"
|
296 |
placeholder="Restore Target Url">
|
297 |
-
<label><?php echo __(
|
298 |
</div>
|
299 |
|
300 |
-
<?php if (
|
301 |
<div class="input-field col s12 m6 ">
|
302 |
<input type="text" name="wp_site_url" id="wp_site_url" class="validate"
|
303 |
placeholder="WP Site Url" value="<?php echo site_url(); ?>">
|
304 |
-
<label><?php echo __(
|
305 |
</div>
|
306 |
|
307 |
<div class="input-field col s12 m6 ">
|
308 |
<input type="text" name="remote_restore_site_url" id="remote_restore_site_url"
|
309 |
class="validate" placeholder="Restore Target Url">
|
310 |
-
<label><?php echo __(
|
311 |
</div>
|
312 |
|
313 |
<?php endif; ?>
|
@@ -319,7 +319,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
319 |
<div class="input-field row">
|
320 |
<select id="remote_database_file" name="remote_database_file" class="browser-default">
|
321 |
<option value="" disabled
|
322 |
-
selected><?php echo __(
|
323 |
</select>
|
324 |
|
325 |
<label></label>
|
@@ -331,7 +331,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
331 |
|
332 |
<div class="status"></div>
|
333 |
<div class="query-box">
|
334 |
-
<h6><?php echo __(
|
335 |
<textarea class="query-list" cols="5"></textarea>
|
336 |
</div>
|
337 |
</div>
|
@@ -339,20 +339,20 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
339 |
<div class="col s12 l5 right-align">
|
340 |
<div class="toggler">
|
341 |
<button class="btn waves-effect waves-light restore_remote_mysqldump normal " type="submit"
|
342 |
-
id="" name="action"><?php echo __(
|
343 |
<i class="material-icons left">navigate_before</i>
|
344 |
</button>
|
345 |
<button class="btn waves-effect waves-light red restore_remote_mysqldump cancel"
|
346 |
type="submit" id=""
|
347 |
-
name="action"><?php echo __(
|
348 |
<i class="material-icons right">close</i>
|
349 |
</button>
|
350 |
</div>
|
351 |
|
352 |
<button class="btn waves-effect waves-light grey" type="submit"
|
353 |
-
title="<?php echo __(
|
354 |
id="skip_restore_remote_database_step"
|
355 |
-
name="action"><?php echo __(
|
356 |
<i class="material-icons right">navigate_next</i>
|
357 |
</button>
|
358 |
|
@@ -363,13 +363,13 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
363 |
|
364 |
<li data-step="5" class="restore-finish-step steps active">
|
365 |
<div class="collapsible-header"><i
|
366 |
-
class="material-icons">folder_open</i><?php echo __(
|
367 |
</div>
|
368 |
<div class="collapsible-body row">
|
369 |
|
370 |
<div class="row">
|
371 |
<div class="col s4">
|
372 |
-
<label><?php echo __(
|
373 |
</div>
|
374 |
|
375 |
<div class="col s8">
|
@@ -387,7 +387,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
387 |
|
388 |
<div class="row">
|
389 |
<div class="col s4">
|
390 |
-
<label><?php echo __(
|
391 |
</div>
|
392 |
<div class="col s8">
|
393 |
<div class="switch">
|
@@ -404,7 +404,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
404 |
|
405 |
<div class="row">
|
406 |
<div class="col s4">
|
407 |
-
<label><?php echo __(
|
408 |
</div>
|
409 |
<div class="col s8">
|
410 |
<div class="switch">
|
@@ -424,8 +424,8 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
424 |
</div>
|
425 |
|
426 |
<div class=" row col s12 center-align" id="xcloner_restore_finish">
|
427 |
-
<h5><?php echo __(
|
428 |
-
<h6><?php echo sprintf(
|
429 |
<a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow
|
430 |
@thinkovi</a>
|
431 |
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
@@ -435,14 +435,14 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
435 |
<div class="row">
|
436 |
<div class="col s6 right-align">
|
437 |
<button class="btn waves-effect waves-light teal" type="submit" id="restore_finish"
|
438 |
-
name="action"><?php echo __(
|
439 |
<i class="material-icons right">navigate_next</i>
|
440 |
</button>
|
441 |
</div>
|
442 |
|
443 |
<div id="open_target_site" class="col s6 left-align">
|
444 |
<a disabled="disabled" href="#" class="btn waves-effect waves-light teal" type="button"
|
445 |
-
target="_blank"><?php echo __(
|
446 |
<i class="material-icons right">navigate_next</i>
|
447 |
</a>
|
448 |
</div>
|
@@ -459,7 +459,7 @@ $backup_list = $xcloner_file_system->get_latest_backups();
|
|
459 |
<!-- List Backup Content Modal-->
|
460 |
<div id="backup_cotent_modal" class="modal">
|
461 |
<div class="modal-content">
|
462 |
-
<h4><?php echo sprintf(
|
463 |
<h5 class="backup-name"></h5>
|
464 |
|
465 |
<div class="progress">
|
11 |
|
12 |
?>
|
13 |
|
14 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
15 |
|
16 |
<script>
|
17 |
+
var xcloner_auth_key = '<?php echo md5(AUTH_KEY)?>';
|
18 |
</script>
|
19 |
|
20 |
<div class="row xcloner-restore">
|
22 |
<ul class="collapsible xcloner-restore " data-collapsible="accordion">
|
23 |
<li data-step="1" class="restore-script-upload-step steps active show">
|
24 |
<div class="collapsible-header active"><i
|
25 |
+
class="material-icons">settings_remote</i><?php echo __("Restore Script Upload", 'xcloner-backup-and-restore') ?>
|
26 |
</div>
|
27 |
<div class="collapsible-body row">
|
28 |
|
29 |
<ul class="text-steps">
|
30 |
+
<li><?php echo __("If you want to do a <strong>Local Target System Restore</strong>, leave Url field below empty and click 'Check Connection', you can skip the next steps.", 'xcloner-backup-and-restore') ?>
|
31 |
</li>
|
32 |
+
<li><?php echo __("If you want to do a <strong>Remote Target System Restore</strong>, please download the restore script from", 'xcloner-backup-and-restore') ?>
|
33 |
<a href='#'
|
34 |
+
onclick="window.location=ajaxurl+'?action=download_restore_script&phar=true'"><strong><?php echo __("here", 'xcloner-backup-and-restore') ?></strong></a>
|
35 |
</li>
|
36 |
<li>
|
37 |
+
<?php echo __("Extract the restore script archive files on your new host", 'xcloner-backup-and-restore') ?>
|
38 |
</li>
|
39 |
<li>
|
40 |
+
<?php echo __("Provide url below to the <u>xcloner_restore.php</u> restore script, like http://my_restore_site.com/xcloner_restore.php", 'xcloner-backup-and-restore') ?>
|
41 |
</li>
|
42 |
<li>
|
43 |
+
<?php echo __("If your server is not web accessible, like a localhost computer, you can use a DynDNS service or install a blank copy of Wordpress with XCloner in the same environment and start the restore from there.", 'xcloner-backup-and-restore') ?>
|
44 |
</li>
|
45 |
+
<?php if (is_ssl()): ?>
|
46 |
<li class="warning">
|
47 |
+
<?php echo __("We have detected your connection to the site as being secure, so your restore script address must start with https://.") ?>
|
48 |
</li>
|
49 |
<?php endif ?>
|
50 |
|
51 |
</ul>
|
52 |
|
53 |
<div class="input-field col l9 s12">
|
54 |
+
<input value="<?php echo (is_ssl()) ? "https://" : "" ?>" id="restore_script_url" type="text"
|
55 |
class="validate"
|
56 |
placeholder="Url to XCloner Restore Script, example http://myddns.com/xcloner/xcloner_restore.php">
|
57 |
<label for="restore_script_url"></label>
|
59 |
</div>
|
60 |
<div class="col l3 s12 right-align">
|
61 |
<button class="btn waves-effect waves-light" type="submit" id="validate_url"
|
62 |
+
name="action"><?php echo __("Check Connection", 'xcloner-backup-and-restore') ?>
|
63 |
<i class="material-icons right">send</i>
|
64 |
</button>
|
65 |
</div>
|
68 |
|
69 |
<li data-step="2" class="backup-upload-step steps">
|
70 |
<div class="collapsible-header active"><i
|
71 |
+
class="material-icons">file_upload</i><?php echo __("Upload Local Backup Archive To Target Host", 'xcloner-backup-and-restore') ?>
|
72 |
</div>
|
73 |
<div class="collapsible-body row">
|
74 |
+
<p><?php echo __("You can skip this step if you want to transfer the archive in some other way, make sure you upload it in the same directory as the restore script from the previous step.", 'xcloner-backup-and-restore') ?></p>
|
75 |
<div class="input-field col s12 l7">
|
76 |
<select id="backup_file" name="backup_file" class="browser-default">
|
77 |
<option value="" disabled
|
78 |
+
selected><?php echo __("Please select a local backup archive to upload to target host", 'xcloner-backup-and-restore') ?></option>
|
79 |
+
<?php if (is_array($backup_list)): ?>
|
80 |
+
<?php foreach ($backup_list as $file): ?>
|
81 |
<option value="<?php echo $file['basename'] ?>">
|
82 |
+
<?php echo $file['basename'] ?> (<?php echo size_format($file['size']) ?>)
|
83 |
</option>
|
84 |
<?php endforeach ?>
|
85 |
<?php endif ?>
|
94 |
<div class="col s12 l5 right-align">
|
95 |
<div class="toggler">
|
96 |
<button class="btn waves-effect waves-light upload-backup normal" type="submit" id=""
|
97 |
+
name="action"><?php echo __("Upload", 'xcloner-backup-and-restore') ?>
|
98 |
<i class="material-icons left">navigate_before</i>
|
99 |
</button>
|
100 |
<button class="btn waves-effect waves-light red upload-backup cancel" type="submit" id=""
|
101 |
+
name="action"><?php echo __("Cancel", 'xcloner-backup-and-restore') ?>
|
102 |
<i class="material-icons right">close</i>
|
103 |
</button>
|
104 |
</div>
|
105 |
<button class="btn waves-effect waves-light grey" type="submit"
|
106 |
+
title="<?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>"
|
107 |
id="skip_upload_backup"
|
108 |
+
name="action"><?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>
|
109 |
<i class="material-icons right">navigate_next</i>
|
110 |
</button>
|
111 |
</div>
|
114 |
|
115 |
<li data-step="3" class="restore-remote-backup-step steps active">
|
116 |
<div class="collapsible-header"><i
|
117 |
+
class="material-icons">folder_open</i><?php echo __("Restore Files Backup Available On Target Location", 'xcloner-backup-and-restore') ?>
|
118 |
<i class="material-icons right" title="Refresh Target Backup Files List"
|
119 |
id="refresh_remote_backup_file">cached</i>
|
120 |
|
121 |
<div class="switch right">
|
122 |
<label>
|
123 |
+
<?php echo __('Verbose Output', 'xcloner-backup-and-restore') ?>
|
124 |
<input type="checkbox" id="toggle_file_restore_display" name="toggle_file_restore_display"
|
125 |
class="" checked value="1">
|
126 |
<span class="lever"></span>
|
135 |
<div class="col s12">
|
136 |
<a class="btn-floating tooltipped btn-small right" data-html="true" data-position="left"
|
137 |
data-delay="50"
|
138 |
+
data-tooltip="<?php echo __("This is the directory where you would like to restore the backup archive files.<br />
|
139 |
+
Please use this with caution when restoring to a live site.", 'xcloner-backup-and-restore') ?>"><i
|
140 |
class="material-icons">help_outline</i>
|
141 |
</a>
|
142 |
+
<h5><?php echo __("Restore Target Path:", 'xcloner-backup-and-restore') ?></h5>
|
143 |
<input type="text" name="remote_restore_path" id="remote_restore_path" class="validate"
|
144 |
placeholder="Restore Target Path">
|
145 |
<label></label>
|
151 |
<div class="col s12">
|
152 |
<a href="#backup_localhost-2017-04-03_10-58-sql-diff2017-03-22_00-00-5b6c4.tgz"
|
153 |
class="list-backup-content btn-floating tooltipped btn-small right"
|
154 |
+
data-tooltip="<?php echo __('Click To List The Selected Backup Content', 'xcloner-backup-and-restore') ?>">
|
155 |
<i class="material-icons">folder_open</i>
|
156 |
</a>
|
157 |
+
<h5><?php echo __("Restore Backup Archive:", 'xcloner-backup-and-restore') ?></h5>
|
158 |
<select id="remote_backup_file" name="remote_backup_file" class="browser-default">
|
159 |
<option value="" disabled
|
160 |
+
selected><?php echo __("Please select the target backup file to restore", 'xcloner-backup-and-restore') ?></option>
|
161 |
</select>
|
162 |
<label></label>
|
163 |
</div>
|
166 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_all" checked
|
167 |
value="" disabled/>
|
168 |
<label for="filter_files_all" class="tooltipped" data-position="right"
|
169 |
+
data-tooltip="<?php echo __("Restore all backup files. Available only when doing a Remote Target System Restore", 'xcloner-backup-and-restore') ?>"><?php echo __("Restore All Files", "xcloner-backup-and-restore") ?></label>
|
170 |
|
171 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_wp_content"
|
172 |
value="/^wp-content\/(.*)/"/>
|
173 |
<label for="filter_files_wp_content" class="tooltipped"
|
174 |
+
data-tooltip="<?php echo __('Restore the files only of the wp-content/ folder', 'xcloner-backup-and-restore') ?>">
|
175 |
+
<?php echo __("Only wp-content", "xcloner-backup-and-restore") ?>
|
176 |
</label>
|
177 |
|
178 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_plugins"
|
179 |
value="/^wp-content\/plugins(.*)/"/>
|
180 |
<label for="filter_files_plugins" class="tooltipped"
|
181 |
+
data-tooltip="<?php echo __('Restore the files only of the wp-content/plugins/ folder', 'xcloner-backup-and-restore') ?>">
|
182 |
+
<?php echo __("Only Plugins", "xcloner-backup-and-restore") ?>
|
183 |
</label>
|
184 |
|
185 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_uploads"
|
186 |
value="/^wp-content\/uploads(.*)/"/>
|
187 |
<label for="filter_files_uploads" class="tooltipped"
|
188 |
+
data-tooltip="<?php echo __('Restore the files only of the wp-content/uploads/ folder only', 'xcloner-backup-and-restore') ?>">
|
189 |
+
<?php echo __("Only Uploads", "xcloner-backup-and-restore") ?>
|
190 |
</label>
|
191 |
|
192 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_themes"
|
193 |
value="/^wp-content\/themes(.*)/"/>
|
194 |
<label for="filter_files_themes" class="tooltipped"
|
195 |
+
data-tooltip="<?php echo __('Restore the files only of the wp-content/themes/ folder', 'xcloner-backup-and-restore') ?>">
|
196 |
+
<?php echo __("Only Themes", "xcloner-backup-and-restore") ?>
|
197 |
</label>
|
198 |
|
199 |
<input class="with-gap" name="filter_files" type="radio" id="filter_files_database"
|
200 |
value="/^xcloner-(.*)\/(.*)\.sql/"/>
|
201 |
<label for="filter_files_database" class="tooltipped"
|
202 |
+
data-tooltip="<?php echo __('Restore the database-sql.sql mysql backup from the xcloner-xxxxx/ folder', 'xcloner-backup-and-restore') ?>">
|
203 |
+
<?php echo __("Only Database Backup", "xcloner-backup-and-restore") ?>
|
204 |
</label>
|
205 |
</div>
|
206 |
</div>
|
216 |
<div class="col s12 l5 right-align">
|
217 |
<div class="toggler">
|
218 |
<button class="btn waves-effect waves-light restore_remote_backup normal " type="submit"
|
219 |
+
id="" name="action"><?php echo __("Restore", 'xcloner-backup-and-restore') ?>
|
220 |
<i class="material-icons left">navigate_before</i>
|
221 |
</button>
|
222 |
<button class="btn waves-effect waves-light red restore_remote_backup cancel" type="submit"
|
223 |
+
id="" name="action"><?php echo __("Cancel", 'xcloner-backup-and-restore') ?>
|
224 |
<i class="material-icons right">close</i>
|
225 |
</button>
|
226 |
</div>
|
227 |
<button class="btn waves-effect waves-light grey" type="submit"
|
228 |
+
title="<?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>"
|
229 |
id="skip_remote_backup_step"
|
230 |
+
name="action"><?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>
|
231 |
<i class="material-icons right">navigate_next</i>
|
232 |
</button>
|
233 |
</div>
|
236 |
|
237 |
<li data-step="4" class="restore-remote-database-step steps active">
|
238 |
<div class="collapsible-header"><i
|
239 |
+
class="material-icons">list</i><?php echo __("Restore Target Database - Search and Replace", 'xcloner-backup-and-restore') ?>
|
240 |
<i class="material-icons right" title="Refresh Database Backup Files List"
|
241 |
id="refresh_database_file">cached</i>
|
242 |
</div>
|
246 |
<div class="col s12">
|
247 |
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50"
|
248 |
data-html="true"
|
249 |
+
data-tooltip="<?php echo __('Please provide below the mysql connection details for the target host database.<br />For live sites we recommend using a new separate database.', 'xcloner-backup-and-restore') ?>"
|
250 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
251 |
+
<h5><?php echo __('Target Mysql Details', 'xcloner-backup-and-restore') ?></h5>
|
252 |
</div>
|
253 |
<div class=" col s12">
|
254 |
<div class="input-field col s12 m6">
|
255 |
<input type="text" name="remote_mysql_host" id="remote_mysql_host" class="validate"
|
256 |
placeholder="Target Mysql Hostname">
|
257 |
+
<label><?php echo __("Target Mysql Hostname", 'xcloner-backup-and-restore') ?></label>
|
258 |
</div>
|
259 |
|
260 |
<div class="input-field col s12 m6">
|
261 |
<input type="text" name="remote_mysql_db" id="remote_mysql_db" class="validate"
|
262 |
placeholder="Target Mysql Database">
|
263 |
+
<label><?php echo __("Target Mysql Database", 'xcloner-backup-and-restore') ?></label>
|
264 |
</div>
|
265 |
|
266 |
<div class="input-field col s12 m6">
|
267 |
<input type="text" name="remote_mysql_user" id="remote_mysql_user" class="validate"
|
268 |
placeholder="Target Mysql Username">
|
269 |
+
<label><?php echo __("Target Mysql Username", 'xcloner-backup-and-restore') ?></label>
|
270 |
</div>
|
271 |
|
272 |
|
273 |
<div class="input-field col s12 m6">
|
274 |
<input type="text" name="remote_mysql_pass" id="remote_mysql_pass" class="validate"
|
275 |
placeholder="Target Mysql Password">
|
276 |
+
<label><?php echo __("Target Mysql Password", 'xcloner-backup-and-restore') ?></label>
|
277 |
</div>
|
278 |
|
279 |
</div>
|
280 |
<div class="col s12">
|
281 |
<a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50"
|
282 |
data-html="true"
|
283 |
+
data-tooltip="<?php echo __('I will attempt to replace all mysql backup records matching the provided Source Url with the provided Target Url. <br />Leave blank the Target Url if you would like to skip this option. <br />As a bonus, I will also replace all matching serialized data and fix it\'s parsing.', 'xcloner-backup-and-restore') ?>"
|
284 |
data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
|
285 |
+
<h5><?php echo __('Target Mysql Search and Replace', 'xcloner-backup-and-restore') ?></h5>
|
286 |
</div>
|
287 |
<div class="col s12">
|
288 |
<div class="input-field col s12 m6 ">
|
289 |
<input type="text" name="wp_home_url" id="wp_home_url" class="validate"
|
290 |
placeholder="WP Home Url" value="<?php echo home_url(); ?>">
|
291 |
+
<label><?php echo __("Source Home Url", 'xcloner-backup-and-restore') ?></label>
|
292 |
</div>
|
293 |
|
294 |
<div class="input-field col s12 m6 ">
|
295 |
<input type="text" name="remote_restore_url" id="remote_restore_url" class="validate"
|
296 |
placeholder="Restore Target Url">
|
297 |
+
<label><?php echo __("With Target Home Url", 'xcloner-backup-and-restore') ?></label>
|
298 |
</div>
|
299 |
|
300 |
+
<?php if (site_url() != home_url()) : ?>
|
301 |
<div class="input-field col s12 m6 ">
|
302 |
<input type="text" name="wp_site_url" id="wp_site_url" class="validate"
|
303 |
placeholder="WP Site Url" value="<?php echo site_url(); ?>">
|
304 |
+
<label><?php echo __("Source Site Url", 'xcloner-backup-and-restore') ?></label>
|
305 |
</div>
|
306 |
|
307 |
<div class="input-field col s12 m6 ">
|
308 |
<input type="text" name="remote_restore_site_url" id="remote_restore_site_url"
|
309 |
class="validate" placeholder="Restore Target Url">
|
310 |
+
<label><?php echo __("With Target Site Url", 'xcloner-backup-and-restore') ?></label>
|
311 |
</div>
|
312 |
|
313 |
<?php endif; ?>
|
319 |
<div class="input-field row">
|
320 |
<select id="remote_database_file" name="remote_database_file" class="browser-default">
|
321 |
<option value="" disabled
|
322 |
+
selected><?php echo __("Please select the target database backup file to restore", 'xcloner-backup-and-restore') ?></option>
|
323 |
</select>
|
324 |
|
325 |
<label></label>
|
331 |
|
332 |
<div class="status"></div>
|
333 |
<div class="query-box">
|
334 |
+
<h6><?php echo __('Use the field below to fix your mysql query and Retry again the Restore, or replace with # to Skip next', 'xcloner-backup-and-restore') ?></h6>
|
335 |
<textarea class="query-list" cols="5"></textarea>
|
336 |
</div>
|
337 |
</div>
|
339 |
<div class="col s12 l5 right-align">
|
340 |
<div class="toggler">
|
341 |
<button class="btn waves-effect waves-light restore_remote_mysqldump normal " type="submit"
|
342 |
+
id="" name="action"><?php echo __("Restore", 'xcloner-backup-and-restore') ?>
|
343 |
<i class="material-icons left">navigate_before</i>
|
344 |
</button>
|
345 |
<button class="btn waves-effect waves-light red restore_remote_mysqldump cancel"
|
346 |
type="submit" id=""
|
347 |
+
name="action"><?php echo __("Cancel", 'xcloner-backup-and-restore') ?>
|
348 |
<i class="material-icons right">close</i>
|
349 |
</button>
|
350 |
</div>
|
351 |
|
352 |
<button class="btn waves-effect waves-light grey" type="submit"
|
353 |
+
title="<?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>"
|
354 |
id="skip_restore_remote_database_step"
|
355 |
+
name="action"><?php echo __("Skip Next", 'xcloner-backup-and-restore') ?>
|
356 |
<i class="material-icons right">navigate_next</i>
|
357 |
</button>
|
358 |
|
363 |
|
364 |
<li data-step="5" class="restore-finish-step steps active">
|
365 |
<div class="collapsible-header"><i
|
366 |
+
class="material-icons">folder_open</i><?php echo __("Finishing up...", 'xcloner-backup-and-restore') ?>
|
367 |
</div>
|
368 |
<div class="collapsible-body row">
|
369 |
|
370 |
<div class="row">
|
371 |
<div class="col s4">
|
372 |
+
<label><?php echo __("Update wp-config.php mysql details and update the Target Site Url", 'xcloner-backup-and-restore') ?></label>
|
373 |
</div>
|
374 |
|
375 |
<div class="col s8">
|
387 |
|
388 |
<div class="row">
|
389 |
<div class="col s4">
|
390 |
+
<label><?php echo __("Delete Restored Backup Temporary Folder", 'xcloner-backup-and-restore') ?></label>
|
391 |
</div>
|
392 |
<div class="col s8">
|
393 |
<div class="switch">
|
404 |
|
405 |
<div class="row">
|
406 |
<div class="col s4">
|
407 |
+
<label><?php echo __("Delete Restore Script", 'xcloner-backup-and-restore') ?></label>
|
408 |
</div>
|
409 |
<div class="col s8">
|
410 |
<div class="switch">
|
424 |
</div>
|
425 |
|
426 |
<div class=" row col s12 center-align" id="xcloner_restore_finish">
|
427 |
+
<h5><?php echo __("Thank you for using XCloner.", 'xcloner-backup-and-restore') ?></h5>
|
428 |
+
<h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'), '<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore" target="_blank">Wordpress XCloner forums</a>') ?></h6>
|
429 |
<a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow
|
430 |
@thinkovi</a>
|
431 |
<script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
|
435 |
<div class="row">
|
436 |
<div class="col s6 right-align">
|
437 |
<button class="btn waves-effect waves-light teal" type="submit" id="restore_finish"
|
438 |
+
name="action"><?php echo __("Finish", 'xcloner-backup-and-restore') ?>
|
439 |
<i class="material-icons right">navigate_next</i>
|
440 |
</button>
|
441 |
</div>
|
442 |
|
443 |
<div id="open_target_site" class="col s6 left-align">
|
444 |
<a disabled="disabled" href="#" class="btn waves-effect waves-light teal" type="button"
|
445 |
+
target="_blank"><?php echo __("Open Target Site", 'xcloner-backup-and-restore') ?>
|
446 |
<i class="material-icons right">navigate_next</i>
|
447 |
</a>
|
448 |
</div>
|
459 |
<!-- List Backup Content Modal-->
|
460 |
<div id="backup_cotent_modal" class="modal">
|
461 |
<div class="modal-content">
|
462 |
+
<h4><?php echo sprintf(__("Listing Backup Content ", 'xcloner-backup-and-restore'), "") ?></h4>
|
463 |
<h5 class="backup-name"></h5>
|
464 |
|
465 |
<div class="progress">
|
admin/partials/xcloner_scheduled_backups_page.php
CHANGED
@@ -4,10 +4,10 @@ $xcloner_scheduler = $this->get_xcloner_container()->get_xcloner_scheduler();
|
|
4 |
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
5 |
$available_storages = $xcloner_remote_storage->get_available_storages();
|
6 |
?>
|
7 |
-
<?php if (
|
8 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
9 |
<p><strong>
|
10 |
-
<?php echo sprintf(
|
11 |
</strong>
|
12 |
</p>
|
13 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
@@ -15,32 +15,32 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
15 |
</div>
|
16 |
<?php endif ?>
|
17 |
|
18 |
-
<h1><?= esc_html(
|
19 |
|
20 |
<div class="row">
|
21 |
<table id="scheduled_backups" class="col s12" cellspacing="0" width="100%">
|
22 |
<thead>
|
23 |
<tr class="grey lighten-2">
|
24 |
-
<th><?php echo __(
|
25 |
-
<th><?php echo __(
|
26 |
-
<th><?php echo __(
|
27 |
-
<th class="hide-on-med-and-down"><?php echo __(
|
28 |
-
<th><?php echo __(
|
29 |
-
<th class="hide-on-med-and-down"><?php echo __(
|
30 |
-
<th><?php echo __(
|
31 |
-
<th class="no-sort"><?php echo __(
|
32 |
</tr>
|
33 |
</thead>
|
34 |
<tfoot>
|
35 |
<tr>
|
36 |
-
<th><?php echo __(
|
37 |
-
<th><?php echo __(
|
38 |
-
<th><?php echo __(
|
39 |
-
<th class="hide-on-med-and-down"><?php echo __(
|
40 |
-
<th><?php echo __(
|
41 |
-
<th class="hide-on-med-and-down"><?php echo __(
|
42 |
-
<th><?php echo __(
|
43 |
-
<th><?php echo __(
|
44 |
</tr>
|
45 |
</tfoot>
|
46 |
<tbody>
|
@@ -50,8 +50,8 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
50 |
|
51 |
<div class="row">
|
52 |
<div class="col s12 m6 offset-m6 teal lighten-1" id="server_time">
|
53 |
-
<h2><?php echo __(
|
54 |
-
class="right"><?php echo current_time(
|
55 |
</div>
|
56 |
</div>
|
57 |
|
@@ -65,17 +65,17 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
65 |
|
66 |
<div class="row">
|
67 |
<div class="col s12 m6">
|
68 |
-
<h4><?php echo __(
|
69 |
id="schedule_id"></span></h4>
|
70 |
</div>
|
71 |
|
72 |
<div class="col s12 m6 right-align">
|
73 |
<div class="switch">
|
74 |
<label>
|
75 |
-
<?php echo __(
|
76 |
<input type="checkbox" id="status" name="status" value="1">
|
77 |
<span class="lever"></span>
|
78 |
-
<?php echo __(
|
79 |
</label>
|
80 |
</div>
|
81 |
</div>
|
@@ -85,27 +85,38 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
85 |
|
86 |
<ul class="nav-tab-wrapper content row">
|
87 |
<li><a href="#scheduler_settings"
|
88 |
-
class="nav-tab col s12 m6 nav-tab-active"><?php echo __(
|
89 |
</li>
|
90 |
<li><a href="#advanced_scheduler_settings"
|
91 |
-
class="nav-tab col s12 m6"><?php echo __(
|
92 |
</ul>
|
93 |
|
94 |
<div class="nav-tab-wrapper-content">
|
95 |
<div id="scheduler_settings" class="tab-content active">
|
96 |
|
97 |
<div class="row">
|
98 |
-
<div class="input-field col s12">
|
99 |
<input placeholder="" name="schedule_name" id="schedule_name" type="text" required value="">
|
100 |
-
<label for="schedule_name"><?php echo __(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
</div>
|
102 |
<!--<div class="input-field inline col s12 l6">
|
103 |
<select id="backup_type" class="" name="backup_type" id="backup_type">
|
104 |
-
<option value=""><?php echo __(
|
105 |
-
<option value="diff"><?php echo __(
|
106 |
-
<option value="full_diff"><?php echo __(
|
107 |
</select>
|
108 |
-
<label for="backup_type"><?php echo __(
|
109 |
</div>-->
|
110 |
</div>
|
111 |
|
@@ -114,18 +125,18 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
114 |
<input placeholder="" name="schedule_start_date" id="schedule_start_date" type="datetime"
|
115 |
value="">
|
116 |
<label for="schedule_start_date"
|
117 |
-
class="active"><?php echo __(
|
118 |
:</label>
|
119 |
</div>
|
120 |
|
121 |
<div class="input-field col s12 l6">
|
122 |
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
123 |
<option value="" disabled
|
124 |
-
selected><?php echo __(
|
125 |
<?php
|
126 |
$schedules = $xcloner_scheduler->get_available_intervals();
|
127 |
|
128 |
-
foreach (
|
129 |
?>
|
130 |
<option value="<?php echo $key ?>"><?php echo $schedule['display'] ?></option>
|
131 |
<?php
|
@@ -135,17 +146,17 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
135 |
</div>
|
136 |
</div>
|
137 |
|
138 |
-
<?php if (
|
139 |
<div class="row">
|
140 |
<div class="input-field col s12 l12">
|
141 |
<select name="schedule_storage" id="schedule_storage" class="validate">
|
142 |
<option value=""
|
143 |
-
selected><?php echo __(
|
144 |
-
<?php foreach (
|
145 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
146 |
<?php endforeach ?>
|
147 |
</select>
|
148 |
-
<label><?php echo __(
|
149 |
</div>
|
150 |
</div>
|
151 |
<?php endif ?>
|
@@ -154,7 +165,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
154 |
<div class="input-field col s12 l12">
|
155 |
<input placeholder="" name="email_notification" id="email_notification" type="text"
|
156 |
value="">
|
157 |
-
<label for="email_notification"><?php echo __(
|
158 |
</div>
|
159 |
</div>
|
160 |
|
@@ -162,7 +173,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
162 |
<div class="input-field col s12 l12">
|
163 |
<input placeholder="" name="diff_start_date" id="diff_start_date" type="text"
|
164 |
class="datepicker_max_today" value="">
|
165 |
-
<label for="diff_start_date"><?php echo __(
|
166 |
</div>
|
167 |
</div>
|
168 |
</div>
|
@@ -171,7 +182,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
171 |
<div class="row">
|
172 |
<div class="input-field col s12 l12">
|
173 |
<input placeholder="" name="backup_name" id="backup_name" type="text" required value="">
|
174 |
-
<label for="backup_name"><?php echo __(
|
175 |
</div>
|
176 |
</div>
|
177 |
|
@@ -180,7 +191,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
180 |
<textarea id="table_params" name="table_params" class="materialize-textarea"
|
181 |
rows="15"></textarea>
|
182 |
<label for="table_params"
|
183 |
-
class="active"><?php echo __(
|
184 |
</div>
|
185 |
</div>
|
186 |
|
@@ -189,7 +200,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
189 |
<textarea id="excluded_files" name="excluded_files" class="materialize-textarea"
|
190 |
rows="15"></textarea>
|
191 |
<label for="excluded_files"
|
192 |
-
class="active"><?php echo __(
|
193 |
</div>
|
194 |
</div>
|
195 |
</div>
|
@@ -199,7 +210,7 @@ $available_storages = $xcloner_remote_storage->get_available_storages();
|
|
199 |
|
200 |
<div class="input-field col s12 ">
|
201 |
<button class="right btn waves-effect waves-light" type="submit"
|
202 |
-
name="action"><?php echo __(
|
203 |
<i class="material-icons right">send</i>
|
204 |
</button>
|
205 |
</div>
|
4 |
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
5 |
$available_storages = $xcloner_remote_storage->get_available_storages();
|
6 |
?>
|
7 |
+
<?php if (!defined("DISABLE_WP_CRON") || !DISABLE_WP_CRON): ?>
|
8 |
<div id="setting-error-" class="error settings-error notice is-dismissible">
|
9 |
<p><strong>
|
10 |
+
<?php echo sprintf(__('We have noticed that DISABLE_WP_CRON is disabled, we recommend enabling that and setting up wp-cron.php to run manually through your hosting account scheduler as explained <a href="%s" target="_blank">here</a>', 'xcloner-backup-and-restore'), "http://www.inmotionhosting.com/support/website/wordpress/disabling-the-wp-cronphp-in-wordpress") ?>
|
11 |
</strong>
|
12 |
</p>
|
13 |
<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span>
|
15 |
</div>
|
16 |
<?php endif ?>
|
17 |
|
18 |
+
<h1><?= esc_html(get_admin_page_title()); ?></h1>
|
19 |
|
20 |
<div class="row">
|
21 |
<table id="scheduled_backups" class="col s12" cellspacing="0" width="100%">
|
22 |
<thead>
|
23 |
<tr class="grey lighten-2">
|
24 |
+
<th><?php echo __('ID', 'xcloner-backup-and-restore') ?></th>
|
25 |
+
<th><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></th>
|
26 |
+
<th><?php echo __('Recurrence', 'xcloner-backup-and-restore') ?></th>
|
27 |
+
<th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore') ?></th>
|
28 |
+
<th><?php echo __('Remote Storage', 'xcloner-backup-and-restore') ?></th>
|
29 |
+
<th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore') ?></th>
|
30 |
+
<th><?php echo __('Status', 'xcloner-backup-and-restore') ?></th>
|
31 |
+
<th class="no-sort"><?php echo __('Action', 'xcloner-backup-and-restore') ?></th>
|
32 |
</tr>
|
33 |
</thead>
|
34 |
<tfoot>
|
35 |
<tr>
|
36 |
+
<th><?php echo __('ID', 'xcloner-backup-and-restore') ?></th>
|
37 |
+
<th><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></th>
|
38 |
+
<th><?php echo __('Recurrence', 'xcloner-backup-and-restore') ?></th>
|
39 |
+
<th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore') ?></th>
|
40 |
+
<th><?php echo __('Remote Storage', 'xcloner-backup-and-restore') ?></th>
|
41 |
+
<th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore') ?></th>
|
42 |
+
<th><?php echo __('Status', 'xcloner-backup-and-restore') ?></th>
|
43 |
+
<th><?php echo __('Action', 'xcloner-backup-and-restore') ?></th>
|
44 |
</tr>
|
45 |
</tfoot>
|
46 |
<tbody>
|
50 |
|
51 |
<div class="row">
|
52 |
<div class="col s12 m6 offset-m6 teal lighten-1" id="server_time">
|
53 |
+
<h2><?php echo __('Current Server Time', 'xcloner-backup-and-restore') ?>: <span
|
54 |
+
class="right"><?php echo current_time('mysql'); ?></span></h2>
|
55 |
</div>
|
56 |
</div>
|
57 |
|
65 |
|
66 |
<div class="row">
|
67 |
<div class="col s12 m6">
|
68 |
+
<h4><?php echo __('Edit Schedule', 'xcloner-backup-and-restore') ?> #<span
|
69 |
id="schedule_id"></span></h4>
|
70 |
</div>
|
71 |
|
72 |
<div class="col s12 m6 right-align">
|
73 |
<div class="switch">
|
74 |
<label>
|
75 |
+
<?php echo __('Off', 'xcloner-backup-and-restore') ?>
|
76 |
<input type="checkbox" id="status" name="status" value="1">
|
77 |
<span class="lever"></span>
|
78 |
+
<?php echo __('On', 'xcloner-backup-and-restore') ?>
|
79 |
</label>
|
80 |
</div>
|
81 |
</div>
|
85 |
|
86 |
<ul class="nav-tab-wrapper content row">
|
87 |
<li><a href="#scheduler_settings"
|
88 |
+
class="nav-tab col s12 m6 nav-tab-active"><?php echo __('Scheduler Settings', 'xcloner-backup-and-restore') ?></a>
|
89 |
</li>
|
90 |
<li><a href="#advanced_scheduler_settings"
|
91 |
+
class="nav-tab col s12 m6"><?php echo __('Advanced', 'xcloner-backup-and-restore') ?></a></li>
|
92 |
</ul>
|
93 |
|
94 |
<div class="nav-tab-wrapper-content">
|
95 |
<div id="scheduler_settings" class="tab-content active">
|
96 |
|
97 |
<div class="row">
|
98 |
+
<div class="input-field col s12 l6">
|
99 |
<input placeholder="" name="schedule_name" id="schedule_name" type="text" required value="">
|
100 |
+
<label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
|
101 |
+
</div>
|
102 |
+
<div class="input-field col s12 l6">
|
103 |
+
<div class="switch">
|
104 |
+
<label>
|
105 |
+
Off
|
106 |
+
<input type="checkbox" name="backup_encrypt" id="backup_encrypt" value="1">
|
107 |
+
<span class="lever"></span>
|
108 |
+
On
|
109 |
+
</label>
|
110 |
+
</div>
|
111 |
+
<label style="top:-0.8em">Encrypt Backup</label>
|
112 |
</div>
|
113 |
<!--<div class="input-field inline col s12 l6">
|
114 |
<select id="backup_type" class="" name="backup_type" id="backup_type">
|
115 |
+
<option value=""><?php echo __("Full Backup", "xcloner-backup-and-restore"); ?></option>
|
116 |
+
<option value="diff"><?php echo __("Differential Backups", "xcloner-backup-and-restore"); ?></option>
|
117 |
+
<option value="full_diff"><?php echo __("Full Backup + Differential Backups", "xcloner-backup-and-restore"); ?></option>
|
118 |
</select>
|
119 |
+
<label for="backup_type"><?php echo __('Scheduled Backup Type', 'xcloner-backup-and-restore') ?></label>
|
120 |
</div>-->
|
121 |
</div>
|
122 |
|
125 |
<input placeholder="" name="schedule_start_date" id="schedule_start_date" type="datetime"
|
126 |
value="">
|
127 |
<label for="schedule_start_date"
|
128 |
+
class="active"><?php echo __('Schedule Start At', 'xcloner-backup-and-restore') ?>
|
129 |
:</label>
|
130 |
</div>
|
131 |
|
132 |
<div class="input-field col s12 l6">
|
133 |
<select name="schedule_frequency" id="schedule_frequency" class="validate" required>
|
134 |
<option value="" disabled
|
135 |
+
selected><?php echo __('Schedule Recurrence', 'xcloner-backup-and-restore') ?></option>
|
136 |
<?php
|
137 |
$schedules = $xcloner_scheduler->get_available_intervals();
|
138 |
|
139 |
+
foreach ($schedules as $key => $schedule) {
|
140 |
?>
|
141 |
<option value="<?php echo $key ?>"><?php echo $schedule['display'] ?></option>
|
142 |
<?php
|
146 |
</div>
|
147 |
</div>
|
148 |
|
149 |
+
<?php if (sizeof($available_storages)): ?>
|
150 |
<div class="row">
|
151 |
<div class="input-field col s12 l12">
|
152 |
<select name="schedule_storage" id="schedule_storage" class="validate">
|
153 |
<option value=""
|
154 |
+
selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
|
155 |
+
<?php foreach ($available_storages as $storage => $text): ?>
|
156 |
<option value="<?php echo $storage ?>"><?php echo $text ?></option>
|
157 |
<?php endforeach ?>
|
158 |
</select>
|
159 |
+
<label><?php echo __('Send To Remote Storage ', 'xcloner-backup-and-restore') ?></label>
|
160 |
</div>
|
161 |
</div>
|
162 |
<?php endif ?>
|
165 |
<div class="input-field col s12 l12">
|
166 |
<input placeholder="" name="email_notification" id="email_notification" type="text"
|
167 |
value="">
|
168 |
+
<label for="email_notification"><?php echo __('Email Notification Address', 'xcloner-backup-and-restore') ?></label>
|
169 |
</div>
|
170 |
</div>
|
171 |
|
173 |
<div class="input-field col s12 l12">
|
174 |
<input placeholder="" name="diff_start_date" id="diff_start_date" type="text"
|
175 |
class="datepicker_max_today" value="">
|
176 |
+
<label for="diff_start_date"><?php echo __('Backup Only Files Modified/Created After', 'xcloner-backup-and-restore') ?></label>
|
177 |
</div>
|
178 |
</div>
|
179 |
</div>
|
182 |
<div class="row">
|
183 |
<div class="input-field col s12 l12">
|
184 |
<input placeholder="" name="backup_name" id="backup_name" type="text" required value="">
|
185 |
+
<label for="backup_name"><?php echo __('Backup Name', 'xcloner-backup-and-restore') ?></label>
|
186 |
</div>
|
187 |
</div>
|
188 |
|
191 |
<textarea id="table_params" name="table_params" class="materialize-textarea"
|
192 |
rows="15"></textarea>
|
193 |
<label for="table_params"
|
194 |
+
class="active"><?php echo __('Included Database Data', 'xcloner-backup-and-restore') ?></label>
|
195 |
</div>
|
196 |
</div>
|
197 |
|
200 |
<textarea id="excluded_files" name="excluded_files" class="materialize-textarea"
|
201 |
rows="15"></textarea>
|
202 |
<label for="excluded_files"
|
203 |
+
class="active"><?php echo __('Excluded Files', 'xcloner-backup-and-restore') ?></label>
|
204 |
</div>
|
205 |
</div>
|
206 |
</div>
|
210 |
|
211 |
<div class="input-field col s12 ">
|
212 |
<button class="right btn waves-effect waves-light" type="submit"
|
213 |
+
name="action"><?php echo __('Save', 'xcloner-backup-and-restore') ?>
|
214 |
<i class="material-icons right">send</i>
|
215 |
</button>
|
216 |
</div>
|
composer.json
CHANGED
@@ -9,8 +9,9 @@
|
|
9 |
"league/flysystem-aws-s3-v3": "^1.0",
|
10 |
"mhetreramesh/flysystem-backblaze": "^1.0",
|
11 |
"league/flysystem-webdav": "^1.0",
|
12 |
-
"srmklive/flysystem-dropbox-v2": "^1.0"
|
13 |
-
"defuse/php-encryption": "^2.2"
|
14 |
},
|
15 |
-
"prefer-stable": true
|
|
|
|
|
16 |
}
|
9 |
"league/flysystem-aws-s3-v3": "^1.0",
|
10 |
"mhetreramesh/flysystem-backblaze": "^1.0",
|
11 |
"league/flysystem-webdav": "^1.0",
|
12 |
+
"srmklive/flysystem-dropbox-v2": "^1.0"
|
|
|
13 |
},
|
14 |
+
"prefer-stable": true,
|
15 |
+
"require-dev": {
|
16 |
+
}
|
17 |
}
|
composer.lock
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
-
"content-hash": "
|
8 |
"packages": [
|
9 |
{
|
10 |
"name": "aws/aws-sdk-php",
|
@@ -128,69 +128,6 @@
|
|
128 |
"homepage": "http://jquery.com",
|
129 |
"time": "2018-03-04T13:23:48+00:00"
|
130 |
},
|
131 |
-
{
|
132 |
-
"name": "defuse/php-encryption",
|
133 |
-
"version": "v2.2.0",
|
134 |
-
"source": {
|
135 |
-
"type": "git",
|
136 |
-
"url": "https://github.com/defuse/php-encryption.git",
|
137 |
-
"reference": "0d4d27c368ca6798bc162469e43248c363c73495"
|
138 |
-
},
|
139 |
-
"dist": {
|
140 |
-
"type": "zip",
|
141 |
-
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/0d4d27c368ca6798bc162469e43248c363c73495",
|
142 |
-
"reference": "0d4d27c368ca6798bc162469e43248c363c73495",
|
143 |
-
"shasum": ""
|
144 |
-
},
|
145 |
-
"require": {
|
146 |
-
"ext-openssl": "*",
|
147 |
-
"paragonie/random_compat": "~2.0",
|
148 |
-
"php": ">=5.4.0"
|
149 |
-
},
|
150 |
-
"require-dev": {
|
151 |
-
"nikic/php-parser": "^2.0|^3.0|^4.0",
|
152 |
-
"phpunit/phpunit": "^4|^5"
|
153 |
-
},
|
154 |
-
"bin": [
|
155 |
-
"bin/generate-defuse-key"
|
156 |
-
],
|
157 |
-
"type": "library",
|
158 |
-
"autoload": {
|
159 |
-
"psr-4": {
|
160 |
-
"Defuse\\Crypto\\": "src"
|
161 |
-
}
|
162 |
-
},
|
163 |
-
"notification-url": "https://packagist.org/downloads/",
|
164 |
-
"license": [
|
165 |
-
"MIT"
|
166 |
-
],
|
167 |
-
"authors": [
|
168 |
-
{
|
169 |
-
"name": "Taylor Hornby",
|
170 |
-
"email": "taylor@defuse.ca",
|
171 |
-
"homepage": "https://defuse.ca/"
|
172 |
-
},
|
173 |
-
{
|
174 |
-
"name": "Scott Arciszewski",
|
175 |
-
"email": "info@paragonie.com",
|
176 |
-
"homepage": "https://paragonie.com"
|
177 |
-
}
|
178 |
-
],
|
179 |
-
"description": "Secure PHP Encryption Library",
|
180 |
-
"keywords": [
|
181 |
-
"aes",
|
182 |
-
"authenticated encryption",
|
183 |
-
"cipher",
|
184 |
-
"crypto",
|
185 |
-
"cryptography",
|
186 |
-
"encrypt",
|
187 |
-
"encryption",
|
188 |
-
"openssl",
|
189 |
-
"security",
|
190 |
-
"symmetric key cryptography"
|
191 |
-
],
|
192 |
-
"time": "2018-04-23T19:33:40+00:00"
|
193 |
-
},
|
194 |
{
|
195 |
"name": "gliterd/backblaze-b2",
|
196 |
"version": "1.0.4",
|
@@ -428,28 +365,28 @@
|
|
428 |
},
|
429 |
{
|
430 |
"name": "league/flysystem",
|
431 |
-
"version": "1.0.
|
432 |
"source": {
|
433 |
"type": "git",
|
434 |
"url": "https://github.com/thephpleague/flysystem.git",
|
435 |
-
"reference": "
|
436 |
},
|
437 |
"dist": {
|
438 |
"type": "zip",
|
439 |
-
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/
|
440 |
-
"reference": "
|
441 |
"shasum": ""
|
442 |
},
|
443 |
"require": {
|
|
|
444 |
"php": ">=5.5.9"
|
445 |
},
|
446 |
"conflict": {
|
447 |
"league/flysystem-sftp": "<1.0.6"
|
448 |
},
|
449 |
"require-dev": {
|
450 |
-
"ext-fileinfo": "*",
|
451 |
"phpspec/phpspec": "^3.4",
|
452 |
-
"phpunit/phpunit": "^5.7"
|
453 |
},
|
454 |
"suggest": {
|
455 |
"ext-fileinfo": "Required for MimeType",
|
@@ -508,7 +445,7 @@
|
|
508 |
"sftp",
|
509 |
"storage"
|
510 |
],
|
511 |
-
"time": "2018-
|
512 |
},
|
513 |
{
|
514 |
"name": "league/flysystem-aws-s3-v3",
|
@@ -607,33 +544,28 @@
|
|
607 |
},
|
608 |
{
|
609 |
"name": "league/flysystem-sftp",
|
610 |
-
"version": "1.0.
|
611 |
"source": {
|
612 |
"type": "git",
|
613 |
"url": "https://github.com/thephpleague/flysystem-sftp.git",
|
614 |
-
"reference": "
|
615 |
},
|
616 |
"dist": {
|
617 |
"type": "zip",
|
618 |
-
"url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/
|
619 |
-
"reference": "
|
620 |
"shasum": ""
|
621 |
},
|
622 |
"require": {
|
623 |
"league/flysystem": "~1.0",
|
624 |
-
"php": ">=5.
|
625 |
"phpseclib/phpseclib": "~2.0"
|
626 |
},
|
627 |
"require-dev": {
|
628 |
"mockery/mockery": "0.9.*",
|
629 |
-
"phpunit/phpunit": "
|
630 |
},
|
631 |
"type": "library",
|
632 |
-
"extra": {
|
633 |
-
"branch-alias": {
|
634 |
-
"dev-master": "1.0-dev"
|
635 |
-
}
|
636 |
-
},
|
637 |
"autoload": {
|
638 |
"psr-4": {
|
639 |
"League\\Flysystem\\Sftp\\": "src/"
|
@@ -650,7 +582,7 @@
|
|
650 |
}
|
651 |
],
|
652 |
"description": "Flysystem adapter for SFTP",
|
653 |
-
"time": "
|
654 |
},
|
655 |
{
|
656 |
"name": "league/flysystem-webdav",
|
@@ -992,55 +924,6 @@
|
|
992 |
],
|
993 |
"time": "2016-12-03T22:08:25+00:00"
|
994 |
},
|
995 |
-
{
|
996 |
-
"name": "paragonie/random_compat",
|
997 |
-
"version": "v2.0.15",
|
998 |
-
"source": {
|
999 |
-
"type": "git",
|
1000 |
-
"url": "https://github.com/paragonie/random_compat.git",
|
1001 |
-
"reference": "10bcb46e8f3d365170f6de9d05245aa066b81f09"
|
1002 |
-
},
|
1003 |
-
"dist": {
|
1004 |
-
"type": "zip",
|
1005 |
-
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/10bcb46e8f3d365170f6de9d05245aa066b81f09",
|
1006 |
-
"reference": "10bcb46e8f3d365170f6de9d05245aa066b81f09",
|
1007 |
-
"shasum": ""
|
1008 |
-
},
|
1009 |
-
"require": {
|
1010 |
-
"php": ">=5.2.0"
|
1011 |
-
},
|
1012 |
-
"require-dev": {
|
1013 |
-
"phpunit/phpunit": "4.*|5.*"
|
1014 |
-
},
|
1015 |
-
"suggest": {
|
1016 |
-
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
1017 |
-
},
|
1018 |
-
"type": "library",
|
1019 |
-
"autoload": {
|
1020 |
-
"files": [
|
1021 |
-
"lib/random.php"
|
1022 |
-
]
|
1023 |
-
},
|
1024 |
-
"notification-url": "https://packagist.org/downloads/",
|
1025 |
-
"license": [
|
1026 |
-
"MIT"
|
1027 |
-
],
|
1028 |
-
"authors": [
|
1029 |
-
{
|
1030 |
-
"name": "Paragon Initiative Enterprises",
|
1031 |
-
"email": "security@paragonie.com",
|
1032 |
-
"homepage": "https://paragonie.com"
|
1033 |
-
}
|
1034 |
-
],
|
1035 |
-
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
1036 |
-
"keywords": [
|
1037 |
-
"csprng",
|
1038 |
-
"polyfill",
|
1039 |
-
"pseudorandom",
|
1040 |
-
"random"
|
1041 |
-
],
|
1042 |
-
"time": "2018-06-08T15:26:40+00:00"
|
1043 |
-
},
|
1044 |
{
|
1045 |
"name": "phpseclib/phpseclib",
|
1046 |
"version": "2.0.11",
|
@@ -1742,16 +1625,16 @@
|
|
1742 |
},
|
1743 |
{
|
1744 |
"name": "vakata/jstree",
|
1745 |
-
"version": "3.3.
|
1746 |
"source": {
|
1747 |
"type": "git",
|
1748 |
"url": "https://github.com/vakata/jstree.git",
|
1749 |
-
"reference": "
|
1750 |
},
|
1751 |
"dist": {
|
1752 |
"type": "zip",
|
1753 |
-
"url": "https://api.github.com/repos/vakata/jstree/zipball/
|
1754 |
-
"reference": "
|
1755 |
"shasum": ""
|
1756 |
},
|
1757 |
"require": {
|
@@ -1795,7 +1678,7 @@
|
|
1795 |
],
|
1796 |
"description": "jsTree is jquery plugin, that provides interactive trees.",
|
1797 |
"homepage": "http://jstree.com",
|
1798 |
-
"time": "2018-
|
1799 |
}
|
1800 |
],
|
1801 |
"packages-dev": [],
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
+
"content-hash": "e32ba7a3036306157c1f3563665aec57",
|
8 |
"packages": [
|
9 |
{
|
10 |
"name": "aws/aws-sdk-php",
|
128 |
"homepage": "http://jquery.com",
|
129 |
"time": "2018-03-04T13:23:48+00:00"
|
130 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
{
|
132 |
"name": "gliterd/backblaze-b2",
|
133 |
"version": "1.0.4",
|
365 |
},
|
366 |
{
|
367 |
"name": "league/flysystem",
|
368 |
+
"version": "1.0.49",
|
369 |
"source": {
|
370 |
"type": "git",
|
371 |
"url": "https://github.com/thephpleague/flysystem.git",
|
372 |
+
"reference": "a63cc83d8a931b271be45148fa39ba7156782ffd"
|
373 |
},
|
374 |
"dist": {
|
375 |
"type": "zip",
|
376 |
+
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a63cc83d8a931b271be45148fa39ba7156782ffd",
|
377 |
+
"reference": "a63cc83d8a931b271be45148fa39ba7156782ffd",
|
378 |
"shasum": ""
|
379 |
},
|
380 |
"require": {
|
381 |
+
"ext-fileinfo": "*",
|
382 |
"php": ">=5.5.9"
|
383 |
},
|
384 |
"conflict": {
|
385 |
"league/flysystem-sftp": "<1.0.6"
|
386 |
},
|
387 |
"require-dev": {
|
|
|
388 |
"phpspec/phpspec": "^3.4",
|
389 |
+
"phpunit/phpunit": "^5.7.10"
|
390 |
},
|
391 |
"suggest": {
|
392 |
"ext-fileinfo": "Required for MimeType",
|
445 |
"sftp",
|
446 |
"storage"
|
447 |
],
|
448 |
+
"time": "2018-11-23T23:41:29+00:00"
|
449 |
},
|
450 |
{
|
451 |
"name": "league/flysystem-aws-s3-v3",
|
544 |
},
|
545 |
{
|
546 |
"name": "league/flysystem-sftp",
|
547 |
+
"version": "1.0.18",
|
548 |
"source": {
|
549 |
"type": "git",
|
550 |
"url": "https://github.com/thephpleague/flysystem-sftp.git",
|
551 |
+
"reference": "61bc5a6ade892b5ac81e62b8c21be2c1798acc2a"
|
552 |
},
|
553 |
"dist": {
|
554 |
"type": "zip",
|
555 |
+
"url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/61bc5a6ade892b5ac81e62b8c21be2c1798acc2a",
|
556 |
+
"reference": "61bc5a6ade892b5ac81e62b8c21be2c1798acc2a",
|
557 |
"shasum": ""
|
558 |
},
|
559 |
"require": {
|
560 |
"league/flysystem": "~1.0",
|
561 |
+
"php": ">=5.6.0",
|
562 |
"phpseclib/phpseclib": "~2.0"
|
563 |
},
|
564 |
"require-dev": {
|
565 |
"mockery/mockery": "0.9.*",
|
566 |
+
"phpunit/phpunit": "^5.7.25"
|
567 |
},
|
568 |
"type": "library",
|
|
|
|
|
|
|
|
|
|
|
569 |
"autoload": {
|
570 |
"psr-4": {
|
571 |
"League\\Flysystem\\Sftp\\": "src/"
|
582 |
}
|
583 |
],
|
584 |
"description": "Flysystem adapter for SFTP",
|
585 |
+
"time": "2019-01-07T11:56:21+00:00"
|
586 |
},
|
587 |
{
|
588 |
"name": "league/flysystem-webdav",
|
924 |
],
|
925 |
"time": "2016-12-03T22:08:25+00:00"
|
926 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
927 |
{
|
928 |
"name": "phpseclib/phpseclib",
|
929 |
"version": "2.0.11",
|
1625 |
},
|
1626 |
{
|
1627 |
"name": "vakata/jstree",
|
1628 |
+
"version": "3.3.7",
|
1629 |
"source": {
|
1630 |
"type": "git",
|
1631 |
"url": "https://github.com/vakata/jstree.git",
|
1632 |
+
"reference": "bc5187e5826244dee5ebdc0e9db2e2652fefe928"
|
1633 |
},
|
1634 |
"dist": {
|
1635 |
"type": "zip",
|
1636 |
+
"url": "https://api.github.com/repos/vakata/jstree/zipball/bc5187e5826244dee5ebdc0e9db2e2652fefe928",
|
1637 |
+
"reference": "bc5187e5826244dee5ebdc0e9db2e2652fefe928",
|
1638 |
"shasum": ""
|
1639 |
},
|
1640 |
"require": {
|
1678 |
],
|
1679 |
"description": "jsTree is jquery plugin, that provides interactive trees.",
|
1680 |
"homepage": "http://jstree.com",
|
1681 |
+
"time": "2018-11-06T21:15:47+00:00"
|
1682 |
}
|
1683 |
],
|
1684 |
"packages-dev": [],
|
includes/class-xcloner-activator.php
CHANGED
@@ -61,22 +61,22 @@ class Xcloner_Activator {
|
|
61 |
|
62 |
global $wpdb;
|
63 |
|
64 |
-
if (
|
65 |
-
wp_die(
|
66 |
-
|
67 |
-
)
|
68 |
}
|
69 |
|
70 |
$charset_collate = $wpdb->get_charset_collate();
|
71 |
|
72 |
-
$installed_ver = get_option(
|
73 |
|
74 |
$xcloner_db_version = Xcloner_Activator::xcloner_db_version;
|
75 |
|
76 |
-
$xcloner_scheduler_table = $wpdb->prefix
|
77 |
|
78 |
-
if (
|
79 |
-
$xcloner_schedule_sql = "CREATE TABLE `"
|
80 |
`id` int(11) NOT NULL AUTO_INCREMENT,
|
81 |
`name` varchar(255) NOT NULL,
|
82 |
`recurrence` varchar(25) NOT NULL,
|
@@ -87,69 +87,73 @@ class Xcloner_Activator {
|
|
87 |
`status` int(1) NOT NULL,
|
88 |
`last_backup` varchar(100) DEFAULT NULL,
|
89 |
PRIMARY KEY (`id`)
|
90 |
-
) " . $charset_collate
|
91 |
";
|
92 |
|
93 |
-
require_once(
|
94 |
-
dbDelta(
|
95 |
|
96 |
-
update_option(
|
97 |
}
|
98 |
|
99 |
-
if (
|
100 |
-
update_option(
|
101 |
}
|
102 |
|
103 |
-
if (
|
104 |
-
update_option(
|
105 |
}
|
106 |
|
107 |
-
if (
|
108 |
-
update_option(
|
109 |
}
|
110 |
|
111 |
-
if (
|
112 |
-
update_option(
|
113 |
}
|
114 |
|
115 |
-
if (
|
116 |
-
update_option(
|
117 |
}
|
118 |
|
119 |
-
if (
|
120 |
-
update_option(
|
121 |
}
|
122 |
|
123 |
-
if (
|
124 |
-
update_option(
|
125 |
}
|
126 |
|
127 |
-
if (
|
128 |
-
update_option(
|
129 |
}
|
130 |
|
131 |
-
if (
|
132 |
-
update_option(
|
133 |
}
|
134 |
|
135 |
-
if (
|
136 |
-
update_option(
|
137 |
}
|
138 |
|
139 |
-
if (
|
140 |
-
update_option(
|
141 |
}
|
142 |
|
143 |
-
if (
|
144 |
-
update_option(
|
145 |
}
|
146 |
|
147 |
/*if(!get_option('xcloner_diff_backup_recreate_period'))
|
148 |
update_option('xcloner_diff_backup_recreate_period', 10);
|
149 |
* */
|
150 |
|
151 |
-
if (
|
152 |
-
update_option(
|
|
|
|
|
|
|
|
|
153 |
}
|
154 |
|
155 |
}
|
61 |
|
62 |
global $wpdb;
|
63 |
|
64 |
+
if (version_compare(phpversion(), Xcloner_Activator::xcloner_minimum_version, '<')) {
|
65 |
+
wp_die('<p>'.sprintf(__("XCloner requires minimum PHP version %s in order to run correctly. We have detected your version as %s"), Xcloner_Activator::xcloner_minimum_version, phpversion()).'</p>', __("XCloner Activation Error"), array('response' => 500,
|
66 |
+
'back_link' => true
|
67 |
+
));
|
68 |
}
|
69 |
|
70 |
$charset_collate = $wpdb->get_charset_collate();
|
71 |
|
72 |
+
$installed_ver = get_option("xcloner_db_version");
|
73 |
|
74 |
$xcloner_db_version = Xcloner_Activator::xcloner_db_version;
|
75 |
|
76 |
+
$xcloner_scheduler_table = $wpdb->prefix."xcloner_scheduler";
|
77 |
|
78 |
+
if ($installed_ver != $xcloner_db_version) {
|
79 |
+
$xcloner_schedule_sql = "CREATE TABLE `".$xcloner_scheduler_table."` (
|
80 |
`id` int(11) NOT NULL AUTO_INCREMENT,
|
81 |
`name` varchar(255) NOT NULL,
|
82 |
`recurrence` varchar(25) NOT NULL,
|
87 |
`status` int(1) NOT NULL,
|
88 |
`last_backup` varchar(100) DEFAULT NULL,
|
89 |
PRIMARY KEY (`id`)
|
90 |
+
) " . $charset_collate.";
|
91 |
";
|
92 |
|
93 |
+
require_once(ABSPATH.'wp-admin/includes/upgrade.php');
|
94 |
+
dbDelta($xcloner_schedule_sql);
|
95 |
|
96 |
+
update_option("xcloner_db_version", $xcloner_db_version);
|
97 |
}
|
98 |
|
99 |
+
if (get_option('xcloner_backup_compression_level') === false) {
|
100 |
+
update_option('xcloner_backup_compression_level', 0);
|
101 |
}
|
102 |
|
103 |
+
if (get_option('xcloner_enable_log') === false) {
|
104 |
+
update_option('xcloner_enable_log', 1);
|
105 |
}
|
106 |
|
107 |
+
if (get_option('xcloner_enable_mysql_backup') === false) {
|
108 |
+
update_option('xcloner_enable_mysql_backup', 1);
|
109 |
}
|
110 |
|
111 |
+
if (get_option('xcloner_system_settings_page') === false) {
|
112 |
+
update_option('xcloner_system_settings_page', 100);
|
113 |
}
|
114 |
|
115 |
+
if (get_option('xcloner_files_to_process_per_request') === false) {
|
116 |
+
update_option('xcloner_files_to_process_per_request', 250);
|
117 |
}
|
118 |
|
119 |
+
if (get_option('xcloner_database_records_per_request') === false) {
|
120 |
+
update_option('xcloner_database_records_per_request', 10000);
|
121 |
}
|
122 |
|
123 |
+
if (get_option('xcloner_exclude_files_larger_than_mb') === false) {
|
124 |
+
update_option('xcloner_exclude_files_larger_than_mb', 0);
|
125 |
}
|
126 |
|
127 |
+
if (get_option('xcloner_split_backup_limit') === false) {
|
128 |
+
update_option('xcloner_split_backup_limit', 2048);
|
129 |
}
|
130 |
|
131 |
+
if (get_option('xcloner_size_limit_per_request') === false) {
|
132 |
+
update_option('xcloner_size_limit_per_request', 50);
|
133 |
}
|
134 |
|
135 |
+
if (get_option('xcloner_cleanup_retention_limit_days') === false) {
|
136 |
+
update_option('xcloner_cleanup_retention_limit_days', 60);
|
137 |
}
|
138 |
|
139 |
+
if (get_option('xcloner_cleanup_retention_limit_archives') === false) {
|
140 |
+
update_option('xcloner_cleanup_retention_limit_archives', 100);
|
141 |
}
|
142 |
|
143 |
+
if (get_option('xcloner_directories_to_scan_per_request') === false) {
|
144 |
+
update_option('xcloner_directories_to_scan_per_request', 25);
|
145 |
}
|
146 |
|
147 |
/*if(!get_option('xcloner_diff_backup_recreate_period'))
|
148 |
update_option('xcloner_diff_backup_recreate_period', 10);
|
149 |
* */
|
150 |
|
151 |
+
if (!get_option('xcloner_regex_exclude')) {
|
152 |
+
update_option('xcloner_regex_exclude', "(wp-content\/updraft|wp-content\/uploads\/wp_all_backup)(.*)$".PHP_EOL."(.*)\.(svn|git)(.*)$".PHP_EOL."wp-content\/cache(.*)$".PHP_EOL."(.*)error_log$");
|
153 |
+
}
|
154 |
+
|
155 |
+
if (!get_option('xcloner_regex_exclude')) {
|
156 |
+
update_option('xcloner_regex_exclude', "(wp-content\/updraft|wp-content\/uploads\/wp_all_backup)(.*)$".PHP_EOL."(.*)\.(svn|git)(.*)$".PHP_EOL."wp-content\/cache(.*)$".PHP_EOL."(.*)error_log$");
|
157 |
}
|
158 |
|
159 |
}
|
includes/class-xcloner-api.php
CHANGED
@@ -43,905 +43,1249 @@ use splitbrain\PHPArchive\FileInfo;
|
|
43 |
class Xcloner_Api
|
44 |
{
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
149 |
* Save Schedule API
|
150 |
*/
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
|
|
283 |
*
|
284 |
* Backup Files API
|
285 |
*
|
286 |
*/
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
|
|
|
|
|
|
345 |
*
|
346 |
* Backup Database API
|
347 |
*
|
348 |
*/
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
|
353 |
-
|
354 |
|
355 |
-
|
356 |
|
357 |
-
|
358 |
-
die('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
|
359 |
-
}
|
360 |
|
361 |
-
|
|
|
|
|
362 |
|
363 |
-
|
364 |
-
$return = $this->xcloner_database->start_database_recursion($this->form_params['database'],
|
365 |
-
$this->form_params['extra'], $init);
|
366 |
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
$data['finished'] = $return['finished'];
|
371 |
-
}
|
372 |
|
373 |
-
|
|
|
|
|
|
|
|
|
374 |
|
375 |
-
|
376 |
-
}
|
377 |
|
378 |
-
|
|
|
|
|
|
|
379 |
*
|
380 |
* Scan Filesystem API
|
381 |
*
|
382 |
*/
|
383 |
-
|
384 |
-
|
385 |
-
|
|
|
|
|
386 |
|
387 |
-
|
388 |
-
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
|
394 |
-
|
395 |
|
396 |
-
|
397 |
|
398 |
-
|
399 |
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
|
406 |
-
|
407 |
-
|
408 |
|
409 |
-
|
410 |
*
|
411 |
* Process params sent by the user
|
412 |
*
|
413 |
*/
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
*
|
487 |
* Get file list for tree view API
|
488 |
*
|
489 |
*/
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
*
|
561 |
* Get databases/tables list for frontend tree display API
|
562 |
*
|
563 |
*/
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
*
|
641 |
* Get schedule by id API
|
642 |
*
|
643 |
*/
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
|
658 |
-
|
659 |
-
|
660 |
|
661 |
-
|
662 |
*
|
663 |
* Get Schedule list API
|
664 |
*
|
665 |
*/
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
|
|
|
|
744 |
*
|
745 |
* Delete Schedule by ID API
|
746 |
*
|
747 |
*/
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
|
752 |
-
|
753 |
-
$scheduler = $this->xcloner_scheduler;
|
754 |
-
$data['finished'] = $scheduler->delete_schedule_by_id($schedule_id);
|
755 |
|
756 |
-
|
757 |
-
|
|
|
758 |
|
759 |
-
|
|
|
|
|
|
|
760 |
*
|
761 |
* Delete backup by name from the storage path
|
762 |
*
|
763 |
*/
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
$storage_selection = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_selection']);
|
770 |
-
|
771 |
-
$data['finished'] = $this->xcloner_file_system->delete_backup_by_name($backup_name, $storage_selection);
|
772 |
-
|
773 |
-
return $this->send_response($data);
|
774 |
-
}
|
775 |
|
776 |
-
|
777 |
-
|
778 |
-
$this->check_access();
|
779 |
|
780 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
781 |
|
782 |
-
$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
783 |
-
$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
|
784 |
-
$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
|
785 |
|
786 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
787 |
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
|
|
792 |
|
793 |
-
|
794 |
-
|
795 |
-
|
|
|
|
|
|
|
796 |
|
797 |
-
|
798 |
-
} catch (Exception $e) {
|
799 |
-
$return['error'] = true;
|
800 |
-
$return['message'] = $e->getMessage();
|
801 |
-
$this->send_response($return, 0);
|
802 |
-
}
|
803 |
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
|
809 |
-
|
810 |
-
|
811 |
-
$return['files'][$i]['path'] = $file->getPath();
|
812 |
-
$return['files'][$i]['size'] = $file->getSize();
|
813 |
-
$return['files'][$i]['mtime'] = date(get_option('date_format') . " " . get_option('time_format'),
|
814 |
-
$file->getMtime());
|
815 |
|
816 |
-
|
817 |
-
|
818 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
819 |
|
820 |
-
|
821 |
-
$return['start'] = $data['start'];
|
822 |
-
$return['finished'] = 0;
|
823 |
-
} else {
|
824 |
-
if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
|
825 |
-
$return['start'] = 0;
|
826 |
|
827 |
-
|
|
|
|
|
828 |
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
840 |
* Copy remote backup to local storage
|
841 |
*/
|
842 |
-
|
843 |
-
|
844 |
|
845 |
-
|
846 |
|
847 |
-
|
848 |
-
|
849 |
|
850 |
-
|
851 |
|
852 |
-
|
853 |
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
|
872 |
|
873 |
-
|
874 |
|
875 |
-
|
876 |
|
877 |
-
|
878 |
*
|
879 |
* Upload backup to remote API
|
880 |
*
|
881 |
*/
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
|
886 |
-
|
887 |
-
$storage_type = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_type']);
|
888 |
|
889 |
-
|
|
|
890 |
|
891 |
-
|
892 |
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
|
911 |
|
912 |
-
|
913 |
|
914 |
-
|
915 |
|
916 |
-
|
917 |
*
|
918 |
* Remote Storage Status Save
|
919 |
*
|
920 |
*/
|
921 |
-
|
922 |
-
|
923 |
-
|
|
|
|
|
924 |
|
925 |
-
|
926 |
|
927 |
-
|
928 |
|
929 |
-
|
930 |
-
|
931 |
|
932 |
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
|
937 |
-
|
938 |
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
|
944 |
-
|
945 |
$file = 'restore/vendor.built';
|
946 |
|
947 |
if(file_exists($file))
|
@@ -957,178 +1301,185 @@ class Xcloner_Api
|
|
957 |
$phar2->setStub($phar2->createDefaultStub('vendor/autoload.php', 'vendor/autoload.php'));
|
958 |
* */
|
959 |
|
960 |
-
|
961 |
|
962 |
-
|
963 |
-
|
964 |
|
965 |
-
|
966 |
-
|
967 |
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
|
973 |
-
|
974 |
-
|
975 |
|
976 |
-
|
977 |
|
978 |
-
|
979 |
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
|
990 |
-
|
991 |
|
992 |
-
|
993 |
-
|
994 |
-
|
|
|
|
|
995 |
|
996 |
-
|
|
|
|
|
|
|
997 |
*
|
998 |
* Download backup by Name from the Storage Path
|
999 |
*
|
1000 |
*/
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
|
|
|
|
1004 |
|
1005 |
-
|
1006 |
|
1007 |
-
$backup_name = $this->xcloner_sanitization->sanitize_input_as_string($_GET['name']);
|
1008 |
|
|
|
|
|
1009 |
|
1010 |
-
$metadata = $this->xcloner_file_system->get_storage_filesystem()->getMetadata($backup_name);
|
1011 |
-
$read_stream = $this->xcloner_file_system->get_storage_filesystem()->readStream($backup_name);
|
1012 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1013 |
|
1014 |
-
|
1015 |
-
header('Expires: 0');
|
1016 |
-
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
1017 |
-
header('Cache-Control: private', false);
|
1018 |
-
header('Content-Transfer-Encoding: binary');
|
1019 |
-
header('Content-Disposition: attachment; filename="' . $metadata['path'] . '";');
|
1020 |
-
header('Content-Type: application/octet-stream');
|
1021 |
-
header('Content-Length: ' . $metadata['size']);
|
1022 |
|
1023 |
-
|
|
|
|
|
|
|
|
|
|
|
1024 |
|
1025 |
-
|
1026 |
-
while (!feof($read_stream)) {
|
1027 |
-
$buffer = fread($read_stream, $chunkSize);
|
1028 |
-
echo $buffer;
|
1029 |
-
}
|
1030 |
-
fclose($read_stream);
|
1031 |
-
exit;
|
1032 |
|
1033 |
-
|
1034 |
|
1035 |
-
|
1036 |
* Restore upload backup
|
1037 |
*/
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
|
|
|
|
1041 |
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
|
1047 |
-
|
1048 |
-
|
1049 |
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
|
1058 |
-
|
1059 |
-
|
1060 |
|
1061 |
-
|
1062 |
|
1063 |
-
|
1064 |
-
|
1065 |
|
1066 |
-
|
1067 |
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
|
1072 |
-
|
1073 |
-
|
1074 |
|
1075 |
-
|
1076 |
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
|
1081 |
-
|
1082 |
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
|
1089 |
-
|
1090 |
|
1091 |
-
|
1092 |
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
|
1099 |
-
|
1100 |
-
|
1101 |
|
1102 |
-
|
1103 |
* Restore backup
|
1104 |
*/
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
|
1109 |
-
|
1110 |
-
|
1111 |
|
1112 |
-
|
1113 |
-
|
1114 |
|
1115 |
-
|
1116 |
*
|
1117 |
* Send the json response back
|
1118 |
*
|
1119 |
*/
|
1120 |
-
|
1121 |
-
|
1122 |
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
|
1132 |
-
|
1133 |
-
}
|
1134 |
}
|
43 |
class Xcloner_Api
|
44 |
{
|
45 |
|
46 |
+
private $xcloner_database;
|
47 |
+
private $xcloner_settings;
|
48 |
+
private $xcloner_file_system;
|
49 |
+
private $xcloner_scheduler;
|
50 |
+
private $xcloner_requirements;
|
51 |
+
private $xcloner_sanitization;
|
52 |
+
private $xcloner_encryption;
|
53 |
+
private $xcloner_remote_storage;
|
54 |
+
private $archive_system;
|
55 |
+
private $form_params;
|
56 |
+
private $logger;
|
57 |
+
private $xcloner_container;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* XCloner_Api construct class
|
61 |
+
*
|
62 |
+
* @param Xcloner $xcloner_container [description]
|
63 |
+
*/
|
64 |
+
public function __construct(Xcloner $xcloner_container)
|
65 |
+
{
|
66 |
+
global $wpdb;
|
67 |
+
|
68 |
+
if (WP_DEBUG) {
|
69 |
+
error_reporting(0);
|
70 |
+
}
|
71 |
+
|
72 |
+
if (ob_get_length()) {
|
73 |
+
ob_end_clean();
|
74 |
+
}
|
75 |
+
ob_start();
|
76 |
+
|
77 |
+
$wpdb->show_errors = false;
|
78 |
+
|
79 |
+
$this->xcloner_container = $xcloner_container;
|
80 |
+
|
81 |
+
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
82 |
+
$this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_api");
|
83 |
+
$this->xcloner_file_system = $xcloner_container->get_xcloner_filesystem();
|
84 |
+
$this->xcloner_sanitization = $xcloner_container->get_xcloner_sanitization();
|
85 |
+
$this->xcloner_requirements = $xcloner_container->get_xcloner_requirements();
|
86 |
+
$this->archive_system = $xcloner_container->get_archive_system();
|
87 |
+
$this->xcloner_database = $xcloner_container->get_xcloner_database();
|
88 |
+
$this->xcloner_scheduler = $xcloner_container->get_xcloner_scheduler();
|
89 |
+
$this->xcloner_encryption = $xcloner_container->get_xcloner_encryption();
|
90 |
+
$this->xcloner_remote_storage = $xcloner_container->get_xcloner_remote_storage();
|
91 |
+
|
92 |
+
if (isset($_POST['API_ID'])) {
|
93 |
+
$this->logger->info("Processing ajax request ID ".substr($this->xcloner_sanitization->sanitize_input_as_string($_POST['API_ID']),
|
94 |
+
0, 15));
|
95 |
+
}
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Get XCloner Container
|
101 |
+
* @return XCloner return the XCloner container
|
102 |
+
*/
|
103 |
+
public function get_xcloner_container()
|
104 |
+
{
|
105 |
+
return $this->xcloner_container;
|
106 |
+
}
|
107 |
+
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Checks API access
|
111 |
+
*/
|
112 |
+
private function check_access()
|
113 |
+
{
|
114 |
+
if (function_exists('current_user_can') && !current_user_can('manage_options')) {
|
115 |
+
$this->send_response(json_encode("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();
|
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 |
+
$return = array();
|
295 |
+
$additional = array();
|
296 |
+
|
297 |
+
$this->check_access();
|
298 |
+
|
299 |
+
$params = json_decode(stripslashes($_POST['data']));
|
300 |
+
|
301 |
+
$init = (int)$_POST['init'];
|
302 |
+
|
303 |
+
if ($params === null) {
|
304 |
+
return $this->send_response('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
|
305 |
+
}
|
306 |
+
|
307 |
+
$this->process_params($params);
|
308 |
+
|
309 |
+
$return['finished'] = 1;
|
310 |
+
|
311 |
+
//$return = $this->archive_system->start_incremental_backup($this->form_params['backup_params'], $this->form_params['extra'], $init);
|
312 |
+
try {
|
313 |
+
$return = $this->archive_system->start_incremental_backup($this->form_params['backup_params'],
|
314 |
+
$this->form_params['extra'], $init);
|
315 |
+
}catch (Exception $e) {
|
316 |
+
$return = array();
|
317 |
+
$return['error'] = true;
|
318 |
+
$return['status'] = 500;
|
319 |
+
$return['error_message'] = $e->getMessage();
|
320 |
+
|
321 |
+
return $this->send_response($return, $hash = 1);
|
322 |
+
}
|
323 |
+
|
324 |
+
if ($return['finished']) {
|
325 |
+
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_with_extension();
|
326 |
+
if ($this->xcloner_file_system->is_part($this->archive_system->get_archive_name_with_extension())) {
|
327 |
+
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_multipart();
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
$data = $return;
|
332 |
+
|
333 |
+
//check if backup is finished
|
334 |
+
if ($return['finished']) {
|
335 |
+
if (isset($this->form_params['backup_params']['email_notification']) and $to = $this->form_params['backup_params']['email_notification']) {
|
336 |
+
try {
|
337 |
+
$from = "";
|
338 |
+
$subject = "";
|
339 |
+
$additional['lines_total'] = $return['extra']['lines_total'];
|
340 |
+
$this->archive_system->send_notification($to, $from, $subject, $return['extra']['backup_parent'],
|
341 |
+
$this->form_params, "", $additional);
|
342 |
+
}catch (Exception $e) {
|
343 |
+
$this->logger->error($e->getMessage());
|
344 |
+
}
|
345 |
+
}
|
346 |
+
$this->xcloner_file_system->remove_tmp_filesystem();
|
347 |
+
}
|
348 |
+
|
349 |
+
return $this->send_response($data, $hash = 1);
|
350 |
+
}
|
351 |
+
|
352 |
+
/*
|
353 |
*
|
354 |
* Backup Database API
|
355 |
*
|
356 |
*/
|
357 |
+
public function backup_database()
|
358 |
+
{
|
359 |
+
$data = array();
|
360 |
|
361 |
+
$this->check_access();
|
362 |
|
363 |
+
$params = json_decode(stripslashes($_POST['data']));
|
364 |
|
365 |
+
$init = (int)$_POST['init'];
|
|
|
|
|
366 |
|
367 |
+
if ($params === null) {
|
368 |
+
return $this->send_response('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
|
369 |
+
}
|
370 |
|
371 |
+
$this->process_params($params);
|
|
|
|
|
372 |
|
373 |
+
//$xcloner_database = $this->init_db();
|
374 |
+
$return = $this->xcloner_database->start_database_recursion($this->form_params['database'],
|
375 |
+
$this->form_params['extra'], $init);
|
|
|
|
|
376 |
|
377 |
+
if (isset($return['error']) and $return['error']) {
|
378 |
+
$data['finished'] = 1;
|
379 |
+
} else {
|
380 |
+
$data['finished'] = $return['finished'];
|
381 |
+
}
|
382 |
|
383 |
+
$data['extra'] = $return;
|
|
|
384 |
|
385 |
+
return $this->send_response($data, $hash = 1);
|
386 |
+
}
|
387 |
+
|
388 |
+
/*
|
389 |
*
|
390 |
* Scan Filesystem API
|
391 |
*
|
392 |
*/
|
393 |
+
public function scan_filesystem()
|
394 |
+
{
|
395 |
+
$data = array();
|
396 |
+
|
397 |
+
$this->check_access();
|
398 |
|
399 |
+
$params = json_decode(stripslashes($_POST['data']));
|
400 |
+
$init = (int)$_POST['init'];
|
401 |
|
402 |
+
if ($params === null) {
|
403 |
+
$this->send_response('{"status":false,"msg":"The post_data parameter must be valid JSON"}');
|
404 |
+
}
|
405 |
|
406 |
+
$this->process_params($params);
|
407 |
|
408 |
+
$this->xcloner_file_system->set_excluded_files($this->form_params['excluded_files']);
|
409 |
|
410 |
+
$return = $this->xcloner_file_system->start_file_recursion($init);
|
411 |
|
412 |
+
$data["finished"] = !$return;
|
413 |
+
$data["total_files_num"] = $this->xcloner_file_system->get_scanned_files_num();
|
414 |
+
$data["last_logged_file"] = $this->xcloner_file_system->last_logged_file();
|
415 |
+
$data["total_files_size"] = sprintf("%.2f",
|
416 |
+
$this->xcloner_file_system->get_scanned_files_total_size() / (1024 * 1024));
|
417 |
|
418 |
+
return $this->send_response($data, $hash = 1);
|
419 |
+
}
|
420 |
|
421 |
+
/*
|
422 |
*
|
423 |
* Process params sent by the user
|
424 |
*
|
425 |
*/
|
426 |
+
private function process_params($params)
|
427 |
+
{
|
428 |
+
if (isset($params->hash)) {
|
429 |
+
$this->xcloner_settings->set_hash($params->hash);
|
430 |
+
}
|
431 |
+
|
432 |
+
$this->form_params['extra'] = array();
|
433 |
+
$this->form_params['backup_params'] = array();
|
434 |
+
|
435 |
+
$this->form_params['database'] = array();
|
436 |
+
|
437 |
+
if (isset($params->backup_params)) {
|
438 |
+
foreach ($params->backup_params as $param) {
|
439 |
+
$this->form_params['backup_params'][$param->name] = $this->xcloner_sanitization->sanitize_input_as_string($param->value);
|
440 |
+
$this->logger->debug("Adding form parameter ".$param->name.".".$param->value."\n", array(
|
441 |
+
'POST',
|
442 |
+
'fields filter'
|
443 |
+
));
|
444 |
+
}
|
445 |
+
}
|
446 |
+
|
447 |
+
$this->form_params['database'] = array();
|
448 |
+
|
449 |
+
if (isset($params->table_params)) {
|
450 |
+
foreach ($params->table_params as $param) {
|
451 |
+
$this->form_params['database'][$param->parent][] = $this->xcloner_sanitization->sanitize_input_as_raw($param->id);
|
452 |
+
$this->logger->debug("Adding database filter ".$param->parent.".".$param->id."\n", array(
|
453 |
+
'POST',
|
454 |
+
'database filter'
|
455 |
+
));
|
456 |
+
}
|
457 |
+
}
|
458 |
+
|
459 |
+
$this->form_params['excluded_files'] = array();
|
460 |
+
if (isset($params->files_params)) {
|
461 |
+
foreach ($params->files_params as $param) {
|
462 |
+
$this->form_params['excluded_files'][] = $this->xcloner_sanitization->sanitize_input_as_relative_path($param->id);
|
463 |
+
}
|
464 |
+
|
465 |
+
$unique_exclude_files = array();
|
466 |
+
|
467 |
+
foreach ($params->files_params as $key => $param) {
|
468 |
+
if (!in_array($param->parent, $this->form_params['excluded_files'])) {
|
469 |
+
//$this->form_params['excluded_files'][] = $this->xcloner_sanitization->sanitize_input_as_relative_path($param->id);
|
470 |
+
$unique_exclude_files[] = $param->id;
|
471 |
+
$this->logger->debug("Adding file filter ".$param->id."\n", array(
|
472 |
+
'POST',
|
473 |
+
'exclude files filter'
|
474 |
+
));
|
475 |
+
}
|
476 |
+
}
|
477 |
+
$this->form_params['excluded_files'] = (array)$unique_exclude_files;
|
478 |
+
|
479 |
+
}
|
480 |
+
|
481 |
+
//$this->form_params['excluded_files'] = array_merge($this->form_params['excluded_files'], $this->exclude_files_by_default);
|
482 |
+
|
483 |
+
if (isset($params->extra)) {
|
484 |
+
foreach ($params->extra as $key => $value) {
|
485 |
+
$this->form_params['extra'][$key] = $this->xcloner_sanitization->sanitize_input_as_raw($value);
|
486 |
+
}
|
487 |
+
}
|
488 |
+
|
489 |
+
if (isset($this->form_params['backup_params']['diff_start_date']) and $this->form_params['backup_params']['diff_start_date']) {
|
490 |
+
$this->form_params['backup_params']['diff_start_date'] = strtotime($this->form_params['backup_params']['diff_start_date']);
|
491 |
+
$this->xcloner_file_system->set_diff_timestamp_start($this->form_params['backup_params']['diff_start_date']);
|
492 |
+
}
|
493 |
+
|
494 |
+
return $this->xcloner_settings->get_hash();
|
495 |
+
}
|
496 |
+
|
497 |
+
/*
|
498 |
*
|
499 |
* Get file list for tree view API
|
500 |
*
|
501 |
*/
|
502 |
+
public function get_file_system_action()
|
503 |
+
{
|
504 |
+
$this->check_access();
|
505 |
+
|
506 |
+
$folder = $this->xcloner_sanitization->sanitize_input_as_relative_path($_POST['id']);
|
507 |
+
|
508 |
+
$data = array();
|
509 |
+
|
510 |
+
if ($folder == "#") {
|
511 |
+
|
512 |
+
$folder = "/";
|
513 |
+
$data[] = array(
|
514 |
+
'id' => $folder,
|
515 |
+
'parent' => '#',
|
516 |
+
'text' => $this->xcloner_settings->get_xcloner_start_path(),
|
517 |
+
//'children' => true,
|
518 |
+
'state' => array('selected' => false, 'opened' => true),
|
519 |
+
'icon' => plugin_dir_url(dirname(__FILE__))."/admin/assets/file-icon-root.png"
|
520 |
+
);
|
521 |
+
}
|
522 |
+
|
523 |
+
try {
|
524 |
+
$files = $this->xcloner_file_system->list_directory($folder);
|
525 |
+
}catch (Exception $e) {
|
526 |
+
|
527 |
+
print $e->getMessage();
|
528 |
+
$this->logger->error($e->getMessage());
|
529 |
+
|
530 |
+
return;
|
531 |
+
}
|
532 |
+
|
533 |
+
$type = array();
|
534 |
+
foreach ($files as $key => $row) {
|
535 |
+
$type[$key] = $row['type'];
|
536 |
+
}
|
537 |
+
array_multisort($type, SORT_ASC, $files);
|
538 |
+
|
539 |
+
foreach ($files as $file) {
|
540 |
+
$children = false;
|
541 |
+
$text = $file['basename'];
|
542 |
+
|
543 |
+
if ($file['type'] == "dir") {
|
544 |
+
$children = true;
|
545 |
+
} else {
|
546 |
+
$text .= " (".$this->xcloner_requirements->file_format_size($file['size']).")";
|
547 |
+
}
|
548 |
+
|
549 |
+
if ($this->xcloner_file_system->is_excluded($file)) {
|
550 |
+
$selected = true;
|
551 |
+
} else {
|
552 |
+
$selected = false;
|
553 |
+
}
|
554 |
+
|
555 |
+
$data[] = array(
|
556 |
+
'id' => $file['path'],
|
557 |
+
'parent' => $folder,
|
558 |
+
'text' => $text,
|
559 |
+
//'title' => "test",
|
560 |
+
'children' => $children,
|
561 |
+
'state' => array('selected' => $selected, 'opened' => false, "checkbox_disabled" => $selected),
|
562 |
+
'icon' => plugin_dir_url(dirname(__FILE__))."/admin/assets/file-icon-".strtolower(substr($file['type'],
|
563 |
+
0, 1)).".png"
|
564 |
+
);
|
565 |
+
}
|
566 |
+
|
567 |
+
|
568 |
+
return $this->send_response($data, 0);
|
569 |
+
}
|
570 |
+
|
571 |
+
/*
|
572 |
*
|
573 |
* Get databases/tables list for frontend tree display API
|
574 |
*
|
575 |
*/
|
576 |
+
public function get_database_tables_action()
|
577 |
+
{
|
578 |
+
$this->check_access();
|
579 |
+
|
580 |
+
$database = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['id']);
|
581 |
+
|
582 |
+
$data = array();
|
583 |
+
|
584 |
+
$xcloner_backup_only_wp_tables = $this->xcloner_settings->get_xcloner_option('xcloner_backup_only_wp_tables');
|
585 |
+
|
586 |
+
if ($database == "#") {
|
587 |
+
try {
|
588 |
+
$return = $this->xcloner_database->get_all_databases();
|
589 |
+
}catch (Exception $e) {
|
590 |
+
$this->logger->error($e->getMessage());
|
591 |
+
}
|
592 |
+
|
593 |
+
foreach ($return as $database) {
|
594 |
+
if ($xcloner_backup_only_wp_tables and $database['name'] != $this->xcloner_settings->get_db_database()) {
|
595 |
+
continue;
|
596 |
+
}
|
597 |
+
|
598 |
+
$state = array();
|
599 |
+
|
600 |
+
if ($database['name'] == $this->xcloner_settings->get_db_database()) {
|
601 |
+
$state['selected'] = true;
|
602 |
+
if ($database['num_tables'] < 25) {
|
603 |
+
$state['opened'] = false;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
$data[] = array(
|
608 |
+
'id' => $database['name'],
|
609 |
+
'parent' => '#',
|
610 |
+
'text' => $database['name']." (".(int)$database['num_tables'].")",
|
611 |
+
'children' => true,
|
612 |
+
'state' => $state,
|
613 |
+
'icon' => plugin_dir_url(dirname(__FILE__))."/admin/assets/database-icon.png"
|
614 |
+
);
|
615 |
+
}
|
616 |
+
|
617 |
+
} else {
|
618 |
+
|
619 |
+
try {
|
620 |
+
$return = $this->xcloner_database->list_tables($database, "", 1);
|
621 |
+
}catch (Exception $e) {
|
622 |
+
$this->logger->error($e->getMessage());
|
623 |
+
}
|
624 |
+
|
625 |
+
foreach ($return as $table) {
|
626 |
+
$state = array();
|
627 |
+
|
628 |
+
if ($xcloner_backup_only_wp_tables and !stristr($table['name'],
|
629 |
+
$this->xcloner_settings->get_table_prefix())) {
|
630 |
+
continue;
|
631 |
+
}
|
632 |
+
|
633 |
+
if (isset($database['name']) and $database['name'] == $this->xcloner_settings->get_db_database()) {
|
634 |
+
$state = array('selected' => true);
|
635 |
+
}
|
636 |
+
|
637 |
+
$data[] = array(
|
638 |
+
'id' => $database.".".$table['name'],
|
639 |
+
'parent' => $database,
|
640 |
+
'text' => $table['name']." (".(int)$table['records'].")",
|
641 |
+
'children' => false,
|
642 |
+
'state' => $state,
|
643 |
+
'icon' => plugin_dir_url(dirname(__FILE__))."/admin/assets/table-icon.png"
|
644 |
+
);
|
645 |
+
}
|
646 |
+
}
|
647 |
+
|
648 |
+
return $this->send_response($data, 0);
|
649 |
+
}
|
650 |
+
|
651 |
+
/*
|
652 |
*
|
653 |
* Get schedule by id API
|
654 |
*
|
655 |
*/
|
656 |
+
public function get_schedule_by_id()
|
657 |
+
{
|
658 |
+
$this->check_access();
|
659 |
|
660 |
+
$schedule_id = $this->xcloner_sanitization->sanitize_input_as_int($_GET['id']);
|
661 |
+
$scheduler = $this->xcloner_scheduler;
|
662 |
+
$data = $scheduler->get_schedule_by_id($schedule_id);
|
663 |
|
664 |
+
$data['start_at'] = date("Y-m-d H:i",
|
665 |
+
strtotime($data['start_at']) + (get_option('gmt_offset') * HOUR_IN_SECONDS));
|
666 |
+
if (isset($data['backup_params']->diff_start_date) && $data['backup_params']->diff_start_date != "") {
|
667 |
+
$data['backup_params']->diff_start_date = date("Y-m-d", ($data['backup_params']->diff_start_date));
|
668 |
+
}
|
669 |
|
670 |
+
return $this->send_response($data);
|
671 |
+
}
|
672 |
|
673 |
+
/*
|
674 |
*
|
675 |
* Get Schedule list API
|
676 |
*
|
677 |
*/
|
678 |
+
public function get_scheduler_list()
|
679 |
+
{
|
680 |
+
$return = array();
|
681 |
+
|
682 |
+
$this->check_access();
|
683 |
+
|
684 |
+
$scheduler = $this->xcloner_scheduler;
|
685 |
+
$data = $scheduler->get_scheduler_list();
|
686 |
+
$return['data'] = array();
|
687 |
+
|
688 |
+
foreach ($data as $res) {
|
689 |
+
$action = "<a href=\"#".$res->id."\" class=\"edit\" title='Edit'> <i class=\"material-icons \">edit</i></a>
|
690 |
+
<a href=\"#" . $res->id."\" class=\"delete\" title='Delete'><i class=\"material-icons \">delete</i></a>";
|
691 |
+
if ($res->status) {
|
692 |
+
$status = '<i class="material-icons active status">timer</i>';
|
693 |
+
} else {
|
694 |
+
$status = '<i class="material-icons status inactive">timer_off</i>';
|
695 |
+
}
|
696 |
+
|
697 |
+
$next_run_time = wp_next_scheduled('xcloner_scheduler_'.$res->id, array($res->id));
|
698 |
+
|
699 |
+
$next_run = date(get_option('date_format')." ".get_option('time_format'), $next_run_time);
|
700 |
+
|
701 |
+
$remote_storage = $res->remote_storage;
|
702 |
+
|
703 |
+
if (!$next_run_time >= time()) {
|
704 |
+
$next_run = " ";
|
705 |
+
}
|
706 |
+
|
707 |
+
if (trim($next_run)) {
|
708 |
+
$date_text = date(get_option('date_format')." ".get_option('time_format'),
|
709 |
+
$next_run_time + (get_option('gmt_offset') * HOUR_IN_SECONDS));
|
710 |
+
|
711 |
+
if ($next_run_time >= time()) {
|
712 |
+
$next_run = "in ".human_time_diff($next_run_time, time());
|
713 |
+
} else {
|
714 |
+
$next_run = __("executed", 'xcloner-backup-and-restore');
|
715 |
+
}
|
716 |
+
|
717 |
+
$next_run = "<a href='#' title='".$date_text."'>".$next_run."</a>";
|
718 |
+
//$next_run .=" ($date_text)";
|
719 |
+
}
|
720 |
+
|
721 |
+
$backup_text = "";
|
722 |
+
$backup_size = "";
|
723 |
+
$backup_time = "";
|
724 |
+
|
725 |
+
if ($res->last_backup) {
|
726 |
+
if ($this->xcloner_file_system->get_storage_filesystem()->has($res->last_backup)) {
|
727 |
+
$metadata = $this->xcloner_file_system->get_storage_filesystem()->getMetadata($res->last_backup);
|
728 |
+
$backup_size = size_format($this->xcloner_file_system->get_backup_size($res->last_backup));
|
729 |
+
$backup_time = date(get_option('date_format')." ".get_option('time_format'),
|
730 |
+
$metadata['timestamp'] + (get_option('gmt_offset') * HOUR_IN_SECONDS));
|
731 |
+
}
|
732 |
+
|
733 |
+
$backup_text = "<span title='".$backup_time."' class='shorten_string'>".$res->last_backup." (".$backup_size.")</span>";
|
734 |
+
}
|
735 |
+
|
736 |
+
$schedules = wp_get_schedules();
|
737 |
+
|
738 |
+
if (isset($schedules[$res->recurrence])) {
|
739 |
+
$res->recurrence = $schedules[$res->recurrence]['display'];
|
740 |
+
}
|
741 |
+
|
742 |
+
$return['data'][] = array(
|
743 |
+
$res->id,
|
744 |
+
$res->name,
|
745 |
+
$res->recurrence, /*$res->start_at,*/
|
746 |
+
$next_run,
|
747 |
+
$remote_storage,
|
748 |
+
$backup_text,
|
749 |
+
$status,
|
750 |
+
$action
|
751 |
+
);
|
752 |
+
}
|
753 |
+
|
754 |
+
return $this->send_response($return, 0);
|
755 |
+
}
|
756 |
+
|
757 |
+
/*
|
758 |
*
|
759 |
* Delete Schedule by ID API
|
760 |
*
|
761 |
*/
|
762 |
+
public function delete_schedule_by_id()
|
763 |
+
{
|
764 |
+
$data = array();
|
765 |
|
766 |
+
$this->check_access();
|
|
|
|
|
767 |
|
768 |
+
$schedule_id = $this->xcloner_sanitization->sanitize_input_as_int($_GET['id']);
|
769 |
+
$scheduler = $this->xcloner_scheduler;
|
770 |
+
$data['finished'] = $scheduler->delete_schedule_by_id($schedule_id);
|
771 |
|
772 |
+
return $this->send_response($data);
|
773 |
+
}
|
774 |
+
|
775 |
+
/*
|
776 |
*
|
777 |
* Delete backup by name from the storage path
|
778 |
*
|
779 |
*/
|
780 |
+
public function delete_backup_by_name()
|
781 |
+
{
|
782 |
+
$data = array();
|
783 |
+
|
784 |
+
$this->check_access();
|
|
|
|
|
|
|
|
|
|
|
|
|
785 |
|
786 |
+
$backup_name = $this->xcloner_sanitization->sanitize_input_as_string($_POST['name']);
|
787 |
+
$storage_selection = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_selection']);
|
|
|
788 |
|
789 |
+
$data['finished'] = $this->xcloner_file_system->delete_backup_by_name($backup_name, $storage_selection);
|
790 |
+
|
791 |
+
return $this->send_response($data);
|
792 |
+
}
|
793 |
+
|
794 |
+
/**
|
795 |
+
* API Incremental Backup Encryption Method
|
796 |
+
*/
|
797 |
+
public function backup_encryption()
|
798 |
+
{
|
799 |
+
$this->check_access();
|
800 |
+
|
801 |
+
$backup_parts = array();
|
802 |
+
$return = array();
|
803 |
|
|
|
|
|
|
|
804 |
|
805 |
+
if (isset($_POST['data'])) {
|
806 |
+
$params = json_decode(stripslashes($_POST['data']));
|
807 |
+
|
808 |
+
$this->process_params($params);
|
809 |
+
$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($this->form_params['extra']['backup_parent']);
|
810 |
+
|
811 |
+
if (isset($this->form_params['extra']['start'])) {
|
812 |
+
$start = $this->xcloner_sanitization->sanitize_input_as_int($this->form_params['extra']['start']);
|
813 |
+
} else {
|
814 |
+
$start = 0;
|
815 |
+
}
|
816 |
+
|
817 |
+
if (isset($this->form_params['extra']['iv'])) {
|
818 |
+
$iv = $this->xcloner_sanitization->sanitize_input_as_raw($this->form_params['extra']['iv']);
|
819 |
+
} else {
|
820 |
+
$iv = "";
|
821 |
+
}
|
822 |
|
823 |
+
if (isset($this->form_params['extra']['part'])) {
|
824 |
+
$return['part'] = (int)$this->xcloner_sanitization->sanitize_input_as_int($this->form_params['extra']['part']);
|
825 |
+
} else {
|
826 |
+
$return['part'] = 0;
|
827 |
+
}
|
828 |
|
829 |
+
} else {
|
830 |
+
$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
831 |
+
$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
|
832 |
+
$iv = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['iv']);
|
833 |
+
$return['part'] = (int)$this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
|
834 |
+
}
|
835 |
|
836 |
+
$backup_file = $source_backup_file;
|
|
|
|
|
|
|
|
|
|
|
837 |
|
838 |
+
if ($this->xcloner_file_system->is_multipart($backup_file)) {
|
839 |
+
$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
|
840 |
+
$backup_file = $backup_parts[$return['part']];
|
841 |
+
}
|
842 |
|
843 |
+
$return['processing_file'] = $backup_file;
|
844 |
+
$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path().DS.$backup_file);
|
|
|
|
|
|
|
|
|
845 |
|
846 |
+
try {
|
847 |
+
$this->logger->info(json_encode($_POST));
|
848 |
+
$this->logger->info($iv);
|
849 |
+
$return = array_merge($return,
|
850 |
+
$this->xcloner_encryption->encrypt_file($backup_file, "", "", $start, base64_decode($iv)));
|
851 |
+
}catch (\Exception $e) {
|
852 |
+
$return['error'] = true;
|
853 |
+
$return['message'] = $e->getMessage();
|
854 |
+
$return['error_message'] = $e->getMessage();
|
855 |
+
}
|
856 |
|
857 |
+
//echo strlen($return['iv']);exit;
|
|
|
|
|
|
|
|
|
|
|
858 |
|
859 |
+
if (isset($return['finished']) && $return['finished']) {
|
860 |
+
if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
|
861 |
+
$return['start'] = 0;
|
862 |
|
863 |
+
++$return['part'];
|
864 |
+
|
865 |
+
if ($return['part'] < sizeof($backup_parts)) {
|
866 |
+
$return['finished'] = 0;
|
867 |
+
}
|
868 |
+
|
869 |
+
}
|
870 |
+
}
|
871 |
+
|
872 |
+
if (isset($_POST['data'])) {
|
873 |
+
$return['extra'] = array_merge($this->form_params['extra'], $return);
|
874 |
+
}
|
875 |
+
|
876 |
+
$this->send_response($return, 0);
|
877 |
+
}
|
878 |
+
|
879 |
+
/**
|
880 |
+
* API Incremental Backup Decryption Method
|
881 |
+
*/
|
882 |
+
public function backup_decryption()
|
883 |
+
{
|
884 |
+
$this->check_access();
|
885 |
+
|
886 |
+
$backup_parts = array();
|
887 |
+
$return = array();
|
888 |
+
|
889 |
+
$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
890 |
+
$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
|
891 |
+
$iv = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['iv']);
|
892 |
+
$decryption_key = $this->xcloner_sanitization->sanitize_input_as_raw($_POST['decryption_key']); ;
|
893 |
+
$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
|
894 |
+
|
895 |
+
$backup_file = $source_backup_file;
|
896 |
+
|
897 |
+
if ($this->xcloner_file_system->is_multipart($backup_file)) {
|
898 |
+
$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
|
899 |
+
$backup_file = $backup_parts[$return['part']];
|
900 |
+
}
|
901 |
+
|
902 |
+
$return['processing_file'] = $backup_file;
|
903 |
+
$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path().DS.$backup_file);
|
904 |
+
|
905 |
+
try {
|
906 |
+
$return = array_merge($return,
|
907 |
+
$this->xcloner_encryption->decrypt_file($backup_file, "", $decryption_key, $start, base64_decode($iv)));
|
908 |
+
}catch (\Exception $e) {
|
909 |
+
$return['error'] = true;
|
910 |
+
$return['message'] = $e->getMessage();
|
911 |
+
}
|
912 |
+
|
913 |
+
if ($return['finished']) {
|
914 |
+
if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
|
915 |
+
$return['start'] = 0;
|
916 |
+
|
917 |
+
++$return['part'];
|
918 |
+
|
919 |
+
if ($return['part'] < sizeof($backup_parts)) {
|
920 |
+
$return['finished'] = 0;
|
921 |
+
}
|
922 |
+
|
923 |
+
}
|
924 |
+
}
|
925 |
+
|
926 |
+
$this->send_response($return, 0);
|
927 |
+
}
|
928 |
+
|
929 |
+
public function get_manage_backups_list() {
|
930 |
+
|
931 |
+
$this->check_access();
|
932 |
+
|
933 |
+
$return = array();
|
934 |
+
$storage_selection = "";
|
935 |
+
|
936 |
+
if (isset($_GET['storage_selection']) and $_GET['storage_selection']) {
|
937 |
+
$storage_selection = $this->xcloner_sanitization->sanitize_input_as_string($_GET['storage_selection']);
|
938 |
+
}
|
939 |
+
$available_storages = $this->xcloner_remote_storage->get_available_storages();
|
940 |
+
|
941 |
+
$backup_list = $this->xcloner_file_system->get_backup_archives_list($storage_selection);
|
942 |
+
|
943 |
+
$i = -1;
|
944 |
+
foreach ($backup_list as $file_info):?>
|
945 |
+
<?php
|
946 |
+
if ($storage_selection == "gdrive") {
|
947 |
+
$file_info['path'] = $file_info['filename'].".".$file_info['extension'];
|
948 |
+
}
|
949 |
+
$file_exists_on_local_storage = true;
|
950 |
+
|
951 |
+
if ($storage_selection) {
|
952 |
+
if (!$this->xcloner_file_system->get_storage_filesystem()->has($file_info['path'])) {
|
953 |
+
$file_exists_on_local_storage = false;
|
954 |
+
}
|
955 |
+
}
|
956 |
+
|
957 |
+
?>
|
958 |
+
<?php if (!isset($file_info['parent'])): ?>
|
959 |
+
|
960 |
+
<?php ob_start(); ?>
|
961 |
+
<p>
|
962 |
+
<input name="backup[]" value="<?php echo $file_info['basename'] ?>" type="checkbox"
|
963 |
+
id="checkbox_<?php echo ++$i ?>">
|
964 |
+
<label for="checkbox_<?php echo $i ?>"> </label>
|
965 |
+
</p>
|
966 |
+
<?php
|
967 |
+
$return['data'][$i][] = ob_get_contents();
|
968 |
+
ob_end_clean();
|
969 |
+
?>
|
970 |
+
|
971 |
+
<?php ob_start(); ?>
|
972 |
+
<span class=""><?php echo $file_info['path'] ?></span>
|
973 |
+
<?php if (!$file_exists_on_local_storage): ?>
|
974 |
+
<a href="#"
|
975 |
+
title="<?php echo __("File does not exists on local storage",
|
976 |
+
"xcloner-backup-and-restore") ?>"><i
|
977 |
+
class="material-icons backup_warning">warning</i></a>
|
978 |
+
<?php endif ?>
|
979 |
+
<?php
|
980 |
+
if (isset($file_info['childs']) and is_array($file_info['childs'])):
|
981 |
+
?>
|
982 |
+
<a href="#" title="expand" class="expand-multipart add"><i
|
983 |
+
class="material-icons">add</i></a>
|
984 |
+
<a href="#" title="collapse" class="expand-multipart remove"><i class="material-icons">remove</i></a>
|
985 |
+
<ul class="multipart">
|
986 |
+
<?php foreach ($file_info['childs'] as $child): ?>
|
987 |
+
<li>
|
988 |
+
<?php echo $child[0] ?> (<?php echo esc_html(size_format($child[2])) ?>)
|
989 |
+
<?php
|
990 |
+
$child_exists_on_local_storage = true;
|
991 |
+
if ($storage_selection) {
|
992 |
+
if (!$this->xcloner_file_system->get_storage_filesystem()->has($child[0])) {
|
993 |
+
$child_exists_on_local_storage = false;
|
994 |
+
}
|
995 |
+
}
|
996 |
+
?>
|
997 |
+
<?php if (!$child_exists_on_local_storage): ?>
|
998 |
+
<a href="#"
|
999 |
+
title="<?php echo __("File does not exists on local storage",
|
1000 |
+
"xcloner-backup-and-restore") ?>"><i
|
1001 |
+
class="material-icons backup_warning">warning</i></a>
|
1002 |
+
<?php endif ?>
|
1003 |
+
<?php if (!$storage_selection) : ?>
|
1004 |
+
<a href="#<?php echo $child[0]; ?>" class="download"
|
1005 |
+
title="Download Backup"><i class="material-icons">file_download</i></a>
|
1006 |
+
|
1007 |
+
<?php if ($this->xcloner_encryption->is_encrypted_file($child[0])) :?>
|
1008 |
+
<a href="#<?php echo $child[0] ?>" class="backup-decryption"
|
1009 |
+
title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
|
1010 |
+
<i class="material-icons">enhanced_encryption</i>
|
1011 |
+
</a>
|
1012 |
+
<?php else: ?>
|
1013 |
+
<a href="#<?php echo $child[0] ?>" class="list-backup-content"
|
1014 |
+
title="<?php echo __('List Backup Content',
|
1015 |
+
'xcloner-backup-and-restore') ?>"><i
|
1016 |
+
class="material-icons">folder_open</i></a>
|
1017 |
+
|
1018 |
+
<a href="#<?php echo $child[0] ?>" class="backup-encryption"
|
1019 |
+
title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
|
1020 |
+
<i class="material-icons">no_encryption</i>
|
1021 |
+
</a>
|
1022 |
+
<?php endif?>
|
1023 |
+
|
1024 |
+
<?php elseif ($storage_selection != "gdrive" && !$this->xcloner_file_system->get_storage_filesystem()->has($child[0])): ?>
|
1025 |
+
<a href="#<?php echo $child[0] ?>" class="copy-remote-to-local"
|
1026 |
+
title="<?php echo __('Push Backup To Local Storage',
|
1027 |
+
'xcloner-backup-and-restore') ?>"><i
|
1028 |
+
class="material-icons">file_upload</i></a>
|
1029 |
+
<?php endif ?>
|
1030 |
+
</li>
|
1031 |
+
<?php endforeach; ?>
|
1032 |
+
</ul>
|
1033 |
+
<?php endif; ?>
|
1034 |
+
<?php
|
1035 |
+
$return['data'][$i][] = ob_get_contents();
|
1036 |
+
ob_end_clean();
|
1037 |
+
?>
|
1038 |
+
<?php ob_start(); ?>
|
1039 |
+
<?php if (isset($file_info['timestamp']))
|
1040 |
+
echo date("Y-m-d H:i", $file_info['timestamp'])
|
1041 |
+
?>
|
1042 |
+
<?php
|
1043 |
+
$return['data'][$i][] = ob_get_contents();
|
1044 |
+
ob_end_clean();
|
1045 |
+
?>
|
1046 |
+
|
1047 |
+
<?php ob_start(); ?>
|
1048 |
+
<?php echo esc_html(size_format($file_info['size'])) ?>
|
1049 |
+
<?php
|
1050 |
+
$return['data'][$i][] = ob_get_contents();
|
1051 |
+
ob_end_clean();
|
1052 |
+
?>
|
1053 |
+
|
1054 |
+
<?php ob_start(); ?>
|
1055 |
+
<?php if (!$storage_selection): ?>
|
1056 |
+
<a href="#<?php echo $file_info['basename']; ?>" class="download"
|
1057 |
+
title="<?php echo __('Download Backup', 'xcloner-backup-and-restore') ?>"><i
|
1058 |
+
class="material-icons">file_download</i></a>
|
1059 |
+
|
1060 |
+
<?php if (sizeof($available_storages)): ?>
|
1061 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="cloud-upload"
|
1062 |
+
title="<?php echo __('Send Backup To Remote Storage',
|
1063 |
+
'xcloner-backup-and-restore') ?>"><i
|
1064 |
+
class="material-icons">cloud_upload</i></a>
|
1065 |
+
<?php endif ?>
|
1066 |
+
<?php
|
1067 |
+
$basename = $file_info['basename'];
|
1068 |
+
if (isset($file_info['childs']) and sizeof($file_info['childs']))
|
1069 |
+
$basename = $file_info['childs'][0][0];
|
1070 |
+
?>
|
1071 |
+
<?php if ($this->xcloner_encryption->is_encrypted_file($basename)) :?>
|
1072 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="backup-decryption"
|
1073 |
+
title="<?php echo __('Backup Decryption', 'xcloner-backup-and-restore') ?>">
|
1074 |
+
<i class="material-icons">enhanced_encryption</i>
|
1075 |
+
</a>
|
1076 |
+
<?php else: ?>
|
1077 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="list-backup-content"
|
1078 |
+
title="<?php echo __('List Backup Content', 'xcloner-backup-and-restore') ?>"><i
|
1079 |
+
class="material-icons">folder_open</i></a>
|
1080 |
+
|
1081 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="backup-encryption"
|
1082 |
+
title="<?php echo __('Backup Encryption', 'xcloner-backup-and-restore') ?>">
|
1083 |
+
<i class="material-icons">no_encryption</i>
|
1084 |
+
</a>
|
1085 |
+
<?php endif?>
|
1086 |
+
<?php endif; ?>
|
1087 |
+
|
1088 |
+
<a href="#<?php echo $file_info['basename'] ?>" class="delete"
|
1089 |
+
title="<?php echo __('Delete Backup', 'xcloner-backup-and-restore') ?>">
|
1090 |
+
<i class="material-icons">delete</i>
|
1091 |
+
</a>
|
1092 |
+
<?php if ($storage_selection and !$file_exists_on_local_storage): ?>
|
1093 |
+
<a href="#<?php echo $file_info['basename']; ?>" class="copy-remote-to-local"
|
1094 |
+
title="<?php echo __('Push Backup To Local Storage', 'xcloner-backup-and-restore') ?>"><i
|
1095 |
+
class="material-icons">file_upload</i></a>
|
1096 |
+
<?php endif ?>
|
1097 |
+
|
1098 |
+
<?php
|
1099 |
+
$return['data'][$i][] = ob_get_contents();
|
1100 |
+
ob_end_clean(); ?>
|
1101 |
+
|
1102 |
+
<?php endif ?>
|
1103 |
+
<?php endforeach ?>
|
1104 |
+
<?php
|
1105 |
+
$this->send_response($return, 0);
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
/**
|
1109 |
+
* API method to list internal backup files
|
1110 |
+
*/
|
1111 |
+
public function list_backup_files()
|
1112 |
+
{
|
1113 |
+
$this->check_access();
|
1114 |
+
|
1115 |
+
$backup_parts = array();
|
1116 |
+
$return = array();
|
1117 |
+
|
1118 |
+
$source_backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
1119 |
+
$start = $this->xcloner_sanitization->sanitize_input_as_int($_POST['start']);
|
1120 |
+
$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
|
1121 |
+
|
1122 |
+
$backup_file = $source_backup_file;
|
1123 |
+
|
1124 |
+
if ($this->xcloner_file_system->is_multipart($backup_file)) {
|
1125 |
+
$backup_parts = $this->xcloner_file_system->get_multipart_files($backup_file);
|
1126 |
+
$backup_file = $backup_parts[$return['part']];
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
if ($this->xcloner_encryption->is_encrypted_file($backup_file)) {
|
1130 |
+
$return['error'] = true;
|
1131 |
+
$return['message'] = __("Backup archive is encrypted, please decrypt it first before you can list it's content.", "xcloner-backup-and-restore");
|
1132 |
+
$this->send_response($return, 0);
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
try {
|
1136 |
+
$tar = new Tar();
|
1137 |
+
$tar->open($this->xcloner_settings->get_xcloner_store_path().DS.$backup_file, $start);
|
1138 |
+
|
1139 |
+
$data = $tar->contents(get_option('xcloner_files_to_process_per_request'));
|
1140 |
+
}catch (Exception $e) {
|
1141 |
+
$return['error'] = true;
|
1142 |
+
$return['message'] = $e->getMessage();
|
1143 |
+
$this->send_response($return, 0);
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
$return['files'] = array();
|
1147 |
+
$return['finished'] = 1;
|
1148 |
+
$return['total_size'] = filesize($this->xcloner_settings->get_xcloner_store_path().DS.$backup_file);
|
1149 |
+
$i = 0;
|
1150 |
+
|
1151 |
+
if (isset($data['extracted_files']) and is_array($data['extracted_files'])) {
|
1152 |
+
foreach ($data['extracted_files'] as $file) {
|
1153 |
+
$return['files'][$i]['path'] = $file->getPath();
|
1154 |
+
$return['files'][$i]['size'] = $file->getSize();
|
1155 |
+
$return['files'][$i]['mtime'] = date(get_option('date_format')." ".get_option('time_format'),
|
1156 |
+
$file->getMtime());
|
1157 |
+
|
1158 |
+
$i++;
|
1159 |
+
}
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
if (isset($data['start'])) {
|
1163 |
+
$return['start'] = $data['start'];
|
1164 |
+
$return['finished'] = 0;
|
1165 |
+
} else {
|
1166 |
+
if ($this->xcloner_file_system->is_multipart($source_backup_file)) {
|
1167 |
+
$return['start'] = 0;
|
1168 |
+
|
1169 |
+
++$return['part'];
|
1170 |
+
|
1171 |
+
if ($return['part'] < sizeof($backup_parts)) {
|
1172 |
+
$return['finished'] = 0;
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
}
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
$this->send_response($return, 0);
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
/*
|
1182 |
* Copy remote backup to local storage
|
1183 |
*/
|
1184 |
+
public function copy_backup_remote_to_local()
|
1185 |
+
{
|
1186 |
|
1187 |
+
$this->check_access();
|
1188 |
|
1189 |
+
$backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
1190 |
+
$storage_type = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_type']);
|
1191 |
|
1192 |
+
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
1193 |
|
1194 |
+
$return = array();
|
1195 |
|
1196 |
+
try {
|
1197 |
+
if (method_exists($xcloner_remote_storage, "copy_backup_remote_to_local")) {
|
1198 |
+
$return = call_user_func_array(array(
|
1199 |
+
$xcloner_remote_storage,
|
1200 |
+
"copy_backup_remote_to_local"
|
1201 |
+
), array($backup_file, $storage_type));
|
1202 |
+
}
|
1203 |
+
}catch (Exception $e) {
|
1204 |
|
1205 |
+
$return['error'] = 1;
|
1206 |
+
$return['message'] = $e->getMessage();
|
1207 |
+
}
|
1208 |
|
1209 |
+
if (!$return) {
|
1210 |
+
$return['error'] = 1;
|
1211 |
+
$return['message'] = "Upload failed, please check the error log for more information!";
|
1212 |
+
}
|
1213 |
|
1214 |
|
1215 |
+
$this->send_response($return, 0);
|
1216 |
|
1217 |
+
}
|
1218 |
|
1219 |
+
/*
|
1220 |
*
|
1221 |
* Upload backup to remote API
|
1222 |
*
|
1223 |
*/
|
1224 |
+
public function upload_backup_to_remote()
|
1225 |
+
{
|
1226 |
+
$this->check_access();
|
1227 |
|
1228 |
+
$return = array();
|
|
|
1229 |
|
1230 |
+
$backup_file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
1231 |
+
$storage_type = $this->xcloner_sanitization->sanitize_input_as_string($_POST['storage_type']);
|
1232 |
|
1233 |
+
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
1234 |
|
1235 |
+
try {
|
1236 |
+
if (method_exists($xcloner_remote_storage, "upload_backup_to_storage")) {
|
1237 |
+
$return = call_user_func_array(array(
|
1238 |
+
$xcloner_remote_storage,
|
1239 |
+
"upload_backup_to_storage"
|
1240 |
+
), array($backup_file, $storage_type));
|
1241 |
+
}
|
1242 |
+
}catch (Exception $e) {
|
1243 |
|
1244 |
+
$return['error'] = 1;
|
1245 |
+
$return['message'] = $e->getMessage();
|
1246 |
+
}
|
1247 |
|
1248 |
+
if (!$return) {
|
1249 |
+
$return['error'] = 1;
|
1250 |
+
$return['message'] = "Upload failed, please check the error log for more information!";
|
1251 |
+
}
|
1252 |
|
1253 |
|
1254 |
+
$this->send_response($return, 0);
|
1255 |
|
1256 |
+
}
|
1257 |
|
1258 |
+
/*
|
1259 |
*
|
1260 |
* Remote Storage Status Save
|
1261 |
*
|
1262 |
*/
|
1263 |
+
public function remote_storage_save_status()
|
1264 |
+
{
|
1265 |
+
$this->check_access();
|
1266 |
+
|
1267 |
+
$return = array();
|
1268 |
|
1269 |
+
$xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
1270 |
|
1271 |
+
$return['finished'] = $xcloner_remote_storage->change_storage_status($_POST['id'], $_POST['value']);
|
1272 |
|
1273 |
+
$this->send_response($return, 0);
|
1274 |
+
}
|
1275 |
|
1276 |
|
1277 |
+
public function download_restore_script()
|
1278 |
+
{
|
1279 |
+
$this->check_access();
|
1280 |
|
1281 |
+
ob_end_clean();
|
1282 |
|
1283 |
+
$adapter = new Local(dirname(__DIR__), LOCK_EX, '0001');
|
1284 |
+
$xcloner_plugin_filesystem = new Filesystem($adapter, new Config([
|
1285 |
+
'disable_asserts' => true,
|
1286 |
+
]));
|
1287 |
|
1288 |
+
/* Generate PHAR FILE
|
1289 |
$file = 'restore/vendor.built';
|
1290 |
|
1291 |
if(file_exists($file))
|
1301 |
$phar2->setStub($phar2->createDefaultStub('vendor/autoload.php', 'vendor/autoload.php'));
|
1302 |
* */
|
1303 |
|
1304 |
+
$tmp_file = $this->xcloner_settings->get_xcloner_tmp_path().DS."xcloner-restore.tgz";
|
1305 |
|
1306 |
+
$tar = new Tar();
|
1307 |
+
$tar->create($tmp_file);
|
1308 |
|
1309 |
+
$tar->addFile(dirname(__DIR__)."/restore/vendor.build.txt", "vendor.phar");
|
1310 |
+
//$tar->addFile(dirname(__DIR__)."/restore/vendor.tgz", "vendor.tgz");
|
1311 |
|
1312 |
+
$files = $xcloner_plugin_filesystem->listContents("vendor/", true);
|
1313 |
+
foreach ($files as $file) {
|
1314 |
+
$tar->addFile(dirname(__DIR__).DS.$file['path'], $file['path']);
|
1315 |
+
}
|
1316 |
|
1317 |
+
$content = file_get_contents(dirname(__DIR__)."/restore/xcloner_restore.php");
|
1318 |
+
$content = str_replace("define('AUTH_KEY', '');", "define('AUTH_KEY', '".md5(AUTH_KEY)."');", $content);
|
1319 |
|
1320 |
+
$tar->addData("xcloner_restore.php", $content);
|
1321 |
|
1322 |
+
$tar->close();
|
1323 |
|
1324 |
+
if (file_exists($tmp_file)) {
|
1325 |
+
header('Content-Description: File Transfer');
|
1326 |
+
header('Content-Type: application/octet-stream');
|
1327 |
+
header('Content-Disposition: attachment; filename="'.basename($tmp_file).'"');
|
1328 |
+
header('Expires: 0');
|
1329 |
+
header('Cache-Control: must-revalidate');
|
1330 |
+
header('Pragma: public');
|
1331 |
+
header('Content-Length: '.filesize($tmp_file));
|
1332 |
+
readfile($tmp_file);
|
1333 |
|
1334 |
+
}
|
1335 |
|
1336 |
+
try {
|
1337 |
+
unlink($tmp_file);
|
1338 |
+
}catch (Exception $e) {
|
1339 |
+
//We are not interested in the error here
|
1340 |
+
}
|
1341 |
|
1342 |
+
die();
|
1343 |
+
}
|
1344 |
+
|
1345 |
+
/*
|
1346 |
*
|
1347 |
* Download backup by Name from the Storage Path
|
1348 |
*
|
1349 |
*/
|
1350 |
+
public function download_backup_by_name()
|
1351 |
+
{
|
1352 |
+
$this->check_access();
|
1353 |
+
|
1354 |
+
ob_end_clean();
|
1355 |
|
1356 |
+
$backup_name = $this->xcloner_sanitization->sanitize_input_as_string($_GET['name']);
|
1357 |
|
|
|
1358 |
|
1359 |
+
$metadata = $this->xcloner_file_system->get_storage_filesystem()->getMetadata($backup_name);
|
1360 |
+
$read_stream = $this->xcloner_file_system->get_storage_filesystem()->readStream($backup_name);
|
1361 |
|
|
|
|
|
1362 |
|
1363 |
+
header('Pragma: public');
|
1364 |
+
header('Expires: 0');
|
1365 |
+
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
1366 |
+
header('Cache-Control: private', false);
|
1367 |
+
header('Content-Transfer-Encoding: binary');
|
1368 |
+
header('Content-Disposition: attachment; filename="'.$metadata['path'].'";');
|
1369 |
+
header('Content-Type: application/octet-stream');
|
1370 |
+
header('Content-Length: '.$metadata['size']);
|
1371 |
|
1372 |
+
ob_end_clean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1373 |
|
1374 |
+
$chunkSize = 1024 * 1024;
|
1375 |
+
while (!feof($read_stream)) {
|
1376 |
+
$buffer = fread($read_stream, $chunkSize);
|
1377 |
+
echo $buffer;
|
1378 |
+
}
|
1379 |
+
fclose($read_stream);
|
1380 |
|
1381 |
+
wp_die();
|
|
|
|
|
|
|
|
|
|
|
|
|
1382 |
|
1383 |
+
}
|
1384 |
|
1385 |
+
/*
|
1386 |
* Restore upload backup
|
1387 |
*/
|
1388 |
+
public function restore_upload_backup()
|
1389 |
+
{
|
1390 |
+
$this->check_access();
|
1391 |
+
|
1392 |
+
$return = array();
|
1393 |
|
1394 |
+
$return['part'] = 0;
|
1395 |
+
$return['total_parts'] = 0;
|
1396 |
+
$return['uploaded_size'] = 0;
|
1397 |
+
$is_multipart = 0;
|
1398 |
|
1399 |
+
$file = $this->xcloner_sanitization->sanitize_input_as_string($_POST['file']);
|
1400 |
+
$hash = $this->xcloner_sanitization->sanitize_input_as_string($_POST['hash']);
|
1401 |
|
1402 |
+
if (isset($_POST['part'])) {
|
1403 |
+
$return['part'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['part']);
|
1404 |
+
}
|
1405 |
|
1406 |
+
if (isset($_POST['uploaded_size'])) {
|
1407 |
+
$return['uploaded_size'] = $this->xcloner_sanitization->sanitize_input_as_int($_POST['uploaded_size']);
|
1408 |
+
}
|
1409 |
|
1410 |
+
$start = $this->xcloner_sanitization->sanitize_input_as_string($_POST['start']);
|
1411 |
+
$target_url = $this->xcloner_sanitization->sanitize_input_as_string($_POST['target_url']);
|
1412 |
|
1413 |
+
$return['total_size'] = $this->xcloner_file_system->get_backup_size($file);
|
1414 |
|
1415 |
+
if ($this->xcloner_file_system->is_multipart($file)) {
|
1416 |
+
$backup_parts = $this->xcloner_file_system->get_multipart_files($file);
|
1417 |
|
1418 |
+
$return['total_parts'] = sizeof($backup_parts) + 1;
|
1419 |
|
1420 |
+
if ($return['part'] and isset($backup_parts[$return['part'] - 1])) {
|
1421 |
+
$file = $backup_parts[$return['part'] - 1];
|
1422 |
+
}
|
1423 |
|
1424 |
+
$is_multipart = 1;
|
1425 |
+
}
|
1426 |
|
1427 |
+
try {
|
1428 |
|
1429 |
+
$xcloner_file_transfer = $this->get_xcloner_container()->get_xcloner_file_transfer();
|
1430 |
+
$xcloner_file_transfer->set_target($target_url);
|
1431 |
+
$return['start'] = $xcloner_file_transfer->transfer_file($file, $start, $hash);
|
1432 |
|
1433 |
+
}catch (Exception $e) {
|
1434 |
|
1435 |
+
$return = array();
|
1436 |
+
$return['error'] = true;
|
1437 |
+
$return['status'] = 500;
|
1438 |
+
$return['message'] = "CURL communication error with the restore host. ".$e->getMessage();
|
1439 |
+
$this->send_response($return, 0);
|
1440 |
|
1441 |
+
}
|
1442 |
|
1443 |
+
$return['status'] = 200;
|
1444 |
|
1445 |
+
//we have finished the upload
|
1446 |
+
if (!$return['start'] and $is_multipart) {
|
1447 |
+
$return['part']++;
|
1448 |
+
$return['uploaded_size'] += $this->xcloner_file_system->get_storage_filesystem()->getSize($file);
|
1449 |
+
}
|
1450 |
|
1451 |
+
$this->send_response($return, 0);
|
1452 |
+
}
|
1453 |
|
1454 |
+
/*
|
1455 |
* Restore backup
|
1456 |
*/
|
1457 |
+
public function restore_backup()
|
1458 |
+
{
|
1459 |
+
$this->check_access();
|
1460 |
|
1461 |
+
define("XCLONER_PLUGIN_ACCESS", 1);
|
1462 |
+
include_once(dirname(__DIR__).DS."restore".DS."xcloner_restore.php");
|
1463 |
|
1464 |
+
return;
|
1465 |
+
}
|
1466 |
|
1467 |
+
/*
|
1468 |
*
|
1469 |
* Send the json response back
|
1470 |
*
|
1471 |
*/
|
1472 |
+
private function send_response($data, $attach_hash = 1)
|
1473 |
+
{
|
1474 |
|
1475 |
+
if ($attach_hash and null !== $this->xcloner_settings->get_hash()) {
|
1476 |
+
$data['hash'] = $this->xcloner_settings->get_hash();
|
1477 |
+
}
|
1478 |
|
1479 |
+
if (ob_get_length()) {
|
1480 |
+
ob_clean();
|
1481 |
+
}
|
1482 |
+
wp_send_json($data);
|
1483 |
|
1484 |
+
}
|
|
|
1485 |
}
|
includes/class-xcloner-archive.php
CHANGED
@@ -36,171 +36,181 @@ use splitbrain\PHPArchive\FileInfo;
|
|
36 |
*/
|
37 |
class Xcloner_Archive extends Tar
|
38 |
{
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
|
66 |
/**
|
67 |
-
*
|
68 |
* @var string
|
69 |
*/
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
|
115 |
-
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
|
122 |
-
|
123 |
* Rename backup archive
|
124 |
*
|
125 |
* @param string $old_name
|
126 |
* @param string $new_name
|
127 |
*
|
128 |
*/
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
*
|
138 |
* Set the backup archive name
|
139 |
*
|
140 |
*/
|
141 |
-
|
142 |
-
|
143 |
|
144 |
-
|
145 |
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
|
154 |
-
|
|
|
|
|
155 |
|
156 |
-
|
157 |
|
158 |
-
|
159 |
-
$new_name = preg_replace('/-part(\d*)/', "-part" . $part, $this->archive_name);
|
160 |
-
if (!stristr($new_name, "-part")) {
|
161 |
-
$new_name = $this->archive_name . "-part" . $part;
|
162 |
-
}
|
163 |
|
164 |
-
|
165 |
-
|
|
|
|
|
|
|
166 |
|
167 |
-
|
168 |
-
|
169 |
|
170 |
-
|
|
|
|
|
|
|
171 |
*
|
172 |
* Returns the backup archive name
|
173 |
*
|
174 |
* @return string archive name
|
175 |
*/
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
|
181 |
-
|
182 |
*
|
183 |
* Returns the multipart naming for the backup archive
|
184 |
*
|
185 |
* @return string multi-part backup name
|
186 |
*/
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
|
193 |
-
|
194 |
*
|
195 |
* Returns the full backup name including extension
|
196 |
*
|
197 |
*/
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
|
203 |
-
|
204 |
*
|
205 |
* Send notification error by E-Mail
|
206 |
*
|
@@ -213,31 +223,35 @@ class Xcloner_Archive extends Tar
|
|
213 |
*
|
214 |
* @return bool
|
215 |
*/
|
216 |
-
public function send_notification_error($to, $from, $subject, $backup_name, $params, $error_message)
|
217 |
-
{
|
218 |
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
222 |
|
223 |
-
|
|
|
|
|
224 |
|
225 |
-
|
226 |
|
227 |
-
|
228 |
|
229 |
-
|
230 |
|
231 |
-
|
232 |
-
|
233 |
-
|
|
|
|
|
234 |
|
235 |
-
|
236 |
|
237 |
-
|
238 |
-
|
239 |
|
240 |
-
|
241 |
*
|
242 |
* Send backup archive notfication by E-Mail
|
243 |
*
|
@@ -251,480 +265,490 @@ class Xcloner_Archive extends Tar
|
|
251 |
*
|
252 |
* @return bool
|
253 |
*/
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
|
271 |
-
|
272 |
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
|
277 |
-
|
278 |
-
|
279 |
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
|
285 |
-
|
286 |
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
|
291 |
-
|
292 |
-
|
293 |
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
|
299 |
-
|
300 |
|
301 |
-
|
302 |
-
|
303 |
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
|
314 |
-
|
315 |
|
316 |
-
|
317 |
|
318 |
-
|
319 |
-
|
320 |
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
|
326 |
-
|
327 |
|
328 |
-
|
329 |
|
330 |
-
|
331 |
|
332 |
-
|
333 |
|
334 |
-
|
335 |
-
|
336 |
|
337 |
-
|
338 |
*
|
339 |
* Incremental Backup method
|
340 |
*
|
341 |
*/
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
|
350 |
-
|
351 |
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
|
|
|
|
|
|
|
|
357 |
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
|
362 |
-
|
363 |
-
|
364 |
|
365 |
-
|
366 |
|
367 |
-
|
368 |
-
|
369 |
|
370 |
-
|
371 |
|
372 |
-
|
373 |
|
374 |
-
|
375 |
-
|
376 |
|
377 |
-
|
378 |
|
379 |
-
|
380 |
|
381 |
-
|
382 |
|
383 |
-
|
384 |
-
|
385 |
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
|
402 |
-
|
403 |
|
404 |
-
|
405 |
|
406 |
-
|
407 |
|
408 |
-
|
409 |
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
|
417 |
-
|
418 |
|
419 |
-
|
420 |
|
421 |
-
|
422 |
|
423 |
-
|
424 |
|
425 |
-
|
426 |
-
|
427 |
|
428 |
-
|
429 |
|
430 |
-
|
431 |
|
432 |
-
|
433 |
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
|
438 |
-
|
439 |
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
|
451 |
-
|
452 |
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
|
461 |
-
|
462 |
|
463 |
-
|
464 |
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
|
473 |
-
|
474 |
|
475 |
-
|
476 |
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
|
489 |
-
|
490 |
-
|
491 |
|
492 |
-
|
493 |
|
494 |
-
|
495 |
-
|
496 |
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
|
538 |
-
|
539 |
-
|
540 |
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
|
553 |
-
|
554 |
-
|
555 |
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
|
560 |
-
|
561 |
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
|
567 |
-
|
568 |
-
|
569 |
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
|
574 |
-
|
575 |
*
|
576 |
* Write multipart file components
|
577 |
*
|
578 |
*/
|
579 |
-
|
580 |
-
|
581 |
-
|
|
|
|
|
582 |
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
|
587 |
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
|
592 |
-
|
593 |
*
|
594 |
* Create a new backup part
|
595 |
*
|
596 |
*/
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
|
621 |
-
|
622 |
|
623 |
-
|
624 |
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
|
630 |
-
|
631 |
|
632 |
-
|
633 |
|
634 |
-
|
635 |
*
|
636 |
* Add file to archive
|
637 |
*
|
638 |
*/
|
639 |
-
public function add_file_to_archive($file_info, $start_at_byte, $byte_limit = 0, $append, $filesystem)
|
640 |
-
{
|
641 |
-
|
642 |
-
$start_adapter = $this->filesystem->get_adapter($filesystem);
|
643 |
-
$start_filesystem = $this->filesystem->get_adapter($filesystem);
|
644 |
-
|
645 |
-
if (!$file_info['path']) {
|
646 |
-
return;
|
647 |
-
}
|
648 |
-
|
649 |
-
if (isset($file_info['archive_prefix_path'])) {
|
650 |
-
$file_info['target_path'] = $file_info['archive_prefix_path'] . "/" . $file_info['path'];
|
651 |
-
} else {
|
652 |
-
$file_info['target_path'] = $file_info['path'];
|
653 |
-
}
|
654 |
-
|
655 |
-
$last_position = $start_at_byte;
|
656 |
|
657 |
-
|
|
|
|
|
|
|
|
|
658 |
|
659 |
-
|
660 |
-
|
661 |
-
$this->logger->info(sprintf("Adding %s bytes of file %s to archive %s ", $bytes_wrote,
|
662 |
-
$file_info['target_path'], $this->get_archive_name_with_extension()));
|
663 |
-
$this->backup_archive->addFile($start_adapter->applyPathPrefix($file_info['path']),
|
664 |
-
$file_info['target_path']);
|
665 |
-
} else {
|
666 |
-
$tmp_file = md5($file_info['path']);
|
667 |
-
|
668 |
-
//we isolate file to tmp if we are at byte 0, the starting point of file reading
|
669 |
-
if (!$start_at_byte) {
|
670 |
-
$this->logger->info(sprintf("Copying %s file to tmp filesystem file %s to prevent reading changes",
|
671 |
-
$file_info['path'], $tmp_file));
|
672 |
-
$file_stream = $start_filesystem->readStream($file_info['path']);
|
673 |
-
|
674 |
-
if (is_resource($file_stream['stream'])) {
|
675 |
-
$this->filesystem->get_tmp_filesystem()->writeStream($tmp_file, $file_stream['stream']);
|
676 |
-
}
|
677 |
-
}
|
678 |
-
|
679 |
-
if ($this->filesystem->get_tmp_filesystem()->has($tmp_file)) {
|
680 |
-
$is_tmp = 1;
|
681 |
-
$last_position = $this->backup_archive->appendFileData($this->filesystem->get_tmp_filesystem_adapter()
|
682 |
-
->applyPathPrefix($tmp_file),
|
683 |
-
$file_info['target_path'], $start_at_byte, $byte_limit);
|
684 |
-
} else {
|
685 |
-
$is_tmp = 0;
|
686 |
-
$last_position = $this->backup_archive->appendFileData($start_adapter->applyPathPrefix($file_info['path']),
|
687 |
-
$file_info['target_path'], $start_at_byte, $byte_limit);
|
688 |
-
}
|
689 |
-
|
690 |
-
|
691 |
-
if ($last_position == -1) {
|
692 |
-
$bytes_wrote = $file_info['size'] - $start_at_byte;
|
693 |
-
} else {
|
694 |
-
$bytes_wrote = $last_position - $start_at_byte;
|
695 |
-
}
|
696 |
|
|
|
|
|
|
|
697 |
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
$bytes_wrote, $start_at_byte, $file_info['target_path'], $tmp_file, $this->get_archive_name()));
|
704 |
-
}
|
705 |
-
|
706 |
-
//we delete here the isolated tmp file
|
707 |
-
if ($last_position == -1) {
|
708 |
-
if ($this->filesystem->get_tmp_filesystem_adapter()->has($tmp_file)) {
|
709 |
-
$this->logger->info(sprintf("Deleting %s from the tmp filesystem", $tmp_file));
|
710 |
-
$this->filesystem->get_tmp_filesystem_adapter()->delete($tmp_file);
|
711 |
-
}
|
712 |
-
}
|
713 |
|
714 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
715 |
|
716 |
-
|
717 |
-
}
|
718 |
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
|
|
|
|
|
|
728 |
public function openForAppend($file = '')
|
729 |
{
|
730 |
$this->file = $file;
|
@@ -754,17 +778,17 @@ class Xcloner_Archive extends Tar
|
|
754 |
}
|
755 |
*/
|
756 |
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
* public function appendFileData($file, $fileinfo = '', $start = 0, $limit = 0)
|
769 |
{
|
770 |
$end = $start+($limit*512);
|
@@ -820,15 +844,15 @@ class Xcloner_Archive extends Tar
|
|
820 |
return $last_position;
|
821 |
}*/
|
822 |
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
{
|
833 |
$this->openForAppend($archive);
|
834 |
return $start = $this->appendFileData($file, $start, $this->file_size_per_request_limit);
|
36 |
*/
|
37 |
class Xcloner_Archive extends Tar
|
38 |
{
|
39 |
+
/**
|
40 |
+
* Process file size per API request
|
41 |
+
* @var float|int
|
42 |
+
*/
|
43 |
+
private $file_size_per_request_limit = 52428800; //50MB = 52428800; 1MB = 1048576
|
44 |
+
/**
|
45 |
+
* Files count to process per API request
|
46 |
+
* @var int
|
47 |
+
*/
|
48 |
+
private $files_to_process_per_request = 250; //block of 512 bytes
|
49 |
+
/**
|
50 |
+
* Compression level, 0-uncompressed, 9-maximum compression
|
51 |
+
* @var int
|
52 |
+
*/
|
53 |
+
private $compression_level = 0; //0-9 , 0 uncompressed
|
54 |
+
/**
|
55 |
+
* Split backup size limit
|
56 |
+
* Create a new backup archive file once the set size is reached
|
57 |
+
* @var float|int
|
58 |
+
*/
|
59 |
+
private $xcloner_split_backup_limit = 2048; //2048MB
|
60 |
+
/**
|
61 |
+
* Number of processed bytes
|
62 |
+
* @var int
|
63 |
+
*/
|
64 |
+
private $processed_size_bytes = 0;
|
65 |
|
66 |
/**
|
67 |
+
* The backup name encryption suffix
|
68 |
* @var string
|
69 |
*/
|
70 |
+
private $encrypt_suffix = "-enc";
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Archive name
|
74 |
+
* @var string
|
75 |
+
*/
|
76 |
+
private $archive_name;
|
77 |
+
/**
|
78 |
+
* @var Tar
|
79 |
+
*/
|
80 |
+
private $backup_archive;
|
81 |
+
/**
|
82 |
+
* @var Xcloner_File_System
|
83 |
+
*/
|
84 |
+
private $filesystem;
|
85 |
+
/**
|
86 |
+
* @var Xcloner_Logger
|
87 |
+
*/
|
88 |
+
private $logger;
|
89 |
+
/**
|
90 |
+
* @var Xcloner_Settings
|
91 |
+
*/
|
92 |
+
private $xcloner_settings;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* [__construct description]
|
96 |
+
* @param Xcloner $xcloner_container XCloner Container
|
97 |
+
* @param string $archive_name Achive Name
|
98 |
+
*/
|
99 |
+
public function __construct(Xcloner $xcloner_container, $archive_name = "")
|
100 |
+
{
|
101 |
+
$this->filesystem = $xcloner_container->get_xcloner_filesystem();
|
102 |
+
$this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_archive");
|
103 |
+
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
104 |
+
|
105 |
+
if ($value = $this->xcloner_settings->get_xcloner_option('xcloner_size_limit_per_request')) {
|
106 |
+
$this->file_size_per_request_limit = $value * 1024 * 1024;
|
107 |
+
} //MB
|
108 |
+
|
109 |
+
if ($value = $this->xcloner_settings->get_xcloner_option('xcloner_files_to_process_per_request')) {
|
110 |
+
$this->files_to_process_per_request = $value;
|
111 |
+
}
|
112 |
|
113 |
+
if ($value = get_option('xcloner_backup_compression_level')) {
|
114 |
+
$this->compression_level = $value;
|
115 |
+
}
|
116 |
|
117 |
+
if ($value = get_option('xcloner_split_backup_limit')) {
|
118 |
+
$this->xcloner_split_backup_limit = $value;
|
119 |
+
}
|
120 |
|
121 |
+
$this->xcloner_split_backup_limit = $this->xcloner_split_backup_limit * 1024 * 1024; //transform to bytes
|
122 |
|
123 |
+
if (isset($archive_name) && $archive_name) {
|
124 |
+
$this->set_archive_name($archive_name);
|
125 |
+
}
|
126 |
+
}
|
127 |
|
128 |
+
/*
|
129 |
* Rename backup archive
|
130 |
*
|
131 |
* @param string $old_name
|
132 |
* @param string $new_name
|
133 |
*
|
134 |
*/
|
135 |
+
public function rename_archive($old_name, $new_name)
|
136 |
+
{
|
137 |
+
$this->logger->info(sprintf("Renaming backup archive %s to %s", $old_name, $new_name));
|
138 |
+
$storage_filesystem = $this->filesystem->get_storage_filesystem();
|
139 |
+
$storage_filesystem->rename($old_name, $new_name);
|
140 |
+
}
|
141 |
+
|
142 |
+
/*
|
143 |
*
|
144 |
* Set the backup archive name
|
145 |
*
|
146 |
*/
|
147 |
+
public function set_archive_name($name = "", $part = 0, $encrypt_prefix = false)
|
148 |
+
{
|
149 |
|
150 |
+
$this->archive_name = $this->filesystem->process_backup_name($name);
|
151 |
|
152 |
+
if($encrypt_prefix) {
|
153 |
+
$this->archive_name .= $this->encrypt_suffix;
|
154 |
+
}
|
155 |
|
156 |
+
if ($diff_timestamp_start = $this->filesystem->get_diff_timestamp_start()) {
|
157 |
+
//$this->archive_name = $this->archive_name."-diff-".date("Y-m-d_H-i",$diff_timestamp_start);
|
158 |
+
$new_name = $this->archive_name;
|
159 |
|
160 |
+
if (!stristr($new_name, "-diff")) {
|
161 |
+
$new_name = $this->archive_name."-diff".date("Y-m-d_H-i", $diff_timestamp_start);
|
162 |
+
}
|
163 |
|
164 |
+
$this->archive_name = $new_name;
|
165 |
|
166 |
+
}
|
|
|
|
|
|
|
|
|
167 |
|
168 |
+
if (isset($part) and $part) {
|
169 |
+
$new_name = preg_replace('/-part(\d*)/', "-part".$part, $this->archive_name);
|
170 |
+
if (!stristr($new_name, "-part")) {
|
171 |
+
$new_name = $this->archive_name."-part".$part;
|
172 |
+
}
|
173 |
|
174 |
+
$this->archive_name = $new_name;
|
175 |
+
}
|
176 |
|
177 |
+
return $this;
|
178 |
+
}
|
179 |
+
|
180 |
+
/*
|
181 |
*
|
182 |
* Returns the backup archive name
|
183 |
*
|
184 |
* @return string archive name
|
185 |
*/
|
186 |
+
public function get_archive_name()
|
187 |
+
{
|
188 |
+
return $this->archive_name;
|
189 |
+
}
|
190 |
|
191 |
+
/*
|
192 |
*
|
193 |
* Returns the multipart naming for the backup archive
|
194 |
*
|
195 |
* @return string multi-part backup name
|
196 |
*/
|
197 |
+
public function get_archive_name_multipart()
|
198 |
+
{
|
199 |
+
$new_name = preg_replace('/-part(\d*)/', "", $this->archive_name);
|
200 |
+
return $new_name."-multipart".$this->xcloner_settings->get_backup_extension_name(".csv");
|
201 |
+
}
|
202 |
|
203 |
+
/*
|
204 |
*
|
205 |
* Returns the full backup name including extension
|
206 |
*
|
207 |
*/
|
208 |
+
public function get_archive_name_with_extension()
|
209 |
+
{
|
210 |
+
return $this->archive_name.$this->xcloner_settings->get_backup_extension_name();
|
211 |
+
}
|
212 |
|
213 |
+
/*
|
214 |
*
|
215 |
* Send notification error by E-Mail
|
216 |
*
|
223 |
*
|
224 |
* @return bool
|
225 |
*/
|
|
|
|
|
226 |
|
227 |
+
/**
|
228 |
+
* @param string $error_message
|
229 |
+
*/
|
230 |
+
public function send_notification_error($to, $from, $subject, $backup_name, $params, $error_message)
|
231 |
+
{
|
232 |
|
233 |
+
$body = "";
|
234 |
+
$body .= sprintf(__("Backup Site Url: %s"), get_site_url());
|
235 |
+
$body .= "<br /><>";
|
236 |
|
237 |
+
$body .= sprintf(__("Error Message: %s"), $error_message);
|
238 |
|
239 |
+
$this->logger->info(sprintf("Sending backup error notification to %s", $to));
|
240 |
|
241 |
+
$admin_email = get_option("admin_email");
|
242 |
|
243 |
+
$headers = array('Content-Type: text/html; charset=UTF-8');
|
244 |
+
|
245 |
+
if ($admin_email and $from) {
|
246 |
+
$headers[] = 'From: '.$from.' <'.$admin_email.'>';
|
247 |
+
}
|
248 |
|
249 |
+
$return = wp_mail($to, $subject, $body, $headers);
|
250 |
|
251 |
+
return $return;
|
252 |
+
}
|
253 |
|
254 |
+
/*
|
255 |
*
|
256 |
* Send backup archive notfication by E-Mail
|
257 |
*
|
265 |
*
|
266 |
* @return bool
|
267 |
*/
|
268 |
+
public function send_notification(
|
269 |
+
$to,
|
270 |
+
$from,
|
271 |
+
$subject,
|
272 |
+
$backup_name,
|
273 |
+
$params,
|
274 |
+
$error_message = "",
|
275 |
+
$additional = array()
|
276 |
+
) {
|
277 |
+
if (!$from) {
|
278 |
+
$from = "XCloner Backup";
|
279 |
+
}
|
280 |
|
281 |
+
if (($error_message)) {
|
282 |
+
return $this->send_notification_error($to, $from, $subject, $backup_name, $params, $error_message);
|
283 |
+
}
|
284 |
|
285 |
+
$params = (array)$params;
|
286 |
|
287 |
+
if (!$subject) {
|
288 |
+
$subject = sprintf(__("New backup generated %s"), $backup_name);
|
289 |
+
}
|
290 |
|
291 |
+
$body = sprintf(__("Generated Backup Size: %s"), size_format($this->filesystem->get_backup_size($backup_name)));
|
292 |
+
$body .= "<br /><br />";
|
293 |
|
294 |
+
if (isset($additional['lines_total'])) {
|
295 |
+
$body .= sprintf(__("Total files added: %s"), $additional['lines_total']);
|
296 |
+
$body .= "<br /><br />";
|
297 |
+
}
|
298 |
|
299 |
+
$backup_parts = $this->filesystem->get_multipart_files($backup_name);
|
300 |
|
301 |
+
if (!$backups_counter = sizeof($backup_parts)) {
|
302 |
+
$backups_counter = 1;
|
303 |
+
}
|
304 |
|
305 |
+
$body .= sprintf(__("Backup Parts: %s"), $backups_counter);
|
306 |
+
$body .= "<br />";
|
307 |
|
308 |
+
if (sizeof($backup_parts)) {
|
309 |
+
$body .= implode("<br />", $backup_parts);
|
310 |
+
$body .= "<br />";
|
311 |
+
}
|
312 |
|
313 |
+
$body .= "<br />";
|
314 |
|
315 |
+
$body .= sprintf(__("Backup Site Url: %s"), get_site_url());
|
316 |
+
$body .= "<br />";
|
317 |
|
318 |
+
if (isset($params['backup_params']->backup_comments)) {
|
319 |
+
$body .= __("Backup Comments: ").$params['backup_params']->backup_comments;
|
320 |
+
$body .= "<br /><br />";
|
321 |
+
}
|
322 |
|
323 |
+
if ($this->xcloner_settings->get_xcloner_option('xcloner_enable_log')) {
|
324 |
+
$body .= __("Latest 50 Log Lines: ")."<br />".implode("<br />\n",
|
325 |
+
$this->logger->getLastDebugLines(50));
|
326 |
+
}
|
327 |
|
328 |
+
$attachments = $this->filesystem->get_backup_attachments();
|
329 |
|
330 |
+
$attachments_archive = $this->xcloner_settings->get_xcloner_tmp_path().DS."info.tgz";
|
331 |
|
332 |
+
$tar = new Tar();
|
333 |
+
$tar->create($attachments_archive);
|
334 |
|
335 |
+
foreach ($attachments as $key => $file) {
|
336 |
+
$tar->addFile($file, basename($file));
|
337 |
+
}
|
338 |
+
$tar->close();
|
339 |
|
340 |
+
$this->logger->info(sprintf("Sending backup notification to %s", $to));
|
341 |
|
342 |
+
$admin_email = get_option("admin_email");
|
343 |
|
344 |
+
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: '.$from.' <'.$admin_email.'>');
|
345 |
|
346 |
+
$return = wp_mail($to, $subject, $body, $headers, array($attachments_archive));
|
347 |
|
348 |
+
return $return;
|
349 |
+
}
|
350 |
|
351 |
+
/*
|
352 |
*
|
353 |
* Incremental Backup method
|
354 |
*
|
355 |
*/
|
356 |
+
public function start_incremental_backup($backup_params, $extra_params, $init)
|
357 |
+
{
|
358 |
+
$return = array();
|
359 |
|
360 |
+
if (!isset($extra_params['backup_part'])) {
|
361 |
+
$extra_params['backup_part'] = 0;
|
362 |
+
}
|
363 |
|
364 |
+
$return['extra']['backup_part'] = $extra_params['backup_part'];
|
365 |
|
366 |
+
if (isset($extra_params['backup_archive_name'])) {
|
367 |
+
$this->set_archive_name($extra_params['backup_archive_name'], $return['extra']['backup_part']);
|
368 |
+
} else {
|
369 |
+
$encrypt = false;
|
370 |
+
if(isset($backup_params['backup_encrypt']) && $backup_params['backup_encrypt']) {
|
371 |
+
$encrypt = true;
|
372 |
+
}
|
373 |
+
$this->set_archive_name($backup_params['backup_name'], 0, $encrypt);
|
374 |
+
}
|
375 |
|
376 |
+
if (!$this->get_archive_name()) {
|
377 |
+
$this->set_archive_name();
|
378 |
+
}
|
379 |
|
380 |
+
$this->backup_archive = new Tar();
|
381 |
+
$this->backup_archive->setCompression($this->compression_level);
|
382 |
|
383 |
+
$archive_info = $this->filesystem->get_storage_path_file_info($this->get_archive_name_with_extension());
|
384 |
|
385 |
+
if ($init) {
|
386 |
+
$this->logger->info(sprintf(__("Initializing the backup archive %s"), $this->get_archive_name()));
|
387 |
|
388 |
+
$this->backup_archive->create($archive_info->getPath().DS.$archive_info->getFilename());
|
389 |
|
390 |
+
$return['extra']['backup_init'] = 1;
|
391 |
|
392 |
+
} else {
|
393 |
+
$this->logger->info(sprintf(__("Opening for append the backup archive %s"), $this->get_archive_name()));
|
394 |
|
395 |
+
$this->backup_archive->openForAppend($archive_info->getPath().DS.$archive_info->getFilename());
|
396 |
|
397 |
+
$return['extra']['backup_init'] = 0;
|
398 |
|
399 |
+
}
|
400 |
|
401 |
+
$return['extra']['backup_archive_name'] = $this->get_archive_name();
|
402 |
+
$return['extra']['backup_archive_name_full'] = $this->get_archive_name_with_extension();
|
403 |
|
404 |
+
if (!isset($extra_params['start_at_line'])) {
|
405 |
+
$extra_params['start_at_line'] = 0;
|
406 |
+
}
|
407 |
|
408 |
+
if (!isset($extra_params['start_at_byte'])) {
|
409 |
+
$extra_params['start_at_byte'] = 0;
|
410 |
+
}
|
411 |
|
412 |
+
if (!$this->filesystem->get_tmp_filesystem()->has($this->filesystem->get_included_files_handler())) {
|
413 |
+
$this->logger->error(sprintf("Missing the includes file handler %s, aborting...",
|
414 |
+
$this->filesystem->get_included_files_handler()));
|
415 |
|
416 |
+
$return['finished'] = 1;
|
417 |
+
return $return;
|
418 |
+
}
|
419 |
|
420 |
+
$included_files_handler = $this->filesystem->get_included_files_handler(1);
|
421 |
|
422 |
+
$file = new SplFileObject($included_files_handler);
|
423 |
|
424 |
+
$file->seek(PHP_INT_MAX);
|
425 |
|
426 |
+
$return['extra']['lines_total'] = ($file->key() - 1);
|
427 |
|
428 |
+
//we skip the first CSV line with headers
|
429 |
+
if (!$extra_params['start_at_line']) {
|
430 |
+
$file->seek(1);
|
431 |
+
} else {
|
432 |
+
$file->seek($extra_params['start_at_line'] + 1);
|
433 |
+
}
|
434 |
|
435 |
+
$this->processed_size_bytes = 0;
|
436 |
|
437 |
+
$counter = 0;
|
438 |
|
439 |
+
$start_byte = $extra_params['start_at_byte'];
|
440 |
|
441 |
+
$byte_limit = 0;
|
442 |
|
443 |
+
while (!$file->eof() and $counter <= $this->files_to_process_per_request) {
|
444 |
+
$current_line_str = $file->current();
|
445 |
|
446 |
+
$line = str_getcsv($current_line_str);
|
447 |
|
448 |
+
$relative_path = stripslashes($line[0]);
|
449 |
|
450 |
+
$start_filesystem = "start_filesystem";
|
451 |
|
452 |
+
if (isset($line[4])) {
|
453 |
+
$start_filesystem = $line[4];
|
454 |
+
}
|
455 |
|
456 |
+
//$adapter = $this->filesystem->get_adapter($start_filesystem);
|
457 |
|
458 |
+
if (!$relative_path || !$this->filesystem->get_filesystem($start_filesystem)->has($relative_path)) {
|
459 |
+
if ($relative_path != "") {
|
460 |
+
$this->logger->error(sprintf("Could not add file %b to backup archive, file not found",
|
461 |
+
$relative_path));
|
462 |
+
}
|
463 |
|
464 |
+
$extra_params['start_at_line']++;
|
465 |
+
$file->next();
|
466 |
+
continue;
|
467 |
+
}
|
468 |
|
469 |
+
$file_info = $this->filesystem->get_filesystem($start_filesystem)->getMetadata($relative_path);
|
470 |
|
471 |
+
if (!isset($file_info['size'])) {
|
472 |
+
$file_info['size'] = 0;
|
473 |
+
}
|
474 |
|
475 |
+
if ($start_filesystem == "tmp_filesystem") {
|
476 |
+
$file_info['archive_prefix_path'] = $this->xcloner_settings->get_xcloner_tmp_path_suffix();
|
477 |
+
}
|
478 |
|
479 |
+
$byte_limit = (int)$this->file_size_per_request_limit / 512;
|
480 |
|
481 |
+
$append = 0;
|
482 |
|
483 |
+
if ($file_info['size'] > $byte_limit * 512 or $start_byte) {
|
484 |
+
$append = 1;
|
485 |
+
}
|
486 |
|
487 |
+
if (!isset($return['extra']['backup_size'])) {
|
488 |
+
$return['extra']['backup_size'] = 0;
|
489 |
+
}
|
490 |
|
491 |
+
$return['extra']['backup_size'] = $archive_info->getSize();
|
492 |
|
493 |
+
$estimated_new_size = $return['extra']['backup_size'] + $file_info['size'];
|
494 |
|
495 |
+
//we create a new backup part if we reach the Split Achive Limit
|
496 |
+
if ($this->xcloner_split_backup_limit and ($estimated_new_size > $this->xcloner_split_backup_limit) and (!$start_byte)) {
|
497 |
+
$this->logger->info(sprintf("Backup size limit %s bytes reached, file add estimate %s, attempt to create a new archive ",
|
498 |
+
$this->xcloner_split_backup_limit, $estimated_new_size));
|
499 |
+
list($archive_info, $return['extra']['backup_part']) = $this->create_new_backup_part($return['extra']['backup_part']);
|
500 |
|
501 |
+
if ($file_info['size'] > $this->xcloner_split_backup_limit) {
|
502 |
+
$this->logger->info(sprintf("Excluding %s file as it's size(%s) is bigger than the backup split limit of %s and it won't fit a single backup file",
|
503 |
+
$file_info['path'], $file_info['size'], $this->xcloner_split_backup_limit));
|
504 |
+
$extra_params['start_at_line']++;
|
505 |
+
}
|
506 |
|
507 |
+
$return['extra']['start_at_line'] = $extra_params['start_at_line'];
|
508 |
+
$return['extra']['start_at_byte'] = 0;
|
509 |
|
510 |
+
$return['finished'] = 0;
|
511 |
|
512 |
+
return $return;
|
513 |
+
}
|
514 |
|
515 |
+
list($bytes_wrote, $last_position) = $this->add_file_to_archive($file_info, $start_byte, $byte_limit,
|
516 |
+
$append, $start_filesystem);
|
517 |
+
$this->processed_size_bytes += $bytes_wrote;
|
518 |
|
519 |
+
//echo" - processed ".$this->processed_size_bytes." bytes ".$this->file_size_per_request_limit." last_position:".$last_position." \n";
|
520 |
+
$return['extra']['processed_file'] = $file_info['path'];
|
521 |
+
$return['extra']['processed_file_size'] = $file_info['size'];
|
522 |
+
$return['extra']['backup_size'] = $archive_info->getSize();
|
523 |
|
524 |
+
if ($last_position > 0) {
|
525 |
+
$start_byte = $last_position;
|
526 |
+
} else {
|
527 |
+
$extra_params['start_at_line']++;
|
528 |
+
$file->next();
|
529 |
+
$start_byte = 0;
|
530 |
+
$counter++;
|
531 |
+
}
|
532 |
|
533 |
+
if ($this->processed_size_bytes >= $this->file_size_per_request_limit) {
|
534 |
+
clearstatcache();
|
535 |
+
$return['extra']['backup_size'] = $archive_info->getSize();
|
536 |
|
537 |
+
$return['finished'] = 0;
|
538 |
+
$return['extra']['start_at_line'] = $extra_params['start_at_line'];
|
539 |
+
$return['extra']['start_at_byte'] = $last_position;
|
540 |
+
$this->logger->info(sprintf("Reached the maximum %s request data limit, returning response",
|
541 |
+
$this->file_size_per_request_limit));
|
542 |
+
return $return;
|
543 |
+
}
|
544 |
+
}
|
545 |
|
546 |
+
if (!$file->eof()) {
|
547 |
+
clearstatcache();
|
548 |
+
$return['extra']['backup_size'] = $archive_info->getSize();
|
549 |
|
550 |
+
$return['finished'] = 0;
|
551 |
+
$return['extra']['start_at_line'] = $extra_params['start_at_line'];
|
552 |
+
$return['extra']['start_at_byte'] = $last_position;
|
553 |
+
$this->logger->info(sprintf("We have reached the maximum files to process per request limit of %s, returning response",
|
554 |
+
$this->files_to_process_per_request));
|
555 |
|
556 |
+
return $return;
|
557 |
+
}
|
558 |
|
559 |
+
//close the backup archive by adding 2*512 blocks of zero bytes
|
560 |
+
$this->logger->info(sprintf("Closing the backup archive %s with 2*512 zero bytes blocks.",
|
561 |
+
$this->get_archive_name_with_extension()));
|
562 |
+
$this->backup_archive->close();
|
563 |
|
564 |
+
/**
|
565 |
+
* XCloner HOOK backup_archive_finished.
|
566 |
+
*
|
567 |
+
* This will get triggered when a backup archive is finished writing.
|
568 |
+
*/
|
569 |
+
//do_action('backup_archive_finished', $this->backup_archive, $this);
|
570 |
|
571 |
+
//updating archive_info
|
572 |
+
$archive_info = $this->filesystem->get_storage_path_file_info($this->get_archive_name_with_extension());
|
573 |
|
574 |
+
if ($return['extra']['backup_part']) {
|
575 |
+
$this->write_multipart_file($this->get_archive_name_with_extension());
|
576 |
+
}
|
577 |
|
578 |
+
$return['extra']['start_at_line'] = $extra_params['start_at_line'] - 1;
|
579 |
|
580 |
+
if (isset($file_info)) {
|
581 |
+
$return['extra']['processed_file'] = $file_info['path'];
|
582 |
+
$return['extra']['processed_file_size'] = $file_info['size'];
|
583 |
+
}
|
584 |
|
585 |
+
clearstatcache();
|
586 |
+
$return['extra']['backup_size'] = $archive_info->getSize();
|
587 |
|
588 |
+
$return['finished'] = 1;
|
589 |
+
return $return;
|
590 |
+
}
|
591 |
|
592 |
+
/*
|
593 |
*
|
594 |
* Write multipart file components
|
595 |
*
|
596 |
*/
|
597 |
+
private function write_multipart_file($path = "")
|
598 |
+
{
|
599 |
+
if (!$path) {
|
600 |
+
$path = $this->get_archive_name_with_extension();
|
601 |
+
}
|
602 |
|
603 |
+
$file = $this->filesystem->get_filesystem("storage_filesystem_append")->getMetadata($path);
|
604 |
+
//print_r($file_info);
|
605 |
+
$line = '"'.$file['path'].'","'.$file['timestamp'].'","'.$file['size'].'"'.PHP_EOL;
|
606 |
|
607 |
|
608 |
+
$this->filesystem->get_filesystem("storage_filesystem_append")
|
609 |
+
->write($this->get_archive_name_multipart(), $line);
|
610 |
+
}
|
611 |
|
612 |
+
/*
|
613 |
*
|
614 |
* Create a new backup part
|
615 |
*
|
616 |
*/
|
617 |
+
private function create_new_backup_part($part = 0)
|
618 |
+
{
|
619 |
+
//close the backup archive by adding 2*512 blocks of zero bytes
|
620 |
+
$this->logger->info(sprintf("Closing the backup archive %s with 2*512 zero bytes blocks.",
|
621 |
+
$this->get_archive_name_with_extension()));
|
622 |
+
$this->backup_archive->close();
|
623 |
+
|
624 |
+
if (!$part) {
|
625 |
+
$old_name = $this->get_archive_name_with_extension();
|
626 |
+
$this->set_archive_name($this->get_archive_name(), ++$part);
|
627 |
+
$this->rename_archive($old_name, $this->get_archive_name_with_extension());
|
628 |
+
|
629 |
+
if ($this->filesystem->get_storage_filesystem()->has($this->get_archive_name_multipart())) {
|
630 |
+
$this->filesystem->get_storage_filesystem()->delete($this->get_archive_name_multipart());
|
631 |
+
}
|
632 |
+
|
633 |
+
$this->write_multipart_file($this->get_archive_name_with_extension());
|
634 |
+
|
635 |
+
} else {
|
636 |
+
$this->logger->info(sprintf("Creating new multipart info file %s",
|
637 |
+
$this->get_archive_name_with_extension()));
|
638 |
+
$this->write_multipart_file($this->get_archive_name_with_extension());
|
639 |
+
}
|
640 |
|
641 |
+
$this->set_archive_name($this->get_archive_name(), ++$part);
|
642 |
|
643 |
+
$this->logger->info(sprintf("Creating new backup archive part %s", $this->get_archive_name_with_extension()));
|
644 |
|
645 |
+
$this->backup_archive = new Tar();
|
646 |
+
$this->backup_archive->setCompression($this->compression_level);
|
647 |
+
$archive_info = $this->filesystem->get_storage_path_file_info($this->get_archive_name_with_extension());
|
648 |
+
$this->backup_archive->create($archive_info->getPath().DS.$archive_info->getFilename());
|
649 |
|
650 |
+
return array($archive_info, $part);
|
651 |
|
652 |
+
}
|
653 |
|
654 |
+
/*
|
655 |
*
|
656 |
* Add file to archive
|
657 |
*
|
658 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
659 |
|
660 |
+
/**
|
661 |
+
* @param integer $append
|
662 |
+
*/
|
663 |
+
public function add_file_to_archive($file_info, $start_at_byte, $byte_limit = 0, $append, $filesystem)
|
664 |
+
{
|
665 |
|
666 |
+
$start_adapter = $this->filesystem->get_adapter($filesystem);
|
667 |
+
$start_filesystem = $this->filesystem->get_adapter($filesystem);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
668 |
|
669 |
+
if (!$file_info['path']) {
|
670 |
+
return;
|
671 |
+
}
|
672 |
|
673 |
+
if (isset($file_info['archive_prefix_path'])) {
|
674 |
+
$file_info['target_path'] = $file_info['archive_prefix_path']."/".$file_info['path'];
|
675 |
+
} else {
|
676 |
+
$file_info['target_path'] = $file_info['path'];
|
677 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
678 |
|
679 |
+
$last_position = $start_at_byte;
|
680 |
+
|
681 |
+
//$start_adapter = $this->filesystem->get_start_adapter();
|
682 |
+
|
683 |
+
if (!$append) {
|
684 |
+
$bytes_wrote = $file_info['size'];
|
685 |
+
$this->logger->info(sprintf("Adding %s bytes of file %s to archive %s ", $bytes_wrote,
|
686 |
+
$file_info['target_path'], $this->get_archive_name_with_extension()));
|
687 |
+
$this->backup_archive->addFile($start_adapter->applyPathPrefix($file_info['path']),
|
688 |
+
$file_info['target_path']);
|
689 |
+
} else {
|
690 |
+
$tmp_file = md5($file_info['path']);
|
691 |
+
|
692 |
+
//we isolate file to tmp if we are at byte 0, the starting point of file reading
|
693 |
+
if (!$start_at_byte) {
|
694 |
+
$this->logger->info(sprintf("Copying %s file to tmp filesystem file %s to prevent reading changes",
|
695 |
+
$file_info['path'], $tmp_file));
|
696 |
+
$file_stream = $start_filesystem->readStream($file_info['path']);
|
697 |
+
|
698 |
+
if (is_resource($file_stream['stream'])) {
|
699 |
+
$this->filesystem->get_tmp_filesystem()->writeStream($tmp_file, $file_stream['stream']);
|
700 |
+
}
|
701 |
+
}
|
702 |
+
|
703 |
+
if ($this->filesystem->get_tmp_filesystem()->has($tmp_file)) {
|
704 |
+
$is_tmp = 1;
|
705 |
+
$last_position = $this->backup_archive->appendFileData($this->filesystem->get_tmp_filesystem_adapter()
|
706 |
+
->applyPathPrefix($tmp_file),
|
707 |
+
$file_info['target_path'], $start_at_byte, $byte_limit);
|
708 |
+
} else {
|
709 |
+
$is_tmp = 0;
|
710 |
+
$last_position = $this->backup_archive->appendFileData($start_adapter->applyPathPrefix($file_info['path']),
|
711 |
+
$file_info['target_path'], $start_at_byte, $byte_limit);
|
712 |
+
}
|
713 |
+
|
714 |
+
|
715 |
+
if ($last_position == -1) {
|
716 |
+
$bytes_wrote = $file_info['size'] - $start_at_byte;
|
717 |
+
} else {
|
718 |
+
$bytes_wrote = $last_position - $start_at_byte;
|
719 |
+
}
|
720 |
+
|
721 |
+
|
722 |
+
if ($is_tmp) {
|
723 |
+
$this->logger->info(sprintf("Appended %s bytes, starting position %s, of tmp file %s (%s) to archive %s ",
|
724 |
+
$bytes_wrote, $start_at_byte, $tmp_file, $file_info['target_path'], $this->get_archive_name()));
|
725 |
+
} else {
|
726 |
+
$this->logger->info(sprintf("Appended %s bytes, starting position %s, of original file %s to archive %s ",
|
727 |
+
$bytes_wrote, $start_at_byte, $file_info['target_path'], $tmp_file, $this->get_archive_name()));
|
728 |
+
}
|
729 |
+
|
730 |
+
//we delete here the isolated tmp file
|
731 |
+
if ($last_position == -1) {
|
732 |
+
if ($this->filesystem->get_tmp_filesystem_adapter()->has($tmp_file)) {
|
733 |
+
$this->logger->info(sprintf("Deleting %s from the tmp filesystem", $tmp_file));
|
734 |
+
$this->filesystem->get_tmp_filesystem_adapter()->delete($tmp_file);
|
735 |
+
}
|
736 |
+
}
|
737 |
|
738 |
+
}
|
|
|
739 |
|
740 |
+
return array($bytes_wrote, $last_position);
|
741 |
+
}
|
742 |
+
|
743 |
+
/**
|
744 |
+
* Open a TAR archive and put the file cursor at the end for data appending
|
745 |
+
*
|
746 |
+
* If $file is empty, the tar file will be created in memory
|
747 |
+
*
|
748 |
+
* @param string $file
|
749 |
+
* @throws ArchiveIOException
|
750 |
+
*/
|
751 |
+
/*
|
752 |
public function openForAppend($file = '')
|
753 |
{
|
754 |
$this->file = $file;
|
778 |
}
|
779 |
*/
|
780 |
|
781 |
+
/**
|
782 |
+
* Append data to a file to the current TAR archive using an existing file in the filesystem
|
783 |
+
*
|
784 |
+
* @param string $file path to the original file
|
785 |
+
* @param int $start starting reading position in file
|
786 |
+
* @param int $end end position in reading multiple with 512
|
787 |
+
* @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with
|
788 |
+
* all meta data, empty to take from original
|
789 |
+
* @throws ArchiveIOException
|
790 |
+
*/
|
791 |
+
/*
|
792 |
* public function appendFileData($file, $fileinfo = '', $start = 0, $limit = 0)
|
793 |
{
|
794 |
$end = $start+($limit*512);
|
844 |
return $last_position;
|
845 |
}*/
|
846 |
|
847 |
+
/**
|
848 |
+
* Adds a file to a TAR archive by appending it's data
|
849 |
+
*
|
850 |
+
* @param string $archive name of the archive file
|
851 |
+
* @param string $file name of the file to read data from
|
852 |
+
* @param string $start start position from where to start reading data
|
853 |
+
* @throws ArchiveIOException
|
854 |
+
*/
|
855 |
+
/*public function addFileToArchive($archive, $file, $start = 0)
|
856 |
{
|
857 |
$this->openForAppend($archive);
|
858 |
return $start = $this->appendFileData($file, $start, $this->file_size_per_request_limit);
|
includes/class-xcloner-database.php
CHANGED
@@ -21,41 +21,42 @@
|
|
21 |
*/
|
22 |
|
23 |
|
24 |
-
class Xcloner_Database extends wpdb{
|
25 |
|
26 |
|
27 |
-
public $debug
|
28 |
-
public $recordsPerSession
|
29 |
-
public $dbCompatibility
|
30 |
public $dbDropSyntax = 1;
|
31 |
public $countRecords = 0;
|
32 |
|
33 |
private $link;
|
34 |
private $db_selected;
|
35 |
private $logger;
|
|
|
36 |
private $fs;
|
37 |
|
38 |
private $TEMP_DBPROCESS_FILE = ".database";
|
39 |
private $TEMP_DUMP_FILE = "database-backup.sql";
|
40 |
|
41 |
-
public function __construct(Xcloner $xcloner_container, $wp_user="", $wp_pass="", $wp_db="", $wp_host="")
|
42 |
{
|
43 |
-
$this->logger
|
44 |
-
$this->xcloner_settings
|
45 |
-
$this->fs
|
46 |
|
47 |
-
if($this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request'))
|
48 |
-
$this->recordsPerSession
|
49 |
|
50 |
-
if(!$this->recordsPerSession)
|
51 |
$this->recordsPerSession = 100;
|
52 |
|
53 |
-
if(!$wp_user && !$wp_pass && !$wp_host && !$wp_db
|
54 |
{
|
55 |
$wp_host = $this->xcloner_settings->get_db_hostname();
|
56 |
$wp_user = $this->xcloner_settings->get_db_username();
|
57 |
$wp_pass = $this->xcloner_settings->get_db_password();
|
58 |
-
$wp_db
|
59 |
}
|
60 |
|
61 |
parent::__construct($wp_user, $wp_pass, $wp_db, $wp_host);
|
@@ -71,7 +72,7 @@ class Xcloner_Database extends wpdb{
|
|
71 |
*/
|
72 |
public function init($data, $start = 0)
|
73 |
{
|
74 |
-
if($start and $this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE)){
|
75 |
$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
|
76 |
}
|
77 |
|
@@ -90,7 +91,7 @@ class Xcloner_Database extends wpdb{
|
|
90 |
"database_count"=>0,
|
91 |
);
|
92 |
|
93 |
-
if(!$this->xcloner_settings->get_enable_mysql_backup())
|
94 |
{
|
95 |
$return['finished'] = 1;
|
96 |
return $return;
|
@@ -100,44 +101,44 @@ class Xcloner_Database extends wpdb{
|
|
100 |
|
101 |
$this->init($params, $init);
|
102 |
|
103 |
-
if($init)
|
104 |
{
|
105 |
$db_count = 0;
|
106 |
|
107 |
-
if(isset($params['#']))
|
108 |
{
|
109 |
-
foreach($params['#'] as $database)
|
110 |
{
|
111 |
-
if(!isset($params[$database]) or !is_array($params[$database]))
|
112 |
$params[$database] = array();
|
113 |
}
|
114 |
$db_count = -1;
|
115 |
}
|
116 |
|
117 |
-
if(isset($params) and is_array($params))
|
118 |
-
foreach($params as $database=>$tables)
|
119 |
{
|
120 |
-
if($database != "#")
|
121 |
{
|
122 |
$stats = $this->write_backup_process_list($database, $tables);
|
123 |
-
$return['stats']['tables_count']
|
124 |
-
$return['stats']['total_records']
|
125 |
}
|
126 |
}
|
127 |
|
128 |
-
if(sizeof($params))
|
129 |
-
$return['stats']['database_count'] = sizeof($params)
|
130 |
else
|
131 |
$return['stats']['database_count'] = 0;
|
132 |
|
133 |
return $return;
|
134 |
}
|
135 |
|
136 |
-
if(!isset($extra_params['startAtLine']))
|
137 |
$extra_params['startAtLine'] = 0;
|
138 |
-
if(!isset($extra_params['startAtRecord']))
|
139 |
$extra_params['startAtRecord'] = 0;
|
140 |
-
if(!isset($extra_params['dumpfile']))
|
141 |
$extra_params['dumpfile'] = "";
|
142 |
|
143 |
$return = $this->process_incremental($extra_params['startAtLine'], $extra_params['startAtRecord'], $extra_params['dumpfile']);
|
@@ -148,13 +149,13 @@ class Xcloner_Database extends wpdb{
|
|
148 |
public function log($message = "")
|
149 |
{
|
150 |
|
151 |
-
if($message){
|
152 |
-
$this->logger->info(
|
153 |
-
}else{
|
154 |
-
if($this->last_query)
|
155 |
-
$this->logger->debug(
|
156 |
-
if($this->last_error)
|
157 |
-
$this->logger->error(
|
158 |
}
|
159 |
|
160 |
return;
|
@@ -169,7 +170,7 @@ class Xcloner_Database extends wpdb{
|
|
169 |
*/
|
170 |
public function error($message)
|
171 |
{
|
172 |
-
$this->logger->error(
|
173 |
|
174 |
return;
|
175 |
}
|
@@ -179,7 +180,6 @@ class Xcloner_Database extends wpdb{
|
|
179 |
*
|
180 |
* name: headers
|
181 |
* @param
|
182 |
-
* @return
|
183 |
*/
|
184 |
private function headers()
|
185 |
{
|
@@ -202,7 +202,7 @@ class Xcloner_Database extends wpdb{
|
|
202 |
|
203 |
$query = "show tables in `".$database."`";
|
204 |
|
205 |
-
$res =
|
206 |
$this->log();
|
207 |
|
208 |
return count($res);
|
@@ -225,9 +225,9 @@ class Xcloner_Database extends wpdb{
|
|
225 |
$databases_list[$i]['num_tables'] = $this->get_database_num_tables($this->dbname);
|
226 |
$i++;
|
227 |
|
228 |
-
if(is_array($databases))
|
229 |
-
foreach(
|
230 |
-
if($db->Database != $this->dbname)
|
231 |
{
|
232 |
$databases_list[$i]['name'] = $db->Database;
|
233 |
$databases_list[$i]['num_tables'] = $this->get_database_num_tables($db->Database);
|
@@ -243,7 +243,7 @@ class Xcloner_Database extends wpdb{
|
|
243 |
*
|
244 |
* name: list_tables
|
245 |
* @param string $database
|
246 |
-
* @param array $
|
247 |
* @param int $get_num_records
|
248 |
* @return array $tablesList
|
249 |
*/
|
@@ -252,7 +252,7 @@ class Xcloner_Database extends wpdb{
|
|
252 |
$tablesList[0] = array( );
|
253 |
$inc = 0;
|
254 |
|
255 |
-
if(!$database)
|
256 |
$database = $this->dbname;
|
257 |
|
258 |
$this->logger->debug(sprintf(("Listing tables in %s database"), $database));
|
@@ -260,14 +260,14 @@ class Xcloner_Database extends wpdb{
|
|
260 |
$tables = $this->get_results("SHOW TABLES in `".$database."`");
|
261 |
$this->log();
|
262 |
|
263 |
-
foreach ($tables as $table){
|
264 |
|
265 |
$table = array_values((array)$table)[0];
|
266 |
|
267 |
$tablesList[$inc]['name'] = $table;
|
268 |
$tablesList[$inc]['database'] = $database;
|
269 |
|
270 |
-
if($get_num_records)
|
271 |
{
|
272 |
$records_num_result = $this->get_var("SELECT count(*) FROM `".$database."`.`".$table."`");
|
273 |
$this->log();
|
@@ -277,14 +277,14 @@ class Xcloner_Database extends wpdb{
|
|
277 |
|
278 |
$tablesList[$inc]['excluded'] = 0;
|
279 |
|
280 |
-
if(sizeof($included) and is_array($included))
|
281 |
-
if(!in_array($table, $included)
|
282 |
{
|
283 |
$tablesList[$inc]['excluded'] = 1;
|
284 |
$this->log(sprintf(__("Excluding table %s.%s from backup"), $table, $database));
|
285 |
}
|
286 |
$inc++;
|
287 |
-
|
288 |
|
289 |
return $tablesList;
|
290 |
|
@@ -299,7 +299,7 @@ class Xcloner_Database extends wpdb{
|
|
299 |
|
300 |
$tables = $this->list_tables($dbname, $incl_tables, 1);
|
301 |
|
302 |
-
if($this->dbname != $dbname)
|
303 |
$dumpfile = $dbname."-backup.sql";
|
304 |
else
|
305 |
$dumpfile = $this->TEMP_DUMP_FILE;
|
@@ -308,8 +308,8 @@ class Xcloner_Database extends wpdb{
|
|
308 |
$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
|
309 |
|
310 |
// write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
|
311 |
-
foreach($tables as $key=>$table)
|
312 |
-
if($table!= "" and !$tables[$key]['excluded']){
|
313 |
|
314 |
$line = sprintf("`%s`.`%s`\t%s\t%s\n", $dbname, $tables[$key]['name'], $tables[$key]['records'], $tables[$key]['excluded']);
|
315 |
$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
|
@@ -353,25 +353,25 @@ class Xcloner_Database extends wpdb{
|
|
353 |
* int $dbDropSyntax - check if the DROP TABLE syntax should be added
|
354 |
* @return array $return
|
355 |
*/
|
356 |
-
public function process_incremental($startAtLine= 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility= ""){
|
357 |
|
358 |
$count = 0;
|
359 |
$return['finished'] = 0;
|
360 |
$lines = array();
|
361 |
|
362 |
-
if($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
|
363 |
-
$lines = array_filter(explode("\n"
|
364 |
|
365 |
-
foreach ($lines as $buffer){
|
366 |
|
367 |
-
if($count == $startAtLine)
|
368 |
{
|
369 |
|
370 |
-
$tableInfo =explode("\t", $buffer);
|
371 |
|
372 |
-
if($tableInfo[0] == "###newdump###"){
|
373 |
// we create a new mysql dump file
|
374 |
-
if($dumpfile != ""){
|
375 |
// we finished a previous one and write the footers
|
376 |
$return['dumpsize'] = $this->data_footers($dumpfile);
|
377 |
}
|
@@ -385,13 +385,13 @@ class Xcloner_Database extends wpdb{
|
|
385 |
$startAtLine++;
|
386 |
$return['new_dump'] = 1;
|
387 |
//break;
|
388 |
-
}else{
|
389 |
//we export the table
|
390 |
-
if($tableInfo[0] == "###enddump###")
|
391 |
$return['endDump'] = 1;
|
392 |
|
393 |
//table is excluded
|
394 |
-
if($tableInfo[2])
|
395 |
continue;
|
396 |
|
397 |
$next = $startAtRecord + $this->recordsPerSession;
|
@@ -403,28 +403,28 @@ class Xcloner_Database extends wpdb{
|
|
403 |
|
404 |
//return something to the browser
|
405 |
$return['databaseName'] = $databaseName;
|
406 |
-
$return['tableName']
|
407 |
$return['totalRecords'] = $tableInfo[1];
|
408 |
|
409 |
$processed_records = 0;
|
410 |
|
411 |
-
if(trim($tableName) !=""
|
412 |
$processed_records = $this->export_table($databaseName, $tableName, $startAtRecord, $this->recordsPerSession, $dumpfile);
|
413 |
|
414 |
-
$return['processedRecords'] = $startAtRecord
|
415 |
|
416 |
-
if($next >= $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
|
417 |
{
|
418 |
-
$startAtLine
|
419 |
$startAtRecord = 0;
|
420 |
-
}else{
|
421 |
$startAtRecord = $startAtRecord + $this->recordsPerSession;
|
422 |
}
|
423 |
|
424 |
//$return['dbCompatibility'] = self::$dbCompatibility;
|
425 |
|
426 |
-
$return['startAtLine']
|
427 |
-
$return['startAtRecord']
|
428 |
$return['dumpfile'] = $dumpfile;
|
429 |
$return['dumpsize'] = $this->fs->get_tmp_filesystem_append()->getSize($dumpfile);
|
430 |
|
@@ -442,15 +442,15 @@ class Xcloner_Database extends wpdb{
|
|
442 |
}
|
443 |
|
444 |
//while is finished, lets go home...
|
445 |
-
if($dumpfile != ""){
|
446 |
// we finished a previous one and write the footers
|
447 |
$return['dumpsize'] = $this->data_footers($dumpfile);
|
448 |
$return['dumpfile'] = ($dumpfile);
|
449 |
}
|
450 |
$return['finished'] = 1;
|
451 |
-
$return['startAtLine']
|
452 |
|
453 |
-
if($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
|
454 |
$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
|
455 |
|
456 |
$this->logger->debug(sprintf(("Database backup finished!")));
|
@@ -473,13 +473,18 @@ class Xcloner_Database extends wpdb{
|
|
473 |
* handler $fd - file handler where to write the records
|
474 |
* @return
|
475 |
*/
|
|
|
|
|
|
|
|
|
|
|
476 |
public function export_table($databaseName, $tableName, $start, $limit, $dumpfile)
|
477 |
{
|
478 |
$this->logger->debug(sprintf(("Exporting table %s.%s data"), $databaseName, $tableName));
|
479 |
|
480 |
$records = 0;
|
481 |
|
482 |
-
if($start == 0)
|
483 |
$this->dump_structure($databaseName, $tableName, $dumpfile);
|
484 |
|
485 |
$start = intval($start);
|
@@ -487,36 +492,36 @@ class Xcloner_Database extends wpdb{
|
|
487 |
//exporting the table content now
|
488 |
|
489 |
$query = "SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;";
|
490 |
-
if($this->use_mysqli)
|
491 |
{
|
492 |
$result = mysqli_query($this->dbh, $query);
|
493 |
$mysql_fetch_function = "mysqli_fetch_array";
|
494 |
|
495 |
-
}else{
|
496 |
$result = mysql_query($query, $this->dbh);
|
497 |
$mysql_fetch_function = "mysqli_fetch_array";
|
498 |
}
|
499 |
//$result = $this->get_results($query, ARRAY_N);
|
500 |
//print_r($result); exit;
|
501 |
|
502 |
-
if($result){
|
503 |
-
while($row = $mysql_fetch_function($result, MYSQLI_ASSOC)){
|
504 |
|
505 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, "INSERT INTO `$tableName` VALUES (");
|
506 |
$arr = $row;
|
507 |
$buffer = "";
|
508 |
$this->countRecords++;
|
509 |
|
510 |
-
|
511 |
$value = $this->_real_escape($value);
|
512 |
|
513 |
-
if(method_exists($this, 'remove_placeholder_escape')){
|
514 |
$value = $this->remove_placeholder_escape($value);
|
515 |
}
|
516 |
|
517 |
$buffer .= "'".$value."', ";
|
518 |
}
|
519 |
-
$buffer = rtrim($buffer, ', ')
|
520 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $buffer);
|
521 |
unset($buffer);
|
522 |
|
@@ -531,29 +536,29 @@ class Xcloner_Database extends wpdb{
|
|
531 |
|
532 |
}
|
533 |
|
534 |
-
public function dump_structure($databaseName, $tableName
|
535 |
{
|
536 |
$this->log(sprintf(__("Dumping the structure for %s.%s table"), $databaseName, $tableName));
|
537 |
|
538 |
$line = ("\n#\n# Table structure for table `$tableName`\n#\n\n");
|
539 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
540 |
|
541 |
-
|
542 |
-
|
543 |
$line = ("\nDROP table IF EXISTS `$tableName`;\n");
|
544 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
545 |
}
|
546 |
|
547 |
//$result = mysqli_query($this->dbh,"SHOW CREATE table `$databaseName`.`$tableName`;");
|
548 |
$result = $this->get_row("SHOW CREATE table `$databaseName`.`$tableName`;", ARRAY_N);
|
549 |
-
if($result){
|
550 |
//$row = mysqli_fetch_row( $result);
|
551 |
$line = ($result[1].";\n");
|
552 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
553 |
}
|
554 |
|
555 |
-
$line = (
|
556 |
-
$line .=("#\n# Dumping data for table `$tableName`\n#\n\n");
|
557 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
558 |
|
559 |
return;
|
@@ -576,7 +581,7 @@ class Xcloner_Database extends wpdb{
|
|
576 |
|
577 |
}
|
578 |
|
579 |
-
public function resetcountRecords(){
|
580 |
|
581 |
$this->countRecords = 0;
|
582 |
|
@@ -584,7 +589,7 @@ class Xcloner_Database extends wpdb{
|
|
584 |
|
585 |
}
|
586 |
|
587 |
-
public function getcountRecords(){
|
588 |
|
589 |
return $this->countRecords;
|
590 |
|
@@ -601,14 +606,14 @@ class Xcloner_Database extends wpdb{
|
|
601 |
$return .= "# Powered by XCloner Site Backup\n";
|
602 |
$return .= "# http://www.xcloner.com\n";
|
603 |
$return .= "#\n";
|
604 |
-
$return .= "# Host: "
|
605 |
-
$return .= "# Generation Time: "
|
606 |
-
$return .= "# PHP Version: "
|
607 |
-
$return .= "# Database Charset: "
|
608 |
|
609 |
$results = $this->get_results("SHOW VARIABLES LIKE \"%version%\";", ARRAY_N);
|
610 |
-
if(isset($results)){
|
611 |
-
foreach($results as $result){
|
612 |
|
613 |
$return .= "# MYSQL ".$result[0].": ".$result[1]."\n";
|
614 |
|
@@ -618,13 +623,13 @@ class Xcloner_Database extends wpdb{
|
|
618 |
$results = $this->get_results("SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
|
619 |
FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '".$database."';");
|
620 |
|
621 |
-
if(isset($results[0])){
|
622 |
|
623 |
$return .= "# MYSQL DEFAULT_CHARACTER_SET_NAME: ".$results[0]->DEFAULT_CHARACTER_SET_NAME."\n";
|
624 |
$return .= "# MYSQL SCHEMA_NAME: ".$results[0]->DEFAULT_COLLATION_NAME."\n";
|
625 |
}
|
626 |
|
627 |
-
$return .= "#\n# Database : `"
|
628 |
|
629 |
$this->log(sprintf(__("Writing %s database dump headers"), $database));
|
630 |
|
21 |
*/
|
22 |
|
23 |
|
24 |
+
class Xcloner_Database extends wpdb {
|
25 |
|
26 |
|
27 |
+
public $debug = 0;
|
28 |
+
public $recordsPerSession = 10000;
|
29 |
+
public $dbCompatibility = "";
|
30 |
public $dbDropSyntax = 1;
|
31 |
public $countRecords = 0;
|
32 |
|
33 |
private $link;
|
34 |
private $db_selected;
|
35 |
private $logger;
|
36 |
+
private $xcloner_settings;
|
37 |
private $fs;
|
38 |
|
39 |
private $TEMP_DBPROCESS_FILE = ".database";
|
40 |
private $TEMP_DUMP_FILE = "database-backup.sql";
|
41 |
|
42 |
+
public function __construct(Xcloner $xcloner_container, $wp_user = "", $wp_pass = "", $wp_db = "", $wp_host = "")
|
43 |
{
|
44 |
+
$this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_database");
|
45 |
+
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
46 |
+
$this->fs = $xcloner_container->get_xcloner_filesystem();
|
47 |
|
48 |
+
if ($this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request'))
|
49 |
+
$this->recordsPerSession = $this->xcloner_settings->get_xcloner_option('xcloner_database_records_per_request');
|
50 |
|
51 |
+
if (!$this->recordsPerSession)
|
52 |
$this->recordsPerSession = 100;
|
53 |
|
54 |
+
if (!$wp_user && !$wp_pass && !$wp_host && !$wp_db)
|
55 |
{
|
56 |
$wp_host = $this->xcloner_settings->get_db_hostname();
|
57 |
$wp_user = $this->xcloner_settings->get_db_username();
|
58 |
$wp_pass = $this->xcloner_settings->get_db_password();
|
59 |
+
$wp_db = $this->xcloner_settings->get_db_database();
|
60 |
}
|
61 |
|
62 |
parent::__construct($wp_user, $wp_pass, $wp_db, $wp_host);
|
72 |
*/
|
73 |
public function init($data, $start = 0)
|
74 |
{
|
75 |
+
if ($start and $this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE)) {
|
76 |
$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
|
77 |
}
|
78 |
|
91 |
"database_count"=>0,
|
92 |
);
|
93 |
|
94 |
+
if (!$this->xcloner_settings->get_enable_mysql_backup())
|
95 |
{
|
96 |
$return['finished'] = 1;
|
97 |
return $return;
|
101 |
|
102 |
$this->init($params, $init);
|
103 |
|
104 |
+
if ($init)
|
105 |
{
|
106 |
$db_count = 0;
|
107 |
|
108 |
+
if (isset($params['#']))
|
109 |
{
|
110 |
+
foreach ($params['#'] as $database)
|
111 |
{
|
112 |
+
if (!isset($params[$database]) or !is_array($params[$database]))
|
113 |
$params[$database] = array();
|
114 |
}
|
115 |
$db_count = -1;
|
116 |
}
|
117 |
|
118 |
+
if (isset($params) and is_array($params))
|
119 |
+
foreach ($params as $database=>$tables)
|
120 |
{
|
121 |
+
if ($database != "#")
|
122 |
{
|
123 |
$stats = $this->write_backup_process_list($database, $tables);
|
124 |
+
$return['stats']['tables_count'] += $stats['tables_count'];
|
125 |
+
$return['stats']['total_records'] += $stats['total_records'];
|
126 |
}
|
127 |
}
|
128 |
|
129 |
+
if (sizeof($params))
|
130 |
+
$return['stats']['database_count'] = sizeof($params) + $db_count;
|
131 |
else
|
132 |
$return['stats']['database_count'] = 0;
|
133 |
|
134 |
return $return;
|
135 |
}
|
136 |
|
137 |
+
if (!isset($extra_params['startAtLine']))
|
138 |
$extra_params['startAtLine'] = 0;
|
139 |
+
if (!isset($extra_params['startAtRecord']))
|
140 |
$extra_params['startAtRecord'] = 0;
|
141 |
+
if (!isset($extra_params['dumpfile']))
|
142 |
$extra_params['dumpfile'] = "";
|
143 |
|
144 |
$return = $this->process_incremental($extra_params['startAtLine'], $extra_params['startAtRecord'], $extra_params['dumpfile']);
|
149 |
public function log($message = "")
|
150 |
{
|
151 |
|
152 |
+
if ($message) {
|
153 |
+
$this->logger->info($message, array(""));
|
154 |
+
} else {
|
155 |
+
if ($this->last_query)
|
156 |
+
$this->logger->debug($this->last_query, array(""));
|
157 |
+
if ($this->last_error)
|
158 |
+
$this->logger->error($this->last_error, array(""));
|
159 |
}
|
160 |
|
161 |
return;
|
170 |
*/
|
171 |
public function error($message)
|
172 |
{
|
173 |
+
$this->logger->error($message, array(""));
|
174 |
|
175 |
return;
|
176 |
}
|
180 |
*
|
181 |
* name: headers
|
182 |
* @param
|
|
|
183 |
*/
|
184 |
private function headers()
|
185 |
{
|
202 |
|
203 |
$query = "show tables in `".$database."`";
|
204 |
|
205 |
+
$res = $this->get_results($query);
|
206 |
$this->log();
|
207 |
|
208 |
return count($res);
|
225 |
$databases_list[$i]['num_tables'] = $this->get_database_num_tables($this->dbname);
|
226 |
$i++;
|
227 |
|
228 |
+
if (is_array($databases))
|
229 |
+
foreach ($databases as $db) {
|
230 |
+
if ($db->Database != $this->dbname)
|
231 |
{
|
232 |
$databases_list[$i]['name'] = $db->Database;
|
233 |
$databases_list[$i]['num_tables'] = $this->get_database_num_tables($db->Database);
|
243 |
*
|
244 |
* name: list_tables
|
245 |
* @param string $database
|
246 |
+
* @param array $included
|
247 |
* @param int $get_num_records
|
248 |
* @return array $tablesList
|
249 |
*/
|
252 |
$tablesList[0] = array( );
|
253 |
$inc = 0;
|
254 |
|
255 |
+
if (!$database)
|
256 |
$database = $this->dbname;
|
257 |
|
258 |
$this->logger->debug(sprintf(("Listing tables in %s database"), $database));
|
260 |
$tables = $this->get_results("SHOW TABLES in `".$database."`");
|
261 |
$this->log();
|
262 |
|
263 |
+
foreach ($tables as $table) {
|
264 |
|
265 |
$table = array_values((array)$table)[0];
|
266 |
|
267 |
$tablesList[$inc]['name'] = $table;
|
268 |
$tablesList[$inc]['database'] = $database;
|
269 |
|
270 |
+
if ($get_num_records)
|
271 |
{
|
272 |
$records_num_result = $this->get_var("SELECT count(*) FROM `".$database."`.`".$table."`");
|
273 |
$this->log();
|
277 |
|
278 |
$tablesList[$inc]['excluded'] = 0;
|
279 |
|
280 |
+
if (sizeof($included) and is_array($included))
|
281 |
+
if (!in_array($table, $included))
|
282 |
{
|
283 |
$tablesList[$inc]['excluded'] = 1;
|
284 |
$this->log(sprintf(__("Excluding table %s.%s from backup"), $table, $database));
|
285 |
}
|
286 |
$inc++;
|
287 |
+
}
|
288 |
|
289 |
return $tablesList;
|
290 |
|
299 |
|
300 |
$tables = $this->list_tables($dbname, $incl_tables, 1);
|
301 |
|
302 |
+
if ($this->dbname != $dbname)
|
303 |
$dumpfile = $dbname."-backup.sql";
|
304 |
else
|
305 |
$dumpfile = $this->TEMP_DUMP_FILE;
|
308 |
$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
|
309 |
|
310 |
// write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
|
311 |
+
foreach ($tables as $key=>$table)
|
312 |
+
if ($table != "" and !$tables[$key]['excluded']) {
|
313 |
|
314 |
$line = sprintf("`%s`.`%s`\t%s\t%s\n", $dbname, $tables[$key]['name'], $tables[$key]['records'], $tables[$key]['excluded']);
|
315 |
$this->fs->get_tmp_filesystem_append()->write($this->TEMP_DBPROCESS_FILE, $line);
|
353 |
* int $dbDropSyntax - check if the DROP TABLE syntax should be added
|
354 |
* @return array $return
|
355 |
*/
|
356 |
+
public function process_incremental($startAtLine = 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility = "") {
|
357 |
|
358 |
$count = 0;
|
359 |
$return['finished'] = 0;
|
360 |
$lines = array();
|
361 |
|
362 |
+
if ($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
|
363 |
+
$lines = array_filter(explode("\n", $this->fs->get_tmp_filesystem()->read($this->TEMP_DBPROCESS_FILE)));
|
364 |
|
365 |
+
foreach ($lines as $buffer) {
|
366 |
|
367 |
+
if ($count == $startAtLine)
|
368 |
{
|
369 |
|
370 |
+
$tableInfo = explode("\t", $buffer);
|
371 |
|
372 |
+
if ($tableInfo[0] == "###newdump###") {
|
373 |
// we create a new mysql dump file
|
374 |
+
if ($dumpfile != "") {
|
375 |
// we finished a previous one and write the footers
|
376 |
$return['dumpsize'] = $this->data_footers($dumpfile);
|
377 |
}
|
385 |
$startAtLine++;
|
386 |
$return['new_dump'] = 1;
|
387 |
//break;
|
388 |
+
} else {
|
389 |
//we export the table
|
390 |
+
if ($tableInfo[0] == "###enddump###")
|
391 |
$return['endDump'] = 1;
|
392 |
|
393 |
//table is excluded
|
394 |
+
if ($tableInfo[2])
|
395 |
continue;
|
396 |
|
397 |
$next = $startAtRecord + $this->recordsPerSession;
|
403 |
|
404 |
//return something to the browser
|
405 |
$return['databaseName'] = $databaseName;
|
406 |
+
$return['tableName'] = $tableName;
|
407 |
$return['totalRecords'] = $tableInfo[1];
|
408 |
|
409 |
$processed_records = 0;
|
410 |
|
411 |
+
if (trim($tableName) != "" and !$tableInfo[2])
|
412 |
$processed_records = $this->export_table($databaseName, $tableName, $startAtRecord, $this->recordsPerSession, $dumpfile);
|
413 |
|
414 |
+
$return['processedRecords'] = $startAtRecord + $processed_records;
|
415 |
|
416 |
+
if ($next >= $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
|
417 |
{
|
418 |
+
$startAtLine++;
|
419 |
$startAtRecord = 0;
|
420 |
+
} else {
|
421 |
$startAtRecord = $startAtRecord + $this->recordsPerSession;
|
422 |
}
|
423 |
|
424 |
//$return['dbCompatibility'] = self::$dbCompatibility;
|
425 |
|
426 |
+
$return['startAtLine'] = $startAtLine;
|
427 |
+
$return['startAtRecord'] = $startAtRecord;
|
428 |
$return['dumpfile'] = $dumpfile;
|
429 |
$return['dumpsize'] = $this->fs->get_tmp_filesystem_append()->getSize($dumpfile);
|
430 |
|
442 |
}
|
443 |
|
444 |
//while is finished, lets go home...
|
445 |
+
if ($dumpfile != "") {
|
446 |
// we finished a previous one and write the footers
|
447 |
$return['dumpsize'] = $this->data_footers($dumpfile);
|
448 |
$return['dumpfile'] = ($dumpfile);
|
449 |
}
|
450 |
$return['finished'] = 1;
|
451 |
+
$return['startAtLine'] = $startAtLine;
|
452 |
|
453 |
+
if ($this->fs->get_tmp_filesystem()->has($this->TEMP_DBPROCESS_FILE))
|
454 |
$this->fs->get_tmp_filesystem()->delete($this->TEMP_DBPROCESS_FILE);
|
455 |
|
456 |
$this->logger->debug(sprintf(("Database backup finished!")));
|
473 |
* handler $fd - file handler where to write the records
|
474 |
* @return
|
475 |
*/
|
476 |
+
|
477 |
+
/**
|
478 |
+
* @param integer $start
|
479 |
+
* @param integer $limit
|
480 |
+
*/
|
481 |
public function export_table($databaseName, $tableName, $start, $limit, $dumpfile)
|
482 |
{
|
483 |
$this->logger->debug(sprintf(("Exporting table %s.%s data"), $databaseName, $tableName));
|
484 |
|
485 |
$records = 0;
|
486 |
|
487 |
+
if ($start == 0)
|
488 |
$this->dump_structure($databaseName, $tableName, $dumpfile);
|
489 |
|
490 |
$start = intval($start);
|
492 |
//exporting the table content now
|
493 |
|
494 |
$query = "SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;";
|
495 |
+
if ($this->use_mysqli)
|
496 |
{
|
497 |
$result = mysqli_query($this->dbh, $query);
|
498 |
$mysql_fetch_function = "mysqli_fetch_array";
|
499 |
|
500 |
+
} else {
|
501 |
$result = mysql_query($query, $this->dbh);
|
502 |
$mysql_fetch_function = "mysqli_fetch_array";
|
503 |
}
|
504 |
//$result = $this->get_results($query, ARRAY_N);
|
505 |
//print_r($result); exit;
|
506 |
|
507 |
+
if ($result) {
|
508 |
+
while ($row = $mysql_fetch_function($result, MYSQLI_ASSOC)) {
|
509 |
|
510 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, "INSERT INTO `$tableName` VALUES (");
|
511 |
$arr = $row;
|
512 |
$buffer = "";
|
513 |
$this->countRecords++;
|
514 |
|
515 |
+
foreach ($arr as $key => $value) {
|
516 |
$value = $this->_real_escape($value);
|
517 |
|
518 |
+
if (method_exists($this, 'remove_placeholder_escape')) {
|
519 |
$value = $this->remove_placeholder_escape($value);
|
520 |
}
|
521 |
|
522 |
$buffer .= "'".$value."', ";
|
523 |
}
|
524 |
+
$buffer = rtrim($buffer, ', ').");\n";
|
525 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $buffer);
|
526 |
unset($buffer);
|
527 |
|
536 |
|
537 |
}
|
538 |
|
539 |
+
public function dump_structure($databaseName, $tableName, $dumpfile)
|
540 |
{
|
541 |
$this->log(sprintf(__("Dumping the structure for %s.%s table"), $databaseName, $tableName));
|
542 |
|
543 |
$line = ("\n#\n# Table structure for table `$tableName`\n#\n\n");
|
544 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
545 |
|
546 |
+
if ($this->dbDropSyntax)
|
547 |
+
{
|
548 |
$line = ("\nDROP table IF EXISTS `$tableName`;\n");
|
549 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
550 |
}
|
551 |
|
552 |
//$result = mysqli_query($this->dbh,"SHOW CREATE table `$databaseName`.`$tableName`;");
|
553 |
$result = $this->get_row("SHOW CREATE table `$databaseName`.`$tableName`;", ARRAY_N);
|
554 |
+
if ($result) {
|
555 |
//$row = mysqli_fetch_row( $result);
|
556 |
$line = ($result[1].";\n");
|
557 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
558 |
}
|
559 |
|
560 |
+
$line = ("\n#\n# End Structure for table `$tableName`\n#\n\n");
|
561 |
+
$line .= ("#\n# Dumping data for table `$tableName`\n#\n\n");
|
562 |
$this->fs->get_tmp_filesystem_append()->write($dumpfile, $line);
|
563 |
|
564 |
return;
|
581 |
|
582 |
}
|
583 |
|
584 |
+
public function resetcountRecords() {
|
585 |
|
586 |
$this->countRecords = 0;
|
587 |
|
589 |
|
590 |
}
|
591 |
|
592 |
+
public function getcountRecords() {
|
593 |
|
594 |
return $this->countRecords;
|
595 |
|
606 |
$return .= "# Powered by XCloner Site Backup\n";
|
607 |
$return .= "# http://www.xcloner.com\n";
|
608 |
$return .= "#\n";
|
609 |
+
$return .= "# Host: ".get_site_url()."\n";
|
610 |
+
$return .= "# Generation Time: ".date("M j, Y \a\\t H:i")."\n";
|
611 |
+
$return .= "# PHP Version: ".phpversion()."\n";
|
612 |
+
$return .= "# Database Charset: ".$this->charset."\n";
|
613 |
|
614 |
$results = $this->get_results("SHOW VARIABLES LIKE \"%version%\";", ARRAY_N);
|
615 |
+
if (isset($results)) {
|
616 |
+
foreach ($results as $result) {
|
617 |
|
618 |
$return .= "# MYSQL ".$result[0].": ".$result[1]."\n";
|
619 |
|
623 |
$results = $this->get_results("SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
|
624 |
FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '".$database."';");
|
625 |
|
626 |
+
if (isset($results[0])) {
|
627 |
|
628 |
$return .= "# MYSQL DEFAULT_CHARACTER_SET_NAME: ".$results[0]->DEFAULT_CHARACTER_SET_NAME."\n";
|
629 |
$return .= "# MYSQL SCHEMA_NAME: ".$results[0]->DEFAULT_COLLATION_NAME."\n";
|
630 |
}
|
631 |
|
632 |
+
$return .= "#\n# Database : `".$database."`\n# --------------------------------------------------------\n\n";
|
633 |
|
634 |
$this->log(sprintf(__("Writing %s database dump headers"), $database));
|
635 |
|
includes/class-xcloner-deactivator.php
CHANGED
@@ -51,11 +51,11 @@ class Xcloner_Deactivator {
|
|
51 |
|
52 |
global $xcloner_plugin;
|
53 |
|
54 |
-
if (
|
55 |
try {
|
56 |
$xcloner_plugin->get_xcloner_filesystem()->cleanup_tmp_directories();
|
57 |
-
}
|
58 |
-
$xcloner_plugin->trigger_message_notice(
|
59 |
}
|
60 |
|
61 |
$xcloner_scheduler = $xcloner_plugin->get_xcloner_scheduler();
|
51 |
|
52 |
global $xcloner_plugin;
|
53 |
|
54 |
+
if (is_a($xcloner_plugin, 'Xcloner')) {
|
55 |
try {
|
56 |
$xcloner_plugin->get_xcloner_filesystem()->cleanup_tmp_directories();
|
57 |
+
}catch (Exception $e) {
|
58 |
+
$xcloner_plugin->trigger_message_notice($e->getMessage());
|
59 |
}
|
60 |
|
61 |
$xcloner_scheduler = $xcloner_plugin->get_xcloner_scheduler();
|
includes/class-xcloner-encryption.php
ADDED
@@ -0,0 +1,394 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by PhpStorm.
|
4 |
+
* User: thinkovi
|
5 |
+
* Date: 2018-11-27
|
6 |
+
* Time: 12:11
|
7 |
+
*/
|
8 |
+
|
9 |
+
//namespace XCloner;
|
10 |
+
|
11 |
+
class Xcloner_Encryption
|
12 |
+
{
|
13 |
+
const FILE_ENCRYPTION_BLOCKS = 1024 * 1024;
|
14 |
+
const FILE_ENCRYPTION_SUFFIX = ".encrypted";
|
15 |
+
const FILE_DECRYPTION_SUFFIX = ".decrypted";
|
16 |
+
|
17 |
+
private $xcloner_settings;
|
18 |
+
private $logger;
|
19 |
+
private $xcloner_container;
|
20 |
+
private $verification = false;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Xcloner_Encryption constructor.
|
24 |
+
* @param Xcloner $xcloner_container
|
25 |
+
*/
|
26 |
+
public function __construct(Xcloner $xcloner_container)
|
27 |
+
{
|
28 |
+
$this->xcloner_container = $xcloner_container;
|
29 |
+
if (property_exists($xcloner_container, 'xcloner_settings')) {
|
30 |
+
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
31 |
+
} else {
|
32 |
+
$this->xcloner_settings = "";
|
33 |
+
}
|
34 |
+
|
35 |
+
if (property_exists($xcloner_container, 'xcloner_logger')) {
|
36 |
+
$this->logger = $xcloner_container->get_xcloner_logger()->withName("xcloner_encryption");
|
37 |
+
} else {
|
38 |
+
$this->logger = "";
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Returns the backup encryption key
|
44 |
+
*
|
45 |
+
* @return string|null
|
46 |
+
*/
|
47 |
+
public function get_backup_encryption_key()
|
48 |
+
{
|
49 |
+
if (is_object($this->xcloner_settings)) {
|
50 |
+
return $this->xcloner_settings->get_xcloner_encryption_key();
|
51 |
+
}
|
52 |
+
|
53 |
+
return null;
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Check if provided filename has encrypted suffix
|
59 |
+
*
|
60 |
+
* @param $filename
|
61 |
+
* @return bool
|
62 |
+
*/
|
63 |
+
public function is_encrypted_file($filename) {
|
64 |
+
$fp = fopen($this->get_xcloner_path().$filename, 'r');
|
65 |
+
if (is_resource($fp)) {
|
66 |
+
$encryption_length = fread($fp, 16);
|
67 |
+
fclose($fp);
|
68 |
+
if (is_numeric($encryption_length)) {
|
69 |
+
return true;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
return false;
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Returns the filename with encrypted suffix
|
79 |
+
*
|
80 |
+
* @param string $filename
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
public function get_encrypted_target_backup_file_name($filename) {
|
84 |
+
|
85 |
+
return str_replace(self::FILE_DECRYPTION_SUFFIX, "", $filename).self::FILE_ENCRYPTION_SUFFIX;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Returns the filename without encrypted suffix
|
90 |
+
*
|
91 |
+
* @param string $filename
|
92 |
+
* @return string
|
93 |
+
*/
|
94 |
+
public function get_decrypted_target_backup_file_name($filename) {
|
95 |
+
|
96 |
+
return str_replace(self::FILE_ENCRYPTION_SUFFIX, "", $filename).self::FILE_DECRYPTION_SUFFIX;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Encrypt the passed file and saves the result in a new file with ".enc" as suffix.
|
101 |
+
*
|
102 |
+
* @param string $source Path to file that should be encrypted
|
103 |
+
* @param string $dest File name where the encryped file should be written to.
|
104 |
+
* @param string $key The key used for the encryption
|
105 |
+
* @param int $start Start position for reading when doing incremental mode.
|
106 |
+
* @param string $iv The IV key to use.
|
107 |
+
* @param bool $verification Weather we should we try to verify the decryption.
|
108 |
+
* @return array|false Returns array or FALSE if an error occured
|
109 |
+
* @throws Exception
|
110 |
+
*/
|
111 |
+
public function encrypt_file($source, $dest = "", $key = "", $start = 0, $iv = 0, $verification = true, $recursive = false)
|
112 |
+
{
|
113 |
+
if (is_object($this->logger)) {
|
114 |
+
$this->logger->info(sprintf('Encrypting file %s at position %d IV %s', $source, $start, base64_encode($iv)));
|
115 |
+
}
|
116 |
+
|
117 |
+
//$key = substr(sha1($key, true), 0, 16);
|
118 |
+
if (!$key) {
|
119 |
+
$key = $this->get_backup_encryption_key();
|
120 |
+
}
|
121 |
+
$key_digest = openssl_digest($key, "md5", true);
|
122 |
+
|
123 |
+
$keep_local = 1;
|
124 |
+
if (!$dest) {
|
125 |
+
$dest = $this->get_encrypted_target_backup_file_name($source);
|
126 |
+
$keep_local = 0;
|
127 |
+
}
|
128 |
+
|
129 |
+
if (!$iv || !$start) {
|
130 |
+
//$iv = openssl_random_pseudo_bytes(16);
|
131 |
+
$iv = str_pad(self::FILE_ENCRYPTION_BLOCKS, 16, "0000000000000000", STR_PAD_LEFT);
|
132 |
+
}
|
133 |
+
|
134 |
+
if (!$start) {
|
135 |
+
$fpOut = fopen($this->get_xcloner_path().$dest, 'w');
|
136 |
+
} else {
|
137 |
+
$fpOut = fopen($this->get_xcloner_path().$dest, 'a');
|
138 |
+
}
|
139 |
+
|
140 |
+
if (is_resource($fpOut)) {
|
141 |
+
|
142 |
+
// Put the initialization vector to the beginning of the file
|
143 |
+
if (!$start) {
|
144 |
+
fwrite($fpOut, $iv);
|
145 |
+
}
|
146 |
+
|
147 |
+
if (file_exists($this->get_xcloner_path().$source) &&
|
148 |
+
$fpIn = fopen($this->get_xcloner_path().$source, 'rb')) {
|
149 |
+
|
150 |
+
fseek($fpIn, (int)$start);
|
151 |
+
|
152 |
+
if (!feof($fpIn)) {
|
153 |
+
|
154 |
+
$plaintext = fread($fpIn, 16 * self::FILE_ENCRYPTION_BLOCKS);
|
155 |
+
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key_digest, OPENSSL_RAW_DATA, $iv);
|
156 |
+
|
157 |
+
// Use the first 16 bytes of the ciphertext as the next initialization vector
|
158 |
+
$iv = substr($ciphertext, 0, 16);
|
159 |
+
//$iv = openssl_random_pseudo_bytes(16);
|
160 |
+
|
161 |
+
fwrite($fpOut, $ciphertext);
|
162 |
+
|
163 |
+
$start = ftell($fpIn);
|
164 |
+
|
165 |
+
fclose($fpOut);
|
166 |
+
|
167 |
+
if (!feof($fpIn)) {
|
168 |
+
fclose($fpIn);
|
169 |
+
//echo "\n NEW:".$key.md5($iv);
|
170 |
+
//self::encryptFile($source, $dest, $key, $start, $iv);
|
171 |
+
if ($recursive) {
|
172 |
+
$this->encrypt_file($source, $dest, $key, $start, ($iv), $verification, $recursive);
|
173 |
+
} else {
|
174 |
+
|
175 |
+
if (($iv) != base64_decode(base64_encode($iv)))
|
176 |
+
{
|
177 |
+
throw new \Exception('Could not encode IV for transport');
|
178 |
+
}
|
179 |
+
|
180 |
+
return array(
|
181 |
+
"start" => $start,
|
182 |
+
"iv" => base64_encode($iv),
|
183 |
+
"target_file" => $dest,
|
184 |
+
"finished" => 0
|
185 |
+
);
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
}
|
190 |
+
} else {
|
191 |
+
if (is_object($this->logger)) {
|
192 |
+
$this->logger->error('Unable to read source file for encryption.');
|
193 |
+
}
|
194 |
+
throw new \Exception("Unable to read source file for encryption.");
|
195 |
+
}
|
196 |
+
} else {
|
197 |
+
if (is_object($this->logger)) {
|
198 |
+
$this->logger->error('Unable to write destination file for encryption.');
|
199 |
+
}
|
200 |
+
throw new \Exception("Unable to write destination file for encryption.");
|
201 |
+
}
|
202 |
+
|
203 |
+
if ($verification) {
|
204 |
+
$this->verify_encrypted_file($dest);
|
205 |
+
}
|
206 |
+
|
207 |
+
//we replace the original backup with the encrypted one
|
208 |
+
if (!$keep_local && copy($this->get_xcloner_path().$dest,
|
209 |
+
$this->get_xcloner_path().$source)) {
|
210 |
+
unlink($this->get_xcloner_path().$dest);
|
211 |
+
}
|
212 |
+
|
213 |
+
|
214 |
+
return array("target_file" => $dest, "finished" => 1);
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* @param string $file
|
219 |
+
*/
|
220 |
+
public function verify_encrypted_file($file) {
|
221 |
+
if (is_object($this->logger)) {
|
222 |
+
$this->logger->info(sprintf('Verifying encrypted file %s', $file));
|
223 |
+
}
|
224 |
+
|
225 |
+
$this->verification = true;
|
226 |
+
$this->decrypt_file($file);
|
227 |
+
$this->verification = false;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Dencrypt the passed file and saves the result in a new file, removing the
|
232 |
+
* last 4 characters from file name.
|
233 |
+
*
|
234 |
+
* @param string $source Path to file that should be decrypted
|
235 |
+
* @param string $dest File name where the decryped file should be written to.
|
236 |
+
* @param string $key The key used for the decryption (must be the same as for encryption)
|
237 |
+
* @param int $start Start position for reading when doing incremental mode.
|
238 |
+
* @param string $iv The IV key to use.
|
239 |
+
* @return array|false Returns array or FALSE if an error occured
|
240 |
+
* @throws Exception
|
241 |
+
*/
|
242 |
+
public function decrypt_file($source, $dest = "", $key = "", $start = 0, $iv = 0, $recursive = false)
|
243 |
+
{
|
244 |
+
if (is_object($this->logger)) {
|
245 |
+
$this->logger->info(sprintf('Decrypting file %s at position %d with IV %s', $source, $start, base64_encode($iv)));
|
246 |
+
}
|
247 |
+
|
248 |
+
//$key = substr(sha1($key, true), 0, 16);
|
249 |
+
if (!$key) {
|
250 |
+
$key = $this->get_backup_encryption_key();
|
251 |
+
}
|
252 |
+
|
253 |
+
$key_digest = openssl_digest($key, "md5", true);
|
254 |
+
|
255 |
+
$keep_local = 1;
|
256 |
+
if (!$dest) {
|
257 |
+
$dest = $this->get_decrypted_target_backup_file_name($source);
|
258 |
+
$keep_local = 0;
|
259 |
+
}
|
260 |
+
|
261 |
+
if (!$start) {
|
262 |
+
if ($this->verification) {
|
263 |
+
$fpOut = fopen("php://stdout", 'w');
|
264 |
+
} else {
|
265 |
+
$fpOut = fopen($this->get_xcloner_path().$dest, 'w');
|
266 |
+
}
|
267 |
+
} else {
|
268 |
+
if ($this->verification) {
|
269 |
+
$fpOut = fopen("php://stdout", 'a');
|
270 |
+
} else {
|
271 |
+
$fpOut = fopen($this->get_xcloner_path().$dest, 'a');
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
if (is_resource($fpOut)) {
|
276 |
+
if (file_exists($this->get_xcloner_path().$source) &&
|
277 |
+
$fpIn = fopen($this->get_xcloner_path().$source, 'rb')) {
|
278 |
+
|
279 |
+
$encryption_length = (int)fread($fpIn, 16);
|
280 |
+
if (!$encryption_length) {
|
281 |
+
$encryption_length = self::FILE_ENCRYPTION_BLOCKS;
|
282 |
+
}
|
283 |
+
|
284 |
+
fseek($fpIn, (int)$start);
|
285 |
+
|
286 |
+
// Get the initialzation vector from the beginning of the file
|
287 |
+
if (!$iv) {
|
288 |
+
$iv = fread($fpIn, 16);
|
289 |
+
}
|
290 |
+
|
291 |
+
if (!feof($fpIn)) {
|
292 |
+
|
293 |
+
// we have to read one block more for decrypting than for encrypting
|
294 |
+
$ciphertext = fread($fpIn, 16 * ($encryption_length + 1));
|
295 |
+
$plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key_digest, OPENSSL_RAW_DATA, $iv);
|
296 |
+
|
297 |
+
if (!$plaintext) {
|
298 |
+
unlink($this->get_xcloner_path().$dest);
|
299 |
+
if (is_object($this->logger)) {
|
300 |
+
$this->logger->error('Backup decryption failed, please check your provided Encryption Key.');
|
301 |
+
}
|
302 |
+
throw new \Exception("Backup decryption failed, please check your provided Encryption Key.");
|
303 |
+
}
|
304 |
+
|
305 |
+
// Use the first 16 bytes of the ciphertext as the next initialization vector
|
306 |
+
$iv = substr($ciphertext, 0, 16);
|
307 |
+
|
308 |
+
if (!$this->verification) {
|
309 |
+
fwrite($fpOut, $plaintext);
|
310 |
+
}
|
311 |
+
|
312 |
+
$start = ftell($fpIn);
|
313 |
+
|
314 |
+
fclose($fpOut);
|
315 |
+
|
316 |
+
if (!feof($fpIn)) {
|
317 |
+
fclose($fpIn);
|
318 |
+
if ($this->verification || $recursive) {
|
319 |
+
unset($ciphertext);
|
320 |
+
unset($plaintext);
|
321 |
+
$this->decrypt_file($source, $dest, $key, $start, $iv, $recursive);
|
322 |
+
} else {
|
323 |
+
if (($iv) != base64_decode(base64_encode($iv)))
|
324 |
+
{
|
325 |
+
throw new \Exception('Could not encode IV for transport');
|
326 |
+
}
|
327 |
+
|
328 |
+
return array(
|
329 |
+
"start" => $start,
|
330 |
+
"encryption_length" => $encryption_length,
|
331 |
+
"iv" => base64_encode($iv),
|
332 |
+
"target_file" => $dest,
|
333 |
+
"finished" => 0
|
334 |
+
);
|
335 |
+
}
|
336 |
+
}
|
337 |
+
|
338 |
+
}
|
339 |
+
} else {
|
340 |
+
if (is_object($this->logger)) {
|
341 |
+
$this->logger->error('Unable to read source file for decryption');
|
342 |
+
}
|
343 |
+
throw new \Exception("Unable to read source file for decryption");
|
344 |
+
}
|
345 |
+
} else {
|
346 |
+
if (is_object($this->logger)) {
|
347 |
+
$this->logger->error('Unable to write destination file for decryption');
|
348 |
+
}
|
349 |
+
throw new \Exception("Unable to write destination file for decryption");
|
350 |
+
}
|
351 |
+
|
352 |
+
//we replace the original backup with the encrypted one
|
353 |
+
if (!$keep_local && !$this->verification && copy($this->get_xcloner_path().$dest,
|
354 |
+
$this->get_xcloner_path().$source)) {
|
355 |
+
unlink($this->get_xcloner_path().$dest);
|
356 |
+
}
|
357 |
+
|
358 |
+
return array("target_file" => $dest, "finished" => 1);
|
359 |
+
}
|
360 |
+
|
361 |
+
public function get_xcloner_path() {
|
362 |
+
if (is_object($this->xcloner_settings)) {
|
363 |
+
return $this->xcloner_settings->get_xcloner_store_path().DS;
|
364 |
+
}
|
365 |
+
|
366 |
+
return null;
|
367 |
+
}
|
368 |
+
|
369 |
+
}
|
370 |
+
|
371 |
+
|
372 |
+
try {
|
373 |
+
|
374 |
+
if (isset($argv[1])) {
|
375 |
+
|
376 |
+
class Xcloner {
|
377 |
+
/**
|
378 |
+
* Xcloner constructor.
|
379 |
+
*/
|
380 |
+
public function __construct()
|
381 |
+
{
|
382 |
+
}
|
383 |
+
}
|
384 |
+
$xcloner_encryption = new Xcloner_Encryption(new Xcloner());
|
385 |
+
|
386 |
+
if ($argv[1] == "-e") {
|
387 |
+
$xcloner_encryption->encrypt_file($argv[2], $argv[2].".enc", $argv[4], 0, 0, false, true);
|
388 |
+
} elseif ($argv[1] == "-d") {
|
389 |
+
$xcloner_encryption->decrypt_file($argv[2], $argv[2].".dec", $argv[4], 0, 0, true);
|
390 |
+
}
|
391 |
+
}
|
392 |
+
}catch (\Exception $e) {
|
393 |
+
echo "CAUGHT: ".$e->getMessage();
|
394 |
+
}
|
includes/class-xcloner-file-system.php
CHANGED
@@ -61,7 +61,7 @@ class Xcloner_File_System
|
|
61 |
private $files_size;
|
62 |
private $last_logged_file;
|
63 |
private $folders_to_process_per_session = 25;
|
64 |
-
private $backup_archive_extensions = array("tar", "tgz", "tar.gz", "gz", "csv");
|
65 |
private $backup_name_tags = array('[time]', '[hostname]', '[domain]');
|
66 |
|
67 |
/**
|
@@ -102,8 +102,8 @@ class Xcloner_File_System
|
|
102 |
$this->storage_filesystem_append = new Filesystem($this->storage_adapter, new Config([
|
103 |
'disable_asserts' => true,
|
104 |
]));
|
105 |
-
}
|
106 |
-
$this->logger->error("Filesystem Initialization Error: "
|
107 |
}
|
108 |
|
109 |
|
@@ -161,7 +161,7 @@ class Xcloner_File_System
|
|
161 |
{
|
162 |
if ($remote_storage_selection != "") {
|
163 |
$remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
164 |
-
$method = "get_"
|
165 |
|
166 |
if (!method_exists($remote_storage, $method)) {
|
167 |
return false;
|
@@ -207,6 +207,9 @@ class Xcloner_File_System
|
|
207 |
return $this->start_filesystem->normalizeFileInfo($info);
|
208 |
}
|
209 |
|
|
|
|
|
|
|
210 |
public function get_storage_path_file_info($file)
|
211 |
{
|
212 |
return $this->getMetadataFull('storage_adapter', $file);
|
@@ -431,7 +434,7 @@ class Xcloner_File_System
|
|
431 |
$this->build_files_list($file);
|
432 |
$counter++;
|
433 |
} else {
|
434 |
-
$this->tmp_filesystem_append->write($this->get_temp_dir_handler(), $file
|
435 |
}
|
436 |
}
|
437 |
} else {
|
@@ -472,15 +475,15 @@ class Xcloner_File_System
|
|
472 |
{
|
473 |
$return = array();
|
474 |
|
475 |
-
$files_list_file = $this->xcloner_settings->get_xcloner_tmp_path()
|
476 |
if (file_exists($files_list_file)) {
|
477 |
$return[] = $files_list_file;
|
478 |
}
|
479 |
|
480 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_enable_log')) {
|
481 |
-
$log_file = $this->xcloner_settings->get_xcloner_tmp_path()
|
482 |
if (!file_exists($log_file)) {
|
483 |
-
$log_file = $this->xcloner_settings->get_xcloner_store_path()
|
484 |
}
|
485 |
|
486 |
if (file_exists($log_file)) {
|
@@ -505,7 +508,11 @@ class Xcloner_File_System
|
|
505 |
}
|
506 |
}
|
507 |
|
508 |
-
|
|
|
|
|
|
|
|
|
509 |
|
510 |
return;
|
511 |
}
|
@@ -614,7 +621,7 @@ class Xcloner_File_System
|
|
614 |
|
615 |
$files = $this->start_filesystem->listContents($folder);
|
616 |
foreach ($files as $file) {
|
617 |
-
if (!is_readable($this->xcloner_settings->get_xcloner_start_path()
|
618 |
$this->logger->info(sprintf(__("Excluding %s from the filesystem list, file not readable"),
|
619 |
$file['path']), array(
|
620 |
"FILESYSTEM SCAN",
|
@@ -642,7 +649,7 @@ class Xcloner_File_System
|
|
642 |
}
|
643 |
}
|
644 |
|
645 |
-
}
|
646 |
|
647 |
$this->logger->error($e->getMessage());
|
648 |
|
@@ -652,7 +659,7 @@ class Xcloner_File_System
|
|
652 |
|
653 |
public function estimate_read_write_time()
|
654 |
{
|
655 |
-
$tmp_file = ".xcloner"
|
656 |
|
657 |
$start_time = microtime(true);
|
658 |
|
@@ -669,7 +676,7 @@ class Xcloner_File_System
|
|
669 |
|
670 |
$this->tmp_filesystem->delete($tmp_file);
|
671 |
|
672 |
-
}
|
673 |
|
674 |
$this->logger->error($e->getMessage());
|
675 |
|
@@ -686,7 +693,7 @@ class Xcloner_File_System
|
|
686 |
$_backup_files_list = array();
|
687 |
|
688 |
//rule date limit
|
689 |
-
$current_timestamp = strtotime("-"
|
690 |
|
691 |
$files = $this->storage_filesystem->listContents();
|
692 |
|
@@ -711,18 +718,18 @@ class Xcloner_File_System
|
|
711 |
{
|
712 |
$this->storage_filesystem->delete($file['path']);
|
713 |
$_storage_size -= $file['size'];
|
714 |
-
$this->logger->info("Deleting backup "
|
715 |
"STORAGE SIZE LIMIT",
|
716 |
-
$_storage_size
|
717 |
));
|
718 |
}
|
719 |
|
720 |
//processing rule days limit
|
721 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days') && $current_timestamp >= $file['timestamp']) {
|
722 |
$this->storage_filesystem->delete($file['path']);
|
723 |
-
$this->logger->info("Deleting backup "
|
724 |
"RETENTION LIMIT TIMESTAMP",
|
725 |
-
$file['timestamp']
|
726 |
));
|
727 |
}
|
728 |
|
@@ -730,9 +737,9 @@ class Xcloner_File_System
|
|
730 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives') && $_backups_counter >= $this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives')) {
|
731 |
$this->storage_filesystem->delete($file['path']);
|
732 |
$_backups_counter--;
|
733 |
-
$this->logger->info("Deleting backup "
|
734 |
"BACKUP QUANTITY LIMIT",
|
735 |
-
$_backups_counter
|
736 |
));
|
737 |
}
|
738 |
|
@@ -741,6 +748,9 @@ class Xcloner_File_System
|
|
741 |
|
742 |
}
|
743 |
|
|
|
|
|
|
|
744 |
public function estimate_reading_time($tmp_file)
|
745 |
{
|
746 |
$this->logger->debug(sprintf(("Estimating file system reading time")));
|
@@ -781,6 +791,9 @@ class Xcloner_File_System
|
|
781 |
return $name;
|
782 |
}
|
783 |
|
|
|
|
|
|
|
784 |
public function sort_by(&$array, $field, $direction = 'asc')
|
785 |
{
|
786 |
if (strtolower($direction) == "desc" || $direction == SORT_DESC) {
|
@@ -829,7 +842,7 @@ class Xcloner_File_System
|
|
829 |
}
|
830 |
|
831 |
if ($timestamp <= $this->get_diff_timestamp_start()) {
|
832 |
-
return " file DIFF timestamp "
|
833 |
}
|
834 |
}
|
835 |
|
@@ -842,7 +855,7 @@ class Xcloner_File_System
|
|
842 |
|
843 |
if ($xcloner_exclude_files_larger_than_mb = $this->xcloner_settings->get_xcloner_option('xcloner_exclude_files_larger_than_mb')) {
|
844 |
if (isset($file['size']) && $file['size'] > $this->calc_to_bytes($xcloner_exclude_files_larger_than_mb)) {
|
845 |
-
return "> "
|
846 |
}
|
847 |
}
|
848 |
|
@@ -855,10 +868,10 @@ class Xcloner_File_System
|
|
855 |
if ($excluded_file_pattern == "/") {
|
856 |
$needle = "$";
|
857 |
} else {
|
858 |
-
$needle = "$"
|
859 |
}
|
860 |
|
861 |
-
if (strstr("$"
|
862 |
return $excluded_file_pattern;
|
863 |
}
|
864 |
}
|
@@ -910,163 +923,163 @@ class Xcloner_File_System
|
|
910 |
* exclude the backup folders
|
911 |
* PATTERN: (^|^\/)(wp-content\/backups|administrator\/backups)(.*)$";
|
912 |
*/
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
|
1072 |
}
|
61 |
private $files_size;
|
62 |
private $last_logged_file;
|
63 |
private $folders_to_process_per_session = 25;
|
64 |
+
private $backup_archive_extensions = array("tar", "tgz", "tar.gz", "gz", "csv", "encrypted", "decrypted");
|
65 |
private $backup_name_tags = array('[time]', '[hostname]', '[domain]');
|
66 |
|
67 |
/**
|
102 |
$this->storage_filesystem_append = new Filesystem($this->storage_adapter, new Config([
|
103 |
'disable_asserts' => true,
|
104 |
]));
|
105 |
+
}catch (Exception $e) {
|
106 |
+
$this->logger->error("Filesystem Initialization Error: ".$e->getMessage());
|
107 |
}
|
108 |
|
109 |
|
161 |
{
|
162 |
if ($remote_storage_selection != "") {
|
163 |
$remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
164 |
+
$method = "get_".$remote_storage_selection."_filesystem";
|
165 |
|
166 |
if (!method_exists($remote_storage, $method)) {
|
167 |
return false;
|
207 |
return $this->start_filesystem->normalizeFileInfo($info);
|
208 |
}
|
209 |
|
210 |
+
/**
|
211 |
+
* @param string $file
|
212 |
+
*/
|
213 |
public function get_storage_path_file_info($file)
|
214 |
{
|
215 |
return $this->getMetadataFull('storage_adapter', $file);
|
434 |
$this->build_files_list($file);
|
435 |
$counter++;
|
436 |
} else {
|
437 |
+
$this->tmp_filesystem_append->write($this->get_temp_dir_handler(), $file."\n");
|
438 |
}
|
439 |
}
|
440 |
} else {
|
475 |
{
|
476 |
$return = array();
|
477 |
|
478 |
+
$files_list_file = $this->xcloner_settings->get_xcloner_tmp_path().DS.$this->get_included_files_handler();
|
479 |
if (file_exists($files_list_file)) {
|
480 |
$return[] = $files_list_file;
|
481 |
}
|
482 |
|
483 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_enable_log')) {
|
484 |
+
$log_file = $this->xcloner_settings->get_xcloner_tmp_path().DS.$this->xcloner_settings->get_logger_filename(1);
|
485 |
if (!file_exists($log_file)) {
|
486 |
+
$log_file = $this->xcloner_settings->get_xcloner_store_path().DS.$this->xcloner_settings->get_logger_filename();
|
487 |
}
|
488 |
|
489 |
if (file_exists($log_file)) {
|
508 |
}
|
509 |
}
|
510 |
|
511 |
+
try {
|
512 |
+
rmdir($this->xcloner_settings->get_xcloner_tmp_path());
|
513 |
+
}catch (Exception $e) {
|
514 |
+
//silent continue
|
515 |
+
}
|
516 |
|
517 |
return;
|
518 |
}
|
621 |
|
622 |
$files = $this->start_filesystem->listContents($folder);
|
623 |
foreach ($files as $file) {
|
624 |
+
if (!is_readable($this->xcloner_settings->get_xcloner_start_path().DS.$file['path'])) {
|
625 |
$this->logger->info(sprintf(__("Excluding %s from the filesystem list, file not readable"),
|
626 |
$file['path']), array(
|
627 |
"FILESYSTEM SCAN",
|
649 |
}
|
650 |
}
|
651 |
|
652 |
+
}catch (Exception $e) {
|
653 |
|
654 |
$this->logger->error($e->getMessage());
|
655 |
|
659 |
|
660 |
public function estimate_read_write_time()
|
661 |
{
|
662 |
+
$tmp_file = ".xcloner".substr(md5(time()), 0, 5);
|
663 |
|
664 |
$start_time = microtime(true);
|
665 |
|
676 |
|
677 |
$this->tmp_filesystem->delete($tmp_file);
|
678 |
|
679 |
+
}catch (Exception $e) {
|
680 |
|
681 |
$this->logger->error($e->getMessage());
|
682 |
|
693 |
$_backup_files_list = array();
|
694 |
|
695 |
//rule date limit
|
696 |
+
$current_timestamp = strtotime("-".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days')." days");
|
697 |
|
698 |
$files = $this->storage_filesystem->listContents();
|
699 |
|
718 |
{
|
719 |
$this->storage_filesystem->delete($file['path']);
|
720 |
$_storage_size -= $file['size'];
|
721 |
+
$this->logger->info("Deleting backup ".$file['path']." matching rule", array(
|
722 |
"STORAGE SIZE LIMIT",
|
723 |
+
$_storage_size." >= ".$set_storage_limit
|
724 |
));
|
725 |
}
|
726 |
|
727 |
//processing rule days limit
|
728 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days') && $current_timestamp >= $file['timestamp']) {
|
729 |
$this->storage_filesystem->delete($file['path']);
|
730 |
+
$this->logger->info("Deleting backup ".$file['path']." matching rule", array(
|
731 |
"RETENTION LIMIT TIMESTAMP",
|
732 |
+
$file['timestamp']." =< ".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_days')
|
733 |
));
|
734 |
}
|
735 |
|
737 |
if ($this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives') && $_backups_counter >= $this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives')) {
|
738 |
$this->storage_filesystem->delete($file['path']);
|
739 |
$_backups_counter--;
|
740 |
+
$this->logger->info("Deleting backup ".$file['path']." matching rule", array(
|
741 |
"BACKUP QUANTITY LIMIT",
|
742 |
+
$_backups_counter." >= ".$this->xcloner_settings->get_xcloner_option('xcloner_cleanup_retention_limit_archives')
|
743 |
));
|
744 |
}
|
745 |
|
748 |
|
749 |
}
|
750 |
|
751 |
+
/**
|
752 |
+
* @param string $tmp_file
|
753 |
+
*/
|
754 |
public function estimate_reading_time($tmp_file)
|
755 |
{
|
756 |
$this->logger->debug(sprintf(("Estimating file system reading time")));
|
791 |
return $name;
|
792 |
}
|
793 |
|
794 |
+
/**
|
795 |
+
* @param string $field
|
796 |
+
*/
|
797 |
public function sort_by(&$array, $field, $direction = 'asc')
|
798 |
{
|
799 |
if (strtolower($direction) == "desc" || $direction == SORT_DESC) {
|
842 |
}
|
843 |
|
844 |
if ($timestamp <= $this->get_diff_timestamp_start()) {
|
845 |
+
return " file DIFF timestamp ".$timestamp." < ".$this->diff_timestamp_start;
|
846 |
}
|
847 |
}
|
848 |
|
855 |
|
856 |
if ($xcloner_exclude_files_larger_than_mb = $this->xcloner_settings->get_xcloner_option('xcloner_exclude_files_larger_than_mb')) {
|
857 |
if (isset($file['size']) && $file['size'] > $this->calc_to_bytes($xcloner_exclude_files_larger_than_mb)) {
|
858 |
+
return "> ".$xcloner_exclude_files_larger_than_mb."MB";
|
859 |
}
|
860 |
}
|
861 |
|
868 |
if ($excluded_file_pattern == "/") {
|
869 |
$needle = "$";
|
870 |
} else {
|
871 |
+
$needle = "$".$excluded_file_pattern;
|
872 |
}
|
873 |
|
874 |
+
if (strstr("$".$file['path'], $needle)) {
|
875 |
return $excluded_file_pattern;
|
876 |
}
|
877 |
}
|
923 |
* exclude the backup folders
|
924 |
* PATTERN: (^|^\/)(wp-content\/backups|administrator\/backups)(.*)$";
|
925 |
*/
|
926 |
+
private function is_excluded_regex($file)
|
927 |
+
{
|
928 |
+
//$this->logger->debug(sprintf(("Checking if %s is excluded"), $file['path']));
|
929 |
+
|
930 |
+
$regex_patterns = explode(PHP_EOL, $this->xcloner_settings->get_xcloner_option('xcloner_regex_exclude'));
|
931 |
+
|
932 |
+
if (is_array($this->additional_regex_patterns)) {
|
933 |
+
$regex_patterns = array_merge($regex_patterns, $this->additional_regex_patterns);
|
934 |
+
}
|
935 |
+
|
936 |
+
//print_r($regex_patterns);exit;
|
937 |
+
|
938 |
+
if (is_array($regex_patterns)) {
|
939 |
+
//$this->excluded_files = array();
|
940 |
+
//$this->excluded_files[] ="(.*)\.(git)(.*)$";
|
941 |
+
//$this->excluded_files[] ="wp-content\/backups(.*)$";
|
942 |
+
|
943 |
+
foreach ($regex_patterns as $excluded_file_pattern) {
|
944 |
+
|
945 |
+
if (substr($excluded_file_pattern, strlen($excluded_file_pattern) - 1,
|
946 |
+
strlen($excluded_file_pattern)) == "\r") {
|
947 |
+
$excluded_file_pattern = substr($excluded_file_pattern, 0, strlen($excluded_file_pattern) - 1);
|
948 |
+
}
|
949 |
+
|
950 |
+
if ($file['path'] == "/") {
|
951 |
+
$needle = "/";
|
952 |
+
} else {
|
953 |
+
$needle = "/".$file['path'];
|
954 |
+
}
|
955 |
+
//echo $needle."---".$excluded_file_pattern."---\n";
|
956 |
+
|
957 |
+
if (@preg_match("/(^|^\/)".$excluded_file_pattern."/i", $needle)) {
|
958 |
+
return $excluded_file_pattern;
|
959 |
+
}
|
960 |
+
}
|
961 |
+
}
|
962 |
+
|
963 |
+
return false;
|
964 |
+
}
|
965 |
+
|
966 |
+
public function store_file($file, $storage = 'start_filesystem')
|
967 |
+
{
|
968 |
+
$this->logger->debug(sprintf("Storing %s in the backup list", $file['path']));
|
969 |
+
|
970 |
+
if (!isset($file['size'])) {
|
971 |
+
$file['size'] = 0;
|
972 |
+
}
|
973 |
+
if (!isset($file['visibility'])) {
|
974 |
+
$file['visibility'] = "private";
|
975 |
+
}
|
976 |
+
|
977 |
+
$csv_filename = str_replace('"', '""', $file['path']);
|
978 |
+
|
979 |
+
$line = '"'.($csv_filename).'","'.$file['timestamp'].'","'.$file['size'].'","'.$file['visibility'].'","'.$storage.'"'.PHP_EOL;
|
980 |
+
|
981 |
+
$this->last_logged_file = $file['path'];
|
982 |
+
|
983 |
+
if ($file['type'] == "dir") {
|
984 |
+
try {
|
985 |
+
$this->tmp_filesystem_append->write($this->get_temp_dir_handler(), $file['path']."\n");
|
986 |
+
}catch (Exception $e) {
|
987 |
+
$this->logger->error($e->getMessage());
|
988 |
+
}
|
989 |
+
}
|
990 |
+
|
991 |
+
if ($this->get_diff_timestamp_start()) {
|
992 |
+
if ($file['type'] != "file" && $response = $this->check_file_diff_time($file)) {
|
993 |
+
$this->logger->info(sprintf("Directory %s archiving skipped on differential backup %s", $file['path'],
|
994 |
+
$response), array(
|
995 |
+
"FILESYSTEM SCAN",
|
996 |
+
"DIR DIFF"
|
997 |
+
));
|
998 |
+
|
999 |
+
return false;
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
try {
|
1004 |
+
if (!$this->tmp_filesystem_append->has($this->get_included_files_handler())) {
|
1005 |
+
//adding fix for UTF-8 CSV preview
|
1006 |
+
$start_line = "\xEF\xBB\xBF".'"Filename","Timestamp","Size","Visibility","Storage"'.PHP_EOL;
|
1007 |
+
$this->tmp_filesystem_append->write($this->get_included_files_handler(), $start_line);
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
$this->tmp_filesystem_append->write($this->get_included_files_handler(), $line);
|
1011 |
+
|
1012 |
+
}catch (Exception $e) {
|
1013 |
+
|
1014 |
+
$this->logger->error($e->getMessage());
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
return true;
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
public function get_fileystem_handler()
|
1021 |
+
{
|
1022 |
+
return $this;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
public function get_filesystem($system = "")
|
1026 |
+
{
|
1027 |
+
if ($system == "storage_filesystem_append") {
|
1028 |
+
return $this->storage_filesystem_append;
|
1029 |
+
} elseif ($system == "tmp_filesystem_append") {
|
1030 |
+
return $this->tmp_filesystem_append;
|
1031 |
+
} elseif ($system == "tmp_filesystem") {
|
1032 |
+
return $this->tmp_filesystem;
|
1033 |
+
} elseif ($system == "storage_filesystem") {
|
1034 |
+
return $this->storage_filesystem;
|
1035 |
+
} else {
|
1036 |
+
return $this->start_filesystem;
|
1037 |
+
}
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
public function get_adapter($system)
|
1041 |
+
{
|
1042 |
+
if ($system == "tmp_filesystem") {
|
1043 |
+
return $this->tmp_adapter;
|
1044 |
+
} elseif ($system == "storage_filesystem") {
|
1045 |
+
return $this->storage_adapter;
|
1046 |
+
} else {
|
1047 |
+
return $this->start_adapter;
|
1048 |
+
}
|
1049 |
+
}
|
1050 |
+
|
1051 |
+
/**
|
1052 |
+
* File scan finished
|
1053 |
+
* Method called when file scan is finished
|
1054 |
+
*
|
1055 |
+
* @return bool
|
1056 |
+
*/
|
1057 |
+
private function scan_finished()
|
1058 |
+
{
|
1059 |
+
if ($this->tmp_filesystem_append->has($this->get_temp_dir_handler()) &&
|
1060 |
+
$this->tmp_filesystem_append->getSize($this->get_temp_dir_handler())) {
|
1061 |
+
return false;
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
if ($this->tmp_filesystem->has($this->get_temp_dir_handler())) {
|
1065 |
+
$this->tmp_filesystem->delete($this->get_temp_dir_handler());
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
$this->logger->debug(sprintf(("File scan finished")));
|
1069 |
+
|
1070 |
+
return true;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
/**
|
1074 |
+
* Calculate bytes from MB value
|
1075 |
+
*
|
1076 |
+
* @param int $mb_size
|
1077 |
+
*
|
1078 |
+
* @return float|int
|
1079 |
+
*/
|
1080 |
+
private function calc_to_bytes($mb_size)
|
1081 |
+
{
|
1082 |
+
return $mb_size * (1024 * 1024);
|
1083 |
+
}
|
1084 |
|
1085 |
}
|
includes/class-xcloner-file-transfer.php
CHANGED
@@ -29,136 +29,137 @@
|
|
29 |
class Xcloner_File_Transfer extends Xcloner_File_System
|
30 |
{
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
|
77 |
|
78 |
-
|
79 |
|
80 |
-
|
81 |
|
82 |
-
|
83 |
|
84 |
-
|
85 |
|
86 |
-
|
87 |
|
88 |
-
|
89 |
|
90 |
-
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
-
|
100 |
|
101 |
-
|
102 |
-
|
103 |
|
104 |
|
105 |
-
|
106 |
-
|
107 |
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
|
115 |
-
|
116 |
-
|
117 |
|
118 |
-
|
119 |
|
120 |
-
$this->get_tmp_filesystem()->delete($tmp_filename);
|
121 |
|
122 |
-
|
123 |
|
124 |
-
|
125 |
-
throw new Exception("We have received no valid response from the remote host, original message: " . $original_result);
|
126 |
-
}
|
127 |
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
$this->remove_tmp_filesystem();
|
136 |
|
137 |
-
|
138 |
-
|
|
|
|
|
139 |
|
140 |
-
|
141 |
-
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
* @param string $mimetype
|
146 |
-
* @param string $postname
|
147 |
-
*
|
148 |
-
* @return CURLFile|string
|
149 |
-
*/
|
150 |
-
private function curl_file_create($filename, $mimetype = '', $postname = '')
|
151 |
-
{
|
152 |
-
if (!function_exists('curl_file_create')) {
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
-
|
|
|
|
|
159 |
|
160 |
-
|
161 |
|
162 |
-
|
163 |
-
|
|
|
|
|
164 |
}
|
29 |
class Xcloner_File_Transfer extends Xcloner_File_System
|
30 |
{
|
31 |
|
32 |
+
/**
|
33 |
+
* Target url web address of the restore script
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
private $target_url;
|
37 |
+
/**
|
38 |
+
* Transfer data limit in bytes
|
39 |
+
* @var int
|
40 |
+
*/
|
41 |
+
private $transfer_limit = 1048576; //bytes 1MB= 1048576 300KB = 358400
|
42 |
|
43 |
|
44 |
+
/**
|
45 |
+
* @param $target_url
|
46 |
+
*
|
47 |
+
* @return mixed
|
48 |
+
*/
|
49 |
+
public function set_target($target_url)
|
50 |
+
{
|
51 |
+
return $this->target_url = $target_url;
|
52 |
+
}
|
53 |
|
54 |
+
/**
|
55 |
+
* @return string
|
56 |
+
*/
|
57 |
+
public function get_target()
|
58 |
+
{
|
59 |
+
return $this->target_url;
|
60 |
+
}
|
61 |
|
62 |
|
63 |
+
/**
|
64 |
+
* @param $file
|
65 |
+
* @param int $start
|
66 |
+
* @param string $hash
|
67 |
+
*
|
68 |
+
* @return bool|int
|
69 |
+
* @throws Exception
|
70 |
+
*/
|
71 |
+
public function transfer_file($file, $start = 0, $hash = "")
|
72 |
+
{
|
73 |
+
if (!$this->target_url) {
|
74 |
+
throw new Exception("Please setup a target url for upload");
|
75 |
+
}
|
76 |
|
77 |
|
78 |
+
$fp = $this->get_storage_filesystem()->readStream($file);
|
79 |
|
80 |
+
fseek($fp, $start, SEEK_SET);
|
81 |
|
82 |
+
$binary_data = fread($fp, $this->transfer_limit);
|
83 |
|
84 |
+
$tmp_filename = "xcloner_upload_".substr(md5(time()), 0, 5);
|
85 |
|
86 |
+
$this->get_tmp_filesystem()->write($tmp_filename, $binary_data);
|
87 |
|
88 |
+
$tmp_file_path = $this->get_tmp_filesystem_adapter()->applyPathPrefix($tmp_filename);
|
89 |
|
90 |
+
$send_array = array();
|
91 |
|
92 |
+
$send_array['file'] = $file;
|
93 |
+
$send_array['start'] = $start;
|
94 |
+
$send_array['xcloner_action'] = "write_file";
|
95 |
+
$send_array['hash'] = $hash;
|
96 |
+
#$send_array['blob'] = $binary_data;
|
97 |
+
$send_array['blob'] = $this->curl_file_create($tmp_file_path, 'application/x-binary', $tmp_filename);
|
98 |
|
99 |
+
//$data = http_build_query($send_array);
|
100 |
|
101 |
+
$this->get_logger()->info(sprintf("Sending curl request to %s with %s data of file %s starting position %s using temporary file %s",
|
102 |
+
$this->target_url, $this->transfer_limit, $file, $start, $tmp_filename));
|
103 |
|
104 |
|
105 |
+
$ch = curl_init();
|
106 |
+
curl_setopt($ch, CURLOPT_URL, $this->target_url);
|
107 |
|
108 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
109 |
+
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
|
110 |
+
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
|
111 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
|
112 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, 1200);
|
113 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
114 |
|
115 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $send_array);
|
116 |
+
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
117 |
|
118 |
+
$original_result = curl_exec($ch);
|
119 |
|
|
|
120 |
|
121 |
+
$this->get_tmp_filesystem()->delete($tmp_filename);
|
122 |
|
123 |
+
$result = json_decode($original_result);
|
|
|
|
|
124 |
|
125 |
+
if (!$result) {
|
126 |
+
throw new Exception("We have received no valid response from the remote host, original message: ".$original_result);
|
127 |
+
}
|
128 |
|
129 |
+
if ($result->status != 200) {
|
130 |
+
throw new Exception($result->response);
|
131 |
+
}
|
|
|
132 |
|
133 |
+
if (ftell($fp) >= $this->get_storage_filesystem()->getSize($file)) {
|
134 |
+
$this->get_logger()->info(sprintf("Upload done for file %s to target url %s, transferred a total of %s bytes",
|
135 |
+
$file, $this->target_url, ftell($fp)));
|
136 |
+
$this->remove_tmp_filesystem();
|
137 |
|
138 |
+
return false;
|
139 |
+
}
|
140 |
|
141 |
+
return ftell($fp);
|
142 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
|
144 |
+
/**
|
145 |
+
* @param string $filename
|
146 |
+
* @param string $mimetype
|
147 |
+
* @param string $postname
|
148 |
+
*
|
149 |
+
* @return CURLFile|string
|
150 |
+
*/
|
151 |
+
private function curl_file_create($filename, $mimetype = '', $postname = '')
|
152 |
+
{
|
153 |
+
if (!function_exists('curl_file_create')) {
|
154 |
|
155 |
+
return "@$filename;filename="
|
156 |
+
. ($postname ?: basename($filename))
|
157 |
+
. ($mimetype ? ";type=$mimetype" : '');
|
158 |
|
159 |
+
} else {
|
160 |
|
161 |
+
return curl_file_create($filename, $mimetype, $postname);
|
162 |
+
|
163 |
+
}
|
164 |
+
}
|
165 |
}
|
includes/class-xcloner-i18n.php
CHANGED
@@ -41,21 +41,21 @@
|
|
41 |
class Xcloner_i18n
|
42 |
{
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
|
58 |
-
|
59 |
|
60 |
|
61 |
}
|
41 |
class Xcloner_i18n
|
42 |
{
|
43 |
|
44 |
+
/**
|
45 |
+
* Load the plugin text domain for translation.
|
46 |
+
*
|
47 |
+
* @since 1.0.0
|
48 |
+
*/
|
49 |
+
public function load_plugin_textdomain()
|
50 |
+
{
|
51 |
|
52 |
+
load_plugin_textdomain(
|
53 |
+
'xcloner-backup-and-restore',
|
54 |
+
false,
|
55 |
+
dirname(dirname(plugin_basename(__FILE__))).'/languages/'
|
56 |
+
);
|
57 |
|
58 |
+
}
|
59 |
|
60 |
|
61 |
}
|
includes/class-xcloner-loader.php
CHANGED
@@ -41,154 +41,167 @@
|
|
41 |
class Xcloner_Loader
|
42 |
{
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
}
|
41 |
class Xcloner_Loader
|
42 |
{
|
43 |
|
44 |
+
/**
|
45 |
+
* The array of actions registered with WordPress.
|
46 |
+
*
|
47 |
+
* @since 1.0.0
|
48 |
+
* @access protected
|
49 |
+
* @var array $actions The actions registered with WordPress to fire when the plugin loads.
|
50 |
+
*/
|
51 |
+
protected $actions;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* The array of filters registered with WordPress.
|
55 |
+
*
|
56 |
+
* @since 1.0.0
|
57 |
+
* @access protected
|
58 |
+
* @var array $filters The filters registered with WordPress to fire when the plugin loads.
|
59 |
+
*/
|
60 |
+
protected $filters;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @var Xcloner
|
64 |
+
*/
|
65 |
+
private $xcloner_plugin;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @var Xcloner
|
69 |
+
*/
|
70 |
+
private $xcloner_container;
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Initialize the collections used to maintain the actions and filters.
|
75 |
+
*
|
76 |
+
* Xcloner_Loader constructor.
|
77 |
+
* @param Xcloner $xcloner_container
|
78 |
+
*/
|
79 |
+
public function __construct(Xcloner $xcloner_container)
|
80 |
+
{
|
81 |
+
|
82 |
+
$this->actions = array();
|
83 |
+
$this->filters = array();
|
84 |
+
|
85 |
+
$this->xcloner_container = $xcloner_container;
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Add XCloner to Admin Menu
|
91 |
+
*/
|
92 |
+
public function xcloner_backup_add_admin_menu()
|
93 |
+
{
|
94 |
+
if (function_exists('add_menu_page')) {
|
95 |
+
add_menu_page(__('Site Backup', 'xcloner-backup-and-restore'),
|
96 |
+
__('Site Backup', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_init_page',
|
97 |
+
array($this->xcloner_container, 'xcloner_display'), 'dashicons-backup');
|
98 |
+
}
|
99 |
+
|
100 |
+
if (function_exists('add_submenu_page')) {
|
101 |
+
|
102 |
+
add_submenu_page('xcloner_init_page', __('XCloner Dashboard', 'xcloner-backup-and-restore'),
|
103 |
+
__('Dashboard', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_init_page',
|
104 |
+
array($this->xcloner_container, 'xcloner_display'));
|
105 |
+
add_submenu_page('xcloner_init_page', __('XCloner Backup Settings', 'xcloner-backup-and-restore'),
|
106 |
+
__('Settings', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_settings_page',
|
107 |
+
array($this->xcloner_container, 'xcloner_display'));
|
108 |
+
add_submenu_page('xcloner_init_page', __('Remote Storage Settings', 'xcloner-backup-and-restore'),
|
109 |
+
__('Remote Storage', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_remote_storage_page',
|
110 |
+
array($this->xcloner_container, 'xcloner_display'));
|
111 |
+
add_submenu_page('xcloner_init_page', __('Manage Backups', 'xcloner-backup-and-restore'),
|
112 |
+
__('Manage Backups', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_manage_backups_page',
|
113 |
+
array($this->xcloner_container, 'xcloner_display'));
|
114 |
+
add_submenu_page('xcloner_init_page', __('Scheduled Backups', 'xcloner-backup-and-restore'),
|
115 |
+
__('Scheduled Backups', 'xcloner-backup-and-restore'), 'manage_options',
|
116 |
+
'xcloner_scheduled_backups_page', array($this->xcloner_container, 'xcloner_display'));
|
117 |
+
add_submenu_page('xcloner_init_page', __('Generate Backups', 'xcloner-backup-and-restore'),
|
118 |
+
__('Generate Backups', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_generate_backups_page',
|
119 |
+
array($this->xcloner_container, 'xcloner_display'));
|
120 |
+
add_submenu_page('xcloner_init_page', __('Restore Backups', 'xcloner-backup-and-restore'),
|
121 |
+
__('Restore Backups', 'xcloner-backup-and-restore'), 'manage_options', 'xcloner_restore_page',
|
122 |
+
array($this->xcloner_container, 'xcloner_display'));
|
123 |
+
}
|
124 |
+
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Add a new action to the collection to be registered with WordPress.
|
130 |
+
*
|
131 |
+
* @since 1.0.0
|
132 |
+
* @param string $hook The name of the WordPress action that is being registered.
|
133 |
+
* @param object $component A reference to the instance of the object on which the action is defined.
|
134 |
+
* @param string $callback The name of the function definition on the $component.
|
135 |
+
* @param int $priority Optional. he priority at which the function should be fired. Default is 10.
|
136 |
+
* @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
|
137 |
+
*/
|
138 |
+
public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1)
|
139 |
+
{
|
140 |
+
$this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Add a new filter to the collection to be registered with WordPress.
|
145 |
+
*
|
146 |
+
* @since 1.0.0
|
147 |
+
* @param string $hook The name of the WordPress filter that is being registered.
|
148 |
+
* @param object $component A reference to the instance of the object on which the filter is defined.
|
149 |
+
* @param string $callback The name of the function definition on the $component.
|
150 |
+
* @param int $priority Optional. he priority at which the function should be fired. Default is 10.
|
151 |
+
* @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
|
152 |
+
*/
|
153 |
+
public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
|
154 |
+
{
|
155 |
+
$this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* A utility function that is used to register the actions and hooks into a single
|
160 |
+
* collection.
|
161 |
+
*
|
162 |
+
* @since 1.0.0
|
163 |
+
* @access private
|
164 |
+
* @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
|
165 |
+
* @param string $hook The name of the WordPress filter that is being registered.
|
166 |
+
* @param object $component A reference to the instance of the object on which the filter is defined.
|
167 |
+
* @param string $callback The name of the function definition on the $component.
|
168 |
+
* @param int $priority The priority at which the function should be fired.
|
169 |
+
* @param int $accepted_args The number of arguments that should be passed to the $callback.
|
170 |
+
* @return array The collection of actions and filters registered with WordPress.
|
171 |
+
*/
|
172 |
+
private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
|
173 |
+
{
|
174 |
+
|
175 |
+
$hooks[] = array(
|
176 |
+
'hook' => $hook,
|
177 |
+
'component' => $component,
|
178 |
+
'callback' => $callback,
|
179 |
+
'priority' => $priority,
|
180 |
+
'accepted_args' => $accepted_args
|
181 |
+
);
|
182 |
+
|
183 |
+
return $hooks;
|
184 |
+
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Register the filters and actions with WordPress.
|
189 |
+
*
|
190 |
+
* @since 1.0.0
|
191 |
+
*/
|
192 |
+
public function run()
|
193 |
+
{
|
194 |
+
|
195 |
+
foreach ($this->filters as $hook) {
|
196 |
+
add_filter($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'],
|
197 |
+
$hook['accepted_args']);
|
198 |
+
}
|
199 |
+
|
200 |
+
foreach ($this->actions as $hook) {
|
201 |
+
add_action($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'],
|
202 |
+
$hook['accepted_args']);
|
203 |
+
}
|
204 |
+
|
205 |
+
}
|
206 |
|
207 |
}
|
includes/class-xcloner-logger.php
CHANGED
@@ -10,99 +10,112 @@ class Xcloner_Logger extends Logger {
|
|
10 |
private $max_logger_files = 7;
|
11 |
private $main_logger_url;
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
} else {
|
17 |
$xcloner_settings = $xcloner_container->get_xcloner_settings();
|
18 |
}
|
19 |
|
20 |
$hash = $xcloner_settings->get_hash();
|
21 |
-
if (
|
22 |
$hash = "";
|
23 |
}
|
24 |
|
25 |
-
$logger_path = $xcloner_settings->get_xcloner_store_path()
|
26 |
$logger_path_tmp = "";
|
27 |
|
28 |
-
if (
|
29 |
-
$logger_path_tmp = $xcloner_settings->get_xcloner_tmp_path()
|
30 |
}
|
31 |
|
32 |
$this->logger_path = $logger_path;
|
33 |
|
34 |
-
if (
|
35 |
$logger_path = 'php://stderr';
|
36 |
$logger_path_tmp = "";
|
37 |
}
|
38 |
|
39 |
-
if (
|
40 |
$logger_path = 'php://stderr';
|
41 |
$logger_path_tmp = "";
|
42 |
}
|
43 |
|
44 |
// create a log channel
|
45 |
-
parent::__construct(
|
46 |
|
47 |
$debug_level = Logger::INFO;
|
48 |
|
49 |
-
if (
|
50 |
$debug_level = Logger::DEBUG;
|
51 |
}
|
52 |
|
53 |
|
54 |
-
if (
|
55 |
-
if (
|
56 |
-
$stream = new StreamHandler(
|
57 |
} else {
|
58 |
-
$stream = new RotatingFileHandler(
|
59 |
}
|
60 |
|
61 |
-
$this->pushHandler(
|
62 |
|
63 |
$this->main_logger_url = $stream->getUrl();
|
64 |
}
|
65 |
|
66 |
-
if (
|
67 |
-
$this->pushHandler(
|
68 |
}
|
69 |
|
70 |
//return $this;
|
71 |
}
|
72 |
|
|
|
|
|
|
|
73 |
function get_main_logger_url() {
|
74 |
return $this->main_logger_url;
|
75 |
}
|
76 |
|
77 |
-
|
|
|
|
|
|
|
|
|
78 |
$lines = array();
|
79 |
|
80 |
-
if (
|
81 |
return false;
|
82 |
}
|
83 |
|
84 |
-
$fp = fopen(
|
85 |
-
fseek(
|
86 |
-
$pos = ftell(
|
87 |
$lastLine = "";
|
88 |
|
89 |
// Loop backword until we have our lines or we reach the start
|
90 |
-
while (
|
91 |
|
92 |
-
$C = fgetc(
|
93 |
-
if (
|
94 |
// skip empty lines
|
95 |
-
if (
|
96 |
$lines[] = $lastLine;
|
97 |
}
|
98 |
$lastLine = '';
|
99 |
} else {
|
100 |
-
$lastLine = $C
|
101 |
}
|
102 |
-
fseek(
|
103 |
}
|
104 |
|
105 |
-
$lines = array_reverse(
|
106 |
|
107 |
return $lines;
|
108 |
}
|
10 |
private $max_logger_files = 7;
|
11 |
private $main_logger_url;
|
12 |
|
13 |
+
/**
|
14 |
+
* Xcloner_Logger constructor.
|
15 |
+
* @param Xcloner $xcloner_container
|
16 |
+
* @param string $logger_name
|
17 |
+
* @throws Exception
|
18 |
+
*/
|
19 |
+
public function __construct(Xcloner $xcloner_container, $logger_name = "xcloner_logger") {
|
20 |
+
if (!$xcloner_container->get_xcloner_settings()) {
|
21 |
+
$xcloner_settings = new Xcloner_Settings($xcloner_container);
|
22 |
} else {
|
23 |
$xcloner_settings = $xcloner_container->get_xcloner_settings();
|
24 |
}
|
25 |
|
26 |
$hash = $xcloner_settings->get_hash();
|
27 |
+
if ($hash == "-".$xcloner_settings->get_server_unique_hash(5)) {
|
28 |
$hash = "";
|
29 |
}
|
30 |
|
31 |
+
$logger_path = $xcloner_settings->get_xcloner_store_path().DS.$xcloner_settings->get_logger_filename();
|
32 |
$logger_path_tmp = "";
|
33 |
|
34 |
+
if ($hash) {
|
35 |
+
$logger_path_tmp = $xcloner_settings->get_xcloner_tmp_path().DS.$xcloner_settings->get_logger_filename(1);
|
36 |
}
|
37 |
|
38 |
$this->logger_path = $logger_path;
|
39 |
|
40 |
+
if (!is_dir($xcloner_settings->get_xcloner_store_path()) or !is_writable($xcloner_settings->get_xcloner_store_path())) {
|
41 |
$logger_path = 'php://stderr';
|
42 |
$logger_path_tmp = "";
|
43 |
}
|
44 |
|
45 |
+
if (!$xcloner_settings->get_xcloner_option('xcloner_enable_log')) {
|
46 |
$logger_path = 'php://stderr';
|
47 |
$logger_path_tmp = "";
|
48 |
}
|
49 |
|
50 |
// create a log channel
|
51 |
+
parent::__construct($logger_name);
|
52 |
|
53 |
$debug_level = Logger::INFO;
|
54 |
|
55 |
+
if (WP_DEBUG) {
|
56 |
$debug_level = Logger::DEBUG;
|
57 |
}
|
58 |
|
59 |
|
60 |
+
if ($logger_path) {
|
61 |
+
if (!$xcloner_settings->get_xcloner_option('xcloner_enable_log')) {
|
62 |
+
$stream = new StreamHandler($logger_path, $debug_level);
|
63 |
} else {
|
64 |
+
$stream = new RotatingFileHandler($logger_path, $this->max_logger_files, $debug_level);
|
65 |
}
|
66 |
|
67 |
+
$this->pushHandler($stream);
|
68 |
|
69 |
$this->main_logger_url = $stream->getUrl();
|
70 |
}
|
71 |
|
72 |
+
if ($hash and $logger_path_tmp) {
|
73 |
+
$this->pushHandler(new StreamHandler($logger_path_tmp, $debug_level));
|
74 |
}
|
75 |
|
76 |
//return $this;
|
77 |
}
|
78 |
|
79 |
+
/**
|
80 |
+
* @return string|null
|
81 |
+
*/
|
82 |
function get_main_logger_url() {
|
83 |
return $this->main_logger_url;
|
84 |
}
|
85 |
|
86 |
+
/**
|
87 |
+
* @param int $totalLines
|
88 |
+
* @return array|bool
|
89 |
+
*/
|
90 |
+
function getLastDebugLines($totalLines = 200) {
|
91 |
$lines = array();
|
92 |
|
93 |
+
if (!file_exists($this->main_logger_url) or !is_readable($this->main_logger_url)) {
|
94 |
return false;
|
95 |
}
|
96 |
|
97 |
+
$fp = fopen($this->main_logger_url, 'r');
|
98 |
+
fseek($fp, - 1, SEEK_END);
|
99 |
+
$pos = ftell($fp);
|
100 |
$lastLine = "";
|
101 |
|
102 |
// Loop backword until we have our lines or we reach the start
|
103 |
+
while ($pos > 0 && count($lines) < $totalLines) {
|
104 |
|
105 |
+
$C = fgetc($fp);
|
106 |
+
if ($C == "\n") {
|
107 |
// skip empty lines
|
108 |
+
if (trim($lastLine) != "") {
|
109 |
$lines[] = $lastLine;
|
110 |
}
|
111 |
$lastLine = '';
|
112 |
} else {
|
113 |
+
$lastLine = $C.$lastLine;
|
114 |
}
|
115 |
+
fseek($fp, $pos--);
|
116 |
}
|
117 |
|
118 |
+
$lines = array_reverse($lines);
|
119 |
|
120 |
return $lines;
|
121 |
}
|
includes/class-xcloner-remote-storage.php
CHANGED
@@ -51,129 +51,135 @@ use League\Flysystem\WebDAV\WebDAVAdapter;
|
|
51 |
/**
|
52 |
* Class Xcloner_Remote_Storage
|
53 |
*/
|
54 |
-
class Xcloner_Remote_Storage
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
foreach ($array as $key => $type) {
|
175 |
|
176 |
-
if(
|
177 |
add_filter("pre_update_option_" . $this->storage_fields['option_prefix'] . $key,
|
178 |
function ($value) {
|
179 |
|
@@ -192,7 +198,7 @@ class Xcloner_Remote_Storage {
|
|
192 |
}
|
193 |
}
|
194 |
|
195 |
-
|
196 |
|
197 |
/**
|
198 |
* Encrypts and Decrypt a string based on openssl lib
|
@@ -201,578 +207,622 @@ class Xcloner_Remote_Storage {
|
|
201 |
* @param string $action
|
202 |
* @return string
|
203 |
*/
|
204 |
-
private function simple_crypt(
|
|
|
205 |
// you may change these values to your own
|
206 |
$secret_key = NONCE_KEY;
|
207 |
$secret_iv = NONCE_SALT;
|
208 |
|
|
|
|
|
|
|
|
|
|
|
209 |
$output = $string;
|
210 |
$encrypt_method = "AES-256-CBC";
|
211 |
-
$key = hash(
|
212 |
-
$iv = substr(
|
213 |
-
|
214 |
-
if(
|
215 |
-
$output = base64_encode(
|
216 |
-
}
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
222 |
}
|
223 |
}
|
224 |
|
225 |
return $output;
|
226 |
}
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
public function get_available_storages() {
|
233 |
-
$return = array();
|
234 |
-
foreach ( $this->storage_fields as $storage => $data ) {
|
235 |
-
$check_field = $this->storage_fields["option_prefix"] . $storage . "_enable";
|
236 |
-
if ( get_option( $check_field ) ) {
|
237 |
-
$return[ $storage ] = $data['text'];
|
238 |
-
}
|
239 |
-
}
|
240 |
-
|
241 |
-
return $return;
|
242 |
-
}
|
243 |
-
|
244 |
-
public function save( $action = "ftp" ) {
|
245 |
-
if ( ! $action ) {
|
246 |
-
return false;
|
247 |
-
}
|
248 |
-
|
249 |
-
$storage = $this->xcloner_sanitization->sanitize_input_as_string( $action );
|
250 |
-
$this->logger->debug( sprintf( "Saving the remote storage %s options", strtoupper( $action ) ) );
|
251 |
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
|
|
|
|
|
|
|
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
}
|
260 |
|
261 |
-
|
262 |
-
|
263 |
-
|
|
|
|
|
264 |
|
265 |
-
|
266 |
-
|
267 |
-
}
|
268 |
|
269 |
-
|
270 |
-
|
|
|
|
|
271 |
|
272 |
-
|
|
|
|
|
273 |
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
$this->xcloner->trigger_message( __( "%s connection is valid.", 'xcloner-backup-and-restore' ), "success", $this->storage_fields[ $action ]['text'] );
|
278 |
-
$this->logger->debug( sprintf( "Connection to remote storage %s is valid", strtoupper( $action ) ) );
|
279 |
-
} catch ( Exception $e ) {
|
280 |
-
$this->xcloner->trigger_message( "%s connection error: " . $e->getMessage(), "error", $this->storage_fields[ $action ]['text'] );
|
281 |
-
}
|
282 |
-
}
|
283 |
|
284 |
-
|
285 |
-
|
|
|
286 |
|
287 |
-
|
|
|
|
|
288 |
|
289 |
-
|
290 |
-
return false;
|
291 |
-
}
|
292 |
|
293 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
|
295 |
-
|
|
|
|
|
|
|
|
|
|
|
296 |
|
297 |
-
|
298 |
-
|
299 |
-
throw new Exception( __( "Could not read data", 'xcloner-backup-and-restore' ) );
|
300 |
-
}
|
301 |
-
$this->logger->debug( sprintf( "I can list data from remote storage %s", strtoupper( $storage_type ) ) );
|
302 |
|
303 |
-
|
304 |
-
|
|
|
305 |
|
306 |
-
|
307 |
-
if ( ! $filesystem->write( $test_file, "data" ) ) {
|
308 |
-
throw new Exception( __( "Could not write data", 'xcloner-backup-and-restore' ) );
|
309 |
-
}
|
310 |
-
$this->logger->debug( sprintf( "I can write data to remote storage %s", strtoupper( $storage_type ) ) );
|
311 |
|
312 |
-
|
313 |
-
if ( ! $filesystem->has( $test_file ) ) {
|
314 |
-
throw new Exception( __( "Could not read data", 'xcloner-backup-and-restore' ) );
|
315 |
-
}
|
316 |
-
$this->logger->debug( sprintf( "I can read data to remote storage %s", strtoupper( $storage_type ) ) );
|
317 |
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
|
324 |
-
|
325 |
-
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
|
|
|
|
|
330 |
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
333 |
|
334 |
-
|
|
|
|
|
|
|
|
|
335 |
|
336 |
-
|
337 |
-
|
338 |
-
}
|
339 |
|
340 |
-
|
|
|
|
|
|
|
341 |
|
342 |
-
|
343 |
-
|
344 |
|
345 |
-
|
346 |
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
return false;
|
351 |
-
}*/
|
352 |
|
353 |
-
|
354 |
|
355 |
-
|
356 |
-
|
357 |
|
358 |
-
|
359 |
-
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
|
367 |
-
|
368 |
-
if ( ! $remote_storage_filesystem->writeStream( $part_file, $backup_file_stream ) ) {
|
369 |
-
return false;
|
370 |
-
}
|
371 |
-
}
|
372 |
-
}
|
373 |
-
}
|
374 |
|
375 |
-
|
|
|
376 |
|
377 |
-
|
|
|
378 |
|
379 |
-
|
|
|
|
|
|
|
|
|
|
|
380 |
|
381 |
-
|
382 |
-
|
|
|
|
|
|
|
|
|
|
|
383 |
|
384 |
-
|
385 |
|
386 |
-
|
387 |
-
return false;
|
388 |
-
}
|
389 |
|
390 |
-
|
391 |
|
392 |
-
|
393 |
-
|
|
|
394 |
|
395 |
-
|
396 |
-
}
|
397 |
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
}
|
402 |
|
403 |
-
|
404 |
|
405 |
-
|
|
|
406 |
|
407 |
-
|
408 |
-
|
409 |
|
410 |
-
|
411 |
-
|
|
|
|
|
412 |
|
413 |
-
|
414 |
-
|
415 |
-
if ( is_array( $parts ) ) {
|
416 |
-
foreach ( $parts as $part_file ) {
|
417 |
-
$this->logger->info( sprintf( "Transferring backup %s to local storage from %s storage", $part_file, strtoupper( $storage ) ), array( "" ) );
|
418 |
|
419 |
-
|
420 |
-
if ( ! $this->xcloner_file_system->get_storage_filesystem()->writeStream( $part_file, $backup_file_stream ) ) {
|
421 |
-
return false;
|
422 |
-
}
|
423 |
-
}
|
424 |
-
}
|
425 |
-
}
|
426 |
|
427 |
-
|
|
|
428 |
|
429 |
-
|
|
|
430 |
|
431 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
|
433 |
-
|
434 |
-
$check_field = $this->storage_fields["option_prefix"] . $storage . "_cleanup_days";
|
435 |
-
if ( $expire_days = get_option( $check_field ) ) {
|
436 |
-
$this->logger->info( sprintf( "Doing %s remote storage cleanup for %s days limit", strtoupper( $storage ), $expire_days ) );
|
437 |
-
$files = $remote_storage_filesystem->listContents();
|
438 |
|
439 |
-
|
440 |
|
441 |
-
|
442 |
-
foreach ( $files as $file ) {
|
443 |
-
$file['timestamp'] = $remote_storage_filesystem->getTimestamp( $file['path'] );
|
444 |
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
|
458 |
-
|
459 |
-
|
|
|
460 |
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
|
475 |
-
|
476 |
|
477 |
-
|
478 |
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
|
483 |
-
|
484 |
-
|
485 |
|
486 |
-
|
487 |
-
|
|
|
488 |
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
|
493 |
-
|
494 |
-
|
495 |
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
|
500 |
-
|
501 |
-
|
502 |
|
503 |
-
|
504 |
-
|
|
|
505 |
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
|
514 |
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
|
524 |
-
|
525 |
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
|
530 |
|
531 |
-
|
532 |
|
533 |
-
|
534 |
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
|
540 |
-
|
541 |
-
|
542 |
|
543 |
-
|
544 |
-
|
|
|
545 |
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
|
550 |
|
551 |
-
|
552 |
-
|
|
|
553 |
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
|
558 |
-
|
559 |
-
|
560 |
|
561 |
-
|
562 |
-
|
|
|
563 |
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
|
575 |
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
|
582 |
-
|
583 |
-
|
584 |
|
585 |
|
586 |
-
|
|
|
587 |
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
|
593 |
-
|
594 |
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
|
600 |
-
|
601 |
-
|
602 |
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
|
607 |
-
|
608 |
-
|
609 |
|
610 |
-
|
611 |
-
|
|
|
612 |
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
|
617 |
-
|
618 |
-
|
619 |
|
620 |
-
|
621 |
-
|
|
|
622 |
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
|
627 |
-
|
628 |
-
|
629 |
|
630 |
-
|
631 |
-
|
632 |
|
633 |
-
|
634 |
-
|
635 |
|
636 |
-
|
637 |
|
638 |
-
|
639 |
<script>
|
640 |
window.location = '<?php echo $redirect_url?>';
|
641 |
</script>
|
642 |
-
|
643 |
|
644 |
-
|
645 |
-
|
646 |
-
/*
|
647 |
-
* php composer.phar remove nao-pon/flysystem-google-drive
|
648 |
-
*
|
649 |
-
*/
|
650 |
-
public function get_gdrive_filesystem() {
|
651 |
|
652 |
-
|
653 |
-
|
654 |
-
|
|
|
|
|
|
|
655 |
|
656 |
-
|
|
|
|
|
657 |
|
658 |
-
|
659 |
|
660 |
-
|
661 |
-
$error_msg = "Could not initialize the Google Drive Class, please check that the xcloner-google-drive plugin is enabled...";
|
662 |
-
$this->logger->error( $error_msg );
|
663 |
-
throw new Exception( $error_msg );
|
664 |
-
}
|
665 |
|
666 |
-
|
|
|
|
|
|
|
|
|
667 |
|
668 |
-
|
669 |
|
670 |
-
|
671 |
-
$this->logger->info(sprintf("Doing a Google Drive emptyTrash call"), array(""));
|
672 |
-
$service->files->emptyTrash();
|
673 |
-
}*/
|
674 |
|
675 |
-
|
676 |
-
|
|
|
|
|
677 |
|
678 |
-
|
|
|
679 |
|
680 |
-
|
681 |
|
682 |
-
|
683 |
-
$folderID = str_replace( "id=", "", $tmp['query'] );
|
684 |
-
}
|
685 |
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
'pageSize' => 1,
|
690 |
-
'q' => $query
|
691 |
-
] );
|
692 |
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
701 |
|
702 |
-
|
703 |
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
|
714 |
|
715 |
-
|
716 |
-
|
717 |
|
718 |
-
|
719 |
-
|
|
|
720 |
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
|
734 |
-
|
735 |
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
|
740 |
-
|
741 |
-
|
742 |
|
743 |
-
|
744 |
-
|
|
|
745 |
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
|
758 |
-
|
759 |
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
|
764 |
-
|
765 |
-
|
766 |
|
767 |
-
|
768 |
-
|
769 |
-
|
|
|
770 |
|
771 |
-
|
772 |
-
|
773 |
|
774 |
-
|
775 |
-
|
776 |
-
|
|
|
777 |
|
778 |
}
|
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 |
|
198 |
}
|
199 |
}
|
200 |
|
201 |
+
}
|
202 |
|
203 |
/**
|
204 |
* Encrypts and Decrypt a string based on openssl lib
|
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);
|
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)) {
|
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"),
|
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"));
|
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"));
|
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"));
|
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"));
|
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"));
|
639 |
+
$client->setClientSecret(get_option("xcloner_gdrive_client_secret"));
|
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();
|
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"));
|
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"));
|
721 |
|
722 |
+
$folderID = get_option("xcloner_gdrive_target_folder");
|
723 |
|
724 |
+
$tmp = parse_url($folderID);
|
|
|
|
|
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);
|
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 |
}
|
includes/class-xcloner-requirements.php
CHANGED
@@ -8,7 +8,7 @@ class Xcloner_Requirements {
|
|
8 |
private $xcloner_settings;
|
9 |
private $xcloner_container;
|
10 |
|
11 |
-
public function __construct(
|
12 |
$this->xcloner_container = $xcloner_container;
|
13 |
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
14 |
}
|
@@ -18,37 +18,37 @@ class Xcloner_Requirements {
|
|
18 |
}
|
19 |
|
20 |
public function check_backup_ready_status() {
|
21 |
-
if (
|
22 |
return false;
|
23 |
}
|
24 |
|
25 |
-
if (
|
26 |
return false;
|
27 |
}
|
28 |
|
29 |
-
if (
|
30 |
return false;
|
31 |
}
|
32 |
|
33 |
-
if (
|
34 |
return false;
|
35 |
}
|
36 |
|
37 |
-
if (
|
38 |
return false;
|
39 |
}
|
40 |
|
41 |
return true;
|
42 |
}
|
43 |
|
44 |
-
public function get_constant(
|
45 |
return $this->$var;
|
46 |
}
|
47 |
|
48 |
-
public function check_min_php_version(
|
49 |
|
50 |
-
if (
|
51 |
-
if (
|
52 |
return false;
|
53 |
} else {
|
54 |
return true;
|
@@ -58,7 +58,7 @@ class Xcloner_Requirements {
|
|
58 |
return phpversion();
|
59 |
}
|
60 |
|
61 |
-
public function check_safe_mode(
|
62 |
/*no longer needed for PHP 7*/
|
63 |
$safe_mode = "Off";
|
64 |
|
@@ -77,68 +77,68 @@ class Xcloner_Requirements {
|
|
77 |
return $safe_mode;
|
78 |
}
|
79 |
|
80 |
-
public function check_xcloner_start_path(
|
81 |
$path = $this->xcloner_settings->get_xcloner_start_path();
|
82 |
|
83 |
-
if (
|
84 |
-
if (
|
85 |
return false;
|
86 |
}
|
87 |
|
88 |
-
return is_readable(
|
89 |
}
|
90 |
|
91 |
return $path;
|
92 |
}
|
93 |
|
94 |
-
public function check_xcloner_tmp_path(
|
95 |
$path = $this->xcloner_settings->get_xcloner_tmp_path();
|
96 |
|
97 |
-
if (
|
98 |
-
if (
|
99 |
return false;
|
100 |
}
|
101 |
|
102 |
-
if (
|
103 |
-
@chmod(
|
104 |
}
|
105 |
|
106 |
-
return is_writeable(
|
107 |
}
|
108 |
|
109 |
return $path;
|
110 |
}
|
111 |
|
112 |
-
public function check_xcloner_store_path(
|
113 |
$path = $this->xcloner_settings->get_xcloner_store_path();
|
114 |
|
115 |
-
if (
|
116 |
-
if (
|
117 |
return false;
|
118 |
}
|
119 |
|
120 |
-
if (
|
121 |
-
@chmod(
|
122 |
}
|
123 |
|
124 |
-
return is_writeable(
|
125 |
}
|
126 |
|
127 |
return $path;
|
128 |
}
|
129 |
|
130 |
public function get_max_execution_time() {
|
131 |
-
return ini_get(
|
132 |
}
|
133 |
|
134 |
public function get_memory_limit() {
|
135 |
-
return ini_get(
|
136 |
}
|
137 |
|
138 |
public function get_open_basedir() {
|
139 |
-
$open_basedir = ini_get(
|
140 |
|
141 |
-
if (
|
142 |
$open_basedir = "none";
|
143 |
}
|
144 |
|
@@ -146,21 +146,21 @@ class Xcloner_Requirements {
|
|
146 |
}
|
147 |
|
148 |
public function get_free_disk_space() {
|
149 |
-
return $this->file_format_size(
|
150 |
}
|
151 |
|
152 |
-
public function file_format_size(
|
153 |
-
$unit_list = array(
|
154 |
|
155 |
-
if (
|
156 |
-
return $bytes
|
157 |
}
|
158 |
|
159 |
-
$unit_count = count(
|
160 |
-
for (
|
161 |
$power = $i * 10;
|
162 |
-
if (
|
163 |
-
return round(
|
164 |
}
|
165 |
}
|
166 |
}
|
8 |
private $xcloner_settings;
|
9 |
private $xcloner_container;
|
10 |
|
11 |
+
public function __construct(Xcloner $xcloner_container) {
|
12 |
$this->xcloner_container = $xcloner_container;
|
13 |
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
14 |
}
|
18 |
}
|
19 |
|
20 |
public function check_backup_ready_status() {
|
21 |
+
if (!$this->check_min_php_version(1)) {
|
22 |
return false;
|
23 |
}
|
24 |
|
25 |
+
if (!$this->check_safe_mode(1)) {
|
26 |
return false;
|
27 |
}
|
28 |
|
29 |
+
if (!$this->check_xcloner_start_path(1)) {
|
30 |
return false;
|
31 |
}
|
32 |
|
33 |
+
if (!$this->check_xcloner_store_path(1)) {
|
34 |
return false;
|
35 |
}
|
36 |
|
37 |
+
if (!$this->check_xcloner_tmp_path(1)) {
|
38 |
return false;
|
39 |
}
|
40 |
|
41 |
return true;
|
42 |
}
|
43 |
|
44 |
+
public function get_constant($var) {
|
45 |
return $this->$var;
|
46 |
}
|
47 |
|
48 |
+
public function check_min_php_version($return_bool = 0) {
|
49 |
|
50 |
+
if ($return_bool == 1) {
|
51 |
+
if (version_compare(phpversion(), $this->min_php_version, '<')) {
|
52 |
return false;
|
53 |
} else {
|
54 |
return true;
|
58 |
return phpversion();
|
59 |
}
|
60 |
|
61 |
+
public function check_safe_mode($return_bool = 0) {
|
62 |
/*no longer needed for PHP 7*/
|
63 |
$safe_mode = "Off";
|
64 |
|
77 |
return $safe_mode;
|
78 |
}
|
79 |
|
80 |
+
public function check_xcloner_start_path($return_bool = 0) {
|
81 |
$path = $this->xcloner_settings->get_xcloner_start_path();
|
82 |
|
83 |
+
if ($return_bool) {
|
84 |
+
if (!file_exists($path)) {
|
85 |
return false;
|
86 |
}
|
87 |
|
88 |
+
return is_readable($path);
|
89 |
}
|
90 |
|
91 |
return $path;
|
92 |
}
|
93 |
|
94 |
+
public function check_xcloner_tmp_path($return_bool = 0) {
|
95 |
$path = $this->xcloner_settings->get_xcloner_tmp_path();
|
96 |
|
97 |
+
if ($return_bool) {
|
98 |
+
if (!file_exists($path)) {
|
99 |
return false;
|
100 |
}
|
101 |
|
102 |
+
if (!is_writeable($path)) {
|
103 |
+
@chmod($path, 0777);
|
104 |
}
|
105 |
|
106 |
+
return is_writeable($path);
|
107 |
}
|
108 |
|
109 |
return $path;
|
110 |
}
|
111 |
|
112 |
+
public function check_xcloner_store_path($return_bool = 0) {
|
113 |
$path = $this->xcloner_settings->get_xcloner_store_path();
|
114 |
|
115 |
+
if ($return_bool) {
|
116 |
+
if (!file_exists($path)) {
|
117 |
return false;
|
118 |
}
|
119 |
|
120 |
+
if (!is_writeable($path)) {
|
121 |
+
@chmod($path, 0777);
|
122 |
}
|
123 |
|
124 |
+
return is_writeable($path);
|
125 |
}
|
126 |
|
127 |
return $path;
|
128 |
}
|
129 |
|
130 |
public function get_max_execution_time() {
|
131 |
+
return ini_get('max_execution_time');
|
132 |
}
|
133 |
|
134 |
public function get_memory_limit() {
|
135 |
+
return ini_get('memory_limit');
|
136 |
}
|
137 |
|
138 |
public function get_open_basedir() {
|
139 |
+
$open_basedir = ini_get('open_basedir');
|
140 |
|
141 |
+
if (!$open_basedir) {
|
142 |
$open_basedir = "none";
|
143 |
}
|
144 |
|
146 |
}
|
147 |
|
148 |
public function get_free_disk_space() {
|
149 |
+
return $this->file_format_size(disk_free_space($this->xcloner_settings->get_xcloner_store_path()));
|
150 |
}
|
151 |
|
152 |
+
public function file_format_size($bytes, $decimals = 2) {
|
153 |
+
$unit_list = array('B', 'KB', 'MB', 'GB', 'PB');
|
154 |
|
155 |
+
if ($bytes == 0) {
|
156 |
+
return $bytes.' '.$unit_list[0];
|
157 |
}
|
158 |
|
159 |
+
$unit_count = count($unit_list);
|
160 |
+
for ($i = $unit_count - 1; $i >= 0; $i--) {
|
161 |
$power = $i * 10;
|
162 |
+
if (($bytes >> $power) >= 1) {
|
163 |
+
return round($bytes / (1 << $power), $decimals).' '.$unit_list[$i];
|
164 |
}
|
165 |
}
|
166 |
}
|
includes/class-xcloner-sanitization.php
CHANGED
@@ -7,29 +7,29 @@ class Xcloner_Sanitization {
|
|
7 |
public function __construct() {
|
8 |
}
|
9 |
|
10 |
-
public function sanitize_input_as_int(
|
11 |
-
return filter_var(
|
12 |
}
|
13 |
|
14 |
-
public function sanitize_input_as_float(
|
15 |
-
return filter_var(
|
16 |
}
|
17 |
|
18 |
-
public function sanitize_input_as_string(
|
19 |
-
return filter_var(
|
20 |
}
|
21 |
|
22 |
-
public function sanitize_input_as_absolute_path(
|
23 |
-
$path = filter_var(
|
24 |
|
25 |
try {
|
26 |
-
$option = Util::normalizePath(
|
27 |
-
}
|
28 |
-
add_settings_error(
|
29 |
}
|
30 |
|
31 |
-
if (
|
32 |
-
add_settings_error(
|
33 |
|
34 |
return false;
|
35 |
}
|
@@ -37,23 +37,23 @@ class Xcloner_Sanitization {
|
|
37 |
return $path;
|
38 |
}
|
39 |
|
40 |
-
public function sanitize_input_as_path(
|
41 |
-
return filter_var(
|
42 |
}
|
43 |
|
44 |
-
public function sanitize_input_as_relative_path(
|
45 |
-
$option = filter_var(
|
46 |
-
$option = str_replace(
|
47 |
|
48 |
return $option;
|
49 |
}
|
50 |
|
51 |
-
public function sanitize_input_as_email(
|
52 |
-
return filter_var(
|
53 |
}
|
54 |
|
55 |
-
public function sanitize_input_as_raw(
|
56 |
-
return filter_var(
|
57 |
}
|
58 |
|
59 |
}
|
7 |
public function __construct() {
|
8 |
}
|
9 |
|
10 |
+
public function sanitize_input_as_int($option) {
|
11 |
+
return filter_var($option, FILTER_SANITIZE_NUMBER_INT);
|
12 |
}
|
13 |
|
14 |
+
public function sanitize_input_as_float($option) {
|
15 |
+
return filter_var($option, FILTER_VALIDATE_FLOAT);
|
16 |
}
|
17 |
|
18 |
+
public function sanitize_input_as_string($option) {
|
19 |
+
return filter_var($option, FILTER_SANITIZE_STRING);
|
20 |
}
|
21 |
|
22 |
+
public function sanitize_input_as_absolute_path($option) {
|
23 |
+
$path = filter_var($option, FILTER_SANITIZE_URL);
|
24 |
|
25 |
try {
|
26 |
+
$option = Util::normalizePath($path);
|
27 |
+
}catch (Exception $e) {
|
28 |
+
add_settings_error('xcloner_error_message', '', __($e->getMessage()), 'error');
|
29 |
}
|
30 |
|
31 |
+
if ($path and !is_dir($path)) {
|
32 |
+
add_settings_error('xcloner_error_message', '', __(sprintf('Invalid Server Path %s', $option)), 'error');
|
33 |
|
34 |
return false;
|
35 |
}
|
37 |
return $path;
|
38 |
}
|
39 |
|
40 |
+
public function sanitize_input_as_path($option) {
|
41 |
+
return filter_var($option, FILTER_SANITIZE_URL);
|
42 |
}
|
43 |
|
44 |
+
public function sanitize_input_as_relative_path($option) {
|
45 |
+
$option = filter_var($option, FILTER_SANITIZE_URL);
|
46 |
+
$option = str_replace("..", "", $option);
|
47 |
|
48 |
return $option;
|
49 |
}
|
50 |
|
51 |
+
public function sanitize_input_as_email($option) {
|
52 |
+
return filter_var($option, FILTER_SANITIZE_EMAIL);
|
53 |
}
|
54 |
|
55 |
+
public function sanitize_input_as_raw($option) {
|
56 |
+
return filter_var($option, FILTER_UNSAFE_RAW);
|
57 |
}
|
58 |
|
59 |
}
|
includes/class-xcloner-scheduler.php
CHANGED
@@ -11,42 +11,44 @@ class Xcloner_Scheduler {
|
|
11 |
private $xcloner_settings;
|
12 |
private $logger;
|
13 |
private $xcloner_file_system;
|
|
|
|
|
14 |
|
15 |
-
private $allowed_schedules = array(
|
16 |
|
17 |
/*public function __call($method, $args) {
|
18 |
echo "$method is not defined";
|
19 |
}*/
|
20 |
|
21 |
-
public function __construct(
|
22 |
global $wpdb;
|
23 |
|
24 |
$this->db = $wpdb;
|
25 |
$wpdb->show_errors = false;
|
26 |
|
27 |
$this->xcloner_container = $xcloner_container;
|
28 |
-
$this->xcloner_settings = $xcloner_container->get_xcloner_settings();
|
29 |
|
30 |
-
$this->scheduler_table = $this->db->prefix
|
31 |
}
|
32 |
|
33 |
private function get_xcloner_container() {
|
34 |
return $this->xcloner_container;
|
35 |
}
|
36 |
|
37 |
-
private function set_xcloner_container(
|
38 |
$this->xcloner_container = $container;
|
39 |
}
|
40 |
|
41 |
-
public function get_scheduler_list(
|
42 |
-
$list = $this->db->get_results(
|
43 |
|
44 |
-
if (
|
45 |
$new_list = array();
|
46 |
|
47 |
-
foreach (
|
48 |
-
if (
|
49 |
-
$res->next_run_time = wp_next_scheduled(
|
50 |
$new_list[] = $res;
|
51 |
}
|
52 |
}
|
@@ -56,42 +58,41 @@ class Xcloner_Scheduler {
|
|
56 |
return $list;
|
57 |
}
|
58 |
|
59 |
-
public function get_next_run_schedule(
|
60 |
-
$list = $this->get_scheduler_list(
|
61 |
|
62 |
return $list;
|
63 |
}
|
64 |
|
65 |
-
public function get_schedule_by_id_object(
|
66 |
-
$data = $this->db->get_row(
|
67 |
|
68 |
return $data;
|
69 |
}
|
70 |
|
71 |
-
public function get_schedule_by_id(
|
72 |
-
$data = $this->db->get_row(
|
73 |
|
74 |
-
if (
|
75 |
return false;
|
76 |
}
|
77 |
|
78 |
-
$params = json_decode(
|
79 |
|
80 |
//print_r($params);
|
81 |
$data['params'] = "";
|
82 |
$data['backup_params'] = $params->backup_params;
|
83 |
-
$data['table_params'] = json_encode(
|
84 |
-
$data['excluded_files'] = json_encode(
|
85 |
-
|
86 |
|
87 |
return $data;
|
88 |
}
|
89 |
|
90 |
-
public function delete_schedule_by_id(
|
91 |
-
$hook = 'xcloner_scheduler_'
|
92 |
-
wp_clear_scheduled_hook(
|
93 |
|
94 |
-
$data = $this->db->delete(
|
95 |
|
96 |
return $data;
|
97 |
}
|
@@ -99,68 +100,74 @@ class Xcloner_Scheduler {
|
|
99 |
public function deactivate_wp_cron_hooks() {
|
100 |
$list = $this->get_scheduler_list();
|
101 |
|
102 |
-
foreach (
|
103 |
-
$hook = 'xcloner_scheduler_'
|
104 |
|
105 |
-
$timestamp = wp_next_scheduled(
|
106 |
-
|
|
|
107 |
}
|
108 |
}
|
109 |
|
110 |
public function update_wp_cron_hooks() {
|
111 |
$list = $this->get_scheduler_list();
|
112 |
|
113 |
-
foreach (
|
114 |
-
$hook = 'xcloner_scheduler_'
|
115 |
|
116 |
//adding the xcloner_scheduler hook with xcloner_scheduler_callback callback
|
117 |
-
add_action(
|
118 |
|
119 |
-
if (
|
120 |
|
121 |
-
if (
|
122 |
-
wp_schedule_single_event(
|
123 |
} else {
|
124 |
-
wp_schedule_event(
|
125 |
}
|
126 |
|
127 |
-
} elseif (
|
128 |
-
$timestamp = wp_next_scheduled(
|
129 |
-
|
|
|
130 |
}
|
131 |
}
|
132 |
|
133 |
}
|
134 |
|
135 |
-
public function update_cron_hook(
|
136 |
-
$schedule = $this->get_schedule_by_id_object(
|
137 |
-
$hook = 'xcloner_scheduler_'
|
138 |
|
139 |
-
$timestamp = wp_next_scheduled(
|
140 |
-
|
|
|
141 |
|
142 |
-
if (
|
143 |
|
144 |
-
if (
|
145 |
-
wp_schedule_single_event(
|
146 |
} else {
|
147 |
-
wp_schedule_event(
|
148 |
}
|
149 |
|
150 |
}
|
151 |
}
|
152 |
|
153 |
-
public function disable_single_cron(
|
154 |
-
$
|
155 |
-
$
|
156 |
-
|
|
|
|
|
|
|
157 |
|
158 |
$schedule['status'] = 0;
|
159 |
|
160 |
$update = $this->db->update(
|
161 |
$this->scheduler_table,
|
162 |
$schedule,
|
163 |
-
array(
|
164 |
array(
|
165 |
'%s',
|
166 |
'%s'
|
@@ -170,13 +177,15 @@ class Xcloner_Scheduler {
|
|
170 |
return $update;
|
171 |
}
|
172 |
|
173 |
-
public function update_hash(
|
|
|
|
|
174 |
$schedule['hash'] = $hash;
|
175 |
|
176 |
$update = $this->db->update(
|
177 |
$this->scheduler_table,
|
178 |
$schedule,
|
179 |
-
array(
|
180 |
array(
|
181 |
'%s',
|
182 |
'%s'
|
@@ -186,13 +195,17 @@ class Xcloner_Scheduler {
|
|
186 |
return $update;
|
187 |
}
|
188 |
|
189 |
-
public function update_last_backup(
|
|
|
|
|
|
|
|
|
190 |
$schedule['last_backup'] = $last_backup;
|
191 |
|
192 |
$update = $this->db->update(
|
193 |
$this->scheduler_table,
|
194 |
$schedule,
|
195 |
-
array(
|
196 |
array(
|
197 |
'%s',
|
198 |
'%s'
|
@@ -202,150 +215,203 @@ class Xcloner_Scheduler {
|
|
202 |
return $update;
|
203 |
}
|
204 |
|
205 |
-
private function _xcloner_scheduler_callback(
|
206 |
-
set_time_limit(
|
|
|
207 |
|
208 |
$xcloner = new XCloner();
|
209 |
$xcloner->init();
|
210 |
-
$this->set_xcloner_container(
|
|
|
|
|
|
|
211 |
|
212 |
#$hash = $this->xcloner_settings->get_hash();
|
213 |
#$this->get_xcloner_container()->get_xcloner_settings()->set_hash($hash);
|
214 |
|
215 |
//$this->xcloner_settings = $this->get_xcloner_container()->get_xcloner_settings();
|
216 |
$this->xcloner_file_system = $this->get_xcloner_container()->get_xcloner_filesystem();
|
|
|
217 |
$this->xcloner_database = $this->get_xcloner_container()->get_xcloner_database();
|
218 |
$this->archive_system = $this->get_xcloner_container()->get_archive_system();
|
219 |
-
$this->logger = $this->get_xcloner_container()->get_xcloner_logger()->withName(
|
220 |
$this->xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
221 |
|
222 |
-
$this->logger->info(
|
223 |
|
224 |
-
if (
|
225 |
-
$this->xcloner_file_system->set_diff_timestamp_start(
|
226 |
}
|
227 |
|
228 |
-
if (
|
229 |
-
$this->disable_single_cron(
|
230 |
}
|
231 |
|
232 |
-
if (
|
233 |
-
$this->logger->info(
|
234 |
|
235 |
return;
|
236 |
}
|
237 |
|
238 |
//echo $this->get_xcloner_container()->get_xcloner_settings()->get_hash(); exit;
|
239 |
|
240 |
-
$this->update_hash(
|
241 |
|
242 |
-
$this->logger->info(
|
243 |
|
244 |
-
$this->xcloner_file_system->set_excluded_files(
|
245 |
|
246 |
$init = 1;
|
247 |
$continue = 1;
|
248 |
|
249 |
-
while (
|
250 |
-
$continue = $this->xcloner_file_system->start_file_recursion(
|
251 |
|
252 |
$init = 0;
|
253 |
}
|
254 |
|
255 |
-
$this->logger->info(
|
256 |
|
257 |
-
$this->logger->info(
|
258 |
|
259 |
$init = 1;
|
260 |
$return['finished'] = 0;
|
261 |
|
262 |
-
while (
|
263 |
-
$return = $this->xcloner_database->start_database_recursion(
|
264 |
$init = 0;
|
265 |
}
|
266 |
|
267 |
-
$this->logger->info(
|
268 |
|
269 |
-
$this->logger->info(
|
270 |
|
271 |
$init = 0;
|
272 |
$return['finished'] = 0;
|
273 |
$return['extra'] = array();
|
274 |
|
275 |
-
while (
|
276 |
-
$return = $this->archive_system->start_incremental_backup(
|
277 |
$init = 0;
|
278 |
}
|
279 |
-
$this->logger->info(
|
280 |
|
281 |
//getting the last backup archive file
|
282 |
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_with_extension();
|
283 |
-
if (
|
284 |
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_multipart();
|
285 |
}
|
286 |
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
-
if ( isset( $schedule['remote_storage'] ) && $schedule['remote_storage'] && array_key_exists( $schedule['remote_storage'], $this->xcloner_remote_storage->get_available_storages() ) ) {
|
290 |
$backup_file = $return['extra']['backup_parent'];
|
291 |
|
292 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
|
294 |
-
|
295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
$this->xcloner_remote_storage,
|
297 |
"upload_backup_to_storage"
|
298 |
-
), array(
|
299 |
}
|
300 |
}
|
301 |
|
302 |
-
|
|
|
303 |
try {
|
304 |
$from = "";
|
305 |
$additional['lines_total'] = $return['extra']['lines_total'];
|
306 |
-
$subject = sprintf(
|
307 |
|
308 |
-
$this->archive_system->send_notification(
|
309 |
|
310 |
-
}
|
311 |
-
$this->logger->error(
|
312 |
}
|
313 |
}
|
314 |
|
315 |
//CHECK IF WE SHOULD DELETE BACKUP AFTER REMOTE TRANSFER IS DONE
|
316 |
-
if (
|
317 |
-
$this->logger->info(
|
318 |
-
$this->xcloner_file_system->delete_backup_by_name(
|
319 |
|
320 |
}
|
321 |
|
|
|
322 |
$this->xcloner_file_system->remove_tmp_filesystem();
|
323 |
|
|
|
324 |
$this->xcloner_file_system->backup_storage_cleanup();
|
325 |
|
326 |
-
//
|
327 |
$this->xcloner_file_system->cleanup_tmp_directories();
|
328 |
}
|
329 |
|
330 |
-
public function xcloner_scheduler_callback(
|
331 |
-
if (
|
332 |
-
$schedule = $this->get_schedule_by_id(
|
333 |
}
|
334 |
|
335 |
try {
|
|
|
|
|
|
|
|
|
|
|
336 |
|
337 |
-
|
338 |
-
|
339 |
-
} catch ( Exception $e ) {
|
340 |
|
341 |
//send email to site admin if email notification is not set in the scheduler
|
342 |
-
if (
|
343 |
-
$schedule['backup_params']->email_notification = get_option(
|
344 |
}
|
345 |
|
346 |
-
if (
|
347 |
$from = "";
|
348 |
-
$this->archive_system->send_notification(
|
349 |
}
|
350 |
|
351 |
}
|
@@ -356,14 +422,14 @@ class Xcloner_Scheduler {
|
|
356 |
$schedules = wp_get_schedules();
|
357 |
$new_schedules = array();
|
358 |
|
359 |
-
foreach (
|
360 |
-
if (
|
361 |
-
$new_schedules[
|
362 |
-
$intervals[
|
363 |
}
|
364 |
}
|
365 |
|
366 |
-
array_multisort(
|
367 |
|
368 |
return $new_schedules;
|
369 |
}
|
11 |
private $xcloner_settings;
|
12 |
private $logger;
|
13 |
private $xcloner_file_system;
|
14 |
+
private $xcloner_encryption;
|
15 |
+
private $xcloner_container;
|
16 |
|
17 |
+
private $allowed_schedules = array("hourly", "twicedaily", "daily", "weekly", "monthly");
|
18 |
|
19 |
/*public function __call($method, $args) {
|
20 |
echo "$method is not defined";
|
21 |
}*/
|
22 |
|
23 |
+
public function __construct(Xcloner $xcloner_container) {
|
24 |
global $wpdb;
|
25 |
|
26 |
$this->db = $wpdb;
|
27 |
$wpdb->show_errors = false;
|
28 |
|
29 |
$this->xcloner_container = $xcloner_container;
|
30 |
+
$this->xcloner_settings = $this->xcloner_container->get_xcloner_settings();
|
31 |
|
32 |
+
$this->scheduler_table = $this->db->prefix.$this->scheduler_table;
|
33 |
}
|
34 |
|
35 |
private function get_xcloner_container() {
|
36 |
return $this->xcloner_container;
|
37 |
}
|
38 |
|
39 |
+
private function set_xcloner_container(Xcloner $container) {
|
40 |
$this->xcloner_container = $container;
|
41 |
}
|
42 |
|
43 |
+
public function get_scheduler_list($return_only_enabled = 0) {
|
44 |
+
$list = $this->db->get_results("SELECT * FROM ".$this->scheduler_table);
|
45 |
|
46 |
+
if ($return_only_enabled) {
|
47 |
$new_list = array();
|
48 |
|
49 |
+
foreach ($list as $res) {
|
50 |
+
if ($res->status) {
|
51 |
+
$res->next_run_time = wp_next_scheduled('xcloner_scheduler_'.$res->id, array($res->id)) + (get_option('gmt_offset') * HOUR_IN_SECONDS);
|
52 |
$new_list[] = $res;
|
53 |
}
|
54 |
}
|
58 |
return $list;
|
59 |
}
|
60 |
|
61 |
+
public function get_next_run_schedule( ) {
|
62 |
+
$list = $this->get_scheduler_list($return_only_enabled = 1);
|
63 |
|
64 |
return $list;
|
65 |
}
|
66 |
|
67 |
+
public function get_schedule_by_id_object($id) {
|
68 |
+
$data = $this->db->get_row("SELECT * FROM ".$this->scheduler_table." WHERE id=".$id);
|
69 |
|
70 |
return $data;
|
71 |
}
|
72 |
|
73 |
+
public function get_schedule_by_id($id) {
|
74 |
+
$data = $this->db->get_row("SELECT * FROM ".$this->scheduler_table." WHERE id=".$id, ARRAY_A);
|
75 |
|
76 |
+
if (!$data) {
|
77 |
return false;
|
78 |
}
|
79 |
|
80 |
+
$params = json_decode($data['params']);
|
81 |
|
82 |
//print_r($params);
|
83 |
$data['params'] = "";
|
84 |
$data['backup_params'] = $params->backup_params;
|
85 |
+
$data['table_params'] = json_encode($params->database);
|
86 |
+
$data['excluded_files'] = json_encode($params->excluded_files);
|
|
|
87 |
|
88 |
return $data;
|
89 |
}
|
90 |
|
91 |
+
public function delete_schedule_by_id($id) {
|
92 |
+
$hook = 'xcloner_scheduler_'.$id;
|
93 |
+
wp_clear_scheduled_hook($hook, array($id));
|
94 |
|
95 |
+
$data = $this->db->delete($this->scheduler_table, array('id' => $id));
|
96 |
|
97 |
return $data;
|
98 |
}
|
100 |
public function deactivate_wp_cron_hooks() {
|
101 |
$list = $this->get_scheduler_list();
|
102 |
|
103 |
+
foreach ($list as $schedule) {
|
104 |
+
$hook = 'xcloner_scheduler_'.$schedule->id;
|
105 |
|
106 |
+
if ($timestamp = wp_next_scheduled($hook, array($schedule->id))) {
|
107 |
+
wp_unschedule_event($timestamp, $hook, array($schedule->id));
|
108 |
+
}
|
109 |
}
|
110 |
}
|
111 |
|
112 |
public function update_wp_cron_hooks() {
|
113 |
$list = $this->get_scheduler_list();
|
114 |
|
115 |
+
foreach ($list as $schedule) {
|
116 |
+
$hook = 'xcloner_scheduler_'.$schedule->id;
|
117 |
|
118 |
//adding the xcloner_scheduler hook with xcloner_scheduler_callback callback
|
119 |
+
add_action($hook, array($this, 'xcloner_scheduler_callback'), 10, 1);
|
120 |
|
121 |
+
if (!wp_next_scheduled($hook, array($schedule->id)) and $schedule->status) {
|
122 |
|
123 |
+
if ($schedule->recurrence == "single") {
|
124 |
+
wp_schedule_single_event(strtotime($schedule->start_at), $hook, array($schedule->id));
|
125 |
} else {
|
126 |
+
wp_schedule_event(strtotime($schedule->start_at), $schedule->recurrence, $hook, array($schedule->id));
|
127 |
}
|
128 |
|
129 |
+
} elseif (!$schedule->status) {
|
130 |
+
if ($timestamp = wp_next_scheduled($hook, array($schedule->id))) {
|
131 |
+
wp_unschedule_event($timestamp, $hook, array($schedule->id));
|
132 |
+
}
|
133 |
}
|
134 |
}
|
135 |
|
136 |
}
|
137 |
|
138 |
+
public function update_cron_hook($id) {
|
139 |
+
$schedule = $this->get_schedule_by_id_object($id);
|
140 |
+
$hook = 'xcloner_scheduler_'.$schedule->id;
|
141 |
|
142 |
+
if ($timestamp = wp_next_scheduled($hook, array($schedule->id))) {
|
143 |
+
wp_unschedule_event($timestamp, $hook, array($schedule->id));
|
144 |
+
}
|
145 |
|
146 |
+
if ($schedule->status) {
|
147 |
|
148 |
+
if ($schedule->recurrence == "single") {
|
149 |
+
wp_schedule_single_event(strtotime($schedule->start_at), $hook, array($schedule->id));
|
150 |
} else {
|
151 |
+
wp_schedule_event(strtotime($schedule->start_at), $schedule->recurrence, $hook, array($schedule->id));
|
152 |
}
|
153 |
|
154 |
}
|
155 |
}
|
156 |
|
157 |
+
public function disable_single_cron($schedule_id) {
|
158 |
+
$schedule = array();
|
159 |
+
$hook = 'xcloner_scheduler_'.$schedule_id;
|
160 |
+
|
161 |
+
if ($timestamp = wp_next_scheduled($hook, array($schedule_id))) {
|
162 |
+
wp_unschedule_event($timestamp, $hook, array($schedule_id));
|
163 |
+
}
|
164 |
|
165 |
$schedule['status'] = 0;
|
166 |
|
167 |
$update = $this->db->update(
|
168 |
$this->scheduler_table,
|
169 |
$schedule,
|
170 |
+
array('id' => $schedule_id),
|
171 |
array(
|
172 |
'%s',
|
173 |
'%s'
|
177 |
return $update;
|
178 |
}
|
179 |
|
180 |
+
public function update_hash($schedule_id, $hash) {
|
181 |
+
$schedule = array();
|
182 |
+
|
183 |
$schedule['hash'] = $hash;
|
184 |
|
185 |
$update = $this->db->update(
|
186 |
$this->scheduler_table,
|
187 |
$schedule,
|
188 |
+
array('id' => $schedule_id),
|
189 |
array(
|
190 |
'%s',
|
191 |
'%s'
|
195 |
return $update;
|
196 |
}
|
197 |
|
198 |
+
public function update_last_backup($schedule_id, $last_backup) {
|
199 |
+
$schedule = array();
|
200 |
+
|
201 |
+
$this->logger->info(sprintf('Updating last backup %s for schedule id #%s', $last_backup, $schedule_id));
|
202 |
+
|
203 |
$schedule['last_backup'] = $last_backup;
|
204 |
|
205 |
$update = $this->db->update(
|
206 |
$this->scheduler_table,
|
207 |
$schedule,
|
208 |
+
array('id' => $schedule_id),
|
209 |
array(
|
210 |
'%s',
|
211 |
'%s'
|
215 |
return $update;
|
216 |
}
|
217 |
|
218 |
+
private function _xcloner_scheduler_callback($id, $schedule) {
|
219 |
+
set_time_limit(0);
|
220 |
+
|
221 |
|
222 |
$xcloner = new XCloner();
|
223 |
$xcloner->init();
|
224 |
+
$this->set_xcloner_container($xcloner);
|
225 |
+
$return_encrypted = array();
|
226 |
+
$return = array();
|
227 |
+
$additional = array();
|
228 |
|
229 |
#$hash = $this->xcloner_settings->get_hash();
|
230 |
#$this->get_xcloner_container()->get_xcloner_settings()->set_hash($hash);
|
231 |
|
232 |
//$this->xcloner_settings = $this->get_xcloner_container()->get_xcloner_settings();
|
233 |
$this->xcloner_file_system = $this->get_xcloner_container()->get_xcloner_filesystem();
|
234 |
+
$this->xcloner_encryption = $this->get_xcloner_container()->get_xcloner_encryption();
|
235 |
$this->xcloner_database = $this->get_xcloner_container()->get_xcloner_database();
|
236 |
$this->archive_system = $this->get_xcloner_container()->get_archive_system();
|
237 |
+
$this->logger = $this->get_xcloner_container()->get_xcloner_logger()->withName("xcloner_scheduler");
|
238 |
$this->xcloner_remote_storage = $this->get_xcloner_container()->get_xcloner_remote_storage();
|
239 |
|
240 |
+
$this->logger->info(sprintf("New schedule hash is %s", $this->xcloner_settings->get_hash()));
|
241 |
|
242 |
+
if (isset($schedule['backup_params']->diff_start_date) && $schedule['backup_params']->diff_start_date) {
|
243 |
+
$this->xcloner_file_system->set_diff_timestamp_start($schedule['backup_params']->diff_start_date);
|
244 |
}
|
245 |
|
246 |
+
if ($schedule['recurrence'] == "single") {
|
247 |
+
$this->disable_single_cron($schedule['id']);
|
248 |
}
|
249 |
|
250 |
+
if (!$schedule) {
|
251 |
+
$this->logger->info(sprintf("Could not load schedule with id'%s'", $id), array("CRON"));
|
252 |
|
253 |
return;
|
254 |
}
|
255 |
|
256 |
//echo $this->get_xcloner_container()->get_xcloner_settings()->get_hash(); exit;
|
257 |
|
258 |
+
$this->update_hash($schedule['id'], $this->xcloner_settings->get_hash());
|
259 |
|
260 |
+
$this->logger->info(sprintf("Starting cron schedule '%s'", $schedule['name']), array("CRON"));
|
261 |
|
262 |
+
$this->xcloner_file_system->set_excluded_files(json_decode($schedule['excluded_files']));
|
263 |
|
264 |
$init = 1;
|
265 |
$continue = 1;
|
266 |
|
267 |
+
while ($continue) {
|
268 |
+
$continue = $this->xcloner_file_system->start_file_recursion($init);
|
269 |
|
270 |
$init = 0;
|
271 |
}
|
272 |
|
273 |
+
$this->logger->info(sprintf("File scan finished"), array("CRON"));
|
274 |
|
275 |
+
$this->logger->info(sprintf("Starting the database backup"), array("CRON"));
|
276 |
|
277 |
$init = 1;
|
278 |
$return['finished'] = 0;
|
279 |
|
280 |
+
while (!$return['finished']) {
|
281 |
+
$return = $this->xcloner_database->start_database_recursion((array)json_decode($schedule['table_params']), $return, $init);
|
282 |
$init = 0;
|
283 |
}
|
284 |
|
285 |
+
$this->logger->info(sprintf("Database backup done"), array("CRON"));
|
286 |
|
287 |
+
$this->logger->info(sprintf("Starting file archive process"), array("CRON"));
|
288 |
|
289 |
$init = 0;
|
290 |
$return['finished'] = 0;
|
291 |
$return['extra'] = array();
|
292 |
|
293 |
+
while (!$return['finished']) {
|
294 |
+
$return = $this->archive_system->start_incremental_backup((array)$schedule['backup_params'], $return['extra'], $init);
|
295 |
$init = 0;
|
296 |
}
|
297 |
+
$this->logger->info(sprintf("File archive process FINISHED."), array("CRON"));
|
298 |
|
299 |
//getting the last backup archive file
|
300 |
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_with_extension();
|
301 |
+
if ($this->xcloner_file_system->is_part($this->archive_system->get_archive_name_with_extension())) {
|
302 |
$return['extra']['backup_parent'] = $this->archive_system->get_archive_name_multipart();
|
303 |
}
|
304 |
|
305 |
+
//Updating schedule last backup archive
|
306 |
+
$this->update_last_backup($schedule['id'], $return['extra']['backup_parent']);
|
307 |
+
|
308 |
+
//Encrypting the backup archive
|
309 |
+
$return_encrypted['finished'] = 0;
|
310 |
+
$return_encrypted['start'] = 0;
|
311 |
+
$return_encrypted['iv'] = '';
|
312 |
+
$return_encrypted['target_file'] = '';
|
313 |
+
$part = 0;
|
314 |
+
$backup_parts = array();
|
315 |
+
|
316 |
+
if ($schedule['backup_params']->backup_encrypt) {
|
317 |
+
$this->logger->info(sprintf("Encrypting backup archive %s.", $return['extra']['backup_parent']), array("CRON"));
|
318 |
|
|
|
319 |
$backup_file = $return['extra']['backup_parent'];
|
320 |
|
321 |
+
if ($this->xcloner_file_system->is_multipart($return['extra']['backup_parent'])) {
|
322 |
+
$backup_parts = $this->xcloner_file_system->get_multipart_files($return['extra']['backup_parent']);
|
323 |
+
$backup_file = $backup_parts[$part];
|
324 |
+
}
|
325 |
+
|
326 |
+
while (!$return_encrypted['finished']) {
|
327 |
+
$return_encrypted = $this->xcloner_encryption->encrypt_file(
|
328 |
+
$backup_file,
|
329 |
+
"",
|
330 |
+
"",
|
331 |
+
"",
|
332 |
+
"",
|
333 |
+
true,
|
334 |
+
true
|
335 |
+
);
|
336 |
+
|
337 |
+
if ($return_encrypted['finished']) {
|
338 |
+
++$part;
|
339 |
+
|
340 |
+
if ($part < sizeof($backup_parts)) {
|
341 |
+
$return_encrypted['finished'] = 0;
|
342 |
+
$backup_file = $backup_parts[$part];
|
343 |
+
}
|
344 |
+
}
|
345 |
+
}
|
346 |
+
}
|
347 |
|
348 |
+
//Sending backup to remote storage
|
349 |
+
if (isset($schedule['remote_storage']) && $schedule['remote_storage'] && array_key_exists($schedule['remote_storage'], $this->xcloner_remote_storage->get_available_storages())) {
|
350 |
+
$backup_file = $return['extra']['backup_parent'];
|
351 |
+
|
352 |
+
$this->logger->info(sprintf("Transferring backup to remote storage %s", strtoupper($schedule['remote_storage'])), array("CRON"));
|
353 |
+
|
354 |
+
if (method_exists($this->xcloner_remote_storage, "upload_backup_to_storage")) {
|
355 |
+
call_user_func_array(array(
|
356 |
$this->xcloner_remote_storage,
|
357 |
"upload_backup_to_storage"
|
358 |
+
), array($backup_file, $schedule['remote_storage']));
|
359 |
}
|
360 |
}
|
361 |
|
362 |
+
//Sending email notification
|
363 |
+
if (isset($schedule['backup_params']->email_notification) and $to = $schedule['backup_params']->email_notification) {
|
364 |
try {
|
365 |
$from = "";
|
366 |
$additional['lines_total'] = $return['extra']['lines_total'];
|
367 |
+
$subject = sprintf(__("%s - new backup generated %s"), $schedule['name'], $return['extra']['backup_parent']);
|
368 |
|
369 |
+
$this->archive_system->send_notification($to, $from, $subject, $return['extra']['backup_parent'], $schedule, "", $additional);
|
370 |
|
371 |
+
}catch (Exception $e) {
|
372 |
+
$this->logger->error($e->getMessage());
|
373 |
}
|
374 |
}
|
375 |
|
376 |
//CHECK IF WE SHOULD DELETE BACKUP AFTER REMOTE TRANSFER IS DONE
|
377 |
+
if ($schedule['remote_storage'] && $this->xcloner_settings->get_xcloner_option('xcloner_cleanup_delete_after_remote_transfer')) {
|
378 |
+
$this->logger->info(sprintf("Deleting %s from local storage matching rule xcloner_cleanup_delete_after_remote_transfer", $return['extra']['backup_parent']));
|
379 |
+
$this->xcloner_file_system->delete_backup_by_name($return['extra']['backup_parent']);
|
380 |
|
381 |
}
|
382 |
|
383 |
+
//Removing the tmp filesystem used for backup
|
384 |
$this->xcloner_file_system->remove_tmp_filesystem();
|
385 |
|
386 |
+
//Backup Storage Cleanup
|
387 |
$this->xcloner_file_system->backup_storage_cleanup();
|
388 |
|
389 |
+
//Filesystem Cleanup
|
390 |
$this->xcloner_file_system->cleanup_tmp_directories();
|
391 |
}
|
392 |
|
393 |
+
public function xcloner_scheduler_callback($id, $schedule = "") {
|
394 |
+
if ($id) {
|
395 |
+
$schedule = $this->get_schedule_by_id($id);
|
396 |
}
|
397 |
|
398 |
try {
|
399 |
+
if (get_option('xcloner_disable_email_notification')) {
|
400 |
+
//we disable email notifications
|
401 |
+
$schedule['backup_params']->email_notification = "";
|
402 |
+
}
|
403 |
+
$this->_xcloner_scheduler_callback($id, $schedule);
|
404 |
|
405 |
+
}catch (Exception $e) {
|
|
|
|
|
406 |
|
407 |
//send email to site admin if email notification is not set in the scheduler
|
408 |
+
if (!isset($schedule['backup_params']->email_notification) || !$schedule['backup_params']->email_notification) {
|
409 |
+
$schedule['backup_params']->email_notification = get_option('admin_email');
|
410 |
}
|
411 |
|
412 |
+
if (isset($schedule['backup_params']->email_notification) && $to = $schedule['backup_params']->email_notification) {
|
413 |
$from = "";
|
414 |
+
$this->archive_system->send_notification($to, $from, $schedule['name']." - backup error", "", "", $e->getMessage());
|
415 |
}
|
416 |
|
417 |
}
|
422 |
$schedules = wp_get_schedules();
|
423 |
$new_schedules = array();
|
424 |
|
425 |
+
foreach ($schedules as $key => $row) {
|
426 |
+
if (in_array($key, $this->allowed_schedules)) {
|
427 |
+
$new_schedules[$key] = $row;
|
428 |
+
$intervals[$key] = $row['interval'];
|
429 |
}
|
430 |
}
|
431 |
|
432 |
+
array_multisort($intervals, SORT_ASC, $new_schedules);
|
433 |
|
434 |
return $new_schedules;
|
435 |
}
|
includes/class-xcloner-settings.php
CHANGED
@@ -7,10 +7,10 @@ class Xcloner_Settings {
|
|
7 |
private $xcloner_sanitization;
|
8 |
private $xcloner_container;
|
9 |
|
10 |
-
public function __construct(
|
11 |
$this->xcloner_container = $xcloner_container;
|
12 |
-
if (
|
13 |
-
$this->set_hash(
|
14 |
}
|
15 |
}
|
16 |
|
@@ -18,93 +18,125 @@ class Xcloner_Settings {
|
|
18 |
return $this->xcloner_container;
|
19 |
}
|
20 |
|
21 |
-
public function get_logger_filename(
|
22 |
-
if (
|
23 |
-
$filename = sprintf(
|
24 |
} else {
|
25 |
-
$filename = sprintf(
|
26 |
}
|
27 |
|
28 |
return $filename;
|
29 |
}
|
30 |
|
31 |
public function get_xcloner_start_path() {
|
32 |
-
if (
|
33 |
-
$path = realpath(
|
34 |
} else {
|
35 |
-
$path = get_option(
|
36 |
}
|
37 |
|
38 |
return $path;
|
39 |
}
|
40 |
|
41 |
-
public function get_xcloner_dir_path(
|
42 |
-
$path =
|
43 |
|
44 |
return $path;
|
45 |
}
|
46 |
|
47 |
public function get_xcloner_store_path() {
|
48 |
-
if (
|
49 |
-
$path = realpath(
|
50 |
} else {
|
51 |
-
$path = get_option(
|
52 |
}
|
53 |
|
54 |
return $path;
|
55 |
}
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
public function get_xcloner_tmp_path_suffix() {
|
58 |
-
return "xcloner"
|
59 |
}
|
60 |
|
61 |
|
62 |
-
public function get_xcloner_tmp_path(
|
63 |
-
if (
|
64 |
$path = $this->get_xcloner_store_path();
|
65 |
} else {
|
66 |
|
67 |
$path = sys_get_temp_dir();
|
68 |
-
if (
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
71 |
}
|
72 |
|
73 |
-
if (
|
74 |
$path = $this->get_xcloner_store_path();
|
75 |
}
|
76 |
}
|
77 |
|
78 |
-
if (
|
79 |
-
$path = $path
|
80 |
}
|
81 |
|
82 |
return $path;
|
83 |
}
|
84 |
|
85 |
public function get_enable_mysql_backup() {
|
86 |
-
if (
|
87 |
return true;
|
88 |
}
|
89 |
|
90 |
return false;
|
91 |
}
|
92 |
|
93 |
-
public function get_backup_extension_name(
|
94 |
-
if (
|
95 |
-
if (
|
96 |
$ext = ".tgz";
|
97 |
} else {
|
98 |
$ext = ".tar";
|
99 |
}
|
100 |
}
|
101 |
|
102 |
-
return (
|
103 |
}
|
104 |
|
105 |
public function get_hash() {
|
106 |
-
if (
|
107 |
-
$this->set_hash(
|
108 |
}
|
109 |
|
110 |
//echo $this->hash;
|
@@ -112,27 +144,27 @@ class Xcloner_Settings {
|
|
112 |
}
|
113 |
|
114 |
public function generate_new_hash() {
|
115 |
-
$hash = "-"
|
116 |
|
117 |
-
$this->set_hash(
|
118 |
|
119 |
return $hash;
|
120 |
}
|
121 |
|
122 |
-
public function set_hash(
|
123 |
-
if (
|
124 |
-
$hash = "-"
|
125 |
}
|
126 |
|
127 |
-
$this->hash = substr(
|
128 |
|
129 |
return $this;
|
130 |
}
|
131 |
|
132 |
public function get_default_backup_name() {
|
133 |
-
$data = parse_url(
|
134 |
|
135 |
-
$backup_name = "backup_[domain]"
|
136 |
|
137 |
return $backup_name;
|
138 |
}
|
@@ -140,7 +172,7 @@ class Xcloner_Settings {
|
|
140 |
public function get_db_hostname() {
|
141 |
global $wpdb;
|
142 |
|
143 |
-
if (
|
144 |
$data = $wpdb->dbhost;
|
145 |
}
|
146 |
|
@@ -150,7 +182,7 @@ class Xcloner_Settings {
|
|
150 |
public function get_db_username() {
|
151 |
global $wpdb;
|
152 |
|
153 |
-
if (
|
154 |
$data = $wpdb->dbuser;
|
155 |
}
|
156 |
|
@@ -160,7 +192,7 @@ class Xcloner_Settings {
|
|
160 |
public function get_db_password() {
|
161 |
global $wpdb;
|
162 |
|
163 |
-
if (
|
164 |
$data = $wpdb->dbpassword;
|
165 |
}
|
166 |
|
@@ -170,7 +202,7 @@ class Xcloner_Settings {
|
|
170 |
public function get_db_database() {
|
171 |
global $wpdb;
|
172 |
|
173 |
-
if (
|
174 |
$data = $wpdb->dbname;
|
175 |
}
|
176 |
|
@@ -183,17 +215,20 @@ class Xcloner_Settings {
|
|
183 |
return $wpdb->prefix;
|
184 |
}
|
185 |
|
186 |
-
|
187 |
-
|
|
|
|
|
|
|
188 |
|
189 |
return $data;
|
190 |
}
|
191 |
|
192 |
-
public function get_server_unique_hash(
|
193 |
-
$hash = md5(
|
194 |
|
195 |
-
if (
|
196 |
-
$hash = substr(
|
197 |
}
|
198 |
|
199 |
return $hash;
|
@@ -204,20 +239,20 @@ class Xcloner_Settings {
|
|
204 |
$this->xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
205 |
|
206 |
//ADDING MISSING OPTIONS
|
207 |
-
if (
|
208 |
-
add_option(
|
209 |
} // end if
|
210 |
|
211 |
-
if (
|
212 |
-
add_option(
|
213 |
} // end if
|
214 |
|
215 |
-
if (
|
216 |
-
add_option(
|
217 |
} // end if
|
218 |
|
219 |
-
if (
|
220 |
-
add_option(
|
221 |
} // end if
|
222 |
|
223 |
|
@@ -225,31 +260,31 @@ class Xcloner_Settings {
|
|
225 |
//GENERAL section
|
226 |
add_settings_section(
|
227 |
'xcloner_general_settings_group',
|
228 |
-
__(
|
229 |
-
array(
|
230 |
'xcloner_settings_page'
|
231 |
);
|
232 |
//MYSQL section
|
233 |
add_settings_section(
|
234 |
'xcloner_mysql_settings_group',
|
235 |
-
__(
|
236 |
-
array(
|
237 |
'xcloner_mysql_settings_page'
|
238 |
);
|
239 |
|
240 |
//SYSTEM section
|
241 |
add_settings_section(
|
242 |
'xcloner_system_settings_group',
|
243 |
-
__(
|
244 |
-
array(
|
245 |
'xcloner_system_settings_page'
|
246 |
);
|
247 |
|
248 |
//CLEANUP section
|
249 |
add_settings_section(
|
250 |
'xcloner_cleanup_settings_group',
|
251 |
-
__(
|
252 |
-
array(
|
253 |
'xcloner_cleanup_settings_page'
|
254 |
);
|
255 |
|
@@ -257,269 +292,287 @@ class Xcloner_Settings {
|
|
257 |
//CRON section
|
258 |
add_settings_section(
|
259 |
'xcloner_cron_settings_group',
|
260 |
-
__(
|
261 |
-
array(
|
262 |
'xcloner_cron_settings_page'
|
263 |
);
|
264 |
|
265 |
|
266 |
//REGISTERING THE 'GENERAL SECTION' FIELDS
|
267 |
-
register_setting(
|
268 |
$this->xcloner_sanitization,
|
269 |
"sanitize_input_as_int"
|
270 |
-
)
|
271 |
add_settings_field(
|
272 |
'xcloner_backup_compression_level',
|
273 |
-
__(
|
274 |
-
array(
|
275 |
'xcloner_settings_page',
|
276 |
'xcloner_general_settings_group',
|
277 |
array(
|
278 |
'xcloner_backup_compression_level',
|
279 |
-
__(
|
280 |
0,
|
281 |
9
|
282 |
)
|
283 |
);
|
284 |
|
285 |
-
register_setting(
|
286 |
$this->xcloner_sanitization,
|
287 |
"sanitize_input_as_absolute_path"
|
288 |
-
)
|
289 |
add_settings_field(
|
290 |
'xcloner_start_path',
|
291 |
-
__(
|
292 |
-
array(
|
293 |
'xcloner_settings_page',
|
294 |
'xcloner_general_settings_group',
|
295 |
array(
|
296 |
'xcloner_start_path',
|
297 |
-
__(
|
298 |
$this->get_xcloner_start_path(),
|
299 |
//'disabled'
|
300 |
)
|
301 |
);
|
302 |
|
303 |
-
register_setting(
|
304 |
$this->xcloner_sanitization,
|
305 |
"sanitize_input_as_absolute_path"
|
306 |
-
)
|
307 |
add_settings_field(
|
308 |
'xcloner_store_path',
|
309 |
-
__(
|
310 |
-
array(
|
311 |
'xcloner_settings_page',
|
312 |
'xcloner_general_settings_group',
|
313 |
array(
|
314 |
'xcloner_store_path',
|
315 |
-
__(
|
316 |
$this->get_xcloner_store_path(),
|
317 |
//'disabled'
|
318 |
)
|
319 |
);
|
320 |
|
321 |
-
register_setting(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
$this->xcloner_sanitization,
|
323 |
"sanitize_input_as_int"
|
324 |
-
)
|
325 |
add_settings_field(
|
326 |
'xcloner_enable_log',
|
327 |
-
__(
|
328 |
-
array(
|
329 |
'xcloner_settings_page',
|
330 |
'xcloner_general_settings_group',
|
331 |
array(
|
332 |
'xcloner_enable_log',
|
333 |
-
sprintf(
|
334 |
)
|
335 |
);
|
336 |
|
337 |
-
register_setting(
|
338 |
$this->xcloner_sanitization,
|
339 |
"sanitize_input_as_int"
|
340 |
-
)
|
341 |
add_settings_field(
|
342 |
'xcloner_enable_pre_update_backup',
|
343 |
-
__(
|
344 |
-
array(
|
345 |
'xcloner_settings_page',
|
346 |
'xcloner_general_settings_group',
|
347 |
array(
|
348 |
'xcloner_enable_pre_update_backup',
|
349 |
-
sprintf(
|
350 |
)
|
351 |
);
|
352 |
|
353 |
-
register_setting(
|
354 |
$this->xcloner_sanitization,
|
355 |
"sanitize_input_as_raw"
|
356 |
-
)
|
357 |
add_settings_field(
|
358 |
'xcloner_regex_exclude',
|
359 |
-
__(
|
360 |
-
array(
|
361 |
'xcloner_settings_page',
|
362 |
'xcloner_general_settings_group',
|
363 |
array(
|
364 |
'xcloner_regex_exclude',
|
365 |
-
__(
|
366 |
//$this->get_xcloner_store_path(),
|
367 |
//'disabled'
|
368 |
)
|
369 |
);
|
370 |
|
371 |
//REGISTERING THE 'MYSQL SECTION' FIELDS
|
372 |
-
register_setting(
|
373 |
$this->xcloner_sanitization,
|
374 |
"sanitize_input_as_int"
|
375 |
-
)
|
376 |
add_settings_field(
|
377 |
'xcloner_enable_mysql_backup',
|
378 |
-
__(
|
379 |
-
array(
|
380 |
'xcloner_mysql_settings_page',
|
381 |
'xcloner_mysql_settings_group',
|
382 |
array(
|
383 |
'xcloner_enable_mysql_backup',
|
384 |
-
__(
|
385 |
)
|
386 |
);
|
387 |
|
388 |
-
register_setting(
|
389 |
add_settings_field(
|
390 |
'xcloner_backup_only_wp_tables',
|
391 |
-
__(
|
392 |
-
array(
|
393 |
'xcloner_mysql_settings_page',
|
394 |
'xcloner_mysql_settings_group',
|
395 |
array(
|
396 |
'xcloner_backup_only_wp_tables',
|
397 |
-
sprintf(
|
398 |
)
|
399 |
);
|
400 |
|
401 |
-
register_setting(
|
402 |
$this->xcloner_sanitization,
|
403 |
"sanitize_input_as_raw"
|
404 |
-
)
|
405 |
add_settings_field(
|
406 |
'xcloner_mysql_hostname',
|
407 |
-
__(
|
408 |
-
array(
|
409 |
'xcloner_mysql_settings_page',
|
410 |
'xcloner_mysql_settings_group',
|
411 |
array(
|
412 |
'xcloner_mysql_hostname',
|
413 |
-
__(
|
414 |
$this->get_db_hostname(),
|
415 |
'disabled'
|
416 |
)
|
417 |
);
|
418 |
|
419 |
-
register_setting(
|
420 |
$this->xcloner_sanitization,
|
421 |
"sanitize_input_as_raw"
|
422 |
-
)
|
423 |
add_settings_field(
|
424 |
'xcloner_mysql_username',
|
425 |
-
__(
|
426 |
-
array(
|
427 |
'xcloner_mysql_settings_page',
|
428 |
'xcloner_mysql_settings_group',
|
429 |
array(
|
430 |
'xcloner_mysql_username',
|
431 |
-
__(
|
432 |
$this->get_db_username(),
|
433 |
'disabled'
|
434 |
)
|
435 |
);
|
436 |
|
437 |
-
register_setting(
|
438 |
$this->xcloner_sanitization,
|
439 |
"sanitize_input_as_raw"
|
440 |
-
)
|
441 |
add_settings_field(
|
442 |
'xcloner_mysql_database',
|
443 |
-
__(
|
444 |
-
array(
|
445 |
'xcloner_mysql_settings_page',
|
446 |
'xcloner_mysql_settings_group',
|
447 |
array(
|
448 |
'xcloner_mysql_database',
|
449 |
-
__(
|
450 |
$this->get_db_database(),
|
451 |
'disabled'
|
452 |
)
|
453 |
);
|
454 |
|
455 |
//REGISTERING THE 'SYSTEM SECTION' FIELDS
|
456 |
-
register_setting(
|
457 |
$this->xcloner_sanitization,
|
458 |
"sanitize_input_as_int"
|
459 |
-
)
|
460 |
add_settings_field(
|
461 |
'xcloner_size_limit_per_request',
|
462 |
-
__(
|
463 |
-
array(
|
464 |
'xcloner_system_settings_page',
|
465 |
'xcloner_system_settings_group',
|
466 |
array(
|
467 |
'xcloner_size_limit_per_request',
|
468 |
-
__(
|
469 |
0,
|
470 |
1024
|
471 |
)
|
472 |
);
|
473 |
|
474 |
-
register_setting(
|
475 |
$this->xcloner_sanitization,
|
476 |
"sanitize_input_as_int"
|
477 |
-
)
|
478 |
add_settings_field(
|
479 |
'xcloner_files_to_process_per_request',
|
480 |
-
__(
|
481 |
-
array(
|
482 |
'xcloner_system_settings_page',
|
483 |
'xcloner_system_settings_group',
|
484 |
array(
|
485 |
'xcloner_files_to_process_per_request',
|
486 |
-
__(
|
487 |
0,
|
488 |
1000
|
489 |
)
|
490 |
);
|
491 |
|
492 |
-
register_setting(
|
493 |
$this->xcloner_sanitization,
|
494 |
"sanitize_input_as_int"
|
495 |
-
)
|
496 |
add_settings_field(
|
497 |
'xcloner_directories_to_scan_per_request',
|
498 |
-
__(
|
499 |
-
array(
|
500 |
'xcloner_system_settings_page',
|
501 |
'xcloner_system_settings_group',
|
502 |
array(
|
503 |
'xcloner_directories_to_scan_per_request',
|
504 |
-
__(
|
505 |
0,
|
506 |
1000
|
507 |
)
|
508 |
);
|
509 |
|
510 |
-
register_setting(
|
511 |
$this->xcloner_sanitization,
|
512 |
"sanitize_input_as_int"
|
513 |
-
)
|
514 |
add_settings_field(
|
515 |
'xcloner_database_records_per_request',
|
516 |
-
__(
|
517 |
-
array(
|
518 |
'xcloner_system_settings_page',
|
519 |
'xcloner_system_settings_group',
|
520 |
array(
|
521 |
'xcloner_database_records_per_request',
|
522 |
-
__(
|
523 |
0,
|
524 |
100000
|
525 |
)
|
@@ -537,127 +590,140 @@ class Xcloner_Settings {
|
|
537 |
)
|
538 |
);*/
|
539 |
|
540 |
-
register_setting(
|
541 |
$this->xcloner_sanitization,
|
542 |
"sanitize_input_as_int"
|
543 |
-
)
|
544 |
add_settings_field(
|
545 |
'xcloner_exclude_files_larger_than_mb',
|
546 |
-
__(
|
547 |
-
array(
|
548 |
'xcloner_system_settings_page',
|
549 |
'xcloner_system_settings_group',
|
550 |
array(
|
551 |
'xcloner_exclude_files_larger_than_mb',
|
552 |
-
__(
|
553 |
)
|
554 |
);
|
555 |
|
556 |
-
register_setting(
|
557 |
$this->xcloner_sanitization,
|
558 |
"sanitize_input_as_int"
|
559 |
-
)
|
560 |
add_settings_field(
|
561 |
'xcloner_split_backup_limit',
|
562 |
-
__(
|
563 |
-
array(
|
564 |
'xcloner_system_settings_page',
|
565 |
'xcloner_system_settings_group',
|
566 |
array(
|
567 |
'xcloner_split_backup_limit',
|
568 |
-
__(
|
569 |
)
|
570 |
);
|
571 |
|
572 |
-
register_setting(
|
573 |
add_settings_field(
|
574 |
'xcloner_force_tmp_path_site_root',
|
575 |
-
__(
|
576 |
-
array(
|
577 |
'xcloner_system_settings_page',
|
578 |
'xcloner_system_settings_group',
|
579 |
array(
|
580 |
'xcloner_force_tmp_path_site_root',
|
581 |
-
sprintf(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
582 |
)
|
583 |
);
|
584 |
|
585 |
//REGISTERING THE 'CLEANUP SECTION' FIELDS
|
586 |
-
register_setting(
|
587 |
$this->xcloner_sanitization,
|
588 |
"sanitize_input_as_int"
|
589 |
-
)
|
590 |
add_settings_field(
|
591 |
'xcloner_cleanup_retention_limit_days',
|
592 |
-
__(
|
593 |
-
array(
|
594 |
'xcloner_cleanup_settings_page',
|
595 |
'xcloner_cleanup_settings_group',
|
596 |
array(
|
597 |
'xcloner_cleanup_retention_limit_days',
|
598 |
-
__(
|
599 |
)
|
600 |
);
|
601 |
|
602 |
-
register_setting(
|
603 |
$this->xcloner_sanitization,
|
604 |
"sanitize_input_as_int"
|
605 |
-
)
|
606 |
add_settings_field(
|
607 |
'xcloner_cleanup_retention_limit_archives',
|
608 |
-
__(
|
609 |
-
array(
|
610 |
'xcloner_cleanup_settings_page',
|
611 |
'xcloner_cleanup_settings_group',
|
612 |
array(
|
613 |
'xcloner_cleanup_retention_limit_archives',
|
614 |
-
__(
|
615 |
)
|
616 |
);
|
617 |
|
618 |
-
register_setting(
|
619 |
$this->xcloner_sanitization,
|
620 |
"sanitize_input_as_int"
|
621 |
-
)
|
622 |
add_settings_field(
|
623 |
'xcloner_cleanup_capacity_limit',
|
624 |
-
__(
|
625 |
-
array(
|
626 |
'xcloner_cleanup_settings_page',
|
627 |
'xcloner_cleanup_settings_group',
|
628 |
array(
|
629 |
'xcloner_cleanup_capacity_limit',
|
630 |
-
__(
|
631 |
)
|
632 |
);
|
633 |
|
634 |
-
register_setting(
|
635 |
$this->xcloner_sanitization,
|
636 |
"sanitize_input_as_int"
|
637 |
-
)
|
638 |
add_settings_field(
|
639 |
'xcloner_cleanup_delete_after_remote_transfer',
|
640 |
-
__(
|
641 |
-
array(
|
642 |
'xcloner_cleanup_settings_page',
|
643 |
'xcloner_cleanup_settings_group',
|
644 |
array(
|
645 |
'xcloner_cleanup_delete_after_remote_transfer',
|
646 |
-
__(
|
647 |
)
|
648 |
);
|
649 |
|
650 |
//REGISTERING THE 'CRON SECTION' FIELDS
|
651 |
-
register_setting(
|
652 |
add_settings_field(
|
653 |
'xcloner_cron_frequency',
|
654 |
-
__(
|
655 |
-
array(
|
656 |
'xcloner_cron_settings_page',
|
657 |
'xcloner_cron_settings_group',
|
658 |
array(
|
659 |
'xcloner_cron_frequency',
|
660 |
-
__(
|
661 |
)
|
662 |
);
|
663 |
}
|
@@ -675,26 +741,26 @@ class Xcloner_Settings {
|
|
675 |
}
|
676 |
|
677 |
// text field content cb
|
678 |
-
public function do_form_text_field(
|
679 |
-
if (
|
680 |
$params[3] = 0;
|
681 |
}
|
682 |
-
if (
|
683 |
$params[2] = 0;
|
684 |
}
|
685 |
|
686 |
-
list(
|
687 |
|
688 |
-
if (
|
689 |
-
$value = get_option(
|
690 |
}
|
691 |
// output the field
|
692 |
?>
|
693 |
<div class="row">
|
694 |
<div class="input-field col s10 m10 l8">
|
695 |
-
<input class="validate" <?php echo (
|
696 |
id="<?php echo $fieldname ?>" type="text" class="validate"
|
697 |
-
value="<?php echo isset(
|
698 |
</div>
|
699 |
<div class="col s2 m2 ">
|
700 |
<a class="btn-floating tooltipped btn-small" data-position="left" data-delay="50"
|
@@ -707,26 +773,26 @@ class Xcloner_Settings {
|
|
707 |
}
|
708 |
|
709 |
// textarea field content cb
|
710 |
-
public function do_form_textarea_field(
|
711 |
-
if (
|
712 |
$params[3] = 0;
|
713 |
}
|
714 |
-
if (
|
715 |
$params[2] = 0;
|
716 |
}
|
717 |
|
718 |
-
list(
|
719 |
|
720 |
-
if (
|
721 |
-
$value = get_option(
|
722 |
}
|
723 |
// output the field
|
724 |
?>
|
725 |
<div class="row">
|
726 |
<div class="input-field col s10 m10 l8">
|
727 |
-
<textarea class="validate" <?php echo (
|
728 |
id="<?php echo $fieldname ?>" type="text" class="validate"
|
729 |
-
value=""><?php echo isset(
|
730 |
</div>
|
731 |
<div class="col s2 m2 ">
|
732 |
<a class="btn-floating tooltipped btn-small" data-position="center" data-html="true" data-delay="50"
|
@@ -735,39 +801,39 @@ class Xcloner_Settings {
|
|
735 |
<div class="col s12">
|
736 |
<ul class="xcloner_regex_exclude_limit">
|
737 |
<li>Exclude all except .php file: <span
|
738 |
-
class="regex_pattern"><?php echo htmlentities(
|
739 |
<li>Exclude all except .php and .txt: <span
|
740 |
-
class="regex_pattern"> <?php echo htmlentities(
|
741 |
</li>
|
742 |
<li>Exclude all .avi files: <span
|
743 |
-
class="regex_pattern"> <?php echo htmlentities(
|
744 |
<li>Exclude all .jpg,.gif and .png files: <span
|
745 |
-
class="regex_pattern"> <?php echo htmlentities(
|
746 |
</li>
|
747 |
<li>Exclude all .svn and .git: <span
|
748 |
-
class="regex_pattern"> <?php echo htmlentities(
|
749 |
<li>Exclude root directory /test: <span
|
750 |
-
class="regex_pattern"> <?php echo htmlentities(
|
751 |
-
class="regex_pattern"> <?php echo htmlentities(
|
752 |
<li>Exclude the wp-admin folder: <span
|
753 |
-
class="regex_pattern"> <?php echo htmlentities(
|
754 |
<li>Exclude the wp-content/uploads folder: <span
|
755 |
-
class="regex_pattern"> <?php echo htmlentities(
|
756 |
</li>
|
757 |
<li>Exclude the wp-admin, wp-includes and wp-config.php: <span
|
758 |
-
class="regex_pattern"> <?php echo htmlentities(
|
759 |
</li>
|
760 |
<li>Exclude wp-content/updraft and wp/content/uploads/wp_all_backup folder :<span
|
761 |
class="regex_pattern">\/(wp-content\/updraft|\/wp-content\/uploads\/wp_all_backup)(.*)$</span>
|
762 |
</li>
|
763 |
<li>Exclude all cache folders from wp-content/ and it's subdirectories: <span
|
764 |
-
class="regex_pattern"> <?php echo htmlentities(
|
765 |
</li>
|
766 |
<li>Exclude wp-content/cache/ folder: <span
|
767 |
-
class="regex_pattern"> <?php echo htmlentities(
|
768 |
</li>
|
769 |
<li>Exclude all error_log files: <span
|
770 |
-
class="regex_pattern"> <?php echo htmlentities(
|
771 |
</ul>
|
772 |
</div>
|
773 |
</div>
|
@@ -777,26 +843,26 @@ class Xcloner_Settings {
|
|
777 |
}
|
778 |
|
779 |
// number field content cb
|
780 |
-
public function do_form_number_field(
|
781 |
-
if (
|
782 |
$params[3] = 0;
|
783 |
}
|
784 |
-
if (
|
785 |
$params[2] = 0;
|
786 |
}
|
787 |
|
788 |
-
list(
|
789 |
|
790 |
-
if (
|
791 |
-
$value = get_option(
|
792 |
}
|
793 |
// output the field
|
794 |
?>
|
795 |
<div class="row">
|
796 |
<div class="input-field col s10 m5 l3">
|
797 |
-
<input class="validate" <?php echo (
|
798 |
id="<?php echo $fieldname ?>" type="number" class="validate"
|
799 |
-
value="<?php echo isset(
|
800 |
</div>
|
801 |
<div class="col s2 m2 ">
|
802 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50"
|
@@ -808,22 +874,22 @@ class Xcloner_Settings {
|
|
808 |
<?php
|
809 |
}
|
810 |
|
811 |
-
public function do_form_range_field(
|
812 |
-
if (
|
813 |
$params[4] = 0;
|
814 |
}
|
815 |
|
816 |
-
list(
|
817 |
-
$value = get_option(
|
818 |
?>
|
819 |
<div class="row">
|
820 |
<div class="input-field col s10 m10 l8">
|
821 |
<p class="range-field">
|
822 |
-
<input <?php echo (
|
823 |
id="<?php echo $fieldname ?>"
|
824 |
min="<?php echo $range_start ?>"
|
825 |
max="<?php echo $range_end ?>"
|
826 |
-
value="<?php echo isset(
|
827 |
</p>
|
828 |
</div>
|
829 |
<div class="col s2 m2 ">
|
@@ -835,22 +901,22 @@ class Xcloner_Settings {
|
|
835 |
}
|
836 |
|
837 |
|
838 |
-
public function do_form_switch_field(
|
839 |
-
if (
|
840 |
$params[2] = 0;
|
841 |
}
|
842 |
-
list(
|
843 |
-
$value = get_option(
|
844 |
?>
|
845 |
<div class="row">
|
846 |
<div class="input-field col s10 m5 l3">
|
847 |
<div class="switch">
|
848 |
<label>
|
849 |
Off
|
850 |
-
<input <?php echo (
|
851 |
name="<?php echo $fieldname ?>"
|
852 |
id="<?php echo $fieldname ?>"
|
853 |
-
value="1" <?php echo (
|
854 |
">
|
855 |
<span class="lever"></span>
|
856 |
On
|
7 |
private $xcloner_sanitization;
|
8 |
private $xcloner_container;
|
9 |
|
10 |
+
public function __construct(Xcloner $xcloner_container, $hash = "") {
|
11 |
$this->xcloner_container = $xcloner_container;
|
12 |
+
if (isset($hash)) {
|
13 |
+
$this->set_hash($hash);
|
14 |
}
|
15 |
}
|
16 |
|
18 |
return $this->xcloner_container;
|
19 |
}
|
20 |
|
21 |
+
public function get_logger_filename($include_hash = 0) {
|
22 |
+
if ($include_hash) {
|
23 |
+
$filename = sprintf($this->logger_file_hash, $this->get_hash());
|
24 |
} else {
|
25 |
+
$filename = sprintf($this->logger_file, $this->get_server_unique_hash(5));
|
26 |
}
|
27 |
|
28 |
return $filename;
|
29 |
}
|
30 |
|
31 |
public function get_xcloner_start_path() {
|
32 |
+
if (!get_option('xcloner_start_path') or !is_dir(/** @scrutinizer ignore-type */get_option('xcloner_start_path'))) {
|
33 |
+
$path = realpath(ABSPATH);
|
34 |
} else {
|
35 |
+
$path = get_option('xcloner_start_path');
|
36 |
}
|
37 |
|
38 |
return $path;
|
39 |
}
|
40 |
|
41 |
+
public function get_xcloner_dir_path($dir) {
|
42 |
+
$path = $this->get_xcloner_start_path().DS.$dir;
|
43 |
|
44 |
return $path;
|
45 |
}
|
46 |
|
47 |
public function get_xcloner_store_path() {
|
48 |
+
if (!get_option('xcloner_store_path') or !is_dir(/** @scrutinizer ignore-type */get_option('xcloner_store_path'))) {
|
49 |
+
$path = realpath(XCLONER_STORAGE_PATH);
|
50 |
} else {
|
51 |
+
$path = get_option('xcloner_store_path');
|
52 |
}
|
53 |
|
54 |
return $path;
|
55 |
}
|
56 |
|
57 |
+
public function get_xcloner_encryption_key() {
|
58 |
+
|
59 |
+
if (!get_option('xcloner_encryption_key'))
|
60 |
+
{
|
61 |
+
$key = $this->randomString(35);
|
62 |
+
update_option('xcloner_encryption_key', $key);
|
63 |
+
}
|
64 |
+
|
65 |
+
return get_option('xcloner_encryption_key');
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Create a random string
|
70 |
+
* @author XEWeb <>
|
71 |
+
* @param $length the length of the string to create
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
private function randomString($length = 6) {
|
75 |
+
$str = "";
|
76 |
+
$characters = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
|
77 |
+
$max = count($characters) - 1;
|
78 |
+
for ($i = 0; $i < $length; $i++) {
|
79 |
+
$rand = mt_rand(0, $max);
|
80 |
+
$str .= $characters[$rand];
|
81 |
+
}
|
82 |
+
return $str;
|
83 |
+
}
|
84 |
+
|
85 |
public function get_xcloner_tmp_path_suffix() {
|
86 |
+
return "xcloner".$this->get_hash();
|
87 |
}
|
88 |
|
89 |
|
90 |
+
public function get_xcloner_tmp_path($suffix = true) {
|
91 |
+
if (get_option('xcloner_force_tmp_path_site_root')) {
|
92 |
$path = $this->get_xcloner_store_path();
|
93 |
} else {
|
94 |
|
95 |
$path = sys_get_temp_dir();
|
96 |
+
if (!is_dir($path)) {
|
97 |
+
try {
|
98 |
+
mkdir($path);
|
99 |
+
chmod($path, 0777);
|
100 |
+
}catch(Exception $e){
|
101 |
+
//silent catch
|
102 |
+
}
|
103 |
}
|
104 |
|
105 |
+
if (!is_dir($path) or !is_writeable($path)) {
|
106 |
$path = $this->get_xcloner_store_path();
|
107 |
}
|
108 |
}
|
109 |
|
110 |
+
if ($suffix) {
|
111 |
+
$path = $path.DS.".".$this->get_xcloner_tmp_path_suffix();
|
112 |
}
|
113 |
|
114 |
return $path;
|
115 |
}
|
116 |
|
117 |
public function get_enable_mysql_backup() {
|
118 |
+
if (get_option('xcloner_enable_mysql_backup')) {
|
119 |
return true;
|
120 |
}
|
121 |
|
122 |
return false;
|
123 |
}
|
124 |
|
125 |
+
public function get_backup_extension_name($ext = "") {
|
126 |
+
if (!$ext) {
|
127 |
+
if (get_option('xcloner_backup_compression_level')) {
|
128 |
$ext = ".tgz";
|
129 |
} else {
|
130 |
$ext = ".tar";
|
131 |
}
|
132 |
}
|
133 |
|
134 |
+
return ($this->get_hash()).$ext;
|
135 |
}
|
136 |
|
137 |
public function get_hash() {
|
138 |
+
if (!$this->hash) {
|
139 |
+
$this->set_hash("-".$this->get_server_unique_hash(5));
|
140 |
}
|
141 |
|
142 |
//echo $this->hash;
|
144 |
}
|
145 |
|
146 |
public function generate_new_hash() {
|
147 |
+
$hash = "-".md5(rand());
|
148 |
|
149 |
+
$this->set_hash(substr($hash, 0, 6));
|
150 |
|
151 |
return $hash;
|
152 |
}
|
153 |
|
154 |
+
public function set_hash($hash = "") {
|
155 |
+
if (substr($hash, 0, 1) != "-" and strlen($hash)) {
|
156 |
+
$hash = "-".$hash;
|
157 |
}
|
158 |
|
159 |
+
$this->hash = substr($hash, 0, 6);
|
160 |
|
161 |
return $this;
|
162 |
}
|
163 |
|
164 |
public function get_default_backup_name() {
|
165 |
+
$data = parse_url(get_site_url());
|
166 |
|
167 |
+
$backup_name = "backup_[domain]".(isset($data['port']) ? "_".$data['port'] : "")."-[time]-".($this->get_enable_mysql_backup() ? "sql" : "nosql");
|
168 |
|
169 |
return $backup_name;
|
170 |
}
|
172 |
public function get_db_hostname() {
|
173 |
global $wpdb;
|
174 |
|
175 |
+
if (!$data = get_option('xcloner_mysql_hostname')) {
|
176 |
$data = $wpdb->dbhost;
|
177 |
}
|
178 |
|
182 |
public function get_db_username() {
|
183 |
global $wpdb;
|
184 |
|
185 |
+
if (!$data = get_option('xcloner_mysql_username')) {
|
186 |
$data = $wpdb->dbuser;
|
187 |
}
|
188 |
|
192 |
public function get_db_password() {
|
193 |
global $wpdb;
|
194 |
|
195 |
+
if (!$data = get_option('xcloner_mysql_password')) {
|
196 |
$data = $wpdb->dbpassword;
|
197 |
}
|
198 |
|
202 |
public function get_db_database() {
|
203 |
global $wpdb;
|
204 |
|
205 |
+
if (!$data = get_option('xcloner_mysql_database')) {
|
206 |
$data = $wpdb->dbname;
|
207 |
}
|
208 |
|
215 |
return $wpdb->prefix;
|
216 |
}
|
217 |
|
218 |
+
/**
|
219 |
+
* @param string $option
|
220 |
+
*/
|
221 |
+
public function get_xcloner_option($option) {
|
222 |
+
$data = get_option($option);
|
223 |
|
224 |
return $data;
|
225 |
}
|
226 |
|
227 |
+
public function get_server_unique_hash($strlen = 0) {
|
228 |
+
$hash = md5(get_home_url().__DIR__);
|
229 |
|
230 |
+
if ($strlen) {
|
231 |
+
$hash = substr($hash, 0, $strlen);
|
232 |
}
|
233 |
|
234 |
return $hash;
|
239 |
$this->xcloner_sanitization = $this->get_xcloner_container()->get_xcloner_sanitization();
|
240 |
|
241 |
//ADDING MISSING OPTIONS
|
242 |
+
if (false == get_option('xcloner_mysql_settings_page')) {
|
243 |
+
add_option('xcloner_mysql_settings_page');
|
244 |
} // end if
|
245 |
|
246 |
+
if (false == get_option('xcloner_cron_settings_page')) {
|
247 |
+
add_option('xcloner_cron_settings_page');
|
248 |
} // end if
|
249 |
|
250 |
+
if (false == get_option('xcloner_system_settings_page')) {
|
251 |
+
add_option('xcloner_system_settings_page');
|
252 |
} // end if
|
253 |
|
254 |
+
if (false == get_option('xcloner_cleanup_settings_page')) {
|
255 |
+
add_option('xcloner_cleanup_settings_page');
|
256 |
} // end if
|
257 |
|
258 |
|
260 |
//GENERAL section
|
261 |
add_settings_section(
|
262 |
'xcloner_general_settings_group',
|
263 |
+
__(' '),
|
264 |
+
array($this, 'xcloner_settings_section_cb'),
|
265 |
'xcloner_settings_page'
|
266 |
);
|
267 |
//MYSQL section
|
268 |
add_settings_section(
|
269 |
'xcloner_mysql_settings_group',
|
270 |
+
__(' '),
|
271 |
+
array($this, 'xcloner_settings_section_cb'),
|
272 |
'xcloner_mysql_settings_page'
|
273 |
);
|
274 |
|
275 |
//SYSTEM section
|
276 |
add_settings_section(
|
277 |
'xcloner_system_settings_group',
|
278 |
+
__('These are advanced options recommended for developers!', 'xcloner-backup-and-restore'),
|
279 |
+
array($this, 'xcloner_settings_section_cb'),
|
280 |
'xcloner_system_settings_page'
|
281 |
);
|
282 |
|
283 |
//CLEANUP section
|
284 |
add_settings_section(
|
285 |
'xcloner_cleanup_settings_group',
|
286 |
+
__(' '),
|
287 |
+
array($this, 'xcloner_settings_section_cb'),
|
288 |
'xcloner_cleanup_settings_page'
|
289 |
);
|
290 |
|
292 |
//CRON section
|
293 |
add_settings_section(
|
294 |
'xcloner_cron_settings_group',
|
295 |
+
__(' '),
|
296 |
+
array($this, 'xcloner_settings_section_cb'),
|
297 |
'xcloner_cron_settings_page'
|
298 |
);
|
299 |
|
300 |
|
301 |
//REGISTERING THE 'GENERAL SECTION' FIELDS
|
302 |
+
register_setting('xcloner_general_settings_group', 'xcloner_backup_compression_level', array(
|
303 |
$this->xcloner_sanitization,
|
304 |
"sanitize_input_as_int"
|
305 |
+
));
|
306 |
add_settings_field(
|
307 |
'xcloner_backup_compression_level',
|
308 |
+
__('Backup Compression Level', 'xcloner-backup-and-restore'),
|
309 |
+
array($this, 'do_form_range_field'),
|
310 |
'xcloner_settings_page',
|
311 |
'xcloner_general_settings_group',
|
312 |
array(
|
313 |
'xcloner_backup_compression_level',
|
314 |
+
__('Options between [0-9]. Value 0 means no compression, while 9 is maximum compression affecting cpu load', 'xcloner-backup-and-restore'),
|
315 |
0,
|
316 |
9
|
317 |
)
|
318 |
);
|
319 |
|
320 |
+
register_setting('xcloner_general_settings_group', 'xcloner_start_path', array(
|
321 |
$this->xcloner_sanitization,
|
322 |
"sanitize_input_as_absolute_path"
|
323 |
+
));
|
324 |
add_settings_field(
|
325 |
'xcloner_start_path',
|
326 |
+
__('Backup Start Location', 'xcloner-backup-and-restore'),
|
327 |
+
array($this, 'do_form_text_field'),
|
328 |
'xcloner_settings_page',
|
329 |
'xcloner_general_settings_group',
|
330 |
array(
|
331 |
'xcloner_start_path',
|
332 |
+
__('Base path location from where XCloner can start the Backup.', 'xcloner-backup-and-restore'),
|
333 |
$this->get_xcloner_start_path(),
|
334 |
//'disabled'
|
335 |
)
|
336 |
);
|
337 |
|
338 |
+
register_setting('xcloner_general_settings_group', 'xcloner_store_path', array(
|
339 |
$this->xcloner_sanitization,
|
340 |
"sanitize_input_as_absolute_path"
|
341 |
+
));
|
342 |
add_settings_field(
|
343 |
'xcloner_store_path',
|
344 |
+
__('Backup Storage Location', 'xcloner-backup-and-restore'),
|
345 |
+
array($this, 'do_form_text_field'),
|
346 |
'xcloner_settings_page',
|
347 |
'xcloner_general_settings_group',
|
348 |
array(
|
349 |
'xcloner_store_path',
|
350 |
+
__('Location where XCloner will store the Backup archives.', 'xcloner-backup-and-restore'),
|
351 |
$this->get_xcloner_store_path(),
|
352 |
//'disabled'
|
353 |
)
|
354 |
);
|
355 |
|
356 |
+
register_setting('xcloner_general_settings_group', 'xcloner_encryption_key', array(
|
357 |
+
$this->xcloner_sanitization,
|
358 |
+
"sanitize_input_as_string"
|
359 |
+
));
|
360 |
+
add_settings_field(
|
361 |
+
'xcloner_encryption_key',
|
362 |
+
__('Backup Encryption Key', 'xcloner-backup-and-restore'),
|
363 |
+
array($this, 'do_form_text_field'),
|
364 |
+
'xcloner_settings_page',
|
365 |
+
'xcloner_general_settings_group',
|
366 |
+
array(
|
367 |
+
'xcloner_encryption_key',
|
368 |
+
__('Backup Encryption Key used to Encrypt/Decrypt backups, you might want to save this somewhere else as well.', 'xcloner-backup-and-restore'),
|
369 |
+
$this->get_xcloner_encryption_key(),
|
370 |
+
//'disabled'
|
371 |
+
)
|
372 |
+
);
|
373 |
+
|
374 |
+
register_setting('xcloner_general_settings_group', 'xcloner_enable_log', array(
|
375 |
$this->xcloner_sanitization,
|
376 |
"sanitize_input_as_int"
|
377 |
+
));
|
378 |
add_settings_field(
|
379 |
'xcloner_enable_log',
|
380 |
+
__('Enable XCloner Backup Log', 'xcloner-backup-and-restore'),
|
381 |
+
array($this, 'do_form_switch_field'),
|
382 |
'xcloner_settings_page',
|
383 |
'xcloner_general_settings_group',
|
384 |
array(
|
385 |
'xcloner_enable_log',
|
386 |
+
sprintf(__('Enable the XCloner Backup log. You will find it stored unde the Backup Storage Location, file %s', 'xcloner-backup-and-restore'), $this->get_logger_filename())
|
387 |
)
|
388 |
);
|
389 |
|
390 |
+
register_setting('xcloner_general_settings_group', 'xcloner_enable_pre_update_backup', array(
|
391 |
$this->xcloner_sanitization,
|
392 |
"sanitize_input_as_int"
|
393 |
+
));
|
394 |
add_settings_field(
|
395 |
'xcloner_enable_pre_update_backup',
|
396 |
+
__('Generate Backups before Automatic WP Upgrades', 'xcloner-backup-and-restore'),
|
397 |
+
array($this, 'do_form_switch_field'),
|
398 |
'xcloner_settings_page',
|
399 |
'xcloner_general_settings_group',
|
400 |
array(
|
401 |
'xcloner_enable_pre_update_backup',
|
402 |
+
sprintf(__('Attempt to generate a core, plugins, themes or languages files backup before the automatic update of Wordpress core, plugins, themes or languages files.', 'xcloner-backup-and-restore'), $this->get_logger_filename())
|
403 |
)
|
404 |
);
|
405 |
|
406 |
+
register_setting('xcloner_general_settings_group', 'xcloner_regex_exclude', array(
|
407 |
$this->xcloner_sanitization,
|
408 |
"sanitize_input_as_raw"
|
409 |
+
));
|
410 |
add_settings_field(
|
411 |
'xcloner_regex_exclude',
|
412 |
+
__('Regex Exclude Files', 'xcloner-backup-and-restore'),
|
413 |
+
array($this, 'do_form_textarea_field'),
|
414 |
'xcloner_settings_page',
|
415 |
'xcloner_general_settings_group',
|
416 |
array(
|
417 |
'xcloner_regex_exclude',
|
418 |
+
__('Regular expression match to exclude files and folders, example patterns provided below, one pattern per line', 'xcloner-backup-and-restore'),
|
419 |
//$this->get_xcloner_store_path(),
|
420 |
//'disabled'
|
421 |
)
|
422 |
);
|
423 |
|
424 |
//REGISTERING THE 'MYSQL SECTION' FIELDS
|
425 |
+
register_setting('xcloner_mysql_settings_group', 'xcloner_enable_mysql_backup', array(
|
426 |
$this->xcloner_sanitization,
|
427 |
"sanitize_input_as_int"
|
428 |
+
));
|
429 |
add_settings_field(
|
430 |
'xcloner_enable_mysql_backup',
|
431 |
+
__('Enable Mysql Backup', 'xcloner-backup-and-restore'),
|
432 |
+
array($this, 'do_form_switch_field'),
|
433 |
'xcloner_mysql_settings_page',
|
434 |
'xcloner_mysql_settings_group',
|
435 |
array(
|
436 |
'xcloner_enable_mysql_backup',
|
437 |
+
__('Enable Mysql Backup Option. If you don\'t want to backup the database, you can disable this.', 'xcloner-backup-and-restore')
|
438 |
)
|
439 |
);
|
440 |
|
441 |
+
register_setting('xcloner_mysql_settings_group', 'xcloner_backup_only_wp_tables');
|
442 |
add_settings_field(
|
443 |
'xcloner_backup_only_wp_tables',
|
444 |
+
__('Backup only WP tables', 'xcloner-backup-and-restore'),
|
445 |
+
array($this, 'do_form_switch_field'),
|
446 |
'xcloner_mysql_settings_page',
|
447 |
'xcloner_mysql_settings_group',
|
448 |
array(
|
449 |
'xcloner_backup_only_wp_tables',
|
450 |
+
sprintf(__('Enable this if you only want to Backup only tables starting with \'%s\' prefix', 'xcloner-backup-and-restore'), $this->get_table_prefix())
|
451 |
)
|
452 |
);
|
453 |
|
454 |
+
register_setting('xcloner_mysql_settings_group', 'xcloner_mysql_hostname', array(
|
455 |
$this->xcloner_sanitization,
|
456 |
"sanitize_input_as_raw"
|
457 |
+
));
|
458 |
add_settings_field(
|
459 |
'xcloner_mysql_hostname',
|
460 |
+
__('Mysql Hostname', 'xcloner-backup-and-restore'),
|
461 |
+
array($this, 'do_form_text_field'),
|
462 |
'xcloner_mysql_settings_page',
|
463 |
'xcloner_mysql_settings_group',
|
464 |
array(
|
465 |
'xcloner_mysql_hostname',
|
466 |
+
__('Wordpress mysql hostname', 'xcloner-backup-and-restore'),
|
467 |
$this->get_db_hostname(),
|
468 |
'disabled'
|
469 |
)
|
470 |
);
|
471 |
|
472 |
+
register_setting('xcloner_mysql_settings_group', 'xcloner_mysql_username', array(
|
473 |
$this->xcloner_sanitization,
|
474 |
"sanitize_input_as_raw"
|
475 |
+
));
|
476 |
add_settings_field(
|
477 |
'xcloner_mysql_username',
|
478 |
+
__('Mysql Username', 'xcloner-backup-and-restore'),
|
479 |
+
array($this, 'do_form_text_field'),
|
480 |
'xcloner_mysql_settings_page',
|
481 |
'xcloner_mysql_settings_group',
|
482 |
array(
|
483 |
'xcloner_mysql_username',
|
484 |
+
__('Wordpress mysql username', 'xcloner-backup-and-restore'),
|
485 |
$this->get_db_username(),
|
486 |
'disabled'
|
487 |
)
|
488 |
);
|
489 |
|
490 |
+
register_setting('xcloner_mysql_settings_group', 'xcloner_mysql_database', array(
|
491 |
$this->xcloner_sanitization,
|
492 |
"sanitize_input_as_raw"
|
493 |
+
));
|
494 |
add_settings_field(
|
495 |
'xcloner_mysql_database',
|
496 |
+
__('Mysql Database', 'xcloner-backup-and-restore'),
|
497 |
+
array($this, 'do_form_text_field'),
|
498 |
'xcloner_mysql_settings_page',
|
499 |
'xcloner_mysql_settings_group',
|
500 |
array(
|
501 |
'xcloner_mysql_database',
|
502 |
+
__('Wordpress mysql database', 'xcloner-backup-and-restore'),
|
503 |
$this->get_db_database(),
|
504 |
'disabled'
|
505 |
)
|
506 |
);
|
507 |
|
508 |
//REGISTERING THE 'SYSTEM SECTION' FIELDS
|
509 |
+
register_setting('xcloner_system_settings_group', 'xcloner_size_limit_per_request', array(
|
510 |
$this->xcloner_sanitization,
|
511 |
"sanitize_input_as_int"
|
512 |
+
));
|
513 |
add_settings_field(
|
514 |
'xcloner_size_limit_per_request',
|
515 |
+
__('Data Size Limit Per Request', 'xcloner-backup-and-restore'),
|
516 |
+
array($this, 'do_form_range_field'),
|
517 |
'xcloner_system_settings_page',
|
518 |
'xcloner_system_settings_group',
|
519 |
array(
|
520 |
'xcloner_size_limit_per_request',
|
521 |
+
__('Use this option to set how much file data can XCloner backup in one AJAX request. Range 0-1024 MB', 'xcloner-backup-and-restore'),
|
522 |
0,
|
523 |
1024
|
524 |
)
|
525 |
);
|
526 |
|
527 |
+
register_setting('xcloner_system_settings_group', 'xcloner_files_to_process_per_request', array(
|
528 |
$this->xcloner_sanitization,
|
529 |
"sanitize_input_as_int"
|
530 |
+
));
|
531 |
add_settings_field(
|
532 |
'xcloner_files_to_process_per_request',
|
533 |
+
__('Files To Process Per Request', 'xcloner-backup-and-restore'),
|
534 |
+
array($this, 'do_form_range_field'),
|
535 |
'xcloner_system_settings_page',
|
536 |
'xcloner_system_settings_group',
|
537 |
array(
|
538 |
'xcloner_files_to_process_per_request',
|
539 |
+
__('Use this option to set how many files XCloner should process at one time before doing another AJAX call', 'xcloner-backup-and-restore'),
|
540 |
0,
|
541 |
1000
|
542 |
)
|
543 |
);
|
544 |
|
545 |
+
register_setting('xcloner_system_settings_group', 'xcloner_directories_to_scan_per_request', array(
|
546 |
$this->xcloner_sanitization,
|
547 |
"sanitize_input_as_int"
|
548 |
+
));
|
549 |
add_settings_field(
|
550 |
'xcloner_directories_to_scan_per_request',
|
551 |
+
__('Directories To Scan Per Request', 'xcloner-backup-and-restore'),
|
552 |
+
array($this, 'do_form_range_field'),
|
553 |
'xcloner_system_settings_page',
|
554 |
'xcloner_system_settings_group',
|
555 |
array(
|
556 |
'xcloner_directories_to_scan_per_request',
|
557 |
+
__('Use this option to set how many directories XCloner should scan at one time before doing another AJAX call', 'xcloner-backup-and-restore'),
|
558 |
0,
|
559 |
1000
|
560 |
)
|
561 |
);
|
562 |
|
563 |
+
register_setting('xcloner_system_settings_group', 'xcloner_database_records_per_request', array(
|
564 |
$this->xcloner_sanitization,
|
565 |
"sanitize_input_as_int"
|
566 |
+
));
|
567 |
add_settings_field(
|
568 |
'xcloner_database_records_per_request',
|
569 |
+
__('Database Records Per Request', 'xcloner-backup-and-restore'),
|
570 |
+
array($this, 'do_form_range_field'),
|
571 |
'xcloner_system_settings_page',
|
572 |
'xcloner_system_settings_group',
|
573 |
array(
|
574 |
'xcloner_database_records_per_request',
|
575 |
+
__('Use this option to set how many database table records should be fetched per AJAX request, or set to 0 to fetch all. Range 0-100000 records', 'xcloner-backup-and-restore'),
|
576 |
0,
|
577 |
100000
|
578 |
)
|
590 |
)
|
591 |
);*/
|
592 |
|
593 |
+
register_setting('xcloner_system_settings_group', 'xcloner_exclude_files_larger_than_mb', array(
|
594 |
$this->xcloner_sanitization,
|
595 |
"sanitize_input_as_int"
|
596 |
+
));
|
597 |
add_settings_field(
|
598 |
'xcloner_exclude_files_larger_than_mb',
|
599 |
+
__('Exclude files larger than (MB)', 'xcloner-backup-and-restore'),
|
600 |
+
array($this, 'do_form_number_field'),
|
601 |
'xcloner_system_settings_page',
|
602 |
'xcloner_system_settings_group',
|
603 |
array(
|
604 |
'xcloner_exclude_files_larger_than_mb',
|
605 |
+
__('Use this option to automatically exclude files larger than a certain size in MB, or set to 0 to include all. Range 0-1000 MB', 'xcloner-backup-and-restore'),
|
606 |
)
|
607 |
);
|
608 |
|
609 |
+
register_setting('xcloner_system_settings_group', 'xcloner_split_backup_limit', array(
|
610 |
$this->xcloner_sanitization,
|
611 |
"sanitize_input_as_int"
|
612 |
+
));
|
613 |
add_settings_field(
|
614 |
'xcloner_split_backup_limit',
|
615 |
+
__('Split Backup Archive Limit (MB)', 'xcloner-backup-and-restore'),
|
616 |
+
array($this, 'do_form_number_field'),
|
617 |
'xcloner_system_settings_page',
|
618 |
'xcloner_system_settings_group',
|
619 |
array(
|
620 |
'xcloner_split_backup_limit',
|
621 |
+
__('Use this option to automatically split the backup archive into smaller parts. Range 0-10000 MB', 'xcloner-backup-and-restore'),
|
622 |
)
|
623 |
);
|
624 |
|
625 |
+
register_setting('xcloner_system_settings_group', 'xcloner_force_tmp_path_site_root');
|
626 |
add_settings_field(
|
627 |
'xcloner_force_tmp_path_site_root',
|
628 |
+
__('Force Temporary Path Within XCloner Storage', 'xcloner-backup-and-restore'),
|
629 |
+
array($this, 'do_form_switch_field'),
|
630 |
'xcloner_system_settings_page',
|
631 |
'xcloner_system_settings_group',
|
632 |
array(
|
633 |
'xcloner_force_tmp_path_site_root',
|
634 |
+
sprintf(__('Enable this option if you want the XCloner Temporary Path to be within your XCloner Storage Location', 'xcloner-backup-and-restore'), $this->get_table_prefix())
|
635 |
+
)
|
636 |
+
);
|
637 |
+
|
638 |
+
register_setting('xcloner_system_settings_group', 'xcloner_disable_email_notification');
|
639 |
+
add_settings_field(
|
640 |
+
'xcloner_disable_email_notification',
|
641 |
+
__('Disable Email Notifications', 'xcloner-backup-and-restore'),
|
642 |
+
array($this, 'do_form_switch_field'),
|
643 |
+
'xcloner_system_settings_page',
|
644 |
+
'xcloner_system_settings_group',
|
645 |
+
array(
|
646 |
+
'xcloner_disable_email_notification',
|
647 |
+
sprintf(__('Enable this option if you want the XCloner to NOT send email notifications on successful backups', 'xcloner-backup-and-restore'), $this->get_table_prefix())
|
648 |
)
|
649 |
);
|
650 |
|
651 |
//REGISTERING THE 'CLEANUP SECTION' FIELDS
|
652 |
+
register_setting('xcloner_cleanup_settings_group', 'xcloner_cleanup_retention_limit_days', array(
|
653 |
$this->xcloner_sanitization,
|
654 |
"sanitize_input_as_int"
|
655 |
+
));
|
656 |
add_settings_field(
|
657 |
'xcloner_cleanup_retention_limit_days',
|
658 |
+
__('Cleanup by Date(days)', 'xcloner-backup-and-restore'),
|
659 |
+
array($this, 'do_form_number_field'),
|
660 |
'xcloner_cleanup_settings_page',
|
661 |
'xcloner_cleanup_settings_group',
|
662 |
array(
|
663 |
'xcloner_cleanup_retention_limit_days',
|
664 |
+
__('Specify the maximum number of days a backup archive can be kept on the server. 0 disables this option', 'xcloner-backup-and-restore')
|
665 |
)
|
666 |
);
|
667 |
|
668 |
+
register_setting('xcloner_cleanup_settings_group', 'xcloner_cleanup_retention_limit_archives', array(
|
669 |
$this->xcloner_sanitization,
|
670 |
"sanitize_input_as_int"
|
671 |
+
));
|
672 |
add_settings_field(
|
673 |
'xcloner_cleanup_retention_limit_archives',
|
674 |
+
__('Cleanup by Quantity', 'xcloner-backup-and-restore'),
|
675 |
+
array($this, 'do_form_number_field'),
|
676 |
'xcloner_cleanup_settings_page',
|
677 |
'xcloner_cleanup_settings_group',
|
678 |
array(
|
679 |
'xcloner_cleanup_retention_limit_archives',
|
680 |
+
__('Specify the maximum number of backup archives to keep on the server. 0 disables this option', 'xcloner-backup-and-restore')
|
681 |
)
|
682 |
);
|
683 |
|
684 |
+
register_setting('xcloner_cleanup_settings_group', 'xcloner_cleanup_capacity_limit', array(
|
685 |
$this->xcloner_sanitization,
|
686 |
"sanitize_input_as_int"
|
687 |
+
));
|
688 |
add_settings_field(
|
689 |
'xcloner_cleanup_capacity_limit',
|
690 |
+
__('Cleanup by Capacity(MB)', 'xcloner-backup-and-restore'),
|
691 |
+
array($this, 'do_form_number_field'),
|
692 |
'xcloner_cleanup_settings_page',
|
693 |
'xcloner_cleanup_settings_group',
|
694 |
array(
|
695 |
'xcloner_cleanup_capacity_limit',
|
696 |
+
__('Remove oldest backups if all created backups exceed the configured limit in Megabytes. 0 disables this option', 'xcloner-backup-and-restore')
|
697 |
)
|
698 |
);
|
699 |
|
700 |
+
register_setting('xcloner_cleanup_settings_group', 'xcloner_cleanup_delete_after_remote_transfer', array(
|
701 |
$this->xcloner_sanitization,
|
702 |
"sanitize_input_as_int"
|
703 |
+
));
|
704 |
add_settings_field(
|
705 |
'xcloner_cleanup_delete_after_remote_transfer',
|
706 |
+
__('Delete Backup After Remote Storage Transfer', 'xcloner-backup-and-restore'),
|
707 |
+
array($this, 'do_form_switch_field'),
|
708 |
'xcloner_cleanup_settings_page',
|
709 |
'xcloner_cleanup_settings_group',
|
710 |
array(
|
711 |
'xcloner_cleanup_delete_after_remote_transfer',
|
712 |
+
__('Remove backup created automatically from local storage after sending the backup to Remote Storage', 'xcloner-backup-and-restore')
|
713 |
)
|
714 |
);
|
715 |
|
716 |
//REGISTERING THE 'CRON SECTION' FIELDS
|
717 |
+
register_setting('xcloner_cron_settings_group', 'xcloner_cron_frequency');
|
718 |
add_settings_field(
|
719 |
'xcloner_cron_frequency',
|
720 |
+
__('Cron frequency', 'xcloner-backup-and-restore'),
|
721 |
+
array($this, 'do_form_text_field'),
|
722 |
'xcloner_cron_settings_page',
|
723 |
'xcloner_cron_settings_group',
|
724 |
array(
|
725 |
'xcloner_cron_frequency',
|
726 |
+
__('Cron frequency')
|
727 |
)
|
728 |
);
|
729 |
}
|
741 |
}
|
742 |
|
743 |
// text field content cb
|
744 |
+
public function do_form_text_field($params) {
|
745 |
+
if (!isset($params['3'])) {
|
746 |
$params[3] = 0;
|
747 |
}
|
748 |
+
if (!isset($params['2'])) {
|
749 |
$params[2] = 0;
|
750 |
}
|
751 |
|
752 |
+
list($fieldname, $label, $value, $disabled) = $params;
|
753 |
|
754 |
+
if (!$value) {
|
755 |
+
$value = get_option($fieldname);
|
756 |
}
|
757 |
// output the field
|
758 |
?>
|
759 |
<div class="row">
|
760 |
<div class="input-field col s10 m10 l8">
|
761 |
+
<input class="validate" <?php echo ($disabled) ? "disabled" : "" ?> name="<?php echo $fieldname ?>"
|
762 |
id="<?php echo $fieldname ?>" type="text" class="validate"
|
763 |
+
value="<?php echo isset($value) ? esc_attr($value) : ''; ?>">
|
764 |
</div>
|
765 |
<div class="col s2 m2 ">
|
766 |
<a class="btn-floating tooltipped btn-small" data-position="left" data-delay="50"
|
773 |
}
|
774 |
|
775 |
// textarea field content cb
|
776 |
+
public function do_form_textarea_field($params) {
|
777 |
+
if (!isset($params['3'])) {
|
778 |
$params[3] = 0;
|
779 |
}
|
780 |
+
if (!isset($params['2'])) {
|
781 |
$params[2] = 0;
|
782 |
}
|
783 |
|
784 |
+
list($fieldname, $label, $value, $disabled) = $params;
|
785 |
|
786 |
+
if (!$value) {
|
787 |
+
$value = get_option($fieldname);
|
788 |
}
|
789 |
// output the field
|
790 |
?>
|
791 |
<div class="row">
|
792 |
<div class="input-field col s10 m10 l8">
|
793 |
+
<textarea class="validate" <?php echo ($disabled) ? "disabled" : "" ?> name="<?php echo $fieldname ?>"
|
794 |
id="<?php echo $fieldname ?>" type="text" class="validate"
|
795 |
+
value=""><?php echo isset($value) ? esc_attr($value) : ''; ?></textarea>
|
796 |
</div>
|
797 |
<div class="col s2 m2 ">
|
798 |
<a class="btn-floating tooltipped btn-small" data-position="center" data-html="true" data-delay="50"
|
801 |
<div class="col s12">
|
802 |
<ul class="xcloner_regex_exclude_limit">
|
803 |
<li>Exclude all except .php file: <span
|
804 |
+
class="regex_pattern"><?php echo htmlentities('(.*)\.(.+)$(?<!(php))') ?></span></li>
|
805 |
<li>Exclude all except .php and .txt: <span
|
806 |
+
class="regex_pattern"> <?php echo htmlentities('(.*)\.(.+)$(?<!(php|txt))') ?></span>
|
807 |
</li>
|
808 |
<li>Exclude all .avi files: <span
|
809 |
+
class="regex_pattern"> <?php echo htmlentities('(.*)\.(.+)$(?<=(avi))') ?></span></li>
|
810 |
<li>Exclude all .jpg,.gif and .png files: <span
|
811 |
+
class="regex_pattern"> <?php echo htmlentities('(.*)\.(.+)$(?<=(gif|png|jpg))') ?></span>
|
812 |
</li>
|
813 |
<li>Exclude all .svn and .git: <span
|
814 |
+
class="regex_pattern"> <?php echo htmlentities('(.*)\.(svn|git)(.*)$') ?></span></li>
|
815 |
<li>Exclude root directory /test: <span
|
816 |
+
class="regex_pattern"> <?php echo htmlentities('\/test(.*)$') ?></span> or <span
|
817 |
+
class="regex_pattern"> <?php echo htmlentities('test(.*)$') ?></span></li>
|
818 |
<li>Exclude the wp-admin folder: <span
|
819 |
+
class="regex_pattern"> <?php echo htmlentities('(\/wp-admin)(.*)$') ?></span></li>
|
820 |
<li>Exclude the wp-content/uploads folder: <span
|
821 |
+
class="regex_pattern"> <?php echo htmlentities('(\/wp-content\/uploads)(.*)$') ?></span>
|
822 |
</li>
|
823 |
<li>Exclude the wp-admin, wp-includes and wp-config.php: <span
|
824 |
+
class="regex_pattern"> <?php echo htmlentities('\/(wp-admin|wp-includes|wp-config.php)(.*)$') ?></span>
|
825 |
</li>
|
826 |
<li>Exclude wp-content/updraft and wp/content/uploads/wp_all_backup folder :<span
|
827 |
class="regex_pattern">\/(wp-content\/updraft|\/wp-content\/uploads\/wp_all_backup)(.*)$</span>
|
828 |
</li>
|
829 |
<li>Exclude all cache folders from wp-content/ and it's subdirectories: <span
|
830 |
+
class="regex_pattern"> <?php echo htmlentities('\/wp-content(.*)\/cache($|\/)(.*)') ?></span>
|
831 |
</li>
|
832 |
<li>Exclude wp-content/cache/ folder: <span
|
833 |
+
class="regex_pattern"> <?php echo htmlentities('\/wp-content\/cache(.*)') ?></span>
|
834 |
</li>
|
835 |
<li>Exclude all error_log files: <span
|
836 |
+
class="regex_pattern"> <?php echo htmlentities('(.*)error_log$') ?></span></li>
|
837 |
</ul>
|
838 |
</div>
|
839 |
</div>
|
843 |
}
|
844 |
|
845 |
// number field content cb
|
846 |
+
public function do_form_number_field($params) {
|
847 |
+
if (!isset($params['3'])) {
|
848 |
$params[3] = 0;
|
849 |
}
|
850 |
+
if (!isset($params['2'])) {
|
851 |
$params[2] = 0;
|
852 |
}
|
853 |
|
854 |
+
list($fieldname, $label, $value, $disabled) = $params;
|
855 |
|
856 |
+
if (!$value) {
|
857 |
+
$value = get_option($fieldname);
|
858 |
}
|
859 |
// output the field
|
860 |
?>
|
861 |
<div class="row">
|
862 |
<div class="input-field col s10 m5 l3">
|
863 |
+
<input class="validate" <?php echo ($disabled) ? "disabled" : "" ?> name="<?php echo $fieldname ?>"
|
864 |
id="<?php echo $fieldname ?>" type="number" class="validate"
|
865 |
+
value="<?php echo isset($value) ? esc_attr($value) : ''; ?>">
|
866 |
</div>
|
867 |
<div class="col s2 m2 ">
|
868 |
<a class="btn-floating tooltipped btn-small" data-html="true" data-position="center" data-delay="50"
|
874 |
<?php
|
875 |
}
|
876 |
|
877 |
+
public function do_form_range_field($params) {
|
878 |
+
if (!isset($params['4'])) {
|
879 |
$params[4] = 0;
|
880 |
}
|
881 |
|
882 |
+
list($fieldname, $label, $range_start, $range_end, $disabled) = $params;
|
883 |
+
$value = get_option($fieldname);
|
884 |
?>
|
885 |
<div class="row">
|
886 |
<div class="input-field col s10 m10 l8">
|
887 |
<p class="range-field">
|
888 |
+
<input <?php echo ($disabled) ? "disabled" : "" ?> type="range" name="<?php echo $fieldname ?>"
|
889 |
id="<?php echo $fieldname ?>"
|
890 |
min="<?php echo $range_start ?>"
|
891 |
max="<?php echo $range_end ?>"
|
892 |
+
value="<?php echo isset($value) ? esc_attr($value) : ''; ?>"/>
|
893 |
</p>
|
894 |
</div>
|
895 |
<div class="col s2 m2 ">
|
901 |
}
|
902 |
|
903 |
|
904 |
+
public function do_form_switch_field($params) {
|
905 |
+
if (!isset($params['2'])) {
|
906 |
$params[2] = 0;
|
907 |
}
|
908 |
+
list($fieldname, $label, $disabled) = $params;
|
909 |
+
$value = get_option($fieldname);
|
910 |
?>
|
911 |
<div class="row">
|
912 |
<div class="input-field col s10 m5 l3">
|
913 |
<div class="switch">
|
914 |
<label>
|
915 |
Off
|
916 |
+
<input <?php echo ($disabled) ? "disabled" : "" ?> type="checkbox"
|
917 |
name="<?php echo $fieldname ?>"
|
918 |
id="<?php echo $fieldname ?>"
|
919 |
+
value="1" <?php echo ($value) ? 'checked="checked"' : ''; ?>
|
920 |
">
|
921 |
<span class="lever"></span>
|
922 |
On
|
includes/class-xcloner.php
CHANGED
@@ -83,6 +83,8 @@ class Xcloner {
|
|
83 |
private $xcloner_scheduler;
|
84 |
private $xcloner_remote_storage;
|
85 |
private $xcloner_file_transfer;
|
|
|
|
|
86 |
/**
|
87 |
* Define the core functionality of the plugin.
|
88 |
*
|
@@ -112,7 +114,17 @@ class Xcloner {
|
|
112 |
|
113 |
}
|
114 |
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
{
|
117 |
return $this->xcloner_settings;
|
118 |
}
|
@@ -162,15 +174,29 @@ class Xcloner {
|
|
162 |
return $this->xcloner_file_transfer;
|
163 |
}
|
164 |
|
165 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
$backup_storage_path = realpath(__DIR__.DS."..".DS."..".DS."..").DS."backups".DS;
|
168 |
|
169 |
define("XCLONER_STORAGE_PATH", realpath($backup_storage_path));
|
170 |
|
171 |
-
if(!is_dir($backup_storage_path))
|
172 |
{
|
173 |
-
if(!@mkdir($backup_storage_path))
|
174 |
{
|
175 |
$status = "error";
|
176 |
$message = sprintf(__("Unable to create the Backup Storage Location Folder %s . Please fix this before starting the backup process."), $backup_storage_path);
|
@@ -178,7 +204,7 @@ class Xcloner {
|
|
178 |
return;
|
179 |
}
|
180 |
}
|
181 |
-
if(!is_writable($backup_storage_path))
|
182 |
{
|
183 |
$status = "error";
|
184 |
$message = sprintf(__("Unable to write to the Backup Storage Location Folder %s . Please fix this before starting the backup process."), $backup_storage_path);
|
@@ -192,15 +218,15 @@ class Xcloner {
|
|
192 |
public function trigger_message($message, $status = "error", $message_param1 = "", $message_param2 = "", $message_param3 = "")
|
193 |
{
|
194 |
$message = sprintf(__($message), $message_param1, $message_param2, $message_param3);
|
195 |
-
add_action(
|
196 |
-
do_action(
|
197 |
}
|
198 |
|
199 |
public function trigger_message_notice($message, $status = "success")
|
200 |
{
|
201 |
?>
|
202 |
<div class="notice notice-<?php echo $status?> is-dismissible">
|
203 |
-
<p><?php _e(
|
204 |
</div>
|
205 |
<?php
|
206 |
}
|
@@ -227,79 +253,84 @@ class Xcloner {
|
|
227 |
* The class responsible for orchestrating the actions and filters of the
|
228 |
* core plugin.
|
229 |
*/
|
230 |
-
require_once plugin_dir_path(
|
231 |
|
232 |
/**
|
233 |
* The class responsible for defining internationalization functionality
|
234 |
* of the plugin.
|
235 |
*/
|
236 |
-
require_once plugin_dir_path(
|
237 |
|
238 |
/**
|
239 |
* The class responsible for defining all actions that occur in the admin area.
|
240 |
*/
|
241 |
-
require_once plugin_dir_path(
|
242 |
|
243 |
/**
|
244 |
* The class responsible for debugging XCloner.
|
245 |
*/
|
246 |
-
require_once plugin_dir_path(
|
247 |
|
248 |
/**
|
249 |
* The class responsible for defining the admin settings area.
|
250 |
*/
|
251 |
-
require_once plugin_dir_path(
|
252 |
|
253 |
/**
|
254 |
* The class responsible for defining the Remote Storage settings area.
|
255 |
*/
|
256 |
-
require_once plugin_dir_path(
|
257 |
|
258 |
/**
|
259 |
* The class responsible for implementing the database backup methods.
|
260 |
*/
|
261 |
-
require_once plugin_dir_path(
|
262 |
|
263 |
/**
|
264 |
* The class responsible for sanitization of users input.
|
265 |
*/
|
266 |
-
require_once plugin_dir_path(
|
267 |
|
268 |
/**
|
269 |
* The class responsible for XCloner system requirements validation.
|
270 |
*/
|
271 |
-
require_once plugin_dir_path(
|
272 |
|
273 |
/**
|
274 |
* The class responsible for XCloner backup archive creation.
|
275 |
*/
|
276 |
-
require_once plugin_dir_path(
|
277 |
|
278 |
/**
|
279 |
* The class responsible for XCloner API requests.
|
280 |
*/
|
281 |
-
require_once plugin_dir_path(
|
282 |
|
283 |
/**
|
284 |
* The class responsible for the XCloner File System methods.
|
285 |
*/
|
286 |
-
require_once plugin_dir_path(
|
287 |
|
288 |
/**
|
289 |
* The class responsible for the XCloner File Transfer methods.
|
290 |
*/
|
291 |
-
require_once plugin_dir_path(
|
292 |
|
293 |
/**
|
294 |
* The class responsible for the XCloner Scheduler methods.
|
295 |
*/
|
296 |
-
require_once plugin_dir_path(
|
|
|
|
|
|
|
|
|
|
|
297 |
|
298 |
/**
|
299 |
* The class responsible for defining all actions that occur in the public-facing
|
300 |
* side of the site.
|
301 |
*/
|
302 |
-
require_once plugin_dir_path(
|
303 |
|
304 |
$this->loader = new Xcloner_Loader($this);
|
305 |
|
@@ -318,10 +349,10 @@ class Xcloner {
|
|
318 |
|
319 |
$plugin_i18n = new Xcloner_i18n();
|
320 |
|
321 |
-
$this->loader->add_action(
|
322 |
|
323 |
//wp_localize_script( 'ajax-script', 'my_ajax_object',
|
324 |
-
|
325 |
|
326 |
}
|
327 |
|
@@ -334,13 +365,13 @@ class Xcloner {
|
|
334 |
*/
|
335 |
private function define_admin_hooks() {
|
336 |
|
337 |
-
$plugin_admin = new Xcloner_Admin(
|
338 |
$this->plugin_admin = $plugin_admin;
|
339 |
|
340 |
-
$this->loader->add_action(
|
341 |
-
$this->loader->add_action(
|
342 |
|
343 |
-
add_action(
|
344 |
}
|
345 |
|
346 |
/**
|
@@ -349,33 +380,33 @@ class Xcloner {
|
|
349 |
* @access private
|
350 |
*
|
351 |
*/
|
352 |
-
private function define_admin_menu(){
|
353 |
|
354 |
add_action('admin_menu', array($this->loader, 'xcloner_backup_add_admin_menu'));
|
355 |
|
356 |
}
|
357 |
|
358 |
-
private function define_plugin_settings(){
|
359 |
/**
|
360 |
-
|
361 |
-
|
362 |
|
363 |
$this->xcloner_settings = new XCloner_Settings($this);
|
364 |
|
365 |
-
if(defined('DOING_CRON') || isset($_POST['hash'])){
|
366 |
|
367 |
-
if(defined('DOING_CRON') || $_POST['hash'] == "generate_hash"){
|
368 |
$this->xcloner_settings->generate_new_hash();
|
369 |
-
}else{
|
370 |
$this->xcloner_settings->set_hash($_POST['hash']);
|
371 |
}
|
372 |
}
|
373 |
|
374 |
-
if(defined('DOING_CRON') || !isset($_POST['hash']))
|
375 |
{
|
376 |
-
add_action(
|
377 |
-
$this->
|
378 |
-
$this->
|
379 |
});
|
380 |
}
|
381 |
|
@@ -392,23 +423,29 @@ class Xcloner {
|
|
392 |
}
|
393 |
|
394 |
/*
|
|
|
|
|
395 |
* type = core|plugin|theme|translation
|
396 |
*/
|
397 |
public function pre_auto_update($type, $item, $context)
|
398 |
{
|
399 |
-
if(!$type)
|
400 |
{
|
401 |
return false;
|
402 |
}
|
403 |
|
|
|
|
|
|
|
|
|
404 |
$this->get_xcloner_logger()->info(sprintf("Doing automatic backup before %s upgrade, pre_auto_update hook.", $type));
|
405 |
|
406 |
$content_dir = str_replace(ABSPATH, "", WP_CONTENT_DIR);
|
407 |
$plugins_dir = str_replace(ABSPATH, "", WP_PLUGIN_DIR);
|
408 |
-
$langs_dir = $content_dir
|
409 |
-
$themes_dir = $content_dir
|
410 |
|
411 |
-
switch (
|
412 |
case 'core':
|
413 |
$exclude_files = array(
|
414 |
"^(?!(wp-admin|wp-includes|(?!.*\/.*.php)))(.*)$",
|
@@ -418,7 +455,7 @@ class Xcloner {
|
|
418 |
|
419 |
$dir_array = explode(DS, $plugins_dir);
|
420 |
|
421 |
-
foreach($dir_array as $dir)
|
422 |
{
|
423 |
$data .= "\/".$dir;
|
424 |
$regex .= $data."$|";
|
@@ -434,7 +471,7 @@ class Xcloner {
|
|
434 |
|
435 |
$dir_array = explode(DS, $themes_dir);
|
436 |
|
437 |
-
foreach($dir_array as $dir)
|
438 |
{
|
439 |
$data .= "\/".$dir;
|
440 |
$regex .= $data."$|";
|
@@ -450,7 +487,7 @@ class Xcloner {
|
|
450 |
|
451 |
$dir_array = explode(DS, $langs_dir);
|
452 |
|
453 |
-
foreach($dir_array as $dir)
|
454 |
{
|
455 |
$data .= "\/".$dir;
|
456 |
$regex .= $data."$|";
|
@@ -476,9 +513,9 @@ class Xcloner {
|
|
476 |
$schedule['backup_params']->email_notification = get_option('admin_email');
|
477 |
$schedule['backup_params']->backup_name = "backup_pre_auto_update_".$type."_[domain]-[time]-sql";
|
478 |
|
479 |
-
try{
|
480 |
$this->xcloner_scheduler->xcloner_scheduler_callback(0, $schedule);
|
481 |
-
}catch(Exception $e){
|
482 |
$this->get_xcloner_logger()->error($e->getMessage());
|
483 |
}
|
484 |
|
@@ -493,10 +530,10 @@ class Xcloner {
|
|
493 |
*/
|
494 |
private function define_public_hooks() {
|
495 |
|
496 |
-
$plugin_public = new Xcloner_Public(
|
497 |
|
498 |
-
$this->loader->add_action(
|
499 |
-
$this->loader->add_action(
|
500 |
|
501 |
}
|
502 |
|
@@ -505,91 +542,102 @@ class Xcloner {
|
|
505 |
$logger = new XCloner_Logger($this, "php_system");
|
506 |
$error = error_get_last();
|
507 |
|
508 |
-
if($error['type'] and $logger)
|
509 |
{
|
510 |
-
$logger->info($this->friendly_error_type
|
511 |
}
|
512 |
|
513 |
}
|
514 |
|
515 |
-
function friendly_error_type($type) {
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
$levels[$value]= $key; //substr($key,2);
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
}
|
526 |
|
|
|
|
|
|
|
|
|
527 |
private function define_ajax_hooks()
|
528 |
{
|
529 |
//adding the pre-update hook
|
530 |
|
531 |
-
if(is_admin() || defined('DOING_CRON'))
|
532 |
{
|
533 |
-
$this->xcloner_logger
|
534 |
-
$this->xcloner_filesystem
|
535 |
|
536 |
//$this->xcloner_filesystem->set_diff_timestamp_start (strtotime("-15 days"));
|
537 |
|
538 |
-
$this->archive_system
|
539 |
-
$this->xcloner_database
|
540 |
-
$this->xcloner_scheduler
|
541 |
-
$this->xcloner_remote_storage
|
542 |
$this->xcloner_file_transfer = new Xcloner_File_Transfer($this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
543 |
|
544 |
-
|
545 |
-
|
546 |
-
add_action( 'wp_ajax_get_database_tables_action', array($xcloner_api,'get_database_tables_action') );
|
547 |
-
add_action( 'wp_ajax_get_file_system_action', array($xcloner_api,'get_file_system_action') );
|
548 |
-
add_action( 'wp_ajax_scan_filesystem', array($xcloner_api,'scan_filesystem') );
|
549 |
-
add_action( 'wp_ajax_backup_database', array($xcloner_api,'backup_database') );
|
550 |
-
add_action( 'wp_ajax_backup_files' , array($xcloner_api,'backup_files') );
|
551 |
-
add_action( 'wp_ajax_save_schedule' , array($xcloner_api,'save_schedule') );
|
552 |
-
add_action( 'wp_ajax_get_schedule_by_id', array($xcloner_api,'get_schedule_by_id') );
|
553 |
-
add_action( 'wp_ajax_get_scheduler_list', array($xcloner_api,'get_scheduler_list') );
|
554 |
-
add_action( 'wp_ajax_delete_schedule_by_id' , array($xcloner_api,'delete_schedule_by_id') );
|
555 |
-
add_action( 'wp_ajax_delete_backup_by_name' , array($xcloner_api,'delete_backup_by_name') );
|
556 |
-
add_action( 'wp_ajax_download_backup_by_name', array($xcloner_api,'download_backup_by_name') );
|
557 |
-
add_action( 'wp_ajax_remote_storage_save_status', array($xcloner_api,'remote_storage_save_status') );
|
558 |
-
add_action( 'wp_ajax_upload_backup_to_remote', array($xcloner_api,'upload_backup_to_remote') );
|
559 |
-
add_action( 'wp_ajax_list_backup_files' , array($xcloner_api,'list_backup_files') );
|
560 |
-
add_action( 'wp_ajax_restore_upload_backup' , array($xcloner_api,'restore_upload_backup') );
|
561 |
-
add_action( 'wp_ajax_download_restore_script', array($xcloner_api,'download_restore_script') );
|
562 |
-
add_action( 'wp_ajax_copy_backup_remote_to_local', array($xcloner_api,'copy_backup_remote_to_local') );
|
563 |
-
add_action( 'wp_ajax_restore_backup', array($xcloner_api,'restore_backup') );
|
564 |
-
add_action( 'admin_notices', array($this, 'xcloner_error_admin_notices' ));
|
565 |
-
|
566 |
-
}
|
567 |
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
add_action("pre_auto_update", array($this, "pre_auto_update"), 1, 3);
|
572 |
}
|
573 |
}
|
574 |
|
575 |
-
function add_plugin_action_links($links, $file) {
|
576 |
-
|
577 |
{
|
578 |
$links[] = '<a href="admin.php?page=xcloner_settings_page">'.__('Settings', 'xcloner-backup-and-restore').'</a>';
|
579 |
$links[] = '<a href="admin.php?page=xcloner_generate_backups_page">'.__('Generate Backup', 'xcloner-backup-and-restore').'</a>';
|
580 |
}
|
581 |
|
582 |
-
|
583 |
-
|
584 |
|
585 |
public function xcloner_error_admin_notices() {
|
586 |
-
settings_errors(
|
587 |
}
|
588 |
|
|
|
|
|
|
|
589 |
public function define_cron_hooks()
|
590 |
{
|
591 |
//registering new schedule intervals
|
592 |
-
add_filter(
|
593 |
|
594 |
|
595 |
$xcloner_scheduler = $this->get_xcloner_scheduler();
|
@@ -597,7 +645,11 @@ class Xcloner {
|
|
597 |
|
598 |
}
|
599 |
|
600 |
-
|
|
|
|
|
|
|
|
|
601 |
{
|
602 |
//weekly scheduler interval
|
603 |
$schedules['weekly'] = array(
|
@@ -651,26 +703,16 @@ class Xcloner {
|
|
651 |
return $this->loader;
|
652 |
}
|
653 |
|
654 |
-
|
655 |
-
* Retrieve the version number of the plugin.
|
656 |
-
*
|
657 |
-
* @since 1.0.0
|
658 |
-
* @return string The version number of the plugin.
|
659 |
-
*/
|
660 |
-
public function get_version() {
|
661 |
-
return $this->version;
|
662 |
-
}
|
663 |
-
|
664 |
-
function xcloner_display()
|
665 |
{
|
666 |
// check user capabilities
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
|
671 |
$page = sanitize_key($_GET['page']);
|
672 |
|
673 |
-
if($page)
|
674 |
{
|
675 |
$this->display($page);
|
676 |
}
|
83 |
private $xcloner_scheduler;
|
84 |
private $xcloner_remote_storage;
|
85 |
private $xcloner_file_transfer;
|
86 |
+
private $xcloner_encryption;
|
87 |
+
|
88 |
/**
|
89 |
* Define the core functionality of the plugin.
|
90 |
*
|
114 |
|
115 |
}
|
116 |
|
117 |
+
/**
|
118 |
+
* Retrieve the version number of the plugin.
|
119 |
+
*
|
120 |
+
* @since 1.0.0
|
121 |
+
* @return string The version number of the plugin.
|
122 |
+
*/
|
123 |
+
/*public function get_version() {
|
124 |
+
return $this->version;
|
125 |
+
}
|
126 |
+
|
127 |
+
public function get_xcloner_settings()
|
128 |
{
|
129 |
return $this->xcloner_settings;
|
130 |
}
|
174 |
return $this->xcloner_file_transfer;
|
175 |
}
|
176 |
|
177 |
+
public function get_xcloner_encryption()
|
178 |
+
{
|
179 |
+
return $this->xcloner_encryption;
|
180 |
+
}*/
|
181 |
+
|
182 |
+
public function __call($property, $args) {
|
183 |
+
|
184 |
+
$property = str_replace("get_", "", $property);
|
185 |
+
|
186 |
+
if(property_exists($this, $property)){
|
187 |
+
return $this->$property;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
public function check_dependencies() {
|
192 |
|
193 |
$backup_storage_path = realpath(__DIR__.DS."..".DS."..".DS."..").DS."backups".DS;
|
194 |
|
195 |
define("XCLONER_STORAGE_PATH", realpath($backup_storage_path));
|
196 |
|
197 |
+
if (!is_dir($backup_storage_path))
|
198 |
{
|
199 |
+
if (!@mkdir($backup_storage_path))
|
200 |
{
|
201 |
$status = "error";
|
202 |
$message = sprintf(__("Unable to create the Backup Storage Location Folder %s . Please fix this before starting the backup process."), $backup_storage_path);
|
204 |
return;
|
205 |
}
|
206 |
}
|
207 |
+
if (!is_writable($backup_storage_path))
|
208 |
{
|
209 |
$status = "error";
|
210 |
$message = sprintf(__("Unable to write to the Backup Storage Location Folder %s . Please fix this before starting the backup process."), $backup_storage_path);
|
218 |
public function trigger_message($message, $status = "error", $message_param1 = "", $message_param2 = "", $message_param3 = "")
|
219 |
{
|
220 |
$message = sprintf(__($message), $message_param1, $message_param2, $message_param3);
|
221 |
+
add_action('xcloner_admin_notices', array($this, "trigger_message_notice"), 10, 2);
|
222 |
+
do_action('xcloner_admin_notices', $message, $status);
|
223 |
}
|
224 |
|
225 |
public function trigger_message_notice($message, $status = "success")
|
226 |
{
|
227 |
?>
|
228 |
<div class="notice notice-<?php echo $status?> is-dismissible">
|
229 |
+
<p><?php _e($message, 'xcloner-backup-and-restore'); ?></p>
|
230 |
</div>
|
231 |
<?php
|
232 |
}
|
253 |
* The class responsible for orchestrating the actions and filters of the
|
254 |
* core plugin.
|
255 |
*/
|
256 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-loader.php';
|
257 |
|
258 |
/**
|
259 |
* The class responsible for defining internationalization functionality
|
260 |
* of the plugin.
|
261 |
*/
|
262 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-i18n.php';
|
263 |
|
264 |
/**
|
265 |
* The class responsible for defining all actions that occur in the admin area.
|
266 |
*/
|
267 |
+
require_once plugin_dir_path(dirname(__FILE__)).'admin/class-xcloner-admin.php';
|
268 |
|
269 |
/**
|
270 |
* The class responsible for debugging XCloner.
|
271 |
*/
|
272 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-logger.php';
|
273 |
|
274 |
/**
|
275 |
* The class responsible for defining the admin settings area.
|
276 |
*/
|
277 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-settings.php';
|
278 |
|
279 |
/**
|
280 |
* The class responsible for defining the Remote Storage settings area.
|
281 |
*/
|
282 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-remote-storage.php';
|
283 |
|
284 |
/**
|
285 |
* The class responsible for implementing the database backup methods.
|
286 |
*/
|
287 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-database.php';
|
288 |
|
289 |
/**
|
290 |
* The class responsible for sanitization of users input.
|
291 |
*/
|
292 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-sanitization.php';
|
293 |
|
294 |
/**
|
295 |
* The class responsible for XCloner system requirements validation.
|
296 |
*/
|
297 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-requirements.php';
|
298 |
|
299 |
/**
|
300 |
* The class responsible for XCloner backup archive creation.
|
301 |
*/
|
302 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-archive.php';
|
303 |
|
304 |
/**
|
305 |
* The class responsible for XCloner API requests.
|
306 |
*/
|
307 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-api.php';
|
308 |
|
309 |
/**
|
310 |
* The class responsible for the XCloner File System methods.
|
311 |
*/
|
312 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-file-system.php';
|
313 |
|
314 |
/**
|
315 |
* The class responsible for the XCloner File Transfer methods.
|
316 |
*/
|
317 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-file-transfer.php';
|
318 |
|
319 |
/**
|
320 |
* The class responsible for the XCloner Scheduler methods.
|
321 |
*/
|
322 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-scheduler.php';
|
323 |
+
|
324 |
+
/**
|
325 |
+
* The class responsible for the XCloner Encryption methods.
|
326 |
+
*/
|
327 |
+
require_once plugin_dir_path(dirname(__FILE__)).'includes/class-xcloner-encryption.php';
|
328 |
|
329 |
/**
|
330 |
* The class responsible for defining all actions that occur in the public-facing
|
331 |
* side of the site.
|
332 |
*/
|
333 |
+
require_once plugin_dir_path(dirname(__FILE__)).'public/class-xcloner-public.php';
|
334 |
|
335 |
$this->loader = new Xcloner_Loader($this);
|
336 |
|
349 |
|
350 |
$plugin_i18n = new Xcloner_i18n();
|
351 |
|
352 |
+
$this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain');
|
353 |
|
354 |
//wp_localize_script( 'ajax-script', 'my_ajax_object',
|
355 |
+
// array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
|
356 |
|
357 |
}
|
358 |
|
365 |
*/
|
366 |
private function define_admin_hooks() {
|
367 |
|
368 |
+
$plugin_admin = new Xcloner_Admin($this);
|
369 |
$this->plugin_admin = $plugin_admin;
|
370 |
|
371 |
+
$this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles');
|
372 |
+
$this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
|
373 |
|
374 |
+
add_action('backup_archive_finished', array($this, 'do_action_after_backup_finished'), 10, 2);
|
375 |
}
|
376 |
|
377 |
/**
|
380 |
* @access private
|
381 |
*
|
382 |
*/
|
383 |
+
private function define_admin_menu() {
|
384 |
|
385 |
add_action('admin_menu', array($this->loader, 'xcloner_backup_add_admin_menu'));
|
386 |
|
387 |
}
|
388 |
|
389 |
+
private function define_plugin_settings() {
|
390 |
/**
|
391 |
+
* register wporg_settings_init to the admin_init action hook
|
392 |
+
*/
|
393 |
|
394 |
$this->xcloner_settings = new XCloner_Settings($this);
|
395 |
|
396 |
+
if (defined('DOING_CRON') || isset($_POST['hash'])) {
|
397 |
|
398 |
+
if (defined('DOING_CRON') || $_POST['hash'] == "generate_hash") {
|
399 |
$this->xcloner_settings->generate_new_hash();
|
400 |
+
} else {
|
401 |
$this->xcloner_settings->set_hash($_POST['hash']);
|
402 |
}
|
403 |
}
|
404 |
|
405 |
+
if (defined('DOING_CRON') || !isset($_POST['hash']))
|
406 |
{
|
407 |
+
add_action('shutdown', function() {
|
408 |
+
$this->xcloner_filesystem = new Xcloner_File_System($this);
|
409 |
+
$this->xcloner_filesystem->remove_tmp_filesystem();
|
410 |
});
|
411 |
}
|
412 |
|
423 |
}
|
424 |
|
425 |
/*
|
426 |
+
* @method static $this get_xcloner_logger()
|
427 |
+
* @method static $this get_xcloner_settings()
|
428 |
* type = core|plugin|theme|translation
|
429 |
*/
|
430 |
public function pre_auto_update($type, $item, $context)
|
431 |
{
|
432 |
+
if (!$type)
|
433 |
{
|
434 |
return false;
|
435 |
}
|
436 |
|
437 |
+
$exclude_files = array();
|
438 |
+
$regex = "";
|
439 |
+
$data = "";
|
440 |
+
|
441 |
$this->get_xcloner_logger()->info(sprintf("Doing automatic backup before %s upgrade, pre_auto_update hook.", $type));
|
442 |
|
443 |
$content_dir = str_replace(ABSPATH, "", WP_CONTENT_DIR);
|
444 |
$plugins_dir = str_replace(ABSPATH, "", WP_PLUGIN_DIR);
|
445 |
+
$langs_dir = $content_dir.DS."languages";
|
446 |
+
$themes_dir = $content_dir.DS."themes";
|
447 |
|
448 |
+
switch ($type) {
|
449 |
case 'core':
|
450 |
$exclude_files = array(
|
451 |
"^(?!(wp-admin|wp-includes|(?!.*\/.*.php)))(.*)$",
|
455 |
|
456 |
$dir_array = explode(DS, $plugins_dir);
|
457 |
|
458 |
+
foreach ($dir_array as $dir)
|
459 |
{
|
460 |
$data .= "\/".$dir;
|
461 |
$regex .= $data."$|";
|
471 |
|
472 |
$dir_array = explode(DS, $themes_dir);
|
473 |
|
474 |
+
foreach ($dir_array as $dir)
|
475 |
{
|
476 |
$data .= "\/".$dir;
|
477 |
$regex .= $data."$|";
|
487 |
|
488 |
$dir_array = explode(DS, $langs_dir);
|
489 |
|
490 |
+
foreach ($dir_array as $dir)
|
491 |
{
|
492 |
$data .= "\/".$dir;
|
493 |
$regex .= $data."$|";
|
513 |
$schedule['backup_params']->email_notification = get_option('admin_email');
|
514 |
$schedule['backup_params']->backup_name = "backup_pre_auto_update_".$type."_[domain]-[time]-sql";
|
515 |
|
516 |
+
try {
|
517 |
$this->xcloner_scheduler->xcloner_scheduler_callback(0, $schedule);
|
518 |
+
}catch (Exception $e) {
|
519 |
$this->get_xcloner_logger()->error($e->getMessage());
|
520 |
}
|
521 |
|
530 |
*/
|
531 |
private function define_public_hooks() {
|
532 |
|
533 |
+
$plugin_public = new Xcloner_Public($this);
|
534 |
|
535 |
+
$this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_styles');
|
536 |
+
$this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts');
|
537 |
|
538 |
}
|
539 |
|
542 |
$logger = new XCloner_Logger($this, "php_system");
|
543 |
$error = error_get_last();
|
544 |
|
545 |
+
if ($error['type'] and $logger)
|
546 |
{
|
547 |
+
$logger->info($this->friendly_error_type($error['type']).": ".var_export($error, true));
|
548 |
}
|
549 |
|
550 |
}
|
551 |
|
552 |
+
public function friendly_error_type($type) {
|
553 |
+
static $levels = null;
|
554 |
+
if ($levels === null) {
|
555 |
+
$levels = [];
|
556 |
+
foreach (get_defined_constants() as $key=>$value) {
|
557 |
+
if (strpos($key, 'E_') !== 0) {continue; }
|
558 |
+
$levels[$value] = $key; //substr($key,2);
|
559 |
+
}
|
560 |
+
}
|
561 |
+
return (isset($levels[$type]) ? $levels[$type] : "Error #{$type}");
|
562 |
}
|
563 |
|
564 |
+
/**
|
565 |
+
* @method get_xcloner_settings()
|
566 |
+
* @throws Exception
|
567 |
+
*/
|
568 |
private function define_ajax_hooks()
|
569 |
{
|
570 |
//adding the pre-update hook
|
571 |
|
572 |
+
if (is_admin() || defined('DOING_CRON'))
|
573 |
{
|
574 |
+
$this->xcloner_logger = new XCloner_Logger($this, "xcloner_api");
|
575 |
+
$this->xcloner_filesystem = new Xcloner_File_System($this);
|
576 |
|
577 |
//$this->xcloner_filesystem->set_diff_timestamp_start (strtotime("-15 days"));
|
578 |
|
579 |
+
$this->archive_system = new Xcloner_Archive($this);
|
580 |
+
$this->xcloner_database = new Xcloner_Database($this);
|
581 |
+
$this->xcloner_scheduler = new Xcloner_Scheduler($this);
|
582 |
+
$this->xcloner_remote_storage = new Xcloner_Remote_Storage($this);
|
583 |
$this->xcloner_file_transfer = new Xcloner_File_Transfer($this);
|
584 |
+
$this->xcloner_encryption = new Xcloner_Encryption($this);
|
585 |
+
|
586 |
+
$xcloner_api = new Xcloner_Api($this);
|
587 |
+
|
588 |
+
add_action('wp_ajax_get_database_tables_action', array($xcloner_api, 'get_database_tables_action'));
|
589 |
+
add_action('wp_ajax_get_file_system_action', array($xcloner_api, 'get_file_system_action'));
|
590 |
+
add_action('wp_ajax_scan_filesystem', array($xcloner_api, 'scan_filesystem'));
|
591 |
+
add_action('wp_ajax_backup_database', array($xcloner_api, 'backup_database'));
|
592 |
+
add_action('wp_ajax_backup_files', array($xcloner_api, 'backup_files'));
|
593 |
+
add_action('wp_ajax_save_schedule', array($xcloner_api, 'save_schedule'));
|
594 |
+
add_action('wp_ajax_get_schedule_by_id', array($xcloner_api, 'get_schedule_by_id'));
|
595 |
+
add_action('wp_ajax_get_scheduler_list', array($xcloner_api, 'get_scheduler_list'));
|
596 |
+
add_action('wp_ajax_delete_schedule_by_id', array($xcloner_api, 'delete_schedule_by_id'));
|
597 |
+
add_action('wp_ajax_delete_backup_by_name', array($xcloner_api, 'delete_backup_by_name'));
|
598 |
+
add_action('wp_ajax_download_backup_by_name', array($xcloner_api, 'download_backup_by_name'));
|
599 |
+
add_action('wp_ajax_remote_storage_save_status', array($xcloner_api, 'remote_storage_save_status'));
|
600 |
+
add_action('wp_ajax_upload_backup_to_remote', array($xcloner_api, 'upload_backup_to_remote'));
|
601 |
+
add_action('wp_ajax_list_backup_files', array($xcloner_api, 'list_backup_files'));
|
602 |
+
add_action('wp_ajax_restore_upload_backup', array($xcloner_api, 'restore_upload_backup'));
|
603 |
+
add_action('wp_ajax_download_restore_script', array($xcloner_api, 'download_restore_script'));
|
604 |
+
add_action('wp_ajax_copy_backup_remote_to_local', array($xcloner_api, 'copy_backup_remote_to_local'));
|
605 |
+
add_action('wp_ajax_restore_backup', array($xcloner_api, 'restore_backup'));
|
606 |
+
add_action('wp_ajax_backup_encryption', array($xcloner_api, 'backup_encryption'));
|
607 |
+
add_action('wp_ajax_backup_decryption', array($xcloner_api, 'backup_decryption'));
|
608 |
+
add_action('wp_ajax_get_manage_backups_list', array($xcloner_api, 'get_manage_backups_list'));
|
609 |
+
add_action('admin_notices', array($this, 'xcloner_error_admin_notices'));
|
610 |
|
611 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
|
613 |
+
//Do a pre-update backup of targeted files
|
614 |
+
if ($this->get_xcloner_settings()->get_xcloner_option('xcloner_enable_pre_update_backup'))
|
615 |
+
{
|
616 |
add_action("pre_auto_update", array($this, "pre_auto_update"), 1, 3);
|
617 |
}
|
618 |
}
|
619 |
|
620 |
+
public function add_plugin_action_links($links, $file) {
|
621 |
+
if ($file == plugin_basename(dirname(dirname(__FILE__)).'/xcloner.php'))
|
622 |
{
|
623 |
$links[] = '<a href="admin.php?page=xcloner_settings_page">'.__('Settings', 'xcloner-backup-and-restore').'</a>';
|
624 |
$links[] = '<a href="admin.php?page=xcloner_generate_backups_page">'.__('Generate Backup', 'xcloner-backup-and-restore').'</a>';
|
625 |
}
|
626 |
|
627 |
+
return $links;
|
628 |
+
}
|
629 |
|
630 |
public function xcloner_error_admin_notices() {
|
631 |
+
settings_errors('xcloner_error_message');
|
632 |
}
|
633 |
|
634 |
+
/**
|
635 |
+
* @method get_xcloner_scheduler()
|
636 |
+
*/
|
637 |
public function define_cron_hooks()
|
638 |
{
|
639 |
//registering new schedule intervals
|
640 |
+
add_filter('cron_schedules', array($this, 'add_new_intervals'));
|
641 |
|
642 |
|
643 |
$xcloner_scheduler = $this->get_xcloner_scheduler();
|
645 |
|
646 |
}
|
647 |
|
648 |
+
/**
|
649 |
+
* @param $schedules
|
650 |
+
* @return mixed
|
651 |
+
*/
|
652 |
+
public function add_new_intervals($schedules)
|
653 |
{
|
654 |
//weekly scheduler interval
|
655 |
$schedules['weekly'] = array(
|
703 |
return $this->loader;
|
704 |
}
|
705 |
|
706 |
+
public function xcloner_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
707 |
{
|
708 |
// check user capabilities
|
709 |
+
if (!current_user_can('manage_options')) {
|
710 |
+
return;
|
711 |
+
}
|
712 |
|
713 |
$page = sanitize_key($_GET['page']);
|
714 |
|
715 |
+
if ($page)
|
716 |
{
|
717 |
$this->display($page);
|
718 |
}
|
public/class-xcloner-public.php
CHANGED
@@ -45,10 +45,8 @@ class Xcloner_Public {
|
|
45 |
*
|
46 |
* @since 1.0.0
|
47 |
*
|
48 |
-
* @param string $plugin_name The name of the plugin.
|
49 |
-
* @param string $version The version of this plugin.
|
50 |
*/
|
51 |
-
public function __construct(
|
52 |
|
53 |
$this->plugin_name = $xcloner_container->get_plugin_name();
|
54 |
$this->version = $xcloner_container->get_version();
|
@@ -74,7 +72,7 @@ class Xcloner_Public {
|
|
74 |
* class.
|
75 |
*/
|
76 |
|
77 |
-
wp_enqueue_style(
|
78 |
|
79 |
}
|
80 |
|
@@ -97,7 +95,7 @@ class Xcloner_Public {
|
|
97 |
* class.
|
98 |
*/
|
99 |
|
100 |
-
wp_enqueue_script(
|
101 |
|
102 |
}
|
103 |
|
45 |
*
|
46 |
* @since 1.0.0
|
47 |
*
|
|
|
|
|
48 |
*/
|
49 |
+
public function __construct(Xcloner $xcloner_container) {
|
50 |
|
51 |
$this->plugin_name = $xcloner_container->get_plugin_name();
|
52 |
$this->version = $xcloner_container->get_version();
|
72 |
* class.
|
73 |
*/
|
74 |
|
75 |
+
wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__).'css/xcloner-public.css', array(), $this->version, 'all');
|
76 |
|
77 |
}
|
78 |
|
95 |
* class.
|
96 |
*/
|
97 |
|
98 |
+
wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__).'js/xcloner-public.js', array('jquery'), $this->version, false);
|
99 |
|
100 |
}
|
101 |
|
restore/xcloner_restore.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if(!defined('AUTH_KEY'))
|
4 |
{
|
5 |
define('AUTH_KEY', '');
|
6 |
}
|
7 |
|
8 |
-
if(!defined("DS"))
|
9 |
{
|
10 |
define("DS", DIRECTORY_SEPARATOR);
|
11 |
}
|
12 |
|
13 |
-
if(!defined('XCLONER_PLUGIN_ACCESS') || XCLONER_PLUGIN_ACCESS != 1)
|
14 |
{
|
15 |
-
if(!AUTH_KEY)
|
16 |
{
|
17 |
Xcloner_Restore::send_response("404", "Could not run restore script, AUTH_KEY not set!");
|
18 |
exit;
|
19 |
}
|
20 |
|
21 |
-
if(!isset($_REQUEST['hash']))
|
22 |
{
|
23 |
Xcloner_Restore::send_response("404", "Could not run restore script, sent HASH is empty!");
|
24 |
exit;
|
25 |
}
|
26 |
|
27 |
-
if($_REQUEST['hash'] != AUTH_KEY)
|
28 |
{
|
29 |
Xcloner_Restore::send_response("404", "Could not run restore script, AUTH_KEY doesn't match the sent HASH!");
|
30 |
exit;
|
@@ -32,28 +32,28 @@ if(!defined('XCLONER_PLUGIN_ACCESS') || XCLONER_PLUGIN_ACCESS != 1)
|
|
32 |
}
|
33 |
|
34 |
//check minimum PHP version
|
35 |
-
if(version_compare(phpversion(), Xcloner_Restore::xcloner_minimum_version, '<'))
|
36 |
{
|
37 |
-
Xcloner_Restore::send_response(500, sprintf(("XCloner requires minimum PHP version %s in order to run correctly. We have detected your version as %s"),Xcloner_Restore::xcloner_minimum_version, phpversion())
|
38 |
exit;
|
39 |
|
40 |
}
|
41 |
|
42 |
-
$file = dirname(
|
43 |
|
44 |
-
if(file_exists($file))
|
45 |
{
|
46 |
|
47 |
require_once($file);
|
48 |
}
|
49 |
-
elseif(file_exists("vendor.phar") and extension_loaded('phar'))
|
50 |
{
|
51 |
require_once(__DIR__.DS."vendor.phar");
|
52 |
-
}else{
|
53 |
|
54 |
-
$file = dirname(
|
55 |
|
56 |
-
if(!file_exists($file))
|
57 |
{
|
58 |
Xcloner_Restore::send_response("404", "File $file does not exists, please extract the vendor.tgz archive on the server or enable PHP Phar module!");
|
59 |
exit;
|
@@ -78,16 +78,16 @@ use Monolog\Handler\StreamHandler;
|
|
78 |
|
79 |
//do not modify below
|
80 |
$that = "";
|
81 |
-
if(defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
82 |
{
|
83 |
$that = $this;
|
84 |
}
|
85 |
$xcloner_restore = new Xcloner_Restore($that);
|
86 |
|
87 |
-
try{
|
88 |
$return = $xcloner_restore->init();
|
89 |
$xcloner_restore->send_response(200, $return);
|
90 |
-
}catch(Exception $e){
|
91 |
$xcloner_restore->send_response(417, $e->getMessage());
|
92 |
}
|
93 |
|
@@ -96,27 +96,34 @@ class Xcloner_Restore
|
|
96 |
|
97 |
const xcloner_minimum_version = "5.4.0";
|
98 |
|
99 |
-
private $backup_archive_extensions
|
100 |
-
private $process_files_limit
|
101 |
-
private $process_files_limit_list
|
102 |
-
private $process_mysql_records_limit
|
103 |
private $adapter;
|
104 |
private $filesystem;
|
105 |
private $logger;
|
106 |
private $backup_storage_dir;
|
107 |
private $parent_api;
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
public function __construct($parent_api = "")
|
111 |
{
|
112 |
register_shutdown_function(array($this, 'exception_handler'));
|
113 |
|
114 |
-
if(defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
115 |
{
|
116 |
$dir = $parent_api->get_xcloner_container()->get_xcloner_settings()->get_xcloner_store_path();
|
117 |
}
|
118 |
|
119 |
-
if(!isset($dir) || !$dir){
|
120 |
$dir = dirname(__FILE__);
|
121 |
}
|
122 |
|
@@ -124,7 +131,7 @@ class Xcloner_Restore
|
|
124 |
|
125 |
$this->backup_storage_dir = $dir;
|
126 |
|
127 |
-
$this->adapter = new Local($dir
|
128 |
$this->filesystem = new Filesystem($this->adapter, new Config([
|
129 |
'disable_asserts' => true,
|
130 |
]));
|
@@ -133,52 +140,65 @@ class Xcloner_Restore
|
|
133 |
|
134 |
$logger_path = $this->get_logger_filename();
|
135 |
|
136 |
-
if(!is_writeable($logger_path) and !touch($logger_path))
|
137 |
{
|
138 |
$logger_path = "php://stderr";
|
139 |
}
|
140 |
|
141 |
$this->logger->pushHandler(new StreamHandler($logger_path, Logger::DEBUG));
|
142 |
|
143 |
-
if(isset($_POST['API_ID'])){
|
144 |
-
$this->logger->info("Processing ajax request ID ".substr(filter_input(INPUT_POST, 'API_ID', FILTER_SANITIZE_STRING), 0
|
145 |
}
|
146 |
|
147 |
}
|
148 |
-
|
|
|
|
|
|
|
149 |
public function exception_handler() {
|
150 |
|
151 |
$error = error_get_last();
|
152 |
|
153 |
-
if($error['type'] and $this->logger)
|
154 |
{
|
155 |
-
$this->logger->info($this->friendly_error_type
|
156 |
}
|
157 |
|
158 |
}
|
159 |
-
|
|
|
|
|
|
|
|
|
160 |
private function friendly_error_type($type) {
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
$levels[$value]= $key; //substr($key,2);
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
}
|
171 |
|
172 |
public function get_logger_filename()
|
173 |
{
|
174 |
-
$filename = $this->backup_storage_dir
|
175 |
|
176 |
return $filename;
|
177 |
}
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
public function init()
|
180 |
{
|
181 |
-
if(isset($_POST['xcloner_action']) and $_POST['xcloner_action'])
|
182 |
{
|
183 |
$method = filter_input(INPUT_POST, 'xcloner_action', FILTER_SANITIZE_STRING);
|
184 |
|
@@ -186,53 +206,64 @@ class Xcloner_Restore
|
|
186 |
|
187 |
$method .= "_action";
|
188 |
|
189 |
-
if(method_exists($this, $method))
|
190 |
{
|
191 |
$this->logger->debug(sprintf('Starting action %s', $method));
|
192 |
return call_user_func(array($this, $method));
|
193 |
|
194 |
-
}else{
|
195 |
-
throw new Exception($method
|
196 |
}
|
197 |
}
|
198 |
|
199 |
return $this->check_system();
|
200 |
}
|
201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
public function write_file_action()
|
203 |
{
|
204 |
-
if(isset($_POST['file']))
|
205 |
{
|
206 |
$target_file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING);
|
207 |
|
208 |
-
if(!$_POST['start'])
|
209 |
$fp = fopen($target_file, "wb+");
|
210 |
else
|
211 |
$fp = fopen($target_file, "ab+");
|
212 |
|
213 |
-
if(!$fp)
|
214 |
throw new Exception("Unable to open $target_file file for writing");
|
215 |
|
216 |
fseek($fp, $_POST['start']);
|
217 |
|
218 |
-
if(isset($_FILES['blob']))
|
219 |
{
|
220 |
$this->logger->debug(sprintf('Writing %s bytes to file %s starting position %s using FILES blob', filesize($_FILES['blob']['tmp_name']), $target_file, $_POST['start']));
|
221 |
|
222 |
$blob = file_get_contents($_FILES['blob']['tmp_name']);
|
223 |
|
224 |
-
if(!$bytes_written = fwrite($fp, $blob))
|
225 |
throw new Exception("Unable to write data to file $target_file");
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
229 |
$this->logger->debug(sprintf('Writing %s bytes to file %s starting position %s using POST blob', strlen($_POST['blob']), $target_file, $_POST['start']));
|
230 |
|
231 |
$blob = $_POST['blob'];
|
232 |
|
233 |
-
if(!$bytes_written = fwrite($fp, $blob))
|
234 |
throw new Exception("Unable to write data to file $target_file");
|
235 |
-
}else{
|
236 |
throw new Exception("Upload failed, did not receive any binary data");
|
237 |
}
|
238 |
|
@@ -242,39 +273,54 @@ class Xcloner_Restore
|
|
242 |
return $bytes_written;
|
243 |
|
244 |
}
|
245 |
-
|
246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
{
|
248 |
$this->logger->info(sprintf('Connecting to mysql database %s with %s@%s', $remote_mysql_db, $remote_mysql_user, $remote_mysql_host));
|
249 |
|
250 |
$mysqli = new mysqli($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
251 |
|
252 |
if ($mysqli->connect_error) {
|
253 |
-
throw new Exception('Connect Error ('
|
254 |
. $mysqli->connect_error);
|
255 |
}
|
256 |
|
257 |
$mysqli->query("SET sql_mode='';");
|
258 |
$mysqli->query("SET foreign_key_checks = 0;");
|
259 |
-
if(isset($_REQUEST['charset_of_file']) and $_REQUEST['charset_of_file'])
|
260 |
$mysqli->query("SET NAMES ".$_REQUEST['charset_of_file']."");
|
261 |
else
|
262 |
$mysqli->query("SET NAMES utf8;");
|
263 |
|
264 |
return $mysqli;
|
265 |
}
|
266 |
-
|
|
|
|
|
|
|
|
|
|
|
267 |
public function restore_mysql_backup_action()
|
268 |
{
|
269 |
-
$mysqldump_file
|
270 |
-
$remote_path
|
271 |
$remote_mysql_user = filter_input(INPUT_POST, 'remote_mysql_user', FILTER_SANITIZE_STRING);
|
272 |
$remote_mysql_pass = filter_input(INPUT_POST, 'remote_mysql_pass', FILTER_SANITIZE_STRING);
|
273 |
-
$remote_mysql_db
|
274 |
$remote_mysql_host = filter_input(INPUT_POST, 'remote_mysql_host', FILTER_SANITIZE_STRING);
|
275 |
-
$execute_query
|
276 |
-
$error_line
|
277 |
-
$start
|
278 |
|
279 |
$wp_home_url = filter_input(INPUT_POST, 'wp_home_url', FILTER_SANITIZE_STRING);
|
280 |
$remote_restore_url = filter_input(INPUT_POST, 'remote_restore_url', FILTER_SANITIZE_STRING);
|
@@ -284,8 +330,8 @@ class Xcloner_Restore
|
|
284 |
|
285 |
$mysql_backup_file = $remote_path.DS.$mysqldump_file;
|
286 |
|
287 |
-
if(!file_exists($mysql_backup_file))
|
288 |
-
throw new Exception(sprintf("Mysql backup file %s does not exists"
|
289 |
|
290 |
|
291 |
/*if(defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
@@ -299,17 +345,18 @@ class Xcloner_Restore
|
|
299 |
}*/
|
300 |
|
301 |
{
|
302 |
-
$mysqli = $this->mysql_connect($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db
|
303 |
}
|
304 |
|
305 |
$line_count = 0;
|
306 |
$query = "";
|
|
|
307 |
$return['finished'] = 1;
|
308 |
$return['backup_file'] = $mysqldump_file;
|
309 |
$return['backup_size'] = filesize($mysql_backup_file);
|
310 |
|
311 |
$fp = fopen($mysql_backup_file, "r");
|
312 |
-
if($fp)
|
313 |
{
|
314 |
$this->logger->info(sprintf("Opening mysql dump file %s at position %s.", $mysql_backup_file, $start));
|
315 |
fseek($fp, $start);
|
@@ -317,49 +364,49 @@ class Xcloner_Restore
|
|
317 |
// process the line read.
|
318 |
|
319 |
//check if line is comment
|
320 |
-
if(substr($line, 0, 1) == "#")
|
321 |
continue;
|
322 |
|
323 |
//check if line is empty
|
324 |
-
if($line == "\n" or trim($line) == "")
|
325 |
continue;
|
326 |
|
327 |
-
if(substr($line, strlen($line)-2, strlen($line)) == ";\n")
|
328 |
$query .= $line;
|
329 |
-
else{
|
330 |
$query .= $line;
|
331 |
continue;
|
332 |
}
|
333 |
|
334 |
-
if($execute_query)
|
335 |
{
|
336 |
-
$query
|
337 |
$execute_query = "";
|
338 |
}
|
339 |
|
340 |
//Doing serialized url replace here
|
341 |
|
342 |
-
if($wp_site_url and $wp_home_url and strlen($wp_home_url) < strlen($wp_site_url))
|
343 |
{
|
344 |
-
list($wp_home_url
|
345 |
-
list($remote_restore_url
|
346 |
|
347 |
}
|
348 |
|
349 |
-
if($wp_home_url and $remote_restore_url and strpos($query, $wp_home_url) !== false)
|
350 |
{
|
351 |
$query = $this->url_replace($wp_home_url, $remote_restore_url, $query);
|
352 |
}
|
353 |
|
354 |
-
if($wp_site_url and $restore_site_url and strpos($query, $wp_site_url) !== false)
|
355 |
{
|
356 |
$query = $this->url_replace($wp_site_url, $restore_site_url, $query);
|
357 |
}
|
358 |
|
359 |
-
if(!$mysqli->query($query) && !stristr($mysqli->error,"Duplicate entry"))
|
360 |
{
|
361 |
//$return['error_line'] = $line_count;
|
362 |
-
$return['start'] = ftell($fp)-strlen($line);
|
363 |
$return['query_error'] = true;
|
364 |
$return['query'] = $query;
|
365 |
$return['message'] = sprintf("Mysql Error: %s\n", $mysqli->error);
|
@@ -376,36 +423,44 @@ class Xcloner_Restore
|
|
376 |
$line_count++;
|
377 |
|
378 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
}
|
380 |
|
381 |
-
$return['start'] = ftell($fp);
|
382 |
-
|
383 |
-
$this->logger->info(sprintf("Executed %s queries of size %s bytes", $line_count, ($return['start']-$start)));
|
384 |
-
|
385 |
-
if(!feof($fp))
|
386 |
-
{
|
387 |
-
$return['finished'] = 0;
|
388 |
-
}else{
|
389 |
-
$this->logger->info(sprintf("Mysql Import Done."));
|
390 |
-
}
|
391 |
-
|
392 |
-
fclose($fp);
|
393 |
-
|
394 |
$this->send_response(200, $return);
|
395 |
}
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
private function url_replace($search, $replace, $query)
|
398 |
{
|
399 |
$this->logger->info(sprintf("Doing url replace on query with length %s", strlen($query)), array("QUERY_REPLACE"));
|
400 |
$query = str_replace($search, $replace, $query);
|
401 |
$original_query = $query;
|
402 |
|
403 |
-
if($this->has_serialized($query))
|
404 |
{
|
405 |
$this->logger->info(sprintf("Query contains serialized data, doing serialized size fix"), array("QUERY_REPLACE"));
|
406 |
$query = $this->do_serialized_fix($query);
|
407 |
|
408 |
-
if(!$query)
|
409 |
{
|
410 |
$this->logger->info(sprintf("Serialization probably failed here..."), array("QUERY_REPLACE"));
|
411 |
$query = $original_query;
|
@@ -415,43 +470,48 @@ class Xcloner_Restore
|
|
415 |
|
416 |
return $query;
|
417 |
}
|
418 |
-
|
|
|
|
|
|
|
|
|
|
|
419 |
public function list_backup_files_action()
|
420 |
{
|
421 |
$backup_parts = array();
|
422 |
|
423 |
$source_backup_file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING);
|
424 |
-
$start
|
425 |
-
$return['part']
|
426 |
|
427 |
$backup_file = $source_backup_file;
|
428 |
|
429 |
-
if($this->is_multipart($backup_file))
|
430 |
{
|
431 |
$backup_parts = $this->get_multipart_files($backup_file);
|
432 |
$backup_file = $backup_parts[$return['part']];
|
433 |
}
|
434 |
|
435 |
-
try{
|
436 |
$tar = new Tar();
|
437 |
$tar->open($this->backup_storage_dir.DS.$backup_file, $start);
|
438 |
|
439 |
$data = $tar->contents($this->process_files_limit_list);
|
440 |
-
}catch(Exception $e)
|
441 |
{
|
442 |
$return['error'] = true;
|
443 |
$return['message'] = $e->getMessage();
|
444 |
$this->send_response(200, $return);
|
445 |
}
|
446 |
|
447 |
-
$return['files']
|
448 |
-
$return['finished']
|
449 |
-
$return['total_size']
|
450 |
$i = 0;
|
451 |
|
452 |
-
if(isset($data['extracted_files']) and is_array($data['extracted_files']))
|
453 |
{
|
454 |
-
foreach($data['extracted_files'] as $file)
|
455 |
{
|
456 |
$return['files'][$i]['path'] = $file->getPath();
|
457 |
$return['files'][$i]['size'] = $file->getSize();
|
@@ -461,18 +521,18 @@ class Xcloner_Restore
|
|
461 |
}
|
462 |
}
|
463 |
|
464 |
-
if(isset($data['start']))
|
465 |
{
|
466 |
$return['start'] = $data['start'];
|
467 |
$return['finished'] = 0;
|
468 |
-
}else{
|
469 |
-
if($this->is_multipart($source_backup_file))
|
470 |
{
|
471 |
$return['start'] = 0;
|
472 |
|
473 |
++$return['part'];
|
474 |
|
475 |
-
if($return['part'] < sizeof($backup_parts))
|
476 |
$return['finished'] = 0;
|
477 |
|
478 |
}
|
@@ -480,7 +540,12 @@ class Xcloner_Restore
|
|
480 |
|
481 |
$this->send_response(200, $return);
|
482 |
}
|
483 |
-
|
|
|
|
|
|
|
|
|
|
|
484 |
public function restore_finish_action()
|
485 |
{
|
486 |
$remote_path = filter_input(INPUT_POST, 'remote_path', FILTER_SANITIZE_STRING);
|
@@ -490,28 +555,28 @@ class Xcloner_Restore
|
|
490 |
|
491 |
$remote_mysql_user = filter_input(INPUT_POST, 'remote_mysql_user', FILTER_SANITIZE_STRING);
|
492 |
$remote_mysql_pass = filter_input(INPUT_POST, 'remote_mysql_pass', FILTER_SANITIZE_STRING);
|
493 |
-
$remote_mysql_db
|
494 |
$remote_mysql_host = filter_input(INPUT_POST, 'remote_mysql_host', FILTER_SANITIZE_STRING);
|
495 |
|
496 |
-
$update_remote_site_url
|
497 |
-
$delete_restore_script
|
498 |
-
$delete_backup_temporary_folder
|
499 |
|
500 |
-
if($update_remote_site_url)
|
501 |
{
|
502 |
-
$mysqli = $this->mysql_connect($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db
|
503 |
$this->update_wp_config($remote_path, $remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
504 |
$this->update_wp_url($remote_path, $remote_restore_url, $mysqli);
|
505 |
}
|
506 |
|
507 |
-
if($delete_backup_temporary_folder)
|
508 |
{
|
509 |
$this->delete_backup_temporary_folder($remote_path);
|
510 |
}
|
511 |
|
512 |
-
if(!defined('XCLONER_PLUGIN_ACCESS') || XCLONER_PLUGIN_ACCESS != 1)
|
513 |
{
|
514 |
-
if($delete_restore_script)
|
515 |
{
|
516 |
$this->delete_self();
|
517 |
}
|
@@ -520,10 +585,16 @@ class Xcloner_Restore
|
|
520 |
$return = "Restore Process Finished.";
|
521 |
$this->send_response(200, $return);
|
522 |
}
|
523 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
524 |
private function delete_backup_temporary_folder($remote_path)
|
525 |
{
|
526 |
-
$this->target_adapter = new Local($remote_path
|
527 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
528 |
'disable_asserts' => true,
|
529 |
]));
|
@@ -531,13 +602,13 @@ class Xcloner_Restore
|
|
531 |
$mysqldump_list = array();
|
532 |
$list = $this->target_filesystem->listContents();
|
533 |
|
534 |
-
foreach($list as $file)
|
535 |
{
|
536 |
$matches = array();
|
537 |
|
538 |
-
if($file['type'] == "dir")
|
539 |
{
|
540 |
-
if(preg_match("/xcloner-(\w*)/", $file['basename'], $matches)){
|
541 |
$this->logger->info(sprintf('Deleting temporary folder %s', $file['path']));
|
542 |
$this->target_filesystem->deleteDir($file['path']);
|
543 |
}
|
@@ -547,50 +618,63 @@ class Xcloner_Restore
|
|
547 |
return true;
|
548 |
|
549 |
}
|
550 |
-
|
|
|
|
|
|
|
|
|
|
|
551 |
private function delete_self()
|
552 |
{
|
553 |
-
if($this->filesystem->has("vendor.phar"))
|
554 |
{
|
555 |
$this->logger->info(sprintf('Deleting vendor.phar'));
|
556 |
$this->filesystem->delete("vendor.phar");
|
557 |
}
|
558 |
-
if($this->filesystem->has("vendor"))
|
559 |
{
|
560 |
$this->logger->info(sprintf('Deleting vendor folder'));
|
561 |
$this->filesystem->deleteDir("vendor");
|
562 |
}
|
563 |
-
if($this->filesystem->has("xcloner_restore.php"))
|
564 |
{
|
565 |
$this->logger->info(sprintf('Deleting xcloner_restore.php'));
|
566 |
$this->filesystem->delete("xcloner_restore.php");
|
567 |
}
|
568 |
|
569 |
-
if($this->filesystem->has("xcloner_restore.log"))
|
570 |
{
|
571 |
$this->logger->info(sprintf('Deleting xcloner_restore.log'));
|
572 |
$this->filesystem->delete("xcloner_restore.log");
|
573 |
}
|
574 |
|
575 |
-
if($this->filesystem->has($this->get_logger_filename()))
|
576 |
{
|
577 |
$this->logger->info(sprintf('Deleting logger file %s', $this->get_logger_filename()));
|
578 |
$this->filesystem->delete($this->get_logger_filename());
|
579 |
}
|
580 |
|
581 |
}
|
582 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
private function update_wp_url($wp_path, $url, $mysqli)
|
584 |
{
|
585 |
$wp_config = $wp_path.DS."wp-config.php";
|
586 |
|
587 |
$this->logger->info(sprintf('Updating site url to %s', $url));
|
588 |
|
589 |
-
if(file_exists($wp_config))
|
590 |
{
|
591 |
$config = file_get_contents($wp_config);
|
592 |
preg_match("/.*table_prefix.*=.*'(.*)'/i", $config, $matches);
|
593 |
-
if(isset($matches[1]))
|
594 |
$table_prefix = $matches[1];
|
595 |
else
|
596 |
throw new Exception("Could not load wordpress table prefix from wp-config.php file.");
|
@@ -598,20 +682,31 @@ class Xcloner_Restore
|
|
598 |
else
|
599 |
throw new Exception("Could not update the SITEURL and HOME, wp-config.php file not found");
|
600 |
|
601 |
-
if(!$mysqli->query("update ".$table_prefix."options set option_value='".($url)."' where option_name='home'"))
|
602 |
throw new Exception(sprintf("Could not update the HOME option, error: %s\n", $mysqli->error));
|
603 |
|
604 |
-
if(!$mysqli->query("update ".$table_prefix."options set option_value='".($url)."' where option_name='siteurl'"))
|
605 |
throw new Exception(sprintf("Could not update the SITEURL option, error: %s\n", $mysqli->error));
|
606 |
|
607 |
return true;
|
608 |
}
|
609 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
610 |
private function update_wp_config($remote_path, $remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db)
|
611 |
{
|
612 |
$wp_config = $remote_path.DS."wp-config.php";
|
613 |
|
614 |
-
if(!file_exists($wp_config))
|
615 |
{
|
616 |
throw new Exception("Could not find the wp-config.php in ".$remote_path);
|
617 |
}
|
@@ -629,7 +724,7 @@ class Xcloner_Restore
|
|
629 |
|
630 |
$this->logger->info(sprintf('Updating wp-config.php file with the new mysql details'));
|
631 |
|
632 |
-
if(!file_put_contents($wp_config, $content))
|
633 |
throw new Exception("Could not write updated config data to ".$wp_config);
|
634 |
|
635 |
chmod($wp_config, $file_perms);
|
@@ -637,7 +732,11 @@ class Xcloner_Restore
|
|
637 |
return $wp_config;
|
638 |
|
639 |
}
|
640 |
-
|
|
|
|
|
|
|
|
|
641 |
public function list_mysqldump_backups_action()
|
642 |
{
|
643 |
$source_backup_file = filter_input(INPUT_POST, 'backup_file', FILTER_SANITIZE_STRING);
|
@@ -645,7 +744,7 @@ class Xcloner_Restore
|
|
645 |
|
646 |
$hash = $this->get_hash_from_backup($source_backup_file);
|
647 |
|
648 |
-
$this->target_adapter = new Local($remote_path
|
649 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
650 |
'disable_asserts' => true,
|
651 |
]));
|
@@ -653,25 +752,25 @@ class Xcloner_Restore
|
|
653 |
$mysqldump_list = array();
|
654 |
$list = $this->target_filesystem->listContents();
|
655 |
|
656 |
-
foreach($list as $file)
|
657 |
{
|
658 |
$matches = array();
|
659 |
|
660 |
-
if($file['type'] == "dir")
|
661 |
{
|
662 |
-
if(preg_match("/xcloner-(\w*)/", $file['basename'], $matches))
|
663 |
{
|
664 |
$files = $this->target_filesystem->listContents($file['basename']);
|
665 |
-
foreach($files as $file)
|
666 |
{
|
667 |
-
if($file['extension'] == "sql")
|
668 |
{
|
669 |
$this->logger->info(sprintf('Found %s mysql backup file', $file['path']));
|
670 |
$mysqldump_list[$file['path']]['path'] = $file['path'];
|
671 |
$mysqldump_list[$file['path']]['size'] = $file['size'];
|
672 |
-
$mysqldump_list[$file['path']]['timestamp'] = date("d M,Y H:i"
|
673 |
|
674 |
-
if($hash and $hash == $matches[1])
|
675 |
$mysqldump_list[$file['path']]['selected'] = "selected";
|
676 |
else
|
677 |
$mysqldump_list[$file['path']]['selected'] = "";
|
@@ -681,25 +780,36 @@ class Xcloner_Restore
|
|
681 |
}
|
682 |
}
|
683 |
|
684 |
-
$this->sort_by($mysqldump_list, 'timestamp','desc');
|
685 |
$return['files'] = $mysqldump_list;
|
686 |
|
687 |
$this->send_response(200, $return);
|
688 |
}
|
689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
private function get_hash_from_backup($backup_file)
|
691 |
{
|
692 |
-
if(!$backup_file)
|
693 |
return false;
|
694 |
|
695 |
-
$result = preg_match("/-(\w*)./", substr($backup_file, strlen($backup_file)-10, strlen($backup_file)), $matches)
|
696 |
|
697 |
-
if($result and isset($matches[1]))
|
698 |
return ($matches[1]);
|
699 |
|
700 |
return false;
|
701 |
}
|
702 |
-
|
|
|
|
|
|
|
|
|
|
|
703 |
public function list_backup_archives_action()
|
704 |
{
|
705 |
$local_backup_file = filter_input(INPUT_POST, 'local_backup_file', FILTER_SANITIZE_STRING);
|
@@ -708,18 +818,18 @@ class Xcloner_Restore
|
|
708 |
$backup_files = array();
|
709 |
$parents = array();
|
710 |
|
711 |
-
foreach($list as $file_info)
|
712 |
{
|
713 |
$data = array();
|
714 |
|
715 |
-
if(isset($file_info['extension']) and $file_info['extension'] == "csv")
|
716 |
{
|
717 |
$lines = explode(PHP_EOL, $this->filesystem->read($file_info['path']));
|
718 |
-
foreach($lines as $line)
|
719 |
-
if($line)
|
720 |
{
|
721 |
$data = str_getcsv($line);
|
722 |
-
if(is_array($data)){
|
723 |
$parents[$data[0]] = $file_info['path'];
|
724 |
$file_info['childs'][] = $data;
|
725 |
$file_info['size'] += $data[2];
|
@@ -728,19 +838,19 @@ class Xcloner_Restore
|
|
728 |
|
729 |
}
|
730 |
|
731 |
-
if($file_info['type'] == 'file' and isset($file_info['extension']) and in_array($file_info['extension'], $this->backup_archive_extensions))
|
732 |
$backup_files[$file_info['path']] = $file_info;
|
733 |
}
|
734 |
|
735 |
$new_list = array();
|
736 |
|
737 |
-
foreach($backup_files as $key=>$file_info)
|
738 |
{
|
739 |
-
if(isset($parents[$file_info['path']]))
|
740 |
$backup_files[$key]['parent'] = $parents[$file_info['path']];
|
741 |
-
else{
|
742 |
|
743 |
-
if($local_backup_file and ($file_info['basename'] == $local_backup_file))
|
744 |
$file_info['selected'] = 'selected';
|
745 |
|
746 |
$this->logger->info(sprintf('Found %s backup file', $file_info['path']));
|
@@ -750,25 +860,31 @@ class Xcloner_Restore
|
|
750 |
|
751 |
}
|
752 |
|
753 |
-
$this->sort_by($new_list, "timestamp","desc");
|
754 |
|
755 |
$return['files'] = $new_list;
|
756 |
|
757 |
$this->send_response(200, $return);
|
758 |
|
759 |
}
|
760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
public function restore_backup_to_path_action()
|
762 |
{
|
763 |
-
$source_backup_file
|
764 |
-
$remote_path
|
765 |
$include_filter_files = filter_input(INPUT_POST, 'filter_files', FILTER_SANITIZE_STRING);
|
766 |
$exclude_filter_files = "";
|
767 |
-
$start
|
768 |
-
$return['part']
|
769 |
$return['processed'] = (int)filter_input(INPUT_POST, 'processed', FILTER_SANITIZE_NUMBER_INT);
|
770 |
|
771 |
-
$this->target_adapter = new Local($remote_path
|
772 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
773 |
'disable_asserts' => true,
|
774 |
]));
|
@@ -780,82 +896,112 @@ class Xcloner_Restore
|
|
780 |
$return['total_size'] = $this->get_backup_size($backup_file);
|
781 |
|
782 |
$backup_archive = new Tar();
|
783 |
-
if($this->is_multipart($backup_file))
|
784 |
{
|
785 |
-
if(!$return['part'])
|
786 |
$return['processed'] += $this->filesystem->getSize($backup_file);
|
787 |
|
788 |
$backup_parts = $this->get_multipart_files($backup_file);
|
789 |
$backup_file = $backup_parts[$return['part']];
|
790 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
791 |
|
792 |
$this->logger->info(sprintf('Opening backup archive %s at position %s', $backup_file, $start));
|
793 |
-
$backup_archive->open($this->backup_storage_dir
|
794 |
|
795 |
-
$data = $backup_archive->extract($remote_path, ''
|
796 |
|
797 |
-
if(isset($data['extracted_files']))
|
798 |
{
|
799 |
-
foreach($data['extracted_files'] as $spl_fileinfo)
|
800 |
{
|
801 |
$this->logger->info(sprintf('Extracted %s file', $spl_fileinfo->getPath()));
|
802 |
$return['extracted_files'][] = $spl_fileinfo->getPath()." (".$spl_fileinfo->getSize()." bytes)";
|
803 |
}
|
804 |
}
|
805 |
|
806 |
-
if(isset($data['start']))
|
807 |
//if(isset($data['start']) and $data['start'] <= $this->filesystem->getSize($backup_file))
|
808 |
{
|
809 |
$return['finished'] = 0;
|
810 |
$return['start'] = $data['start'];
|
811 |
-
}else{
|
812 |
|
813 |
$return['processed'] += $start;
|
814 |
|
815 |
-
if($this->is_multipart($source_backup_file))
|
816 |
{
|
817 |
$return['start'] = 0;
|
818 |
|
819 |
++$return['part'];
|
820 |
|
821 |
-
if($return['part'] < sizeof($backup_parts))
|
822 |
$return['finished'] = 0;
|
823 |
|
824 |
}
|
825 |
}
|
826 |
|
827 |
-
if($return['finished'])
|
828 |
$this->logger->info(sprintf('Done extracting %s', $source_backup_file));
|
829 |
|
830 |
$return['backup_file'] = $backup_file;
|
831 |
|
832 |
$this->send_response(200, $return);
|
833 |
}
|
834 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
835 |
public function get_current_directory_action()
|
836 |
{
|
837 |
global $wpdb;
|
838 |
|
839 |
$restore_script_url = filter_input(INPUT_POST, 'restore_script_url', FILTER_SANITIZE_STRING);
|
840 |
|
841 |
-
$pathinfo = pathinfo(
|
842 |
|
843 |
$suffix = "";
|
844 |
$return['remote_mysql_host'] = "localhost";
|
845 |
$return['remote_mysql_user'] = "";
|
846 |
$return['remote_mysql_pass'] = "";
|
847 |
-
$return['remote_mysql_db']
|
848 |
|
849 |
-
if(defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
850 |
{
|
851 |
$return['dir'] = realpath(get_home_path().DS.$suffix);
|
852 |
-
$return['restore_script_url']
|
853 |
$return['remote_mysql_host'] = $wpdb->dbhost;
|
854 |
$return['remote_mysql_user'] = $wpdb->dbuser;
|
855 |
$return['remote_mysql_pass'] = $wpdb->dbpassword;
|
856 |
-
$return['remote_mysql_db']
|
857 |
}
|
858 |
-
else{
|
859 |
$return['dir'] = ($pathinfo['dirname']).DS.$suffix;
|
860 |
$return['restore_script_url'] = str_replace($pathinfo['basename'], "", $restore_script_url).$suffix;
|
861 |
}
|
@@ -864,75 +1010,109 @@ class Xcloner_Restore
|
|
864 |
|
865 |
$this->send_response(200, $return);
|
866 |
}
|
867 |
-
|
|
|
|
|
|
|
|
|
|
|
868 |
public function check_system()
|
869 |
{
|
870 |
//check if i can write
|
871 |
$tmp_file = md5(time());
|
872 |
-
if(!file_put_contents($tmp_file, "++"))
|
873 |
throw new Exception("Could not write to new host");
|
874 |
|
875 |
-
if(!unlink($tmp_file))
|
876 |
throw new Exception("Could not delete temporary file from new host");
|
877 |
|
878 |
$max_upload = $this->return_bytes((ini_get('upload_max_filesize')));
|
879 |
$max_post = $this->return_bytes((ini_get('post_max_size')));
|
880 |
|
881 |
$return['max_upload_size'] = min($max_upload, $max_post); // bytes
|
882 |
-
$return['status']
|
883 |
|
884 |
$this->logger->info(sprintf('Current filesystem max upload size is %s bytes', $return['max_upload_size']));
|
885 |
|
886 |
$this->send_response(200, $return);
|
887 |
}
|
888 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
private function return_bytes($val) {
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
|
|
|
|
|
|
903 |
}
|
904 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
905 |
public function is_multipart($backup_name)
|
906 |
{
|
907 |
-
if(stristr($backup_name, "-multipart"))
|
908 |
return true;
|
909 |
|
910 |
return false;
|
911 |
}
|
912 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
913 |
public function get_backup_size($backup_name)
|
914 |
{
|
915 |
$backup_size = $this->filesystem->getSize($backup_name);
|
916 |
-
if($this->is_multipart($backup_name))
|
917 |
{
|
918 |
$backup_parts = $this->get_multipart_files($backup_name);
|
919 |
-
foreach($backup_parts as $part_file)
|
920 |
$backup_size += $this->filesystem->getSize($part_file);
|
921 |
}
|
922 |
|
923 |
return $backup_size;
|
924 |
}
|
925 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
public function get_multipart_files($backup_name)
|
927 |
{
|
928 |
$files = array();
|
929 |
|
930 |
-
if($this->is_multipart($backup_name))
|
931 |
{
|
932 |
$lines = explode(PHP_EOL, $this->filesystem->read($backup_name));
|
933 |
-
foreach($lines as $line)
|
934 |
{
|
935 |
-
if($line)
|
936 |
{
|
937 |
$data = str_getcsv($line);
|
938 |
$files[] = $data[0];
|
@@ -942,26 +1122,63 @@ class Xcloner_Restore
|
|
942 |
|
943 |
return $files;
|
944 |
}
|
945 |
-
|
946 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
{
|
948 |
$direction = strtolower($direction);
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
}
|
964 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
965 |
public static function send_response($status = 200, $response)
|
966 |
{
|
967 |
header("Access-Control-Allow-Origin: *");
|
@@ -970,63 +1187,83 @@ class Xcloner_Restore
|
|
970 |
$return['status'] = $status;
|
971 |
$return['statusText'] = $response;
|
972 |
|
973 |
-
if(isset($response['error']) && $response['error'])
|
974 |
{
|
975 |
$return['statusText'] = $response['message'];
|
976 |
$return['error'] = true;
|
977 |
-
}elseif($status != 200 and $status != 418)
|
978 |
{
|
979 |
$return['error'] = true;
|
980 |
$return['message'] = $response;
|
981 |
}
|
982 |
|
983 |
-
|
984 |
-
|
985 |
}
|
986 |
-
|
987 |
-
|
988 |
* Serialize fix methods below for mysql query lines
|
989 |
-
|
|
|
|
|
|
|
990 |
|
991 |
function do_serialized_fix($query)
|
992 |
{
|
993 |
-
$query = str_replace(array("\\n","\\r","\\'"), array("","","\""), ($query));
|
994 |
|
995 |
-
return preg_replace_callback('!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!', function
|
996 |
$data = "";
|
997 |
|
998 |
-
if(!isset($m[3]))
|
999 |
$m[3] = "";
|
1000 |
|
1001 |
$data = 's:'.strlen(($m[3])).':\"'.($m[3]).'\";';
|
1002 |
-
|
1003 |
|
1004 |
-
|
1005 |
-
|
1006 |
}
|
1007 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1008 |
private function unescape_quotes($value) {
|
1009 |
return str_replace('\"', '"', $value);
|
1010 |
}
|
1011 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1012 |
private function unescape_mysql($value) {
|
1013 |
-
return str_replace(array("\\\\", "\\0", "\\n", "\\r", "\Z",
|
1014 |
-
array("\\",
|
1015 |
$value);
|
1016 |
-
}
|
1017 |
-
|
1018 |
-
|
|
|
|
|
|
|
|
|
|
|
1019 |
private function has_serialized($s)
|
1020 |
{
|
1021 |
-
if(
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
}else{
|
1029 |
-
|
1030 |
}
|
1031 |
|
1032 |
}
|
1 |
<?php
|
2 |
|
3 |
+
if (!defined('AUTH_KEY'))
|
4 |
{
|
5 |
define('AUTH_KEY', '');
|
6 |
}
|
7 |
|
8 |
+
if (!defined("DS"))
|
9 |
{
|
10 |
define("DS", DIRECTORY_SEPARATOR);
|
11 |
}
|
12 |
|
13 |
+
if (!defined('XCLONER_PLUGIN_ACCESS') || XCLONER_PLUGIN_ACCESS != 1)
|
14 |
{
|
15 |
+
if (!AUTH_KEY)
|
16 |
{
|
17 |
Xcloner_Restore::send_response("404", "Could not run restore script, AUTH_KEY not set!");
|
18 |
exit;
|
19 |
}
|
20 |
|
21 |
+
if (!isset($_REQUEST['hash']))
|
22 |
{
|
23 |
Xcloner_Restore::send_response("404", "Could not run restore script, sent HASH is empty!");
|
24 |
exit;
|
25 |
}
|
26 |
|
27 |
+
if ($_REQUEST['hash'] != AUTH_KEY)
|
28 |
{
|
29 |
Xcloner_Restore::send_response("404", "Could not run restore script, AUTH_KEY doesn't match the sent HASH!");
|
30 |
exit;
|
32 |
}
|
33 |
|
34 |
//check minimum PHP version
|
35 |
+
if (version_compare(phpversion(), Xcloner_Restore::xcloner_minimum_version, '<'))
|
36 |
{
|
37 |
+
Xcloner_Restore::send_response(500, sprintf(("XCloner requires minimum PHP version %s in order to run correctly. We have detected your version as %s"), Xcloner_Restore::xcloner_minimum_version, phpversion()));
|
38 |
exit;
|
39 |
|
40 |
}
|
41 |
|
42 |
+
$file = dirname(__DIR__).DS.'vendor'.DS.'autoload.php';
|
43 |
|
44 |
+
if (file_exists($file))
|
45 |
{
|
46 |
|
47 |
require_once($file);
|
48 |
}
|
49 |
+
elseif (file_exists("vendor.phar") and extension_loaded('phar'))
|
50 |
{
|
51 |
require_once(__DIR__.DS."vendor.phar");
|
52 |
+
} else {
|
53 |
|
54 |
+
$file = dirname(__FILE__).DS.'vendor'.DS.'autoload.php';
|
55 |
|
56 |
+
if (!file_exists($file))
|
57 |
{
|
58 |
Xcloner_Restore::send_response("404", "File $file does not exists, please extract the vendor.tgz archive on the server or enable PHP Phar module!");
|
59 |
exit;
|
78 |
|
79 |
//do not modify below
|
80 |
$that = "";
|
81 |
+
if (defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
82 |
{
|
83 |
$that = $this;
|
84 |
}
|
85 |
$xcloner_restore = new Xcloner_Restore($that);
|
86 |
|
87 |
+
try {
|
88 |
$return = $xcloner_restore->init();
|
89 |
$xcloner_restore->send_response(200, $return);
|
90 |
+
}catch (Exception $e) {
|
91 |
$xcloner_restore->send_response(417, $e->getMessage());
|
92 |
}
|
93 |
|
96 |
|
97 |
const xcloner_minimum_version = "5.4.0";
|
98 |
|
99 |
+
private $backup_archive_extensions = array("zip", "tar", "tgz", "tar.gz", "gz", "csv");
|
100 |
+
private $process_files_limit = 150;
|
101 |
+
private $process_files_limit_list = 350;
|
102 |
+
private $process_mysql_records_limit = 250;
|
103 |
private $adapter;
|
104 |
private $filesystem;
|
105 |
private $logger;
|
106 |
private $backup_storage_dir;
|
107 |
private $parent_api;
|
108 |
+
|
109 |
+
private $target_adapter;
|
110 |
+
private $target_filesystem;
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Xcloner_Restore constructor.
|
114 |
+
* @param string $parent_api
|
115 |
+
* @throws Exception
|
116 |
+
*/
|
117 |
public function __construct($parent_api = "")
|
118 |
{
|
119 |
register_shutdown_function(array($this, 'exception_handler'));
|
120 |
|
121 |
+
if (defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
122 |
{
|
123 |
$dir = $parent_api->get_xcloner_container()->get_xcloner_settings()->get_xcloner_store_path();
|
124 |
}
|
125 |
|
126 |
+
if (!isset($dir) || !$dir) {
|
127 |
$dir = dirname(__FILE__);
|
128 |
}
|
129 |
|
131 |
|
132 |
$this->backup_storage_dir = $dir;
|
133 |
|
134 |
+
$this->adapter = new Local($dir, LOCK_EX, 'SKIP_LINKS');
|
135 |
$this->filesystem = new Filesystem($this->adapter, new Config([
|
136 |
'disable_asserts' => true,
|
137 |
]));
|
140 |
|
141 |
$logger_path = $this->get_logger_filename();
|
142 |
|
143 |
+
if (!is_writeable($logger_path) and !touch($logger_path))
|
144 |
{
|
145 |
$logger_path = "php://stderr";
|
146 |
}
|
147 |
|
148 |
$this->logger->pushHandler(new StreamHandler($logger_path, Logger::DEBUG));
|
149 |
|
150 |
+
if (isset($_POST['API_ID'])) {
|
151 |
+
$this->logger->info("Processing ajax request ID ".substr(filter_input(INPUT_POST, 'API_ID', FILTER_SANITIZE_STRING), 0, 15));
|
152 |
}
|
153 |
|
154 |
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Exception handler method
|
158 |
+
*/
|
159 |
public function exception_handler() {
|
160 |
|
161 |
$error = error_get_last();
|
162 |
|
163 |
+
if ($error['type'] and $this->logger)
|
164 |
{
|
165 |
+
$this->logger->info($this->friendly_error_type($error['type']).": ".var_export($error, true));
|
166 |
}
|
167 |
|
168 |
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param $type
|
172 |
+
* @return mixed|string
|
173 |
+
*/
|
174 |
private function friendly_error_type($type) {
|
175 |
+
static $levels = null;
|
176 |
+
if ($levels === null) {
|
177 |
+
$levels = [];
|
178 |
+
foreach (get_defined_constants() as $key=>$value) {
|
179 |
+
if (strpos($key, 'E_') !== 0) {continue; }
|
180 |
+
$levels[$value] = $key; //substr($key,2);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
return (isset($levels[$type]) ? $levels[$type] : "Error #{$type}");
|
184 |
}
|
185 |
|
186 |
public function get_logger_filename()
|
187 |
{
|
188 |
+
$filename = $this->backup_storage_dir.DS."xcloner_restore.log";
|
189 |
|
190 |
return $filename;
|
191 |
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Init method
|
195 |
+
*
|
196 |
+
* @return mixed|void
|
197 |
+
* @throws Exception
|
198 |
+
*/
|
199 |
public function init()
|
200 |
{
|
201 |
+
if (isset($_POST['xcloner_action']) and $_POST['xcloner_action'])
|
202 |
{
|
203 |
$method = filter_input(INPUT_POST, 'xcloner_action', FILTER_SANITIZE_STRING);
|
204 |
|
206 |
|
207 |
$method .= "_action";
|
208 |
|
209 |
+
if (method_exists($this, $method))
|
210 |
{
|
211 |
$this->logger->debug(sprintf('Starting action %s', $method));
|
212 |
return call_user_func(array($this, $method));
|
213 |
|
214 |
+
} else {
|
215 |
+
throw new Exception($method." does not exists");
|
216 |
}
|
217 |
}
|
218 |
|
219 |
return $this->check_system();
|
220 |
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Write file method
|
224 |
+
*
|
225 |
+
* @return bool|int
|
226 |
+
* @throws Exception
|
227 |
+
*/
|
228 |
public function write_file_action()
|
229 |
{
|
230 |
+
if (isset($_POST['file']))
|
231 |
{
|
232 |
$target_file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING);
|
233 |
|
234 |
+
if (!$_POST['start'])
|
235 |
$fp = fopen($target_file, "wb+");
|
236 |
else
|
237 |
$fp = fopen($target_file, "ab+");
|
238 |
|
239 |
+
if (!$fp)
|
240 |
throw new Exception("Unable to open $target_file file for writing");
|
241 |
|
242 |
fseek($fp, $_POST['start']);
|
243 |
|
244 |
+
if (isset($_FILES['blob']))
|
245 |
{
|
246 |
$this->logger->debug(sprintf('Writing %s bytes to file %s starting position %s using FILES blob', filesize($_FILES['blob']['tmp_name']), $target_file, $_POST['start']));
|
247 |
|
248 |
$blob = file_get_contents($_FILES['blob']['tmp_name']);
|
249 |
|
250 |
+
if (!$bytes_written = fwrite($fp, $blob))
|
251 |
throw new Exception("Unable to write data to file $target_file");
|
252 |
+
|
253 |
+
try {
|
254 |
+
unlink($_FILES['blob']['tmp_name']);
|
255 |
+
}catch (Exception $e) {
|
256 |
+
//silent message
|
257 |
+
}
|
258 |
+
|
259 |
+
}elseif (isset($_POST['blob'])) {
|
260 |
$this->logger->debug(sprintf('Writing %s bytes to file %s starting position %s using POST blob', strlen($_POST['blob']), $target_file, $_POST['start']));
|
261 |
|
262 |
$blob = $_POST['blob'];
|
263 |
|
264 |
+
if (!$bytes_written = fwrite($fp, $blob))
|
265 |
throw new Exception("Unable to write data to file $target_file");
|
266 |
+
} else {
|
267 |
throw new Exception("Upload failed, did not receive any binary data");
|
268 |
}
|
269 |
|
273 |
return $bytes_written;
|
274 |
|
275 |
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Connect to mysql server method
|
279 |
+
*
|
280 |
+
* @param $remote_mysql_host
|
281 |
+
* @param $remote_mysql_user
|
282 |
+
* @param $remote_mysql_pass
|
283 |
+
* @param $remote_mysql_db
|
284 |
+
* @return mysqli
|
285 |
+
* @throws Exception
|
286 |
+
*/
|
287 |
+
public function mysql_connect($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db)
|
288 |
{
|
289 |
$this->logger->info(sprintf('Connecting to mysql database %s with %s@%s', $remote_mysql_db, $remote_mysql_user, $remote_mysql_host));
|
290 |
|
291 |
$mysqli = new mysqli($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
292 |
|
293 |
if ($mysqli->connect_error) {
|
294 |
+
throw new Exception('Connect Error ('.$mysqli->connect_errno.') '
|
295 |
. $mysqli->connect_error);
|
296 |
}
|
297 |
|
298 |
$mysqli->query("SET sql_mode='';");
|
299 |
$mysqli->query("SET foreign_key_checks = 0;");
|
300 |
+
if (isset($_REQUEST['charset_of_file']) and $_REQUEST['charset_of_file'])
|
301 |
$mysqli->query("SET NAMES ".$_REQUEST['charset_of_file']."");
|
302 |
else
|
303 |
$mysqli->query("SET NAMES utf8;");
|
304 |
|
305 |
return $mysqli;
|
306 |
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Restore mysql backup file
|
310 |
+
*
|
311 |
+
* @throws Exception
|
312 |
+
*/
|
313 |
public function restore_mysql_backup_action()
|
314 |
{
|
315 |
+
$mysqldump_file = filter_input(INPUT_POST, 'mysqldump_file', FILTER_SANITIZE_STRING);
|
316 |
+
$remote_path = filter_input(INPUT_POST, 'remote_path', FILTER_SANITIZE_STRING);
|
317 |
$remote_mysql_user = filter_input(INPUT_POST, 'remote_mysql_user', FILTER_SANITIZE_STRING);
|
318 |
$remote_mysql_pass = filter_input(INPUT_POST, 'remote_mysql_pass', FILTER_SANITIZE_STRING);
|
319 |
+
$remote_mysql_db = filter_input(INPUT_POST, 'remote_mysql_db', FILTER_SANITIZE_STRING);
|
320 |
$remote_mysql_host = filter_input(INPUT_POST, 'remote_mysql_host', FILTER_SANITIZE_STRING);
|
321 |
+
$execute_query = trim(stripslashes($_POST['query']));
|
322 |
+
$error_line = filter_input(INPUT_POST, 'error_line', FILTER_SANITIZE_NUMBER_INT);
|
323 |
+
$start = filter_input(INPUT_POST, 'start', FILTER_SANITIZE_NUMBER_INT);
|
324 |
|
325 |
$wp_home_url = filter_input(INPUT_POST, 'wp_home_url', FILTER_SANITIZE_STRING);
|
326 |
$remote_restore_url = filter_input(INPUT_POST, 'remote_restore_url', FILTER_SANITIZE_STRING);
|
330 |
|
331 |
$mysql_backup_file = $remote_path.DS.$mysqldump_file;
|
332 |
|
333 |
+
if (!file_exists($mysql_backup_file))
|
334 |
+
throw new Exception(sprintf("Mysql backup file %s does not exists", $mysql_backup_file));
|
335 |
|
336 |
|
337 |
/*if(defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
345 |
}*/
|
346 |
|
347 |
{
|
348 |
+
$mysqli = $this->mysql_connect($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
349 |
}
|
350 |
|
351 |
$line_count = 0;
|
352 |
$query = "";
|
353 |
+
$return = array();
|
354 |
$return['finished'] = 1;
|
355 |
$return['backup_file'] = $mysqldump_file;
|
356 |
$return['backup_size'] = filesize($mysql_backup_file);
|
357 |
|
358 |
$fp = fopen($mysql_backup_file, "r");
|
359 |
+
if ($fp)
|
360 |
{
|
361 |
$this->logger->info(sprintf("Opening mysql dump file %s at position %s.", $mysql_backup_file, $start));
|
362 |
fseek($fp, $start);
|
364 |
// process the line read.
|
365 |
|
366 |
//check if line is comment
|
367 |
+
if (substr($line, 0, 1) == "#")
|
368 |
continue;
|
369 |
|
370 |
//check if line is empty
|
371 |
+
if ($line == "\n" or trim($line) == "")
|
372 |
continue;
|
373 |
|
374 |
+
if (substr($line, strlen($line) - 2, strlen($line)) == ";\n")
|
375 |
$query .= $line;
|
376 |
+
else {
|
377 |
$query .= $line;
|
378 |
continue;
|
379 |
}
|
380 |
|
381 |
+
if ($execute_query)
|
382 |
{
|
383 |
+
$query = (($execute_query));
|
384 |
$execute_query = "";
|
385 |
}
|
386 |
|
387 |
//Doing serialized url replace here
|
388 |
|
389 |
+
if ($wp_site_url and $wp_home_url and strlen($wp_home_url) < strlen($wp_site_url))
|
390 |
{
|
391 |
+
list($wp_home_url, $wp_site_url) = array($wp_site_url, $wp_home_url);
|
392 |
+
list($remote_restore_url, $restore_site_url) = array($restore_site_url, $remote_restore_url);
|
393 |
|
394 |
}
|
395 |
|
396 |
+
if ($wp_home_url and $remote_restore_url and strpos($query, $wp_home_url) !== false)
|
397 |
{
|
398 |
$query = $this->url_replace($wp_home_url, $remote_restore_url, $query);
|
399 |
}
|
400 |
|
401 |
+
if ($wp_site_url and $restore_site_url and strpos($query, $wp_site_url) !== false)
|
402 |
{
|
403 |
$query = $this->url_replace($wp_site_url, $restore_site_url, $query);
|
404 |
}
|
405 |
|
406 |
+
if (!$mysqli->query($query) && !stristr($mysqli->error, "Duplicate entry"))
|
407 |
{
|
408 |
//$return['error_line'] = $line_count;
|
409 |
+
$return['start'] = ftell($fp) - strlen($line);
|
410 |
$return['query_error'] = true;
|
411 |
$return['query'] = $query;
|
412 |
$return['message'] = sprintf("Mysql Error: %s\n", $mysqli->error);
|
423 |
$line_count++;
|
424 |
|
425 |
}
|
426 |
+
|
427 |
+
$return['start'] = ftell($fp);
|
428 |
+
|
429 |
+
$this->logger->info(sprintf("Executed %s queries of size %s bytes", $line_count, ($return['start'] - $start)));
|
430 |
+
|
431 |
+
if (!feof($fp))
|
432 |
+
{
|
433 |
+
$return['finished'] = 0;
|
434 |
+
} else {
|
435 |
+
$this->logger->info(sprintf("Mysql Import Done."));
|
436 |
+
}
|
437 |
+
|
438 |
+
fclose($fp);
|
439 |
}
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
$this->send_response(200, $return);
|
442 |
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Url replace method inside database backup file
|
446 |
+
*
|
447 |
+
* @param $search
|
448 |
+
* @param $replace
|
449 |
+
* @param $query
|
450 |
+
* @return mixed|string|string[]|null
|
451 |
+
*/
|
452 |
private function url_replace($search, $replace, $query)
|
453 |
{
|
454 |
$this->logger->info(sprintf("Doing url replace on query with length %s", strlen($query)), array("QUERY_REPLACE"));
|
455 |
$query = str_replace($search, $replace, $query);
|
456 |
$original_query = $query;
|
457 |
|
458 |
+
if ($this->has_serialized($query))
|
459 |
{
|
460 |
$this->logger->info(sprintf("Query contains serialized data, doing serialized size fix"), array("QUERY_REPLACE"));
|
461 |
$query = $this->do_serialized_fix($query);
|
462 |
|
463 |
+
if (!$query)
|
464 |
{
|
465 |
$this->logger->info(sprintf("Serialization probably failed here..."), array("QUERY_REPLACE"));
|
466 |
$query = $original_query;
|
470 |
|
471 |
return $query;
|
472 |
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* List backup files method
|
476 |
+
*
|
477 |
+
* @throws \League\Flysystem\FileNotFoundException
|
478 |
+
*/
|
479 |
public function list_backup_files_action()
|
480 |
{
|
481 |
$backup_parts = array();
|
482 |
|
483 |
$source_backup_file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING);
|
484 |
+
$start = (int)filter_input(INPUT_POST, 'start', FILTER_SANITIZE_STRING);
|
485 |
+
$return['part'] = (int)filter_input(INPUT_POST, 'part', FILTER_SANITIZE_STRING);
|
486 |
|
487 |
$backup_file = $source_backup_file;
|
488 |
|
489 |
+
if ($this->is_multipart($backup_file))
|
490 |
{
|
491 |
$backup_parts = $this->get_multipart_files($backup_file);
|
492 |
$backup_file = $backup_parts[$return['part']];
|
493 |
}
|
494 |
|
495 |
+
try {
|
496 |
$tar = new Tar();
|
497 |
$tar->open($this->backup_storage_dir.DS.$backup_file, $start);
|
498 |
|
499 |
$data = $tar->contents($this->process_files_limit_list);
|
500 |
+
}catch (Exception $e)
|
501 |
{
|
502 |
$return['error'] = true;
|
503 |
$return['message'] = $e->getMessage();
|
504 |
$this->send_response(200, $return);
|
505 |
}
|
506 |
|
507 |
+
$return['files'] = array();
|
508 |
+
$return['finished'] = 1;
|
509 |
+
$return['total_size'] = filesize($this->backup_storage_dir.DS.$backup_file);
|
510 |
$i = 0;
|
511 |
|
512 |
+
if (isset($data['extracted_files']) and is_array($data['extracted_files']))
|
513 |
{
|
514 |
+
foreach ($data['extracted_files'] as $file)
|
515 |
{
|
516 |
$return['files'][$i]['path'] = $file->getPath();
|
517 |
$return['files'][$i]['size'] = $file->getSize();
|
521 |
}
|
522 |
}
|
523 |
|
524 |
+
if (isset($data['start']))
|
525 |
{
|
526 |
$return['start'] = $data['start'];
|
527 |
$return['finished'] = 0;
|
528 |
+
} else {
|
529 |
+
if ($this->is_multipart($source_backup_file))
|
530 |
{
|
531 |
$return['start'] = 0;
|
532 |
|
533 |
++$return['part'];
|
534 |
|
535 |
+
if ($return['part'] < sizeof($backup_parts))
|
536 |
$return['finished'] = 0;
|
537 |
|
538 |
}
|
540 |
|
541 |
$this->send_response(200, $return);
|
542 |
}
|
543 |
+
|
544 |
+
/**
|
545 |
+
* Finish backup restore method
|
546 |
+
*
|
547 |
+
* @throws \League\Flysystem\FileNotFoundException
|
548 |
+
*/
|
549 |
public function restore_finish_action()
|
550 |
{
|
551 |
$remote_path = filter_input(INPUT_POST, 'remote_path', FILTER_SANITIZE_STRING);
|
555 |
|
556 |
$remote_mysql_user = filter_input(INPUT_POST, 'remote_mysql_user', FILTER_SANITIZE_STRING);
|
557 |
$remote_mysql_pass = filter_input(INPUT_POST, 'remote_mysql_pass', FILTER_SANITIZE_STRING);
|
558 |
+
$remote_mysql_db = filter_input(INPUT_POST, 'remote_mysql_db', FILTER_SANITIZE_STRING);
|
559 |
$remote_mysql_host = filter_input(INPUT_POST, 'remote_mysql_host', FILTER_SANITIZE_STRING);
|
560 |
|
561 |
+
$update_remote_site_url = filter_input(INPUT_POST, 'update_remote_site_url', FILTER_SANITIZE_NUMBER_INT);
|
562 |
+
$delete_restore_script = filter_input(INPUT_POST, 'delete_restore_script', FILTER_SANITIZE_NUMBER_INT);
|
563 |
+
$delete_backup_temporary_folder = filter_input(INPUT_POST, 'delete_backup_temporary_folder', FILTER_SANITIZE_NUMBER_INT);
|
564 |
|
565 |
+
if ($update_remote_site_url)
|
566 |
{
|
567 |
+
$mysqli = $this->mysql_connect($remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
568 |
$this->update_wp_config($remote_path, $remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db);
|
569 |
$this->update_wp_url($remote_path, $remote_restore_url, $mysqli);
|
570 |
}
|
571 |
|
572 |
+
if ($delete_backup_temporary_folder)
|
573 |
{
|
574 |
$this->delete_backup_temporary_folder($remote_path);
|
575 |
}
|
576 |
|
577 |
+
if (!defined('XCLONER_PLUGIN_ACCESS') || XCLONER_PLUGIN_ACCESS != 1)
|
578 |
{
|
579 |
+
if ($delete_restore_script)
|
580 |
{
|
581 |
$this->delete_self();
|
582 |
}
|
585 |
$return = "Restore Process Finished.";
|
586 |
$this->send_response(200, $return);
|
587 |
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Delete backup temporary folder
|
591 |
+
*
|
592 |
+
* @param $remote_path
|
593 |
+
* @return bool
|
594 |
+
*/
|
595 |
private function delete_backup_temporary_folder($remote_path)
|
596 |
{
|
597 |
+
$this->target_adapter = new Local($remote_path, LOCK_EX, 'SKIP_LINKS');
|
598 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
599 |
'disable_asserts' => true,
|
600 |
]));
|
602 |
$mysqldump_list = array();
|
603 |
$list = $this->target_filesystem->listContents();
|
604 |
|
605 |
+
foreach ($list as $file)
|
606 |
{
|
607 |
$matches = array();
|
608 |
|
609 |
+
if ($file['type'] == "dir")
|
610 |
{
|
611 |
+
if (preg_match("/xcloner-(\w*)/", $file['basename'], $matches)) {
|
612 |
$this->logger->info(sprintf('Deleting temporary folder %s', $file['path']));
|
613 |
$this->target_filesystem->deleteDir($file['path']);
|
614 |
}
|
618 |
return true;
|
619 |
|
620 |
}
|
621 |
+
|
622 |
+
/**
|
623 |
+
* Delete restore script method
|
624 |
+
*
|
625 |
+
* @throws \League\Flysystem\FileNotFoundException
|
626 |
+
*/
|
627 |
private function delete_self()
|
628 |
{
|
629 |
+
if ($this->filesystem->has("vendor.phar"))
|
630 |
{
|
631 |
$this->logger->info(sprintf('Deleting vendor.phar'));
|
632 |
$this->filesystem->delete("vendor.phar");
|
633 |
}
|
634 |
+
if ($this->filesystem->has("vendor"))
|
635 |
{
|
636 |
$this->logger->info(sprintf('Deleting vendor folder'));
|
637 |
$this->filesystem->deleteDir("vendor");
|
638 |
}
|
639 |
+
if ($this->filesystem->has("xcloner_restore.php"))
|
640 |
{
|
641 |
$this->logger->info(sprintf('Deleting xcloner_restore.php'));
|
642 |
$this->filesystem->delete("xcloner_restore.php");
|
643 |
}
|
644 |
|
645 |
+
if ($this->filesystem->has("xcloner_restore.log"))
|
646 |
{
|
647 |
$this->logger->info(sprintf('Deleting xcloner_restore.log'));
|
648 |
$this->filesystem->delete("xcloner_restore.log");
|
649 |
}
|
650 |
|
651 |
+
if ($this->filesystem->has($this->get_logger_filename()))
|
652 |
{
|
653 |
$this->logger->info(sprintf('Deleting logger file %s', $this->get_logger_filename()));
|
654 |
$this->filesystem->delete($this->get_logger_filename());
|
655 |
}
|
656 |
|
657 |
}
|
658 |
+
|
659 |
+
/**
|
660 |
+
* Update Wordpress url in wp-config.php method
|
661 |
+
* @param $wp_path
|
662 |
+
* @param $url
|
663 |
+
* @param mysqli $mysqli
|
664 |
+
* @return bool
|
665 |
+
* @throws Exception
|
666 |
+
*/
|
667 |
private function update_wp_url($wp_path, $url, $mysqli)
|
668 |
{
|
669 |
$wp_config = $wp_path.DS."wp-config.php";
|
670 |
|
671 |
$this->logger->info(sprintf('Updating site url to %s', $url));
|
672 |
|
673 |
+
if (file_exists($wp_config))
|
674 |
{
|
675 |
$config = file_get_contents($wp_config);
|
676 |
preg_match("/.*table_prefix.*=.*'(.*)'/i", $config, $matches);
|
677 |
+
if (isset($matches[1]))
|
678 |
$table_prefix = $matches[1];
|
679 |
else
|
680 |
throw new Exception("Could not load wordpress table prefix from wp-config.php file.");
|
682 |
else
|
683 |
throw new Exception("Could not update the SITEURL and HOME, wp-config.php file not found");
|
684 |
|
685 |
+
if (!$mysqli->query("update ".$table_prefix."options set option_value='".($url)."' where option_name='home'"))
|
686 |
throw new Exception(sprintf("Could not update the HOME option, error: %s\n", $mysqli->error));
|
687 |
|
688 |
+
if (!$mysqli->query("update ".$table_prefix."options set option_value='".($url)."' where option_name='siteurl'"))
|
689 |
throw new Exception(sprintf("Could not update the SITEURL option, error: %s\n", $mysqli->error));
|
690 |
|
691 |
return true;
|
692 |
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* Update local wp-config.php file method
|
696 |
+
*
|
697 |
+
* @param $remote_path
|
698 |
+
* @param $remote_mysql_host
|
699 |
+
* @param $remote_mysql_user
|
700 |
+
* @param $remote_mysql_pass
|
701 |
+
* @param $remote_mysql_db
|
702 |
+
* @return string
|
703 |
+
* @throws Exception
|
704 |
+
*/
|
705 |
private function update_wp_config($remote_path, $remote_mysql_host, $remote_mysql_user, $remote_mysql_pass, $remote_mysql_db)
|
706 |
{
|
707 |
$wp_config = $remote_path.DS."wp-config.php";
|
708 |
|
709 |
+
if (!file_exists($wp_config))
|
710 |
{
|
711 |
throw new Exception("Could not find the wp-config.php in ".$remote_path);
|
712 |
}
|
724 |
|
725 |
$this->logger->info(sprintf('Updating wp-config.php file with the new mysql details'));
|
726 |
|
727 |
+
if (!file_put_contents($wp_config, $content))
|
728 |
throw new Exception("Could not write updated config data to ".$wp_config);
|
729 |
|
730 |
chmod($wp_config, $file_perms);
|
732 |
return $wp_config;
|
733 |
|
734 |
}
|
735 |
+
|
736 |
+
/**
|
737 |
+
* List mysqldump database backup files
|
738 |
+
*
|
739 |
+
*/
|
740 |
public function list_mysqldump_backups_action()
|
741 |
{
|
742 |
$source_backup_file = filter_input(INPUT_POST, 'backup_file', FILTER_SANITIZE_STRING);
|
744 |
|
745 |
$hash = $this->get_hash_from_backup($source_backup_file);
|
746 |
|
747 |
+
$this->target_adapter = new Local($remote_path, LOCK_EX, 'SKIP_LINKS');
|
748 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
749 |
'disable_asserts' => true,
|
750 |
]));
|
752 |
$mysqldump_list = array();
|
753 |
$list = $this->target_filesystem->listContents();
|
754 |
|
755 |
+
foreach ($list as $file)
|
756 |
{
|
757 |
$matches = array();
|
758 |
|
759 |
+
if ($file['type'] == "dir")
|
760 |
{
|
761 |
+
if (preg_match("/xcloner-(\w*)/", $file['basename'], $matches))
|
762 |
{
|
763 |
$files = $this->target_filesystem->listContents($file['basename']);
|
764 |
+
foreach ($files as $file)
|
765 |
{
|
766 |
+
if ($file['extension'] == "sql")
|
767 |
{
|
768 |
$this->logger->info(sprintf('Found %s mysql backup file', $file['path']));
|
769 |
$mysqldump_list[$file['path']]['path'] = $file['path'];
|
770 |
$mysqldump_list[$file['path']]['size'] = $file['size'];
|
771 |
+
$mysqldump_list[$file['path']]['timestamp'] = date("d M,Y H:i", $file['timestamp']);
|
772 |
|
773 |
+
if ($hash and $hash == $matches[1])
|
774 |
$mysqldump_list[$file['path']]['selected'] = "selected";
|
775 |
else
|
776 |
$mysqldump_list[$file['path']]['selected'] = "";
|
780 |
}
|
781 |
}
|
782 |
|
783 |
+
$this->sort_by($mysqldump_list, 'timestamp', 'desc');
|
784 |
$return['files'] = $mysqldump_list;
|
785 |
|
786 |
$this->send_response(200, $return);
|
787 |
}
|
788 |
+
|
789 |
+
/**
|
790 |
+
* Get backup hash method
|
791 |
+
*
|
792 |
+
* @param $backup_file
|
793 |
+
* @return false|string
|
794 |
+
*/
|
795 |
private function get_hash_from_backup($backup_file)
|
796 |
{
|
797 |
+
if (!$backup_file)
|
798 |
return false;
|
799 |
|
800 |
+
$result = preg_match("/-(\w*)./", substr($backup_file, strlen($backup_file) - 10, strlen($backup_file)), $matches);
|
801 |
|
802 |
+
if ($result and isset($matches[1]))
|
803 |
return ($matches[1]);
|
804 |
|
805 |
return false;
|
806 |
}
|
807 |
+
|
808 |
+
/**
|
809 |
+
* List backup archives found on local system
|
810 |
+
*
|
811 |
+
* @throws \League\Flysystem\FileNotFoundException
|
812 |
+
*/
|
813 |
public function list_backup_archives_action()
|
814 |
{
|
815 |
$local_backup_file = filter_input(INPUT_POST, 'local_backup_file', FILTER_SANITIZE_STRING);
|
818 |
$backup_files = array();
|
819 |
$parents = array();
|
820 |
|
821 |
+
foreach ($list as $file_info)
|
822 |
{
|
823 |
$data = array();
|
824 |
|
825 |
+
if (isset($file_info['extension']) and $file_info['extension'] == "csv")
|
826 |
{
|
827 |
$lines = explode(PHP_EOL, $this->filesystem->read($file_info['path']));
|
828 |
+
foreach ($lines as $line)
|
829 |
+
if ($line)
|
830 |
{
|
831 |
$data = str_getcsv($line);
|
832 |
+
if (is_array($data)) {
|
833 |
$parents[$data[0]] = $file_info['path'];
|
834 |
$file_info['childs'][] = $data;
|
835 |
$file_info['size'] += $data[2];
|
838 |
|
839 |
}
|
840 |
|
841 |
+
if ($file_info['type'] == 'file' and isset($file_info['extension']) and in_array($file_info['extension'], $this->backup_archive_extensions))
|
842 |
$backup_files[$file_info['path']] = $file_info;
|
843 |
}
|
844 |
|
845 |
$new_list = array();
|
846 |
|
847 |
+
foreach ($backup_files as $key=>$file_info)
|
848 |
{
|
849 |
+
if (isset($parents[$file_info['path']]))
|
850 |
$backup_files[$key]['parent'] = $parents[$file_info['path']];
|
851 |
+
else {
|
852 |
|
853 |
+
if ($local_backup_file and ($file_info['basename'] == $local_backup_file))
|
854 |
$file_info['selected'] = 'selected';
|
855 |
|
856 |
$this->logger->info(sprintf('Found %s backup file', $file_info['path']));
|
860 |
|
861 |
}
|
862 |
|
863 |
+
$this->sort_by($new_list, "timestamp", "desc");
|
864 |
|
865 |
$return['files'] = $new_list;
|
866 |
|
867 |
$this->send_response(200, $return);
|
868 |
|
869 |
}
|
870 |
+
|
871 |
+
/**
|
872 |
+
* Restore backup archive to local path
|
873 |
+
*
|
874 |
+
* @throws \League\Flysystem\FileNotFoundException
|
875 |
+
* @throws \splitbrain\PHPArchive\ArchiveIOException
|
876 |
+
*/
|
877 |
public function restore_backup_to_path_action()
|
878 |
{
|
879 |
+
$source_backup_file = filter_input(INPUT_POST, 'backup_file', FILTER_SANITIZE_STRING);
|
880 |
+
$remote_path = filter_input(INPUT_POST, 'remote_path', FILTER_SANITIZE_STRING);
|
881 |
$include_filter_files = filter_input(INPUT_POST, 'filter_files', FILTER_SANITIZE_STRING);
|
882 |
$exclude_filter_files = "";
|
883 |
+
$start = filter_input(INPUT_POST, 'start', FILTER_SANITIZE_NUMBER_INT);
|
884 |
+
$return['part'] = (int)filter_input(INPUT_POST, 'part', FILTER_SANITIZE_NUMBER_INT);
|
885 |
$return['processed'] = (int)filter_input(INPUT_POST, 'processed', FILTER_SANITIZE_NUMBER_INT);
|
886 |
|
887 |
+
$this->target_adapter = new Local($remote_path, LOCK_EX, 'SKIP_LINKS');
|
888 |
$this->target_filesystem = new Filesystem($this->target_adapter, new Config([
|
889 |
'disable_asserts' => true,
|
890 |
]));
|
896 |
$return['total_size'] = $this->get_backup_size($backup_file);
|
897 |
|
898 |
$backup_archive = new Tar();
|
899 |
+
if ($this->is_multipart($backup_file))
|
900 |
{
|
901 |
+
if (!$return['part'])
|
902 |
$return['processed'] += $this->filesystem->getSize($backup_file);
|
903 |
|
904 |
$backup_parts = $this->get_multipart_files($backup_file);
|
905 |
$backup_file = $backup_parts[$return['part']];
|
906 |
+
}
|
907 |
+
|
908 |
+
if( $this->is_encrypted_file($backup_file) ) {
|
909 |
+
$message = sprintf('Backup file %s seems encrypted, please Decrypt it first from your Manage Backups panel.', $backup_file);
|
910 |
+
$this->logger->error($message);
|
911 |
+
$this->send_response(500, $message);
|
912 |
+
return;
|
913 |
+
}
|
914 |
|
915 |
$this->logger->info(sprintf('Opening backup archive %s at position %s', $backup_file, $start));
|
916 |
+
$backup_archive->open($this->backup_storage_dir.DS.$backup_file, $start);
|
917 |
|
918 |
+
$data = $backup_archive->extract($remote_path, '', $exclude_filter_files, $include_filter_files, $this->process_files_limit);
|
919 |
|
920 |
+
if (isset($data['extracted_files']))
|
921 |
{
|
922 |
+
foreach ($data['extracted_files'] as $spl_fileinfo)
|
923 |
{
|
924 |
$this->logger->info(sprintf('Extracted %s file', $spl_fileinfo->getPath()));
|
925 |
$return['extracted_files'][] = $spl_fileinfo->getPath()." (".$spl_fileinfo->getSize()." bytes)";
|
926 |
}
|
927 |
}
|
928 |
|
929 |
+
if (isset($data['start']))
|
930 |
//if(isset($data['start']) and $data['start'] <= $this->filesystem->getSize($backup_file))
|
931 |
{
|
932 |
$return['finished'] = 0;
|
933 |
$return['start'] = $data['start'];
|
934 |
+
} else {
|
935 |
|
936 |
$return['processed'] += $start;
|
937 |
|
938 |
+
if ($this->is_multipart($source_backup_file))
|
939 |
{
|
940 |
$return['start'] = 0;
|
941 |
|
942 |
++$return['part'];
|
943 |
|
944 |
+
if ($return['part'] < sizeof($backup_parts))
|
945 |
$return['finished'] = 0;
|
946 |
|
947 |
}
|
948 |
}
|
949 |
|
950 |
+
if ($return['finished'])
|
951 |
$this->logger->info(sprintf('Done extracting %s', $source_backup_file));
|
952 |
|
953 |
$return['backup_file'] = $backup_file;
|
954 |
|
955 |
$this->send_response(200, $return);
|
956 |
}
|
957 |
+
|
958 |
+
/**
|
959 |
+
* Check if provided filename has encrypted suffix
|
960 |
+
*
|
961 |
+
* @param $filename
|
962 |
+
* @return bool
|
963 |
+
*/
|
964 |
+
public function is_encrypted_file($filename) {
|
965 |
+
$fp = $this->filesystem->readStream( $filename );
|
966 |
+
if (is_resource($fp)) {
|
967 |
+
$encryption_length = fread($fp, 16);
|
968 |
+
fclose($fp);
|
969 |
+
if (is_numeric($encryption_length)) {
|
970 |
+
return true;
|
971 |
+
}
|
972 |
+
}
|
973 |
+
|
974 |
+
return false;
|
975 |
+
|
976 |
+
}
|
977 |
+
|
978 |
+
/**
|
979 |
+
* Get current directory method
|
980 |
+
*/
|
981 |
public function get_current_directory_action()
|
982 |
{
|
983 |
global $wpdb;
|
984 |
|
985 |
$restore_script_url = filter_input(INPUT_POST, 'restore_script_url', FILTER_SANITIZE_STRING);
|
986 |
|
987 |
+
$pathinfo = pathinfo(__FILE__);
|
988 |
|
989 |
$suffix = "";
|
990 |
$return['remote_mysql_host'] = "localhost";
|
991 |
$return['remote_mysql_user'] = "";
|
992 |
$return['remote_mysql_pass'] = "";
|
993 |
+
$return['remote_mysql_db'] = "";
|
994 |
|
995 |
+
if (defined('XCLONER_PLUGIN_ACCESS') && XCLONER_PLUGIN_ACCESS)
|
996 |
{
|
997 |
$return['dir'] = realpath(get_home_path().DS.$suffix);
|
998 |
+
$return['restore_script_url'] = get_site_url();
|
999 |
$return['remote_mysql_host'] = $wpdb->dbhost;
|
1000 |
$return['remote_mysql_user'] = $wpdb->dbuser;
|
1001 |
$return['remote_mysql_pass'] = $wpdb->dbpassword;
|
1002 |
+
$return['remote_mysql_db'] = $wpdb->dbname;
|
1003 |
}
|
1004 |
+
else {
|
1005 |
$return['dir'] = ($pathinfo['dirname']).DS.$suffix;
|
1006 |
$return['restore_script_url'] = str_replace($pathinfo['basename'], "", $restore_script_url).$suffix;
|
1007 |
}
|
1010 |
|
1011 |
$this->send_response(200, $return);
|
1012 |
}
|
1013 |
+
|
1014 |
+
/**
|
1015 |
+
* Check current filesystem
|
1016 |
+
*
|
1017 |
+
* @throws Exception
|
1018 |
+
*/
|
1019 |
public function check_system()
|
1020 |
{
|
1021 |
//check if i can write
|
1022 |
$tmp_file = md5(time());
|
1023 |
+
if (!file_put_contents($tmp_file, "++"))
|
1024 |
throw new Exception("Could not write to new host");
|
1025 |
|
1026 |
+
if (!unlink($tmp_file))
|
1027 |
throw new Exception("Could not delete temporary file from new host");
|
1028 |
|
1029 |
$max_upload = $this->return_bytes((ini_get('upload_max_filesize')));
|
1030 |
$max_post = $this->return_bytes((ini_get('post_max_size')));
|
1031 |
|
1032 |
$return['max_upload_size'] = min($max_upload, $max_post); // bytes
|
1033 |
+
$return['status'] = true;
|
1034 |
|
1035 |
$this->logger->info(sprintf('Current filesystem max upload size is %s bytes', $return['max_upload_size']));
|
1036 |
|
1037 |
$this->send_response(200, $return);
|
1038 |
}
|
1039 |
+
|
1040 |
+
/**
|
1041 |
+
* Return bytes from human readable value
|
1042 |
+
*
|
1043 |
+
* @param string $val
|
1044 |
+
* @return int
|
1045 |
+
*
|
1046 |
+
*/
|
1047 |
private function return_bytes($val) {
|
1048 |
+
$numeric_val = (int)trim($val);
|
1049 |
+
$last = strtolower($val[strlen($val) - 1]);
|
1050 |
+
switch ($last) {
|
1051 |
+
// The 'G' modifier is available since PHP 5.1.0
|
1052 |
+
case 'g':
|
1053 |
+
//gigabytes
|
1054 |
+
$numeric_val *= 1024;
|
1055 |
+
case 'm':
|
1056 |
+
//megabytes
|
1057 |
+
$numeric_val *= 1024;
|
1058 |
+
case 'k':
|
1059 |
+
//kilobytes
|
1060 |
+
$numeric_val *= 1024;
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
return $numeric_val;
|
1064 |
}
|
1065 |
+
|
1066 |
+
/**
|
1067 |
+
* Check if backup archive os multipart
|
1068 |
+
*
|
1069 |
+
* @param $backup_name
|
1070 |
+
* @return bool
|
1071 |
+
*/
|
1072 |
public function is_multipart($backup_name)
|
1073 |
{
|
1074 |
+
if (stristr($backup_name, "-multipart"))
|
1075 |
return true;
|
1076 |
|
1077 |
return false;
|
1078 |
}
|
1079 |
+
|
1080 |
+
/**
|
1081 |
+
* Get backup archive size
|
1082 |
+
*
|
1083 |
+
* @param $backup_name
|
1084 |
+
* @return bool|false|int
|
1085 |
+
* @throws \League\Flysystem\FileNotFoundException
|
1086 |
+
*/
|
1087 |
public function get_backup_size($backup_name)
|
1088 |
{
|
1089 |
$backup_size = $this->filesystem->getSize($backup_name);
|
1090 |
+
if ($this->is_multipart($backup_name))
|
1091 |
{
|
1092 |
$backup_parts = $this->get_multipart_files($backup_name);
|
1093 |
+
foreach ($backup_parts as $part_file)
|
1094 |
$backup_size += $this->filesystem->getSize($part_file);
|
1095 |
}
|
1096 |
|
1097 |
return $backup_size;
|
1098 |
}
|
1099 |
+
|
1100 |
+
/**
|
1101 |
+
* Get multipart backup files list
|
1102 |
+
* @param $backup_name
|
1103 |
+
* @return array
|
1104 |
+
* @throws \League\Flysystem\FileNotFoundException
|
1105 |
+
*/
|
1106 |
public function get_multipart_files($backup_name)
|
1107 |
{
|
1108 |
$files = array();
|
1109 |
|
1110 |
+
if ($this->is_multipart($backup_name))
|
1111 |
{
|
1112 |
$lines = explode(PHP_EOL, $this->filesystem->read($backup_name));
|
1113 |
+
foreach ($lines as $line)
|
1114 |
{
|
1115 |
+
if ($line)
|
1116 |
{
|
1117 |
$data = str_getcsv($line);
|
1118 |
$files[] = $data[0];
|
1122 |
|
1123 |
return $files;
|
1124 |
}
|
1125 |
+
|
1126 |
+
/**
|
1127 |
+
* Sort_by method
|
1128 |
+
*
|
1129 |
+
* @param $array
|
1130 |
+
* @param string $field
|
1131 |
+
* @param string $direction
|
1132 |
+
* @return bool
|
1133 |
+
*/
|
1134 |
+
private function sort_by(&$array, $field, $direction = 'asc')
|
1135 |
{
|
1136 |
$direction = strtolower($direction);
|
1137 |
+
|
1138 |
+
usort($array,
|
1139 |
+
|
1140 |
+
/**
|
1141 |
+
* @param string $b
|
1142 |
+
*/
|
1143 |
+
function($a, $b) use($field, $direction){
|
1144 |
+
|
1145 |
+
$a = $a[$field];
|
1146 |
+
$b = $b[$field];
|
1147 |
+
|
1148 |
+
if ($a == $b)
|
1149 |
+
{
|
1150 |
+
return 0;
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
if ($direction == 'desc') {
|
1154 |
+
if ($a > $b) {
|
1155 |
+
return -1;
|
1156 |
+
}
|
1157 |
+
else {
|
1158 |
+
return 1;
|
1159 |
+
}
|
1160 |
+
} else {
|
1161 |
+
if ($a < $b) {
|
1162 |
+
return -1;
|
1163 |
+
}
|
1164 |
+
else {
|
1165 |
+
return 1;
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
//return ($a.($direction == 'desc' ? '>' : '<').$b) ? -1 : 1;
|
1170 |
+
}
|
1171 |
+
);
|
1172 |
+
|
1173 |
+
return true;
|
1174 |
}
|
1175 |
+
|
1176 |
+
/**
|
1177 |
+
* Send response method
|
1178 |
+
*
|
1179 |
+
* @param int $status
|
1180 |
+
* @param $response
|
1181 |
+
*/
|
1182 |
public static function send_response($status = 200, $response)
|
1183 |
{
|
1184 |
header("Access-Control-Allow-Origin: *");
|
1187 |
$return['status'] = $status;
|
1188 |
$return['statusText'] = $response;
|
1189 |
|
1190 |
+
if (isset($response['error']) && $response['error'])
|
1191 |
{
|
1192 |
$return['statusText'] = $response['message'];
|
1193 |
$return['error'] = true;
|
1194 |
+
}elseif ($status != 200 and $status != 418)
|
1195 |
{
|
1196 |
$return['error'] = true;
|
1197 |
$return['message'] = $response;
|
1198 |
}
|
1199 |
|
1200 |
+
die (json_encode($return));
|
1201 |
+
|
1202 |
}
|
1203 |
+
|
1204 |
+
/**
|
1205 |
* Serialize fix methods below for mysql query lines
|
1206 |
+
*
|
1207 |
+
* @param $query
|
1208 |
+
* @return string
|
1209 |
+
*/
|
1210 |
|
1211 |
function do_serialized_fix($query)
|
1212 |
{
|
1213 |
+
$query = str_replace(array("\\n", "\\r", "\\'"), array("", "", "\""), ($query));
|
1214 |
|
1215 |
+
return preg_replace_callback('!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!', function($m) {
|
1216 |
$data = "";
|
1217 |
|
1218 |
+
if (!isset($m[3]))
|
1219 |
$m[3] = "";
|
1220 |
|
1221 |
$data = 's:'.strlen(($m[3])).':\"'.($m[3]).'\";';
|
1222 |
+
//return $this->unescape_quotes($data);
|
1223 |
|
1224 |
+
return $data;
|
1225 |
+
}, $query);
|
1226 |
}
|
1227 |
+
|
1228 |
+
/**
|
1229 |
+
* Unescape quotes method
|
1230 |
+
*
|
1231 |
+
* @param $value
|
1232 |
+
* @return mixed
|
1233 |
+
*/
|
1234 |
private function unescape_quotes($value) {
|
1235 |
return str_replace('\"', '"', $value);
|
1236 |
}
|
1237 |
+
|
1238 |
+
/**
|
1239 |
+
* Unescape mysql method
|
1240 |
+
*
|
1241 |
+
* @param $value
|
1242 |
+
* @return mixed
|
1243 |
+
*/
|
1244 |
private function unescape_mysql($value) {
|
1245 |
+
return str_replace(array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'),
|
1246 |
+
array("\\", "\0", "\n", "\r", "\x1a", "'", '"'),
|
1247 |
$value);
|
1248 |
+
}
|
1249 |
+
|
1250 |
+
/**
|
1251 |
+
* Check if string is in serialized format
|
1252 |
+
*
|
1253 |
+
* @param $s
|
1254 |
+
* @return bool
|
1255 |
+
*/
|
1256 |
private function has_serialized($s)
|
1257 |
{
|
1258 |
+
if (
|
1259 |
+
stristr($s, '{') !== false &&
|
1260 |
+
stristr($s, '}') !== false &&
|
1261 |
+
stristr($s, ';') !== false &&
|
1262 |
+
stristr($s, ':') !== false
|
1263 |
+
) {
|
1264 |
+
return true;
|
1265 |
+
} else {
|
1266 |
+
return false;
|
1267 |
}
|
1268 |
|
1269 |
}
|
uninstall.php
CHANGED
@@ -26,6 +26,6 @@
|
|
26 |
*/
|
27 |
|
28 |
// If uninstall not called from WordPress, then exit.
|
29 |
-
if (
|
30 |
exit;
|
31 |
}
|
26 |
*/
|
27 |
|
28 |
// If uninstall not called from WordPress, then exit.
|
29 |
+
if (!defined('WP_UNINSTALL_PLUGIN')) {
|
30 |
exit;
|
31 |
}
|
vendor/composer/ClassLoader.php
CHANGED
@@ -279,7 +279,7 @@ class ClassLoader
|
|
279 |
*/
|
280 |
public function setApcuPrefix($apcuPrefix)
|
281 |
{
|
282 |
-
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
283 |
}
|
284 |
|
285 |
/**
|
@@ -377,7 +377,7 @@ class ClassLoader
|
|
377 |
$subPath = $class;
|
378 |
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
379 |
$subPath = substr($subPath, 0, $lastPos);
|
380 |
-
$search = $subPath.'\\';
|
381 |
if (isset($this->prefixDirsPsr4[$search])) {
|
382 |
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
383 |
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
279 |
*/
|
280 |
public function setApcuPrefix($apcuPrefix)
|
281 |
{
|
282 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
283 |
}
|
284 |
|
285 |
/**
|
377 |
$subPath = $class;
|
378 |
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
379 |
$subPath = substr($subPath, 0, $lastPos);
|
380 |
+
$search = $subPath . '\\';
|
381 |
if (isset($this->prefixDirsPsr4[$search])) {
|
382 |
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
383 |
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
vendor/composer/autoload_files.php
CHANGED
@@ -18,6 +18,5 @@ return array(
|
|
18 |
'93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php',
|
19 |
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php',
|
20 |
'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php',
|
21 |
-
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
|
22 |
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
23 |
);
|
18 |
'93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php',
|
19 |
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php',
|
20 |
'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php',
|
|
|
21 |
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
22 |
);
|
vendor/composer/autoload_psr4.php
CHANGED
@@ -32,7 +32,6 @@ return array(
|
|
32 |
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
33 |
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
34 |
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
35 |
-
'Defuse\\Crypto\\' => array($vendorDir . '/defuse/php-encryption/src'),
|
36 |
'BackblazeB2\\' => array($vendorDir . '/gliterd/backblaze-b2/src'),
|
37 |
'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'),
|
38 |
);
|
32 |
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
33 |
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
34 |
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
|
|
35 |
'BackblazeB2\\' => array($vendorDir . '/gliterd/backblaze-b2/src'),
|
36 |
'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'),
|
37 |
);
|
vendor/composer/autoload_static.php
CHANGED
@@ -19,7 +19,6 @@ class ComposerStaticInit571f9d19802717f7be61d57b40d60b28
|
|
19 |
'93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php',
|
20 |
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php',
|
21 |
'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php',
|
22 |
-
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
|
23 |
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
24 |
);
|
25 |
|
@@ -74,10 +73,6 @@ class ComposerStaticInit571f9d19802717f7be61d57b40d60b28
|
|
74 |
'GuzzleHttp\\Promise\\' => 19,
|
75 |
'GuzzleHttp\\' => 11,
|
76 |
),
|
77 |
-
'D' =>
|
78 |
-
array (
|
79 |
-
'Defuse\\Crypto\\' => 14,
|
80 |
-
),
|
81 |
'B' =>
|
82 |
array (
|
83 |
'BackblazeB2\\' => 12,
|
@@ -193,10 +188,6 @@ class ComposerStaticInit571f9d19802717f7be61d57b40d60b28
|
|
193 |
array (
|
194 |
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
|
195 |
),
|
196 |
-
'Defuse\\Crypto\\' =>
|
197 |
-
array (
|
198 |
-
0 => __DIR__ . '/..' . '/defuse/php-encryption/src',
|
199 |
-
),
|
200 |
'BackblazeB2\\' =>
|
201 |
array (
|
202 |
0 => __DIR__ . '/..' . '/gliterd/backblaze-b2/src',
|
19 |
'93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php',
|
20 |
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php',
|
21 |
'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php',
|
|
|
22 |
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
23 |
);
|
24 |
|
73 |
'GuzzleHttp\\Promise\\' => 19,
|
74 |
'GuzzleHttp\\' => 11,
|
75 |
),
|
|
|
|
|
|
|
|
|
76 |
'B' =>
|
77 |
array (
|
78 |
'BackblazeB2\\' => 12,
|
188 |
array (
|
189 |
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
|
190 |
),
|
|
|
|
|
|
|
|
|
191 |
'BackblazeB2\\' =>
|
192 |
array (
|
193 |
0 => __DIR__ . '/..' . '/gliterd/backblaze-b2/src',
|
vendor/composer/installed.json
CHANGED
@@ -125,71 +125,6 @@
|
|
125 |
"description": "jQuery JavaScript Library",
|
126 |
"homepage": "http://jquery.com"
|
127 |
},
|
128 |
-
{
|
129 |
-
"name": "defuse/php-encryption",
|
130 |
-
"version": "v2.2.0",
|
131 |
-
"version_normalized": "2.2.0.0",
|
132 |
-
"source": {
|
133 |
-
"type": "git",
|
134 |
-
"url": "https://github.com/defuse/php-encryption.git",
|
135 |
-
"reference": "0d4d27c368ca6798bc162469e43248c363c73495"
|
136 |
-
},
|
137 |
-
"dist": {
|
138 |
-
"type": "zip",
|
139 |
-
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/0d4d27c368ca6798bc162469e43248c363c73495",
|
140 |
-
"reference": "0d4d27c368ca6798bc162469e43248c363c73495",
|
141 |
-
"shasum": ""
|
142 |
-
},
|
143 |
-
"require": {
|
144 |
-
"ext-openssl": "*",
|
145 |
-
"paragonie/random_compat": "~2.0",
|
146 |
-
"php": ">=5.4.0"
|
147 |
-
},
|
148 |
-
"require-dev": {
|
149 |
-
"nikic/php-parser": "^2.0|^3.0|^4.0",
|
150 |
-
"phpunit/phpunit": "^4|^5"
|
151 |
-
},
|
152 |
-
"time": "2018-04-23T19:33:40+00:00",
|
153 |
-
"bin": [
|
154 |
-
"bin/generate-defuse-key"
|
155 |
-
],
|
156 |
-
"type": "library",
|
157 |
-
"installation-source": "dist",
|
158 |
-
"autoload": {
|
159 |
-
"psr-4": {
|
160 |
-
"Defuse\\Crypto\\": "src"
|
161 |
-
}
|
162 |
-
},
|
163 |
-
"notification-url": "https://packagist.org/downloads/",
|
164 |
-
"license": [
|
165 |
-
"MIT"
|
166 |
-
],
|
167 |
-
"authors": [
|
168 |
-
{
|
169 |
-
"name": "Taylor Hornby",
|
170 |
-
"email": "taylor@defuse.ca",
|
171 |
-
"homepage": "https://defuse.ca/"
|
172 |
-
},
|
173 |
-
{
|
174 |
-
"name": "Scott Arciszewski",
|
175 |
-
"email": "info@paragonie.com",
|
176 |
-
"homepage": "https://paragonie.com"
|
177 |
-
}
|
178 |
-
],
|
179 |
-
"description": "Secure PHP Encryption Library",
|
180 |
-
"keywords": [
|
181 |
-
"aes",
|
182 |
-
"authenticated encryption",
|
183 |
-
"cipher",
|
184 |
-
"crypto",
|
185 |
-
"cryptography",
|
186 |
-
"encrypt",
|
187 |
-
"encryption",
|
188 |
-
"openssl",
|
189 |
-
"security",
|
190 |
-
"symmetric key cryptography"
|
191 |
-
]
|
192 |
-
},
|
193 |
{
|
194 |
"name": "gliterd/backblaze-b2",
|
195 |
"version": "1.0.4",
|
@@ -435,29 +370,29 @@
|
|
435 |
},
|
436 |
{
|
437 |
"name": "league/flysystem",
|
438 |
-
"version": "1.0.
|
439 |
-
"version_normalized": "1.0.
|
440 |
"source": {
|
441 |
"type": "git",
|
442 |
"url": "https://github.com/thephpleague/flysystem.git",
|
443 |
-
"reference": "
|
444 |
},
|
445 |
"dist": {
|
446 |
"type": "zip",
|
447 |
-
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/
|
448 |
-
"reference": "
|
449 |
"shasum": ""
|
450 |
},
|
451 |
"require": {
|
|
|
452 |
"php": ">=5.5.9"
|
453 |
},
|
454 |
"conflict": {
|
455 |
"league/flysystem-sftp": "<1.0.6"
|
456 |
},
|
457 |
"require-dev": {
|
458 |
-
"ext-fileinfo": "*",
|
459 |
"phpspec/phpspec": "^3.4",
|
460 |
-
"phpunit/phpunit": "^5.7"
|
461 |
},
|
462 |
"suggest": {
|
463 |
"ext-fileinfo": "Required for MimeType",
|
@@ -475,7 +410,7 @@
|
|
475 |
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
|
476 |
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
|
477 |
},
|
478 |
-
"time": "2018-
|
479 |
"type": "library",
|
480 |
"extra": {
|
481 |
"branch-alias": {
|
@@ -620,35 +555,30 @@
|
|
620 |
},
|
621 |
{
|
622 |
"name": "league/flysystem-sftp",
|
623 |
-
"version": "1.0.
|
624 |
-
"version_normalized": "1.0.
|
625 |
"source": {
|
626 |
"type": "git",
|
627 |
"url": "https://github.com/thephpleague/flysystem-sftp.git",
|
628 |
-
"reference": "
|
629 |
},
|
630 |
"dist": {
|
631 |
"type": "zip",
|
632 |
-
"url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/
|
633 |
-
"reference": "
|
634 |
"shasum": ""
|
635 |
},
|
636 |
"require": {
|
637 |
"league/flysystem": "~1.0",
|
638 |
-
"php": ">=5.
|
639 |
"phpseclib/phpseclib": "~2.0"
|
640 |
},
|
641 |
"require-dev": {
|
642 |
"mockery/mockery": "0.9.*",
|
643 |
-
"phpunit/phpunit": "
|
644 |
},
|
645 |
-
"time": "
|
646 |
"type": "library",
|
647 |
-
"extra": {
|
648 |
-
"branch-alias": {
|
649 |
-
"dev-master": "1.0-dev"
|
650 |
-
}
|
651 |
-
},
|
652 |
"installation-source": "source",
|
653 |
"autoload": {
|
654 |
"psr-4": {
|
@@ -1019,57 +949,6 @@
|
|
1019 |
"jsonpath"
|
1020 |
]
|
1021 |
},
|
1022 |
-
{
|
1023 |
-
"name": "paragonie/random_compat",
|
1024 |
-
"version": "v2.0.15",
|
1025 |
-
"version_normalized": "2.0.15.0",
|
1026 |
-
"source": {
|
1027 |
-
"type": "git",
|
1028 |
-
"url": "https://github.com/paragonie/random_compat.git",
|
1029 |
-
"reference": "10bcb46e8f3d365170f6de9d05245aa066b81f09"
|
1030 |
-
},
|
1031 |
-
"dist": {
|
1032 |
-
"type": "zip",
|
1033 |
-
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/10bcb46e8f3d365170f6de9d05245aa066b81f09",
|
1034 |
-
"reference": "10bcb46e8f3d365170f6de9d05245aa066b81f09",
|
1035 |
-
"shasum": ""
|
1036 |
-
},
|
1037 |
-
"require": {
|
1038 |
-
"php": ">=5.2.0"
|
1039 |
-
},
|
1040 |
-
"require-dev": {
|
1041 |
-
"phpunit/phpunit": "4.*|5.*"
|
1042 |
-
},
|
1043 |
-
"suggest": {
|
1044 |
-
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
1045 |
-
},
|
1046 |
-
"time": "2018-06-08T15:26:40+00:00",
|
1047 |
-
"type": "library",
|
1048 |
-
"installation-source": "dist",
|
1049 |
-
"autoload": {
|
1050 |
-
"files": [
|
1051 |
-
"lib/random.php"
|
1052 |
-
]
|
1053 |
-
},
|
1054 |
-
"notification-url": "https://packagist.org/downloads/",
|
1055 |
-
"license": [
|
1056 |
-
"MIT"
|
1057 |
-
],
|
1058 |
-
"authors": [
|
1059 |
-
{
|
1060 |
-
"name": "Paragon Initiative Enterprises",
|
1061 |
-
"email": "security@paragonie.com",
|
1062 |
-
"homepage": "https://paragonie.com"
|
1063 |
-
}
|
1064 |
-
],
|
1065 |
-
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
1066 |
-
"keywords": [
|
1067 |
-
"csprng",
|
1068 |
-
"polyfill",
|
1069 |
-
"pseudorandom",
|
1070 |
-
"random"
|
1071 |
-
]
|
1072 |
-
},
|
1073 |
{
|
1074 |
"name": "phpseclib/phpseclib",
|
1075 |
"version": "2.0.11",
|
@@ -1793,17 +1672,17 @@
|
|
1793 |
},
|
1794 |
{
|
1795 |
"name": "vakata/jstree",
|
1796 |
-
"version": "3.3.
|
1797 |
-
"version_normalized": "3.3.
|
1798 |
"source": {
|
1799 |
"type": "git",
|
1800 |
"url": "https://github.com/vakata/jstree.git",
|
1801 |
-
"reference": "
|
1802 |
},
|
1803 |
"dist": {
|
1804 |
"type": "zip",
|
1805 |
-
"url": "https://api.github.com/repos/vakata/jstree/zipball/
|
1806 |
-
"reference": "
|
1807 |
"shasum": ""
|
1808 |
},
|
1809 |
"require": {
|
@@ -1812,7 +1691,7 @@
|
|
1812 |
"suggest": {
|
1813 |
"robloach/component-installer": "Allows installation of Components via Composer"
|
1814 |
},
|
1815 |
-
"time": "2018-
|
1816 |
"type": "component",
|
1817 |
"extra": {
|
1818 |
"component": {
|
125 |
"description": "jQuery JavaScript Library",
|
126 |
"homepage": "http://jquery.com"
|
127 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
{
|
129 |
"name": "gliterd/backblaze-b2",
|
130 |
"version": "1.0.4",
|
370 |
},
|
371 |
{
|
372 |
"name": "league/flysystem",
|
373 |
+
"version": "1.0.49",
|
374 |
+
"version_normalized": "1.0.49.0",
|
375 |
"source": {
|
376 |
"type": "git",
|
377 |
"url": "https://github.com/thephpleague/flysystem.git",
|
378 |
+
"reference": "a63cc83d8a931b271be45148fa39ba7156782ffd"
|
379 |
},
|
380 |
"dist": {
|
381 |
"type": "zip",
|
382 |
+
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a63cc83d8a931b271be45148fa39ba7156782ffd",
|
383 |
+
"reference": "a63cc83d8a931b271be45148fa39ba7156782ffd",
|
384 |
"shasum": ""
|
385 |
},
|
386 |
"require": {
|
387 |
+
"ext-fileinfo": "*",
|
388 |
"php": ">=5.5.9"
|
389 |
},
|
390 |
"conflict": {
|
391 |
"league/flysystem-sftp": "<1.0.6"
|
392 |
},
|
393 |
"require-dev": {
|
|
|
394 |
"phpspec/phpspec": "^3.4",
|
395 |
+
"phpunit/phpunit": "^5.7.10"
|
396 |
},
|
397 |
"suggest": {
|
398 |
"ext-fileinfo": "Required for MimeType",
|
410 |
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
|
411 |
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
|
412 |
},
|
413 |
+
"time": "2018-11-23T23:41:29+00:00",
|
414 |
"type": "library",
|
415 |
"extra": {
|
416 |
"branch-alias": {
|
555 |
},
|
556 |
{
|
557 |
"name": "league/flysystem-sftp",
|
558 |
+
"version": "1.0.18",
|
559 |
+
"version_normalized": "1.0.18.0",
|
560 |
"source": {
|
561 |
"type": "git",
|
562 |
"url": "https://github.com/thephpleague/flysystem-sftp.git",
|
563 |
+
"reference": "61bc5a6ade892b5ac81e62b8c21be2c1798acc2a"
|
564 |
},
|
565 |
"dist": {
|
566 |
"type": "zip",
|
567 |
+
"url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/61bc5a6ade892b5ac81e62b8c21be2c1798acc2a",
|
568 |
+
"reference": "61bc5a6ade892b5ac81e62b8c21be2c1798acc2a",
|
569 |
"shasum": ""
|
570 |
},
|
571 |
"require": {
|
572 |
"league/flysystem": "~1.0",
|
573 |
+
"php": ">=5.6.0",
|
574 |
"phpseclib/phpseclib": "~2.0"
|
575 |
},
|
576 |
"require-dev": {
|
577 |
"mockery/mockery": "0.9.*",
|
578 |
+
"phpunit/phpunit": "^5.7.25"
|
579 |
},
|
580 |
+
"time": "2019-01-07T11:56:21+00:00",
|
581 |
"type": "library",
|
|
|
|
|
|
|
|
|
|
|
582 |
"installation-source": "source",
|
583 |
"autoload": {
|
584 |
"psr-4": {
|
949 |
"jsonpath"
|
950 |
]
|
951 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
952 |
{
|
953 |
"name": "phpseclib/phpseclib",
|
954 |
"version": "2.0.11",
|
1672 |
},
|
1673 |
{
|
1674 |
"name": "vakata/jstree",
|
1675 |
+
"version": "3.3.7",
|
1676 |
+
"version_normalized": "3.3.7.0",
|
1677 |
"source": {
|
1678 |
"type": "git",
|
1679 |
"url": "https://github.com/vakata/jstree.git",
|
1680 |
+
"reference": "bc5187e5826244dee5ebdc0e9db2e2652fefe928"
|
1681 |
},
|
1682 |
"dist": {
|
1683 |
"type": "zip",
|
1684 |
+
"url": "https://api.github.com/repos/vakata/jstree/zipball/bc5187e5826244dee5ebdc0e9db2e2652fefe928",
|
1685 |
+
"reference": "bc5187e5826244dee5ebdc0e9db2e2652fefe928",
|
1686 |
"shasum": ""
|
1687 |
},
|
1688 |
"require": {
|
1691 |
"suggest": {
|
1692 |
"robloach/component-installer": "Allows installation of Components via Composer"
|
1693 |
},
|
1694 |
+
"time": "2018-11-06T21:15:47+00:00",
|
1695 |
"type": "component",
|
1696 |
"extra": {
|
1697 |
"component": {
|
vendor/defuse/php-encryption/.gitignore
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
*~
|
2 |
-
/test/unit/File/big-generated-file
|
3 |
-
/composer.lock
|
4 |
-
/vendor
|
5 |
-
defuse-crypto.phar
|
6 |
-
defuse-crypto.phar.sig
|
7 |
-
composer.phar
|
8 |
-
box.phar
|
9 |
-
phpunit.phar
|
10 |
-
phpunit.phar.asc
|
11 |
-
test/unit/File/tmp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/.php_cs
DELETED
@@ -1,60 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
$config = Symfony\CS\Config\Config::create()
|
4 |
-
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
|
5 |
-
->fixers([
|
6 |
-
'blankline_after_open_tag',
|
7 |
-
'empty_return',
|
8 |
-
'extra_empty_lines',
|
9 |
-
'function_typehint_space',
|
10 |
-
'join_function',
|
11 |
-
'method_argument_default_value',
|
12 |
-
'multiline_array_trailing_comma',
|
13 |
-
'no_blank_lines_after_class_opening',
|
14 |
-
'no_empty_lines_after_phpdocs',
|
15 |
-
'phpdoc_indent',
|
16 |
-
'phpdoc_no_access',
|
17 |
-
'phpdoc_no_empty_return',
|
18 |
-
'phpdoc_no_package',
|
19 |
-
'phpdoc_params',
|
20 |
-
'phpdoc_scalar',
|
21 |
-
'phpdoc_separation',
|
22 |
-
'phpdoc_trim',
|
23 |
-
'phpdoc_type_to_var',
|
24 |
-
'phpdoc_types',
|
25 |
-
'phpdoc_var_without_name',
|
26 |
-
'remove_leading_slash_use',
|
27 |
-
'remove_lines_between_uses',
|
28 |
-
'short_bool_cast',
|
29 |
-
'single_quote',
|
30 |
-
'spaces_after_semicolon',
|
31 |
-
'spaces_before_semicolon',
|
32 |
-
'spaces_cast',
|
33 |
-
'standardize_not_equal',
|
34 |
-
'ternary_spaces',
|
35 |
-
'trim_array_spaces',
|
36 |
-
'unneeded_control_parentheses',
|
37 |
-
'unused_use',
|
38 |
-
'whitespacy_lines',
|
39 |
-
'align_double_arrow',
|
40 |
-
'concat_with_spaces',
|
41 |
-
'logical_not_operators_with_successor_space',
|
42 |
-
'multiline_spaces_before_semicolon',
|
43 |
-
'newline_after_open_tag',
|
44 |
-
'ordered_use',
|
45 |
-
'php_unit_construct',
|
46 |
-
'phpdoc_order',
|
47 |
-
'short_array_syntax',
|
48 |
-
]);
|
49 |
-
|
50 |
-
if (null === $input->getArgument('path')) {
|
51 |
-
$config
|
52 |
-
->finder(
|
53 |
-
Symfony\CS\Finder\DefaultFinder::create()
|
54 |
-
->in('src')
|
55 |
-
->in('test')
|
56 |
-
->exclude('vendor')
|
57 |
-
);
|
58 |
-
}
|
59 |
-
|
60 |
-
return $config;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/LICENSE
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
The MIT License (MIT)
|
2 |
-
|
3 |
-
Copyright (c) 2016 Taylor Hornby <https://defuse.ca> and Paragon Initiative
|
4 |
-
Enterprises <https://paragonie.com>.
|
5 |
-
|
6 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
7 |
-
this software and associated documentation files (the "Software"), to deal in
|
8 |
-
the Software without restriction, including without limitation the rights to
|
9 |
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
10 |
-
the Software, and to permit persons to whom the Software is furnished to do so,
|
11 |
-
subject to the following conditions:
|
12 |
-
|
13 |
-
The above copyright notice and this permission notice shall be included in all
|
14 |
-
copies or substantial portions of the Software.
|
15 |
-
|
16 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
18 |
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
19 |
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
20 |
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
21 |
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/README.md
DELETED
@@ -1,102 +0,0 @@
|
|
1 |
-
php-encryption
|
2 |
-
===============
|
3 |
-
|
4 |
-
[![Build Status](https://travis-ci.org/defuse/php-encryption.svg?branch=master)](https://travis-ci.org/defuse/php-encryption)
|
5 |
-
[![codecov](https://codecov.io/gh/defuse/php-encryption/branch/master/graph/badge.svg)](https://codecov.io/gh/defuse/php-encryption)
|
6 |
-
[![Latest Stable Version](https://poser.pugx.org/defuse/php-encryption/v/stable)](https://packagist.org/packages/defuse/php-encryption)
|
7 |
-
[![Latest Unstable Version](https://poser.pugx.org/defuse/php-encryption/v/unstable)](https://packagist.org/packages/defuse/php-encryption)
|
8 |
-
[![License](https://poser.pugx.org/defuse/php-encryption/license)](https://packagist.org/packages/defuse/php-encryption)
|
9 |
-
[![Downloads](https://img.shields.io/packagist/dt/defuse/php-encryption.svg)](https://packagist.org/packages/defuse/php-encryption)
|
10 |
-
|
11 |
-
This is a library for encrypting data with a key or password in PHP. **It
|
12 |
-
requires PHP 5.6 or newer and OpenSSL 1.0.1 or newer.** The current version is
|
13 |
-
v2.2.0, which is expected to remain stable and supported by its authors with
|
14 |
-
security and bugfixes until at least January 1st, 2020.
|
15 |
-
|
16 |
-
The library is a joint effort between [Taylor Hornby](https://defuse.ca/) and
|
17 |
-
[Scott Arciszewski](https://paragonie.com/blog/author/scott-arcizewski) as well
|
18 |
-
as numerous open-source contributors.
|
19 |
-
|
20 |
-
What separates this library from other PHP encryption libraries is, firstly,
|
21 |
-
that it is secure. The authors used to encounter insecure PHP encryption code on
|
22 |
-
a daily basis, so they created this library to bring more security to the
|
23 |
-
ecosystem. Secondly, this library is "difficult to misuse." Like
|
24 |
-
[libsodium](https://github.com/jedisct1/libsodium), its API is designed to be
|
25 |
-
easy to use in a secure way and hard to use in an insecure way.
|
26 |
-
|
27 |
-
|
28 |
-
Dependencies
|
29 |
-
------------
|
30 |
-
|
31 |
-
This library requires no special dependencies except for PHP 5.6 or newer with
|
32 |
-
the OpenSSL extensions (version 1.0.1 or later) enabled (this is the default).
|
33 |
-
It uses [random\_compat](https://github.com/paragonie/random_compat), which is
|
34 |
-
bundled in with this library so that your users will not need to follow any
|
35 |
-
special installation steps.
|
36 |
-
|
37 |
-
Getting Started
|
38 |
-
----------------
|
39 |
-
|
40 |
-
Start with the [**Tutorial**](docs/Tutorial.md). You can find instructions for
|
41 |
-
obtaining this library's code securely in the [Installing and
|
42 |
-
Verifying](docs/InstallingAndVerifying.md) documentation.
|
43 |
-
|
44 |
-
After you've read the tutorial and got the code, refer to the formal
|
45 |
-
documentation for each of the classes this library provides:
|
46 |
-
|
47 |
-
- [Crypto](docs/classes/Crypto.md)
|
48 |
-
- [File](docs/classes/File.md)
|
49 |
-
- [Key](docs/classes/Key.md)
|
50 |
-
- [KeyProtectedByPassword](docs/classes/KeyProtectedByPassword.md)
|
51 |
-
|
52 |
-
If you encounter difficulties, see the [FAQ](docs/FAQ.md) answers. The fixes to
|
53 |
-
the most commonly-reported problems are explained there.
|
54 |
-
|
55 |
-
If you're a cryptographer and want to understand the nitty-gritty details of how
|
56 |
-
this library works, look at the [Cryptography Details](docs/CryptoDetails.md)
|
57 |
-
documentation.
|
58 |
-
|
59 |
-
If you're interested in contributing to this library, see the [Internal
|
60 |
-
Developer Documentation](docs/InternalDeveloperDocs.md).
|
61 |
-
|
62 |
-
Other Language Support
|
63 |
-
----------------------
|
64 |
-
|
65 |
-
This library is intended for server-side PHP software that needs to encrypt data at rest.
|
66 |
-
If you are building software that needs to encrypt client-side, or building a system that
|
67 |
-
requires cross-platform encryption/decryption support, we strongly recommend using
|
68 |
-
[libsodium](https://download.libsodium.org/doc/bindings_for_other_languages) instead.
|
69 |
-
|
70 |
-
Examples
|
71 |
-
---------
|
72 |
-
|
73 |
-
If the documentation is not enough for you to understand how to use this
|
74 |
-
library, then you can look at an example project that uses this library:
|
75 |
-
|
76 |
-
- [encutil](https://github.com/defuse/encutil)
|
77 |
-
- [fileencrypt](https://github.com/tsusanka/fileencrypt)
|
78 |
-
|
79 |
-
Security Audit Status
|
80 |
-
---------------------
|
81 |
-
|
82 |
-
This code has not been subjected to a formal, paid, security audit. However, it
|
83 |
-
has received lots of review from members of the PHP security community, and the
|
84 |
-
authors are experienced with cryptography. In all likelihood, you are safer
|
85 |
-
using this library than almost any other encryption library for PHP.
|
86 |
-
|
87 |
-
If you use this library as a part of your business and would like to help fund
|
88 |
-
a formal audit, please [contact Taylor Hornby](https://defuse.ca/contact.htm).
|
89 |
-
|
90 |
-
Public Keys
|
91 |
-
------------
|
92 |
-
|
93 |
-
The GnuPG public key used to sign releases is available in
|
94 |
-
[dist/signingkey.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey.asc). Its fingerprint is:
|
95 |
-
|
96 |
-
```
|
97 |
-
2FA6 1D8D 99B9 2658 6BAC 3D53 385E E055 A129 1538
|
98 |
-
```
|
99 |
-
|
100 |
-
You can verify it against Taylor Hornby's [contact
|
101 |
-
page](https://defuse.ca/contact.htm) and
|
102 |
-
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/bin/generate-defuse-key
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
#!/usr/bin/env php
|
2 |
-
<?php
|
3 |
-
|
4 |
-
use Defuse\Crypto\Key;
|
5 |
-
|
6 |
-
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
|
7 |
-
if (file_exists($file)) {
|
8 |
-
require $file;
|
9 |
-
break;
|
10 |
-
}
|
11 |
-
}
|
12 |
-
|
13 |
-
$key = Key::createNewRandomKey();
|
14 |
-
echo $key->saveToAsciiSafeString(), "\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/composer.json
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "defuse/php-encryption",
|
3 |
-
"description": "Secure PHP Encryption Library",
|
4 |
-
"license": "MIT",
|
5 |
-
"keywords": ["security", "encryption", "AES", "openssl", "cipher", "cryptography", "symmetric key cryptography", "crypto", "encrypt", "authenticated encryption"],
|
6 |
-
"authors": [
|
7 |
-
{
|
8 |
-
"name": "Taylor Hornby",
|
9 |
-
"email": "taylor@defuse.ca",
|
10 |
-
"homepage": "https://defuse.ca/"
|
11 |
-
},
|
12 |
-
{
|
13 |
-
"name": "Scott Arciszewski",
|
14 |
-
"email": "info@paragonie.com",
|
15 |
-
"homepage": "https://paragonie.com"
|
16 |
-
}
|
17 |
-
],
|
18 |
-
"autoload": {
|
19 |
-
"psr-4": {
|
20 |
-
"Defuse\\Crypto\\": "src"
|
21 |
-
}
|
22 |
-
},
|
23 |
-
"require": {
|
24 |
-
"paragonie/random_compat": "~2.0",
|
25 |
-
"ext-openssl": "*",
|
26 |
-
"php": ">=5.4.0"
|
27 |
-
},
|
28 |
-
"require-dev": {
|
29 |
-
"phpunit/phpunit": "^4|^5",
|
30 |
-
"nikic/php-parser": "^2.0|^3.0|^4.0"
|
31 |
-
},
|
32 |
-
"bin": [
|
33 |
-
"bin/generate-defuse-key"
|
34 |
-
]
|
35 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/dist/Makefile
DELETED
@@ -1,37 +0,0 @@
|
|
1 |
-
# This builds defuse-crypto.phar. To run this Makefile, `box` and `composer`
|
2 |
-
# must be installed and in your $PATH. Run it from inside the dist/ directory.
|
3 |
-
|
4 |
-
box := $(shell which box)
|
5 |
-
composer := "composer"
|
6 |
-
|
7 |
-
.PHONY: all
|
8 |
-
all: build-phar
|
9 |
-
|
10 |
-
.PHONY: sign-phar
|
11 |
-
sign-phar:
|
12 |
-
gpg -u 7B4B2D98 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar
|
13 |
-
|
14 |
-
# ensure we run in clean tree. export git tree and run there.
|
15 |
-
.PHONY: build-phar
|
16 |
-
build-phar:
|
17 |
-
@echo "Creating .phar from revision $(shell git rev-parse HEAD)."
|
18 |
-
rm -rf worktree
|
19 |
-
install -d worktree
|
20 |
-
(cd $(CURDIR)/..; git archive HEAD) | tar -x -C worktree
|
21 |
-
$(MAKE) -f $(CURDIR)/Makefile -C worktree defuse-crypto.phar
|
22 |
-
mv worktree/*.phar .
|
23 |
-
rm -rf worktree
|
24 |
-
|
25 |
-
.PHONY: clean
|
26 |
-
clean:
|
27 |
-
rm -vf defuse-crypto.phar defuse-crypto.phar.sig
|
28 |
-
|
29 |
-
# Inside workdir/:
|
30 |
-
|
31 |
-
defuse-crypto.phar: dist/box.json composer.lock
|
32 |
-
cp dist/box.json .
|
33 |
-
php -d phar.readonly=0 $(box) build -c box.json -v
|
34 |
-
|
35 |
-
composer.lock:
|
36 |
-
$(composer) install --no-dev
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/dist/box.json
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"chmod": "0755",
|
3 |
-
"finder": [
|
4 |
-
{
|
5 |
-
"in": "src",
|
6 |
-
"name": "*.php"
|
7 |
-
},
|
8 |
-
{
|
9 |
-
"in": "vendor/composer",
|
10 |
-
"name": "*.php"
|
11 |
-
},
|
12 |
-
{
|
13 |
-
"in": "vendor/paragonie",
|
14 |
-
"name": "*.php",
|
15 |
-
"exclude": "other"
|
16 |
-
}
|
17 |
-
],
|
18 |
-
"compactors": [
|
19 |
-
"Herrera\\Box\\Compactor\\Php"
|
20 |
-
],
|
21 |
-
"main": "vendor/autoload.php",
|
22 |
-
"output": "defuse-crypto.phar",
|
23 |
-
"shebang": false,
|
24 |
-
"stub": true
|
25 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/dist/signingkey.asc
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2 |
-
Version: GnuPG v2
|
3 |
-
|
4 |
-
mQINBFarvO4BEACdQBaLt6SUBx1cB5liUu1qo+YwVLh9bxTregQtmEREMdTVqXYt
|
5 |
-
e5b79uL4pQp2GlKHcEyRURS+6rIIruM0oh9ZYGTJYPAkCDzJxaU2awZeFbfBvpCm
|
6 |
-
iF66/O4ZJI4mlT8dFKmxBJxDhfeOR2UmmhDiEsJK9FxBKUzvo/dWrX2pBzf8Y122
|
7 |
-
iIaVraSo+tymaf7vriaIf/NnSKhDw8dtQYGM4NMrxxsPTfbCF8XiboDgTkoD2A+6
|
8 |
-
NpOJYxA4Veedsf2TP9YLhljH4m5yYlfjjqBzbBCPWuE6Hhy5Xze9mncgDr7LKenm
|
9 |
-
Ctf2NxW6y4O3RCI+9eLlBfFWB+KuGV87/b5daetX7NNLbjID8z2rqEa+d6wu5xA5
|
10 |
-
Ta2uiVkAOEovr3XnkayZ9zth+Za7w7Ai0ln0N/LVMkM+Gu4z/pJv6HjmTGDM2wJb
|
11 |
-
fs+UOM0TFdg+N81Do67XT2M4o0MeHyUqsIiWpYa2Qf1PNmqTQNJnRk8uZZ9I96Nh
|
12 |
-
eCgNuCbhsQiYBMicox+xmuWAlGAfA06y0kCtmqGhiBGArdJlWvUqPqGiZ4Hln9z0
|
13 |
-
FJmXDOh0Q/FIPxcDg8mKRRbx+lOP389PLsPpj4b2B/4PEgfpCCOwuKpLotATZxC1
|
14 |
-
9JwFk0Y/cvUUkq4a+nAJBNtBbtRJkEesuuUnRq6XexmnE3uUucDcV0XCSwARAQAB
|
15 |
-
tCBUYXlsb3IgSG9ybmJ5IDx0YXlsb3JAZGVmdXNlLmNhPokCPQQTAQgAJwUCVqu8
|
16 |
-
7gIbAwUJB4TOAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA4XuBVoSkVOJbx
|
17 |
-
EACG0F9blPMAsK05EWyNnnS4mw25zPfbaqqEvYbquAeM0nBpRDm7sRn2MNR0AL4g
|
18 |
-
7XrtxE/4qYkdEl6f2wFCQeRhZgxE3w22llredzLme11Hic8hn4i7ysdIw0r9dMMR
|
19 |
-
kjgR5UcWpv8iU847czyK09PkKW2EaLRbX2qbA7rNU5qCFKeD4Sy4bBTteISeVsHo
|
20 |
-
Vr9o1/bRrMhgZ++ts8hYf0LmujIf5cxp+qcdKwCXSnS/gmmXaKRMCPv/Wdlq9bt6
|
21 |
-
LX9jZB9lXBdGxcBJeFOsTG+QRDiVjg3d6i3o3TAKV87ALBI4v2ADEYtN8lviHo3/
|
22 |
-
SovVKv6zrUsZHxhoGiLTiksNrYsKMmiMxdJCoOazmtUPnZ4UOtT8NdqMPoKvdoRz
|
23 |
-
f4rhZ+f5jSVD9OuX2PDmfyq21Rdiym7Vcgr+uTIFJ3ShRHjWb/ytCwoB2FeGY6+G
|
24 |
-
AKY58bTQvUIqEJvSov/+TAqZ4BfOuSdTLcHglV1OdUu2SFZvU2gmyVp0l5elGv5t
|
25 |
-
FyUlBJUkQT9MtvsdLOR7vQi8QapV+9LWpqwvaj9hyEJz848DQ2sdYTphUytFHv7H
|
26 |
-
k58DAtVhTrVjHyeefjiYtMl6vSAgTjy5LWAUpo5TfhdGrAi0Tdd/GD7amHoWoDy8
|
27 |
-
EKXKq2xPLo3JOdkWYQUi5NErzEskfsSzpCOgyDJmGetWK7kCDQRWq7zuARAAu7/i
|
28 |
-
cm8cjgLhHEX/bgfwOT2hLOLSjjve0O8YFSuJO9XqIHXqmfVOrqWtfG0Mh4bwlfqc
|
29 |
-
MAvBfF5NSSPfAE4ftBAQ1e5jEv8hJeqICpq3IHTFX4etBs49NfNkyveQl/amVTu1
|
30 |
-
+/O5J4CuIcsEf3y0Xuu38n7EB3SfMQCWLcOR1NyZoX3bI+CGRpOVVoFse3ljSWL4
|
31 |
-
LhLVl0WiEMXULsussEoN+c6x9KCyAi/jFOrxrTrFC//sZesKj6KucoqKGfwMWrrv
|
32 |
-
IeRT9Ga8Wn5MJnQu0aWg+zVVYqTedXZLNLODgQIInFnXO0seBXy15yDok1y5bkx2
|
33 |
-
sinKg4+mueYaGUpoUti0hM3J3yaC34i6Cwa8MQoLNw1JIS/oNtKjpMxyV10w8aoc
|
34 |
-
PHRK3n7UYp10mJHx7aM+lldSKvVS1NTQmI4vloNLwMp324H5ANDFAlRUz7mysVnu
|
35 |
-
DEEvigPSPxs5ZYENu/i7pCQC5qHfhrlBrQwTjhegr0pQPcumy2fO5SGC9l/5B7ev
|
36 |
-
bqQSZmDeWWoTvh2w2wl5/RWAsgZKx6rDtkCqYx7sSBY17uorrxP24LP4zhq7NxRV
|
37 |
-
nfdsLogbCFNVQ66u7qvq5zFccdFtg9h1HQWdS7wbnKSBGZoo5gl6js7GGtxfGbb0
|
38 |
-
oQ9kp6eciF4U92r6POhVgbRe4CfPo50nqgZBddkAEQEAAYkCJQQYAQgADwUCVqu8
|
39 |
-
7gIbDAUJB4TOAAAKCRA4XuBVoSkVOFJ8D/9J8IJ4XWUU3FYIaHJ3XeSoxDmTi7d5
|
40 |
-
WmNdf1lmwz82MQjG4uw17oCbvQzmj4/a/CM1Ly4v0WwBhUf9aiNErD0ByHASFnuc
|
41 |
-
tlQBLVJdk0vRyD0fZakGg64qCA76hiySjMhlGHkQFyP2mDORc2GNu/OqFGm79pXT
|
42 |
-
ZUplXxd431E603/agM5xJrweutMMpP1nBFTSEMJvbMNzDVN8I1A1CH4zVmAVxOUk
|
43 |
-
sQ5L5rXW+KeXWyiMF24+l2CMnkQ2CxfHpkcpfPJs1Cbt+TIBSSofIqK8QJXrb/2f
|
44 |
-
Zpl/ftqW7Xe86rJFrB/Y/77LDWx10rqWEvfCqrBxrMj7ONAQfbKQF/IjAwDN17Wf
|
45 |
-
1K74rqKnRu+KHCyNM89s1iDbQC9kzZfzYt4AEOvAH/ZQDMZffzPSbnfkBerExFpa
|
46 |
-
93XMuiR66jiBsf9IXIQeydpJD4Ogl2sSUSxFEJxJ/bBSxPxC5w7/BVMA7Am1y8Zo
|
47 |
-
3hrpqnX2PBzxG7L0FZ6fYkfR3p8JS7vI6nByBf2IDv8W32wn43olPf+u6uobHLvt
|
48 |
-
ttapOjwPAhPDalRuxs9U6WSg06QJkT/0F8TFUPWpsFmKTl+G4Ty7PHWsjeeNHJCL
|
49 |
-
7/5RQboFY3k8Jy3/sIofABO6Un9LJivDuu9PxqA0IgvaS6Mja8JdCCk9Nyk4vHB7
|
50 |
-
IEgAL/CYqrk38w==
|
51 |
-
=lmD7
|
52 |
-
-----END PGP PUBLIC KEY BLOCK-----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/CryptoDetails.md
DELETED
@@ -1,64 +0,0 @@
|
|
1 |
-
Cryptography Details
|
2 |
-
=====================
|
3 |
-
|
4 |
-
Here is a high-level description of how this library works. Any discrepancy
|
5 |
-
between this documentation and the actual implementation will be considered
|
6 |
-
a security bug.
|
7 |
-
|
8 |
-
Let's start with the following definitions:
|
9 |
-
|
10 |
-
- HKDF-SHA256(*k*, *n*, *info*, *s*) is the key derivation function specified in
|
11 |
-
RFC 5869 (using the SHA256 hash function). The parameters are:
|
12 |
-
- *k*: The initial keying material.
|
13 |
-
- *n*: The number of output bytes.
|
14 |
-
- *info*: The info string.
|
15 |
-
- *s*: The salt.
|
16 |
-
- AES-256-CTR(*m*, *k*, *iv*) is AES-256 encryption in CTR mode. The parameters
|
17 |
-
are:
|
18 |
-
- *m*: An arbitrary-length (possibly zero-length) message.
|
19 |
-
- *k*: A 32-byte key.
|
20 |
-
- *iv*: A 16-byte initialization vector (nonce).
|
21 |
-
- PBKDF2-SHA256(*p*, *s*, *i*, *n*) is the password-based key derivation
|
22 |
-
function defined in RFC 2898 (using the SHA256 hash function). The parameters
|
23 |
-
are:
|
24 |
-
- *p*: The password string.
|
25 |
-
- *s*: The salt string.
|
26 |
-
- *i*: The iteration count.
|
27 |
-
- *n*: The output length in bytes.
|
28 |
-
- VERSION is the string `"\xDE\xF5\x02\x00"`.
|
29 |
-
- AUTHINFO is the string `"DefusePHP|V2|KeyForAuthentication"`.
|
30 |
-
- ENCRINFO is the string `"DefusePHP|V2|KeyForEncryption"`.
|
31 |
-
|
32 |
-
To encrypt a message *m* using a 32-byte key *k*, the following steps are taken:
|
33 |
-
|
34 |
-
1. Generate a random 32-byte string *salt*.
|
35 |
-
2. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*).
|
36 |
-
3. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*).
|
37 |
-
4. Generate a random 16-byte initialization vector *iv*.
|
38 |
-
5. Compute *c* = AES-256-CTR(*m*, *ekey*, *iv*).
|
39 |
-
6. Combine *ctxt* = VERSION || *salt* || *iv* || *c*.
|
40 |
-
7. Compute *h* = HMAC-SHA256(*ctxt*, *akey*).
|
41 |
-
8. Output *ctxt* || *h*.
|
42 |
-
|
43 |
-
Decryption is roughly the reverse process (see the code for details, since the
|
44 |
-
security of the decryption routine is highly implementation-dependent).
|
45 |
-
|
46 |
-
For encryption using a password *p*, steps 1-3 above are replaced by:
|
47 |
-
|
48 |
-
1. Generate a random 32-byte string *salt*.
|
49 |
-
2. Compute *k* = PBKDF2-SHA256(SHA256(*p*), *salt*, 100000, 32).
|
50 |
-
3. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*)
|
51 |
-
4. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*)
|
52 |
-
|
53 |
-
The remainder of the process is the same. Notice the reuse of the same *salt*
|
54 |
-
for PBKDF2-SHA256 and HKDF-SHA256. The prehashing of the password in step 2 is
|
55 |
-
done to prevent a [DoS attack using long
|
56 |
-
passwords](https://github.com/defuse/php-encryption/issues/230).
|
57 |
-
|
58 |
-
For `KeyProtectedByPassword`, the serialized key is encrypted according to the
|
59 |
-
password encryption defined above. However, the actual password used for
|
60 |
-
encryption is the SHA256 hash of the password the user provided. This is done in
|
61 |
-
order to provide domain separation between the message encryption in the user's
|
62 |
-
application and the internal key encryption done by this library. It fixes
|
63 |
-
a [key replacement chosen-protocol
|
64 |
-
attack](https://github.com/defuse/php-encryption/issues/240).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/FAQ.md
DELETED
@@ -1,51 +0,0 @@
|
|
1 |
-
Frequently Asked Questions
|
2 |
-
===========================
|
3 |
-
|
4 |
-
How do I use this library to encrypt passwords?
|
5 |
-
------------------------------------------------
|
6 |
-
|
7 |
-
Passwords should not be encrypted, they should be hashed with a *slow* password
|
8 |
-
hashing function that's designed to slow down password guessing attacks. See
|
9 |
-
[How to Safely Store Your Users' Passwords in
|
10 |
-
2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016).
|
11 |
-
|
12 |
-
How do I give it the same key every time instead of a new random key?
|
13 |
-
----------------------------------------------------------------------
|
14 |
-
|
15 |
-
A `Key` object can be saved to a string by calling its `saveToAsciiSafeString()`
|
16 |
-
method. You will have to save that string somewhere safe, and then load it back
|
17 |
-
into a `Key` object using `Key`'s `loadFromAsciiSafeString` static method.
|
18 |
-
|
19 |
-
Where you store the string depends on your application. For example if you are
|
20 |
-
using `KeyProtectedByPassword` to encrypt files with a user's login password,
|
21 |
-
then you should not store the `Key` at all. If you are protecting sensitive data
|
22 |
-
on a server that may be compromised, then you should store it in a hardware
|
23 |
-
security module. When in doubt, consult a security expert.
|
24 |
-
|
25 |
-
Why is an EnvironmentIsBrokenException getting thrown?
|
26 |
-
-------------------------------------------------------
|
27 |
-
|
28 |
-
Either you've encountered a bug in this library, or your system doesn't support
|
29 |
-
the use of this library. For example, if your system does not have a secure
|
30 |
-
random number generator, this library will refuse to run, by throwing that
|
31 |
-
exception, instead of falling back to an insecure random number generator.
|
32 |
-
|
33 |
-
Why am I getting a BadFormatException when loading a Key from a string?
|
34 |
-
------------------------------------------------------------------------
|
35 |
-
|
36 |
-
If you're getting this exception, then the string you're giving to
|
37 |
-
`loadFromAsciiSafeString()` is *not* the same as the string you got from
|
38 |
-
`saveToAsciiSafeString()`. Perhaps your database column isn't wide enough and
|
39 |
-
it's truncating the string as you insert it?
|
40 |
-
|
41 |
-
Does encrypting hide the length of the plaintext?
|
42 |
-
--------------------------------------------------
|
43 |
-
|
44 |
-
Encryption does not, and is not intended to, hide the length of the data being
|
45 |
-
encrypted. For example, it is not safe to encrypt a field in which only a small
|
46 |
-
number of different-length values are possible (e.g. "male" or "female") since
|
47 |
-
it would be possible to tell what the plaintext is by looking at the length of
|
48 |
-
the ciphertext. In order to do this safely, it is your responsibility to, before
|
49 |
-
encrypting, pad the data out to the length of the longest string that will ever
|
50 |
-
be encrypted. This way, all plaintexts are the same length, and no information
|
51 |
-
about the plaintext can be gleaned from the length of the ciphertext.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/InstallingAndVerifying.md
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
Getting The Code
|
2 |
-
=================
|
3 |
-
|
4 |
-
There are two ways to use this library in your applications. You can either:
|
5 |
-
|
6 |
-
1. Use [Composer](https://getcomposer.org/), or
|
7 |
-
2. `require_once` a single `.phar` file in your application.
|
8 |
-
|
9 |
-
If you are not using either option (for example, because you're using Git submodules), you may need to write your own autoloader ([example](https://gist.github.com/paragonie-scott/949daee819bb7f19c50e5e103170b400)).
|
10 |
-
|
11 |
-
Option 1: Using Composer
|
12 |
-
-------------------------
|
13 |
-
|
14 |
-
Run this inside the directory of your composer-enabled project:
|
15 |
-
|
16 |
-
```sh
|
17 |
-
composer require defuse/php-encryption
|
18 |
-
```
|
19 |
-
|
20 |
-
Unfortunately, composer doesn't provide a way for you to verify that the code
|
21 |
-
you're getting was signed by this library's authors. If you want a more secure
|
22 |
-
option, use the `.phar` method described below.
|
23 |
-
|
24 |
-
Option 2: Including a PHAR
|
25 |
-
----------------------------
|
26 |
-
|
27 |
-
The `.phar` option lets you include this library into your project simply by
|
28 |
-
calling `require_once` on a single file. Download `defuse-crypto.phar` and
|
29 |
-
`defuse-crypto.phar.sig` from this project's
|
30 |
-
[releases](https://github.com/defuse/php-encryption/releases) page.
|
31 |
-
|
32 |
-
You should verify the integrity of the `.phar`. The `defuse-crypto.phar.sig`
|
33 |
-
contains the signature of `defuse-crypto.phar`. It is signed with Taylor
|
34 |
-
Hornby's PGP key. You can find Taylor's public key in `dist/signingkey.asc`. You
|
35 |
-
can verify the public key's fingerprint against the Taylor Hornby's [contact
|
36 |
-
page](https://defuse.ca/contact.htm) and
|
37 |
-
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).
|
38 |
-
|
39 |
-
Once you have verified the signature, it is safe to use the `.phar`. Place it
|
40 |
-
somewhere in your file system, e.g. `/var/www/lib/defuse-crypto.phar`, and then
|
41 |
-
pass that path to `require_once`.
|
42 |
-
|
43 |
-
```php
|
44 |
-
<?php
|
45 |
-
|
46 |
-
require_once('/var/www/lib/defuse-crypto.phar');
|
47 |
-
|
48 |
-
// ... the Crypto, File, Key, and KeyProtectedByPassword classes are now
|
49 |
-
// available ...
|
50 |
-
|
51 |
-
// ...
|
52 |
-
```
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md
DELETED
@@ -1,166 +0,0 @@
|
|
1 |
-
Information for the Developers of php-encryption
|
2 |
-
=================================================
|
3 |
-
|
4 |
-
Status
|
5 |
-
-------
|
6 |
-
|
7 |
-
This library is currently frozen under a long-term support release. We do not
|
8 |
-
plan to add any new features. We will maintain the library by fixing any bugs
|
9 |
-
that are reported, or security vulnerabilities that are found.
|
10 |
-
|
11 |
-
Development Environment
|
12 |
-
------------------------
|
13 |
-
|
14 |
-
Development is done on Linux. To run the tests, you will need to have the
|
15 |
-
following tools installed:
|
16 |
-
|
17 |
-
- `php` (with OpenSSL enabled, if you're compiling from source).
|
18 |
-
- `gpg`
|
19 |
-
- `composer`
|
20 |
-
|
21 |
-
Running the Tests
|
22 |
-
------------------
|
23 |
-
|
24 |
-
First do `composer install` and then you can run the tests by running
|
25 |
-
`./test.sh`. This will download a PHPUnit PHAR, verify its cryptographic
|
26 |
-
signatures, and then use it to run the tests in `test/unit`.
|
27 |
-
|
28 |
-
Getting and Using Psalm
|
29 |
-
-----------------------
|
30 |
-
|
31 |
-
[Psalm](https://github.com/vimeo/psalm) is a static analysis suite for PHP projects.
|
32 |
-
We use Psalm to ensure type safety throughout our library.
|
33 |
-
|
34 |
-
To install Psalm, you just need to run one command:
|
35 |
-
|
36 |
-
composer require --dev "vimeo/psalm:dev-master"
|
37 |
-
|
38 |
-
To verify that your code changes are still strictly type-safe, run the following
|
39 |
-
command:
|
40 |
-
|
41 |
-
vendor/bin/psalm
|
42 |
-
|
43 |
-
Reporting Bugs
|
44 |
-
---------------
|
45 |
-
|
46 |
-
Please report bugs, even critical security vulnerabilities, by opening an issue
|
47 |
-
on GitHub. We recommend disclosing security vulnerabilities found in this
|
48 |
-
library *publicly* as soon as possible.
|
49 |
-
|
50 |
-
Philosophy
|
51 |
-
-----------
|
52 |
-
|
53 |
-
This library is developed around several core values:
|
54 |
-
|
55 |
-
- Rule #1: Security is prioritized over everything else.
|
56 |
-
|
57 |
-
> Whenever there is a conflict between security and some other property,
|
58 |
-
> security will be favored. For example, the library has runtime tests,
|
59 |
-
> which make it slower, but will hopefully stop it from encrypting stuff
|
60 |
-
> if the platform it's running on is broken.
|
61 |
-
|
62 |
-
- Rule #2: It should be difficult to misuse the library.
|
63 |
-
|
64 |
-
> We assume the developers using this library have no experience with
|
65 |
-
> cryptography. We only assume that they know that the "key" is something
|
66 |
-
> you need to encrypt and decrypt the messages, and that it must be kept
|
67 |
-
> secret. Whenever possible, the library should refuse to encrypt or decrypt
|
68 |
-
> messages when it is not being used correctly.
|
69 |
-
|
70 |
-
- Rule #3: The library aims only to be compatible with itself.
|
71 |
-
|
72 |
-
> Other PHP encryption libraries try to support every possible type of
|
73 |
-
> encryption, even the insecure ones (e.g. ECB mode). Because there are so
|
74 |
-
> many options, inexperienced developers must decide whether to use "CBC
|
75 |
-
> mode" or "ECB mode" when both are meaningless terms to them. This
|
76 |
-
> inevitably leads to vulnerabilities.
|
77 |
-
|
78 |
-
> This library will only support one secure mode. A developer using this
|
79 |
-
> library will call "encrypt" and "decrypt" methods without worrying about
|
80 |
-
> how they are implemented.
|
81 |
-
|
82 |
-
- Rule #4: The library should require no special installation.
|
83 |
-
|
84 |
-
> Some PHP encryption libraries, like libsodium-php, are not straightforward
|
85 |
-
> to install and cannot packaged with "just download and extract"
|
86 |
-
> applications. This library will always be just a handful of PHP files that
|
87 |
-
> you can copy to your source tree and require().
|
88 |
-
|
89 |
-
Publishing Releases
|
90 |
-
--------------------
|
91 |
-
|
92 |
-
To make a release, you will need to install [composer](https://getcomposer.org/)
|
93 |
-
and [box](https://github.com/box-project/box2) on your system. They will need to
|
94 |
-
be available in your `$PATH` so that running the commands `composer` and `box`
|
95 |
-
in your terminal run them, respectively. You will also need the private key for
|
96 |
-
signing (ID: 7B4B2D98) available.
|
97 |
-
|
98 |
-
Once you have those tools installed and the key available follow these steps:
|
99 |
-
|
100 |
-
**Remember to set the version number in `composer.json`!**
|
101 |
-
|
102 |
-
Make a fresh clone of the repository:
|
103 |
-
|
104 |
-
```
|
105 |
-
git clone <url>
|
106 |
-
```
|
107 |
-
|
108 |
-
Check out the branch you want to release:
|
109 |
-
|
110 |
-
```
|
111 |
-
git checkout <branchname>
|
112 |
-
```
|
113 |
-
|
114 |
-
Check that the version number in composer.json is correct:
|
115 |
-
|
116 |
-
```
|
117 |
-
cat composer.json
|
118 |
-
```
|
119 |
-
|
120 |
-
Check that the version number and support lifetime in README.md are correct:
|
121 |
-
|
122 |
-
```
|
123 |
-
cat README.md
|
124 |
-
```
|
125 |
-
|
126 |
-
Run the tests:
|
127 |
-
|
128 |
-
```
|
129 |
-
composer install
|
130 |
-
./test.sh
|
131 |
-
```
|
132 |
-
|
133 |
-
Generate the `.phar`:
|
134 |
-
|
135 |
-
```
|
136 |
-
cd dist
|
137 |
-
make build-phar
|
138 |
-
```
|
139 |
-
|
140 |
-
Test the `.phar`:
|
141 |
-
|
142 |
-
```
|
143 |
-
cd ../
|
144 |
-
./test.sh dist/defuse-crypto.phar
|
145 |
-
```
|
146 |
-
|
147 |
-
Sign the `.phar`:
|
148 |
-
|
149 |
-
```
|
150 |
-
cd dist
|
151 |
-
make sign-phar
|
152 |
-
```
|
153 |
-
|
154 |
-
Tag the release:
|
155 |
-
|
156 |
-
```
|
157 |
-
git -c user.signingkey=7B4B2D98 tag -s "<TAG NAME>" -m "<TAG MESSAGE>"
|
158 |
-
```
|
159 |
-
|
160 |
-
`<TAG NAME>` should be in the format `v2.0.0` and `<TAG MESSAGE>` should look
|
161 |
-
like "Release of v2.0.0."
|
162 |
-
|
163 |
-
Push the tag to github, then use the
|
164 |
-
[releases](https://github.com/defuse/php-encryption/releases) page to draft
|
165 |
-
a new release for that tag. Upload the `.phar` and the `.phar.sig` file to be
|
166 |
-
included as part of that release.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/Tutorial.md
DELETED
@@ -1,314 +0,0 @@
|
|
1 |
-
Tutorial
|
2 |
-
=========
|
3 |
-
|
4 |
-
Hello! If you're reading this file, it's because you want to add encryption to
|
5 |
-
one of your PHP projects. My job, as the person writing this documentation, is
|
6 |
-
to help you make sure you're doing the right thing and then show you how to use
|
7 |
-
this library to do it. To help me help you, please read the documentation
|
8 |
-
*carefully* and *deliberately*.
|
9 |
-
|
10 |
-
A Word of Caution
|
11 |
-
------------------
|
12 |
-
|
13 |
-
Encryption is not magic dust you can sprinkle on a system to make it more
|
14 |
-
secure. The way encryption is integrated into a system's design needs to be
|
15 |
-
carefully thought out. Sometimes, encryption is the wrong thing to use. Other
|
16 |
-
times, encryption needs to be used in a very specific way in order for it to
|
17 |
-
work as intended. Even if you are sure of what you are doing, we strongly
|
18 |
-
recommend seeking advice from an expert.
|
19 |
-
|
20 |
-
The first step is to think about your application's threat model. Ask yourself
|
21 |
-
the following questions. Who will want to attack my application, and what will
|
22 |
-
they get out of it? Are they trying to steal some information? Trying to alter
|
23 |
-
or destroy some information? Or just trying to make the system go down so people
|
24 |
-
can't access it? Then ask yourself how encryption can help combat those threats.
|
25 |
-
If you're going to add encryption to your application, you should have a very
|
26 |
-
clear idea of exactly which kinds of attacks it's helping to secure your
|
27 |
-
application against. Once you have your threat model, think about what kinds of
|
28 |
-
attacks it *does not* cover, and whether or not you should improve your threat
|
29 |
-
model to include those attacks.
|
30 |
-
|
31 |
-
**This isn't for storing user login passwords:** The most common use of
|
32 |
-
cryptography in web applications is to protect the users' login passwords. If
|
33 |
-
you're trying to use this library to "encrypt" your users' passwords, you're in
|
34 |
-
the wrong place. Passwords shouldn't be *encrypted*, they should be *hashed*
|
35 |
-
with a slow computation-heavy function that makes password guessing attacks more
|
36 |
-
expensive. See [How to Safely Store Your Users' Passwords in
|
37 |
-
2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016).
|
38 |
-
|
39 |
-
**This isn't for encrypting network communication:** Likewise, if you're trying
|
40 |
-
to encrypt messages sent between two parties over the Internet, you don't want
|
41 |
-
to be using this library. For that, set up a TLS connection between the two
|
42 |
-
points, or, if it's a chat app, use the [Signal
|
43 |
-
Protocol](https://whispersystems.org/blog/advanced-ratcheting/).
|
44 |
-
|
45 |
-
What this library provides is symmetric encryption for "data at rest." This
|
46 |
-
means it is not suitable for use in building protocols where "data is in motion"
|
47 |
-
(i.e. moving over a network) except in limited set of cases.
|
48 |
-
|
49 |
-
Please note that **encryption does not, and is not intended to, hide the
|
50 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
51 |
-
a field in which only a small number of different-length values are possible
|
52 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
53 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
54 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
55 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
56 |
-
same length, and no information about the plaintext can be gleaned from the
|
57 |
-
length of the ciphertext.
|
58 |
-
|
59 |
-
Getting the Code
|
60 |
-
-----------------
|
61 |
-
|
62 |
-
There are several different ways to obtain this library's code and to add it to
|
63 |
-
your project. Even if you've already cloned the code from GitHub, you should
|
64 |
-
take steps to verify the cryptographic signatures to make sure the code you got
|
65 |
-
was not intercepted and modified by an attacker.
|
66 |
-
|
67 |
-
Please head over to the [**Installing and
|
68 |
-
Verifying**](InstallingAndVerifying.md) documentation to get the code, and then
|
69 |
-
come back here to continue the tutorial.
|
70 |
-
|
71 |
-
Using the Library
|
72 |
-
------------------
|
73 |
-
|
74 |
-
I'm going to assume you know what symmetric encryption is, and the difference
|
75 |
-
between symmetric and asymmetric encryption. If you don't, I recommend taking
|
76 |
-
[Dan Boneh's Cryptography I course](https://www.coursera.org/learn/crypto/) on
|
77 |
-
Coursera.
|
78 |
-
|
79 |
-
To give you a quick introduction to the library, I'm going to explain how it
|
80 |
-
would be used in two sterotypical scenarios. Hopefully, one of these sterotypes
|
81 |
-
is close enough to what you want to do that you'll be able to figure out what
|
82 |
-
needs to be different on your own.
|
83 |
-
|
84 |
-
### Formal Documentation
|
85 |
-
|
86 |
-
While this tutorial should get you up and running fast, it's important to
|
87 |
-
understand how this library behaves. Please make sure to read the formal
|
88 |
-
documentation of all of the functions you're using, since there are some
|
89 |
-
important security warnings there.
|
90 |
-
|
91 |
-
The following classes are available for you to use:
|
92 |
-
|
93 |
-
- [Crypto](classes/Crypto.md): Encrypting and decrypting strings.
|
94 |
-
- [File](classes/File.md): Encrypting and decrypting files.
|
95 |
-
- [Key](classes/Key.md): Represents a secret encryption key.
|
96 |
-
- [KeyProtectedByPassword](classes/KeyProtectedByPassword.md): Represents
|
97 |
-
a secret encryption key that needs to be "unlocked" by a password before it
|
98 |
-
can be used.
|
99 |
-
|
100 |
-
### Scenario #1: Keep data secret from the database administrator
|
101 |
-
|
102 |
-
In this scenario, our threat model is as follows. Alice is a server
|
103 |
-
administrator responsible for managing a trusted web server. Eve is a database
|
104 |
-
administrator responsible for managing a database server. Dave is a web
|
105 |
-
developer working on code that will eventually run on the trusted web server.
|
106 |
-
|
107 |
-
Let's say Alice and Dave trust each other, and Alice is going to host Dave's
|
108 |
-
application on her server. But both Alice and Dave don't trust Eve. They know
|
109 |
-
Eve is a good database administrator, but she might have incentive to steal the
|
110 |
-
data from the database. They want to keep some of the web application's data
|
111 |
-
secret from Eve.
|
112 |
-
|
113 |
-
In order to do that, Alice will use the included `generate-defuse-key` script
|
114 |
-
which generates a random encryption key and prints it to standard output:
|
115 |
-
|
116 |
-
```sh
|
117 |
-
$ composer require defuse/php-encryption
|
118 |
-
$ vendor/bin/generate-defuse-key
|
119 |
-
```
|
120 |
-
|
121 |
-
Alice will run this script once and save the output to a configuration file, say
|
122 |
-
in `/etc/daveapp-secret-key.txt` and set the file permissions so that only the
|
123 |
-
user that the website PHP scripts run as can access it.
|
124 |
-
|
125 |
-
Dave will write his code to load the key from the configuration file:
|
126 |
-
|
127 |
-
```php
|
128 |
-
<?php
|
129 |
-
use Defuse\Crypto\Key;
|
130 |
-
|
131 |
-
function loadEncryptionKeyFromConfig()
|
132 |
-
{
|
133 |
-
$keyAscii = // ... load the contents of /etc/daveapp-secret-key.txt
|
134 |
-
return Key::loadFromAsciiSafeString($keyAscii);
|
135 |
-
}
|
136 |
-
```
|
137 |
-
|
138 |
-
Then, whenever Dave wants to save a secret value to the database, he will first
|
139 |
-
encrypt it:
|
140 |
-
|
141 |
-
```php
|
142 |
-
<?php
|
143 |
-
use Defuse\Crypto\Crypto;
|
144 |
-
|
145 |
-
// ...
|
146 |
-
$key = loadEncryptionKeyFromConfig();
|
147 |
-
// ...
|
148 |
-
$ciphertext = Crypto::encrypt($secret_data, $key);
|
149 |
-
// ... save $ciphertext into the database ...
|
150 |
-
```
|
151 |
-
|
152 |
-
Whenever Dave wants to get the value back from the database, he must decrypt it
|
153 |
-
using the same key:
|
154 |
-
|
155 |
-
```php
|
156 |
-
<?php
|
157 |
-
use Defuse\Crypto\Crypto;
|
158 |
-
|
159 |
-
// ...
|
160 |
-
$key = loadEncryptionKeyFromConfig();
|
161 |
-
// ...
|
162 |
-
$ciphertext = // ... load $ciphertext from the database
|
163 |
-
try {
|
164 |
-
$secret_data = Crypto::decrypt($ciphertext, $key);
|
165 |
-
} catch (\Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
|
166 |
-
// An attack! Either the wrong key was loaded, or the ciphertext has
|
167 |
-
// changed since it was created -- either corrupted in the database or
|
168 |
-
// intentionally modified by Eve trying to carry out an attack.
|
169 |
-
|
170 |
-
// ... handle this case in a way that's suitable to your application ...
|
171 |
-
}
|
172 |
-
```
|
173 |
-
|
174 |
-
Note that if anyone ever steals the key from Alice's server, they can decrypt
|
175 |
-
all of the ciphertexts that are stored in the database. As part of our threat
|
176 |
-
model, we are assuming Alice's server administration skills and Dave's secure
|
177 |
-
coding skills are good enough to stop Eve from being able to steal the key.
|
178 |
-
Under those assumptions, this solution will prevent Eve from seeing data that's
|
179 |
-
stored in the database.
|
180 |
-
|
181 |
-
However, notice that our threat model says nothing about what could happen if
|
182 |
-
Eve wants to *modify* the data. With this solution, Eve will not be able to
|
183 |
-
alter any individual ciphertext (because each ciphertext has its own
|
184 |
-
cryptographic integrity check), but Eve *will* be able to swap ciphertexts for
|
185 |
-
one another, and revert ciphertexts to what they used to be at previous times.
|
186 |
-
If we needed to defend against such attacks, we would have to re-design our
|
187 |
-
threat model and come up with a different solution.
|
188 |
-
|
189 |
-
### Scenario #2: Encrypting account data with the user's login password
|
190 |
-
|
191 |
-
This scenario is like Scenario 1, but subtly different. The threat model is as
|
192 |
-
follows. We have Alice, a server administrator, and Dave, the developer. Alice
|
193 |
-
and Dave trust each other, and Alice wants to host Dave's web application,
|
194 |
-
including its database, on her server. Alice is worried about her server getting
|
195 |
-
hacked. The application will store the users' credit card numbers, and Alice
|
196 |
-
wants to protect them in case the server gets hacked.
|
197 |
-
|
198 |
-
We can model the situation like this: after the server gets hacked, the attacker
|
199 |
-
will have read and write access to all data on it until the attack is detected
|
200 |
-
and Alice rebuilds the server. We'll call the time the attacker has access to
|
201 |
-
the server the *exposure window.* One idea to minimize loss is to encrypt the
|
202 |
-
users' credit card numbers using a key made from their login password. Then, as
|
203 |
-
long as the users all have strong passwords, and they are never logged in during
|
204 |
-
the exposure window, their credit cards will be protected from the attacker.
|
205 |
-
|
206 |
-
To implement this, Dave will use the `KeyProtectedByPassword` class. When a new
|
207 |
-
user account is created, Dave will save a new key to their account, one that's
|
208 |
-
protected by their login password:
|
209 |
-
|
210 |
-
```php
|
211 |
-
<?php
|
212 |
-
use Defuse\Crypto\KeyProtectedByPassword;
|
213 |
-
|
214 |
-
function CreateUserAccount($username, $password)
|
215 |
-
{
|
216 |
-
// ... other user account creation stuff, including password hashing
|
217 |
-
|
218 |
-
$protected_key = KeyProtectedByPassword::createRandomPasswordProtectedKey($password);
|
219 |
-
$protected_key_encoded = $protected_key->saveToAsciiSafeString();
|
220 |
-
// ... save $protected_key_encoded into the user's account record
|
221 |
-
}
|
222 |
-
```
|
223 |
-
|
224 |
-
**WARNING:** Because of the way `KeyProtectedByPassword` is implemented, knowing
|
225 |
-
`SHA256($password)` is enough to decrypt a `KeyProtectedByPassword`. To be
|
226 |
-
secure, your application MUST NOT EVER compute `SHA256($password)` and use or
|
227 |
-
store it for any reason. You must also make sure that other libraries your
|
228 |
-
application is using don't compute it either.
|
229 |
-
|
230 |
-
Then, when the user logs in, Dave's code will load the protected key from the
|
231 |
-
user's account record, unlock it to get a `Key` object, and save the `Key`
|
232 |
-
object somewhere safe (like temporary memory-backed session storage). Note that
|
233 |
-
wherever Dave's code saves the key, it must be destroyed once the user logs out,
|
234 |
-
or else the attacker might be able to find users' keys even if they were never
|
235 |
-
logged in during the attack.
|
236 |
-
|
237 |
-
```php
|
238 |
-
<?php
|
239 |
-
use Defuse\Crypto\KeyProtectedByPassword;
|
240 |
-
|
241 |
-
// ... authenticate the user using a good password hashing scheme
|
242 |
-
// keep the user's password in $password
|
243 |
-
|
244 |
-
$protected_key_encoded = // ... load it from the user's account record
|
245 |
-
$protected_key = KeyProtectedByPassword::loadFromAsciiSafeString($protected_key_encoded);
|
246 |
-
$user_key = $protected_key->unlockKey($password);
|
247 |
-
$user_key_encoded = $user_key->saveToAsciiSafeString();
|
248 |
-
// ... save $user_key_encoded in the session
|
249 |
-
```
|
250 |
-
|
251 |
-
```php
|
252 |
-
<?php
|
253 |
-
// ... when the user is logging out ...
|
254 |
-
// ... securely wipe the saved $user_key_encoded from the system ...
|
255 |
-
```
|
256 |
-
|
257 |
-
When a user adds their credit card number, Dave's code will get the key from the
|
258 |
-
session and use it to encrypt the credit card number:
|
259 |
-
|
260 |
-
```php
|
261 |
-
<?php
|
262 |
-
use Defuse\Crypto\Crypto;
|
263 |
-
use Defuse\Crypto\Key;
|
264 |
-
|
265 |
-
// ...
|
266 |
-
|
267 |
-
$user_key_encoded = // ... get it out of the session ...
|
268 |
-
$user_key = Key::loadFromAsciiSafeString($user_key_encoded);
|
269 |
-
|
270 |
-
// ...
|
271 |
-
|
272 |
-
$credit_card_number = // ... get credit card number from the user
|
273 |
-
$encrypted_card_number = Crypto::encrypt($credit_card_number, $user_key);
|
274 |
-
// ... save $encrypted_card_number in the database
|
275 |
-
```
|
276 |
-
|
277 |
-
When the application needs to use the credit card number, it will decrypt it:
|
278 |
-
|
279 |
-
```php
|
280 |
-
<?php
|
281 |
-
use Defuse\Crypto\Crypto;
|
282 |
-
use Defuse\Crypto\Key;
|
283 |
-
|
284 |
-
// ...
|
285 |
-
|
286 |
-
$user_key_encoded = // ... get it out of the session
|
287 |
-
$user_key = Key::loadFromAsciiSafeString($user_key_encoded);
|
288 |
-
|
289 |
-
// ...
|
290 |
-
|
291 |
-
$encrypted_card_number = // ... load it from the database ...
|
292 |
-
try {
|
293 |
-
$credit_card_number = Crypto::decrypt($encrypted_card_number, $user_key);
|
294 |
-
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
|
295 |
-
// Either there's a bug in our code, we're trying to decrypt with the
|
296 |
-
// wrong key, or the encrypted credit card number was corrupted in the
|
297 |
-
// database.
|
298 |
-
|
299 |
-
// ... handle this case ...
|
300 |
-
}
|
301 |
-
```
|
302 |
-
|
303 |
-
With all caveats carefully heeded, this solution limits credit card number
|
304 |
-
exposure in the case where Alice's server gets hacked for a short amount of
|
305 |
-
time. Remember to think about the attacks that *aren't* included in our threat
|
306 |
-
model. The attacker is still free to do all sorts of harmful things like
|
307 |
-
modifying the server's data which may go undetected if Alice doesn't have secure
|
308 |
-
backups to compare against.
|
309 |
-
|
310 |
-
Getting Help
|
311 |
-
-------------
|
312 |
-
|
313 |
-
If you're having difficulty using the library, see if your problem is already
|
314 |
-
solved by an answer in the [FAQ](FAQ.md).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/UpgradingFromV1.2.md
DELETED
@@ -1,51 +0,0 @@
|
|
1 |
-
Upgrading From Version 1.2
|
2 |
-
===========================
|
3 |
-
|
4 |
-
With version 2.0.0 of this library came major changes to the ciphertext format,
|
5 |
-
algorithms used for encryption, and API.
|
6 |
-
|
7 |
-
In version 1.2, keys were represented by 16-byte string variables. In version
|
8 |
-
2.0.0, keys are represented by objects, instances of the `Key` class. This
|
9 |
-
change was made in order to make it harder to misuse the API. For example, in
|
10 |
-
version 1.2, you could pass in *any* 16-byte string, but in version 2.0.0 you
|
11 |
-
need a `Key` object, which you can only get if you're "doing the right thing."
|
12 |
-
|
13 |
-
This means that for all of your old version 1.2 keys, you'll have to:
|
14 |
-
|
15 |
-
1. Generate a new version 2.0.0 key.
|
16 |
-
2. For all of the ciphertexts encrypted under the old key:
|
17 |
-
1. Decrypt the ciphertext using the old version 1.2 key.
|
18 |
-
2. Re-encrypt it using the new version 2.0.0 key.
|
19 |
-
|
20 |
-
Use the special `Crypto::legacyDecrypt()` method to decrypt the old ciphertexts
|
21 |
-
using the old key and then re-encrypt them using `Crypto::encrypt()` with the
|
22 |
-
new key. Your code will look something like the following. To avoid data loss,
|
23 |
-
securely back up your keys and data before running your upgrade code.
|
24 |
-
|
25 |
-
```php
|
26 |
-
<?php
|
27 |
-
|
28 |
-
// ...
|
29 |
-
|
30 |
-
$legacy_ciphertext = // ... get the ciphertext you want to upgrade ...
|
31 |
-
$legacy_key = // ... get the key to decrypt this ciphertext ...
|
32 |
-
|
33 |
-
// Generate the new key that we'll re-encrypt the ciphertext with.
|
34 |
-
$new_key = Key::createNewRandomKey();
|
35 |
-
// ... save it somewhere ...
|
36 |
-
|
37 |
-
// Decrypt it.
|
38 |
-
try {
|
39 |
-
$plaintext = Crypto::legacyDecrypt($legacy_ciphertext, $legacy_key);
|
40 |
-
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex)
|
41 |
-
{
|
42 |
-
// ... TODO: handle this case appropriately ...
|
43 |
-
}
|
44 |
-
|
45 |
-
// Re-encrypt it.
|
46 |
-
$new_ciphertext = Crypto::encrypt($plaintext, $new_key);
|
47 |
-
|
48 |
-
// ... replace the old $legacy_ciphertext with the new $new_ciphertext
|
49 |
-
|
50 |
-
// ...
|
51 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/classes/Crypto.md
DELETED
@@ -1,280 +0,0 @@
|
|
1 |
-
Class: Defuse\Crypto\Crypto
|
2 |
-
============================
|
3 |
-
|
4 |
-
The `Crypto` class provides encryption and decryption of strings either using
|
5 |
-
a secret key or secret password. For encryption and decryption of large files,
|
6 |
-
see the `File` class.
|
7 |
-
|
8 |
-
This code for this class is in `src/Crypto.php`.
|
9 |
-
|
10 |
-
Instance Methods
|
11 |
-
-----------------
|
12 |
-
|
13 |
-
This class has no instance methods.
|
14 |
-
|
15 |
-
Static Methods
|
16 |
-
---------------
|
17 |
-
|
18 |
-
### Crypto::encrypt($plaintext, Key $key, $raw\_binary = false)
|
19 |
-
|
20 |
-
**Description:**
|
21 |
-
|
22 |
-
Encrypts a plaintext string using a secret key.
|
23 |
-
|
24 |
-
**Parameters:**
|
25 |
-
|
26 |
-
1. `$plaintext` is the string to encrypt.
|
27 |
-
2. `$key` is an instance of `Key` containing the secret key for encryption.
|
28 |
-
3. `$raw_binary` determines whether the output will be a byte string (true) or
|
29 |
-
hex encoded (false, the default).
|
30 |
-
|
31 |
-
**Return value:**
|
32 |
-
|
33 |
-
Returns a ciphertext string representing `$plaintext` encrypted with the key
|
34 |
-
`$key`. Knowledge of `$key` is required in order to decrypt the ciphertext and
|
35 |
-
recover the plaintext.
|
36 |
-
|
37 |
-
**Exceptions:**
|
38 |
-
|
39 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
40 |
-
the platform the code is running on cannot safely perform encryption for some
|
41 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
42 |
-
detected a bug in this library.
|
43 |
-
|
44 |
-
- `\TypeError` is thrown if the parameters are not of the expected types.
|
45 |
-
|
46 |
-
**Side-effects and performance:**
|
47 |
-
|
48 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
49 |
-
time one of the `Crypto` methods has been called. The performance overhead is
|
50 |
-
negligible and can be safely ignored in all applications.
|
51 |
-
|
52 |
-
**Cautions:**
|
53 |
-
|
54 |
-
The ciphertext returned by this method is decryptable by anyone with knowledge
|
55 |
-
of the key `$key`. It is the caller's responsibility to keep `$key` secret.
|
56 |
-
Where `$key` should be stored is up to the caller and depends on the threat
|
57 |
-
model the caller is designing their application under. If you are unsure where
|
58 |
-
to store `$key`, consult with a professional cryptographer to get help designing
|
59 |
-
your application.
|
60 |
-
|
61 |
-
Please note that **encryption does not, and is not intended to, hide the
|
62 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
63 |
-
a field in which only a small number of different-length values are possible
|
64 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
65 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
66 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
67 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
68 |
-
same length, and no information about the plaintext can be gleaned from the
|
69 |
-
length of the ciphertext.
|
70 |
-
|
71 |
-
### Crypto::decrypt($ciphertext, Key $key, $raw\_binary = false)
|
72 |
-
|
73 |
-
**Description:**
|
74 |
-
|
75 |
-
Decrypts a ciphertext string using a secret key.
|
76 |
-
|
77 |
-
**Parameters:**
|
78 |
-
|
79 |
-
1. `$ciphertext` is the ciphertext to be decrypted.
|
80 |
-
2. `$key` is an instance of `Key` containing the secret key for decryption.
|
81 |
-
3. `$raw_binary` must have the same value as the `$raw_binary` given to the
|
82 |
-
call to `encrypt()` that generated `$ciphertext`.
|
83 |
-
|
84 |
-
**Return value:**
|
85 |
-
|
86 |
-
If the decryption succeeds, returns a string containing the same value as the
|
87 |
-
string that was passed to `encrypt()` when `$ciphertext` was produced. Upon
|
88 |
-
a successful return, the caller can be assured that `$ciphertext` could not have
|
89 |
-
been produced except by someone with knowledge of `$key`.
|
90 |
-
|
91 |
-
**Exceptions:**
|
92 |
-
|
93 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
94 |
-
the platform the code is running on cannot safely perform encryption for some
|
95 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
96 |
-
detected a bug in this library.
|
97 |
-
|
98 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
99 |
-
the `$key` is not the correct key for the given ciphertext, or if the
|
100 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
101 |
-
distinguish between these two cases.
|
102 |
-
|
103 |
-
- `\TypeError` is thrown if the parameters are not of the expected types.
|
104 |
-
|
105 |
-
**Side-effects and performance:**
|
106 |
-
|
107 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
108 |
-
time one of the `Crypto` methods has been called. The performance overhead is
|
109 |
-
negligible and can be safely ignored in all applications.
|
110 |
-
|
111 |
-
**Cautions:**
|
112 |
-
|
113 |
-
It is impossible in principle to distinguish between the case where you attempt
|
114 |
-
to decrypt with the wrong key and the case where you attempt to decrypt
|
115 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
116 |
-
this ambiguity, as it depends on the application this library is being used in.
|
117 |
-
If in doubt, consult with a professional cryptographer.
|
118 |
-
|
119 |
-
### Crypto::encryptWithPassword($plaintext, $password, $raw\_binary = false)
|
120 |
-
|
121 |
-
**Description:**
|
122 |
-
|
123 |
-
Encrypts a plaintext string using a secret password.
|
124 |
-
|
125 |
-
**Parameters:**
|
126 |
-
|
127 |
-
1. `$plaintext` is the string to encrypt.
|
128 |
-
2. `$password` is a string containing the secret password used for encryption.
|
129 |
-
3. `$raw_binary` determines whether the output will be a byte string (true) or
|
130 |
-
hex encoded (false, the default).
|
131 |
-
|
132 |
-
**Return value:**
|
133 |
-
|
134 |
-
Returns a ciphertext string representing `$plaintext` encrypted with a key
|
135 |
-
derived from `$password`. Knowledge of `$password` is required in order to
|
136 |
-
decrypt the ciphertext and recover the plaintext.
|
137 |
-
|
138 |
-
**Exceptions:**
|
139 |
-
|
140 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
141 |
-
the platform the code is running on cannot safely perform encryption for some
|
142 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
143 |
-
detected a bug in this library.
|
144 |
-
|
145 |
-
- `\TypeError` is thrown if the parameters are not of the expected types.
|
146 |
-
|
147 |
-
**Side-effects and performance:**
|
148 |
-
|
149 |
-
This method is intentionally slow, using a lot of CPU resources for a fraction
|
150 |
-
of a second. It applies key stretching to the password in order to make password
|
151 |
-
guessing attacks more computationally expensive. If you need a faster way to
|
152 |
-
encrypt multiple ciphertexts under the same password, see the
|
153 |
-
`KeyProtectedByPassword` class.
|
154 |
-
|
155 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
156 |
-
time one of the `Crypto` methods has been called. The performance overhead is
|
157 |
-
negligible and can be safely ignored in all applications.
|
158 |
-
|
159 |
-
**Cautions:**
|
160 |
-
|
161 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
162 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
163 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
164 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
165 |
-
them to the user or saving them to log files).
|
166 |
-
|
167 |
-
### Crypto::decryptWithPassword($ciphertext, $password, $raw\_binary = false)
|
168 |
-
|
169 |
-
**Description:**
|
170 |
-
|
171 |
-
Decrypts a ciphertext string using a secret password.
|
172 |
-
|
173 |
-
**Parameters:**
|
174 |
-
|
175 |
-
1. `$ciphertext` is the ciphertext to be decrypted.
|
176 |
-
2. `$password` is a string containing the secret password used for decryption.
|
177 |
-
3. `$raw_binary` must have the same value as the `$raw_binary` given to the
|
178 |
-
call to `encryptWithPassword()` that generated `$ciphertext`.
|
179 |
-
|
180 |
-
**Return value:**
|
181 |
-
|
182 |
-
If the decryption succeeds, returns a string containing the same value as the
|
183 |
-
string that was passed to `encryptWithPassword()` when `$ciphertext` was
|
184 |
-
produced. Upon a successful return, the caller can be assured that `$ciphertext`
|
185 |
-
could not have been produced except by someone with knowledge of `$password`.
|
186 |
-
|
187 |
-
**Exceptions:**
|
188 |
-
|
189 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
190 |
-
the platform the code is running on cannot safely perform encryption for some
|
191 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
192 |
-
detected a bug in this library.
|
193 |
-
|
194 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
195 |
-
the `$password` is not the correct password for the given ciphertext, or if
|
196 |
-
the ciphertext has been modified (possibly maliciously). There is no way to
|
197 |
-
distinguish between these two cases.
|
198 |
-
|
199 |
-
- `\TypeError` is thrown if the parameters are not of the expected types.
|
200 |
-
|
201 |
-
**Side-effects:**
|
202 |
-
|
203 |
-
This method is intentionally slow. It applies key stretching to the password in
|
204 |
-
order to make password guessing attacks more computationally expensive. If you
|
205 |
-
need a faster way to encrypt multiple ciphertexts under the same password, see
|
206 |
-
the `KeyProtectedByPassword` class.
|
207 |
-
|
208 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
209 |
-
time one of the `Crypto` methods has been called. The performance overhead is
|
210 |
-
negligible and can be safely ignored in all applications.
|
211 |
-
|
212 |
-
**Cautions:**
|
213 |
-
|
214 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
215 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
216 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
217 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
218 |
-
them to the user or saving them to log files).
|
219 |
-
|
220 |
-
It is impossible in principle to distinguish between the case where you attempt
|
221 |
-
to decrypt with the wrong password and the case where you attempt to decrypt
|
222 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
223 |
-
this ambiguity, as it depends on the application this library is being used in.
|
224 |
-
If in doubt, consult with a professional cryptographer.
|
225 |
-
|
226 |
-
### Crypto::legacyDecrypt($ciphertext, $key)
|
227 |
-
|
228 |
-
**Description:**
|
229 |
-
|
230 |
-
Decrypts a ciphertext produced by version 1 of this library so that the
|
231 |
-
plaintext can be re-encrypted into a version 2 ciphertext. See [Upgrading from
|
232 |
-
v1.2](../UpgradingFromV1.2.md).
|
233 |
-
|
234 |
-
**Parameters:**
|
235 |
-
|
236 |
-
1. `$ciphertext` is a ciphertext produced by version 1.x of this library.
|
237 |
-
2. `$key` is a 16-byte string (*not* a Key object) containing the key that was
|
238 |
-
used with version 1.x of this library to produce `$ciphertext`.
|
239 |
-
|
240 |
-
**Return value:**
|
241 |
-
|
242 |
-
If the decryption succeeds, returns the string that was encrypted to make
|
243 |
-
`$ciphertext` by version 1.x of this library. Upon a successful return, the
|
244 |
-
caller can be assured that `$ciphertext` could not have been produced except by
|
245 |
-
someone with knowledge of `$key`.
|
246 |
-
|
247 |
-
**Exceptions:**
|
248 |
-
|
249 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
250 |
-
the platform the code is running on cannot safely perform encryption for some
|
251 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
252 |
-
detected a bug in this library.
|
253 |
-
|
254 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
255 |
-
the `$key` is not the correct key for the given ciphertext, or if the
|
256 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
257 |
-
distinguish between these two cases.
|
258 |
-
|
259 |
-
- `\TypeError` is thrown if the parameters are not of the expected types.
|
260 |
-
|
261 |
-
**Side-effects:**
|
262 |
-
|
263 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
264 |
-
time one of the `Crypto` methods has been called. The performance overhead is
|
265 |
-
negligible and can be safely ignored in all applications.
|
266 |
-
|
267 |
-
**Cautions:**
|
268 |
-
|
269 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
270 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
271 |
-
value of `$key` may be leaked out to an attacker through the stack trace. We
|
272 |
-
recommend configuring PHP to never output stack traces (either displaying them
|
273 |
-
to the user or saving them to log files).
|
274 |
-
|
275 |
-
It is impossible in principle to distinguish between the case where you attempt
|
276 |
-
to decrypt with the wrong key and the case where you attempt to decrypt
|
277 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
278 |
-
this ambiguity, as it depends on the application this library is being used in.
|
279 |
-
If in doubt, consult with a professional cryptographer.
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/classes/File.md
DELETED
@@ -1,486 +0,0 @@
|
|
1 |
-
Class: Defuse\Crypto\File
|
2 |
-
==========================
|
3 |
-
|
4 |
-
Instance Methods
|
5 |
-
-----------------
|
6 |
-
|
7 |
-
This class has no instance methods.
|
8 |
-
|
9 |
-
Static Methods
|
10 |
-
---------------
|
11 |
-
|
12 |
-
### File::encryptFile($inputFilename, $outputFilename, Key $key)
|
13 |
-
|
14 |
-
**Description:**
|
15 |
-
|
16 |
-
Encrypts a file using a secret key.
|
17 |
-
|
18 |
-
**Parameters:**
|
19 |
-
|
20 |
-
1. `$inputFilename` is the path to a file containing the plaintext to encrypt.
|
21 |
-
2. `$outputFilename` is the path to save the ciphertext file.
|
22 |
-
3. `$key` is an instance of `Key` containing the secret key for encryption.
|
23 |
-
|
24 |
-
**Behavior:**
|
25 |
-
|
26 |
-
Encrypts the contents of the input file, writing the result to the output file.
|
27 |
-
If the output file already exists, it is overwritten.
|
28 |
-
|
29 |
-
**Return value:**
|
30 |
-
|
31 |
-
Does not return a value.
|
32 |
-
|
33 |
-
**Exceptions:**
|
34 |
-
|
35 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
36 |
-
|
37 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
38 |
-
the platform the code is running on cannot safely perform encryption for some
|
39 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
40 |
-
detected a bug in this library.
|
41 |
-
|
42 |
-
**Side-effects and performance:**
|
43 |
-
|
44 |
-
None.
|
45 |
-
|
46 |
-
**Cautions:**
|
47 |
-
|
48 |
-
The ciphertext output by this method is decryptable by anyone with knowledge of
|
49 |
-
the key `$key`. It is the caller's responsibility to keep `$key` secret. Where
|
50 |
-
`$key` should be stored is up to the caller and depends on the threat model the
|
51 |
-
caller is designing their application under. If you are unsure where to store
|
52 |
-
`$key`, consult with a professional cryptographer to get help designing your
|
53 |
-
application.
|
54 |
-
|
55 |
-
Please note that **encryption does not, and is not intended to, hide the
|
56 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
57 |
-
a field in which only a small number of different-length values are possible
|
58 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
59 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
60 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
61 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
62 |
-
same length, and no information about the plaintext can be gleaned from the
|
63 |
-
length of the ciphertext.
|
64 |
-
|
65 |
-
### File::decryptFile($inputFilename, $outputFilename, Key $key)
|
66 |
-
|
67 |
-
**Description:**
|
68 |
-
|
69 |
-
Decrypts a file using a secret key.
|
70 |
-
|
71 |
-
**Parameters:**
|
72 |
-
|
73 |
-
1. `$inputFilename` is the path to a file containing the ciphertext to decrypt.
|
74 |
-
2. `$outputFilename` is the path to save the decrypted plaintext file.
|
75 |
-
3. `$key` is an instance of `Key` containing the secret key for decryption.
|
76 |
-
|
77 |
-
**Behavior:**
|
78 |
-
|
79 |
-
Decrypts the contents of the input file, writing the result to the output file.
|
80 |
-
If the output file already exists, it is overwritten.
|
81 |
-
|
82 |
-
**Return value:**
|
83 |
-
|
84 |
-
Does not return a value.
|
85 |
-
|
86 |
-
**Exceptions:**
|
87 |
-
|
88 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
89 |
-
|
90 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
91 |
-
the platform the code is running on cannot safely perform encryption for some
|
92 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
93 |
-
detected a bug in this library.
|
94 |
-
|
95 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
96 |
-
the `$key` is not the correct key for the given ciphertext, or if the
|
97 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
98 |
-
distinguish between these two cases.
|
99 |
-
|
100 |
-
**Side-effects and performance:**
|
101 |
-
|
102 |
-
The input ciphertext is processed in two passes. The first pass verifies the
|
103 |
-
integrity and the second pass performs the actual decryption of the file and
|
104 |
-
writing to the output file. This is done in a streaming manner so that only
|
105 |
-
a small part of the file is ever loaded into memory at a time.
|
106 |
-
|
107 |
-
**Cautions:**
|
108 |
-
|
109 |
-
Be aware that when `Defuse\Crypto\WrongKeyOrModifiedCiphertextException` is
|
110 |
-
thrown, some partial plaintext data may have been written to the output. Any
|
111 |
-
plaintext data that is output is guaranteed to be a prefix of the original
|
112 |
-
plaintext (i.e. at worst it was truncated). This can only happen if an attacker
|
113 |
-
modifies the input between the first pass (integrity check) and the second pass
|
114 |
-
(decryption) over the file.
|
115 |
-
|
116 |
-
It is impossible in principle to distinguish between the case where you attempt
|
117 |
-
to decrypt with the wrong key and the case where you attempt to decrypt
|
118 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
119 |
-
this ambiguity, as it depends on the application this library is being used in.
|
120 |
-
If in doubt, consult with a professional cryptographer.
|
121 |
-
|
122 |
-
### File::encryptFileWithPassword($inputFilename, $outputFilename, $password)
|
123 |
-
|
124 |
-
**Description:**
|
125 |
-
|
126 |
-
Encrypts a file with a password.
|
127 |
-
|
128 |
-
**Parameters:**
|
129 |
-
|
130 |
-
1. `$inputFilename` is the path to a file containing the plaintext to encrypt.
|
131 |
-
2. `$outputFilename` is the path to save the ciphertext file.
|
132 |
-
3. `$password` is the password used for decryption.
|
133 |
-
|
134 |
-
**Behavior:**
|
135 |
-
|
136 |
-
Encrypts the contents of the input file, writing the result to the output file.
|
137 |
-
If the output file already exists, it is overwritten.
|
138 |
-
|
139 |
-
**Return value:**
|
140 |
-
|
141 |
-
Does not return a value.
|
142 |
-
|
143 |
-
**Exceptions:**
|
144 |
-
|
145 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
146 |
-
|
147 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
148 |
-
the platform the code is running on cannot safely perform encryption for some
|
149 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
150 |
-
detected a bug in this library.
|
151 |
-
|
152 |
-
**Side-effects and performance:**
|
153 |
-
|
154 |
-
This method is intentionally slow, using a lot of CPU resources for a fraction
|
155 |
-
of a second. It applies key stretching to the password in order to make password
|
156 |
-
guessing attacks more computationally expensive. If you need a faster way to
|
157 |
-
encrypt multiple ciphertexts under the same password, see the
|
158 |
-
`KeyProtectedByPassword` class.
|
159 |
-
|
160 |
-
**Cautions:**
|
161 |
-
|
162 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
163 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
164 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
165 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
166 |
-
them to the user or saving them to log files).
|
167 |
-
|
168 |
-
Please note that **encryption does not, and is not intended to, hide the
|
169 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
170 |
-
a field in which only a small number of different-length values are possible
|
171 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
172 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
173 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
174 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
175 |
-
same length, and no information about the plaintext can be gleaned from the
|
176 |
-
length of the ciphertext.
|
177 |
-
|
178 |
-
### File::decryptFileWithPassword($inputFilename, $outputFilename, $password)
|
179 |
-
|
180 |
-
**Description:**
|
181 |
-
|
182 |
-
Decrypts a file with a password.
|
183 |
-
|
184 |
-
**Parameters:**
|
185 |
-
|
186 |
-
1. `$inputFilename` is the path to a file containing the ciphertext to decrypt.
|
187 |
-
2. `$outputFilename` is the path to save the decrypted plaintext file.
|
188 |
-
3. `$password` is the password used for decryption.
|
189 |
-
|
190 |
-
**Behavior:**
|
191 |
-
|
192 |
-
Decrypts the contents of the input file, writing the result to the output file.
|
193 |
-
If the output file already exists, it is overwritten.
|
194 |
-
|
195 |
-
**Return value:**
|
196 |
-
|
197 |
-
Does not return a value.
|
198 |
-
|
199 |
-
**Exceptions:**
|
200 |
-
|
201 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
202 |
-
|
203 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
204 |
-
the platform the code is running on cannot safely perform encryption for some
|
205 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
206 |
-
detected a bug in this library.
|
207 |
-
|
208 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
209 |
-
the `$password` is not the correct key for the given ciphertext, or if the
|
210 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
211 |
-
distinguish between these two cases.
|
212 |
-
|
213 |
-
**Side-effects and performance:**
|
214 |
-
|
215 |
-
This method is intentionally slow, using a lot of CPU resources for a fraction
|
216 |
-
of a second. It applies key stretching to the password in order to make password
|
217 |
-
guessing attacks more computationally expensive. If you need a faster way to
|
218 |
-
encrypt multiple ciphertexts under the same password, see the
|
219 |
-
`KeyProtectedByPassword` class.
|
220 |
-
|
221 |
-
The input ciphertext is processed in two passes. The first pass verifies the
|
222 |
-
integrity and the second pass performs the actual decryption of the file and
|
223 |
-
writing to the output file. This is done in a streaming manner so that only
|
224 |
-
a small part of the file is ever loaded into memory at a time.
|
225 |
-
|
226 |
-
**Cautions:**
|
227 |
-
|
228 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
229 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
230 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
231 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
232 |
-
them to the user or saving them to log files).
|
233 |
-
|
234 |
-
Be aware that when `Defuse\Crypto\WrongKeyOrModifiedCiphertextException` is
|
235 |
-
thrown, some partial plaintext data may have been written to the output. Any
|
236 |
-
plaintext data that is output is guaranteed to be a prefix of the original
|
237 |
-
plaintext (i.e. at worst it was truncated). This can only happen if an attacker
|
238 |
-
modifies the input between the first pass (integrity check) and the second pass
|
239 |
-
(decryption) over the file.
|
240 |
-
|
241 |
-
It is impossible in principle to distinguish between the case where you attempt
|
242 |
-
to decrypt with the wrong password and the case where you attempt to decrypt
|
243 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
244 |
-
this ambiguity, as it depends on the application this library is being used in.
|
245 |
-
If in doubt, consult with a professional cryptographer.
|
246 |
-
|
247 |
-
### File::encryptResource($inputHandle, $outputHandle, Key $key)
|
248 |
-
|
249 |
-
**Description:**
|
250 |
-
|
251 |
-
Encrypts a resource (stream) with a secret key.
|
252 |
-
|
253 |
-
**Parameters:**
|
254 |
-
|
255 |
-
1. `$inputHandle` is a handle to a resource (like a file pointer) containing the
|
256 |
-
plaintext to encrypt.
|
257 |
-
2. `$outputHandle` is a handle to a resource (like a file pointer) that the
|
258 |
-
ciphertext will be written to.
|
259 |
-
3. `$key` is an instance of `Key` containing the secret key for encryption.
|
260 |
-
|
261 |
-
**Behavior:**
|
262 |
-
|
263 |
-
Encrypts the data read from the input stream and writes it to the output stream.
|
264 |
-
|
265 |
-
**Return value:**
|
266 |
-
|
267 |
-
Does not return a value.
|
268 |
-
|
269 |
-
**Exceptions:**
|
270 |
-
|
271 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
272 |
-
|
273 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
274 |
-
the platform the code is running on cannot safely perform encryption for some
|
275 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
276 |
-
detected a bug in this library.
|
277 |
-
|
278 |
-
**Side-effects and performance:**
|
279 |
-
|
280 |
-
None.
|
281 |
-
|
282 |
-
**Cautions:**
|
283 |
-
|
284 |
-
The ciphertext output by this method is decryptable by anyone with knowledge of
|
285 |
-
the key `$key`. It is the caller's responsibility to keep `$key` secret. Where
|
286 |
-
`$key` should be stored is up to the caller and depends on the threat model the
|
287 |
-
caller is designing their application under. If you are unsure where to store
|
288 |
-
`$key`, consult with a professional cryptographer to get help designing your
|
289 |
-
application.
|
290 |
-
|
291 |
-
Please note that **encryption does not, and is not intended to, hide the
|
292 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
293 |
-
a field in which only a small number of different-length values are possible
|
294 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
295 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
296 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
297 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
298 |
-
same length, and no information about the plaintext can be gleaned from the
|
299 |
-
length of the ciphertext.
|
300 |
-
|
301 |
-
### File::decryptResource($inputHandle, $outputHandle, Key $key)
|
302 |
-
|
303 |
-
**Description:**
|
304 |
-
|
305 |
-
Decrypts a resource (stream) with a secret key.
|
306 |
-
|
307 |
-
**Parameters:**
|
308 |
-
|
309 |
-
1. `$inputHandle` is a handle to a file-backed resource containing the
|
310 |
-
ciphertext to decrypt. It must be a file not a network stream or standard
|
311 |
-
input.
|
312 |
-
2. `$outputHandle` is a handle to a resource (like a file pointer) that the
|
313 |
-
plaintext will be written to.
|
314 |
-
3. `$key` is an instance of `Key` containing the secret key for decryption.
|
315 |
-
|
316 |
-
**Behavior:**
|
317 |
-
|
318 |
-
Decrypts the data read from the input stream and writes it to the output stream.
|
319 |
-
|
320 |
-
**Return value:**
|
321 |
-
|
322 |
-
Does not return a value.
|
323 |
-
|
324 |
-
**Exceptions:**
|
325 |
-
|
326 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
327 |
-
|
328 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
329 |
-
the platform the code is running on cannot safely perform encryption for some
|
330 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
331 |
-
detected a bug in this library.
|
332 |
-
|
333 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
334 |
-
the `$key` is not the correct key for the given ciphertext, or if the
|
335 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
336 |
-
distinguish between these two cases.
|
337 |
-
|
338 |
-
**Side-effects and performance:**
|
339 |
-
|
340 |
-
The input ciphertext is processed in two passes. The first pass verifies the
|
341 |
-
integrity and the second pass performs the actual decryption of the file and
|
342 |
-
writing to the output file. This is done in a streaming manner so that only
|
343 |
-
a small part of the file is ever loaded into memory at a time.
|
344 |
-
|
345 |
-
**Cautions:**
|
346 |
-
|
347 |
-
Be aware that when `Defuse\Crypto\WrongKeyOrModifiedCiphertextException` is
|
348 |
-
thrown, some partial plaintext data may have been written to the output. Any
|
349 |
-
plaintext data that is output is guaranteed to be a prefix of the original
|
350 |
-
plaintext (i.e. at worst it was truncated). This can only happen if an attacker
|
351 |
-
modifies the input between the first pass (integrity check) and the second pass
|
352 |
-
(decryption) over the file.
|
353 |
-
|
354 |
-
It is impossible in principle to distinguish between the case where you attempt
|
355 |
-
to decrypt with the wrong key and the case where you attempt to decrypt
|
356 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
357 |
-
this ambiguity, as it depends on the application this library is being used in.
|
358 |
-
If in doubt, consult with a professional cryptographer.
|
359 |
-
|
360 |
-
### File::encryptResourceWithPassword($inputHandle, $outputHandle, $password)
|
361 |
-
|
362 |
-
**Description:**
|
363 |
-
|
364 |
-
Encrypts a resource (stream) with a password.
|
365 |
-
|
366 |
-
**Parameters:**
|
367 |
-
|
368 |
-
1. `$inputHandle` is a handle to a resource (like a file pointer) containing the
|
369 |
-
plaintext to encrypt.
|
370 |
-
2. `$outputHandle` is a handle to a resource (like a file pointer) that the
|
371 |
-
ciphertext will be written to.
|
372 |
-
3. `$password` is the password used for encryption.
|
373 |
-
|
374 |
-
**Behavior:**
|
375 |
-
|
376 |
-
Encrypts the data read from the input stream and writes it to the output stream.
|
377 |
-
|
378 |
-
**Return value:**
|
379 |
-
|
380 |
-
Does not return a value.
|
381 |
-
|
382 |
-
**Exceptions:**
|
383 |
-
|
384 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
385 |
-
|
386 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
387 |
-
the platform the code is running on cannot safely perform encryption for some
|
388 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
389 |
-
detected a bug in this library.
|
390 |
-
|
391 |
-
**Side-effects and performance:**
|
392 |
-
|
393 |
-
This method is intentionally slow, using a lot of CPU resources for a fraction
|
394 |
-
of a second. It applies key stretching to the password in order to make password
|
395 |
-
guessing attacks more computationally expensive. If you need a faster way to
|
396 |
-
encrypt multiple ciphertexts under the same password, see the
|
397 |
-
`KeyProtectedByPassword` class.
|
398 |
-
|
399 |
-
**Cautions:**
|
400 |
-
|
401 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
402 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
403 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
404 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
405 |
-
them to the user or saving them to log files).
|
406 |
-
|
407 |
-
Please note that **encryption does not, and is not intended to, hide the
|
408 |
-
*length* of the data being encrypted.** For example, it is not safe to encrypt
|
409 |
-
a field in which only a small number of different-length values are possible
|
410 |
-
(e.g. "male" or "female") since it would be possible to tell what the plaintext
|
411 |
-
is by looking at the length of the ciphertext. In order to do this safely, it is
|
412 |
-
your responsibility to, before encrypting, pad the data out to the length of the
|
413 |
-
longest string that will ever be encrypted. This way, all plaintexts are the
|
414 |
-
same length, and no information about the plaintext can be gleaned from the
|
415 |
-
length of the ciphertext.
|
416 |
-
|
417 |
-
### File::decryptResourceWithPassword($inputHandle, $outputHandle, $password)
|
418 |
-
|
419 |
-
**Description:**
|
420 |
-
|
421 |
-
Decrypts a resource (stream) with a password.
|
422 |
-
|
423 |
-
**Parameters:**
|
424 |
-
|
425 |
-
1. `$inputHandle` is a handle to a file-backed resource containing the
|
426 |
-
ciphertext to decrypt. It must be a file not a network stream or standard
|
427 |
-
input.
|
428 |
-
2. `$outputHandle` is a handle to a resource (like a file pointer) that the
|
429 |
-
plaintext will be written to.
|
430 |
-
3. `$password` is the password used for decryption.
|
431 |
-
|
432 |
-
**Behavior:**
|
433 |
-
|
434 |
-
Decrypts the data read from the input stream and writes it to the output stream.
|
435 |
-
|
436 |
-
**Return value:**
|
437 |
-
|
438 |
-
Does not return a value.
|
439 |
-
|
440 |
-
**Exceptions:**
|
441 |
-
|
442 |
-
- `Defuse\Crypto\Exception\IOException` is thrown if there is an I/O error.
|
443 |
-
|
444 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
445 |
-
the platform the code is running on cannot safely perform encryption for some
|
446 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
447 |
-
detected a bug in this library.
|
448 |
-
|
449 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
450 |
-
the `$password` is not the correct key for the given ciphertext, or if the
|
451 |
-
ciphertext has been modified (possibly maliciously). There is no way to
|
452 |
-
distinguish between these two cases.
|
453 |
-
|
454 |
-
**Side-effects and performance:**
|
455 |
-
|
456 |
-
This method is intentionally slow, using a lot of CPU resources for a fraction
|
457 |
-
of a second. It applies key stretching to the password in order to make password
|
458 |
-
guessing attacks more computationally expensive. If you need a faster way to
|
459 |
-
encrypt multiple ciphertexts under the same password, see the
|
460 |
-
`KeyProtectedByPassword` class.
|
461 |
-
|
462 |
-
The input ciphertext is processed in two passes. The first pass verifies the
|
463 |
-
integrity and the second pass performs the actual decryption of the file and
|
464 |
-
writing to the output file. This is done in a streaming manner so that only
|
465 |
-
a small part of the file is ever loaded into memory at a time.
|
466 |
-
|
467 |
-
**Cautions:**
|
468 |
-
|
469 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
470 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
471 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
472 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
473 |
-
them to the user or saving them to log files).
|
474 |
-
|
475 |
-
Be aware that when `Defuse\Crypto\WrongKeyOrModifiedCiphertextException` is
|
476 |
-
thrown, some partial plaintext data may have been written to the output. Any
|
477 |
-
plaintext data that is output is guaranteed to be a prefix of the original
|
478 |
-
plaintext (i.e. at worst it was truncated). This can only happen if an attacker
|
479 |
-
modifies the input between the first pass (integrity check) and the second pass
|
480 |
-
(decryption) over the file.
|
481 |
-
|
482 |
-
It is impossible in principle to distinguish between the case where you attempt
|
483 |
-
to decrypt with the wrong password and the case where you attempt to decrypt
|
484 |
-
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
|
485 |
-
this ambiguity, as it depends on the application this library is being used in.
|
486 |
-
If in doubt, consult with a professional cryptographer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/classes/Key.md
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
Class: Defuse\Crypto\Key
|
2 |
-
=========================
|
3 |
-
|
4 |
-
The `Key` class represents a secret key used for encrypting and decrypting. Once
|
5 |
-
you have a `Key` instance, you can use it with the `Crypto` class to encrypt and
|
6 |
-
decrypt strings and with the `File` class to encrypt and decrypt files.
|
7 |
-
|
8 |
-
Instance Methods
|
9 |
-
-----------------
|
10 |
-
|
11 |
-
### saveToAsciiSafeString()
|
12 |
-
|
13 |
-
**Description:**
|
14 |
-
|
15 |
-
Saves the encryption key to a string of printable ASCII characters, which can be
|
16 |
-
loaded again into a `Key` instance using `Key::loadFromAsciiSafeString()`.
|
17 |
-
|
18 |
-
**Parameters:**
|
19 |
-
|
20 |
-
This method does not take any parameters.
|
21 |
-
|
22 |
-
**Return value:**
|
23 |
-
|
24 |
-
Returns a string of printable ASCII characters representing this `Key` instance,
|
25 |
-
which can be loaded back into an instance of `Key` using
|
26 |
-
`Key::loadFromAsciiSafeString()`.
|
27 |
-
|
28 |
-
**Exceptions:**
|
29 |
-
|
30 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
31 |
-
the platform the code is running on cannot safely perform encryption for some
|
32 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
33 |
-
detected a bug in this library.
|
34 |
-
|
35 |
-
**Side-effects and performance:**
|
36 |
-
|
37 |
-
None.
|
38 |
-
|
39 |
-
**Cautions:**
|
40 |
-
|
41 |
-
This method currently returns a hexadecimal string. You should not rely on this
|
42 |
-
behavior. For example, it may be improved in the future to return a base64
|
43 |
-
string.
|
44 |
-
|
45 |
-
Static Methods
|
46 |
-
---------------
|
47 |
-
|
48 |
-
### Key::createNewRandomKey()
|
49 |
-
|
50 |
-
**Description:**
|
51 |
-
|
52 |
-
Generates a new random key and returns an instance of `Key`.
|
53 |
-
|
54 |
-
**Parameters:**
|
55 |
-
|
56 |
-
This method does not take any parameters.
|
57 |
-
|
58 |
-
**Return value:**
|
59 |
-
|
60 |
-
Returns an instance of `Key` containing a randomly-generated encryption key.
|
61 |
-
|
62 |
-
**Exceptions:**
|
63 |
-
|
64 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
65 |
-
the platform the code is running on cannot safely perform encryption for some
|
66 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
67 |
-
detected a bug in this library.
|
68 |
-
|
69 |
-
**Side-effects and performance:**
|
70 |
-
|
71 |
-
None.
|
72 |
-
|
73 |
-
**Cautions:**
|
74 |
-
|
75 |
-
None.
|
76 |
-
|
77 |
-
### Key::loadFromAsciiSafeString($saved\_key\_string, $do\_not\_trim = false)
|
78 |
-
|
79 |
-
**Description:**
|
80 |
-
|
81 |
-
Loads an instance of `Key` that was saved to a string by
|
82 |
-
`saveToAsciiSafeString()`.
|
83 |
-
|
84 |
-
By default, this function will call `Encoding::trimTrailingWhitespace()`
|
85 |
-
to remove trailing CR, LF, NUL, TAB, and SPACE characters, which are commonly
|
86 |
-
appended to files when working with text editors.
|
87 |
-
|
88 |
-
**Parameters:**
|
89 |
-
|
90 |
-
1. `$saved_key_string` is the string returned from `saveToAsciiSafeString()`
|
91 |
-
when the original `Key` instance was saved.
|
92 |
-
2. `$do_not_trim` should be set to `TRUE` if you do not wish for the library
|
93 |
-
to automatically strip trailing whitespace from the string.
|
94 |
-
|
95 |
-
**Return value:**
|
96 |
-
|
97 |
-
Returns an instance of `Key` representing the same encryption key as the one
|
98 |
-
that was represented by the `Key` instance that got saved into
|
99 |
-
`$saved_key_string` by a call to `saveToAsciiSafeString()`.
|
100 |
-
|
101 |
-
**Exceptions:**
|
102 |
-
|
103 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
104 |
-
the platform the code is running on cannot safely perform encryption for some
|
105 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
106 |
-
detected a bug in this library.
|
107 |
-
|
108 |
-
- `Defuse\Crypto\Exception\BadFormatException` is thrown whenever
|
109 |
-
`$saved_key_string` does not represent a valid `Key` instance.
|
110 |
-
|
111 |
-
**Side-effects and performance:**
|
112 |
-
|
113 |
-
None.
|
114 |
-
|
115 |
-
**Cautions:**
|
116 |
-
|
117 |
-
None.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/docs/classes/KeyProtectedByPassword.md
DELETED
@@ -1,259 +0,0 @@
|
|
1 |
-
Class: Defuse\Crypto\KeyProtectedByPassword
|
2 |
-
============================================
|
3 |
-
|
4 |
-
The `KeyProtectedByPassword` class represents a key that is "locked" with
|
5 |
-
a password. In order to obtain an instance of `Key` that you can use for
|
6 |
-
encrypting and decrypting, a `KeyProtectedByPassword` must first be "unlocked"
|
7 |
-
by providing the correct password.
|
8 |
-
|
9 |
-
`KeyProtectedByPassword` provides an alternative to using the
|
10 |
-
`encryptWithPassword()`, `decryptWithPassword()`, `encryptFileWithPassword()`,
|
11 |
-
and `decryptFileWithPassword()` methods with several advantages:
|
12 |
-
|
13 |
-
- The slow and computationally-expensive key stretching is run only once when
|
14 |
-
you unlock a `KeyProtectedByPassword` to obtain the `Key`.
|
15 |
-
- You do not have to keep the original password in memory to encrypt and decrypt
|
16 |
-
things. After you've obtained the `Key` from a `KeyProtectedByPassword`, the
|
17 |
-
password is no longer necessary.
|
18 |
-
|
19 |
-
Instance Methods
|
20 |
-
-----------------
|
21 |
-
|
22 |
-
### saveToAsciiSafeString()
|
23 |
-
|
24 |
-
**Description:**
|
25 |
-
|
26 |
-
Saves the protected key to a string of printable ASCII characters, which can be
|
27 |
-
loaded again into a `KeyProtectedByPassword` instance using
|
28 |
-
`KeyProtectedByPassword::loadFromAsciiSafeString()`.
|
29 |
-
|
30 |
-
**Parameters:**
|
31 |
-
|
32 |
-
This method does not take any parameters.
|
33 |
-
|
34 |
-
**Return value:**
|
35 |
-
|
36 |
-
Returns a string of printable ASCII characters representing this
|
37 |
-
`KeyProtectedByPassword` instance, which can be loaded back into an instance of
|
38 |
-
`KeyProtectedByPassword` using
|
39 |
-
`KeyProtectedByPassword::loadFromAsciiSafeString()`.
|
40 |
-
|
41 |
-
**Exceptions:**
|
42 |
-
|
43 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
44 |
-
the platform the code is running on cannot safely perform encryption for some
|
45 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
46 |
-
detected a bug in this library.
|
47 |
-
|
48 |
-
**Side-effects and performance:**
|
49 |
-
|
50 |
-
None.
|
51 |
-
|
52 |
-
**Cautions:**
|
53 |
-
|
54 |
-
This method currently returns a hexadecimal string. You should not rely on this
|
55 |
-
behavior. For example, it may be improved in the future to return a base64
|
56 |
-
string.
|
57 |
-
|
58 |
-
### unlockKey($password)
|
59 |
-
|
60 |
-
**Description:**
|
61 |
-
|
62 |
-
Unlocks the password-protected key, obtaining a `Key` which can be used for
|
63 |
-
encryption and decryption.
|
64 |
-
|
65 |
-
**Parameters:**
|
66 |
-
|
67 |
-
1. `$password` is the password required to unlock this `KeyProtectedByPassword`
|
68 |
-
to obtain the `Key`.
|
69 |
-
|
70 |
-
**Return value:**
|
71 |
-
|
72 |
-
If `$password` is the correct password, then this method returns an instance of
|
73 |
-
the `Key` class.
|
74 |
-
|
75 |
-
**Exceptions:**
|
76 |
-
|
77 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
78 |
-
the platform the code is running on cannot safely perform encryption for some
|
79 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
80 |
-
detected a bug in this library.
|
81 |
-
|
82 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
83 |
-
either the given `$password` is not the correct password for this
|
84 |
-
`KeyProtectedByPassword` or the ciphertext stored internally by this object
|
85 |
-
has been modified, i.e. it was accidentally corrupted or intentionally
|
86 |
-
corrupted by an attacker. There is no way for the caller to distinguish
|
87 |
-
between these two cases.
|
88 |
-
|
89 |
-
**Side-effects and performance:**
|
90 |
-
|
91 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
92 |
-
time this method or one of the `Crypto` methods has been called. The performance
|
93 |
-
overhead is negligible and can be safely ignored in all applications.
|
94 |
-
|
95 |
-
**Cautions:**
|
96 |
-
|
97 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
98 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
99 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
100 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
101 |
-
them to the user or saving them to log files).
|
102 |
-
|
103 |
-
It is impossible in principle to distinguish between the case where you attempt
|
104 |
-
to unlock with the wrong password and the case where you attempt to unlock
|
105 |
-
a modified (corrupted) `KeyProtectedByPassword`. It is up to the caller how to
|
106 |
-
best deal with this ambiguity, as it depends on the application this library is
|
107 |
-
being used in. If in doubt, consult with a professional cryptographer.
|
108 |
-
|
109 |
-
### changePassword($current\_password, $new\_password)
|
110 |
-
|
111 |
-
**Description:**
|
112 |
-
|
113 |
-
Changes the password, so that calling `unlockKey` on this object in the future
|
114 |
-
will require you to pass `$new\_password` instead of the old password. It is
|
115 |
-
your responsibility to overwrite all stored copies of this
|
116 |
-
`KeyProtectedByPassword`. Any copies you leave lying around can still be
|
117 |
-
decrypted with the old password.
|
118 |
-
|
119 |
-
**Parameters:**
|
120 |
-
|
121 |
-
1. `$current\_password` is the password that this `KeyProtectedByPassword` is
|
122 |
-
currently protected with.
|
123 |
-
2. `$new\_password` is the new password, which the `KeyProtectedByPassword` will
|
124 |
-
be protected with once this operation completes.
|
125 |
-
|
126 |
-
**Return value:**
|
127 |
-
|
128 |
-
If `$current\_password` is the correct password, then this method updates itself
|
129 |
-
to be protected with the new password, and also returns itself.
|
130 |
-
|
131 |
-
**Exceptions:**
|
132 |
-
|
133 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
134 |
-
the platform the code is running on cannot safely perform encryption for some
|
135 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
136 |
-
detected a bug in this library.
|
137 |
-
|
138 |
-
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
|
139 |
-
either the given `$current\_password` is not the correct password for this
|
140 |
-
`KeyProtectedByPassword` or the ciphertext stored internally by this object
|
141 |
-
has been modified, i.e. it was accidentally corrupted or intentionally
|
142 |
-
corrupted by an attacker. There is no way for the caller to distinguish
|
143 |
-
between these two cases.
|
144 |
-
|
145 |
-
**Side-effects and performance:**
|
146 |
-
|
147 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
148 |
-
time this method or one of the `Crypto` methods has been called. The performance
|
149 |
-
overhead is negligible and can be safely ignored in all applications.
|
150 |
-
|
151 |
-
**Cautions:**
|
152 |
-
|
153 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
154 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
155 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
156 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
157 |
-
them to the user or saving them to log files).
|
158 |
-
|
159 |
-
It is impossible in principle to distinguish between the case where you attempt
|
160 |
-
to unlock with the wrong password and the case where you attempt to unlock
|
161 |
-
a modified (corrupted) `KeyProtectedByPassword`. It is up to the caller how to
|
162 |
-
best deal with this ambiguity, as it depends on the application this library is
|
163 |
-
being used in. If in doubt, consult with a professional cryptographer.
|
164 |
-
|
165 |
-
**WARNING:** Because of the way `KeyProtectedByPassword` is implemented, knowing
|
166 |
-
`SHA256($password)` is enough to decrypt a `KeyProtectedByPassword`. To be
|
167 |
-
secure, your application MUST NOT EVER compute `SHA256($password)` and use or
|
168 |
-
store it for any reason. You must also make sure that other libraries your
|
169 |
-
application is using don't compute it either.
|
170 |
-
|
171 |
-
Static Methods
|
172 |
-
---------------
|
173 |
-
|
174 |
-
### KeyProtectedByPassword::createRandomPasswordProtectedKey($password)
|
175 |
-
|
176 |
-
**Description:**
|
177 |
-
|
178 |
-
Generates a new random key that's protected by the string `$password` and
|
179 |
-
returns an instance of `KeyProtectedByPassword`.
|
180 |
-
|
181 |
-
**Parameters:**
|
182 |
-
|
183 |
-
1. `$password` is the password used to protect the random key.
|
184 |
-
|
185 |
-
**Return value:**
|
186 |
-
|
187 |
-
Returns an instance of `KeyProtectedByPassword` containing a randomly-generated
|
188 |
-
encryption key that's protected by the password `$password`.
|
189 |
-
|
190 |
-
**Exceptions:**
|
191 |
-
|
192 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
193 |
-
the platform the code is running on cannot safely perform encryption for some
|
194 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
195 |
-
detected a bug in this library.
|
196 |
-
|
197 |
-
**Side-effects and performance:**
|
198 |
-
|
199 |
-
This method runs a small and very fast set of self-tests if it is the very first
|
200 |
-
time this method or one of the `Crypto` methods has been called. The performance
|
201 |
-
overhead is negligible and can be safely ignored in all applications.
|
202 |
-
|
203 |
-
**Cautions:**
|
204 |
-
|
205 |
-
PHP stack traces display (portions of) the arguments passed to methods on the
|
206 |
-
call stack. If an exception is thrown inside this call, and it is uncaught, the
|
207 |
-
value of `$password` may be leaked out to an attacker through the stack trace.
|
208 |
-
We recommend configuring PHP to never output stack traces (either displaying
|
209 |
-
them to the user or saving them to log files).
|
210 |
-
|
211 |
-
Be aware that if you protecting multiple keys with the same password, an
|
212 |
-
attacker with write access to your system will be able to swap the protected
|
213 |
-
keys around so that the wrong key gets used next time it is unlocked. This could
|
214 |
-
lead to data being encrypted with the wrong key, perhaps one that the attacker
|
215 |
-
knows.
|
216 |
-
|
217 |
-
**WARNING:** Because of the way `KeyProtectedByPassword` is implemented, knowing
|
218 |
-
`SHA256($password)` is enough to decrypt a `KeyProtectedByPassword`. To be
|
219 |
-
secure, your application MUST NOT EVER compute `SHA256($password)` and use or
|
220 |
-
store it for any reason. You must also make sure that other libraries your
|
221 |
-
application is using don't compute it either.
|
222 |
-
|
223 |
-
### KeyProtectedByPassword::loadFromAsciiSafeString($saved\_key\_string)
|
224 |
-
|
225 |
-
**Description:**
|
226 |
-
|
227 |
-
Loads an instance of `KeyProtectedByPassword` that was saved to a string by
|
228 |
-
`saveToAsciiSafeString()`.
|
229 |
-
|
230 |
-
**Parameters:**
|
231 |
-
|
232 |
-
1. `$saved_key_string` is the string returned from `saveToAsciiSafeString()`
|
233 |
-
when the original `KeyProtectedByPassword` instance was saved.
|
234 |
-
|
235 |
-
**Return value:**
|
236 |
-
|
237 |
-
Returns an instance of `KeyProtectedByPassword` representing the same
|
238 |
-
password-protected key as the one that was represented by the
|
239 |
-
`KeyProtectedByPassword` instance that got saved into `$saved_key_string` by
|
240 |
-
a call to `saveToAsciiSafeString()`.
|
241 |
-
|
242 |
-
**Exceptions:**
|
243 |
-
|
244 |
-
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
|
245 |
-
the platform the code is running on cannot safely perform encryption for some
|
246 |
-
reason (e.g. it lacks a secure random number generator), or the runtime tests
|
247 |
-
detected a bug in this library.
|
248 |
-
|
249 |
-
- `Defuse\Crypto\Exception\BadFormatException` is thrown whenever
|
250 |
-
`$saved_key_string` does not represent a valid `KeyProtectedByPassword`
|
251 |
-
instance.
|
252 |
-
|
253 |
-
**Side-effects and performance:**
|
254 |
-
|
255 |
-
None.
|
256 |
-
|
257 |
-
**Cautions:**
|
258 |
-
|
259 |
-
None.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/psalm.xml
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
<?xml version="1.0"?>
|
2 |
-
<psalm
|
3 |
-
useDocblockTypes="true"
|
4 |
-
>
|
5 |
-
<projectFiles>
|
6 |
-
<directory name="src" />
|
7 |
-
</projectFiles>
|
8 |
-
<issueHandlers>
|
9 |
-
<DocblockTypeContradiction errorLevel="info" />
|
10 |
-
<RedundantConditionGivenDocblockType errorLevel="info" />
|
11 |
-
</issueHandlers>
|
12 |
-
</psalm>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Core.php
DELETED
@@ -1,448 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class Core
|
8 |
-
{
|
9 |
-
const HEADER_VERSION_SIZE = 4;
|
10 |
-
const MINIMUM_CIPHERTEXT_SIZE = 84;
|
11 |
-
|
12 |
-
const CURRENT_VERSION = "\xDE\xF5\x02\x00";
|
13 |
-
|
14 |
-
const CIPHER_METHOD = 'aes-256-ctr';
|
15 |
-
const BLOCK_BYTE_SIZE = 16;
|
16 |
-
const KEY_BYTE_SIZE = 32;
|
17 |
-
const SALT_BYTE_SIZE = 32;
|
18 |
-
const MAC_BYTE_SIZE = 32;
|
19 |
-
const HASH_FUNCTION_NAME = 'sha256';
|
20 |
-
const ENCRYPTION_INFO_STRING = 'DefusePHP|V2|KeyForEncryption';
|
21 |
-
const AUTHENTICATION_INFO_STRING = 'DefusePHP|V2|KeyForAuthentication';
|
22 |
-
const BUFFER_BYTE_SIZE = 1048576;
|
23 |
-
|
24 |
-
const LEGACY_CIPHER_METHOD = 'aes-128-cbc';
|
25 |
-
const LEGACY_BLOCK_BYTE_SIZE = 16;
|
26 |
-
const LEGACY_KEY_BYTE_SIZE = 16;
|
27 |
-
const LEGACY_HASH_FUNCTION_NAME = 'sha256';
|
28 |
-
const LEGACY_MAC_BYTE_SIZE = 32;
|
29 |
-
const LEGACY_ENCRYPTION_INFO_STRING = 'DefusePHP|KeyForEncryption';
|
30 |
-
const LEGACY_AUTHENTICATION_INFO_STRING = 'DefusePHP|KeyForAuthentication';
|
31 |
-
|
32 |
-
/*
|
33 |
-
* V2.0 Format: VERSION (4 bytes) || SALT (32 bytes) || IV (16 bytes) ||
|
34 |
-
* CIPHERTEXT (varies) || HMAC (32 bytes)
|
35 |
-
*
|
36 |
-
* V1.0 Format: HMAC (32 bytes) || IV (16 bytes) || CIPHERTEXT (varies).
|
37 |
-
*/
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Adds an integer to a block-sized counter.
|
41 |
-
*
|
42 |
-
* @param string $ctr
|
43 |
-
* @param int $inc
|
44 |
-
*
|
45 |
-
* @throws Ex\EnvironmentIsBrokenException
|
46 |
-
*
|
47 |
-
* @return string
|
48 |
-
*
|
49 |
-
* @psalm-suppress RedundantCondition - It's valid to use is_int to check for overflow.
|
50 |
-
*/
|
51 |
-
public static function incrementCounter($ctr, $inc)
|
52 |
-
{
|
53 |
-
Core::ensureTrue(
|
54 |
-
Core::ourStrlen($ctr) === Core::BLOCK_BYTE_SIZE,
|
55 |
-
'Trying to increment a nonce of the wrong size.'
|
56 |
-
);
|
57 |
-
|
58 |
-
Core::ensureTrue(
|
59 |
-
\is_int($inc),
|
60 |
-
'Trying to increment nonce by a non-integer.'
|
61 |
-
);
|
62 |
-
|
63 |
-
// The caller is probably re-using CTR-mode keystream if they increment by 0.
|
64 |
-
Core::ensureTrue(
|
65 |
-
$inc > 0,
|
66 |
-
'Trying to increment a nonce by a nonpositive amount'
|
67 |
-
);
|
68 |
-
|
69 |
-
Core::ensureTrue(
|
70 |
-
$inc <= PHP_INT_MAX - 255,
|
71 |
-
'Integer overflow may occur'
|
72 |
-
);
|
73 |
-
|
74 |
-
/*
|
75 |
-
* We start at the rightmost byte (big-endian)
|
76 |
-
* So, too, does OpenSSL: http://stackoverflow.com/a/3146214/2224584
|
77 |
-
*/
|
78 |
-
for ($i = Core::BLOCK_BYTE_SIZE - 1; $i >= 0; --$i) {
|
79 |
-
$sum = \ord($ctr[$i]) + $inc;
|
80 |
-
|
81 |
-
/* Detect integer overflow and fail. */
|
82 |
-
Core::ensureTrue(\is_int($sum), 'Integer overflow in CTR mode nonce increment');
|
83 |
-
|
84 |
-
$ctr[$i] = \pack('C', $sum & 0xFF);
|
85 |
-
$inc = $sum >> 8;
|
86 |
-
}
|
87 |
-
return $ctr;
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Returns a random byte string of the specified length.
|
92 |
-
*
|
93 |
-
* @param int $octets
|
94 |
-
*
|
95 |
-
* @throws Ex\EnvironmentIsBrokenException
|
96 |
-
*
|
97 |
-
* @return string
|
98 |
-
*/
|
99 |
-
public static function secureRandom($octets)
|
100 |
-
{
|
101 |
-
self::ensureFunctionExists('random_bytes');
|
102 |
-
try {
|
103 |
-
return \random_bytes($octets);
|
104 |
-
} catch (\Exception $ex) {
|
105 |
-
throw new Ex\EnvironmentIsBrokenException(
|
106 |
-
'Your system does not have a secure random number generator.'
|
107 |
-
);
|
108 |
-
}
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Computes the HKDF key derivation function specified in
|
113 |
-
* http://tools.ietf.org/html/rfc5869.
|
114 |
-
*
|
115 |
-
* @param string $hash Hash Function
|
116 |
-
* @param string $ikm Initial Keying Material
|
117 |
-
* @param int $length How many bytes?
|
118 |
-
* @param string $info What sort of key are we deriving?
|
119 |
-
* @param string $salt
|
120 |
-
*
|
121 |
-
* @throws Ex\EnvironmentIsBrokenException
|
122 |
-
* @psalm-suppress UndefinedFunction - We're checking if the function exists first.
|
123 |
-
*
|
124 |
-
* @return string
|
125 |
-
*/
|
126 |
-
public static function HKDF($hash, $ikm, $length, $info = '', $salt = null)
|
127 |
-
{
|
128 |
-
static $nativeHKDF = null;
|
129 |
-
if ($nativeHKDF === null) {
|
130 |
-
$nativeHKDF = \is_callable('\\hash_hkdf');
|
131 |
-
}
|
132 |
-
if ($nativeHKDF) {
|
133 |
-
if (\is_null($salt)) {
|
134 |
-
$salt = '';
|
135 |
-
}
|
136 |
-
return \hash_hkdf($hash, $ikm, $length, $info, $salt);
|
137 |
-
}
|
138 |
-
|
139 |
-
$digest_length = Core::ourStrlen(\hash_hmac($hash, '', '', true));
|
140 |
-
|
141 |
-
// Sanity-check the desired output length.
|
142 |
-
Core::ensureTrue(
|
143 |
-
!empty($length) && \is_int($length) && $length >= 0 && $length <= 255 * $digest_length,
|
144 |
-
'Bad output length requested of HDKF.'
|
145 |
-
);
|
146 |
-
|
147 |
-
// "if [salt] not provided, is set to a string of HashLen zeroes."
|
148 |
-
if (\is_null($salt)) {
|
149 |
-
$salt = \str_repeat("\x00", $digest_length);
|
150 |
-
}
|
151 |
-
|
152 |
-
// HKDF-Extract:
|
153 |
-
// PRK = HMAC-Hash(salt, IKM)
|
154 |
-
// The salt is the HMAC key.
|
155 |
-
$prk = \hash_hmac($hash, $ikm, $salt, true);
|
156 |
-
|
157 |
-
// HKDF-Expand:
|
158 |
-
|
159 |
-
// This check is useless, but it serves as a reminder to the spec.
|
160 |
-
Core::ensureTrue(Core::ourStrlen($prk) >= $digest_length);
|
161 |
-
|
162 |
-
// T(0) = ''
|
163 |
-
$t = '';
|
164 |
-
$last_block = '';
|
165 |
-
for ($block_index = 1; Core::ourStrlen($t) < $length; ++$block_index) {
|
166 |
-
// T(i) = HMAC-Hash(PRK, T(i-1) | info | 0x??)
|
167 |
-
$last_block = \hash_hmac(
|
168 |
-
$hash,
|
169 |
-
$last_block . $info . \chr($block_index),
|
170 |
-
$prk,
|
171 |
-
true
|
172 |
-
);
|
173 |
-
// T = T(1) | T(2) | T(3) | ... | T(N)
|
174 |
-
$t .= $last_block;
|
175 |
-
}
|
176 |
-
|
177 |
-
// ORM = first L octets of T
|
178 |
-
/** @var string $orm */
|
179 |
-
$orm = Core::ourSubstr($t, 0, $length);
|
180 |
-
Core::ensureTrue(\is_string($orm));
|
181 |
-
return $orm;
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Checks if two equal-length strings are the same without leaking
|
186 |
-
* information through side channels.
|
187 |
-
*
|
188 |
-
* @param string $expected
|
189 |
-
* @param string $given
|
190 |
-
*
|
191 |
-
* @throws Ex\EnvironmentIsBrokenException
|
192 |
-
*
|
193 |
-
* @return bool
|
194 |
-
*/
|
195 |
-
public static function hashEquals($expected, $given)
|
196 |
-
{
|
197 |
-
static $native = null;
|
198 |
-
if ($native === null) {
|
199 |
-
$native = \function_exists('hash_equals');
|
200 |
-
}
|
201 |
-
if ($native) {
|
202 |
-
return \hash_equals($expected, $given);
|
203 |
-
}
|
204 |
-
|
205 |
-
// We can't just compare the strings with '==', since it would make
|
206 |
-
// timing attacks possible. We could use the XOR-OR constant-time
|
207 |
-
// comparison algorithm, but that may not be a reliable defense in an
|
208 |
-
// interpreted language. So we use the approach of HMACing both strings
|
209 |
-
// with a random key and comparing the HMACs.
|
210 |
-
|
211 |
-
// We're not attempting to make variable-length string comparison
|
212 |
-
// secure, as that's very difficult. Make sure the strings are the same
|
213 |
-
// length.
|
214 |
-
Core::ensureTrue(Core::ourStrlen($expected) === Core::ourStrlen($given));
|
215 |
-
|
216 |
-
$blind = Core::secureRandom(32);
|
217 |
-
$message_compare = \hash_hmac(Core::HASH_FUNCTION_NAME, $given, $blind);
|
218 |
-
$correct_compare = \hash_hmac(Core::HASH_FUNCTION_NAME, $expected, $blind);
|
219 |
-
return $correct_compare === $message_compare;
|
220 |
-
}
|
221 |
-
/**
|
222 |
-
* Throws an exception if the constant doesn't exist.
|
223 |
-
*
|
224 |
-
* @param string $name
|
225 |
-
* @return void
|
226 |
-
*
|
227 |
-
* @throws Ex\EnvironmentIsBrokenException
|
228 |
-
*/
|
229 |
-
public static function ensureConstantExists($name)
|
230 |
-
{
|
231 |
-
Core::ensureTrue(\defined($name));
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Throws an exception if the function doesn't exist.
|
236 |
-
*
|
237 |
-
* @param string $name
|
238 |
-
* @return void
|
239 |
-
*
|
240 |
-
* @throws Ex\EnvironmentIsBrokenException
|
241 |
-
*/
|
242 |
-
public static function ensureFunctionExists($name)
|
243 |
-
{
|
244 |
-
Core::ensureTrue(\function_exists($name));
|
245 |
-
}
|
246 |
-
|
247 |
-
/**
|
248 |
-
* Throws an exception if the condition is false.
|
249 |
-
*
|
250 |
-
* @param bool $condition
|
251 |
-
* @param string $message
|
252 |
-
* @return void
|
253 |
-
*
|
254 |
-
* @throws Ex\EnvironmentIsBrokenException
|
255 |
-
*/
|
256 |
-
public static function ensureTrue($condition, $message = '')
|
257 |
-
{
|
258 |
-
if (!$condition) {
|
259 |
-
throw new Ex\EnvironmentIsBrokenException($message);
|
260 |
-
}
|
261 |
-
}
|
262 |
-
|
263 |
-
/*
|
264 |
-
* We need these strlen() and substr() functions because when
|
265 |
-
* 'mbstring.func_overload' is set in php.ini, the standard strlen() and
|
266 |
-
* substr() are replaced by mb_strlen() and mb_substr().
|
267 |
-
*/
|
268 |
-
|
269 |
-
/**
|
270 |
-
* Computes the length of a string in bytes.
|
271 |
-
*
|
272 |
-
* @param string $str
|
273 |
-
*
|
274 |
-
* @throws Ex\EnvironmentIsBrokenException
|
275 |
-
*
|
276 |
-
* @return int
|
277 |
-
*/
|
278 |
-
public static function ourStrlen($str)
|
279 |
-
{
|
280 |
-
static $exists = null;
|
281 |
-
if ($exists === null) {
|
282 |
-
$exists = \extension_loaded('mbstring') && \ini_get('mbstring.func_overload') !== false && (int)\ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING;
|
283 |
-
}
|
284 |
-
if ($exists) {
|
285 |
-
$length = \mb_strlen($str, '8bit');
|
286 |
-
Core::ensureTrue($length !== false);
|
287 |
-
return $length;
|
288 |
-
} else {
|
289 |
-
return \strlen($str);
|
290 |
-
}
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* Behaves roughly like the function substr() in PHP 7 does.
|
295 |
-
*
|
296 |
-
* @param string $str
|
297 |
-
* @param int $start
|
298 |
-
* @param int $length
|
299 |
-
*
|
300 |
-
* @throws Ex\EnvironmentIsBrokenException
|
301 |
-
*
|
302 |
-
* @return string|bool
|
303 |
-
*/
|
304 |
-
public static function ourSubstr($str, $start, $length = null)
|
305 |
-
{
|
306 |
-
static $exists = null;
|
307 |
-
if ($exists === null) {
|
308 |
-
$exists = \extension_loaded('mbstring') && \ini_get('mbstring.func_overload') !== false && (int)\ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING;
|
309 |
-
}
|
310 |
-
|
311 |
-
// This is required to make mb_substr behavior identical to substr.
|
312 |
-
// Without this, mb_substr() would return false, contra to what the
|
313 |
-
// PHP documentation says (it doesn't say it can return false.)
|
314 |
-
$input_len = Core::ourStrlen($str);
|
315 |
-
if ($start === $input_len && !$length) {
|
316 |
-
return '';
|
317 |
-
}
|
318 |
-
|
319 |
-
if ($start > $input_len) {
|
320 |
-
return false;
|
321 |
-
}
|
322 |
-
|
323 |
-
// mb_substr($str, 0, NULL, '8bit') returns an empty string on PHP 5.3,
|
324 |
-
// so we have to find the length ourselves. Also, substr() doesn't
|
325 |
-
// accept null for the length.
|
326 |
-
if (! isset($length)) {
|
327 |
-
if ($start >= 0) {
|
328 |
-
$length = $input_len - $start;
|
329 |
-
} else {
|
330 |
-
$length = -$start;
|
331 |
-
}
|
332 |
-
}
|
333 |
-
|
334 |
-
if ($length < 0) {
|
335 |
-
throw new \InvalidArgumentException(
|
336 |
-
"Negative lengths are not supported with ourSubstr."
|
337 |
-
);
|
338 |
-
}
|
339 |
-
|
340 |
-
if ($exists) {
|
341 |
-
$substr = \mb_substr($str, $start, $length, '8bit');
|
342 |
-
// At this point there are two cases where mb_substr can
|
343 |
-
// legitimately return an empty string. Either $length is 0, or
|
344 |
-
// $start is equal to the length of the string (both mb_substr and
|
345 |
-
// substr return an empty string when this happens). It should never
|
346 |
-
// ever return a string that's longer than $length.
|
347 |
-
if (Core::ourStrlen($substr) > $length || (Core::ourStrlen($substr) === 0 && $length !== 0 && $start !== $input_len)) {
|
348 |
-
throw new Ex\EnvironmentIsBrokenException(
|
349 |
-
'Your version of PHP has bug #66797. Its implementation of
|
350 |
-
mb_substr() is incorrect. See the details here:
|
351 |
-
https://bugs.php.net/bug.php?id=66797'
|
352 |
-
);
|
353 |
-
}
|
354 |
-
return $substr;
|
355 |
-
}
|
356 |
-
|
357 |
-
return \substr($str, $start, $length);
|
358 |
-
}
|
359 |
-
|
360 |
-
/**
|
361 |
-
* Computes the PBKDF2 password-based key derivation function.
|
362 |
-
*
|
363 |
-
* The PBKDF2 function is defined in RFC 2898. Test vectors can be found in
|
364 |
-
* RFC 6070. This implementation of PBKDF2 was originally created by Taylor
|
365 |
-
* Hornby, with improvements from http://www.variations-of-shadow.com/.
|
366 |
-
*
|
367 |
-
* @param string $algorithm The hash algorithm to use. Recommended: SHA256
|
368 |
-
* @param string $password The password.
|
369 |
-
* @param string $salt A salt that is unique to the password.
|
370 |
-
* @param int $count Iteration count. Higher is better, but slower. Recommended: At least 1000.
|
371 |
-
* @param int $key_length The length of the derived key in bytes.
|
372 |
-
* @param bool $raw_output If true, the key is returned in raw binary format. Hex encoded otherwise.
|
373 |
-
*
|
374 |
-
* @throws Ex\EnvironmentIsBrokenException
|
375 |
-
*
|
376 |
-
* @return string A $key_length-byte key derived from the password and salt.
|
377 |
-
*/
|
378 |
-
public static function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
|
379 |
-
{
|
380 |
-
// Type checks:
|
381 |
-
if (! \is_string($algorithm)) {
|
382 |
-
throw new \InvalidArgumentException(
|
383 |
-
'pbkdf2(): algorithm must be a string'
|
384 |
-
);
|
385 |
-
}
|
386 |
-
if (! \is_string($password)) {
|
387 |
-
throw new \InvalidArgumentException(
|
388 |
-
'pbkdf2(): password must be a string'
|
389 |
-
);
|
390 |
-
}
|
391 |
-
if (! \is_string($salt)) {
|
392 |
-
throw new \InvalidArgumentException(
|
393 |
-
'pbkdf2(): salt must be a string'
|
394 |
-
);
|
395 |
-
}
|
396 |
-
// Coerce strings to integers with no information loss or overflow
|
397 |
-
$count += 0;
|
398 |
-
$key_length += 0;
|
399 |
-
|
400 |
-
$algorithm = \strtolower($algorithm);
|
401 |
-
Core::ensureTrue(
|
402 |
-
\in_array($algorithm, \hash_algos(), true),
|
403 |
-
'Invalid or unsupported hash algorithm.'
|
404 |
-
);
|
405 |
-
|
406 |
-
// Whitelist, or we could end up with people using CRC32.
|
407 |
-
$ok_algorithms = [
|
408 |
-
'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
|
409 |
-
'ripemd160', 'ripemd256', 'ripemd320', 'whirlpool',
|
410 |
-
];
|
411 |
-
Core::ensureTrue(
|
412 |
-
\in_array($algorithm, $ok_algorithms, true),
|
413 |
-
'Algorithm is not a secure cryptographic hash function.'
|
414 |
-
);
|
415 |
-
|
416 |
-
Core::ensureTrue($count > 0 && $key_length > 0, 'Invalid PBKDF2 parameters.');
|
417 |
-
|
418 |
-
if (\function_exists('hash_pbkdf2')) {
|
419 |
-
// The output length is in NIBBLES (4-bits) if $raw_output is false!
|
420 |
-
if (! $raw_output) {
|
421 |
-
$key_length = $key_length * 2;
|
422 |
-
}
|
423 |
-
return \hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);
|
424 |
-
}
|
425 |
-
|
426 |
-
$hash_length = Core::ourStrlen(\hash($algorithm, '', true));
|
427 |
-
$block_count = \ceil($key_length / $hash_length);
|
428 |
-
|
429 |
-
$output = '';
|
430 |
-
for ($i = 1; $i <= $block_count; $i++) {
|
431 |
-
// $i encoded as 4 bytes, big endian.
|
432 |
-
$last = $salt . \pack('N', $i);
|
433 |
-
// first iteration
|
434 |
-
$last = $xorsum = \hash_hmac($algorithm, $last, $password, true);
|
435 |
-
// perform the other $count - 1 iterations
|
436 |
-
for ($j = 1; $j < $count; $j++) {
|
437 |
-
$xorsum ^= ($last = \hash_hmac($algorithm, $last, $password, true));
|
438 |
-
}
|
439 |
-
$output .= $xorsum;
|
440 |
-
}
|
441 |
-
|
442 |
-
if ($raw_output) {
|
443 |
-
return (string) Core::ourSubstr($output, 0, $key_length);
|
444 |
-
} else {
|
445 |
-
return Encoding::binToHex((string) Core::ourSubstr($output, 0, $key_length));
|
446 |
-
}
|
447 |
-
}
|
448 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Crypto.php
DELETED
@@ -1,445 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
class Crypto
|
8 |
-
{
|
9 |
-
/**
|
10 |
-
* Encrypts a string with a Key.
|
11 |
-
*
|
12 |
-
* @param string $plaintext
|
13 |
-
* @param Key $key
|
14 |
-
* @param bool $raw_binary
|
15 |
-
*
|
16 |
-
* @throws Ex\EnvironmentIsBrokenException
|
17 |
-
* @throws \TypeError
|
18 |
-
*
|
19 |
-
* @return string
|
20 |
-
*/
|
21 |
-
public static function encrypt($plaintext, $key, $raw_binary = false)
|
22 |
-
{
|
23 |
-
if (!\is_string($plaintext)) {
|
24 |
-
throw new \TypeError(
|
25 |
-
'String expected for argument 1. ' . \ucfirst(\gettype($plaintext)) . ' given instead.'
|
26 |
-
);
|
27 |
-
}
|
28 |
-
if (!($key instanceof Key)) {
|
29 |
-
throw new \TypeError(
|
30 |
-
'Key expected for argument 2. ' . \ucfirst(\gettype($key)) . ' given instead.'
|
31 |
-
);
|
32 |
-
}
|
33 |
-
if (!\is_bool($raw_binary)) {
|
34 |
-
throw new \TypeError(
|
35 |
-
'Boolean expected for argument 3. ' . \ucfirst(\gettype($raw_binary)) . ' given instead.'
|
36 |
-
);
|
37 |
-
}
|
38 |
-
return self::encryptInternal(
|
39 |
-
$plaintext,
|
40 |
-
KeyOrPassword::createFromKey($key),
|
41 |
-
$raw_binary
|
42 |
-
);
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Encrypts a string with a password, using a slow key derivation function
|
47 |
-
* to make password cracking more expensive.
|
48 |
-
*
|
49 |
-
* @param string $plaintext
|
50 |
-
* @param string $password
|
51 |
-
* @param bool $raw_binary
|
52 |
-
*
|
53 |
-
* @throws Ex\EnvironmentIsBrokenException
|
54 |
-
* @throws \TypeError
|
55 |
-
*
|
56 |
-
* @return string
|
57 |
-
*/
|
58 |
-
public static function encryptWithPassword($plaintext, $password, $raw_binary = false)
|
59 |
-
{
|
60 |
-
if (!\is_string($plaintext)) {
|
61 |
-
throw new \TypeError(
|
62 |
-
'String expected for argument 1. ' . \ucfirst(\gettype($plaintext)) . ' given instead.'
|
63 |
-
);
|
64 |
-
}
|
65 |
-
if (!\is_string($password)) {
|
66 |
-
throw new \TypeError(
|
67 |
-
'String expected for argument 2. ' . \ucfirst(\gettype($password)) . ' given instead.'
|
68 |
-
);
|
69 |
-
}
|
70 |
-
if (!\is_bool($raw_binary)) {
|
71 |
-
throw new \TypeError(
|
72 |
-
'Boolean expected for argument 3. ' . \ucfirst(\gettype($raw_binary)) . ' given instead.'
|
73 |
-
);
|
74 |
-
}
|
75 |
-
return self::encryptInternal(
|
76 |
-
$plaintext,
|
77 |
-
KeyOrPassword::createFromPassword($password),
|
78 |
-
$raw_binary
|
79 |
-
);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Decrypts a ciphertext to a string with a Key.
|
84 |
-
*
|
85 |
-
* @param string $ciphertext
|
86 |
-
* @param Key $key
|
87 |
-
* @param bool $raw_binary
|
88 |
-
*
|
89 |
-
* @throws \TypeError
|
90 |
-
* @throws Ex\EnvironmentIsBrokenException
|
91 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
92 |
-
*
|
93 |
-
* @return string
|
94 |
-
*/
|
95 |
-
public static function decrypt($ciphertext, $key, $raw_binary = false)
|
96 |
-
{
|
97 |
-
if (!\is_string($ciphertext)) {
|
98 |
-
throw new \TypeError(
|
99 |
-
'String expected for argument 1. ' . \ucfirst(\gettype($ciphertext)) . ' given instead.'
|
100 |
-
);
|
101 |
-
}
|
102 |
-
if (!($key instanceof Key)) {
|
103 |
-
throw new \TypeError(
|
104 |
-
'Key expected for argument 2. ' . \ucfirst(\gettype($key)) . ' given instead.'
|
105 |
-
);
|
106 |
-
}
|
107 |
-
if (!\is_bool($raw_binary)) {
|
108 |
-
throw new \TypeError(
|
109 |
-
'Boolean expected for argument 3. ' . \ucfirst(\gettype($raw_binary)) . ' given instead.'
|
110 |
-
);
|
111 |
-
}
|
112 |
-
return self::decryptInternal(
|
113 |
-
$ciphertext,
|
114 |
-
KeyOrPassword::createFromKey($key),
|
115 |
-
$raw_binary
|
116 |
-
);
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Decrypts a ciphertext to a string with a password, using a slow key
|
121 |
-
* derivation function to make password cracking more expensive.
|
122 |
-
*
|
123 |
-
* @param string $ciphertext
|
124 |
-
* @param string $password
|
125 |
-
* @param bool $raw_binary
|
126 |
-
*
|
127 |
-
* @throws Ex\EnvironmentIsBrokenException
|
128 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
129 |
-
* @throws \TypeError
|
130 |
-
*
|
131 |
-
* @return string
|
132 |
-
*/
|
133 |
-
public static function decryptWithPassword($ciphertext, $password, $raw_binary = false)
|
134 |
-
{
|
135 |
-
if (!\is_string($ciphertext)) {
|
136 |
-
throw new \TypeError(
|
137 |
-
'String expected for argument 1. ' . \ucfirst(\gettype($ciphertext)) . ' given instead.'
|
138 |
-
);
|
139 |
-
}
|
140 |
-
if (!\is_string($password)) {
|
141 |
-
throw new \TypeError(
|
142 |
-
'String expected for argument 2. ' . \ucfirst(\gettype($password)) . ' given instead.'
|
143 |
-
);
|
144 |
-
}
|
145 |
-
if (!\is_bool($raw_binary)) {
|
146 |
-
throw new \TypeError(
|
147 |
-
'Boolean expected for argument 3. ' . \ucfirst(\gettype($raw_binary)) . ' given instead.'
|
148 |
-
);
|
149 |
-
}
|
150 |
-
return self::decryptInternal(
|
151 |
-
$ciphertext,
|
152 |
-
KeyOrPassword::createFromPassword($password),
|
153 |
-
$raw_binary
|
154 |
-
);
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Decrypts a legacy ciphertext produced by version 1 of this library.
|
159 |
-
*
|
160 |
-
* @param string $ciphertext
|
161 |
-
* @param string $key
|
162 |
-
*
|
163 |
-
* @throws Ex\EnvironmentIsBrokenException
|
164 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
165 |
-
* @throws \TypeError
|
166 |
-
*
|
167 |
-
* @return string
|
168 |
-
*/
|
169 |
-
public static function legacyDecrypt($ciphertext, $key)
|
170 |
-
{
|
171 |
-
if (!\is_string($ciphertext)) {
|
172 |
-
throw new \TypeError(
|
173 |
-
'String expected for argument 1. ' . \ucfirst(\gettype($ciphertext)) . ' given instead.'
|
174 |
-
);
|
175 |
-
}
|
176 |
-
if (!\is_string($key)) {
|
177 |
-
throw new \TypeError(
|
178 |
-
'String expected for argument 2. ' . \ucfirst(\gettype($key)) . ' given instead.'
|
179 |
-
);
|
180 |
-
}
|
181 |
-
|
182 |
-
RuntimeTests::runtimeTest();
|
183 |
-
|
184 |
-
// Extract the HMAC from the front of the ciphertext.
|
185 |
-
if (Core::ourStrlen($ciphertext) <= Core::LEGACY_MAC_BYTE_SIZE) {
|
186 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
187 |
-
'Ciphertext is too short.'
|
188 |
-
);
|
189 |
-
}
|
190 |
-
/**
|
191 |
-
* @var string
|
192 |
-
*/
|
193 |
-
$hmac = Core::ourSubstr($ciphertext, 0, Core::LEGACY_MAC_BYTE_SIZE);
|
194 |
-
Core::ensureTrue(\is_string($hmac));
|
195 |
-
/**
|
196 |
-
* @var string
|
197 |
-
*/
|
198 |
-
$messageCiphertext = Core::ourSubstr($ciphertext, Core::LEGACY_MAC_BYTE_SIZE);
|
199 |
-
Core::ensureTrue(\is_string($messageCiphertext));
|
200 |
-
|
201 |
-
// Regenerate the same authentication sub-key.
|
202 |
-
$akey = Core::HKDF(
|
203 |
-
Core::LEGACY_HASH_FUNCTION_NAME,
|
204 |
-
$key,
|
205 |
-
Core::LEGACY_KEY_BYTE_SIZE,
|
206 |
-
Core::LEGACY_AUTHENTICATION_INFO_STRING,
|
207 |
-
null
|
208 |
-
);
|
209 |
-
|
210 |
-
if (self::verifyHMAC($hmac, $messageCiphertext, $akey)) {
|
211 |
-
// Regenerate the same encryption sub-key.
|
212 |
-
$ekey = Core::HKDF(
|
213 |
-
Core::LEGACY_HASH_FUNCTION_NAME,
|
214 |
-
$key,
|
215 |
-
Core::LEGACY_KEY_BYTE_SIZE,
|
216 |
-
Core::LEGACY_ENCRYPTION_INFO_STRING,
|
217 |
-
null
|
218 |
-
);
|
219 |
-
|
220 |
-
// Extract the IV from the ciphertext.
|
221 |
-
if (Core::ourStrlen($messageCiphertext) <= Core::LEGACY_BLOCK_BYTE_SIZE) {
|
222 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
223 |
-
'Ciphertext is too short.'
|
224 |
-
);
|
225 |
-
}
|
226 |
-
/**
|
227 |
-
* @var string
|
228 |
-
*/
|
229 |
-
$iv = Core::ourSubstr($messageCiphertext, 0, Core::LEGACY_BLOCK_BYTE_SIZE);
|
230 |
-
Core::ensureTrue(\is_string($iv));
|
231 |
-
|
232 |
-
/**
|
233 |
-
* @var string
|
234 |
-
*/
|
235 |
-
$actualCiphertext = Core::ourSubstr($messageCiphertext, Core::LEGACY_BLOCK_BYTE_SIZE);
|
236 |
-
Core::ensureTrue(\is_string($actualCiphertext));
|
237 |
-
|
238 |
-
// Do the decryption.
|
239 |
-
$plaintext = self::plainDecrypt($actualCiphertext, $ekey, $iv, Core::LEGACY_CIPHER_METHOD);
|
240 |
-
return $plaintext;
|
241 |
-
} else {
|
242 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
243 |
-
'Integrity check failed.'
|
244 |
-
);
|
245 |
-
}
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Encrypts a string with either a key or a password.
|
250 |
-
*
|
251 |
-
* @param string $plaintext
|
252 |
-
* @param KeyOrPassword $secret
|
253 |
-
* @param bool $raw_binary
|
254 |
-
*
|
255 |
-
* @return string
|
256 |
-
*/
|
257 |
-
private static function encryptInternal($plaintext, KeyOrPassword $secret, $raw_binary)
|
258 |
-
{
|
259 |
-
RuntimeTests::runtimeTest();
|
260 |
-
|
261 |
-
$salt = Core::secureRandom(Core::SALT_BYTE_SIZE);
|
262 |
-
$keys = $secret->deriveKeys($salt);
|
263 |
-
$ekey = $keys->getEncryptionKey();
|
264 |
-
$akey = $keys->getAuthenticationKey();
|
265 |
-
$iv = Core::secureRandom(Core::BLOCK_BYTE_SIZE);
|
266 |
-
|
267 |
-
$ciphertext = Core::CURRENT_VERSION . $salt . $iv . self::plainEncrypt($plaintext, $ekey, $iv);
|
268 |
-
$auth = \hash_hmac(Core::HASH_FUNCTION_NAME, $ciphertext, $akey, true);
|
269 |
-
$ciphertext = $ciphertext . $auth;
|
270 |
-
|
271 |
-
if ($raw_binary) {
|
272 |
-
return $ciphertext;
|
273 |
-
}
|
274 |
-
return Encoding::binToHex($ciphertext);
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Decrypts a ciphertext to a string with either a key or a password.
|
279 |
-
*
|
280 |
-
* @param string $ciphertext
|
281 |
-
* @param KeyOrPassword $secret
|
282 |
-
* @param bool $raw_binary
|
283 |
-
*
|
284 |
-
* @throws Ex\EnvironmentIsBrokenException
|
285 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
286 |
-
*
|
287 |
-
* @return string
|
288 |
-
*/
|
289 |
-
private static function decryptInternal($ciphertext, KeyOrPassword $secret, $raw_binary)
|
290 |
-
{
|
291 |
-
RuntimeTests::runtimeTest();
|
292 |
-
|
293 |
-
if (! $raw_binary) {
|
294 |
-
try {
|
295 |
-
$ciphertext = Encoding::hexToBin($ciphertext);
|
296 |
-
} catch (Ex\BadFormatException $ex) {
|
297 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
298 |
-
'Ciphertext has invalid hex encoding.'
|
299 |
-
);
|
300 |
-
}
|
301 |
-
}
|
302 |
-
|
303 |
-
if (Core::ourStrlen($ciphertext) < Core::MINIMUM_CIPHERTEXT_SIZE) {
|
304 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
305 |
-
'Ciphertext is too short.'
|
306 |
-
);
|
307 |
-
}
|
308 |
-
|
309 |
-
// Get and check the version header.
|
310 |
-
/** @var string $header */
|
311 |
-
$header = Core::ourSubstr($ciphertext, 0, Core::HEADER_VERSION_SIZE);
|
312 |
-
if ($header !== Core::CURRENT_VERSION) {
|
313 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
314 |
-
'Bad version header.'
|
315 |
-
);
|
316 |
-
}
|
317 |
-
|
318 |
-
// Get the salt.
|
319 |
-
/** @var string $salt */
|
320 |
-
$salt = Core::ourSubstr(
|
321 |
-
$ciphertext,
|
322 |
-
Core::HEADER_VERSION_SIZE,
|
323 |
-
Core::SALT_BYTE_SIZE
|
324 |
-
);
|
325 |
-
Core::ensureTrue(\is_string($salt));
|
326 |
-
|
327 |
-
// Get the IV.
|
328 |
-
/** @var string $iv */
|
329 |
-
$iv = Core::ourSubstr(
|
330 |
-
$ciphertext,
|
331 |
-
Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE,
|
332 |
-
Core::BLOCK_BYTE_SIZE
|
333 |
-
);
|
334 |
-
Core::ensureTrue(\is_string($iv));
|
335 |
-
|
336 |
-
// Get the HMAC.
|
337 |
-
/** @var string $hmac */
|
338 |
-
$hmac = Core::ourSubstr(
|
339 |
-
$ciphertext,
|
340 |
-
Core::ourStrlen($ciphertext) - Core::MAC_BYTE_SIZE,
|
341 |
-
Core::MAC_BYTE_SIZE
|
342 |
-
);
|
343 |
-
Core::ensureTrue(\is_string($hmac));
|
344 |
-
|
345 |
-
// Get the actual encrypted ciphertext.
|
346 |
-
/** @var string $encrypted */
|
347 |
-
$encrypted = Core::ourSubstr(
|
348 |
-
$ciphertext,
|
349 |
-
Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE +
|
350 |
-
Core::BLOCK_BYTE_SIZE,
|
351 |
-
Core::ourStrlen($ciphertext) - Core::MAC_BYTE_SIZE - Core::SALT_BYTE_SIZE -
|
352 |
-
Core::BLOCK_BYTE_SIZE - Core::HEADER_VERSION_SIZE
|
353 |
-
);
|
354 |
-
Core::ensureTrue(\is_string($encrypted));
|
355 |
-
|
356 |
-
// Derive the separate encryption and authentication keys from the key
|
357 |
-
// or password, whichever it is.
|
358 |
-
$keys = $secret->deriveKeys($salt);
|
359 |
-
|
360 |
-
if (self::verifyHMAC($hmac, $header . $salt . $iv . $encrypted, $keys->getAuthenticationKey())) {
|
361 |
-
$plaintext = self::plainDecrypt($encrypted, $keys->getEncryptionKey(), $iv, Core::CIPHER_METHOD);
|
362 |
-
return $plaintext;
|
363 |
-
} else {
|
364 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
365 |
-
'Integrity check failed.'
|
366 |
-
);
|
367 |
-
}
|
368 |
-
}
|
369 |
-
|
370 |
-
/**
|
371 |
-
* Raw unauthenticated encryption (insecure on its own).
|
372 |
-
*
|
373 |
-
* @param string $plaintext
|
374 |
-
* @param string $key
|
375 |
-
* @param string $iv
|
376 |
-
*
|
377 |
-
* @throws Ex\EnvironmentIsBrokenException
|
378 |
-
*
|
379 |
-
* @return string
|
380 |
-
*/
|
381 |
-
protected static function plainEncrypt($plaintext, $key, $iv)
|
382 |
-
{
|
383 |
-
Core::ensureConstantExists('OPENSSL_RAW_DATA');
|
384 |
-
Core::ensureFunctionExists('openssl_encrypt');
|
385 |
-
/** @var string $ciphertext */
|
386 |
-
$ciphertext = \openssl_encrypt(
|
387 |
-
$plaintext,
|
388 |
-
Core::CIPHER_METHOD,
|
389 |
-
$key,
|
390 |
-
OPENSSL_RAW_DATA,
|
391 |
-
$iv
|
392 |
-
);
|
393 |
-
|
394 |
-
Core::ensureTrue(\is_string($ciphertext), 'openssl_encrypt() failed');
|
395 |
-
|
396 |
-
return $ciphertext;
|
397 |
-
}
|
398 |
-
|
399 |
-
/**
|
400 |
-
* Raw unauthenticated decryption (insecure on its own).
|
401 |
-
*
|
402 |
-
* @param string $ciphertext
|
403 |
-
* @param string $key
|
404 |
-
* @param string $iv
|
405 |
-
* @param string $cipherMethod
|
406 |
-
*
|
407 |
-
* @throws Ex\EnvironmentIsBrokenException
|
408 |
-
*
|
409 |
-
* @return string
|
410 |
-
*/
|
411 |
-
protected static function plainDecrypt($ciphertext, $key, $iv, $cipherMethod)
|
412 |
-
{
|
413 |
-
Core::ensureConstantExists('OPENSSL_RAW_DATA');
|
414 |
-
Core::ensureFunctionExists('openssl_decrypt');
|
415 |
-
|
416 |
-
/** @var string $plaintext */
|
417 |
-
$plaintext = \openssl_decrypt(
|
418 |
-
$ciphertext,
|
419 |
-
$cipherMethod,
|
420 |
-
$key,
|
421 |
-
OPENSSL_RAW_DATA,
|
422 |
-
$iv
|
423 |
-
);
|
424 |
-
Core::ensureTrue(\is_string($plaintext), 'openssl_decrypt() failed.');
|
425 |
-
|
426 |
-
return $plaintext;
|
427 |
-
}
|
428 |
-
|
429 |
-
/**
|
430 |
-
* Verifies an HMAC without leaking information through side-channels.
|
431 |
-
*
|
432 |
-
* @param string $expected_hmac
|
433 |
-
* @param string $message
|
434 |
-
* @param string $key
|
435 |
-
*
|
436 |
-
* @throws Ex\EnvironmentIsBrokenException
|
437 |
-
*
|
438 |
-
* @return bool
|
439 |
-
*/
|
440 |
-
protected static function verifyHMAC($expected_hmac, $message, $key)
|
441 |
-
{
|
442 |
-
$message_hmac = \hash_hmac(Core::HASH_FUNCTION_NAME, $message, $key, true);
|
443 |
-
return Core::hashEquals($message_hmac, $expected_hmac);
|
444 |
-
}
|
445 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/DerivedKeys.php
DELETED
@@ -1,50 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class DerivedKeys
|
7 |
-
* @package Defuse\Crypto
|
8 |
-
*/
|
9 |
-
final class DerivedKeys
|
10 |
-
{
|
11 |
-
/**
|
12 |
-
* @var string
|
13 |
-
*/
|
14 |
-
private $akey = '';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
private $ekey = '';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Returns the authentication key.
|
23 |
-
* @return string
|
24 |
-
*/
|
25 |
-
public function getAuthenticationKey()
|
26 |
-
{
|
27 |
-
return $this->akey;
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Returns the encryption key.
|
32 |
-
* @return string
|
33 |
-
*/
|
34 |
-
public function getEncryptionKey()
|
35 |
-
{
|
36 |
-
return $this->ekey;
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Constructor for DerivedKeys.
|
41 |
-
*
|
42 |
-
* @param string $akey
|
43 |
-
* @param string $ekey
|
44 |
-
*/
|
45 |
-
public function __construct($akey, $ekey)
|
46 |
-
{
|
47 |
-
$this->akey = $akey;
|
48 |
-
$this->ekey = $ekey;
|
49 |
-
}
|
50 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Encoding.php
DELETED
@@ -1,268 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class Encoding
|
8 |
-
{
|
9 |
-
const CHECKSUM_BYTE_SIZE = 32;
|
10 |
-
const CHECKSUM_HASH_ALGO = 'sha256';
|
11 |
-
const SERIALIZE_HEADER_BYTES = 4;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Converts a byte string to a hexadecimal string without leaking
|
15 |
-
* information through side channels.
|
16 |
-
*
|
17 |
-
* @param string $byte_string
|
18 |
-
*
|
19 |
-
* @throws Ex\EnvironmentIsBrokenException
|
20 |
-
*
|
21 |
-
* @return string
|
22 |
-
*/
|
23 |
-
public static function binToHex($byte_string)
|
24 |
-
{
|
25 |
-
$hex = '';
|
26 |
-
$len = Core::ourStrlen($byte_string);
|
27 |
-
for ($i = 0; $i < $len; ++$i) {
|
28 |
-
$c = \ord($byte_string[$i]) & 0xf;
|
29 |
-
$b = \ord($byte_string[$i]) >> 4;
|
30 |
-
$hex .= \pack(
|
31 |
-
'CC',
|
32 |
-
87 + $b + ((($b - 10) >> 8) & ~38),
|
33 |
-
87 + $c + ((($c - 10) >> 8) & ~38)
|
34 |
-
);
|
35 |
-
}
|
36 |
-
return $hex;
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Converts a hexadecimal string into a byte string without leaking
|
41 |
-
* information through side channels.
|
42 |
-
*
|
43 |
-
* @param string $hex_string
|
44 |
-
*
|
45 |
-
* @throws Ex\BadFormatException
|
46 |
-
* @throws Ex\EnvironmentIsBrokenException
|
47 |
-
*
|
48 |
-
* @return string
|
49 |
-
*/
|
50 |
-
public static function hexToBin($hex_string)
|
51 |
-
{
|
52 |
-
$hex_pos = 0;
|
53 |
-
$bin = '';
|
54 |
-
$hex_len = Core::ourStrlen($hex_string);
|
55 |
-
$state = 0;
|
56 |
-
$c_acc = 0;
|
57 |
-
|
58 |
-
while ($hex_pos < $hex_len) {
|
59 |
-
$c = \ord($hex_string[$hex_pos]);
|
60 |
-
$c_num = $c ^ 48;
|
61 |
-
$c_num0 = ($c_num - 10) >> 8;
|
62 |
-
$c_alpha = ($c & ~32) - 55;
|
63 |
-
$c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
|
64 |
-
if (($c_num0 | $c_alpha0) === 0) {
|
65 |
-
throw new Ex\BadFormatException(
|
66 |
-
'Encoding::hexToBin() input is not a hex string.'
|
67 |
-
);
|
68 |
-
}
|
69 |
-
$c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
|
70 |
-
if ($state === 0) {
|
71 |
-
$c_acc = $c_val * 16;
|
72 |
-
} else {
|
73 |
-
$bin .= \pack('C', $c_acc | $c_val);
|
74 |
-
}
|
75 |
-
$state ^= 1;
|
76 |
-
++$hex_pos;
|
77 |
-
}
|
78 |
-
return $bin;
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Remove trialing whitespace without table look-ups or branches.
|
83 |
-
*
|
84 |
-
* Calling this function may leak the length of the string as well as the
|
85 |
-
* number of trailing whitespace characters through side-channels.
|
86 |
-
*
|
87 |
-
* @param string $string
|
88 |
-
* @return string
|
89 |
-
*/
|
90 |
-
public static function trimTrailingWhitespace($string = '')
|
91 |
-
{
|
92 |
-
$length = Core::ourStrlen($string);
|
93 |
-
if ($length < 1) {
|
94 |
-
return '';
|
95 |
-
}
|
96 |
-
do {
|
97 |
-
$prevLength = $length;
|
98 |
-
$last = $length - 1;
|
99 |
-
$chr = \ord($string[$last]);
|
100 |
-
|
101 |
-
/* Null Byte (0x00), a.k.a. \0 */
|
102 |
-
// if ($chr === 0x00) $length -= 1;
|
103 |
-
$sub = (($chr - 1) >> 8 ) & 1;
|
104 |
-
$length -= $sub;
|
105 |
-
$last -= $sub;
|
106 |
-
|
107 |
-
/* Horizontal Tab (0x09) a.k.a. \t */
|
108 |
-
$chr = \ord($string[$last]);
|
109 |
-
// if ($chr === 0x09) $length -= 1;
|
110 |
-
$sub = (((0x08 - $chr) & ($chr - 0x0a)) >> 8) & 1;
|
111 |
-
$length -= $sub;
|
112 |
-
$last -= $sub;
|
113 |
-
|
114 |
-
/* New Line (0x0a), a.k.a. \n */
|
115 |
-
$chr = \ord($string[$last]);
|
116 |
-
// if ($chr === 0x0a) $length -= 1;
|
117 |
-
$sub = (((0x09 - $chr) & ($chr - 0x0b)) >> 8) & 1;
|
118 |
-
$length -= $sub;
|
119 |
-
$last -= $sub;
|
120 |
-
|
121 |
-
/* Carriage Return (0x0D), a.k.a. \r */
|
122 |
-
$chr = \ord($string[$last]);
|
123 |
-
// if ($chr === 0x0d) $length -= 1;
|
124 |
-
$sub = (((0x0c - $chr) & ($chr - 0x0e)) >> 8) & 1;
|
125 |
-
$length -= $sub;
|
126 |
-
$last -= $sub;
|
127 |
-
|
128 |
-
/* Space */
|
129 |
-
$chr = \ord($string[$last]);
|
130 |
-
// if ($chr === 0x20) $length -= 1;
|
131 |
-
$sub = (((0x1f - $chr) & ($chr - 0x21)) >> 8) & 1;
|
132 |
-
$length -= $sub;
|
133 |
-
} while ($prevLength !== $length && $length > 0);
|
134 |
-
return (string) Core::ourSubstr($string, 0, $length);
|
135 |
-
}
|
136 |
-
|
137 |
-
/*
|
138 |
-
* SECURITY NOTE ON APPLYING CHECKSUMS TO SECRETS:
|
139 |
-
*
|
140 |
-
* The checksum introduces a potential security weakness. For example,
|
141 |
-
* suppose we apply a checksum to a key, and that an adversary has an
|
142 |
-
* exploit against the process containing the key, such that they can
|
143 |
-
* overwrite an arbitrary byte of memory and then cause the checksum to
|
144 |
-
* be verified and learn the result.
|
145 |
-
*
|
146 |
-
* In this scenario, the adversary can extract the key one byte at
|
147 |
-
* a time by overwriting it with their guess of its value and then
|
148 |
-
* asking if the checksum matches. If it does, their guess was right.
|
149 |
-
* This kind of attack may be more easy to implement and more reliable
|
150 |
-
* than a remote code execution attack.
|
151 |
-
*
|
152 |
-
* This attack also applies to authenticated encryption as a whole, in
|
153 |
-
* the situation where the adversary can overwrite a byte of the key
|
154 |
-
* and then cause a valid ciphertext to be decrypted, and then
|
155 |
-
* determine whether the MAC check passed or failed.
|
156 |
-
*
|
157 |
-
* By using the full SHA256 hash instead of truncating it, I'm ensuring
|
158 |
-
* that both ways of going about the attack are equivalently difficult.
|
159 |
-
* A shorter checksum of say 32 bits might be more useful to the
|
160 |
-
* adversary as an oracle in case their writes are coarser grained.
|
161 |
-
*
|
162 |
-
* Because the scenario assumes a serious vulnerability, we don't try
|
163 |
-
* to prevent attacks of this style.
|
164 |
-
*/
|
165 |
-
|
166 |
-
/**
|
167 |
-
* INTERNAL USE ONLY: Applies a version header, applies a checksum, and
|
168 |
-
* then encodes a byte string into a range of printable ASCII characters.
|
169 |
-
*
|
170 |
-
* @param string $header
|
171 |
-
* @param string $bytes
|
172 |
-
*
|
173 |
-
* @throws Ex\EnvironmentIsBrokenException
|
174 |
-
*
|
175 |
-
* @return string
|
176 |
-
*/
|
177 |
-
public static function saveBytesToChecksummedAsciiSafeString($header, $bytes)
|
178 |
-
{
|
179 |
-
// Headers must be a constant length to prevent one type's header from
|
180 |
-
// being a prefix of another type's header, leading to ambiguity.
|
181 |
-
Core::ensureTrue(
|
182 |
-
Core::ourStrlen($header) === self::SERIALIZE_HEADER_BYTES,
|
183 |
-
'Header must be ' . self::SERIALIZE_HEADER_BYTES . ' bytes.'
|
184 |
-
);
|
185 |
-
|
186 |
-
return Encoding::binToHex(
|
187 |
-
$header .
|
188 |
-
$bytes .
|
189 |
-
\hash(
|
190 |
-
self::CHECKSUM_HASH_ALGO,
|
191 |
-
$header . $bytes,
|
192 |
-
true
|
193 |
-
)
|
194 |
-
);
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* INTERNAL USE ONLY: Decodes, verifies the header and checksum, and returns
|
199 |
-
* the encoded byte string.
|
200 |
-
*
|
201 |
-
* @param string $expected_header
|
202 |
-
* @param string $string
|
203 |
-
*
|
204 |
-
* @throws Ex\EnvironmentIsBrokenException
|
205 |
-
* @throws Ex\BadFormatException
|
206 |
-
*
|
207 |
-
* @return string
|
208 |
-
*/
|
209 |
-
public static function loadBytesFromChecksummedAsciiSafeString($expected_header, $string)
|
210 |
-
{
|
211 |
-
// Headers must be a constant length to prevent one type's header from
|
212 |
-
// being a prefix of another type's header, leading to ambiguity.
|
213 |
-
Core::ensureTrue(
|
214 |
-
Core::ourStrlen($expected_header) === self::SERIALIZE_HEADER_BYTES,
|
215 |
-
'Header must be 4 bytes.'
|
216 |
-
);
|
217 |
-
|
218 |
-
/* If you get an exception here when attempting to load from a file, first pass your
|
219 |
-
key to Encoding::trimTrailingWhitespace() to remove newline characters, etc. */
|
220 |
-
$bytes = Encoding::hexToBin($string);
|
221 |
-
|
222 |
-
/* Make sure we have enough bytes to get the version header and checksum. */
|
223 |
-
if (Core::ourStrlen($bytes) < self::SERIALIZE_HEADER_BYTES + self::CHECKSUM_BYTE_SIZE) {
|
224 |
-
throw new Ex\BadFormatException(
|
225 |
-
'Encoded data is shorter than expected.'
|
226 |
-
);
|
227 |
-
}
|
228 |
-
|
229 |
-
/* Grab the version header. */
|
230 |
-
$actual_header = (string) Core::ourSubstr($bytes, 0, self::SERIALIZE_HEADER_BYTES);
|
231 |
-
|
232 |
-
if ($actual_header !== $expected_header) {
|
233 |
-
throw new Ex\BadFormatException(
|
234 |
-
'Invalid header.'
|
235 |
-
);
|
236 |
-
}
|
237 |
-
|
238 |
-
/* Grab the bytes that are part of the checksum. */
|
239 |
-
$checked_bytes = (string) Core::ourSubstr(
|
240 |
-
$bytes,
|
241 |
-
0,
|
242 |
-
Core::ourStrlen($bytes) - self::CHECKSUM_BYTE_SIZE
|
243 |
-
);
|
244 |
-
|
245 |
-
/* Grab the included checksum. */
|
246 |
-
$checksum_a = (string) Core::ourSubstr(
|
247 |
-
$bytes,
|
248 |
-
Core::ourStrlen($bytes) - self::CHECKSUM_BYTE_SIZE,
|
249 |
-
self::CHECKSUM_BYTE_SIZE
|
250 |
-
);
|
251 |
-
|
252 |
-
/* Re-compute the checksum. */
|
253 |
-
$checksum_b = \hash(self::CHECKSUM_HASH_ALGO, $checked_bytes, true);
|
254 |
-
|
255 |
-
/* Check if the checksum matches. */
|
256 |
-
if (! Core::hashEquals($checksum_a, $checksum_b)) {
|
257 |
-
throw new Ex\BadFormatException(
|
258 |
-
"Data is corrupted, the checksum doesn't match"
|
259 |
-
);
|
260 |
-
}
|
261 |
-
|
262 |
-
return (string) Core::ourSubstr(
|
263 |
-
$bytes,
|
264 |
-
self::SERIALIZE_HEADER_BYTES,
|
265 |
-
Core::ourStrlen($bytes) - self::SERIALIZE_HEADER_BYTES - self::CHECKSUM_BYTE_SIZE
|
266 |
-
);
|
267 |
-
}
|
268 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Exception/BadFormatException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto\Exception;
|
4 |
-
|
5 |
-
class BadFormatException extends \Defuse\Crypto\Exception\CryptoException
|
6 |
-
{
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Exception/CryptoException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto\Exception;
|
4 |
-
|
5 |
-
class CryptoException extends \Exception
|
6 |
-
{
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Exception/EnvironmentIsBrokenException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto\Exception;
|
4 |
-
|
5 |
-
class EnvironmentIsBrokenException extends \Defuse\Crypto\Exception\CryptoException
|
6 |
-
{
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Exception/IOException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto\Exception;
|
4 |
-
|
5 |
-
class IOException extends \Defuse\Crypto\Exception\CryptoException
|
6 |
-
{
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Exception/WrongKeyOrModifiedCiphertextException.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto\Exception;
|
4 |
-
|
5 |
-
class WrongKeyOrModifiedCiphertextException extends \Defuse\Crypto\Exception\CryptoException
|
6 |
-
{
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/File.php
DELETED
@@ -1,762 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class File
|
8 |
-
{
|
9 |
-
/**
|
10 |
-
* Encrypts the input file, saving the ciphertext to the output file.
|
11 |
-
*
|
12 |
-
* @param string $inputFilename
|
13 |
-
* @param string $outputFilename
|
14 |
-
* @param Key $key
|
15 |
-
* @return void
|
16 |
-
*
|
17 |
-
* @throws Ex\EnvironmentIsBrokenException
|
18 |
-
* @throws Ex\IOException
|
19 |
-
*/
|
20 |
-
public static function encryptFile($inputFilename, $outputFilename, Key $key)
|
21 |
-
{
|
22 |
-
self::encryptFileInternal(
|
23 |
-
$inputFilename,
|
24 |
-
$outputFilename,
|
25 |
-
KeyOrPassword::createFromKey($key)
|
26 |
-
);
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Encrypts a file with a password, using a slow key derivation function to
|
31 |
-
* make password cracking more expensive.
|
32 |
-
*
|
33 |
-
* @param string $inputFilename
|
34 |
-
* @param string $outputFilename
|
35 |
-
* @param string $password
|
36 |
-
* @return void
|
37 |
-
*
|
38 |
-
* @throws Ex\EnvironmentIsBrokenException
|
39 |
-
* @throws Ex\IOException
|
40 |
-
*/
|
41 |
-
public static function encryptFileWithPassword($inputFilename, $outputFilename, $password)
|
42 |
-
{
|
43 |
-
self::encryptFileInternal(
|
44 |
-
$inputFilename,
|
45 |
-
$outputFilename,
|
46 |
-
KeyOrPassword::createFromPassword($password)
|
47 |
-
);
|
48 |
-
}
|
49 |
-
|
50 |
-
/**
|
51 |
-
* Decrypts the input file, saving the plaintext to the output file.
|
52 |
-
*
|
53 |
-
* @param string $inputFilename
|
54 |
-
* @param string $outputFilename
|
55 |
-
* @param Key $key
|
56 |
-
* @return void
|
57 |
-
*
|
58 |
-
* @throws Ex\EnvironmentIsBrokenException
|
59 |
-
* @throws Ex\IOException
|
60 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
61 |
-
*/
|
62 |
-
public static function decryptFile($inputFilename, $outputFilename, Key $key)
|
63 |
-
{
|
64 |
-
self::decryptFileInternal(
|
65 |
-
$inputFilename,
|
66 |
-
$outputFilename,
|
67 |
-
KeyOrPassword::createFromKey($key)
|
68 |
-
);
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Decrypts a file with a password, using a slow key derivation function to
|
73 |
-
* make password cracking more expensive.
|
74 |
-
*
|
75 |
-
* @param string $inputFilename
|
76 |
-
* @param string $outputFilename
|
77 |
-
* @param string $password
|
78 |
-
* @return void
|
79 |
-
*
|
80 |
-
* @throws Ex\EnvironmentIsBrokenException
|
81 |
-
* @throws Ex\IOException
|
82 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
83 |
-
*/
|
84 |
-
public static function decryptFileWithPassword($inputFilename, $outputFilename, $password)
|
85 |
-
{
|
86 |
-
self::decryptFileInternal(
|
87 |
-
$inputFilename,
|
88 |
-
$outputFilename,
|
89 |
-
KeyOrPassword::createFromPassword($password)
|
90 |
-
);
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Takes two resource handles and encrypts the contents of the first,
|
95 |
-
* writing the ciphertext into the second.
|
96 |
-
*
|
97 |
-
* @param resource $inputHandle
|
98 |
-
* @param resource $outputHandle
|
99 |
-
* @param Key $key
|
100 |
-
* @return void
|
101 |
-
*
|
102 |
-
* @throws Ex\EnvironmentIsBrokenException
|
103 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
104 |
-
*/
|
105 |
-
public static function encryptResource($inputHandle, $outputHandle, Key $key)
|
106 |
-
{
|
107 |
-
self::encryptResourceInternal(
|
108 |
-
$inputHandle,
|
109 |
-
$outputHandle,
|
110 |
-
KeyOrPassword::createFromKey($key)
|
111 |
-
);
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Encrypts the contents of one resource handle into another with a
|
116 |
-
* password, using a slow key derivation function to make password cracking
|
117 |
-
* more expensive.
|
118 |
-
*
|
119 |
-
* @param resource $inputHandle
|
120 |
-
* @param resource $outputHandle
|
121 |
-
* @param string $password
|
122 |
-
* @return void
|
123 |
-
*
|
124 |
-
* @throws Ex\EnvironmentIsBrokenException
|
125 |
-
* @throws Ex\IOException
|
126 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
127 |
-
*/
|
128 |
-
public static function encryptResourceWithPassword($inputHandle, $outputHandle, $password)
|
129 |
-
{
|
130 |
-
self::encryptResourceInternal(
|
131 |
-
$inputHandle,
|
132 |
-
$outputHandle,
|
133 |
-
KeyOrPassword::createFromPassword($password)
|
134 |
-
);
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Takes two resource handles and decrypts the contents of the first,
|
139 |
-
* writing the plaintext into the second.
|
140 |
-
*
|
141 |
-
* @param resource $inputHandle
|
142 |
-
* @param resource $outputHandle
|
143 |
-
* @param Key $key
|
144 |
-
* @return void
|
145 |
-
*
|
146 |
-
* @throws Ex\EnvironmentIsBrokenException
|
147 |
-
* @throws Ex\IOException
|
148 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
149 |
-
*/
|
150 |
-
public static function decryptResource($inputHandle, $outputHandle, Key $key)
|
151 |
-
{
|
152 |
-
self::decryptResourceInternal(
|
153 |
-
$inputHandle,
|
154 |
-
$outputHandle,
|
155 |
-
KeyOrPassword::createFromKey($key)
|
156 |
-
);
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Decrypts the contents of one resource into another with a password, using
|
161 |
-
* a slow key derivation function to make password cracking more expensive.
|
162 |
-
*
|
163 |
-
* @param resource $inputHandle
|
164 |
-
* @param resource $outputHandle
|
165 |
-
* @param string $password
|
166 |
-
* @return void
|
167 |
-
*
|
168 |
-
* @throws Ex\EnvironmentIsBrokenException
|
169 |
-
* @throws Ex\IOException
|
170 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
171 |
-
*/
|
172 |
-
public static function decryptResourceWithPassword($inputHandle, $outputHandle, $password)
|
173 |
-
{
|
174 |
-
self::decryptResourceInternal(
|
175 |
-
$inputHandle,
|
176 |
-
$outputHandle,
|
177 |
-
KeyOrPassword::createFromPassword($password)
|
178 |
-
);
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Encrypts a file with either a key or a password.
|
183 |
-
*
|
184 |
-
* @param string $inputFilename
|
185 |
-
* @param string $outputFilename
|
186 |
-
* @param KeyOrPassword $secret
|
187 |
-
* @return void
|
188 |
-
*
|
189 |
-
* @throws Ex\CryptoException
|
190 |
-
* @throws Ex\IOException
|
191 |
-
*/
|
192 |
-
private static function encryptFileInternal($inputFilename, $outputFilename, KeyOrPassword $secret)
|
193 |
-
{
|
194 |
-
/* Open the input file. */
|
195 |
-
$if = @\fopen($inputFilename, 'rb');
|
196 |
-
if ($if === false) {
|
197 |
-
throw new Ex\IOException(
|
198 |
-
'Cannot open input file for encrypting: ' .
|
199 |
-
self::getLastErrorMessage()
|
200 |
-
);
|
201 |
-
}
|
202 |
-
if (\is_callable('\\stream_set_read_buffer')) {
|
203 |
-
/* This call can fail, but the only consequence is performance. */
|
204 |
-
\stream_set_read_buffer($if, 0);
|
205 |
-
}
|
206 |
-
|
207 |
-
/* Open the output file. */
|
208 |
-
$of = @\fopen($outputFilename, 'wb');
|
209 |
-
if ($of === false) {
|
210 |
-
\fclose($if);
|
211 |
-
throw new Ex\IOException(
|
212 |
-
'Cannot open output file for encrypting: ' .
|
213 |
-
self::getLastErrorMessage()
|
214 |
-
);
|
215 |
-
}
|
216 |
-
if (\is_callable('\\stream_set_write_buffer')) {
|
217 |
-
/* This call can fail, but the only consequence is performance. */
|
218 |
-
\stream_set_write_buffer($of, 0);
|
219 |
-
}
|
220 |
-
|
221 |
-
/* Perform the encryption. */
|
222 |
-
try {
|
223 |
-
self::encryptResourceInternal($if, $of, $secret);
|
224 |
-
} catch (Ex\CryptoException $ex) {
|
225 |
-
\fclose($if);
|
226 |
-
\fclose($of);
|
227 |
-
throw $ex;
|
228 |
-
}
|
229 |
-
|
230 |
-
/* Close the input file. */
|
231 |
-
if (\fclose($if) === false) {
|
232 |
-
\fclose($of);
|
233 |
-
throw new Ex\IOException(
|
234 |
-
'Cannot close input file after encrypting'
|
235 |
-
);
|
236 |
-
}
|
237 |
-
|
238 |
-
/* Close the output file. */
|
239 |
-
if (\fclose($of) === false) {
|
240 |
-
throw new Ex\IOException(
|
241 |
-
'Cannot close output file after encrypting'
|
242 |
-
);
|
243 |
-
}
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* Decrypts a file with either a key or a password.
|
248 |
-
*
|
249 |
-
* @param string $inputFilename
|
250 |
-
* @param string $outputFilename
|
251 |
-
* @param KeyOrPassword $secret
|
252 |
-
* @return void
|
253 |
-
*
|
254 |
-
* @throws Ex\CryptoException
|
255 |
-
* @throws Ex\IOException
|
256 |
-
*/
|
257 |
-
private static function decryptFileInternal($inputFilename, $outputFilename, KeyOrPassword $secret)
|
258 |
-
{
|
259 |
-
/* Open the input file. */
|
260 |
-
$if = @\fopen($inputFilename, 'rb');
|
261 |
-
if ($if === false) {
|
262 |
-
throw new Ex\IOException(
|
263 |
-
'Cannot open input file for decrypting: ' .
|
264 |
-
self::getLastErrorMessage()
|
265 |
-
);
|
266 |
-
}
|
267 |
-
|
268 |
-
if (\is_callable('\\stream_set_read_buffer')) {
|
269 |
-
/* This call can fail, but the only consequence is performance. */
|
270 |
-
\stream_set_read_buffer($if, 0);
|
271 |
-
}
|
272 |
-
|
273 |
-
/* Open the output file. */
|
274 |
-
$of = @\fopen($outputFilename, 'wb');
|
275 |
-
if ($of === false) {
|
276 |
-
\fclose($if);
|
277 |
-
throw new Ex\IOException(
|
278 |
-
'Cannot open output file for decrypting: ' .
|
279 |
-
self::getLastErrorMessage()
|
280 |
-
);
|
281 |
-
}
|
282 |
-
|
283 |
-
if (\is_callable('\\stream_set_write_buffer')) {
|
284 |
-
/* This call can fail, but the only consequence is performance. */
|
285 |
-
\stream_set_write_buffer($of, 0);
|
286 |
-
}
|
287 |
-
|
288 |
-
/* Perform the decryption. */
|
289 |
-
try {
|
290 |
-
self::decryptResourceInternal($if, $of, $secret);
|
291 |
-
} catch (Ex\CryptoException $ex) {
|
292 |
-
\fclose($if);
|
293 |
-
\fclose($of);
|
294 |
-
throw $ex;
|
295 |
-
}
|
296 |
-
|
297 |
-
/* Close the input file. */
|
298 |
-
if (\fclose($if) === false) {
|
299 |
-
\fclose($of);
|
300 |
-
throw new Ex\IOException(
|
301 |
-
'Cannot close input file after decrypting'
|
302 |
-
);
|
303 |
-
}
|
304 |
-
|
305 |
-
/* Close the output file. */
|
306 |
-
if (\fclose($of) === false) {
|
307 |
-
throw new Ex\IOException(
|
308 |
-
'Cannot close output file after decrypting'
|
309 |
-
);
|
310 |
-
}
|
311 |
-
}
|
312 |
-
|
313 |
-
/**
|
314 |
-
* Encrypts a resource with either a key or a password.
|
315 |
-
*
|
316 |
-
* @param resource $inputHandle
|
317 |
-
* @param resource $outputHandle
|
318 |
-
* @param KeyOrPassword $secret
|
319 |
-
* @return void
|
320 |
-
*
|
321 |
-
* @throws Ex\EnvironmentIsBrokenException
|
322 |
-
* @throws Ex\IOException
|
323 |
-
*/
|
324 |
-
private static function encryptResourceInternal($inputHandle, $outputHandle, KeyOrPassword $secret)
|
325 |
-
{
|
326 |
-
if (! \is_resource($inputHandle)) {
|
327 |
-
throw new Ex\IOException(
|
328 |
-
'Input handle must be a resource!'
|
329 |
-
);
|
330 |
-
}
|
331 |
-
if (! \is_resource($outputHandle)) {
|
332 |
-
throw new Ex\IOException(
|
333 |
-
'Output handle must be a resource!'
|
334 |
-
);
|
335 |
-
}
|
336 |
-
|
337 |
-
$inputStat = \fstat($inputHandle);
|
338 |
-
$inputSize = $inputStat['size'];
|
339 |
-
|
340 |
-
$file_salt = Core::secureRandom(Core::SALT_BYTE_SIZE);
|
341 |
-
$keys = $secret->deriveKeys($file_salt);
|
342 |
-
$ekey = $keys->getEncryptionKey();
|
343 |
-
$akey = $keys->getAuthenticationKey();
|
344 |
-
|
345 |
-
$ivsize = Core::BLOCK_BYTE_SIZE;
|
346 |
-
$iv = Core::secureRandom($ivsize);
|
347 |
-
|
348 |
-
/* Initialize a streaming HMAC state. */
|
349 |
-
/** @var resource $hmac */
|
350 |
-
$hmac = \hash_init(Core::HASH_FUNCTION_NAME, HASH_HMAC, $akey);
|
351 |
-
Core::ensureTrue(
|
352 |
-
\is_resource($hmac) || \is_object($hmac),
|
353 |
-
'Cannot initialize a hash context'
|
354 |
-
);
|
355 |
-
|
356 |
-
/* Write the header, salt, and IV. */
|
357 |
-
self::writeBytes(
|
358 |
-
$outputHandle,
|
359 |
-
Core::CURRENT_VERSION . $file_salt . $iv,
|
360 |
-
Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + $ivsize
|
361 |
-
);
|
362 |
-
|
363 |
-
/* Add the header, salt, and IV to the HMAC. */
|
364 |
-
\hash_update($hmac, Core::CURRENT_VERSION);
|
365 |
-
\hash_update($hmac, $file_salt);
|
366 |
-
\hash_update($hmac, $iv);
|
367 |
-
|
368 |
-
/* $thisIv will be incremented after each call to the encryption. */
|
369 |
-
$thisIv = $iv;
|
370 |
-
|
371 |
-
/* How many blocks do we encrypt at a time? We increment by this value. */
|
372 |
-
$inc = (int) (Core::BUFFER_BYTE_SIZE / Core::BLOCK_BYTE_SIZE);
|
373 |
-
|
374 |
-
/* Loop until we reach the end of the input file. */
|
375 |
-
$at_file_end = false;
|
376 |
-
while (! (\feof($inputHandle) || $at_file_end)) {
|
377 |
-
/* Find out if we can read a full buffer, or only a partial one. */
|
378 |
-
/** @var int */
|
379 |
-
$pos = \ftell($inputHandle);
|
380 |
-
if (!\is_int($pos)) {
|
381 |
-
throw new Ex\IOException(
|
382 |
-
'Could not get current position in input file during encryption'
|
383 |
-
);
|
384 |
-
}
|
385 |
-
if ($pos + Core::BUFFER_BYTE_SIZE >= $inputSize) {
|
386 |
-
/* We're at the end of the file, so we need to break out of the loop. */
|
387 |
-
$at_file_end = true;
|
388 |
-
$read = self::readBytes(
|
389 |
-
$inputHandle,
|
390 |
-
$inputSize - $pos
|
391 |
-
);
|
392 |
-
} else {
|
393 |
-
$read = self::readBytes(
|
394 |
-
$inputHandle,
|
395 |
-
Core::BUFFER_BYTE_SIZE
|
396 |
-
);
|
397 |
-
}
|
398 |
-
|
399 |
-
/* Encrypt this buffer. */
|
400 |
-
/** @var string */
|
401 |
-
$encrypted = \openssl_encrypt(
|
402 |
-
$read,
|
403 |
-
Core::CIPHER_METHOD,
|
404 |
-
$ekey,
|
405 |
-
OPENSSL_RAW_DATA,
|
406 |
-
$thisIv
|
407 |
-
);
|
408 |
-
|
409 |
-
Core::ensureTrue(\is_string($encrypted), 'OpenSSL encryption error');
|
410 |
-
|
411 |
-
/* Write this buffer's ciphertext. */
|
412 |
-
self::writeBytes($outputHandle, $encrypted, Core::ourStrlen($encrypted));
|
413 |
-
/* Add this buffer's ciphertext to the HMAC. */
|
414 |
-
\hash_update($hmac, $encrypted);
|
415 |
-
|
416 |
-
/* Increment the counter by the number of blocks in a buffer. */
|
417 |
-
$thisIv = Core::incrementCounter($thisIv, $inc);
|
418 |
-
/* WARNING: Usually, unless the file is a multiple of the buffer
|
419 |
-
* size, $thisIv will contain an incorrect value here on the last
|
420 |
-
* iteration of this loop. */
|
421 |
-
}
|
422 |
-
|
423 |
-
/* Get the HMAC and append it to the ciphertext. */
|
424 |
-
$final_mac = \hash_final($hmac, true);
|
425 |
-
self::writeBytes($outputHandle, $final_mac, Core::MAC_BYTE_SIZE);
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Decrypts a file-backed resource with either a key or a password.
|
430 |
-
*
|
431 |
-
* @param resource $inputHandle
|
432 |
-
* @param resource $outputHandle
|
433 |
-
* @param KeyOrPassword $secret
|
434 |
-
* @return void
|
435 |
-
*
|
436 |
-
* @throws Ex\EnvironmentIsBrokenException
|
437 |
-
* @throws Ex\IOException
|
438 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
439 |
-
*/
|
440 |
-
public static function decryptResourceInternal($inputHandle, $outputHandle, KeyOrPassword $secret)
|
441 |
-
{
|
442 |
-
if (! \is_resource($inputHandle)) {
|
443 |
-
throw new Ex\IOException(
|
444 |
-
'Input handle must be a resource!'
|
445 |
-
);
|
446 |
-
}
|
447 |
-
if (! \is_resource($outputHandle)) {
|
448 |
-
throw new Ex\IOException(
|
449 |
-
'Output handle must be a resource!'
|
450 |
-
);
|
451 |
-
}
|
452 |
-
|
453 |
-
/* Make sure the file is big enough for all the reads we need to do. */
|
454 |
-
$stat = \fstat($inputHandle);
|
455 |
-
if ($stat['size'] < Core::MINIMUM_CIPHERTEXT_SIZE) {
|
456 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
457 |
-
'Input file is too small to have been created by this library.'
|
458 |
-
);
|
459 |
-
}
|
460 |
-
|
461 |
-
/* Check the version header. */
|
462 |
-
$header = self::readBytes($inputHandle, Core::HEADER_VERSION_SIZE);
|
463 |
-
if ($header !== Core::CURRENT_VERSION) {
|
464 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
465 |
-
'Bad version header.'
|
466 |
-
);
|
467 |
-
}
|
468 |
-
|
469 |
-
/* Get the salt. */
|
470 |
-
$file_salt = self::readBytes($inputHandle, Core::SALT_BYTE_SIZE);
|
471 |
-
|
472 |
-
/* Get the IV. */
|
473 |
-
$ivsize = Core::BLOCK_BYTE_SIZE;
|
474 |
-
$iv = self::readBytes($inputHandle, $ivsize);
|
475 |
-
|
476 |
-
/* Derive the authentication and encryption keys. */
|
477 |
-
$keys = $secret->deriveKeys($file_salt);
|
478 |
-
$ekey = $keys->getEncryptionKey();
|
479 |
-
$akey = $keys->getAuthenticationKey();
|
480 |
-
|
481 |
-
/* We'll store the MAC of each buffer-sized chunk as we verify the
|
482 |
-
* actual MAC, so that we can check them again when decrypting. */
|
483 |
-
$macs = [];
|
484 |
-
|
485 |
-
/* $thisIv will be incremented after each call to the decryption. */
|
486 |
-
$thisIv = $iv;
|
487 |
-
|
488 |
-
/* How many blocks do we encrypt at a time? We increment by this value. */
|
489 |
-
$inc = (int) (Core::BUFFER_BYTE_SIZE / Core::BLOCK_BYTE_SIZE);
|
490 |
-
|
491 |
-
/* Get the HMAC. */
|
492 |
-
if (\fseek($inputHandle, (-1 * Core::MAC_BYTE_SIZE), SEEK_END) === false) {
|
493 |
-
throw new Ex\IOException(
|
494 |
-
'Cannot seek to beginning of MAC within input file'
|
495 |
-
);
|
496 |
-
}
|
497 |
-
|
498 |
-
/* Get the position of the last byte in the actual ciphertext. */
|
499 |
-
/** @var int $cipher_end */
|
500 |
-
$cipher_end = \ftell($inputHandle);
|
501 |
-
if (!\is_int($cipher_end)) {
|
502 |
-
throw new Ex\IOException(
|
503 |
-
'Cannot read input file'
|
504 |
-
);
|
505 |
-
}
|
506 |
-
/* We have the position of the first byte of the HMAC. Go back by one. */
|
507 |
-
--$cipher_end;
|
508 |
-
|
509 |
-
/* Read the HMAC. */
|
510 |
-
/** @var string $stored_mac */
|
511 |
-
$stored_mac = self::readBytes($inputHandle, Core::MAC_BYTE_SIZE);
|
512 |
-
|
513 |
-
/* Initialize a streaming HMAC state. */
|
514 |
-
/** @var resource $hmac */
|
515 |
-
$hmac = \hash_init(Core::HASH_FUNCTION_NAME, HASH_HMAC, $akey);
|
516 |
-
Core::ensureTrue(\is_resource($hmac) || \is_object($hmac), 'Cannot initialize a hash context');
|
517 |
-
|
518 |
-
/* Reset file pointer to the beginning of the file after the header */
|
519 |
-
if (\fseek($inputHandle, Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
|
520 |
-
throw new Ex\IOException(
|
521 |
-
'Cannot read seek within input file'
|
522 |
-
);
|
523 |
-
}
|
524 |
-
|
525 |
-
/* Seek to the start of the actual ciphertext. */
|
526 |
-
if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize, SEEK_CUR) === false) {
|
527 |
-
throw new Ex\IOException(
|
528 |
-
'Cannot seek input file to beginning of ciphertext'
|
529 |
-
);
|
530 |
-
}
|
531 |
-
|
532 |
-
/* PASS #1: Calculating the HMAC. */
|
533 |
-
|
534 |
-
\hash_update($hmac, $header);
|
535 |
-
\hash_update($hmac, $file_salt);
|
536 |
-
\hash_update($hmac, $iv);
|
537 |
-
/** @var resource $hmac2 */
|
538 |
-
$hmac2 = \hash_copy($hmac);
|
539 |
-
|
540 |
-
$break = false;
|
541 |
-
while (! $break) {
|
542 |
-
/** @var int $pos */
|
543 |
-
$pos = \ftell($inputHandle);
|
544 |
-
if (!\is_int($pos)) {
|
545 |
-
throw new Ex\IOException(
|
546 |
-
'Could not get current position in input file during decryption'
|
547 |
-
);
|
548 |
-
}
|
549 |
-
|
550 |
-
/* Read the next buffer-sized chunk (or less). */
|
551 |
-
if ($pos + Core::BUFFER_BYTE_SIZE >= $cipher_end) {
|
552 |
-
$break = true;
|
553 |
-
$read = self::readBytes(
|
554 |
-
$inputHandle,
|
555 |
-
$cipher_end - $pos + 1
|
556 |
-
);
|
557 |
-
} else {
|
558 |
-
$read = self::readBytes(
|
559 |
-
$inputHandle,
|
560 |
-
Core::BUFFER_BYTE_SIZE
|
561 |
-
);
|
562 |
-
}
|
563 |
-
|
564 |
-
/* Update the HMAC. */
|
565 |
-
\hash_update($hmac, $read);
|
566 |
-
|
567 |
-
/* Remember this buffer-sized chunk's HMAC. */
|
568 |
-
/** @var resource $chunk_mac */
|
569 |
-
$chunk_mac = \hash_copy($hmac);
|
570 |
-
Core::ensureTrue(\is_resource($chunk_mac) || \is_object($chunk_mac), 'Cannot duplicate a hash context');
|
571 |
-
$macs []= \hash_final($chunk_mac);
|
572 |
-
}
|
573 |
-
|
574 |
-
/* Get the final HMAC, which should match the stored one. */
|
575 |
-
/** @var string $final_mac */
|
576 |
-
$final_mac = \hash_final($hmac, true);
|
577 |
-
|
578 |
-
/* Verify the HMAC. */
|
579 |
-
if (! Core::hashEquals($final_mac, $stored_mac)) {
|
580 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
581 |
-
'Integrity check failed.'
|
582 |
-
);
|
583 |
-
}
|
584 |
-
|
585 |
-
/* PASS #2: Decrypt and write output. */
|
586 |
-
|
587 |
-
/* Rewind to the start of the actual ciphertext. */
|
588 |
-
if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize + Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
|
589 |
-
throw new Ex\IOException(
|
590 |
-
'Could not move the input file pointer during decryption'
|
591 |
-
);
|
592 |
-
}
|
593 |
-
|
594 |
-
$at_file_end = false;
|
595 |
-
while (! $at_file_end) {
|
596 |
-
/** @var int $pos */
|
597 |
-
$pos = \ftell($inputHandle);
|
598 |
-
if (!\is_int($pos)) {
|
599 |
-
throw new Ex\IOException(
|
600 |
-
'Could not get current position in input file during decryption'
|
601 |
-
);
|
602 |
-
}
|
603 |
-
|
604 |
-
/* Read the next buffer-sized chunk (or less). */
|
605 |
-
if ($pos + Core::BUFFER_BYTE_SIZE >= $cipher_end) {
|
606 |
-
$at_file_end = true;
|
607 |
-
$read = self::readBytes(
|
608 |
-
$inputHandle,
|
609 |
-
$cipher_end - $pos + 1
|
610 |
-
);
|
611 |
-
} else {
|
612 |
-
$read = self::readBytes(
|
613 |
-
$inputHandle,
|
614 |
-
Core::BUFFER_BYTE_SIZE
|
615 |
-
);
|
616 |
-
}
|
617 |
-
|
618 |
-
/* Recalculate the MAC (so far) and compare it with the one we
|
619 |
-
* remembered from pass #1 to ensure attackers didn't change the
|
620 |
-
* ciphertext after MAC verification. */
|
621 |
-
\hash_update($hmac2, $read);
|
622 |
-
/** @var resource $calc_mac */
|
623 |
-
$calc_mac = \hash_copy($hmac2);
|
624 |
-
Core::ensureTrue(\is_resource($calc_mac) || \is_object($calc_mac), 'Cannot duplicate a hash context');
|
625 |
-
$calc = \hash_final($calc_mac);
|
626 |
-
|
627 |
-
if (empty($macs)) {
|
628 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
629 |
-
'File was modified after MAC verification'
|
630 |
-
);
|
631 |
-
} elseif (! Core::hashEquals(\array_shift($macs), $calc)) {
|
632 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
633 |
-
'File was modified after MAC verification'
|
634 |
-
);
|
635 |
-
}
|
636 |
-
|
637 |
-
/* Decrypt this buffer-sized chunk. */
|
638 |
-
/** @var string $decrypted */
|
639 |
-
$decrypted = \openssl_decrypt(
|
640 |
-
$read,
|
641 |
-
Core::CIPHER_METHOD,
|
642 |
-
$ekey,
|
643 |
-
OPENSSL_RAW_DATA,
|
644 |
-
$thisIv
|
645 |
-
);
|
646 |
-
Core::ensureTrue(\is_string($decrypted), 'OpenSSL decryption error');
|
647 |
-
|
648 |
-
/* Write the plaintext to the output file. */
|
649 |
-
self::writeBytes(
|
650 |
-
$outputHandle,
|
651 |
-
$decrypted,
|
652 |
-
Core::ourStrlen($decrypted)
|
653 |
-
);
|
654 |
-
|
655 |
-
/* Increment the IV by the amount of blocks in a buffer. */
|
656 |
-
/** @var string $thisIv */
|
657 |
-
$thisIv = Core::incrementCounter($thisIv, $inc);
|
658 |
-
/* WARNING: Usually, unless the file is a multiple of the buffer
|
659 |
-
* size, $thisIv will contain an incorrect value here on the last
|
660 |
-
* iteration of this loop. */
|
661 |
-
}
|
662 |
-
}
|
663 |
-
|
664 |
-
/**
|
665 |
-
* Read from a stream; prevent partial reads.
|
666 |
-
*
|
667 |
-
* @param resource $stream
|
668 |
-
* @param int $num_bytes
|
669 |
-
* @return string
|
670 |
-
*
|
671 |
-
* @throws Ex\IOException
|
672 |
-
* @throws Ex\EnvironmentIsBrokenException
|
673 |
-
*
|
674 |
-
* @return string
|
675 |
-
*/
|
676 |
-
public static function readBytes($stream, $num_bytes)
|
677 |
-
{
|
678 |
-
Core::ensureTrue($num_bytes >= 0, 'Tried to read less than 0 bytes');
|
679 |
-
|
680 |
-
if ($num_bytes === 0) {
|
681 |
-
return '';
|
682 |
-
}
|
683 |
-
|
684 |
-
$buf = '';
|
685 |
-
$remaining = $num_bytes;
|
686 |
-
while ($remaining > 0 && ! \feof($stream)) {
|
687 |
-
/** @var string $read */
|
688 |
-
$read = \fread($stream, $remaining);
|
689 |
-
if (!\is_string($read)) {
|
690 |
-
throw new Ex\IOException(
|
691 |
-
'Could not read from the file'
|
692 |
-
);
|
693 |
-
}
|
694 |
-
$buf .= $read;
|
695 |
-
$remaining -= Core::ourStrlen($read);
|
696 |
-
}
|
697 |
-
if (Core::ourStrlen($buf) !== $num_bytes) {
|
698 |
-
throw new Ex\IOException(
|
699 |
-
'Tried to read past the end of the file'
|
700 |
-
);
|
701 |
-
}
|
702 |
-
return $buf;
|
703 |
-
}
|
704 |
-
|
705 |
-
/**
|
706 |
-
* Write to a stream; prevents partial writes.
|
707 |
-
*
|
708 |
-
* @param resource $stream
|
709 |
-
* @param string $buf
|
710 |
-
* @param int $num_bytes
|
711 |
-
* @return int
|
712 |
-
*
|
713 |
-
* @throws Ex\IOException
|
714 |
-
*
|
715 |
-
* @return string
|
716 |
-
*/
|
717 |
-
public static function writeBytes($stream, $buf, $num_bytes = null)
|
718 |
-
{
|
719 |
-
$bufSize = Core::ourStrlen($buf);
|
720 |
-
if ($num_bytes === null) {
|
721 |
-
$num_bytes = $bufSize;
|
722 |
-
}
|
723 |
-
if ($num_bytes > $bufSize) {
|
724 |
-
throw new Ex\IOException(
|
725 |
-
'Trying to write more bytes than the buffer contains.'
|
726 |
-
);
|
727 |
-
}
|
728 |
-
if ($num_bytes < 0) {
|
729 |
-
throw new Ex\IOException(
|
730 |
-
'Tried to write less than 0 bytes'
|
731 |
-
);
|
732 |
-
}
|
733 |
-
$remaining = $num_bytes;
|
734 |
-
while ($remaining > 0) {
|
735 |
-
/** @var int $written */
|
736 |
-
$written = \fwrite($stream, $buf, $remaining);
|
737 |
-
if (!\is_int($written)) {
|
738 |
-
throw new Ex\IOException(
|
739 |
-
'Could not write to the file'
|
740 |
-
);
|
741 |
-
}
|
742 |
-
$buf = (string) Core::ourSubstr($buf, $written, null);
|
743 |
-
$remaining -= $written;
|
744 |
-
}
|
745 |
-
return $num_bytes;
|
746 |
-
}
|
747 |
-
|
748 |
-
/**
|
749 |
-
* Returns the last PHP error's or warning's message string.
|
750 |
-
*
|
751 |
-
* @return string
|
752 |
-
*/
|
753 |
-
private static function getLastErrorMessage()
|
754 |
-
{
|
755 |
-
$error = error_get_last();
|
756 |
-
if ($error === null) {
|
757 |
-
return '[no PHP error]';
|
758 |
-
} else {
|
759 |
-
return $error['message'];
|
760 |
-
}
|
761 |
-
}
|
762 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/Key.php
DELETED
@@ -1,94 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class Key
|
8 |
-
{
|
9 |
-
const KEY_CURRENT_VERSION = "\xDE\xF0\x00\x00";
|
10 |
-
const KEY_BYTE_SIZE = 32;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var string
|
14 |
-
*/
|
15 |
-
private $key_bytes;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Creates new random key.
|
19 |
-
*
|
20 |
-
* @throws Ex\EnvironmentIsBrokenException
|
21 |
-
*
|
22 |
-
* @return Key
|
23 |
-
*/
|
24 |
-
public static function createNewRandomKey()
|
25 |
-
{
|
26 |
-
return new Key(Core::secureRandom(self::KEY_BYTE_SIZE));
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Loads a Key from its encoded form.
|
31 |
-
*
|
32 |
-
* By default, this function will call Encoding::trimTrailingWhitespace()
|
33 |
-
* to remove trailing CR, LF, NUL, TAB, and SPACE characters, which are
|
34 |
-
* commonly appended to files when working with text editors.
|
35 |
-
*
|
36 |
-
* @param string $saved_key_string
|
37 |
-
* @param bool $do_not_trim (default: false)
|
38 |
-
*
|
39 |
-
* @throws Ex\BadFormatException
|
40 |
-
* @throws Ex\EnvironmentIsBrokenException
|
41 |
-
*
|
42 |
-
* @return Key
|
43 |
-
*/
|
44 |
-
public static function loadFromAsciiSafeString($saved_key_string, $do_not_trim = false)
|
45 |
-
{
|
46 |
-
if (!$do_not_trim) {
|
47 |
-
$saved_key_string = Encoding::trimTrailingWhitespace($saved_key_string);
|
48 |
-
}
|
49 |
-
$key_bytes = Encoding::loadBytesFromChecksummedAsciiSafeString(self::KEY_CURRENT_VERSION, $saved_key_string);
|
50 |
-
return new Key($key_bytes);
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Encodes the Key into a string of printable ASCII characters.
|
55 |
-
*
|
56 |
-
* @throws Ex\EnvironmentIsBrokenException
|
57 |
-
*
|
58 |
-
* @return string
|
59 |
-
*/
|
60 |
-
public function saveToAsciiSafeString()
|
61 |
-
{
|
62 |
-
return Encoding::saveBytesToChecksummedAsciiSafeString(
|
63 |
-
self::KEY_CURRENT_VERSION,
|
64 |
-
$this->key_bytes
|
65 |
-
);
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Gets the raw bytes of the key.
|
70 |
-
*
|
71 |
-
* @return string
|
72 |
-
*/
|
73 |
-
public function getRawBytes()
|
74 |
-
{
|
75 |
-
return $this->key_bytes;
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Constructs a new Key object from a string of raw bytes.
|
80 |
-
*
|
81 |
-
* @param string $bytes
|
82 |
-
*
|
83 |
-
* @throws Ex\EnvironmentIsBrokenException
|
84 |
-
*/
|
85 |
-
private function __construct($bytes)
|
86 |
-
{
|
87 |
-
Core::ensureTrue(
|
88 |
-
Core::ourStrlen($bytes) === self::KEY_BYTE_SIZE,
|
89 |
-
'Bad key length.'
|
90 |
-
);
|
91 |
-
$this->key_bytes = $bytes;
|
92 |
-
}
|
93 |
-
|
94 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/KeyOrPassword.php
DELETED
@@ -1,149 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class KeyOrPassword
|
8 |
-
{
|
9 |
-
const PBKDF2_ITERATIONS = 100000;
|
10 |
-
const SECRET_TYPE_KEY = 1;
|
11 |
-
const SECRET_TYPE_PASSWORD = 2;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var int
|
15 |
-
*/
|
16 |
-
private $secret_type = 0;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @var Key|string
|
20 |
-
*/
|
21 |
-
private $secret;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Initializes an instance of KeyOrPassword from a key.
|
25 |
-
*
|
26 |
-
* @param Key $key
|
27 |
-
*
|
28 |
-
* @return KeyOrPassword
|
29 |
-
*/
|
30 |
-
public static function createFromKey(Key $key)
|
31 |
-
{
|
32 |
-
return new KeyOrPassword(self::SECRET_TYPE_KEY, $key);
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Initializes an instance of KeyOrPassword from a password.
|
37 |
-
*
|
38 |
-
* @param string $password
|
39 |
-
*
|
40 |
-
* @return KeyOrPassword
|
41 |
-
*/
|
42 |
-
public static function createFromPassword($password)
|
43 |
-
{
|
44 |
-
return new KeyOrPassword(self::SECRET_TYPE_PASSWORD, $password);
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Derives authentication and encryption keys from the secret, using a slow
|
49 |
-
* key derivation function if the secret is a password.
|
50 |
-
*
|
51 |
-
* @param string $salt
|
52 |
-
*
|
53 |
-
* @throws Ex\CryptoException
|
54 |
-
* @throws Ex\EnvironmentIsBrokenException
|
55 |
-
*
|
56 |
-
* @return DerivedKeys
|
57 |
-
*/
|
58 |
-
public function deriveKeys($salt)
|
59 |
-
{
|
60 |
-
Core::ensureTrue(
|
61 |
-
Core::ourStrlen($salt) === Core::SALT_BYTE_SIZE,
|
62 |
-
'Bad salt.'
|
63 |
-
);
|
64 |
-
|
65 |
-
if ($this->secret_type === self::SECRET_TYPE_KEY) {
|
66 |
-
Core::ensureTrue($this->secret instanceof Key);
|
67 |
-
/**
|
68 |
-
* @psalm-suppress PossiblyInvalidMethodCall
|
69 |
-
*/
|
70 |
-
$akey = Core::HKDF(
|
71 |
-
Core::HASH_FUNCTION_NAME,
|
72 |
-
$this->secret->getRawBytes(),
|
73 |
-
Core::KEY_BYTE_SIZE,
|
74 |
-
Core::AUTHENTICATION_INFO_STRING,
|
75 |
-
$salt
|
76 |
-
);
|
77 |
-
/**
|
78 |
-
* @psalm-suppress PossiblyInvalidMethodCall
|
79 |
-
*/
|
80 |
-
$ekey = Core::HKDF(
|
81 |
-
Core::HASH_FUNCTION_NAME,
|
82 |
-
$this->secret->getRawBytes(),
|
83 |
-
Core::KEY_BYTE_SIZE,
|
84 |
-
Core::ENCRYPTION_INFO_STRING,
|
85 |
-
$salt
|
86 |
-
);
|
87 |
-
return new DerivedKeys($akey, $ekey);
|
88 |
-
} elseif ($this->secret_type === self::SECRET_TYPE_PASSWORD) {
|
89 |
-
Core::ensureTrue(\is_string($this->secret));
|
90 |
-
/* Our PBKDF2 polyfill is vulnerable to a DoS attack documented in
|
91 |
-
* GitHub issue #230. The fix is to pre-hash the password to ensure
|
92 |
-
* it is short. We do the prehashing here instead of in pbkdf2() so
|
93 |
-
* that pbkdf2() still computes the function as defined by the
|
94 |
-
* standard. */
|
95 |
-
|
96 |
-
/**
|
97 |
-
* @psalm-suppress PossiblyInvalidArgument
|
98 |
-
*/
|
99 |
-
$prehash = \hash(Core::HASH_FUNCTION_NAME, $this->secret, true);
|
100 |
-
|
101 |
-
$prekey = Core::pbkdf2(
|
102 |
-
Core::HASH_FUNCTION_NAME,
|
103 |
-
$prehash,
|
104 |
-
$salt,
|
105 |
-
self::PBKDF2_ITERATIONS,
|
106 |
-
Core::KEY_BYTE_SIZE,
|
107 |
-
true
|
108 |
-
);
|
109 |
-
$akey = Core::HKDF(
|
110 |
-
Core::HASH_FUNCTION_NAME,
|
111 |
-
$prekey,
|
112 |
-
Core::KEY_BYTE_SIZE,
|
113 |
-
Core::AUTHENTICATION_INFO_STRING,
|
114 |
-
$salt
|
115 |
-
);
|
116 |
-
/* Note the cryptographic re-use of $salt here. */
|
117 |
-
$ekey = Core::HKDF(
|
118 |
-
Core::HASH_FUNCTION_NAME,
|
119 |
-
$prekey,
|
120 |
-
Core::KEY_BYTE_SIZE,
|
121 |
-
Core::ENCRYPTION_INFO_STRING,
|
122 |
-
$salt
|
123 |
-
);
|
124 |
-
return new DerivedKeys($akey, $ekey);
|
125 |
-
} else {
|
126 |
-
throw new Ex\EnvironmentIsBrokenException('Bad secret type.');
|
127 |
-
}
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* Constructor for KeyOrPassword.
|
132 |
-
*
|
133 |
-
* @param int $secret_type
|
134 |
-
* @param mixed $secret (either a Key or a password string)
|
135 |
-
*/
|
136 |
-
private function __construct($secret_type, $secret)
|
137 |
-
{
|
138 |
-
// The constructor is private, so these should never throw.
|
139 |
-
if ($secret_type === self::SECRET_TYPE_KEY) {
|
140 |
-
Core::ensureTrue($secret instanceof Key);
|
141 |
-
} elseif ($secret_type === self::SECRET_TYPE_PASSWORD) {
|
142 |
-
Core::ensureTrue(\is_string($secret));
|
143 |
-
} else {
|
144 |
-
throw new Ex\EnvironmentIsBrokenException('Bad secret type.');
|
145 |
-
}
|
146 |
-
$this->secret_type = $secret_type;
|
147 |
-
$this->secret = $secret;
|
148 |
-
}
|
149 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/KeyProtectedByPassword.php
DELETED
@@ -1,145 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
final class KeyProtectedByPassword
|
8 |
-
{
|
9 |
-
const PASSWORD_KEY_CURRENT_VERSION = "\xDE\xF1\x00\x00";
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @var string
|
13 |
-
*/
|
14 |
-
private $encrypted_key = '';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Creates a random key protected by the provided password.
|
18 |
-
*
|
19 |
-
* @param string $password
|
20 |
-
*
|
21 |
-
* @throws Ex\EnvironmentIsBrokenException
|
22 |
-
*
|
23 |
-
* @return KeyProtectedByPassword
|
24 |
-
*/
|
25 |
-
public static function createRandomPasswordProtectedKey($password)
|
26 |
-
{
|
27 |
-
$inner_key = Key::createNewRandomKey();
|
28 |
-
/* The password is hashed as a form of poor-man's domain separation
|
29 |
-
* between this use of encryptWithPassword() and other uses of
|
30 |
-
* encryptWithPassword() that the user may also be using as part of the
|
31 |
-
* same protocol. */
|
32 |
-
$encrypted_key = Crypto::encryptWithPassword(
|
33 |
-
$inner_key->saveToAsciiSafeString(),
|
34 |
-
\hash(Core::HASH_FUNCTION_NAME, $password, true),
|
35 |
-
true
|
36 |
-
);
|
37 |
-
|
38 |
-
return new KeyProtectedByPassword($encrypted_key);
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Loads a KeyProtectedByPassword from its encoded form.
|
43 |
-
*
|
44 |
-
* @param string $saved_key_string
|
45 |
-
*
|
46 |
-
* @throws Ex\BadFormatException
|
47 |
-
*
|
48 |
-
* @return KeyProtectedByPassword
|
49 |
-
*/
|
50 |
-
public static function loadFromAsciiSafeString($saved_key_string)
|
51 |
-
{
|
52 |
-
$encrypted_key = Encoding::loadBytesFromChecksummedAsciiSafeString(
|
53 |
-
self::PASSWORD_KEY_CURRENT_VERSION,
|
54 |
-
$saved_key_string
|
55 |
-
);
|
56 |
-
return new KeyProtectedByPassword($encrypted_key);
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Encodes the KeyProtectedByPassword into a string of printable ASCII
|
61 |
-
* characters.
|
62 |
-
*
|
63 |
-
* @throws Ex\EnvironmentIsBrokenException
|
64 |
-
*
|
65 |
-
* @return string
|
66 |
-
*/
|
67 |
-
public function saveToAsciiSafeString()
|
68 |
-
{
|
69 |
-
return Encoding::saveBytesToChecksummedAsciiSafeString(
|
70 |
-
self::PASSWORD_KEY_CURRENT_VERSION,
|
71 |
-
$this->encrypted_key
|
72 |
-
);
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Decrypts the protected key, returning an unprotected Key object that can
|
77 |
-
* be used for encryption and decryption.
|
78 |
-
*
|
79 |
-
* @throws Ex\EnvironmentIsBrokenException
|
80 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
81 |
-
*
|
82 |
-
* @param string $password
|
83 |
-
* @return Key
|
84 |
-
*/
|
85 |
-
public function unlockKey($password)
|
86 |
-
{
|
87 |
-
try {
|
88 |
-
$inner_key_encoded = Crypto::decryptWithPassword(
|
89 |
-
$this->encrypted_key,
|
90 |
-
\hash(Core::HASH_FUNCTION_NAME, $password, true),
|
91 |
-
true
|
92 |
-
);
|
93 |
-
return Key::loadFromAsciiSafeString($inner_key_encoded);
|
94 |
-
} catch (Ex\BadFormatException $ex) {
|
95 |
-
/* This should never happen unless an attacker replaced the
|
96 |
-
* encrypted key ciphertext with some other ciphertext that was
|
97 |
-
* encrypted with the same password. We transform the exception type
|
98 |
-
* here in order to make the API simpler, avoiding the need to
|
99 |
-
* document that this method might throw an Ex\BadFormatException. */
|
100 |
-
throw new Ex\WrongKeyOrModifiedCiphertextException(
|
101 |
-
"The decrypted key was found to be in an invalid format. " .
|
102 |
-
"This very likely indicates it was modified by an attacker."
|
103 |
-
);
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Changes the password.
|
109 |
-
*
|
110 |
-
* @param string $current_password
|
111 |
-
* @param string $new_password
|
112 |
-
*
|
113 |
-
* @throws Ex\EnvironmentIsBrokenException
|
114 |
-
* @throws Ex\WrongKeyOrModifiedCiphertextException
|
115 |
-
*
|
116 |
-
* @return KeyProtectedByPassword
|
117 |
-
*/
|
118 |
-
public function changePassword($current_password, $new_password)
|
119 |
-
{
|
120 |
-
$inner_key = $this->unlockKey($current_password);
|
121 |
-
/* The password is hashed as a form of poor-man's domain separation
|
122 |
-
* between this use of encryptWithPassword() and other uses of
|
123 |
-
* encryptWithPassword() that the user may also be using as part of the
|
124 |
-
* same protocol. */
|
125 |
-
$encrypted_key = Crypto::encryptWithPassword(
|
126 |
-
$inner_key->saveToAsciiSafeString(),
|
127 |
-
\hash(Core::HASH_FUNCTION_NAME, $new_password, true),
|
128 |
-
true
|
129 |
-
);
|
130 |
-
|
131 |
-
$this->encrypted_key = $encrypted_key;
|
132 |
-
|
133 |
-
return $this;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Constructor for KeyProtectedByPassword.
|
138 |
-
*
|
139 |
-
* @param string $encrypted_key
|
140 |
-
*/
|
141 |
-
private function __construct($encrypted_key)
|
142 |
-
{
|
143 |
-
$this->encrypted_key = $encrypted_key;
|
144 |
-
}
|
145 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/defuse/php-encryption/src/RuntimeTests.php
DELETED
@@ -1,228 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace Defuse\Crypto;
|
4 |
-
|
5 |
-
use Defuse\Crypto\Exception as Ex;
|
6 |
-
|
7 |
-
/*
|
8 |
-
* We're using static class inheritance to get access to protected methods
|
9 |
-
* inside Crypto. To make it easy to know where the method we're calling can be
|
10 |
-
* found, within this file, prefix calls with `Crypto::` or `RuntimeTests::`,
|
11 |
-
* and don't use `self::`.
|
12 |
-
*/
|
13 |
-
|
14 |
-
class RuntimeTests extends Crypto
|
15 |
-
{
|
16 |
-
/**
|
17 |
-
* Runs the runtime tests.
|
18 |
-
*
|
19 |
-
* @throws Ex\EnvironmentIsBrokenException
|
20 |
-
* @return void
|
21 |
-
*/
|
22 |
-
public static function runtimeTest()
|
23 |
-
{
|
24 |
-
// 0: Tests haven't been run yet.
|
25 |
-
// 1: Tests have passed.
|
26 |
-
// 2: Tests are running right now.
|
27 |
-
// 3: Tests have failed.
|
28 |
-
static $test_state = 0;
|
29 |
-
|
30 |
-
if ($test_state === 1 || $test_state === 2) {
|
31 |
-
return;
|
32 |
-
}
|
33 |
-
|
34 |
-
if ($test_state === 3) {
|
35 |
-
/* If an intermittent problem caused a test to fail previously, we
|
36 |
-
* want that to be indicated to the user with every call to this
|
37 |
-
* library. This way, if the user first does something they really
|
38 |
-
* don't care about, and just ignores all exceptions, they won't get
|
39 |
-
* screwed when they then start to use the library for something
|
40 |
-
* they do care about. */
|
41 |
-
throw new Ex\EnvironmentIsBrokenException('Tests failed previously.');
|
42 |
-
}
|
43 |
-
|
44 |
-
try {
|
45 |
-
$test_state = 2;
|
46 |
-
|
47 |
-
Core::ensureFunctionExists('openssl_get_cipher_methods');
|
48 |
-
if (\in_array(Core::CIPHER_METHOD, \openssl_get_cipher_methods()) === false) {
|
49 |
-
throw new Ex\EnvironmentIsBrokenException(
|
50 |
-
'Cipher method not supported. This is normally caused by an outdated ' .
|
51 |
-
'version of OpenSSL (and/or OpenSSL compiled for FIPS compliance). ' .
|
52 |
-
'Please upgrade to a newer version of OpenSSL that supports ' .
|
53 |
-
Core::CIPHER_METHOD . ' to use this library.'
|
54 |
-
);
|
55 |
-
}
|
56 |
-
|
57 |
-
RuntimeTests::AESTestVector();
|
58 |
-
RuntimeTests::HMACTestVector();
|
59 |
-
RuntimeTests::HKDFTestVector();
|
60 |
-
|
61 |
-
RuntimeTests::testEncryptDecrypt();
|
62 |
-
Core::ensureTrue(Core::ourStrlen(Key::createNewRandomKey()->getRawBytes()) === Core::KEY_BYTE_SIZE);
|
63 |
-
|
64 |
-
Core::ensureTrue(Core::ENCRYPTION_INFO_STRING !== Core::AUTHENTICATION_INFO_STRING);
|
65 |
-
} catch (Ex\EnvironmentIsBrokenException $ex) {
|
66 |
-
// Do this, otherwise it will stay in the "tests are running" state.
|
67 |
-
$test_state = 3;
|
68 |
-
throw $ex;
|
69 |
-
}
|
70 |
-
|
71 |
-
// Change this to '0' make the tests always re-run (for benchmarking).
|
72 |
-
$test_state = 1;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* High-level tests of Crypto operations.
|
77 |
-
*
|
78 |
-
* @throws Ex\EnvironmentIsBrokenException
|
79 |
-
* @return void
|
80 |
-
*/
|
81 |
-
private static function testEncryptDecrypt()
|
82 |
-
{
|
83 |
-
$key = Key::createNewRandomKey();
|
84 |
-
$data = "EnCrYpT EvErYThInG\x00\x00";
|
85 |
-
|
86 |
-
// Make sure encrypting then decrypting doesn't change the message.
|
87 |
-
$ciphertext = Crypto::encrypt($data, $key, true);
|
88 |
-
try {
|
89 |
-
$decrypted = Crypto::decrypt($ciphertext, $key, true);
|
90 |
-
} catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
|
91 |
-
// It's important to catch this and change it into a
|
92 |
-
// Ex\EnvironmentIsBrokenException, otherwise a test failure could trick
|
93 |
-
// the user into thinking it's just an invalid ciphertext!
|
94 |
-
throw new Ex\EnvironmentIsBrokenException();
|
95 |
-
}
|
96 |
-
Core::ensureTrue($decrypted === $data);
|
97 |
-
|
98 |
-
// Modifying the ciphertext: Appending a string.
|
99 |
-
try {
|
100 |
-
Crypto::decrypt($ciphertext . 'a', $key, true);
|
101 |
-
throw new Ex\EnvironmentIsBrokenException();
|
102 |
-
} catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
|
103 |
-
}
|
104 |
-
|
105 |
-
// Modifying the ciphertext: Changing an HMAC byte.
|
106 |
-
$indices_to_change = [
|
107 |
-
0, // The header.
|
108 |
-
Core::HEADER_VERSION_SIZE + 1, // the salt
|
109 |
-
Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + 1, // the IV
|
110 |
-
Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + Core::BLOCK_BYTE_SIZE + 1, // the ciphertext
|
111 |
-
];
|
112 |
-
|
113 |
-
foreach ($indices_to_change as $index) {
|
114 |
-
try {
|
115 |
-
$ciphertext[$index] = \chr((\ord($ciphertext[$index]) + 1) % 256);
|
116 |
-
Crypto::decrypt($ciphertext, $key, true);
|
117 |
-
throw new Ex\EnvironmentIsBrokenException();
|
118 |
-
} catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
|
119 |
-
}
|
120 |
-
}
|
121 |
-
|
122 |
-
// Decrypting with the wrong key.
|
123 |
-
$key = Key::createNewRandomKey();
|
124 |
-
$data = 'abcdef';
|
125 |
-
$ciphertext = Crypto::encrypt($data, $key, true);
|
126 |
-
$wrong_key = Key::createNewRandomKey();
|
127 |
-
try {
|
128 |
-
Crypto::decrypt($ciphertext, $wrong_key, true);
|
129 |
-
throw new Ex\EnvironmentIsBrokenException();
|
130 |
-
} catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
|
131 |
-
}
|
132 |
-
|
133 |
-
// Ciphertext too small.
|
134 |
-
$key = Key::createNewRandomKey();
|
135 |
-
$ciphertext = \str_repeat('A', Core::MINIMUM_CIPHERTEXT_SIZE - 1);
|
136 |
-
try {
|
137 |
-
Crypto::decrypt($ciphertext, $key, true);
|
138 |
-
throw new Ex\EnvironmentIsBrokenException();
|
139 |
-
} catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Test HKDF against test vectors.
|
145 |
-
*
|
146 |
-
* @throws Ex\EnvironmentIsBrokenException
|
147 |
-
* @return void
|
148 |
-
*/
|
149 |
-
private static function HKDFTestVector()
|
150 |
-
{
|
151 |
-
// HKDF test vectors from RFC 5869
|
152 |
-
|
153 |
-
// Test Case 1
|
154 |
-
$ikm = \str_repeat("\x0b", 22);
|
155 |
-
$salt = Encoding::hexToBin('000102030405060708090a0b0c');
|
156 |
-
$info = Encoding::hexToBin('f0f1f2f3f4f5f6f7f8f9');
|
157 |
-
$length = 42;
|
158 |
-
$okm = Encoding::hexToBin(
|
159 |
-
'3cb25f25faacd57a90434f64d0362f2a' .
|
160 |
-
'2d2d0a90cf1a5a4c5db02d56ecc4c5bf' .
|
161 |
-
'34007208d5b887185865'
|
162 |
-
);
|
163 |
-
$computed_okm = Core::HKDF('sha256', $ikm, $length, $info, $salt);
|
164 |
-
Core::ensureTrue($computed_okm === $okm);
|
165 |
-
|
166 |
-
// Test Case 7
|
167 |
-
$ikm = \str_repeat("\x0c", 22);
|
168 |
-
$length = 42;
|
169 |
-
$okm = Encoding::hexToBin(
|
170 |
-
'2c91117204d745f3500d636a62f64f0a' .
|
171 |
-
'b3bae548aa53d423b0d1f27ebba6f5e5' .
|
172 |
-
'673a081d70cce7acfc48'
|
173 |
-
);
|
174 |
-
$computed_okm = Core::HKDF('sha1', $ikm, $length, '', null);
|
175 |
-
Core::ensureTrue($computed_okm === $okm);
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Test HMAC against test vectors.
|
180 |
-
*
|
181 |
-
* @throws Ex\EnvironmentIsBrokenException
|
182 |
-
* @return void
|
183 |
-
*/
|
184 |
-
private static function HMACTestVector()
|
185 |
-
{
|
186 |
-
// HMAC test vector From RFC 4231 (Test Case 1)
|
187 |
-
$key = \str_repeat("\x0b", 20);
|
188 |
-
$data = 'Hi There';
|
189 |
-
$correct = 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7';
|
190 |
-
Core::ensureTrue(
|
191 |
-
\hash_hmac(Core::HASH_FUNCTION_NAME, $data, $key) === $correct
|
192 |
-
);
|
193 |
-
}
|
194 |
-
|
195 |
-
/**
|
196 |
-
* Test AES against test vectors.
|
197 |
-
*
|
198 |
-
* @throws Ex\EnvironmentIsBrokenException
|
199 |
-
* @return void
|
200 |
-
*/
|
201 |
-
private static function AESTestVector()
|
202 |
-
{
|
203 |
-
// AES CTR mode test vector from NIST SP 800-38A
|
204 |
-
$key = Encoding::hexToBin(
|
205 |
-
'603deb1015ca71be2b73aef0857d7781' .
|
206 |
-
'1f352c073b6108d72d9810a30914dff4'
|
207 |
-
);
|
208 |
-
$iv = Encoding::hexToBin('f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff');
|
209 |
-
$plaintext = Encoding::hexToBin(
|
210 |
-
'6bc1bee22e409f96e93d7e117393172a' .
|
211 |
-
'ae2d8a571e03ac9c9eb76fac45af8e51' .
|
212 |
-
'30c81c46a35ce411e5fbc1191a0a52ef' .
|
213 |
-
'f69f2445df4f9b17ad2b417be66c3710'
|
214 |
-
);
|
215 |
-
$ciphertext = Encoding::hexToBin(
|
216 |
-
'601ec313775789a5b7a7f504bbf3d228' .
|
217 |
-
'f443e3ca4d62b59aca84e990cacaf5c5' .
|
218 |
-
'2b0930daa23de94ce87017ba2d84988d' .
|
219 |
-
'dfc9c58db67aada613c2dd08457941a6'
|
220 |
-
);
|
221 |
-
|
222 |
-
$computed_ciphertext = Crypto::plainEncrypt($plaintext, $key, $iv);
|
223 |
-
Core::ensureTrue($computed_ciphertext === $ciphertext);
|
224 |
-
|
225 |
-
$computed_plaintext = Crypto::plainDecrypt($ciphertext, $key, $iv, Core::CIPHER_METHOD);
|
226 |
-
Core::ensureTrue($computed_plaintext === $plaintext);
|
227 |
-
}
|
228 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/gliterd/backblaze-b2/.gitignore
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
build
|
2 |
+
composer.lock
|
3 |
+
docs
|
4 |
+
vendor
|
5 |
+
coverage
|
6 |
+
coverage.xml
|
7 |
+
.idea/
|
vendor/gliterd/backblaze-b2/.scrutinizer.yml
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
filter:
|
2 |
+
paths: [src/*]
|
3 |
+
checks:
|
4 |
+
php:
|
5 |
+
code_rating: true
|
6 |
+
remove_extra_empty_lines: true
|
7 |
+
remove_php_closing_tag: true
|
8 |
+
remove_trailing_whitespace: true
|
9 |
+
fix_use_statements:
|
10 |
+
remove_unused: true
|
11 |
+
preserve_multiple: false
|
12 |
+
preserve_blanklines: true
|
13 |
+
order_alphabetically: true
|
14 |
+
fix_php_opening_tag: true
|
15 |
+
fix_linefeed: true
|
16 |
+
fix_line_ending: true
|
17 |
+
fix_identation_4spaces: true
|
18 |
+
fix_doc_comments: true
|
19 |
+
tools:
|
20 |
+
php_code_coverage: true
|
21 |
+
php_code_sniffer:
|
22 |
+
config:
|
23 |
+
standard: PSR2
|
24 |
+
filter:
|
25 |
+
paths: ['src']
|
26 |
+
php_loc:
|
27 |
+
enabled: true
|
28 |
+
php_cpd:
|
29 |
+
enabled: true
|
30 |
+
build:
|
31 |
+
environment:
|
32 |
+
php:
|
33 |
+
version: 7.1
|
vendor/gliterd/backblaze-b2/.travis.yml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
language: php
|
2 |
+
|
3 |
+
php:
|
4 |
+
- '5.6'
|
5 |
+
- '7.0'
|
6 |
+
- '7.1'
|
7 |
+
- nightly
|
8 |
+
|
9 |
+
before_script: composer install
|
vendor/league/flysystem-sftp/.travis.yml
CHANGED
@@ -12,14 +12,10 @@ env:
|
|
12 |
- PREFER_LOWEST=""
|
13 |
|
14 |
php:
|
15 |
-
- 5.5
|
16 |
- 5.6
|
17 |
- 7.0
|
18 |
- 7.1
|
19 |
-
|
20 |
-
before_install:
|
21 |
-
- composer self-up
|
22 |
-
- composer config --global github-oauth.github.com $GITHUB_OAUTH_TOKEN
|
23 |
|
24 |
install:
|
25 |
- composer update --no-interaction --prefer-stable $PREFER_LOWEST
|
12 |
- PREFER_LOWEST=""
|
13 |
|
14 |
php:
|
|
|
15 |
- 5.6
|
16 |
- 7.0
|
17 |
- 7.1
|
18 |
+
- 7.2
|
|
|
|
|
|
|
19 |
|
20 |
install:
|
21 |
- composer update --no-interaction --prefer-stable $PREFER_LOWEST
|
vendor/league/flysystem-sftp/changelog.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1 |
# Changelog
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
## 1.0.14 - 2017-07-11
|
4 |
|
5 |
### Fixed
|
1 |
# Changelog
|
2 |
|
3 |
+
## 1.0.18 - 2019-01-07
|
4 |
+
|
5 |
+
* Throw an Exception if can't connect to check Host Fingerprint
|
6 |
+
|
7 |
+
## 1.0.17 - 2018-10-14
|
8 |
+
|
9 |
+
* Don't return visibility when not in scope
|
10 |
+
|
11 |
+
## 1.0.16 - 2018-07-08
|
12 |
+
|
13 |
+
### Altered
|
14 |
+
|
15 |
+
* Stat cache is always disabled.
|
16 |
+
|
17 |
+
## 1.0.15 - 2017-11-16
|
18 |
+
|
19 |
+
### Fixed
|
20 |
+
|
21 |
+
* Added missing `path` to read and readStream response.
|
22 |
+
* Upgraded phpunit and lost support for php <=5.5
|
23 |
+
|
24 |
## 1.0.14 - 2017-07-11
|
25 |
|
26 |
### Fixed
|
vendor/league/flysystem-sftp/composer.json
CHANGED
@@ -9,22 +9,17 @@
|
|
9 |
}
|
10 |
],
|
11 |
"require": {
|
12 |
-
"php": ">=5.
|
13 |
"league/flysystem": "~1.0",
|
14 |
"phpseclib/phpseclib": "~2.0"
|
15 |
},
|
16 |
"require-dev": {
|
17 |
-
"
|
18 |
-
"
|
19 |
},
|
20 |
"autoload": {
|
21 |
"psr-4": {
|
22 |
"League\\Flysystem\\Sftp\\": "src/"
|
23 |
}
|
24 |
-
},
|
25 |
-
"extra": {
|
26 |
-
"branch-alias": {
|
27 |
-
"dev-master": "1.0-dev"
|
28 |
-
}
|
29 |
}
|
30 |
}
|
9 |
}
|
10 |
],
|
11 |
"require": {
|
12 |
+
"php": ">=5.6.0",
|
13 |
"league/flysystem": "~1.0",
|
14 |
"phpseclib/phpseclib": "~2.0"
|
15 |
},
|
16 |
"require-dev": {
|
17 |
+
"mockery/mockery": "0.9.*",
|
18 |
+
"phpunit/phpunit": "^5.7.25"
|
19 |
},
|
20 |
"autoload": {
|
21 |
"psr-4": {
|
22 |
"League\\Flysystem\\Sftp\\": "src/"
|
23 |
}
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
}
|
vendor/league/flysystem-sftp/phpunit.xml
CHANGED
@@ -25,7 +25,6 @@
|
|
25 |
</listeners>
|
26 |
<logging>
|
27 |
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
|
28 |
-
<log type="coverage-html" target="coverage" showUncoveredFiles="true"/>
|
29 |
<log type="coverage-clover" target="coverage.xml" showUncoveredFiles="true"/>
|
30 |
</logging>
|
31 |
</phpunit>
|
25 |
</listeners>
|
26 |
<logging>
|
27 |
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
|
|
|
28 |
<log type="coverage-clover" target="coverage.xml" showUncoveredFiles="true"/>
|
29 |
</logging>
|
30 |
</phpunit>
|
vendor/league/flysystem-sftp/readme.md
CHANGED
@@ -7,6 +7,7 @@
|
|
7 |
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
8 |
[![Packagist Version](https://img.shields.io/packagist/v/league/flysystem-sftp.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-sftp)
|
9 |
[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem-sftp.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-sftp)
|
|
|
10 |
|
11 |
This adapter uses phpseclib to provide a SFTP adapter for Flysystem.
|
12 |
|
@@ -16,6 +17,10 @@ This adapter uses phpseclib to provide a SFTP adapter for Flysystem.
|
|
16 |
composer require league/flysystem-sftp
|
17 |
```
|
18 |
|
|
|
|
|
|
|
|
|
19 |
## Usage
|
20 |
|
21 |
```php
|
7 |
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
8 |
[![Packagist Version](https://img.shields.io/packagist/v/league/flysystem-sftp.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-sftp)
|
9 |
[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem-sftp.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-sftp)
|
10 |
+
[![Documentation](https://img.shields.io/badge/read-documentation-brightgreen.svg)](https://flysystem.thephpleague.com/adapter/sftp/)
|
11 |
|
12 |
This adapter uses phpseclib to provide a SFTP adapter for Flysystem.
|
13 |
|
17 |
composer require league/flysystem-sftp
|
18 |
```
|
19 |
|
20 |
+
## Documentation
|
21 |
+
|
22 |
+
Full documentation of this adapter can be found [here](https://flysystem.thephpleague.com/adapter/sftp/): https://flysystem.thephpleague.com/adapter/sftp/
|
23 |
+
|
24 |
## Usage
|
25 |
|
26 |
```php
|
vendor/league/flysystem-sftp/src/SftpAdapter.php
CHANGED
@@ -9,8 +9,8 @@ use League\Flysystem\AdapterInterface;
|
|
9 |
use League\Flysystem\Config;
|
10 |
use League\Flysystem\Util;
|
11 |
use LogicException;
|
12 |
-
use phpseclib\Net\SFTP;
|
13 |
use phpseclib\Crypt\RSA;
|
|
|
14 |
use phpseclib\System\SSH\Agent;
|
15 |
use RuntimeException;
|
16 |
|
@@ -174,6 +174,7 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
174 |
public function connect()
|
175 |
{
|
176 |
$this->connection = $this->connection ?: new SFTP($this->host, $this->port, $this->timeout);
|
|
|
177 |
$this->login();
|
178 |
$this->setConnectionRoot();
|
179 |
}
|
@@ -186,7 +187,13 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
186 |
protected function login()
|
187 |
{
|
188 |
if ($this->hostFingerprint) {
|
189 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
if (0 !== strcasecmp($this->hostFingerprint, $actualFingerprint)) {
|
192 |
throw new LogicException('The authenticity of host '.$this->host.' can\'t be established.');
|
@@ -362,7 +369,7 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
362 |
return false;
|
363 |
}
|
364 |
|
365 |
-
return compact('contents', '
|
366 |
}
|
367 |
|
368 |
/**
|
@@ -374,7 +381,7 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
374 |
return false;
|
375 |
}
|
376 |
|
377 |
-
return compact('
|
378 |
}
|
379 |
|
380 |
/**
|
@@ -413,7 +420,7 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
413 |
return false;
|
414 |
}
|
415 |
|
416 |
-
return compact('contents');
|
417 |
}
|
418 |
|
419 |
/**
|
@@ -431,7 +438,7 @@ class SftpAdapter extends AbstractFtpAdapter
|
|
431 |
|
432 |
rewind($stream);
|
433 |
|
434 |
-
return compact('stream');
|
435 |
}
|
436 |
|
437 |
/**
|
9 |
use League\Flysystem\Config;
|
10 |
use League\Flysystem\Util;
|
11 |
use LogicException;
|
|
|
12 |
use phpseclib\Crypt\RSA;
|
13 |
+
use phpseclib\Net\SFTP;
|
14 |
use phpseclib\System\SSH\Agent;
|
15 |
use RuntimeException;
|
16 |
|
174 |
public function connect()
|
175 |
{
|
176 |
$this->connection = $this->connection ?: new SFTP($this->host, $this->port, $this->timeout);
|
177 |
+
$this->connection->disableStatCache();
|
178 |
$this->login();
|
179 |
$this->setConnectionRoot();
|
180 |
}
|
187 |
protected function login()
|
188 |
{
|
189 |
if ($this->hostFingerprint) {
|
190 |
+
$publicKey = $this->connection->getServerPublicHostKey();
|
191 |
+
|
192 |
+
if ($publicKey === false) {
|
193 |
+
throw new LogicException('Could not connect to server to verify public key.');
|
194 |
+
}
|
195 |
+
|
196 |
+
$actualFingerprint = $this->getHexFingerprintFromSshPublicKey($publicKey);
|
197 |
|
198 |
if (0 !== strcasecmp($this->hostFingerprint, $actualFingerprint)) {
|
199 |
throw new LogicException('The authenticity of host '.$this->host.' can\'t be established.');
|
369 |
return false;
|
370 |
}
|
371 |
|
372 |
+
return compact('contents', 'path');
|
373 |
}
|
374 |
|
375 |
/**
|
381 |
return false;
|
382 |
}
|
383 |
|
384 |
+
return compact('path');
|
385 |
}
|
386 |
|
387 |
/**
|
420 |
return false;
|
421 |
}
|
422 |
|
423 |
+
return compact('contents', 'path');
|
424 |
}
|
425 |
|
426 |
/**
|
438 |
|
439 |
rewind($stream);
|
440 |
|
441 |
+
return compact('stream', 'path');
|
442 |
}
|
443 |
|
444 |
/**
|
vendor/league/flysystem-sftp/tests/SftpAdapterTests.php
CHANGED
@@ -5,12 +5,17 @@ use League\Flysystem\FilesystemInterface;
|
|
5 |
use League\Flysystem\Sftp\SftpAdapter as Sftp;
|
6 |
use League\Flysystem\Sftp\SftpAdapter;
|
7 |
use phpseclib\System\SSH\Agent;
|
|
|
8 |
|
9 |
/**
|
10 |
* @covers \League\Flysystem\Sftp\SftpAdapter<extended>
|
11 |
*/
|
12 |
-
class SftpTests extends
|
13 |
{
|
|
|
|
|
|
|
|
|
14 |
protected function setup()
|
15 |
{
|
16 |
if (! defined('NET_SFTP_TYPE_DIRECTORY')) {
|
@@ -139,6 +144,12 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
139 |
*/
|
140 |
public function testSetVisibility($filesystem, $adapter, $mock)
|
141 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
$mock->shouldReceive('chmod')->twice()->andReturn(true, false);
|
143 |
$this->assertTrue($filesystem->setVisibility('something', 'public'));
|
144 |
$this->assertFalse($filesystem->setVisibility('something', 'public'));
|
@@ -150,6 +161,12 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
150 |
*/
|
151 |
public function testSetVisibilityInvalid($filesystem, $adapter, $mock)
|
152 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
$mock->shouldReceive('stat')->once()->andReturn(true);
|
154 |
$filesystem->setVisibility('something', 'invalid');
|
155 |
}
|
@@ -395,6 +412,7 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
395 |
{
|
396 |
$adapter->setNetSftpConnection($mock);
|
397 |
$mock->shouldReceive('login')->with('test', 'test')->andReturn(true);
|
|
|
398 |
$adapter->connect();
|
399 |
}
|
400 |
|
@@ -543,18 +561,16 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
543 |
'host' => 'example.org',
|
544 |
'username' => 'user',
|
545 |
'password' => '123456',
|
546 |
-
'hostFingerprint' =>
|
547 |
]);
|
548 |
|
549 |
$connection = Mockery::mock('phpseclib\Net\SFTP');
|
550 |
-
|
551 |
$connection->shouldReceive('getServerPublicHostKey')
|
552 |
-
->andReturn(
|
553 |
-
|
554 |
$connection->shouldReceive('login')
|
555 |
->with('user', '123456')
|
556 |
->andReturn(TRUE);
|
557 |
-
|
558 |
$connection->shouldReceive('disconnect');
|
559 |
|
560 |
$adapter->setNetSftpConnection($connection);
|
@@ -574,13 +590,11 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
574 |
|
575 |
$connection->shouldReceive('getServerPublicHostKey')
|
576 |
->never();
|
577 |
-
|
578 |
$connection->shouldReceive('login')
|
579 |
->with('user', '123456')
|
580 |
->andReturn(TRUE);
|
581 |
-
|
582 |
$connection->shouldReceive('disconnect');
|
583 |
-
|
584 |
$adapter->setNetSftpConnection($connection);
|
585 |
|
586 |
$adapter->connect();
|
@@ -602,11 +616,41 @@ class SftpTests extends PHPUnit_Framework_TestCase
|
|
602 |
$connection = Mockery::mock('phpseclib\Net\SFTP');
|
603 |
|
604 |
$connection->shouldReceive('getServerPublicHostKey')
|
605 |
-
->andReturn(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
|
607 |
$connection->shouldReceive('login')
|
608 |
->never();
|
609 |
|
|
|
610 |
$connection->shouldReceive('disconnect');
|
611 |
|
612 |
$adapter->setNetSftpConnection($connection);
|
5 |
use League\Flysystem\Sftp\SftpAdapter as Sftp;
|
6 |
use League\Flysystem\Sftp\SftpAdapter;
|
7 |
use phpseclib\System\SSH\Agent;
|
8 |
+
use PHPUnit\Framework\TestCase;
|
9 |
|
10 |
/**
|
11 |
* @covers \League\Flysystem\Sftp\SftpAdapter<extended>
|
12 |
*/
|
13 |
+
class SftpTests extends TestCase
|
14 |
{
|
15 |
+
const SSH_RSA = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD05PZTxeH6GPDyxLNv7UV05jcK+Y9P8kQnpEZRHOurJVSOB4k6JBXLQtgbffuy8bFYh6mZVx40f5Za0I9mCfPel/xnCu4F1cndZBY3Ww/12rmjYOHie7k9B3h1trJ1mDhXHuiRO6vfy81jMJ9dzJyCwOK9aFGEueQ8WuPMRt9/1g3awi1O0+YZ8gTLtjKbUXLT50/GksiWDFA6DwxjLR7jFEcuPUm/WpBIKMcsbxpjKmTNaCeuoKs9TcpTwg5E311nQfk0oficgyHP/x8m6mNH5q/zOMwaRjyC6LYyBXVJgSKsh7YFf+pRyHFGpWTWKnRKXWG13NLiEKb47SydLe77';
|
16 |
+
|
17 |
+
const SSH_RSA_FINGERPRINT = '88:76:75:96:c1:26:7c:dd:9f:87:50:db:ac:c4:a8:7c';
|
18 |
+
|
19 |
protected function setup()
|
20 |
{
|
21 |
if (! defined('NET_SFTP_TYPE_DIRECTORY')) {
|
144 |
*/
|
145 |
public function testSetVisibility($filesystem, $adapter, $mock)
|
146 |
{
|
147 |
+
$mock->shouldReceive('stat')->andReturn([
|
148 |
+
'type' => 1, // file
|
149 |
+
'mtime' => time(),
|
150 |
+
'size' => 20,
|
151 |
+
'permissions' => 0777,
|
152 |
+
]);
|
153 |
$mock->shouldReceive('chmod')->twice()->andReturn(true, false);
|
154 |
$this->assertTrue($filesystem->setVisibility('something', 'public'));
|
155 |
$this->assertFalse($filesystem->setVisibility('something', 'public'));
|
161 |
*/
|
162 |
public function testSetVisibilityInvalid($filesystem, $adapter, $mock)
|
163 |
{
|
164 |
+
$mock->shouldReceive('stat')->andReturn([
|
165 |
+
'type' => 1, // file
|
166 |
+
'mtime' => time(),
|
167 |
+
'size' => 20,
|
168 |
+
'permissions' => 0777,
|
169 |
+
]);
|
170 |
$mock->shouldReceive('stat')->once()->andReturn(true);
|
171 |
$filesystem->setVisibility('something', 'invalid');
|
172 |
}
|
412 |
{
|
413 |
$adapter->setNetSftpConnection($mock);
|
414 |
$mock->shouldReceive('login')->with('test', 'test')->andReturn(true);
|
415 |
+
$mock->shouldReceive('disableStatCache');
|
416 |
$adapter->connect();
|
417 |
}
|
418 |
|
561 |
'host' => 'example.org',
|
562 |
'username' => 'user',
|
563 |
'password' => '123456',
|
564 |
+
'hostFingerprint' => self::SSH_RSA_FINGERPRINT,
|
565 |
]);
|
566 |
|
567 |
$connection = Mockery::mock('phpseclib\Net\SFTP');
|
|
|
568 |
$connection->shouldReceive('getServerPublicHostKey')
|
569 |
+
->andReturn(self::SSH_RSA);
|
|
|
570 |
$connection->shouldReceive('login')
|
571 |
->with('user', '123456')
|
572 |
->andReturn(TRUE);
|
573 |
+
$connection->shouldReceive('disableStatCache');
|
574 |
$connection->shouldReceive('disconnect');
|
575 |
|
576 |
$adapter->setNetSftpConnection($connection);
|
590 |
|
591 |
$connection->shouldReceive('getServerPublicHostKey')
|
592 |
->never();
|
|
|
593 |
$connection->shouldReceive('login')
|
594 |
->with('user', '123456')
|
595 |
->andReturn(TRUE);
|
596 |
+
$connection->shouldReceive('disableStatCache');
|
597 |
$connection->shouldReceive('disconnect');
|
|
|
598 |
$adapter->setNetSftpConnection($connection);
|
599 |
|
600 |
$adapter->connect();
|
616 |
$connection = Mockery::mock('phpseclib\Net\SFTP');
|
617 |
|
618 |
$connection->shouldReceive('getServerPublicHostKey')
|
619 |
+
->andReturn(self::SSH_RSA);
|
620 |
+
|
621 |
+
$connection->shouldReceive('login')
|
622 |
+
->never();
|
623 |
+
|
624 |
+
$connection->shouldReceive('disableStatCache');
|
625 |
+
$connection->shouldReceive('disconnect');
|
626 |
+
|
627 |
+
$adapter->setNetSftpConnection($connection);
|
628 |
+
|
629 |
+
$adapter->connect();
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* @expectedException LogicException
|
634 |
+
* @expectedExceptionMessage Could not connect to server to verify public key.
|
635 |
+
*/
|
636 |
+
public function testCantConnectToCheckHostFingerprintAbortsLogin()
|
637 |
+
{
|
638 |
+
$adapter = new SftpAdapter([
|
639 |
+
'host' => 'example.org',
|
640 |
+
'username' => 'user',
|
641 |
+
'password' => '123456',
|
642 |
+
'hostFingerprint' => '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00',
|
643 |
+
]);
|
644 |
+
|
645 |
+
$connection = Mockery::mock('phpseclib\Net\SFTP');
|
646 |
+
|
647 |
+
$connection->shouldReceive('getServerPublicHostKey')
|
648 |
+
->andReturn(false); // getServerPublicHostKey returns false if it cant connect.
|
649 |
|
650 |
$connection->shouldReceive('login')
|
651 |
->never();
|
652 |
|
653 |
+
$connection->shouldReceive('disableStatCache');
|
654 |
$connection->shouldReceive('disconnect');
|
655 |
|
656 |
$adapter->setNetSftpConnection($connection);
|
vendor/league/flysystem/.travis.yml
CHANGED
@@ -10,6 +10,7 @@ php:
|
|
10 |
- 7.0
|
11 |
- 7.1
|
12 |
- 7.2
|
|
|
13 |
|
14 |
matrix:
|
15 |
allow_failures:
|
@@ -26,7 +27,6 @@ before_install:
|
|
26 |
|
27 |
install:
|
28 |
- if [[ "${TRAVIS_PHP_VERSION}" == "5.5" ]]; then composer require phpunit/phpunit:^4.8.36 phpspec/phpspec:^2 --prefer-dist --update-with-dependencies; fi
|
29 |
-
- if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require phpunit/phpunit:^6.0 --prefer-dist --update-with-dependencies; fi
|
30 |
- if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require --dev phpstan/phpstan:^0.9.2 --prefer-dist --update-with-dependencies; fi
|
31 |
- travis_retry composer update --prefer-dist $COMPOSER_OPTS
|
32 |
|
10 |
- 7.0
|
11 |
- 7.1
|
12 |
- 7.2
|
13 |
+
- 7.3
|
14 |
|
15 |
matrix:
|
16 |
allow_failures:
|
27 |
|
28 |
install:
|
29 |
- if [[ "${TRAVIS_PHP_VERSION}" == "5.5" ]]; then composer require phpunit/phpunit:^4.8.36 phpspec/phpspec:^2 --prefer-dist --update-with-dependencies; fi
|
|
|
30 |
- if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require --dev phpstan/phpstan:^0.9.2 --prefer-dist --update-with-dependencies; fi
|
31 |
- travis_retry composer update --prefer-dist $COMPOSER_OPTS
|
32 |
|
vendor/league/flysystem/README.md
CHANGED
@@ -62,7 +62,7 @@ Want to get started quickly? Check out some of these integrations:
|
|
62 |
### Officially Supported
|
63 |
* Amazon Web Services - S3 V2: https://github.com/thephpleague/flysystem-aws-s3-v2
|
64 |
* Amazon Web Services - S3 V3: https://github.com/thephpleague/flysystem-aws-s3-v3
|
65 |
-
* Azure Blob Storage: https://github.com/thephpleague/flysystem-azure
|
66 |
* Memory: https://github.com/thephpleague/flysystem-memory
|
67 |
* PHPCR: https://github.com/thephpleague/flysystem-phpcr
|
68 |
* Rackspace Cloud Files: https://github.com/thephpleague/flysystem-rackspace
|
@@ -73,6 +73,7 @@ Want to get started quickly? Check out some of these integrations:
|
|
73 |
### Community Supported
|
74 |
* AliYun OSS Storage: https://github.com/xxtime/flysystem-aliyun-oss
|
75 |
* Amazon Cloud Drive - https://github.com/nikkiii/flysystem-acd
|
|
|
76 |
* Backblaze: https://github.com/mhetreramesh/flysystem-backblaze
|
77 |
* ClamAV Scanner Adapter: https://github.com/mgriego/flysystem-clamav
|
78 |
* Citrix ShareFile: https://github.com/kapersoft/flysystem-sharefile
|
@@ -83,11 +84,13 @@ Want to get started quickly? Check out some of these integrations:
|
|
83 |
* Gaufrette: https://github.com/jenkoian/flysystem-gaufrette
|
84 |
* Google Cloud Storage: https://github.com/Superbalist/flysystem-google-storage
|
85 |
* Google Drive: https://github.com/nao-pon/flysystem-google-drive
|
|
|
86 |
* OneDrive: https://github.com/jacekbarecki/flysystem-onedrive
|
87 |
* OpenStack Swift: https://github.com/nimbusoftltd/flysystem-openstack-swift
|
88 |
* Redis (through Predis): https://github.com/danhunsaker/flysystem-redis
|
89 |
* Selectel Cloud Storage: https://github.com/ArgentCrusade/flysystem-selectel
|
90 |
* SinaAppEngine Storage: https://github.com/litp/flysystem-sae-storage
|
|
|
91 |
|
92 |
## Caching (https://github.com/thephpleague/flysystem-cached-adapter)
|
93 |
|
62 |
### Officially Supported
|
63 |
* Amazon Web Services - S3 V2: https://github.com/thephpleague/flysystem-aws-s3-v2
|
64 |
* Amazon Web Services - S3 V3: https://github.com/thephpleague/flysystem-aws-s3-v3
|
65 |
+
* Azure Blob Storage: https://github.com/thephpleague/flysystem-azure-blob-storage
|
66 |
* Memory: https://github.com/thephpleague/flysystem-memory
|
67 |
* PHPCR: https://github.com/thephpleague/flysystem-phpcr
|
68 |
* Rackspace Cloud Files: https://github.com/thephpleague/flysystem-rackspace
|
73 |
### Community Supported
|
74 |
* AliYun OSS Storage: https://github.com/xxtime/flysystem-aliyun-oss
|
75 |
* Amazon Cloud Drive - https://github.com/nikkiii/flysystem-acd
|
76 |
+
* Azure File Storage: https://github.com/academe/flysystem-azure-file-storage
|
77 |
* Backblaze: https://github.com/mhetreramesh/flysystem-backblaze
|
78 |
* ClamAV Scanner Adapter: https://github.com/mgriego/flysystem-clamav
|
79 |
* Citrix ShareFile: https://github.com/kapersoft/flysystem-sharefile
|
84 |
* Gaufrette: https://github.com/jenkoian/flysystem-gaufrette
|
85 |
* Google Cloud Storage: https://github.com/Superbalist/flysystem-google-storage
|
86 |
* Google Drive: https://github.com/nao-pon/flysystem-google-drive
|
87 |
+
* Google Drive V2 (using regular paths): https://github.com/masbug/flysystem-google-drive-ext
|
88 |
* OneDrive: https://github.com/jacekbarecki/flysystem-onedrive
|
89 |
* OpenStack Swift: https://github.com/nimbusoftltd/flysystem-openstack-swift
|
90 |
* Redis (through Predis): https://github.com/danhunsaker/flysystem-redis
|
91 |
* Selectel Cloud Storage: https://github.com/ArgentCrusade/flysystem-selectel
|
92 |
* SinaAppEngine Storage: https://github.com/litp/flysystem-sae-storage
|
93 |
+
* PDO Database: https://github.com/IntegralSoftware/flysystem-pdo-adapter
|
94 |
|
95 |
## Caching (https://github.com/thephpleague/flysystem-cached-adapter)
|
96 |
|
vendor/league/flysystem/changelog.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1 |
# Changelog
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
## 1.0.44 - 2018-04-06
|
4 |
|
5 |
* Added missing file presence checks on `Filesystem::setVisibility` and `Filesystem::getSize`.
|
1 |
# Changelog
|
2 |
|
3 |
+
## 1.0.49 - 2018-11-24
|
4 |
+
|
5 |
+
* It's my birthday today.
|
6 |
+
* Error message for directory creation in the Local adapter has a better description with more context.
|
7 |
+
|
8 |
+
## 1.0.48 - 2018-10-15
|
9 |
+
|
10 |
+
* The MountManager now implements the FilesystemInterface.
|
11 |
+
|
12 |
+
## 1.0.47 - 2018-09-14
|
13 |
+
|
14 |
+
* Specify mimetype for .epub files
|
15 |
+
|
16 |
+
## 1.0.46 - 2018-08-22
|
17 |
+
|
18 |
+
* Return failure when copying a stream does not work instead of relying only on fclose.
|
19 |
+
|
20 |
+
## 1.0.45 - 2018-05-07
|
21 |
+
|
22 |
+
* Fixed a regression in path-derived metadata fetching.
|
23 |
+
|
24 |
## 1.0.44 - 2018-04-06
|
25 |
|
26 |
* Added missing file presence checks on `Filesystem::setVisibility` and `Filesystem::getSize`.
|
vendor/league/flysystem/composer.json
CHANGED
@@ -14,12 +14,12 @@
|
|
14 |
}
|
15 |
],
|
16 |
"require": {
|
17 |
-
"php": ">=5.5.9"
|
|
|
18 |
},
|
19 |
"require-dev": {
|
20 |
-
"ext-fileinfo": "*",
|
21 |
"phpspec/phpspec": "^3.4",
|
22 |
-
"phpunit/phpunit": "^5.7"
|
23 |
},
|
24 |
"autoload": {
|
25 |
"psr-4": {
|
14 |
}
|
15 |
],
|
16 |
"require": {
|
17 |
+
"php": ">=5.5.9",
|
18 |
+
"ext-fileinfo": "*"
|
19 |
},
|
20 |
"require-dev": {
|
|
|
21 |
"phpspec/phpspec": "^3.4",
|
22 |
+
"phpunit/phpunit": "^5.7.10"
|
23 |
},
|
24 |
"autoload": {
|
25 |
"psr-4": {
|
vendor/league/flysystem/docs/_data/menu.yml
CHANGED
@@ -8,6 +8,7 @@ Usage:
|
|
8 |
Filesystem API: '/docs/usage/filesystem-api/'
|
9 |
|
10 |
Guides:
|
|
|
11 |
Deterministic Code: '/docs/guides/deterministic-programming/'
|
12 |
Handling Uploads: '/docs/guides/uploads/'
|
13 |
|
8 |
Filesystem API: '/docs/usage/filesystem-api/'
|
9 |
|
10 |
Guides:
|
11 |
+
Laravel Usage: '/docs/guides/laravel-usage/'
|
12 |
Deterministic Code: '/docs/guides/deterministic-programming/'
|
13 |
Handling Uploads: '/docs/guides/uploads/'
|
14 |
|
vendor/league/flysystem/docs/_data/project.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
title: "Flysystem"
|
2 |
tagline: "Many filesystems, one API."
|
3 |
description: "Filesystem abstraction library for PHP."
|
4 |
-
version: 1.0.
|
5 |
google_analytics_tracking_id: UA-114647967-1
|
1 |
title: "Flysystem"
|
2 |
tagline: "Many filesystems, one API."
|
3 |
description: "Filesystem abstraction library for PHP."
|
4 |
+
version: 1.0.45
|
5 |
google_analytics_tracking_id: UA-114647967-1
|
vendor/league/flysystem/docs/_includes/carbon.html
CHANGED
@@ -1 +1 @@
|
|
1 |
-
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?
|
1 |
+
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CK7DT2JE&placement=flysystemthephpleaguecom" id="_carbonads_js"></script>
|
vendor/league/flysystem/docs/_layouts/default.html
CHANGED
@@ -19,30 +19,30 @@
|
|
19 |
gtag('config', '{{ site.data.project.google_analytics_tracking_id }}');
|
20 |
</script>
|
21 |
{% endif %}
|
22 |
-
{% endunless %}
|
23 |
-
<!--<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />-->
|
24 |
-
<link rel="stylesheet" href="/dist/styles.css"/>
|
25 |
<base href="https://flysystem.thephpleague.com/" />
|
|
|
|
|
|
|
26 |
</head>
|
27 |
<body class="min-h-screen text-base text-indigo-body-text min-w-full pt-12 leading-normal bg-indigo-lightest">
|
28 |
-
|
29 |
<div class="pb-1 fixed z-10 pin-t w-screen bg-white border-indigo-lighter border-b">
|
30 |
<div class="max-w-2xl mx-auto px-4 py-2">
|
31 |
<div class="flex items-center flex-no-shrink pt-1">
|
32 |
<a href="/" class="flex items-center h-10">
|
33 |
<img class="h-10 w-10 mr-3" width="30" height="30" src="/img/flysystem.svg"/>
|
34 |
-
<span class="pr-2 font-normal overflow-hidden font-heading text-3xl text-indigo-darkest">
|
35 |
Flysystem
|
36 |
<sup class="text-xs relative text-indigo" style="top: -20px;">{{ site.data.project.version }}</sup>
|
37 |
</span>
|
38 |
</a>
|
39 |
<div class="flex-grow"></div>
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
<a href="#" id="menu-toggle" class="block md:hidden h-8 w-8 border p-1 border-transparent text-grey hover:text-grey menu-closed">
|
47 |
<svg class="menu-closed:shown fill-current h-full w-full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
48 |
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/>
|
@@ -87,13 +87,13 @@
|
|
87 |
|
88 |
</footer>
|
89 |
<script type="text/javascript" src="/dist/main.js"></script>
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
</body>
|
99 |
</html>
|
19 |
gtag('config', '{{ site.data.project.google_analytics_tracking_id }}');
|
20 |
</script>
|
21 |
{% endif %}
|
|
|
|
|
|
|
22 |
<base href="https://flysystem.thephpleague.com/" />
|
23 |
+
{% endunless %}
|
24 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
25 |
+
<link rel="stylesheet" href="/dist/styles.css?v=1.0"/>
|
26 |
</head>
|
27 |
<body class="min-h-screen text-base text-indigo-body-text min-w-full pt-12 leading-normal bg-indigo-lightest">
|
28 |
+
{% include size-helper.html %}
|
29 |
<div class="pb-1 fixed z-10 pin-t w-screen bg-white border-indigo-lighter border-b">
|
30 |
<div class="max-w-2xl mx-auto px-4 py-2">
|
31 |
<div class="flex items-center flex-no-shrink pt-1">
|
32 |
<a href="/" class="flex items-center h-10">
|
33 |
<img class="h-10 w-10 mr-3" width="30" height="30" src="/img/flysystem.svg"/>
|
34 |
+
<span class="pr-2 font-normal overflow-hidden font-heading text-3xl text-indigo-darkest -sm:hidden">
|
35 |
Flysystem
|
36 |
<sup class="text-xs relative text-indigo" style="top: -20px;">{{ site.data.project.version }}</sup>
|
37 |
</span>
|
38 |
</a>
|
39 |
<div class="flex-grow"></div>
|
40 |
+
<div class="flex-no-shrink flex-no-grow h-10 px-4 relative">
|
41 |
+
<input id="global-search" class="focus:outline-0 h-10 py-2 pl-8 pr-2 text-indigo-darker rounded bg-indigo-lightest focus:border-indigo-light focus:bg-white focus:placeholder-none max-w-xs w-full appearance-none" type="text" placeholder="Search the docs" />
|
42 |
+
<span class="pointer-events-none absolute pin-y pin-l pl-6 flex items-center">
|
43 |
+
<svg class="fill-current pointer-events-none text-indigo-light w-4 h-4 border-transparent border" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"/></svg>
|
44 |
+
</span>
|
45 |
+
</div>
|
46 |
<a href="#" id="menu-toggle" class="block md:hidden h-8 w-8 border p-1 border-transparent text-grey hover:text-grey menu-closed">
|
47 |
<svg class="menu-closed:shown fill-current h-full w-full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
48 |
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/>
|
87 |
|
88 |
</footer>
|
89 |
<script type="text/javascript" src="/dist/main.js"></script>
|
90 |
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
91 |
+
<script type="text/javascript"> docsearch({
|
92 |
+
apiKey: 'be7daf2d7afded0acb0589a0e304a423',
|
93 |
+
indexName: 'filesystem_thephpleague',
|
94 |
+
inputSelector: '#global-search',
|
95 |
+
debug: {% if site.data.dev.dev_mode %}true{% else %}false{% endif %}
|
96 |
+
});
|
97 |
+
</script>
|
98 |
</body>
|
99 |
</html>
|
vendor/league/flysystem/docs/adapter/azure.md
CHANGED
@@ -8,23 +8,29 @@ title: Azure Blob Storage
|
|
8 |
## Installation
|
9 |
|
10 |
```bash
|
11 |
-
composer require league/flysystem-azure
|
12 |
```
|
13 |
|
14 |
## Usage
|
15 |
|
16 |
```php
|
17 |
-
use
|
18 |
use League\Flysystem\Filesystem;
|
19 |
-
use
|
20 |
|
21 |
-
|
22 |
-
'DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s',
|
23 |
-
'account-name',
|
24 |
-
'api-key'
|
25 |
-
);
|
26 |
|
27 |
-
$
|
28 |
-
|
29 |
-
$filesystem = new Filesystem(
|
|
|
30 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
## Installation
|
9 |
|
10 |
```bash
|
11 |
+
composer require league/flysystem-azure-blob-storage
|
12 |
```
|
13 |
|
14 |
## Usage
|
15 |
|
16 |
```php
|
17 |
+
use League\Flysystem\AzureBlobStorage\AzureBlobStorageAdapter;
|
18 |
use League\Flysystem\Filesystem;
|
19 |
+
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
|
20 |
|
21 |
+
include __DIR__.'/vendor/autoload.php';
|
|
|
|
|
|
|
|
|
22 |
|
23 |
+
$client = BlobRestProxy::createBlobService('DefaultEndpointsProtocol=https;AccountName={YOUR_ACCOUNT_NAME};AccountKey={YOUR_ACCOUNT_KEY};');
|
24 |
+
$adapter = new AzureBlobStorageAdapter($client, 'container_name');
|
25 |
+
$filesystem = new Filesystem($adapter);
|
26 |
+
var_dump($filesystem->listContents());
|
27 |
```
|
28 |
+
|
29 |
+
## Sponsored by:
|
30 |
+
|
31 |
+
<div class="flex my-6">
|
32 |
+
<a target="_blank" href="https://azure.microsoft.com/free/?utm_source=flysystem&utm_medium=banner&utm_campaign=flysystem_sponsorship" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
33 |
+
<img src="/img/azure.svg" class="max-w-full m-6 sm:m-8" alt="Azure.com"/>
|
34 |
+
<span style="background-color: #00a1f1;" class="text-center text-xl hidden sm:block py-4 bg-indigo-dark text-white bg-grey-lightest">Azure.com</span>
|
35 |
+
</a>
|
36 |
+
</div>
|
vendor/league/flysystem/docs/adapter/phpcr.md
CHANGED
@@ -40,9 +40,25 @@ $factory = new RepositoryFactoryDoctrineDBAL();
|
|
40 |
$repository = $factory->getRepository([
|
41 |
'jackalope.doctrine_dbal_connection' => $connection,
|
42 |
]);
|
43 |
-
$session = $repository->login(new SimpleCredentials('', ''));
|
|
|
|
|
|
|
44 |
|
45 |
// this part looks the same regardless of your phpcr implementation.
|
46 |
$root = '/flysystem_tests';
|
47 |
$filesystem = new Filesystem(new PhpcrAdapter($session, $root));
|
48 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
$repository = $factory->getRepository([
|
41 |
'jackalope.doctrine_dbal_connection' => $connection,
|
42 |
]);
|
43 |
+
$session = $repository->login(new SimpleCredentials('username', 'password'));
|
44 |
+
|
45 |
+
//Or when no credentials are required
|
46 |
+
$session = $repository->login();
|
47 |
|
48 |
// this part looks the same regardless of your phpcr implementation.
|
49 |
$root = '/flysystem_tests';
|
50 |
$filesystem = new Filesystem(new PhpcrAdapter($session, $root));
|
51 |
```
|
52 |
+
|
53 |
+
### Indicate specific modification timestamp when writing content
|
54 |
+
By default PHPCR will use the current system time as the "last modified" timestamp of an entry when writing content. A specific timestamp can be provided by using the configuration array:
|
55 |
+
|
56 |
+
```php
|
57 |
+
$path = '/path/to/file.ext';
|
58 |
+
$content = file_get_contents($path);
|
59 |
+
$config = ['timestamp' => filemtime($path)]; //Use the time when the content of the file was last changed.
|
60 |
+
|
61 |
+
$filesystem->write($path, $content, $config);
|
62 |
+
```
|
63 |
+
|
64 |
+
This can be useful when the file timestamp needs to be preserved when copying a file structure to PHPCR.
|
vendor/league/flysystem/docs/adapter/sftp.md
CHANGED
@@ -19,7 +19,7 @@ use League\Flysystem\Sftp\SftpAdapter;
|
|
19 |
|
20 |
$filesystem = new Filesystem(new SftpAdapter([
|
21 |
'host' => 'example.com',
|
22 |
-
'port' =>
|
23 |
'username' => 'username',
|
24 |
'password' => 'password',
|
25 |
'privateKey' => 'path/to/or/contents/of/privatekey',
|
19 |
|
20 |
$filesystem = new Filesystem(new SftpAdapter([
|
21 |
'host' => 'example.com',
|
22 |
+
'port' => 22,
|
23 |
'username' => 'username',
|
24 |
'password' => 'password',
|
25 |
'privateKey' => 'path/to/or/contents/of/privatekey',
|
vendor/league/flysystem/docs/advanced/caching.md
CHANGED
@@ -5,7 +5,7 @@ title: Caching
|
|
5 |
---
|
6 |
|
7 |
File system I/O is slow, so Flysystem uses cached file system meta-data to boost performance. When your application needs to scale you can also choose to use a (shared) persistent caching solution for this.
|
8 |
-
Or enable
|
9 |
|
10 |
## Installing the adapter cache decorator
|
11 |
|
5 |
---
|
6 |
|
7 |
File system I/O is slow, so Flysystem uses cached file system meta-data to boost performance. When your application needs to scale you can also choose to use a (shared) persistent caching solution for this.
|
8 |
+
Or enable per request caching (recommended).
|
9 |
|
10 |
## Installing the adapter cache decorator
|
11 |
|
vendor/league/flysystem/docs/advanced/mount-manager.md
CHANGED
@@ -60,7 +60,7 @@ foreach ($contents as $entry) {
|
|
60 |
### Copy
|
61 |
|
62 |
The copy method provided by the Mount Manager takes the origin of the file into account.
|
63 |
-
When it detects the source and destination are located on
|
64 |
use a streamed upload instead, transparently.
|
65 |
|
66 |
```php
|
@@ -70,7 +70,7 @@ $mountManager->copy('local://some/file.ext', 'backup://storage/location.ext');
|
|
70 |
### Move
|
71 |
|
72 |
The `move` call is the multi-file system counterpart to `rename`. Where rename must be used on
|
73 |
-
the same file system, the `move` call provides the same conceptual behavior, but
|
74 |
different file systems.
|
75 |
|
76 |
```php
|
60 |
### Copy
|
61 |
|
62 |
The copy method provided by the Mount Manager takes the origin of the file into account.
|
63 |
+
When it detects the source and destination are located on different file systems it'll
|
64 |
use a streamed upload instead, transparently.
|
65 |
|
66 |
```php
|
70 |
### Move
|
71 |
|
72 |
The `move` call is the multi-file system counterpart to `rename`. Where rename must be used on
|
73 |
+
the same file system, the `move` call provides the same conceptual behavior, but on two
|
74 |
different file systems.
|
75 |
|
76 |
```php
|
vendor/league/flysystem/docs/advanced/performance.md
CHANGED
@@ -5,7 +5,7 @@ title: Performance
|
|
5 |
---
|
6 |
|
7 |
Flysystem aims to be as reliable as possible. In some cases this means doing extra
|
8 |
-
checks to make sure the outcome will be as expected. For some
|
9 |
will make extra calls to assert whether or not a file exists. This improves the reliability
|
10 |
but also impacts performance. You can opt out of this behaviour.
|
11 |
|
5 |
---
|
6 |
|
7 |
Flysystem aims to be as reliable as possible. In some cases this means doing extra
|
8 |
+
checks to make sure the outcome will be as expected. For some adapters this means Flysystem
|
9 |
will make extra calls to assert whether or not a file exists. This improves the reliability
|
10 |
but also impacts performance. You can opt out of this behaviour.
|
11 |
|
vendor/league/flysystem/docs/advanced/provided-plugins.md
CHANGED
@@ -31,7 +31,7 @@ foreach ($listing as $object) {
|
|
31 |
}
|
32 |
```
|
33 |
|
34 |
-
## Get file
|
35 |
|
36 |
This requires the `League\Flysystem\Plugin\GetWithMetadata` plugin.
|
37 |
|
31 |
}
|
32 |
```
|
33 |
|
34 |
+
## Get file info with explicit metadata.
|
35 |
|
36 |
This requires the `League\Flysystem\Plugin\GetWithMetadata` plugin.
|
37 |
|
vendor/league/flysystem/docs/advanced/upgrade-to-1.0.0.md
CHANGED
@@ -52,7 +52,7 @@ $filesystem = new Filesystem($decoratedAdapter);
|
|
52 |
|
53 |
## Helper Methods
|
54 |
|
55 |
-
In order to clean up the
|
56 |
|
57 |
* ListWith
|
58 |
* ListPaths
|
52 |
|
53 |
## Helper Methods
|
54 |
|
55 |
+
In order to clean up the Filesystem class, some helper functions have been moved to plugins.
|
56 |
|
57 |
* ListWith
|
58 |
* ListPaths
|
vendor/league/flysystem/docs/api.md
CHANGED
@@ -182,7 +182,7 @@ foreach ($listing as $object) {
|
|
182 |
}
|
183 |
~~~
|
184 |
|
185 |
-
__Get file
|
186 |
|
187 |
~~~ php
|
188 |
$info = $filesystem->getWithMetadata('path/to/file.txt', ['timestamp', 'mimetype']);
|
@@ -200,10 +200,10 @@ Some SDK's close streams after consuming them, therefore, before calling fclose
|
|
200 |
|
201 |
~~~ php
|
202 |
$stream = fopen('/path/to/database.backup', 'r+');
|
203 |
-
$filesystem->writeStream('backups/'.strftime('%
|
204 |
|
205 |
// Using write you can also directly set the visibility
|
206 |
-
$filesystem->writeStream('backups/'.strftime('%
|
207 |
'visibility' => AdapterInterface::VISIBILITY_PRIVATE
|
208 |
]);
|
209 |
|
@@ -212,7 +212,7 @@ if (is_resource($stream)) {
|
|
212 |
}
|
213 |
|
214 |
// Or update a file with stream contents
|
215 |
-
$filesystem->updateStream('backups/'.strftime('%
|
216 |
|
217 |
// Retrieve a read-stream
|
218 |
$stream = $filesystem->readStream('something/is/here.ext');
|
182 |
}
|
183 |
~~~
|
184 |
|
185 |
+
__Get file info with explicit metadata__
|
186 |
|
187 |
~~~ php
|
188 |
$info = $filesystem->getWithMetadata('path/to/file.txt', ['timestamp', 'mimetype']);
|
200 |
|
201 |
~~~ php
|
202 |
$stream = fopen('/path/to/database.backup', 'r+');
|
203 |
+
$filesystem->writeStream('backups/'.strftime('%Y-%m-%d').'.backup', $stream);
|
204 |
|
205 |
// Using write you can also directly set the visibility
|
206 |
+
$filesystem->writeStream('backups/'.strftime('%Y-%m-%d').'.backup', $stream, [
|
207 |
'visibility' => AdapterInterface::VISIBILITY_PRIVATE
|
208 |
]);
|
209 |
|
212 |
}
|
213 |
|
214 |
// Or update a file with stream contents
|
215 |
+
$filesystem->updateStream('backups/'.strftime('%Y-%m-%d').'.backup', $stream);
|
216 |
|
217 |
// Retrieve a read-stream
|
218 |
$stream = $filesystem->readStream('something/is/here.ext');
|
vendor/league/flysystem/docs/architecture.md
CHANGED
@@ -30,4 +30,4 @@ timestamp | modified time | `integer`
|
|
30 |
In order to make the most out of every (expensive) filesystem call adapters
|
31 |
return as much information as they can when/if available. This makes it possible
|
32 |
for caching mechanisms to store this information so subsequent calls can be
|
33 |
-
returned from cache without the need for additional
|
30 |
In order to make the most out of every (expensive) filesystem call adapters
|
31 |
return as much information as they can when/if available. This makes it possible
|
32 |
for caching mechanisms to store this information so subsequent calls can be
|
33 |
+
returned from cache without the need for additional filesystem calls.
|
vendor/league/flysystem/docs/dist/styles.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700|Open+Sans:400,400i,600);/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box;font-family:Open Sans,sans-serif;font-weight:400;-webkit-font-smoothing:antialiased}body{margin:0}article,footer,main,menu,nav,section{display:block}h1{font-size:2em}hr{box-sizing:content-box;height:0;overflow:visible;border-bottom-width:1px;border-top-width:1px;opacity:.75;width:50%;margin:3.5rem auto 2rem;border-color:#d9dff1 #d9dff1 #fff}code,pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects;text-decoration:none;color:#4764bd}strong{font-weight:bolder}small{font-size:80%}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-.5em}img{border-style:solid;max-width:100%}svg:not(:root){overflow:hidden}input,select{font-size:100%;line-height:1.15;margin:0}input{overflow:visible}select{text-transform:none}[type=reset],[type=submit],html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}[hidden]{display:none}*,:after,:before{box-sizing:inherit;border:0 solid #dae1e7}blockquote,h1,h2,h3,p,pre,ul{margin:0}[tabindex="-1"]:focus{outline:0!important}[type=button],[type=reset],[type=submit]{border-radius:0}input,select{font-family:inherit}input::placeholder{color:inherit;opacity:.5}[role=button]{cursor:pointer}div.highlighter-rouge{font-family:Courier,monospace;background-color:#fff;padding:.5rem 1rem;margin-left:-1rem;margin-right:-1rem;margin-bottom:1rem;box-shadow:0 2px 4px 0 rgba(0,0,0,.1);display:block}div.highlighter-rouge>div{overflow
|
1 |
+
@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700|Open+Sans:400,400i,600);/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box;font-family:Open Sans,sans-serif;font-weight:400;-webkit-font-smoothing:antialiased}body{margin:0}article,footer,main,menu,nav,section{display:block}h1{font-size:2em}hr{box-sizing:content-box;height:0;overflow:visible;border-bottom-width:1px;border-top-width:1px;opacity:.75;width:50%;margin:3.5rem auto 2rem;border-color:#d9dff1 #d9dff1 #fff}code,pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects;text-decoration:none;color:#4764bd}strong{font-weight:bolder}small{font-size:80%}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-.5em}img{border-style:solid;max-width:100%}svg:not(:root){overflow:hidden}input,select{font-size:100%;line-height:1.15;margin:0}input{overflow:visible}select{text-transform:none}[type=reset],[type=submit],html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}[hidden]{display:none}*,:after,:before{box-sizing:inherit;border:0 solid #dae1e7}blockquote,h1,h2,h3,p,pre,ul{margin:0}[tabindex="-1"]:focus{outline:0!important}[type=button],[type=reset],[type=submit]{border-radius:0}input,select{font-family:inherit}input::placeholder{color:inherit;opacity:.5}[role=button]{cursor:pointer}div.highlighter-rouge{font-family:Courier,monospace;background-color:#fff;padding:.5rem 1rem;margin-left:-1rem;margin-right:-1rem;margin-bottom:1rem;box-shadow:0 2px 4px 0 rgba(0,0,0,.1);display:block}div.highlighter-rouge>div{overflow:auto;width:100%}@media (min-width:768px){div.highlighter-rouge{margin-left:0;margin-right:0}}code.highlighter-rouge{font-family:Courier,monospace;text-shadow:1px 1px 0 #fff,-1px 1px 0 #fff;font-size:1.125rem}@media (min-width:768px){.highlighter-rouge{margin-left:0;margin-right:0}}div.highlighter-rouge.language-bash{background-color:#4764bd;color:#fff;box-shadow:inset 0 4px 8px 0 rgba(0,0,0,.08),inset 0 2px 4px 0 rgba(0,0,0,.12);text-shadow:1px 1px 2px #253461,-1px 1px 2px #253461}.highlight .cp,.highlight .k,.highlight .o{font-weight:700}.highlight .cp{color:#999}.highlight .c1{color:#998;font-style:italic}.highlight .go{color:#888}.highlight .gt{color:#a00}.highlight .kc{font-weight:700}.highlight .s{color:#d14}.highlight .na{color:teal}.highlight .nb{color:#0086b3}.highlight .nc{color:#458;font-weight:700}.highlight .no{color:teal}.highlight .nf{color:#900;font-weight:700}.highlight .nv{color:teal}.highlight .w{color:#bbb}.highlight .mi,.highlight .mo{color:#099}.highlight .s1,.highlight .s2,.highlight .sd,.highlight .si{color:#d14}.algolia-autocomplete{width:100%!important}@media (max-width:768px){.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{max-width:calc(100vw - 2rem)!important;width:calc(100vw - 2rem)!important;min-width:0!important;margin-left:16px!important;right:-3rem!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:58px}.algolia-autocomplete .algolia-docsearch-suggestion--content{width:100%!important;padding-left:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--content:before,.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{display:none!important}}.container{width:100%}@media (min-width:576px){.container{max-width:576px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:992px){.container{max-width:992px}}@media (min-width:1200px){.container{max-width:1200px}}.list-reset{list-style:none;padding:0}.appearance-none{appearance:none}.bg-black{background-color:#22292f}.bg-grey-lightest{background-color:#f8fafc}.bg-white{background-color:#fff}.bg-indigo-darkest{background-color:#253461}.bg-indigo-dark{background-color:#4764bd}.bg-indigo{background-color:#637fd6}.bg-indigo-light{background-color:#acbdf1}.bg-indigo-lightest{background-color:#f7f9fe}.border-transparent{border-color:transparent}.border-indigo-lighter{border-color:#d9dff1}.rounded{border-radius:.25rem}.rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.rounded-br{border-bottom-right-radius:.25rem}.border{border-width:1px}.border-b{border-bottom-width:1px}#carbonads>span,.block,.carbon-img img{display:block}.inline-block{display:inline-block}.table{display:table}.hidden{display:none}.flex{display:flex}.items-center{align-items:center}.flex-grow{flex-grow:1}.flex-no-grow{flex-grow:0}.flex-no-shrink{flex-shrink:0}.font-heading{font-family:Lato,sans-serif}.font-normal{font-weight:400}.h-4{height:1rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-full{height:100%}.leading-normal{line-height:1.75}.leading-loose{line-height:2}.m-6{margin:1.5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-0{margin-top:0}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mb-4,p,ul{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.max-w-xs{max-width:20rem}.max-w-sm{max-width:30rem}.max-w-2xl{max-width:66rem}.max-w-full{max-width:100%}.min-h-screen{min-height:100vh}.min-w-full{min-width:100%}.-ml-2{margin-left:-.5rem}.opacity-50{opacity:.5}.overflow-hidden{overflow:hidden}.p-1{padding:.25rem}.p-2{padding:.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.pl-0{padding-left:0}.pt-1{padding-top:.25rem}.pb-1{padding-bottom:.25rem}.pt-2{padding-top:.5rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pt-4{padding-top:1rem}.pr-6{padding-right:1.5rem}.pl-6{padding-left:1.5rem}.pl-8{padding-left:2rem}.pt-12{padding-top:4rem}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.pin-y{top:0;bottom:0}.pin-t{top:0}.pin-l{left:0}.shadow-md{box-shadow:0 4px 8px 0 rgba(0,0,0,.12),0 2px 4px 0 rgba(0,0,0,.08)}.fill-current{fill:currentColor}.text-center{text-align:center}.hover\:text-grey:hover,.text-grey{color:#b8c2cc}.text-white{color:#fff}.text-indigo-darkest{color:#253461}.text-indigo-body-text{color:#535e7e}.text-indigo-darker{color:#2a3f7d}.text-indigo-dark{color:#4764bd}.text-indigo{color:#637fd6}.text-indigo-light{color:#acbdf1}.text-xs{font-size:.75rem}.text-base{font-size:1rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-3xl{font-size:1.875rem}.uppercase{text-transform:uppercase}.tracking-wide{letter-spacing:.05em}.w-4{width:1rem}.w-8{width:2rem}.w-10{width:2.5rem}.w-1\/3{width:33.33333%}.w-1\/4{width:25%}.w-full{width:100%}.w-screen{width:100vw}.z-10{z-index:1}.z-50{z-index:2}:focus{outline:0}h1,h2,h3{font-family:Lato,sans-serif;line-height:1.25;color:#253461}.focus\:placeholder-none:focus::placeholder{opacity:0}article table{text-align:left;padding:1rem;background-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12),0 2px 4px 0 rgba(0,0,0,.08);margin-left:-1rem;margin-right:-1rem;border-spacing:0;border-collapse:collapse;margin-bottom:1.5rem;padding:0;width:calc(100% + 2rem);overflow:auto}@media (min-width:768px){article table{display:table;width:100%;margin-left:0;margin-right:0}}div.highlighter-rouge+table{margin-top:-1rem;border-top-width:4px;border-color:#4764bd}article table td{vertical-align:top;border-top-width:1px;border-color:#d9dff1;padding:.5rem 1rem}article table th{padding:.5rem 1rem;background-color:#637fd6;color:#fff;font-weight:700}div.highlighter-rouge+table th{color:#637fd6;background-color:#fff}.menu-closed .menu-closed\:shown{display:inline}.menu-closed .menu-closed\:hidden,.menu-closed\:shown{display:none}#carbonads{position:relative;text-shadow:1px 1px 0 hsla(0,0%,100%,.5);background:#fff;max-width:340px;line-height:1.75;font-size:.8rem;color:#3d4852;padding:.5rem;margin-bottom:1rem;background-color:#dae1e7;border-radius:.25rem;box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06);display:inline-block}.carbon-text{padding-left:.5rem;padding-bottom:1rem;line-height:1.75;color:#fff}#carbonads a{color:inherit}.carbon-wrap{display:flex;align-items:start}.carbon-img{flex-grow:0;flex-shrink:0}.carbon-poweredby{position:absolute;left:calc(130px + 1rem);bottom:0;opacity:.75;padding-bottom:.5rem}@media (max-width:576px){.-sm\:hidden{display:none}}@media (min-width:576px){.sm\:block{display:block}.sm\:hidden{display:none}.sm\:m-8{margin:2rem}}@media (min-width:576px) and (max-width:768px){.sm-md\:block{display:block}}@media (min-width:768px){.md\:block{display:block}.md\:hidden{display:none}.md\:w-4\/14{width:28.57143%}.md\:w-10\/14{width:71.42857%}}@media (min-width:768px) and (max-width:992px){.md-lg\:block{display:block}}@media (min-width:992px){.lg\:relative{position:relative}}@media (min-width:992px) and (max-width:1200px){.lg-xl\:block{display:block}}@media (min-width:1200px){.xl\:block{display:block}}
|
vendor/league/flysystem/docs/github.css
CHANGED
@@ -9,7 +9,7 @@ div.highlighter-rouge {
|
|
9 |
}
|
10 |
|
11 |
div.highlighter-rouge > div {
|
12 |
-
@apply overflow-
|
13 |
}
|
14 |
|
15 |
@screen md {
|
@@ -96,4 +96,4 @@ div.highlighter-rouge.language-bash {
|
|
96 |
.highlight .vg { color: teal; }
|
97 |
.highlight .vi { color: teal; }
|
98 |
.highlight .il { color: #009999; }
|
99 |
-
.highlight .gc { color: #999; background-color: #EAF2F5; }
|
9 |
}
|
10 |
|
11 |
div.highlighter-rouge > div {
|
12 |
+
@apply overflow-auto w-full;
|
13 |
}
|
14 |
|
15 |
@screen md {
|
96 |
.highlight .vg { color: teal; }
|
97 |
.highlight .vi { color: teal; }
|
98 |
.highlight .il { color: #009999; }
|
99 |
+
.highlight .gc { color: #999; background-color: #EAF2F5; }
|
vendor/league/flysystem/docs/guides/deterministic-programming.md
CHANGED
@@ -12,7 +12,7 @@ problematic.
|
|
12 |
|
13 |
## Filesystems are slow.
|
14 |
|
15 |
-
In general, filesystem interaction is slow. Every operation
|
16 |
hits the disc in one way or another is slow. While some operations absolutely
|
17 |
require filesystem interaction, there's a number of cases where filesystem
|
18 |
operations can be prevented in order to eliminate the associated penalties.
|
@@ -66,6 +66,6 @@ you can store all the paths in a persistent database. While this is
|
|
66 |
not a conventional thing to do it certainly has a lot of benefits.
|
67 |
|
68 |
File listings are just a select statement: `SELECT * FROM files WHERE path LIKE '/prefix/%'`.
|
69 |
-
Listings can easily be sorted. File existence checks are
|
70 |
File migrations become really easy, even when your path generation
|
71 |
-
strategy changes. Metadata can be
|
12 |
|
13 |
## Filesystems are slow.
|
14 |
|
15 |
+
In general, filesystem interaction is slow. Every operation that
|
16 |
hits the disc in one way or another is slow. While some operations absolutely
|
17 |
require filesystem interaction, there's a number of cases where filesystem
|
18 |
operations can be prevented in order to eliminate the associated penalties.
|
66 |
not a conventional thing to do it certainly has a lot of benefits.
|
67 |
|
68 |
File listings are just a select statement: `SELECT * FROM files WHERE path LIKE '/prefix/%'`.
|
69 |
+
Listings can easily be sorted. File existence checks are inexpensive.
|
70 |
File migrations become really easy, even when your path generation
|
71 |
+
strategy changes. Metadata can be stored alongside your path.
|
vendor/league/flysystem/docs/img/azure.svg
CHANGED
@@ -1 +1,69 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
4 |
+
viewBox="0 0 283.5 283.5" style="enable-background:new 0 0 283.5 283.5;" xml:space="preserve">
|
5 |
+
<style type="text/css">
|
6 |
+
.st0{fill:#737373;}
|
7 |
+
.st1{fill:#F25022;}
|
8 |
+
.st2{fill:#7FBA00;}
|
9 |
+
.st3{fill:#00A4EF;}
|
10 |
+
.st4{fill:#FFB900;}
|
11 |
+
</style>
|
12 |
+
<g id="Azure_s">
|
13 |
+
<g>
|
14 |
+
<path class="st0" d="M118.8,147.7l11.4,30.3h-5.8l-2.7-7.5h-11.9l-2.6,7.5h-5.8l11.4-30.3H118.8z M115.6,153.3l-4.5,12.8h9.1
|
15 |
+
L115.6,153.3L115.6,153.3z"/>
|
16 |
+
<path class="st0" d="M132.7,156.3h17.4v2.1L138.7,174h11.5v4.1H132v-2.4l11.2-15.2h-10.4v-4.2L132.7,156.3L132.7,156.3z"/>
|
17 |
+
<path class="st0" d="M171.9,156.3V178h-5.2v-2.9h-0.1c-0.7,1-1.6,1.8-2.7,2.3c-1.1,0.6-2.4,0.8-3.8,0.8c-2.5,0-4.4-0.7-5.8-2.1
|
18 |
+
c-1.3-1.4-2-3.7-2-6.7v-13.2h5.2v12.6c0,1.8,0.4,3.2,1.1,4.1c0.7,0.9,1.8,1.4,3.3,1.4s2.6-0.5,3.5-1.5s1.3-2.4,1.3-4v-12.6
|
19 |
+
L171.9,156.3L171.9,156.3z"/>
|
20 |
+
<path class="st0" d="M187.3,155.9c0.4,0,0.8,0,1.1,0.1s0.6,0.1,0.8,0.2v5.2c-0.3-0.2-0.7-0.4-1.2-0.6c-0.5-0.2-1.1-0.3-1.9-0.3
|
21 |
+
c-1.3,0-2.3,0.5-3.2,1.6s-1.3,2.7-1.3,4.9v11h-5.1v-21.7h5.1v3.4h0.1c0.5-1.2,1.2-2.1,2.1-2.8C184.9,156.3,186,155.9,187.3,155.9z
|
22 |
+
"/>
|
23 |
+
<path class="st0" d="M207.7,172.5v4.2c-0.8,0.5-2,1-3.3,1.3c-1.4,0.3-2.8,0.5-4.4,0.5c-3.3,0-5.9-1-7.7-2.9s-2.8-4.7-2.8-8.2
|
24 |
+
c0-3.4,1-6.1,2.9-8.3s4.5-3.3,7.5-3.3s5.3,0.9,7,2.8c1.7,1.8,2.5,4.4,2.5,7.6v2.5h-14.9c0.2,2.2,0.9,3.7,2.1,4.6
|
25 |
+
c1.2,0.9,2.7,1.3,4.6,1.3c1.2,0,2.4-0.2,3.5-0.6C205.8,173.6,206.8,173.1,207.7,172.5z M204.4,164.9c0-1.7-0.4-3-1.2-3.9
|
26 |
+
s-1.9-1.3-3.3-1.3c-1.2,0-2.3,0.4-3.3,1.3s-1.6,2.2-1.9,3.9H204.4z"/>
|
27 |
+
</g>
|
28 |
+
</g>
|
29 |
+
<g id="MS-logotype">
|
30 |
+
<path class="st0" d="M136,106v30.3h-5.3v-23.8h-0.1l-9.4,23.8h-3.5l-9.6-23.8H108v23.8h-4.9V106h7.5l8.7,22.5h0.1l9.2-22.5H136z
|
31 |
+
M140.4,108.3c0-0.8,0.3-1.6,0.9-2.1c0.6-0.6,1.3-0.9,2.2-0.9s1.6,0.3,2.2,0.9c0.6,0.6,0.9,1.3,0.9,2.1c0,0.8-0.3,1.5-0.9,2.1
|
32 |
+
c-0.6,0.6-1.3,0.8-2.2,0.8s-1.6-0.3-2.2-0.9C140.7,109.8,140.4,109.1,140.4,108.3z M146.1,114.6v21.7H141v-21.7
|
33 |
+
C141,114.6,146.1,114.6,146.1,114.6z M161.6,132.6c0.8,0,1.6-0.2,2.5-0.5c0.9-0.4,1.8-0.8,2.5-1.4v4.8c-0.8,0.5-1.7,0.8-2.8,1.1
|
34 |
+
c-1,0.2-2.2,0.4-3.4,0.4c-3.2,0-5.8-1-7.8-3s-3-4.6-3-7.7c0-3.5,1-6.4,3.1-8.6c2-2.3,4.9-3.4,8.7-3.4c1,0,1.9,0.1,2.9,0.4
|
35 |
+
c1,0.2,1.8,0.5,2.3,0.9v4.9c-0.8-0.6-1.6-1-2.4-1.3c-0.8-0.3-1.7-0.5-2.5-0.5c-2,0-3.6,0.7-4.9,2c-1.2,1.3-1.9,3.1-1.9,5.3
|
36 |
+
s0.6,3.9,1.8,5.1C157.9,132,159.6,132.6,161.6,132.6z M181.2,114.2c0.4,0,0.8,0,1.1,0.1s0.6,0.1,0.8,0.2v5.2
|
37 |
+
c-0.3-0.2-0.7-0.4-1.2-0.6s-1.1-0.3-1.9-0.3c-1.3,0-2.3,0.5-3.2,1.6s-1.3,2.7-1.3,4.9v11h-5.1v-21.7h5.1v3.4h0.1
|
38 |
+
c0.5-1.2,1.2-2.1,2.1-2.8C178.8,114.6,179.9,114.2,181.2,114.2z M183.4,125.8c0-3.6,1-6.4,3-8.5s4.8-3.2,8.5-3.2c3.4,0,6.1,1,8,3
|
39 |
+
s2.9,4.8,2.9,8.2c0,3.5-1,6.3-3,8.4c-2,2.1-4.8,3.1-8.3,3.1c-3.4,0-6-1-8-3C184.4,131.9,183.4,129.2,183.4,125.8z M188.8,125.6
|
40 |
+
c0,2.3,0.5,4,1.5,5.2s2.5,1.8,4.4,1.8s3.3-0.6,4.2-1.8c1-1.2,1.5-3,1.5-5.3s-0.5-4.1-1.5-5.3c-1-1.2-2.4-1.8-4.2-1.8
|
41 |
+
c-1.9,0-3.3,0.6-4.4,1.9C189.3,121.5,188.8,123.3,188.8,125.6z M213.4,120.3c0,0.7,0.2,1.3,0.7,1.7c0.5,0.4,1.5,0.9,3.1,1.6
|
42 |
+
c2,0.8,3.5,1.7,4.3,2.8c0.8,1,1.2,2.3,1.2,3.7c0,2-0.8,3.7-2.4,4.9c-1.6,1.2-3.7,1.9-6.4,1.9c-0.9,0-1.9-0.1-3-0.3s-2-0.5-2.8-0.8
|
43 |
+
v-5c0.9,0.6,1.9,1.2,3,1.5c1.1,0.4,2,0.6,2.9,0.6c1.2,0,2-0.2,2.6-0.5s0.8-0.9,0.8-1.6c0-0.7-0.3-1.3-0.9-1.8s-1.7-1-3.2-1.7
|
44 |
+
c-1.9-0.8-3.2-1.7-4-2.7s-1.2-2.2-1.2-3.8c0-2,0.8-3.6,2.3-4.8c1.6-1.3,3.6-1.9,6.1-1.9c0.8,0,1.6,0.1,2.6,0.3
|
45 |
+
c0.9,0.2,1.7,0.4,2.4,0.7v4.9c-0.7-0.5-1.5-0.8-2.4-1.2c-0.9-0.3-1.8-0.5-2.7-0.5c-1,0-1.7,0.2-2.3,0.6
|
46 |
+
C213.6,119.1,213.4,119.6,213.4,120.3z M224.9,125.8c0-3.6,1-6.4,3-8.5s4.8-3.2,8.5-3.2c3.4,0,6.1,1,8,3s2.9,4.8,2.9,8.2
|
47 |
+
c0,3.5-1,6.3-3,8.4c-2,2.1-4.8,3.1-8.3,3.1c-3.4,0-6-1-8-3C225.9,131.9,224.9,129.2,224.9,125.8z M230.2,125.6c0,2.3,0.5,4,1.5,5.2
|
48 |
+
s2.5,1.8,4.4,1.8s3.3-0.6,4.2-1.8c1-1.2,1.5-3,1.5-5.3s-0.5-4.1-1.5-5.3c-1-1.2-2.4-1.8-4.2-1.8c-1.9,0-3.3,0.6-4.4,1.9
|
49 |
+
C230.7,121.5,230.2,123.3,230.2,125.6z M264.2,118.8h-7.6v17.5h-5.2v-17.5h-3.6v-4.2h3.6v-3c0-2.3,0.7-4.2,2.2-5.6
|
50 |
+
c1.5-1.5,3.4-2.2,5.7-2.2c0.6,0,1.2,0,1.6,0.1c0.5,0.1,0.9,0.2,1.3,0.3v4.4c-0.2-0.1-0.5-0.2-0.9-0.4c-0.4-0.1-0.9-0.2-1.5-0.2
|
51 |
+
c-1.1,0-1.9,0.3-2.5,1s-0.9,1.7-0.9,3v2.6h7.6v-4.9l5.1-1.6v6.4h5.2v4.2h-5.2V129c0,1.3,0.2,2.3,0.7,2.8s1.3,0.8,2.3,0.8
|
52 |
+
c0.3,0,0.7-0.1,1.1-0.2c0.4-0.1,0.8-0.3,1.1-0.5v4.2c-0.3,0.2-0.9,0.4-1.6,0.5s-1.5,0.2-2.2,0.2c-2.2,0-3.8-0.6-4.9-1.7
|
53 |
+
c-1.1-1.1-1.6-2.9-1.6-5.2v-11.1C264,118.8,264.2,118.8,264.2,118.8z"/>
|
54 |
+
</g>
|
55 |
+
<g id="MS-symbol">
|
56 |
+
<g>
|
57 |
+
<rect x="9.6" y="106" class="st1" width="34.2" height="34.2"/>
|
58 |
+
<rect x="47.4" y="106" class="st2" width="34.2" height="34.2"/>
|
59 |
+
<rect x="9.6" y="143.8" class="st3" width="34.2" height="34.2"/>
|
60 |
+
<rect x="47.4" y="143.8" class="st4" width="34.2" height="34.2"/>
|
61 |
+
</g>
|
62 |
+
<g>
|
63 |
+
<rect x="9.6" y="106" class="st1" width="34.2" height="34.2"/>
|
64 |
+
<rect x="47.4" y="106" class="st2" width="34.2" height="34.2"/>
|
65 |
+
<rect x="9.6" y="143.8" class="st3" width="34.2" height="34.2"/>
|
66 |
+
<rect x="47.4" y="143.8" class="st4" width="34.2" height="34.2"/>
|
67 |
+
</g>
|
68 |
+
</g>
|
69 |
+
</svg>
|
vendor/league/flysystem/docs/index.css
CHANGED
@@ -32,7 +32,7 @@ h1, h2, h3, h4, h5 {
|
|
32 |
opacity: 0;
|
33 |
}
|
34 |
|
35 |
-
p {
|
36 |
@apply mb-4;
|
37 |
}
|
38 |
|
32 |
opacity: 0;
|
33 |
}
|
34 |
|
35 |
+
p, ul {
|
36 |
@apply mb-4;
|
37 |
}
|
38 |
|
vendor/league/flysystem/docs/index.md
CHANGED
@@ -30,11 +30,24 @@ of your code.
|
|
30 |
<a target="_blank" href="https://laravel.com" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
31 |
<img src="/img/laravel.svg" class="w-full" alt="Laravel.com"/>
|
32 |
</a>
|
33 |
-
|
34 |
-
<a target="_blank" href="https://azure.microsoft.com/" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
35 |
<img src="/img/azure.svg" class="max-w-full m-6" alt="Microsoft Azure"/>
|
36 |
</a>
|
37 |
-
-->
|
38 |
</div>
|
39 |
|
40 |
-
View all the <a href="/docs/sponsors/">sponsors</a>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
<a target="_blank" href="https://laravel.com" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
31 |
<img src="/img/laravel.svg" class="w-full" alt="Laravel.com"/>
|
32 |
</a>
|
33 |
+
<a target="_blank" href="https://azure.microsoft.com/free/?utm_source=flysystem&utm_medium=banner&utm_campaign=flysystem_sponsorship" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
|
|
34 |
<img src="/img/azure.svg" class="max-w-full m-6" alt="Microsoft Azure"/>
|
35 |
</a>
|
|
|
36 |
</div>
|
37 |
|
38 |
+
View all the <a href="/docs/sponsors/">sponsors</a>.
|
39 |
+
|
40 |
+
## Getting Started
|
41 |
+
|
42 |
+
* **[Architecture](/docs/architecture/)**: Flysystem's internal architecture
|
43 |
+
* **[Setup/Bootstrap](/docs/usage/setup/)**: Load Flysystem and set up your first adapter
|
44 |
+
* **[Flysystem API](/docs/usage/filesystem-api/)**: How to interact with your Flysystem instance
|
45 |
+
|
46 |
+
### Commonly-Used Adapters
|
47 |
+
|
48 |
+
* **[AWS S3](/docs/adapter/aws-s3/)**
|
49 |
+
* **[Azure](/docs/adapter/azure/)**
|
50 |
+
* **[Digital Ocean Spaces](/docs/adapter/digitalocean-spaces/)**
|
51 |
+
* **[Local](/docs/adapter/local/)**
|
52 |
+
* **[Memory](/docs/adapter/memory/)**
|
53 |
+
* **[Creating An Adapter](/docs/advanced/creating-an-adapter/)**
|
vendor/league/flysystem/docs/sponsors.md
CHANGED
@@ -16,10 +16,10 @@ In order to free up time to keep everything up-to-date financial help is greatly
|
|
16 |
<img src="/img/laravel.svg" class="w-full" alt="Laravel.com"/>
|
17 |
<span style="background-color: #FB503B" class="text-center text-xl hidden sm:block py-4 bg-indigo-dark text-white bg-grey-lightest">Laravel.com</span>
|
18 |
</a>
|
19 |
-
|
20 |
-
<img src="/img/azure.svg" class="max-w-full m-6 sm:m-8" alt="
|
21 |
-
<span style="background-color: #00a1f1;" class="text-center text-xl hidden sm:block py-4 bg-indigo-dark text-white bg-grey-lightest">
|
22 |
-
</a
|
23 |
<a target="_blank" href="https://patreon.com/frankdejonge" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
24 |
<img src="/img/question.svg" class="max-w-full m-6 sm:m-8 opacity-50" alt="Become a sponsor"/>
|
25 |
<span class="text-center text-xl hidden sm:block py-4 bg-indigo-light text-white bg-grey-lightest">Your company?</span>
|
@@ -37,8 +37,14 @@ In order to free up time to keep everything up-to-date financial help is greatly
|
|
37 |
|
38 |
## Bronze Sponsors
|
39 |
|
40 |
-
<
|
41 |
-
<a target="_blank" href="
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
16 |
<img src="/img/laravel.svg" class="w-full" alt="Laravel.com"/>
|
17 |
<span style="background-color: #FB503B" class="text-center text-xl hidden sm:block py-4 bg-indigo-dark text-white bg-grey-lightest">Laravel.com</span>
|
18 |
</a>
|
19 |
+
<a target="_blank" href="https://azure.microsoft.com/free/?utm_source=flysystem&utm_medium=banner&utm_campaign=flysystem_sponsorship" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
20 |
+
<img src="/img/azure.svg" class="max-w-full m-6 sm:m-8" alt="Azure.com"/>
|
21 |
+
<span style="background-color: #00a1f1;" class="text-center text-xl hidden sm:block py-4 bg-indigo-dark text-white bg-grey-lightest">Azure.com</span>
|
22 |
+
</a>
|
23 |
<a target="_blank" href="https://patreon.com/frankdejonge" class="flex-no-grow w-1/3 bg-white rounded shadow-md mr-4 overflow-hidden">
|
24 |
<img src="/img/question.svg" class="max-w-full m-6 sm:m-8 opacity-50" alt="Become a sponsor"/>
|
25 |
<span class="text-center text-xl hidden sm:block py-4 bg-indigo-light text-white bg-grey-lightest">Your company?</span>
|
37 |
|
38 |
## Bronze Sponsors
|
39 |
|
40 |
+
<ul class="pt-4 text-lg">
|
41 |
+
<li><a target="_blank" href="http://isset.nl/">Isset Internet Professionals</a></li>
|
42 |
+
<li><a target="_blank" href="https://jwe.nl/">Jan-Willem Eshuis</a></li>
|
43 |
+
</ul>
|
44 |
+
|
45 |
+
### Become a Sponsor
|
46 |
+
|
47 |
+
If you and your company believe that open source software is valuable and requires
|
48 |
+
financial sustainability, consider supporting:
|
49 |
+
|
50 |
+
<a href="https://www.patreon.com/bePatron?u=8623643"><img src="/img/become_a_patron_button.png" alt="Become a Patron!" title="Become a Patron!"/></a>
|
vendor/league/flysystem/docs/tailwind.js
CHANGED
@@ -170,6 +170,7 @@ module.exports = {
|
|
170 |
*/
|
171 |
|
172 |
screens: {
|
|
|
173 |
'sm': '576px',
|
174 |
'-md': {'max': '768px'},
|
175 |
'sm-md': {'min': '576px', 'max': '768px'},
|
170 |
*/
|
171 |
|
172 |
screens: {
|
173 |
+
'-sm': {'max': '576px'},
|
174 |
'sm': '576px',
|
175 |
'-md': {'max': '768px'},
|
176 |
'sm-md': {'min': '576px', 'max': '768px'},
|
vendor/league/flysystem/docs/usage/filesystem-api.md
CHANGED
@@ -23,6 +23,20 @@ param | description | type
|
|
23 |
|
24 |
---
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
## Update Files
|
27 |
|
28 |
```php
|
@@ -37,6 +51,20 @@ param | description | type
|
|
37 |
|
38 |
---
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
## Write or Update Files
|
41 |
|
42 |
```php
|
@@ -51,6 +79,20 @@ param | description | type
|
|
51 |
|
52 |
---
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
## Read Files
|
55 |
|
56 |
```php
|
@@ -64,16 +106,29 @@ param | description | type
|
|
64 |
|
65 |
---
|
66 |
|
67 |
-
##
|
68 |
|
69 |
```php
|
70 |
-
$
|
71 |
```
|
72 |
|
73 |
param | description | type
|
74 |
------------- | ------------------------ | -----------
|
75 |
`$path` | location of a file | `string`
|
76 |
-
`$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
> This only has consistent behaviour for files, not directories. Directories
|
79 |
> are less important in Flysystem, they're created implicitly and often ignored because
|
@@ -150,7 +205,7 @@ param | description | type
|
|
150 |
|
151 |
## Get Timestamps
|
152 |
|
153 |
-
This function the last updated timestamp.
|
154 |
|
155 |
```php
|
156 |
$response = $filesystem->getTimestamp($path);
|
23 |
|
24 |
---
|
25 |
|
26 |
+
## Write Files using a stream
|
27 |
+
|
28 |
+
```php
|
29 |
+
$response = $filesystem->writeStream($path, $resource);
|
30 |
+
```
|
31 |
+
|
32 |
+
param | description | type
|
33 |
+
------------- | ------------------------ | -----------
|
34 |
+
`$path` | location of a file | `string`
|
35 |
+
`$resource` | file stream | `resource`
|
36 |
+
`$response` | success boolean | `bool`
|
37 |
+
|
38 |
+
---
|
39 |
+
|
40 |
## Update Files
|
41 |
|
42 |
```php
|
51 |
|
52 |
---
|
53 |
|
54 |
+
## Update Files using a stream
|
55 |
+
|
56 |
+
```php
|
57 |
+
$response = $filesystem->updateStream($path, $contents);
|
58 |
+
```
|
59 |
+
|
60 |
+
param | description | type
|
61 |
+
------------- | ------------------------ | -----------
|
62 |
+
`$path` | location of a file | `string`
|
63 |
+
`$resource` | file stream | `resource`
|
64 |
+
`$response` | success boolean | `bool`
|
65 |
+
|
66 |
+
---
|
67 |
+
|
68 |
## Write or Update Files
|
69 |
|
70 |
```php
|
79 |
|
80 |
---
|
81 |
|
82 |
+
## Write or Update Files using a stream
|
83 |
+
|
84 |
+
```php
|
85 |
+
$response = $filesystem->putStream($path, $resource);
|
86 |
+
```
|
87 |
+
|
88 |
+
param | description | type
|
89 |
+
------------- | ------------------------ | -----------
|
90 |
+
`$path` | location of a file | `string`
|
91 |
+
`$resource` | file stream | `resource`
|
92 |
+
`$response` | success boolean | `bool`
|
93 |
+
|
94 |
+
---
|
95 |
+
|
96 |
## Read Files
|
97 |
|
98 |
```php
|
106 |
|
107 |
---
|
108 |
|
109 |
+
## Read Files as a stream
|
110 |
|
111 |
```php
|
112 |
+
$contents = $filesystem->readStream($path);
|
113 |
```
|
114 |
|
115 |
param | description | type
|
116 |
------------- | ------------------------ | -----------
|
117 |
`$path` | location of a file | `string`
|
118 |
+
`$resource` | file stream | `string`
|
119 |
+
|
120 |
+
---
|
121 |
+
|
122 |
+
## Check if a file exists
|
123 |
+
|
124 |
+
```php
|
125 |
+
$exists = $filesystem->has($path);
|
126 |
+
```
|
127 |
+
|
128 |
+
param | description | type
|
129 |
+
------------- | ------------------------- | -----------
|
130 |
+
`$path` | location of a file | `string`
|
131 |
+
`$exists` | whether the file exists | `bool`
|
132 |
|
133 |
> This only has consistent behaviour for files, not directories. Directories
|
134 |
> are less important in Flysystem, they're created implicitly and often ignored because
|
205 |
|
206 |
## Get Timestamps
|
207 |
|
208 |
+
This function returns the last updated timestamp.
|
209 |
|
210 |
```php
|
211 |
$response = $filesystem->getTimestamp($path);
|
vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php
CHANGED
@@ -71,11 +71,6 @@ abstract class AbstractFtpAdapter extends AbstractAdapter
|
|
71 |
*/
|
72 |
protected $systemType;
|
73 |
|
74 |
-
/**
|
75 |
-
* @var bool
|
76 |
-
*/
|
77 |
-
protected $alternativeRecursion = false;
|
78 |
-
|
79 |
/**
|
80 |
* @var SafeStorage
|
81 |
*/
|
71 |
*/
|
72 |
protected $systemType;
|
73 |
|
|
|
|
|
|
|
|
|
|
|
74 |
/**
|
75 |
* @var SafeStorage
|
76 |
*/
|
vendor/league/flysystem/src/Adapter/Local.php
CHANGED
@@ -33,13 +33,13 @@ class Local extends AbstractAdapter
|
|
33 |
*/
|
34 |
protected static $permissions = [
|
35 |
'file' => [
|
36 |
-
'public'
|
37 |
'private' => 0600,
|
38 |
],
|
39 |
-
'dir'
|
40 |
-
'public'
|
41 |
'private' => 0700,
|
42 |
-
]
|
43 |
];
|
44 |
|
45 |
/**
|
@@ -56,6 +56,7 @@ class Local extends AbstractAdapter
|
|
56 |
* @var int
|
57 |
*/
|
58 |
protected $writeFlags;
|
|
|
59 |
/**
|
60 |
* @var int
|
61 |
*/
|
@@ -99,11 +100,16 @@ class Local extends AbstractAdapter
|
|
99 |
{
|
100 |
if ( ! is_dir($root)) {
|
101 |
$umask = umask(0);
|
102 |
-
|
|
|
|
|
|
|
|
|
103 |
umask($umask);
|
104 |
|
105 |
if ( ! is_dir($root)) {
|
106 |
-
|
|
|
107 |
}
|
108 |
}
|
109 |
}
|
@@ -150,18 +156,11 @@ class Local extends AbstractAdapter
|
|
150 |
$this->ensureDirectory(dirname($location));
|
151 |
$stream = fopen($location, 'w+b');
|
152 |
|
153 |
-
if ( ! $stream) {
|
154 |
-
return false;
|
155 |
-
}
|
156 |
-
|
157 |
-
stream_copy_to_stream($resource, $stream);
|
158 |
-
|
159 |
-
if ( ! fclose($stream)) {
|
160 |
return false;
|
161 |
}
|
162 |
|
163 |
$type = 'file';
|
164 |
-
|
165 |
$result = compact('type', 'path');
|
166 |
|
167 |
if ($visibility = $config->get('visibility')) {
|
@@ -261,7 +260,7 @@ class Local extends AbstractAdapter
|
|
261 |
{
|
262 |
$location = $this->applyPathPrefix($path);
|
263 |
|
264 |
-
return unlink($location);
|
265 |
}
|
266 |
|
267 |
/**
|
33 |
*/
|
34 |
protected static $permissions = [
|
35 |
'file' => [
|
36 |
+
'public' => 0644,
|
37 |
'private' => 0600,
|
38 |
],
|
39 |
+
'dir' => [
|
40 |
+
'public' => 0755,
|
41 |
'private' => 0700,
|
42 |
+
],
|
43 |
];
|
44 |
|
45 |
/**
|
56 |
* @var int
|
57 |
*/
|
58 |
protected $writeFlags;
|
59 |
+
|
60 |
/**
|
61 |
* @var int
|
62 |
*/
|
100 |
{
|
101 |
if ( ! is_dir($root)) {
|
102 |
$umask = umask(0);
|
103 |
+
|
104 |
+
if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) {
|
105 |
+
$mkdirError = error_get_last();
|
106 |
+
}
|
107 |
+
|
108 |
umask($umask);
|
109 |
|
110 |
if ( ! is_dir($root)) {
|
111 |
+
$errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
|
112 |
+
throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage));
|
113 |
}
|
114 |
}
|
115 |
}
|
156 |
$this->ensureDirectory(dirname($location));
|
157 |
$stream = fopen($location, 'w+b');
|
158 |
|
159 |
+
if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
return false;
|
161 |
}
|
162 |
|
163 |
$type = 'file';
|
|
|
164 |
$result = compact('type', 'path');
|
165 |
|
166 |
if ($visibility = $config->get('visibility')) {
|
260 |
{
|
261 |
$location = $this->applyPathPrefix($path);
|
262 |
|
263 |
+
return @unlink($location);
|
264 |
}
|
265 |
|
266 |
/**
|
vendor/league/flysystem/src/MountManager.php
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
namespace League\Flysystem;
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
-
use League\Flysystem\FilesystemNotFoundException;
|
7 |
use League\Flysystem\Plugin\PluggableTrait;
|
8 |
use League\Flysystem\Plugin\PluginNotFoundException;
|
9 |
|
@@ -14,36 +13,15 @@ use League\Flysystem\Plugin\PluginNotFoundException;
|
|
14 |
*
|
15 |
* @method AdapterInterface getAdapter($prefix)
|
16 |
* @method Config getConfig($prefix)
|
17 |
-
* @method bool has($path)
|
18 |
-
* @method bool write($path, $contents, array $config = [])
|
19 |
-
* @method bool writeStream($path, $resource, array $config = [])
|
20 |
-
* @method bool put($path, $contents, $config = [])
|
21 |
-
* @method bool putStream($path, $contents, $config = [])
|
22 |
-
* @method string readAndDelete($path)
|
23 |
-
* @method bool update($path, $contents, $config = [])
|
24 |
-
* @method bool updateStream($path, $resource, $config = [])
|
25 |
-
* @method string|false read($path)
|
26 |
-
* @method resource|false readStream($path)
|
27 |
-
* @method bool rename($path, $newpath)
|
28 |
-
* @method bool delete($path)
|
29 |
-
* @method bool deleteDir($dirname)
|
30 |
-
* @method bool createDir($dirname, $config = [])
|
31 |
* @method array listFiles($directory = '', $recursive = false)
|
32 |
* @method array listPaths($directory = '', $recursive = false)
|
33 |
* @method array getWithMetadata($path, array $metadata)
|
34 |
-
* @method string|false getMimetype($path)
|
35 |
-
* @method int|false getTimestamp($path)
|
36 |
-
* @method string|false getVisibility($path)
|
37 |
-
* @method int|false getSize($path);
|
38 |
-
* @method bool setVisibility($path, $visibility)
|
39 |
-
* @method array|false getMetadata($path)
|
40 |
-
* @method Handler get($path, Handler $handler = null)
|
41 |
* @method Filesystem flushCache()
|
42 |
* @method void assertPresent($path)
|
43 |
* @method void assertAbsent($path)
|
44 |
* @method Filesystem addPlugin(PluginInterface $plugin)
|
45 |
*/
|
46 |
-
class MountManager
|
47 |
{
|
48 |
use PluggableTrait;
|
49 |
|
@@ -195,6 +173,7 @@ class MountManager
|
|
195 |
*
|
196 |
* @throws InvalidArgumentException
|
197 |
* @throws FilesystemNotFoundException
|
|
|
198 |
*
|
199 |
* @return bool
|
200 |
*/
|
@@ -317,4 +296,353 @@ class MountManager
|
|
317 |
|
318 |
return explode('://', $path, 2);
|
319 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
}
|
3 |
namespace League\Flysystem;
|
4 |
|
5 |
use InvalidArgumentException;
|
|
|
6 |
use League\Flysystem\Plugin\PluggableTrait;
|
7 |
use League\Flysystem\Plugin\PluginNotFoundException;
|
8 |
|
13 |
*
|
14 |
* @method AdapterInterface getAdapter($prefix)
|
15 |
* @method Config getConfig($prefix)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
* @method array listFiles($directory = '', $recursive = false)
|
17 |
* @method array listPaths($directory = '', $recursive = false)
|
18 |
* @method array getWithMetadata($path, array $metadata)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
* @method Filesystem flushCache()
|
20 |
* @method void assertPresent($path)
|
21 |
* @method void assertAbsent($path)
|
22 |
* @method Filesystem addPlugin(PluginInterface $plugin)
|
23 |
*/
|
24 |
+
class MountManager implements FilesystemInterface
|
25 |
{
|
26 |
use PluggableTrait;
|
27 |
|
173 |
*
|
174 |
* @throws InvalidArgumentException
|
175 |
* @throws FilesystemNotFoundException
|
176 |
+
* @throws FileExistsException
|
177 |
*
|
178 |
* @return bool
|
179 |
*/
|
296 |
|
297 |
return explode('://', $path, 2);
|
298 |
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Check whether a file exists.
|
302 |
+
*
|
303 |
+
* @param string $path
|
304 |
+
*
|
305 |
+
* @return bool
|
306 |
+
*/
|
307 |
+
public function has($path)
|
308 |
+
{
|
309 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
310 |
+
|
311 |
+
return $this->getFilesystem($prefix)->has($path);
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Read a file.
|
316 |
+
*
|
317 |
+
* @param string $path The path to the file.
|
318 |
+
*
|
319 |
+
* @throws FileNotFoundException
|
320 |
+
*
|
321 |
+
* @return string|false The file contents or false on failure.
|
322 |
+
*/
|
323 |
+
public function read($path)
|
324 |
+
{
|
325 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
326 |
+
|
327 |
+
return $this->getFilesystem($prefix)->read($path);
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Retrieves a read-stream for a path.
|
332 |
+
*
|
333 |
+
* @param string $path The path to the file.
|
334 |
+
*
|
335 |
+
* @throws FileNotFoundException
|
336 |
+
*
|
337 |
+
* @return resource|false The path resource or false on failure.
|
338 |
+
*/
|
339 |
+
public function readStream($path)
|
340 |
+
{
|
341 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
342 |
+
|
343 |
+
return $this->getFilesystem($prefix)->readStream($path);
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Get a file's metadata.
|
348 |
+
*
|
349 |
+
* @param string $path The path to the file.
|
350 |
+
*
|
351 |
+
* @throws FileNotFoundException
|
352 |
+
*
|
353 |
+
* @return array|false The file metadata or false on failure.
|
354 |
+
*/
|
355 |
+
public function getMetadata($path)
|
356 |
+
{
|
357 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
358 |
+
|
359 |
+
return $this->getFilesystem($prefix)->getMetadata($path);
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Get a file's size.
|
364 |
+
*
|
365 |
+
* @param string $path The path to the file.
|
366 |
+
*
|
367 |
+
* @throws FileNotFoundException
|
368 |
+
*
|
369 |
+
* @return int|false The file size or false on failure.
|
370 |
+
*/
|
371 |
+
public function getSize($path)
|
372 |
+
{
|
373 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
374 |
+
|
375 |
+
return $this->getFilesystem($prefix)->getSize($path);
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Get a file's mime-type.
|
380 |
+
*
|
381 |
+
* @param string $path The path to the file.
|
382 |
+
*
|
383 |
+
* @throws FileNotFoundException
|
384 |
+
*
|
385 |
+
* @return string|false The file mime-type or false on failure.
|
386 |
+
*/
|
387 |
+
public function getMimetype($path)
|
388 |
+
{
|
389 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
390 |
+
|
391 |
+
return $this->getFilesystem($prefix)->getMimetype($path);
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Get a file's timestamp.
|
396 |
+
*
|
397 |
+
* @param string $path The path to the file.
|
398 |
+
*
|
399 |
+
* @throws FileNotFoundException
|
400 |
+
*
|
401 |
+
* @return string|false The timestamp or false on failure.
|
402 |
+
*/
|
403 |
+
public function getTimestamp($path)
|
404 |
+
{
|
405 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
406 |
+
|
407 |
+
return $this->getFilesystem($prefix)->getTimestamp($path);
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Get a file's visibility.
|
412 |
+
*
|
413 |
+
* @param string $path The path to the file.
|
414 |
+
*
|
415 |
+
* @throws FileNotFoundException
|
416 |
+
*
|
417 |
+
* @return string|false The visibility (public|private) or false on failure.
|
418 |
+
*/
|
419 |
+
public function getVisibility($path)
|
420 |
+
{
|
421 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
422 |
+
|
423 |
+
return $this->getFilesystem($prefix)->getVisibility($path);
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Write a new file.
|
428 |
+
*
|
429 |
+
* @param string $path The path of the new file.
|
430 |
+
* @param string $contents The file contents.
|
431 |
+
* @param array $config An optional configuration array.
|
432 |
+
*
|
433 |
+
* @throws FileExistsException
|
434 |
+
*
|
435 |
+
* @return bool True on success, false on failure.
|
436 |
+
*/
|
437 |
+
public function write($path, $contents, array $config = [])
|
438 |
+
{
|
439 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
440 |
+
|
441 |
+
return $this->getFilesystem($prefix)->write($path, $contents, $config);
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Write a new file using a stream.
|
446 |
+
*
|
447 |
+
* @param string $path The path of the new file.
|
448 |
+
* @param resource $resource The file handle.
|
449 |
+
* @param array $config An optional configuration array.
|
450 |
+
*
|
451 |
+
* @throws InvalidArgumentException If $resource is not a file handle.
|
452 |
+
* @throws FileExistsException
|
453 |
+
*
|
454 |
+
* @return bool True on success, false on failure.
|
455 |
+
*/
|
456 |
+
public function writeStream($path, $resource, array $config = [])
|
457 |
+
{
|
458 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
459 |
+
|
460 |
+
return $this->getFilesystem($prefix)->writeStream($path, $resource, $config);
|
461 |
+
}
|
462 |
+
|
463 |
+
/**
|
464 |
+
* Update an existing file.
|
465 |
+
*
|
466 |
+
* @param string $path The path of the existing file.
|
467 |
+
* @param string $contents The file contents.
|
468 |
+
* @param array $config An optional configuration array.
|
469 |
+
*
|
470 |
+
* @throws FileNotFoundException
|
471 |
+
*
|
472 |
+
* @return bool True on success, false on failure.
|
473 |
+
*/
|
474 |
+
public function update($path, $contents, array $config = [])
|
475 |
+
{
|
476 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
477 |
+
|
478 |
+
return $this->getFilesystem($prefix)->update($path, $contents, $config);
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Update an existing file using a stream.
|
483 |
+
*
|
484 |
+
* @param string $path The path of the existing file.
|
485 |
+
* @param resource $resource The file handle.
|
486 |
+
* @param array $config An optional configuration array.
|
487 |
+
*
|
488 |
+
* @throws InvalidArgumentException If $resource is not a file handle.
|
489 |
+
* @throws FileNotFoundException
|
490 |
+
*
|
491 |
+
* @return bool True on success, false on failure.
|
492 |
+
*/
|
493 |
+
public function updateStream($path, $resource, array $config = [])
|
494 |
+
{
|
495 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
496 |
+
|
497 |
+
return $this->getFilesystem($prefix)->updateStream($path, $resource, $config);
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Rename a file.
|
502 |
+
*
|
503 |
+
* @param string $path Path to the existing file.
|
504 |
+
* @param string $newpath The new path of the file.
|
505 |
+
*
|
506 |
+
* @throws FileExistsException Thrown if $newpath exists.
|
507 |
+
* @throws FileNotFoundException Thrown if $path does not exist.
|
508 |
+
*
|
509 |
+
* @return bool True on success, false on failure.
|
510 |
+
*/
|
511 |
+
public function rename($path, $newpath)
|
512 |
+
{
|
513 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
514 |
+
|
515 |
+
return $this->getFilesystem($prefix)->rename($path, $newpath);
|
516 |
+
}
|
517 |
+
|
518 |
+
/**
|
519 |
+
* Delete a file.
|
520 |
+
*
|
521 |
+
* @param string $path
|
522 |
+
*
|
523 |
+
* @throws FileNotFoundException
|
524 |
+
*
|
525 |
+
* @return bool True on success, false on failure.
|
526 |
+
*/
|
527 |
+
public function delete($path)
|
528 |
+
{
|
529 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
530 |
+
|
531 |
+
return $this->getFilesystem($prefix)->delete($path);
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Delete a directory.
|
536 |
+
*
|
537 |
+
* @param string $dirname
|
538 |
+
*
|
539 |
+
* @throws RootViolationException Thrown if $dirname is empty.
|
540 |
+
*
|
541 |
+
* @return bool True on success, false on failure.
|
542 |
+
*/
|
543 |
+
public function deleteDir($dirname)
|
544 |
+
{
|
545 |
+
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
|
546 |
+
|
547 |
+
return $this->getFilesystem($prefix)->deleteDir($dirname);
|
548 |
+
}
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Create a directory.
|
552 |
+
*
|
553 |
+
* @param string $dirname The name of the new directory.
|
554 |
+
* @param array $config An optional configuration array.
|
555 |
+
*
|
556 |
+
* @return bool True on success, false on failure.
|
557 |
+
*/
|
558 |
+
public function createDir($dirname, array $config = [])
|
559 |
+
{
|
560 |
+
list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
|
561 |
+
|
562 |
+
return $this->getFilesystem($prefix)->createDir($dirname);
|
563 |
+
}
|
564 |
+
|
565 |
+
/**
|
566 |
+
* Set the visibility for a file.
|
567 |
+
*
|
568 |
+
* @param string $path The path to the file.
|
569 |
+
* @param string $visibility One of 'public' or 'private'.
|
570 |
+
*
|
571 |
+
* @throws FileNotFoundException
|
572 |
+
*
|
573 |
+
* @return bool True on success, false on failure.
|
574 |
+
*/
|
575 |
+
public function setVisibility($path, $visibility)
|
576 |
+
{
|
577 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
578 |
+
|
579 |
+
return $this->getFilesystem($prefix)->setVisibility($path, $visibility);
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Create a file or update if exists.
|
584 |
+
*
|
585 |
+
* @param string $path The path to the file.
|
586 |
+
* @param string $contents The file contents.
|
587 |
+
* @param array $config An optional configuration array.
|
588 |
+
*
|
589 |
+
* @return bool True on success, false on failure.
|
590 |
+
*/
|
591 |
+
public function put($path, $contents, array $config = [])
|
592 |
+
{
|
593 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
594 |
+
|
595 |
+
return $this->getFilesystem($prefix)->put($path, $contents, $config);
|
596 |
+
}
|
597 |
+
|
598 |
+
/**
|
599 |
+
* Create a file or update if exists.
|
600 |
+
*
|
601 |
+
* @param string $path The path to the file.
|
602 |
+
* @param resource $resource The file handle.
|
603 |
+
* @param array $config An optional configuration array.
|
604 |
+
*
|
605 |
+
* @throws InvalidArgumentException Thrown if $resource is not a resource.
|
606 |
+
*
|
607 |
+
* @return bool True on success, false on failure.
|
608 |
+
*/
|
609 |
+
public function putStream($path, $resource, array $config = [])
|
610 |
+
{
|
611 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
612 |
+
|
613 |
+
return $this->getFilesystem($prefix)->putStream($path, $resource, $config);
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Read and delete a file.
|
618 |
+
*
|
619 |
+
* @param string $path The path to the file.
|
620 |
+
*
|
621 |
+
* @throws FileNotFoundException
|
622 |
+
*
|
623 |
+
* @return string|false The file contents, or false on failure.
|
624 |
+
*/
|
625 |
+
public function readAndDelete($path)
|
626 |
+
{
|
627 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
628 |
+
|
629 |
+
return $this->getFilesystem($prefix)->readAndDelete($path);
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Get a file/directory handler.
|
634 |
+
*
|
635 |
+
* @deprecated
|
636 |
+
*
|
637 |
+
* @param string $path The path to the file.
|
638 |
+
* @param Handler $handler An optional existing handler to populate.
|
639 |
+
*
|
640 |
+
* @return Handler Either a file or directory handler.
|
641 |
+
*/
|
642 |
+
public function get($path, Handler $handler = null)
|
643 |
+
{
|
644 |
+
list($prefix, $path) = $this->getPrefixAndPath($path);
|
645 |
+
|
646 |
+
return $this->getFilesystem($prefix)->get($path);
|
647 |
+
}
|
648 |
}
|
vendor/league/flysystem/src/Util/MimeType.php
CHANGED
@@ -10,6 +10,166 @@ use ErrorException;
|
|
10 |
*/
|
11 |
class MimeType
|
12 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* Detects MIME Type based on given content.
|
15 |
*
|
@@ -41,17 +201,9 @@ class MimeType
|
|
41 |
*/
|
42 |
public static function detectByFileExtension($extension)
|
43 |
{
|
44 |
-
static
|
45 |
-
|
46 |
-
|
47 |
-
$extensionToMimeTypeMap = static::getExtensionToMimeTypeMap();
|
48 |
-
}
|
49 |
-
|
50 |
-
if (isset($extensionToMimeTypeMap[$extension])) {
|
51 |
-
return $extensionToMimeTypeMap[$extension];
|
52 |
-
}
|
53 |
-
|
54 |
-
return 'text/plain';
|
55 |
}
|
56 |
|
57 |
/**
|
@@ -71,162 +223,6 @@ class MimeType
|
|
71 |
*/
|
72 |
public static function getExtensionToMimeTypeMap()
|
73 |
{
|
74 |
-
return
|
75 |
-
'hqx' => 'application/mac-binhex40',
|
76 |
-
'cpt' => 'application/mac-compactpro',
|
77 |
-
'csv' => 'text/x-comma-separated-values',
|
78 |
-
'bin' => 'application/octet-stream',
|
79 |
-
'dms' => 'application/octet-stream',
|
80 |
-
'lha' => 'application/octet-stream',
|
81 |
-
'lzh' => 'application/octet-stream',
|
82 |
-
'exe' => 'application/octet-stream',
|
83 |
-
'class' => 'application/octet-stream',
|
84 |
-
'psd' => 'application/x-photoshop',
|
85 |
-
'so' => 'application/octet-stream',
|
86 |
-
'sea' => 'application/octet-stream',
|
87 |
-
'dll' => 'application/octet-stream',
|
88 |
-
'oda' => 'application/oda',
|
89 |
-
'pdf' => 'application/pdf',
|
90 |
-
'ai' => 'application/pdf',
|
91 |
-
'eps' => 'application/postscript',
|
92 |
-
'ps' => 'application/postscript',
|
93 |
-
'smi' => 'application/smil',
|
94 |
-
'smil' => 'application/smil',
|
95 |
-
'mif' => 'application/vnd.mif',
|
96 |
-
'xls' => 'application/vnd.ms-excel',
|
97 |
-
'ppt' => 'application/powerpoint',
|
98 |
-
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
99 |
-
'wbxml' => 'application/wbxml',
|
100 |
-
'wmlc' => 'application/wmlc',
|
101 |
-
'dcr' => 'application/x-director',
|
102 |
-
'dir' => 'application/x-director',
|
103 |
-
'dxr' => 'application/x-director',
|
104 |
-
'dvi' => 'application/x-dvi',
|
105 |
-
'gtar' => 'application/x-gtar',
|
106 |
-
'gz' => 'application/x-gzip',
|
107 |
-
'gzip' => 'application/x-gzip',
|
108 |
-
'php' => 'application/x-httpd-php',
|
109 |
-
'php4' => 'application/x-httpd-php',
|
110 |
-
'php3' => 'application/x-httpd-php',
|
111 |
-
'phtml' => 'application/x-httpd-php',
|
112 |
-
'phps' => 'application/x-httpd-php-source',
|
113 |
-
'js' => 'application/javascript',
|
114 |
-
'swf' => 'application/x-shockwave-flash',
|
115 |
-
'sit' => 'application/x-stuffit',
|
116 |
-
'tar' => 'application/x-tar',
|
117 |
-
'tgz' => 'application/x-tar',
|
118 |
-
'z' => 'application/x-compress',
|
119 |
-
'xhtml' => 'application/xhtml+xml',
|
120 |
-
'xht' => 'application/xhtml+xml',
|
121 |
-
'zip' => 'application/x-zip',
|
122 |
-
'rar' => 'application/x-rar',
|
123 |
-
'mid' => 'audio/midi',
|
124 |
-
'midi' => 'audio/midi',
|
125 |
-
'mpga' => 'audio/mpeg',
|
126 |
-
'mp2' => 'audio/mpeg',
|
127 |
-
'mp3' => 'audio/mpeg',
|
128 |
-
'aif' => 'audio/x-aiff',
|
129 |
-
'aiff' => 'audio/x-aiff',
|
130 |
-
'aifc' => 'audio/x-aiff',
|
131 |
-
'ram' => 'audio/x-pn-realaudio',
|
132 |
-
'rm' => 'audio/x-pn-realaudio',
|
133 |
-
'rpm' => 'audio/x-pn-realaudio-plugin',
|
134 |
-
'ra' => 'audio/x-realaudio',
|
135 |
-
'rv' => 'video/vnd.rn-realvideo',
|
136 |
-
'wav' => 'audio/x-wav',
|
137 |
-
'jpg' => 'image/jpeg',
|
138 |
-
'jpeg' => 'image/jpeg',
|
139 |
-
'jpe' => 'image/jpeg',
|
140 |
-
'png' => 'image/png',
|
141 |
-
'gif' => 'image/gif',
|
142 |
-
'bmp' => 'image/bmp',
|
143 |
-
'tiff' => 'image/tiff',
|
144 |
-
'tif' => 'image/tiff',
|
145 |
-
'svg' => 'image/svg+xml',
|
146 |
-
'css' => 'text/css',
|
147 |
-
'html' => 'text/html',
|
148 |
-
'htm' => 'text/html',
|
149 |
-
'shtml' => 'text/html',
|
150 |
-
'txt' => 'text/plain',
|
151 |
-
'text' => 'text/plain',
|
152 |
-
'log' => 'text/plain',
|
153 |
-
'rtx' => 'text/richtext',
|
154 |
-
'rtf' => 'text/rtf',
|
155 |
-
'xml' => 'application/xml',
|
156 |
-
'xsl' => 'application/xml',
|
157 |
-
'dmn' => 'application/octet-stream',
|
158 |
-
'bpmn' => 'application/octet-stream',
|
159 |
-
'mpeg' => 'video/mpeg',
|
160 |
-
'mpg' => 'video/mpeg',
|
161 |
-
'mpe' => 'video/mpeg',
|
162 |
-
'qt' => 'video/quicktime',
|
163 |
-
'mov' => 'video/quicktime',
|
164 |
-
'avi' => 'video/x-msvideo',
|
165 |
-
'movie' => 'video/x-sgi-movie',
|
166 |
-
'doc' => 'application/msword',
|
167 |
-
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
168 |
-
'docm' => 'application/vnd.ms-word.template.macroEnabled.12',
|
169 |
-
'dot' => 'application/msword',
|
170 |
-
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
171 |
-
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
172 |
-
'word' => 'application/msword',
|
173 |
-
'xl' => 'application/excel',
|
174 |
-
'eml' => 'message/rfc822',
|
175 |
-
'json' => 'application/json',
|
176 |
-
'pem' => 'application/x-x509-user-cert',
|
177 |
-
'p10' => 'application/x-pkcs10',
|
178 |
-
'p12' => 'application/x-pkcs12',
|
179 |
-
'p7a' => 'application/x-pkcs7-signature',
|
180 |
-
'p7c' => 'application/pkcs7-mime',
|
181 |
-
'p7m' => 'application/pkcs7-mime',
|
182 |
-
'p7r' => 'application/x-pkcs7-certreqresp',
|
183 |
-
'p7s' => 'application/pkcs7-signature',
|
184 |
-
'crt' => 'application/x-x509-ca-cert',
|
185 |
-
'crl' => 'application/pkix-crl',
|
186 |
-
'der' => 'application/x-x509-ca-cert',
|
187 |
-
'kdb' => 'application/octet-stream',
|
188 |
-
'pgp' => 'application/pgp',
|
189 |
-
'gpg' => 'application/gpg-keys',
|
190 |
-
'sst' => 'application/octet-stream',
|
191 |
-
'csr' => 'application/octet-stream',
|
192 |
-
'rsa' => 'application/x-pkcs7',
|
193 |
-
'cer' => 'application/pkix-cert',
|
194 |
-
'3g2' => 'video/3gpp2',
|
195 |
-
'3gp' => 'video/3gp',
|
196 |
-
'mp4' => 'video/mp4',
|
197 |
-
'm4a' => 'audio/x-m4a',
|
198 |
-
'f4v' => 'video/mp4',
|
199 |
-
'webm' => 'video/webm',
|
200 |
-
'aac' => 'audio/x-acc',
|
201 |
-
'm4u' => 'application/vnd.mpegurl',
|
202 |
-
'm3u' => 'text/plain',
|
203 |
-
'xspf' => 'application/xspf+xml',
|
204 |
-
'vlc' => 'application/videolan',
|
205 |
-
'wmv' => 'video/x-ms-wmv',
|
206 |
-
'au' => 'audio/x-au',
|
207 |
-
'ac3' => 'audio/ac3',
|
208 |
-
'flac' => 'audio/x-flac',
|
209 |
-
'ogg' => 'audio/ogg',
|
210 |
-
'kmz' => 'application/vnd.google-earth.kmz',
|
211 |
-
'kml' => 'application/vnd.google-earth.kml+xml',
|
212 |
-
'ics' => 'text/calendar',
|
213 |
-
'zsh' => 'text/x-scriptzsh',
|
214 |
-
'7zip' => 'application/x-7z-compressed',
|
215 |
-
'cdr' => 'application/cdr',
|
216 |
-
'wma' => 'audio/x-ms-wma',
|
217 |
-
'jar' => 'application/java-archive',
|
218 |
-
'tex' => 'application/x-tex',
|
219 |
-
'latex' => 'application/x-latex',
|
220 |
-
'odt' => 'application/vnd.oasis.opendocument.text',
|
221 |
-
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
222 |
-
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
223 |
-
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
224 |
-
'odc' => 'application/vnd.oasis.opendocument.chart',
|
225 |
-
'odf' => 'application/vnd.oasis.opendocument.formula',
|
226 |
-
'odi' => 'application/vnd.oasis.opendocument.image',
|
227 |
-
'odm' => 'application/vnd.oasis.opendocument.text-master',
|
228 |
-
'odb' => 'application/vnd.oasis.opendocument.database',
|
229 |
-
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
230 |
-
];
|
231 |
}
|
232 |
}
|
10 |
*/
|
11 |
class MimeType
|
12 |
{
|
13 |
+
protected static $extensionToMimeTypeMap = [
|
14 |
+
'hqx' => 'application/mac-binhex40',
|
15 |
+
'cpt' => 'application/mac-compactpro',
|
16 |
+
'csv' => 'text/x-comma-separated-values',
|
17 |
+
'bin' => 'application/octet-stream',
|
18 |
+
'dms' => 'application/octet-stream',
|
19 |
+
'lha' => 'application/octet-stream',
|
20 |
+
'lzh' => 'application/octet-stream',
|
21 |
+
'exe' => 'application/octet-stream',
|
22 |
+
'class' => 'application/octet-stream',
|
23 |
+
'psd' => 'application/x-photoshop',
|
24 |
+
'so' => 'application/octet-stream',
|
25 |
+
'sea' => 'application/octet-stream',
|
26 |
+
'dll' => 'application/octet-stream',
|
27 |
+
'oda' => 'application/oda',
|
28 |
+
'pdf' => 'application/pdf',
|
29 |
+
'ai' => 'application/pdf',
|
30 |
+
'eps' => 'application/postscript',
|
31 |
+
'epub' => 'application/epub+zip',
|
32 |
+
'ps' => 'application/postscript',
|
33 |
+
'smi' => 'application/smil',
|
34 |
+
'smil' => 'application/smil',
|
35 |
+
'mif' => 'application/vnd.mif',
|
36 |
+
'xls' => 'application/vnd.ms-excel',
|
37 |
+
'ppt' => 'application/powerpoint',
|
38 |
+
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
39 |
+
'wbxml' => 'application/wbxml',
|
40 |
+
'wmlc' => 'application/wmlc',
|
41 |
+
'dcr' => 'application/x-director',
|
42 |
+
'dir' => 'application/x-director',
|
43 |
+
'dxr' => 'application/x-director',
|
44 |
+
'dvi' => 'application/x-dvi',
|
45 |
+
'gtar' => 'application/x-gtar',
|
46 |
+
'gz' => 'application/x-gzip',
|
47 |
+
'gzip' => 'application/x-gzip',
|
48 |
+
'php' => 'application/x-httpd-php',
|
49 |
+
'php4' => 'application/x-httpd-php',
|
50 |
+
'php3' => 'application/x-httpd-php',
|
51 |
+
'phtml' => 'application/x-httpd-php',
|
52 |
+
'phps' => 'application/x-httpd-php-source',
|
53 |
+
'js' => 'application/javascript',
|
54 |
+
'swf' => 'application/x-shockwave-flash',
|
55 |
+
'sit' => 'application/x-stuffit',
|
56 |
+
'tar' => 'application/x-tar',
|
57 |
+
'tgz' => 'application/x-tar',
|
58 |
+
'z' => 'application/x-compress',
|
59 |
+
'xhtml' => 'application/xhtml+xml',
|
60 |
+
'xht' => 'application/xhtml+xml',
|
61 |
+
'rdf' => 'application/rdf+xml',
|
62 |
+
'zip' => 'application/x-zip',
|
63 |
+
'rar' => 'application/x-rar',
|
64 |
+
'mid' => 'audio/midi',
|
65 |
+
'midi' => 'audio/midi',
|
66 |
+
'mpga' => 'audio/mpeg',
|
67 |
+
'mp2' => 'audio/mpeg',
|
68 |
+
'mp3' => 'audio/mpeg',
|
69 |
+
'aif' => 'audio/x-aiff',
|
70 |
+
'aiff' => 'audio/x-aiff',
|
71 |
+
'aifc' => 'audio/x-aiff',
|
72 |
+
'ram' => 'audio/x-pn-realaudio',
|
73 |
+
'rm' => 'audio/x-pn-realaudio',
|
74 |
+
'rpm' => 'audio/x-pn-realaudio-plugin',
|
75 |
+
'ra' => 'audio/x-realaudio',
|
76 |
+
'rv' => 'video/vnd.rn-realvideo',
|
77 |
+
'wav' => 'audio/x-wav',
|
78 |
+
'jpg' => 'image/jpeg',
|
79 |
+
'jpeg' => 'image/jpeg',
|
80 |
+
'jpe' => 'image/jpeg',
|
81 |
+
'png' => 'image/png',
|
82 |
+
'gif' => 'image/gif',
|
83 |
+
'bmp' => 'image/bmp',
|
84 |
+
'tiff' => 'image/tiff',
|
85 |
+
'tif' => 'image/tiff',
|
86 |
+
'svg' => 'image/svg+xml',
|
87 |
+
'css' => 'text/css',
|
88 |
+
'html' => 'text/html',
|
89 |
+
'htm' => 'text/html',
|
90 |
+
'shtml' => 'text/html',
|
91 |
+
'txt' => 'text/plain',
|
92 |
+
'text' => 'text/plain',
|
93 |
+
'log' => 'text/plain',
|
94 |
+
'rtx' => 'text/richtext',
|
95 |
+
'rtf' => 'text/rtf',
|
96 |
+
'xml' => 'application/xml',
|
97 |
+
'xsl' => 'application/xml',
|
98 |
+
'dmn' => 'application/octet-stream',
|
99 |
+
'bpmn' => 'application/octet-stream',
|
100 |
+
'mpeg' => 'video/mpeg',
|
101 |
+
'mpg' => 'video/mpeg',
|
102 |
+
'mpe' => 'video/mpeg',
|
103 |
+
'qt' => 'video/quicktime',
|
104 |
+
'mov' => 'video/quicktime',
|
105 |
+
'avi' => 'video/x-msvideo',
|
106 |
+
'movie' => 'video/x-sgi-movie',
|
107 |
+
'doc' => 'application/msword',
|
108 |
+
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
109 |
+
'docm' => 'application/vnd.ms-word.template.macroEnabled.12',
|
110 |
+
'dot' => 'application/msword',
|
111 |
+
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
112 |
+
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
113 |
+
'word' => 'application/msword',
|
114 |
+
'xl' => 'application/excel',
|
115 |
+
'eml' => 'message/rfc822',
|
116 |
+
'json' => 'application/json',
|
117 |
+
'pem' => 'application/x-x509-user-cert',
|
118 |
+
'p10' => 'application/x-pkcs10',
|
119 |
+
'p12' => 'application/x-pkcs12',
|
120 |
+
'p7a' => 'application/x-pkcs7-signature',
|
121 |
+
'p7c' => 'application/pkcs7-mime',
|
122 |
+
'p7m' => 'application/pkcs7-mime',
|
123 |
+
'p7r' => 'application/x-pkcs7-certreqresp',
|
124 |
+
'p7s' => 'application/pkcs7-signature',
|
125 |
+
'crt' => 'application/x-x509-ca-cert',
|
126 |
+
'crl' => 'application/pkix-crl',
|
127 |
+
'der' => 'application/x-x509-ca-cert',
|
128 |
+
'kdb' => 'application/octet-stream',
|
129 |
+
'pgp' => 'application/pgp',
|
130 |
+
'gpg' => 'application/gpg-keys',
|
131 |
+
'sst' => 'application/octet-stream',
|
132 |
+
'csr' => 'application/octet-stream',
|
133 |
+
'rsa' => 'application/x-pkcs7',
|
134 |
+
'cer' => 'application/pkix-cert',
|
135 |
+
'3g2' => 'video/3gpp2',
|
136 |
+
'3gp' => 'video/3gp',
|
137 |
+
'mp4' => 'video/mp4',
|
138 |
+
'm4a' => 'audio/x-m4a',
|
139 |
+
'f4v' => 'video/mp4',
|
140 |
+
'webm' => 'video/webm',
|
141 |
+
'aac' => 'audio/x-acc',
|
142 |
+
'm4u' => 'application/vnd.mpegurl',
|
143 |
+
'm3u' => 'text/plain',
|
144 |
+
'xspf' => 'application/xspf+xml',
|
145 |
+
'vlc' => 'application/videolan',
|
146 |
+
'wmv' => 'video/x-ms-wmv',
|
147 |
+
'au' => 'audio/x-au',
|
148 |
+
'ac3' => 'audio/ac3',
|
149 |
+
'flac' => 'audio/x-flac',
|
150 |
+
'ogg' => 'audio/ogg',
|
151 |
+
'kmz' => 'application/vnd.google-earth.kmz',
|
152 |
+
'kml' => 'application/vnd.google-earth.kml+xml',
|
153 |
+
'ics' => 'text/calendar',
|
154 |
+
'zsh' => 'text/x-scriptzsh',
|
155 |
+
'7zip' => 'application/x-7z-compressed',
|
156 |
+
'cdr' => 'application/cdr',
|
157 |
+
'wma' => 'audio/x-ms-wma',
|
158 |
+
'jar' => 'application/java-archive',
|
159 |
+
'tex' => 'application/x-tex',
|
160 |
+
'latex' => 'application/x-latex',
|
161 |
+
'odt' => 'application/vnd.oasis.opendocument.text',
|
162 |
+
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
163 |
+
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
164 |
+
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
165 |
+
'odc' => 'application/vnd.oasis.opendocument.chart',
|
166 |
+
'odf' => 'application/vnd.oasis.opendocument.formula',
|
167 |
+
'odi' => 'application/vnd.oasis.opendocument.image',
|
168 |
+
'odm' => 'application/vnd.oasis.opendocument.text-master',
|
169 |
+
'odb' => 'application/vnd.oasis.opendocument.database',
|
170 |
+
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
171 |
+
];
|
172 |
+
|
173 |
/**
|
174 |
* Detects MIME Type based on given content.
|
175 |
*
|
201 |
*/
|
202 |
public static function detectByFileExtension($extension)
|
203 |
{
|
204 |
+
return isset(static::$extensionToMimeTypeMap[$extension])
|
205 |
+
? static::$extensionToMimeTypeMap[$extension]
|
206 |
+
: 'text/plain';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
|
209 |
/**
|
223 |
*/
|
224 |
public static function getExtensionToMimeTypeMap()
|
225 |
{
|
226 |
+
return static::$extensionToMimeTypeMap;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
}
|
228 |
}
|
vendor/league/flysystem/stub/FilesystemSpy.php
ADDED
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace League\Flysystem\Stub;
|
4 |
+
|
5 |
+
use InvalidArgumentException;
|
6 |
+
use League\Flysystem\FileExistsException;
|
7 |
+
use League\Flysystem\FileNotFoundException;
|
8 |
+
use League\Flysystem\FilesystemInterface;
|
9 |
+
use League\Flysystem\Handler;
|
10 |
+
use League\Flysystem\Plugin\PluggableTrait;
|
11 |
+
use League\Flysystem\RootViolationException;
|
12 |
+
|
13 |
+
class FilesystemSpy implements FilesystemInterface
|
14 |
+
{
|
15 |
+
use PluggableTrait;
|
16 |
+
|
17 |
+
public $lastCall = [];
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Check whether a file exists.
|
21 |
+
*
|
22 |
+
* @param string $path
|
23 |
+
*
|
24 |
+
* @return bool
|
25 |
+
*/
|
26 |
+
public function has($path)
|
27 |
+
{
|
28 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Read a file.
|
33 |
+
*
|
34 |
+
* @param string $path The path to the file.
|
35 |
+
*
|
36 |
+
* @throws FileNotFoundException
|
37 |
+
*
|
38 |
+
* @return string|false The file contents or false on failure.
|
39 |
+
*/
|
40 |
+
public function read($path)
|
41 |
+
{
|
42 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Retrieves a read-stream for a path.
|
47 |
+
*
|
48 |
+
* @param string $path The path to the file.
|
49 |
+
*
|
50 |
+
* @throws FileNotFoundException
|
51 |
+
*
|
52 |
+
* @return resource|false The path resource or false on failure.
|
53 |
+
*/
|
54 |
+
public function readStream($path)
|
55 |
+
{
|
56 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* List contents of a directory.
|
61 |
+
*
|
62 |
+
* @param string $directory The directory to list.
|
63 |
+
* @param bool $recursive Whether to list recursively.
|
64 |
+
*
|
65 |
+
* @return array A list of file metadata.
|
66 |
+
*/
|
67 |
+
public function listContents($directory = '', $recursive = false)
|
68 |
+
{
|
69 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get a file's metadata.
|
74 |
+
*
|
75 |
+
* @param string $path The path to the file.
|
76 |
+
*
|
77 |
+
* @throws FileNotFoundException
|
78 |
+
*
|
79 |
+
* @return array|false The file metadata or false on failure.
|
80 |
+
*/
|
81 |
+
public function getMetadata($path)
|
82 |
+
{
|
83 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Get a file's size.
|
88 |
+
*
|
89 |
+
* @param string $path The path to the file.
|
90 |
+
*
|
91 |
+
* @throws FileNotFoundException
|
92 |
+
*
|
93 |
+
* @return int|false The file size or false on failure.
|
94 |
+
*/
|
95 |
+
public function getSize($path)
|
96 |
+
{
|
97 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Get a file's mime-type.
|
102 |
+
*
|
103 |
+
* @param string $path The path to the file.
|
104 |
+
*
|
105 |
+
* @throws FileNotFoundException
|
106 |
+
*
|
107 |
+
* @return string|false The file mime-type or false on failure.
|
108 |
+
*/
|
109 |
+
public function getMimetype($path)
|
110 |
+
{
|
111 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Get a file's timestamp.
|
116 |
+
*
|
117 |
+
* @param string $path The path to the file.
|
118 |
+
*
|
119 |
+
* @throws FileNotFoundException
|
120 |
+
*
|
121 |
+
* @return string|false The timestamp or false on failure.
|
122 |
+
*/
|
123 |
+
public function getTimestamp($path)
|
124 |
+
{
|
125 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Get a file's visibility.
|
130 |
+
*
|
131 |
+
* @param string $path The path to the file.
|
132 |
+
*
|
133 |
+
* @throws FileNotFoundException
|
134 |
+
*
|
135 |
+
* @return string|false The visibility (public|private) or false on failure.
|
136 |
+
*/
|
137 |
+
public function getVisibility($path)
|
138 |
+
{
|
139 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Write a new file.
|
144 |
+
*
|
145 |
+
* @param string $path The path of the new file.
|
146 |
+
* @param string $contents The file contents.
|
147 |
+
* @param array $config An optional configuration array.
|
148 |
+
*
|
149 |
+
* @throws FileExistsException
|
150 |
+
*
|
151 |
+
* @return bool True on success, false on failure.
|
152 |
+
*/
|
153 |
+
public function write($path, $contents, array $config = [])
|
154 |
+
{
|
155 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Write a new file using a stream.
|
160 |
+
*
|
161 |
+
* @param string $path The path of the new file.
|
162 |
+
* @param resource $resource The file handle.
|
163 |
+
* @param array $config An optional configuration array.
|
164 |
+
*
|
165 |
+
* @throws InvalidArgumentException If $resource is not a file handle.
|
166 |
+
* @throws FileExistsException
|
167 |
+
*
|
168 |
+
* @return bool True on success, false on failure.
|
169 |
+
*/
|
170 |
+
public function writeStream($path, $resource, array $config = [])
|
171 |
+
{
|
172 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Update an existing file.
|
177 |
+
*
|
178 |
+
* @param string $path The path of the existing file.
|
179 |
+
* @param string $contents The file contents.
|
180 |
+
* @param array $config An optional configuration array.
|
181 |
+
*
|
182 |
+
* @throws FileNotFoundException
|
183 |
+
*
|
184 |
+
* @return bool True on success, false on failure.
|
185 |
+
*/
|
186 |
+
public function update($path, $contents, array $config = [])
|
187 |
+
{
|
188 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Update an existing file using a stream.
|
193 |
+
*
|
194 |
+
* @param string $path The path of the existing file.
|
195 |
+
* @param resource $resource The file handle.
|
196 |
+
* @param array $config An optional configuration array.
|
197 |
+
*
|
198 |
+
* @throws InvalidArgumentException If $resource is not a file handle.
|
199 |
+
* @throws FileNotFoundException
|
200 |
+
*
|
201 |
+
* @return bool True on success, false on failure.
|
202 |
+
*/
|
203 |
+
public function updateStream($path, $resource, array $config = [])
|
204 |
+
{
|
205 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Rename a file.
|
210 |
+
*
|
211 |
+
* @param string $path Path to the existing file.
|
212 |
+
* @param string $newpath The new path of the file.
|
213 |
+
*
|
214 |
+
* @throws FileExistsException Thrown if $newpath exists.
|
215 |
+
* @throws FileNotFoundException Thrown if $path does not exist.
|
216 |
+
*
|
217 |
+
* @return bool True on success, false on failure.
|
218 |
+
*/
|
219 |
+
public function rename($path, $newpath)
|
220 |
+
{
|
221 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Copy a file.
|
226 |
+
*
|
227 |
+
* @param string $path Path to the existing file.
|
228 |
+
* @param string $newpath The new path of the file.
|
229 |
+
*
|
230 |
+
* @throws FileExistsException Thrown if $newpath exists.
|
231 |
+
* @throws FileNotFoundException Thrown if $path does not exist.
|
232 |
+
*
|
233 |
+
* @return bool True on success, false on failure.
|
234 |
+
*/
|
235 |
+
public function copy($path, $newpath)
|
236 |
+
{
|
237 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Delete a file.
|
242 |
+
*
|
243 |
+
* @param string $path
|
244 |
+
*
|
245 |
+
* @throws FileNotFoundException
|
246 |
+
*
|
247 |
+
* @return bool True on success, false on failure.
|
248 |
+
*/
|
249 |
+
public function delete($path)
|
250 |
+
{
|
251 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Delete a directory.
|
256 |
+
*
|
257 |
+
* @param string $dirname
|
258 |
+
*
|
259 |
+
* @throws RootViolationException Thrown if $dirname is empty.
|
260 |
+
*
|
261 |
+
* @return bool True on success, false on failure.
|
262 |
+
*/
|
263 |
+
public function deleteDir($dirname)
|
264 |
+
{
|
265 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Create a directory.
|
270 |
+
*
|
271 |
+
* @param string $dirname The name of the new directory.
|
272 |
+
* @param array $config An optional configuration array.
|
273 |
+
*
|
274 |
+
* @return bool True on success, false on failure.
|
275 |
+
*/
|
276 |
+
public function createDir($dirname, array $config = [])
|
277 |
+
{
|
278 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Set the visibility for a file.
|
283 |
+
*
|
284 |
+
* @param string $path The path to the file.
|
285 |
+
* @param string $visibility One of 'public' or 'private'.
|
286 |
+
*
|
287 |
+
* @throws FileNotFoundException
|
288 |
+
*
|
289 |
+
* @return bool True on success, false on failure.
|
290 |
+
*/
|
291 |
+
public function setVisibility($path, $visibility)
|
292 |
+
{
|
293 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
294 |
+
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Create a file or update if exists.
|
298 |
+
*
|
299 |
+
* @param string $path The path to the file.
|
300 |
+
* @param string $contents The file contents.
|
301 |
+
* @param array $config An optional configuration array.
|
302 |
+
*
|
303 |
+
* @return bool True on success, false on failure.
|
304 |
+
*/
|
305 |
+
public function put($path, $contents, array $config = [])
|
306 |
+
{
|
307 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Create a file or update if exists.
|
312 |
+
*
|
313 |
+
* @param string $path The path to the file.
|
314 |
+
* @param resource $resource The file handle.
|
315 |
+
* @param array $config An optional configuration array.
|
316 |
+
*
|
317 |
+
* @throws InvalidArgumentException Thrown if $resource is not a resource.
|
318 |
+
*
|
319 |
+
* @return bool True on success, false on failure.
|
320 |
+
*/
|
321 |
+
public function putStream($path, $resource, array $config = [])
|
322 |
+
{
|
323 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Read and delete a file.
|
328 |
+
*
|
329 |
+
* @param string $path The path to the file.
|
330 |
+
*
|
331 |
+
* @throws FileNotFoundException
|
332 |
+
*
|
333 |
+
* @return string|false The file contents, or false on failure.
|
334 |
+
*/
|
335 |
+
public function readAndDelete($path)
|
336 |
+
{
|
337 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Get a file/directory handler.
|
342 |
+
*
|
343 |
+
* @deprecated
|
344 |
+
*
|
345 |
+
* @param string $path The path to the file.
|
346 |
+
* @param Handler $handler An optional existing handler to populate.
|
347 |
+
*
|
348 |
+
* @return Handler Either a file or directory handler.
|
349 |
+
*/
|
350 |
+
public function get($path, Handler $handler = null)
|
351 |
+
{
|
352 |
+
$this->lastCall = [__METHOD__, func_get_args()];
|
353 |
+
}
|
354 |
+
}
|
vendor/league/flysystem/tests/FtpTests.php
CHANGED
@@ -110,6 +110,10 @@ function ftp_pwd($connection)
|
|
110 |
|
111 |
function ftp_raw($connection, $command)
|
112 |
{
|
|
|
|
|
|
|
|
|
113 |
if ($command === 'OPTS UTF8 ON') {
|
114 |
return [0 => '200 UTF8 set to on'];
|
115 |
}
|
@@ -762,6 +766,27 @@ class FtpTests extends TestCase
|
|
762 |
$this->assertEquals('file1.txt', $metadata['path']);
|
763 |
}
|
764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
765 |
/**
|
766 |
* @param $adapter
|
767 |
*/
|
110 |
|
111 |
function ftp_raw($connection, $command)
|
112 |
{
|
113 |
+
if ($connection === 'utf8.fail') {
|
114 |
+
return [0 => '421 Service not available, closing control connection'];
|
115 |
+
}
|
116 |
+
|
117 |
if ($command === 'OPTS UTF8 ON') {
|
118 |
return [0 => '200 UTF8 set to on'];
|
119 |
}
|
766 |
$this->assertEquals('file1.txt', $metadata['path']);
|
767 |
}
|
768 |
|
769 |
+
/**
|
770 |
+
* @depends testInstantiable
|
771 |
+
*/
|
772 |
+
public function testItSetUtf8Mode()
|
773 |
+
{
|
774 |
+
$adapter = new Ftp($this->options + ['utf8' => true]);
|
775 |
+
$adapter->setUtf8(true);
|
776 |
+
$this->assertNull($adapter->connect());
|
777 |
+
}
|
778 |
+
|
779 |
+
/**
|
780 |
+
* @depends testInstantiable
|
781 |
+
* @expectedException \RuntimeException
|
782 |
+
*/
|
783 |
+
public function testItThrowsAnExceptionWhenItCouldNotSetUtf8ModeForConnection()
|
784 |
+
{
|
785 |
+
$adapter = new Ftp(['host' => 'utf8.fail', 'utf8' => true]);
|
786 |
+
$adapter->setUtf8(true);
|
787 |
+
$adapter->connect();
|
788 |
+
}
|
789 |
+
|
790 |
/**
|
791 |
* @param $adapter
|
792 |
*/
|
vendor/league/flysystem/tests/LocalAdapterTests.php
CHANGED
@@ -459,6 +459,17 @@ class LocalAdapterTests extends TestCase
|
|
459 |
$this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', $adapter->getMimetype('test.xlsx')['mimetype']);
|
460 |
}
|
461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
462 |
/**
|
463 |
* @expectedException \League\Flysystem\Exception
|
464 |
*/
|
459 |
$this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', $adapter->getMimetype('test.xlsx')['mimetype']);
|
460 |
}
|
461 |
|
462 |
+
public function testDeleteFileShouldReturnTrue(){
|
463 |
+
$root = __DIR__ . '/files/';
|
464 |
+
$original = $root . 'delete.txt';
|
465 |
+
file_put_contents($original, 'something');
|
466 |
+
$this->assertTrue($this->adapter->delete('delete.txt'));
|
467 |
+
}
|
468 |
+
|
469 |
+
public function testDeleteMissingFileShouldReturnFalse(){
|
470 |
+
$this->assertFalse($this->adapter->delete('missing.txt'));
|
471 |
+
}
|
472 |
+
|
473 |
/**
|
474 |
* @expectedException \League\Flysystem\Exception
|
475 |
*/
|
vendor/league/flysystem/tests/MountManagerTests.php
CHANGED
@@ -1,6 +1,9 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
use League\Flysystem\MountManager;
|
|
|
4 |
use PHPUnit\Framework\TestCase;
|
5 |
use Prophecy\Argument;
|
6 |
|
@@ -59,18 +62,6 @@ class MountManagerTests extends TestCase
|
|
59 |
$manager->filterPrefix($arguments);
|
60 |
}
|
61 |
|
62 |
-
public function testCallForwarder()
|
63 |
-
{
|
64 |
-
$manager = new MountManager();
|
65 |
-
$mock = $this->getMockBuilder('League\Flysystem\Filesystem')->disableOriginalConstructor()->getMock();
|
66 |
-
$mock->expects($this->once())
|
67 |
-
->method('__call')
|
68 |
-
->with('aMethodCall', ['file.ext'])
|
69 |
-
->willReturn('a result');
|
70 |
-
$manager->mountFilesystem('prot', $mock);
|
71 |
-
$this->assertEquals($manager->aMethodCall('prot://file.ext'), 'a result');
|
72 |
-
}
|
73 |
-
|
74 |
public function testCopyBetweenFilesystems()
|
75 |
{
|
76 |
$manager = new MountManager();
|
@@ -188,7 +179,12 @@ class MountManagerTests extends TestCase
|
|
188 |
|
189 |
public function provideMountSchemas()
|
190 |
{
|
191 |
-
return [
|
|
|
|
|
|
|
|
|
|
|
192 |
}
|
193 |
|
194 |
/**
|
@@ -198,8 +194,52 @@ class MountManagerTests extends TestCase
|
|
198 |
{
|
199 |
$manager = new MountManager();
|
200 |
$mock = $this->getMockBuilder('League\Flysystem\Filesystem')->disableOriginalConstructor()->getMock();
|
201 |
-
$mock->method('
|
202 |
$manager->mountFilesystem($schema, $mock);
|
203 |
-
$this->assertEquals($manager->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
}
|
205 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use League\Flysystem\AdapterInterface;
|
4 |
+
use League\Flysystem\FilesystemInterface;
|
5 |
use League\Flysystem\MountManager;
|
6 |
+
use League\Flysystem\Stub\FilesystemSpy;
|
7 |
use PHPUnit\Framework\TestCase;
|
8 |
use Prophecy\Argument;
|
9 |
|
62 |
$manager->filterPrefix($arguments);
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
public function testCopyBetweenFilesystems()
|
66 |
{
|
67 |
$manager = new MountManager();
|
179 |
|
180 |
public function provideMountSchemas()
|
181 |
{
|
182 |
+
return [
|
183 |
+
['with.dot'],
|
184 |
+
['with-dash'],
|
185 |
+
['with+plus'],
|
186 |
+
['with:colon']
|
187 |
+
];
|
188 |
}
|
189 |
|
190 |
/**
|
194 |
{
|
195 |
$manager = new MountManager();
|
196 |
$mock = $this->getMockBuilder('League\Flysystem\Filesystem')->disableOriginalConstructor()->getMock();
|
197 |
+
$mock->method('read')->with('file.ext')->willReturn('a result');
|
198 |
$manager->mountFilesystem($schema, $mock);
|
199 |
+
$this->assertEquals($manager->read($schema . '://file.ext'), 'a result');
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @dataProvider methodForwardingProvider
|
204 |
+
*/
|
205 |
+
public function testMethodForwarding($method, array $arguments)
|
206 |
+
{
|
207 |
+
$mountManager = new MountManager();
|
208 |
+
$filesystem = new FilesystemSpy();
|
209 |
+
$mountManager->mountFilesystem('local', $filesystem);
|
210 |
+
$expectedCall = FilesystemSpy::class . '::' . $method;
|
211 |
+
$callingArguments = $arguments;
|
212 |
+
$callingArguments[0] = "local://{$callingArguments[0]}";
|
213 |
+
call_user_func_array([$mountManager, $method], $callingArguments);
|
214 |
+
|
215 |
+
$this->assertEquals([$expectedCall, $arguments], $filesystem->lastCall);
|
216 |
+
}
|
217 |
+
|
218 |
+
public function methodForwardingProvider()
|
219 |
+
{
|
220 |
+
|
221 |
+
return [
|
222 |
+
['write', ['path.txt', 'contents', []]],
|
223 |
+
['writeStream', ['path.txt', 'contents', []]],
|
224 |
+
['update', ['path.txt', 'contents', []]],
|
225 |
+
['updateStream', ['path.txt', 'contents', []]],
|
226 |
+
['put', ['path.txt', 'contents', []]],
|
227 |
+
['putStream', ['path.txt', 'contents', []]],
|
228 |
+
['read', ['path.txt']],
|
229 |
+
['readStream', ['path.txt']],
|
230 |
+
['readAndDelete', ['path.txt']],
|
231 |
+
['get', ['path.txt']],
|
232 |
+
['has', ['path.txt']],
|
233 |
+
['getMetadata', ['path.txt']],
|
234 |
+
['getMimetype', ['path.txt']],
|
235 |
+
['getTimestamp', ['path.txt']],
|
236 |
+
['getSize', ['path.txt']],
|
237 |
+
['delete', ['path.txt']],
|
238 |
+
['deleteDir', ['dirname']],
|
239 |
+
['createDir', ['dirname']],
|
240 |
+
['rename', ['name', 'other-name']],
|
241 |
+
['setVisibility', ['name', AdapterInterface::VISIBILITY_PUBLIC]],
|
242 |
+
['getVisibility', ['name']],
|
243 |
+
];
|
244 |
}
|
245 |
}
|
vendor/league/flysystem/tests/UtilMimeTests.php
CHANGED
@@ -29,6 +29,13 @@ class UtilMimeTests extends TestCase
|
|
29 |
$passthru = true;
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
public function testNoExtension()
|
33 |
{
|
34 |
$this->assertEquals('text/plain', MimeType::detectByFileExtension('dir/file'));
|
29 |
$passthru = true;
|
30 |
}
|
31 |
|
32 |
+
public function testRetrievingAllMimetypes()
|
33 |
+
{
|
34 |
+
$map = MimeType::getExtensionToMimeTypeMap();
|
35 |
+
$this->assertInternalType('array', $map);
|
36 |
+
$this->assertEquals('application/epub+zip', $map['epub']);
|
37 |
+
}
|
38 |
+
|
39 |
public function testNoExtension()
|
40 |
{
|
41 |
$this->assertEquals('text/plain', MimeType::detectByFileExtension('dir/file'));
|
vendor/paragonie/random_compat/LICENSE
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
The MIT License (MIT)
|
2 |
-
|
3 |
-
Copyright (c) 2015 Paragon Initiative Enterprises
|
4 |
-
|
5 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
-
of this software and associated documentation files (the "Software"), to deal
|
7 |
-
in the Software without restriction, including without limitation the rights
|
8 |
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
-
copies of the Software, and to permit persons to whom the Software is
|
10 |
-
furnished to do so, subject to the following conditions:
|
11 |
-
|
12 |
-
The above copyright notice and this permission notice shall be included in all
|
13 |
-
copies or substantial portions of the Software.
|
14 |
-
|
15 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
-
SOFTWARE.
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/build-phar.sh
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
#!/usr/bin/env bash
|
2 |
-
|
3 |
-
basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) )
|
4 |
-
|
5 |
-
php -dphar.readonly=0 "$basedir/other/build_phar.php" $*
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/composer.json
DELETED
@@ -1,38 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "paragonie/random_compat",
|
3 |
-
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
4 |
-
"keywords": [
|
5 |
-
"csprng",
|
6 |
-
"random",
|
7 |
-
"polyfill",
|
8 |
-
"pseudorandom"
|
9 |
-
],
|
10 |
-
"license": "MIT",
|
11 |
-
"type": "library",
|
12 |
-
"authors": [
|
13 |
-
{
|
14 |
-
"name": "Paragon Initiative Enterprises",
|
15 |
-
"email": "security@paragonie.com",
|
16 |
-
"homepage": "https://paragonie.com"
|
17 |
-
}
|
18 |
-
],
|
19 |
-
"support": {
|
20 |
-
"issues": "https://github.com/paragonie/random_compat/issues",
|
21 |
-
"email": "info@paragonie.com",
|
22 |
-
"source": "https://github.com/paragonie/random_compat"
|
23 |
-
},
|
24 |
-
"require": {
|
25 |
-
"php": ">=5.2.0"
|
26 |
-
},
|
27 |
-
"require-dev": {
|
28 |
-
"phpunit/phpunit": "4.*|5.*"
|
29 |
-
},
|
30 |
-
"suggest": {
|
31 |
-
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
32 |
-
},
|
33 |
-
"autoload": {
|
34 |
-
"files": [
|
35 |
-
"lib/random.php"
|
36 |
-
]
|
37 |
-
}
|
38 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/dist/random_compat.phar.pubkey
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
-----BEGIN PUBLIC KEY-----
|
2 |
-
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
|
3 |
-
pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
|
4 |
-
+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
|
5 |
-
-----END PUBLIC KEY-----
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
-----BEGIN PGP SIGNATURE-----
|
2 |
-
Version: GnuPG v2.0.22 (MingW32)
|
3 |
-
|
4 |
-
iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip
|
5 |
-
QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg
|
6 |
-
1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW
|
7 |
-
NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA
|
8 |
-
NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV
|
9 |
-
JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74=
|
10 |
-
=B6+8
|
11 |
-
-----END PGP SIGNATURE-----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/byte_safe_strings.php
DELETED
@@ -1,181 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('RandomCompat_strlen')) {
|
30 |
-
if (
|
31 |
-
defined('MB_OVERLOAD_STRING') &&
|
32 |
-
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
|
33 |
-
) {
|
34 |
-
/**
|
35 |
-
* strlen() implementation that isn't brittle to mbstring.func_overload
|
36 |
-
*
|
37 |
-
* This version uses mb_strlen() in '8bit' mode to treat strings as raw
|
38 |
-
* binary rather than UTF-8, ISO-8859-1, etc
|
39 |
-
*
|
40 |
-
* @param string $binary_string
|
41 |
-
*
|
42 |
-
* @throws TypeError
|
43 |
-
*
|
44 |
-
* @return int
|
45 |
-
*/
|
46 |
-
function RandomCompat_strlen($binary_string)
|
47 |
-
{
|
48 |
-
if (!is_string($binary_string)) {
|
49 |
-
throw new TypeError(
|
50 |
-
'RandomCompat_strlen() expects a string'
|
51 |
-
);
|
52 |
-
}
|
53 |
-
|
54 |
-
return (int) mb_strlen($binary_string, '8bit');
|
55 |
-
}
|
56 |
-
|
57 |
-
} else {
|
58 |
-
/**
|
59 |
-
* strlen() implementation that isn't brittle to mbstring.func_overload
|
60 |
-
*
|
61 |
-
* This version just used the default strlen()
|
62 |
-
*
|
63 |
-
* @param string $binary_string
|
64 |
-
*
|
65 |
-
* @throws TypeError
|
66 |
-
*
|
67 |
-
* @return int
|
68 |
-
*/
|
69 |
-
function RandomCompat_strlen($binary_string)
|
70 |
-
{
|
71 |
-
if (!is_string($binary_string)) {
|
72 |
-
throw new TypeError(
|
73 |
-
'RandomCompat_strlen() expects a string'
|
74 |
-
);
|
75 |
-
}
|
76 |
-
return (int) strlen($binary_string);
|
77 |
-
}
|
78 |
-
}
|
79 |
-
}
|
80 |
-
|
81 |
-
if (!is_callable('RandomCompat_substr')) {
|
82 |
-
|
83 |
-
if (
|
84 |
-
defined('MB_OVERLOAD_STRING')
|
85 |
-
&&
|
86 |
-
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
|
87 |
-
) {
|
88 |
-
/**
|
89 |
-
* substr() implementation that isn't brittle to mbstring.func_overload
|
90 |
-
*
|
91 |
-
* This version uses mb_substr() in '8bit' mode to treat strings as raw
|
92 |
-
* binary rather than UTF-8, ISO-8859-1, etc
|
93 |
-
*
|
94 |
-
* @param string $binary_string
|
95 |
-
* @param int $start
|
96 |
-
* @param int $length (optional)
|
97 |
-
*
|
98 |
-
* @throws TypeError
|
99 |
-
*
|
100 |
-
* @return string
|
101 |
-
*/
|
102 |
-
function RandomCompat_substr($binary_string, $start, $length = null)
|
103 |
-
{
|
104 |
-
if (!is_string($binary_string)) {
|
105 |
-
throw new TypeError(
|
106 |
-
'RandomCompat_substr(): First argument should be a string'
|
107 |
-
);
|
108 |
-
}
|
109 |
-
|
110 |
-
if (!is_int($start)) {
|
111 |
-
throw new TypeError(
|
112 |
-
'RandomCompat_substr(): Second argument should be an integer'
|
113 |
-
);
|
114 |
-
}
|
115 |
-
|
116 |
-
if ($length === null) {
|
117 |
-
/**
|
118 |
-
* mb_substr($str, 0, NULL, '8bit') returns an empty string on
|
119 |
-
* PHP 5.3, so we have to find the length ourselves.
|
120 |
-
*/
|
121 |
-
$length = RandomCompat_strlen($binary_string) - $start;
|
122 |
-
} elseif (!is_int($length)) {
|
123 |
-
throw new TypeError(
|
124 |
-
'RandomCompat_substr(): Third argument should be an integer, or omitted'
|
125 |
-
);
|
126 |
-
}
|
127 |
-
|
128 |
-
// Consistency with PHP's behavior
|
129 |
-
if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
|
130 |
-
return '';
|
131 |
-
}
|
132 |
-
if ($start > RandomCompat_strlen($binary_string)) {
|
133 |
-
return '';
|
134 |
-
}
|
135 |
-
|
136 |
-
return (string) mb_substr($binary_string, $start, $length, '8bit');
|
137 |
-
}
|
138 |
-
|
139 |
-
} else {
|
140 |
-
|
141 |
-
/**
|
142 |
-
* substr() implementation that isn't brittle to mbstring.func_overload
|
143 |
-
*
|
144 |
-
* This version just uses the default substr()
|
145 |
-
*
|
146 |
-
* @param string $binary_string
|
147 |
-
* @param int $start
|
148 |
-
* @param int $length (optional)
|
149 |
-
*
|
150 |
-
* @throws TypeError
|
151 |
-
*
|
152 |
-
* @return string
|
153 |
-
*/
|
154 |
-
function RandomCompat_substr($binary_string, $start, $length = null)
|
155 |
-
{
|
156 |
-
if (!is_string($binary_string)) {
|
157 |
-
throw new TypeError(
|
158 |
-
'RandomCompat_substr(): First argument should be a string'
|
159 |
-
);
|
160 |
-
}
|
161 |
-
|
162 |
-
if (!is_int($start)) {
|
163 |
-
throw new TypeError(
|
164 |
-
'RandomCompat_substr(): Second argument should be an integer'
|
165 |
-
);
|
166 |
-
}
|
167 |
-
|
168 |
-
if ($length !== null) {
|
169 |
-
if (!is_int($length)) {
|
170 |
-
throw new TypeError(
|
171 |
-
'RandomCompat_substr(): Third argument should be an integer, or omitted'
|
172 |
-
);
|
173 |
-
}
|
174 |
-
|
175 |
-
return (string) substr($binary_string, $start, $length);
|
176 |
-
}
|
177 |
-
|
178 |
-
return (string) substr($binary_string, $start);
|
179 |
-
}
|
180 |
-
}
|
181 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/cast_to_int.php
DELETED
@@ -1,75 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('RandomCompat_intval')) {
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Cast to an integer if we can, safely.
|
33 |
-
*
|
34 |
-
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
35 |
-
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
36 |
-
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
37 |
-
* lose precision, so the <= and => operators might accidentally let a float
|
38 |
-
* through.
|
39 |
-
*
|
40 |
-
* @param int|float $number The number we want to convert to an int
|
41 |
-
* @param bool $fail_open Set to true to not throw an exception
|
42 |
-
*
|
43 |
-
* @return float|int
|
44 |
-
* @psalm-suppress InvalidReturnType
|
45 |
-
*
|
46 |
-
* @throws TypeError
|
47 |
-
*/
|
48 |
-
function RandomCompat_intval($number, $fail_open = false)
|
49 |
-
{
|
50 |
-
if (is_int($number) || is_float($number)) {
|
51 |
-
$number += 0;
|
52 |
-
} elseif (is_numeric($number)) {
|
53 |
-
$number += 0;
|
54 |
-
}
|
55 |
-
|
56 |
-
if (
|
57 |
-
is_float($number)
|
58 |
-
&&
|
59 |
-
$number > ~PHP_INT_MAX
|
60 |
-
&&
|
61 |
-
$number < PHP_INT_MAX
|
62 |
-
) {
|
63 |
-
$number = (int) $number;
|
64 |
-
}
|
65 |
-
|
66 |
-
if (is_int($number)) {
|
67 |
-
return (int) $number;
|
68 |
-
} elseif (!$fail_open) {
|
69 |
-
throw new TypeError(
|
70 |
-
'Expected an integer.'
|
71 |
-
);
|
72 |
-
}
|
73 |
-
return $number;
|
74 |
-
}
|
75 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/error_polyfill.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!class_exists('Error', false)) {
|
30 |
-
// We can't really avoid making this extend Exception in PHP 5.
|
31 |
-
class Error extends Exception
|
32 |
-
{
|
33 |
-
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
if (!class_exists('TypeError', false)) {
|
38 |
-
if (is_subclass_of('Error', 'Exception')) {
|
39 |
-
class TypeError extends Error
|
40 |
-
{
|
41 |
-
|
42 |
-
}
|
43 |
-
} else {
|
44 |
-
class TypeError extends Exception
|
45 |
-
{
|
46 |
-
|
47 |
-
}
|
48 |
-
}
|
49 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random.php
DELETED
@@ -1,226 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* @version 2.0.15
|
7 |
-
* @released 2018-06-08
|
8 |
-
*
|
9 |
-
* The MIT License (MIT)
|
10 |
-
*
|
11 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
12 |
-
*
|
13 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
14 |
-
* of this software and associated documentation files (the "Software"), to deal
|
15 |
-
* in the Software without restriction, including without limitation the rights
|
16 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
17 |
-
* copies of the Software, and to permit persons to whom the Software is
|
18 |
-
* furnished to do so, subject to the following conditions:
|
19 |
-
*
|
20 |
-
* The above copyright notice and this permission notice shall be included in
|
21 |
-
* all copies or substantial portions of the Software.
|
22 |
-
*
|
23 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
24 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
26 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
27 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
28 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
29 |
-
* SOFTWARE.
|
30 |
-
*/
|
31 |
-
|
32 |
-
if (!defined('PHP_VERSION_ID')) {
|
33 |
-
// This constant was introduced in PHP 5.2.7
|
34 |
-
$RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
|
35 |
-
define(
|
36 |
-
'PHP_VERSION_ID',
|
37 |
-
$RandomCompatversion[0] * 10000
|
38 |
-
+ $RandomCompatversion[1] * 100
|
39 |
-
+ $RandomCompatversion[2]
|
40 |
-
);
|
41 |
-
$RandomCompatversion = null;
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* PHP 7.0.0 and newer have these functions natively.
|
46 |
-
*/
|
47 |
-
if (PHP_VERSION_ID >= 70000) {
|
48 |
-
return;
|
49 |
-
}
|
50 |
-
|
51 |
-
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
52 |
-
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
53 |
-
}
|
54 |
-
|
55 |
-
$RandomCompatDIR = dirname(__FILE__);
|
56 |
-
|
57 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'byte_safe_strings.php';
|
58 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'cast_to_int.php';
|
59 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'error_polyfill.php';
|
60 |
-
|
61 |
-
if (!is_callable('random_bytes')) {
|
62 |
-
/**
|
63 |
-
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
|
64 |
-
*
|
65 |
-
* We use conditional statements here to define the function in accordance
|
66 |
-
* to the operating environment. It's a micro-optimization.
|
67 |
-
*
|
68 |
-
* In order of preference:
|
69 |
-
* 1. Use libsodium if available.
|
70 |
-
* 2. fread() /dev/urandom if available (never on Windows)
|
71 |
-
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
|
72 |
-
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
|
73 |
-
*
|
74 |
-
* See RATIONALE.md for our reasoning behind this particular order
|
75 |
-
*/
|
76 |
-
if (extension_loaded('libsodium')) {
|
77 |
-
// See random_bytes_libsodium.php
|
78 |
-
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
|
79 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium.php';
|
80 |
-
} elseif (method_exists('Sodium', 'randombytes_buf')) {
|
81 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium_legacy.php';
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Reading directly from /dev/urandom:
|
87 |
-
*/
|
88 |
-
if (DIRECTORY_SEPARATOR === '/') {
|
89 |
-
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
|
90 |
-
// way to exclude Windows.
|
91 |
-
$RandomCompatUrandom = true;
|
92 |
-
$RandomCompat_basedir = ini_get('open_basedir');
|
93 |
-
|
94 |
-
if (!empty($RandomCompat_basedir)) {
|
95 |
-
$RandomCompat_open_basedir = explode(
|
96 |
-
PATH_SEPARATOR,
|
97 |
-
strtolower($RandomCompat_basedir)
|
98 |
-
);
|
99 |
-
$RandomCompatUrandom = (array() !== array_intersect(
|
100 |
-
array('/dev', '/dev/', '/dev/urandom'),
|
101 |
-
$RandomCompat_open_basedir
|
102 |
-
));
|
103 |
-
$RandomCompat_open_basedir = null;
|
104 |
-
}
|
105 |
-
|
106 |
-
if (
|
107 |
-
!is_callable('random_bytes')
|
108 |
-
&&
|
109 |
-
$RandomCompatUrandom
|
110 |
-
&&
|
111 |
-
@is_readable('/dev/urandom')
|
112 |
-
) {
|
113 |
-
// Error suppression on is_readable() in case of an open_basedir
|
114 |
-
// or safe_mode failure. All we care about is whether or not we
|
115 |
-
// can read it at this point. If the PHP environment is going to
|
116 |
-
// panic over trying to see if the file can be read in the first
|
117 |
-
// place, that is not helpful to us here.
|
118 |
-
|
119 |
-
// See random_bytes_dev_urandom.php
|
120 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_dev_urandom.php';
|
121 |
-
}
|
122 |
-
// Unset variables after use
|
123 |
-
$RandomCompat_basedir = null;
|
124 |
-
} else {
|
125 |
-
$RandomCompatUrandom = false;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* mcrypt_create_iv()
|
130 |
-
*
|
131 |
-
* We only want to use mcypt_create_iv() if:
|
132 |
-
*
|
133 |
-
* - random_bytes() hasn't already been defined
|
134 |
-
* - the mcrypt extensions is loaded
|
135 |
-
* - One of these two conditions is true:
|
136 |
-
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
|
137 |
-
* - We're not on Windows and /dev/urandom is readabale
|
138 |
-
* (i.e. we're not in a chroot jail)
|
139 |
-
* - Special case:
|
140 |
-
* - If we're not on Windows, but the PHP version is between
|
141 |
-
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
|
142 |
-
* hang indefinitely. This is bad.
|
143 |
-
* - If we're on Windows, we want to use PHP >= 5.3.7 or else
|
144 |
-
* we get insufficient entropy errors.
|
145 |
-
*/
|
146 |
-
if (
|
147 |
-
!is_callable('random_bytes')
|
148 |
-
&&
|
149 |
-
// Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
|
150 |
-
(DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
|
151 |
-
&&
|
152 |
-
// Prevent this code from hanging indefinitely on non-Windows;
|
153 |
-
// see https://bugs.php.net/bug.php?id=69833
|
154 |
-
(
|
155 |
-
DIRECTORY_SEPARATOR !== '/' ||
|
156 |
-
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
|
157 |
-
)
|
158 |
-
&&
|
159 |
-
extension_loaded('mcrypt')
|
160 |
-
) {
|
161 |
-
// See random_bytes_mcrypt.php
|
162 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_mcrypt.php';
|
163 |
-
}
|
164 |
-
$RandomCompatUrandom = null;
|
165 |
-
|
166 |
-
/**
|
167 |
-
* This is a Windows-specific fallback, for when the mcrypt extension
|
168 |
-
* isn't loaded.
|
169 |
-
*/
|
170 |
-
if (
|
171 |
-
!is_callable('random_bytes')
|
172 |
-
&&
|
173 |
-
extension_loaded('com_dotnet')
|
174 |
-
&&
|
175 |
-
class_exists('COM')
|
176 |
-
) {
|
177 |
-
$RandomCompat_disabled_classes = preg_split(
|
178 |
-
'#\s*,\s*#',
|
179 |
-
strtolower(ini_get('disable_classes'))
|
180 |
-
);
|
181 |
-
|
182 |
-
if (!in_array('com', $RandomCompat_disabled_classes)) {
|
183 |
-
try {
|
184 |
-
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
|
185 |
-
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
|
186 |
-
// See random_bytes_com_dotnet.php
|
187 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_com_dotnet.php';
|
188 |
-
}
|
189 |
-
} catch (com_exception $e) {
|
190 |
-
// Don't try to use it.
|
191 |
-
}
|
192 |
-
}
|
193 |
-
$RandomCompat_disabled_classes = null;
|
194 |
-
$RandomCompatCOMtest = null;
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* throw new Exception
|
199 |
-
*/
|
200 |
-
if (!is_callable('random_bytes')) {
|
201 |
-
/**
|
202 |
-
* We don't have any more options, so let's throw an exception right now
|
203 |
-
* and hope the developer won't let it fail silently.
|
204 |
-
*
|
205 |
-
* @param mixed $length
|
206 |
-
* @psalm-suppress MissingReturnType
|
207 |
-
* @psalm-suppress InvalidReturnType
|
208 |
-
* @throws Exception
|
209 |
-
* @return string
|
210 |
-
*/
|
211 |
-
function random_bytes($length)
|
212 |
-
{
|
213 |
-
unset($length); // Suppress "variable not used" warnings.
|
214 |
-
throw new Exception(
|
215 |
-
'There is no suitable CSPRNG installed on your system'
|
216 |
-
);
|
217 |
-
return '';
|
218 |
-
}
|
219 |
-
}
|
220 |
-
}
|
221 |
-
|
222 |
-
if (!is_callable('random_int')) {
|
223 |
-
require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_int.php';
|
224 |
-
}
|
225 |
-
|
226 |
-
$RandomCompatDIR = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('random_bytes')) {
|
30 |
-
/**
|
31 |
-
* Windows with PHP < 5.3.0 will not have the function
|
32 |
-
* openssl_random_pseudo_bytes() available, so let's use
|
33 |
-
* CAPICOM to work around this deficiency.
|
34 |
-
*
|
35 |
-
* @param int $bytes
|
36 |
-
*
|
37 |
-
* @throws Exception
|
38 |
-
*
|
39 |
-
* @return string
|
40 |
-
*/
|
41 |
-
function random_bytes($bytes)
|
42 |
-
{
|
43 |
-
try {
|
44 |
-
$bytes = RandomCompat_intval($bytes);
|
45 |
-
} catch (TypeError $ex) {
|
46 |
-
throw new TypeError(
|
47 |
-
'random_bytes(): $bytes must be an integer'
|
48 |
-
);
|
49 |
-
}
|
50 |
-
|
51 |
-
if ($bytes < 1) {
|
52 |
-
throw new Error(
|
53 |
-
'Length must be greater than 0'
|
54 |
-
);
|
55 |
-
}
|
56 |
-
|
57 |
-
$buf = '';
|
58 |
-
if (!class_exists('COM')) {
|
59 |
-
throw new Error(
|
60 |
-
'COM does not exist'
|
61 |
-
);
|
62 |
-
}
|
63 |
-
$util = new COM('CAPICOM.Utilities.1');
|
64 |
-
$execCount = 0;
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Let's not let it loop forever. If we run N times and fail to
|
68 |
-
* get N bytes of random data, then CAPICOM has failed us.
|
69 |
-
*/
|
70 |
-
do {
|
71 |
-
$buf .= base64_decode($util->GetRandom($bytes, 0));
|
72 |
-
if (RandomCompat_strlen($buf) >= $bytes) {
|
73 |
-
/**
|
74 |
-
* Return our random entropy buffer here:
|
75 |
-
*/
|
76 |
-
return RandomCompat_substr($buf, 0, $bytes);
|
77 |
-
}
|
78 |
-
++$execCount;
|
79 |
-
} while ($execCount < $bytes);
|
80 |
-
|
81 |
-
/**
|
82 |
-
* If we reach here, PHP has failed us.
|
83 |
-
*/
|
84 |
-
throw new Exception(
|
85 |
-
'Could not gather sufficient random data'
|
86 |
-
);
|
87 |
-
}
|
88 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
DELETED
@@ -1,167 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
30 |
-
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
31 |
-
}
|
32 |
-
|
33 |
-
if (!is_callable('random_bytes')) {
|
34 |
-
/**
|
35 |
-
* Unless open_basedir is enabled, use /dev/urandom for
|
36 |
-
* random numbers in accordance with best practices
|
37 |
-
*
|
38 |
-
* Why we use /dev/urandom and not /dev/random
|
39 |
-
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
|
40 |
-
*
|
41 |
-
* @param int $bytes
|
42 |
-
*
|
43 |
-
* @throws Exception
|
44 |
-
*
|
45 |
-
* @return string
|
46 |
-
*/
|
47 |
-
function random_bytes($bytes)
|
48 |
-
{
|
49 |
-
static $fp = null;
|
50 |
-
/**
|
51 |
-
* This block should only be run once
|
52 |
-
*/
|
53 |
-
if (empty($fp)) {
|
54 |
-
/**
|
55 |
-
* We use /dev/urandom if it is a char device.
|
56 |
-
* We never fall back to /dev/random
|
57 |
-
*/
|
58 |
-
$fp = fopen('/dev/urandom', 'rb');
|
59 |
-
if (!empty($fp)) {
|
60 |
-
$st = fstat($fp);
|
61 |
-
if (($st['mode'] & 0170000) !== 020000) {
|
62 |
-
fclose($fp);
|
63 |
-
$fp = false;
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
if (!empty($fp)) {
|
68 |
-
/**
|
69 |
-
* stream_set_read_buffer() does not exist in HHVM
|
70 |
-
*
|
71 |
-
* If we don't set the stream's read buffer to 0, PHP will
|
72 |
-
* internally buffer 8192 bytes, which can waste entropy
|
73 |
-
*
|
74 |
-
* stream_set_read_buffer returns 0 on success
|
75 |
-
*/
|
76 |
-
if (is_callable('stream_set_read_buffer')) {
|
77 |
-
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
|
78 |
-
}
|
79 |
-
if (is_callable('stream_set_chunk_size')) {
|
80 |
-
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
|
81 |
-
}
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
try {
|
86 |
-
$bytes = RandomCompat_intval($bytes);
|
87 |
-
} catch (TypeError $ex) {
|
88 |
-
throw new TypeError(
|
89 |
-
'random_bytes(): $bytes must be an integer'
|
90 |
-
);
|
91 |
-
}
|
92 |
-
|
93 |
-
if ($bytes < 1) {
|
94 |
-
throw new Error(
|
95 |
-
'Length must be greater than 0'
|
96 |
-
);
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* This if() block only runs if we managed to open a file handle
|
101 |
-
*
|
102 |
-
* It does not belong in an else {} block, because the above
|
103 |
-
* if (empty($fp)) line is logic that should only be run once per
|
104 |
-
* page load.
|
105 |
-
*/
|
106 |
-
if (!empty($fp)) {
|
107 |
-
/**
|
108 |
-
* @var int
|
109 |
-
*/
|
110 |
-
$remaining = $bytes;
|
111 |
-
|
112 |
-
/**
|
113 |
-
* @var string|bool
|
114 |
-
*/
|
115 |
-
$buf = '';
|
116 |
-
|
117 |
-
/**
|
118 |
-
* We use fread() in a loop to protect against partial reads
|
119 |
-
*/
|
120 |
-
do {
|
121 |
-
/**
|
122 |
-
* @var string|bool
|
123 |
-
*/
|
124 |
-
$read = fread($fp, $remaining);
|
125 |
-
if (!is_string($read)) {
|
126 |
-
if ($read === false) {
|
127 |
-
/**
|
128 |
-
* We cannot safely read from the file. Exit the
|
129 |
-
* do-while loop and trigger the exception condition
|
130 |
-
*
|
131 |
-
* @var string|bool
|
132 |
-
*/
|
133 |
-
$buf = false;
|
134 |
-
break;
|
135 |
-
}
|
136 |
-
}
|
137 |
-
/**
|
138 |
-
* Decrease the number of bytes returned from remaining
|
139 |
-
*/
|
140 |
-
$remaining -= RandomCompat_strlen($read);
|
141 |
-
/**
|
142 |
-
* @var string|bool
|
143 |
-
*/
|
144 |
-
$buf = $buf . $read;
|
145 |
-
} while ($remaining > 0);
|
146 |
-
|
147 |
-
/**
|
148 |
-
* Is our result valid?
|
149 |
-
*/
|
150 |
-
if (is_string($buf)) {
|
151 |
-
if (RandomCompat_strlen($buf) === $bytes) {
|
152 |
-
/**
|
153 |
-
* Return our random entropy buffer here:
|
154 |
-
*/
|
155 |
-
return $buf;
|
156 |
-
}
|
157 |
-
}
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* If we reach here, PHP has failed us.
|
162 |
-
*/
|
163 |
-
throw new Exception(
|
164 |
-
'Error reading from source device'
|
165 |
-
);
|
166 |
-
}
|
167 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('random_bytes')) {
|
30 |
-
/**
|
31 |
-
* If the libsodium PHP extension is loaded, we'll use it above any other
|
32 |
-
* solution.
|
33 |
-
*
|
34 |
-
* libsodium-php project:
|
35 |
-
* @ref https://github.com/jedisct1/libsodium-php
|
36 |
-
*
|
37 |
-
* @param int $bytes
|
38 |
-
*
|
39 |
-
* @throws Exception
|
40 |
-
*
|
41 |
-
* @return string
|
42 |
-
*/
|
43 |
-
function random_bytes($bytes)
|
44 |
-
{
|
45 |
-
try {
|
46 |
-
$bytes = RandomCompat_intval($bytes);
|
47 |
-
} catch (TypeError $ex) {
|
48 |
-
throw new TypeError(
|
49 |
-
'random_bytes(): $bytes must be an integer'
|
50 |
-
);
|
51 |
-
}
|
52 |
-
|
53 |
-
if ($bytes < 1) {
|
54 |
-
throw new Error(
|
55 |
-
'Length must be greater than 0'
|
56 |
-
);
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
61 |
-
* generated in one invocation.
|
62 |
-
*/
|
63 |
-
if ($bytes > 2147483647) {
|
64 |
-
$buf = '';
|
65 |
-
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
66 |
-
$n = ($bytes - $i) > 1073741824
|
67 |
-
? 1073741824
|
68 |
-
: $bytes - $i;
|
69 |
-
$buf .= \Sodium\randombytes_buf($n);
|
70 |
-
}
|
71 |
-
} else {
|
72 |
-
$buf = \Sodium\randombytes_buf($bytes);
|
73 |
-
}
|
74 |
-
|
75 |
-
if ($buf !== false) {
|
76 |
-
if (RandomCompat_strlen($buf) === $bytes) {
|
77 |
-
return $buf;
|
78 |
-
}
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* If we reach here, PHP has failed us.
|
83 |
-
*/
|
84 |
-
throw new Exception(
|
85 |
-
'Could not gather sufficient random data'
|
86 |
-
);
|
87 |
-
}
|
88 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
DELETED
@@ -1,92 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('random_bytes')) {
|
30 |
-
/**
|
31 |
-
* If the libsodium PHP extension is loaded, we'll use it above any other
|
32 |
-
* solution.
|
33 |
-
*
|
34 |
-
* libsodium-php project:
|
35 |
-
* @ref https://github.com/jedisct1/libsodium-php
|
36 |
-
*
|
37 |
-
* @param int $bytes
|
38 |
-
*
|
39 |
-
* @throws Exception
|
40 |
-
*
|
41 |
-
* @return string
|
42 |
-
*/
|
43 |
-
function random_bytes($bytes)
|
44 |
-
{
|
45 |
-
try {
|
46 |
-
$bytes = RandomCompat_intval($bytes);
|
47 |
-
} catch (TypeError $ex) {
|
48 |
-
throw new TypeError(
|
49 |
-
'random_bytes(): $bytes must be an integer'
|
50 |
-
);
|
51 |
-
}
|
52 |
-
|
53 |
-
if ($bytes < 1) {
|
54 |
-
throw new Error(
|
55 |
-
'Length must be greater than 0'
|
56 |
-
);
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* @var string
|
61 |
-
*/
|
62 |
-
$buf = '';
|
63 |
-
|
64 |
-
/**
|
65 |
-
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
66 |
-
* generated in one invocation.
|
67 |
-
*/
|
68 |
-
if ($bytes > 2147483647) {
|
69 |
-
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
70 |
-
$n = ($bytes - $i) > 1073741824
|
71 |
-
? 1073741824
|
72 |
-
: $bytes - $i;
|
73 |
-
$buf .= Sodium::randombytes_buf((int) $n);
|
74 |
-
}
|
75 |
-
} else {
|
76 |
-
$buf .= Sodium::randombytes_buf((int) $bytes);
|
77 |
-
}
|
78 |
-
|
79 |
-
if (is_string($buf)) {
|
80 |
-
if (RandomCompat_strlen($buf) === $bytes) {
|
81 |
-
return $buf;
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* If we reach here, PHP has failed us.
|
87 |
-
*/
|
88 |
-
throw new Exception(
|
89 |
-
'Could not gather sufficient random data'
|
90 |
-
);
|
91 |
-
}
|
92 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Random_* Compatibility Library
|
4 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
5 |
-
*
|
6 |
-
* The MIT License (MIT)
|
7 |
-
*
|
8 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
9 |
-
*
|
10 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
-
* of this software and associated documentation files (the "Software"), to deal
|
12 |
-
* in the Software without restriction, including without limitation the rights
|
13 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14 |
-
* copies of the Software, and to permit persons to whom the Software is
|
15 |
-
* furnished to do so, subject to the following conditions:
|
16 |
-
*
|
17 |
-
* The above copyright notice and this permission notice shall be included in
|
18 |
-
* all copies or substantial portions of the Software.
|
19 |
-
*
|
20 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26 |
-
* SOFTWARE.
|
27 |
-
*/
|
28 |
-
|
29 |
-
if (!is_callable('random_bytes')) {
|
30 |
-
/**
|
31 |
-
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
|
32 |
-
*
|
33 |
-
* @ref https://bugs.php.net/bug.php?id=55169
|
34 |
-
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
|
35 |
-
*
|
36 |
-
* @param int $bytes
|
37 |
-
*
|
38 |
-
* @throws Exception
|
39 |
-
*
|
40 |
-
* @return string
|
41 |
-
*/
|
42 |
-
function random_bytes($bytes)
|
43 |
-
{
|
44 |
-
try {
|
45 |
-
$bytes = RandomCompat_intval($bytes);
|
46 |
-
} catch (TypeError $ex) {
|
47 |
-
throw new TypeError(
|
48 |
-
'random_bytes(): $bytes must be an integer'
|
49 |
-
);
|
50 |
-
}
|
51 |
-
|
52 |
-
if ($bytes < 1) {
|
53 |
-
throw new Error(
|
54 |
-
'Length must be greater than 0'
|
55 |
-
);
|
56 |
-
}
|
57 |
-
|
58 |
-
$buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
|
59 |
-
if (
|
60 |
-
$buf !== false
|
61 |
-
&&
|
62 |
-
RandomCompat_strlen($buf) === $bytes
|
63 |
-
) {
|
64 |
-
/**
|
65 |
-
* Return our random entropy buffer here:
|
66 |
-
*/
|
67 |
-
return $buf;
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* If we reach here, PHP has failed us.
|
72 |
-
*/
|
73 |
-
throw new Exception(
|
74 |
-
'Could not gather sufficient random data'
|
75 |
-
);
|
76 |
-
}
|
77 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/lib/random_int.php
DELETED
@@ -1,190 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if (!is_callable('random_int')) {
|
4 |
-
/**
|
5 |
-
* Random_* Compatibility Library
|
6 |
-
* for using the new PHP 7 random_* API in PHP 5 projects
|
7 |
-
*
|
8 |
-
* The MIT License (MIT)
|
9 |
-
*
|
10 |
-
* Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
|
11 |
-
*
|
12 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 |
-
* of this software and associated documentation files (the "Software"), to deal
|
14 |
-
* in the Software without restriction, including without limitation the rights
|
15 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 |
-
* copies of the Software, and to permit persons to whom the Software is
|
17 |
-
* furnished to do so, subject to the following conditions:
|
18 |
-
*
|
19 |
-
* The above copyright notice and this permission notice shall be included in
|
20 |
-
* all copies or substantial portions of the Software.
|
21 |
-
*
|
22 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28 |
-
* SOFTWARE.
|
29 |
-
*/
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Fetch a random integer between $min and $max inclusive
|
33 |
-
*
|
34 |
-
* @param int $min
|
35 |
-
* @param int $max
|
36 |
-
*
|
37 |
-
* @throws Exception
|
38 |
-
*
|
39 |
-
* @return int
|
40 |
-
*/
|
41 |
-
function random_int($min, $max)
|
42 |
-
{
|
43 |
-
/**
|
44 |
-
* Type and input logic checks
|
45 |
-
*
|
46 |
-
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
47 |
-
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
48 |
-
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
49 |
-
* lose precision, so the <= and => operators might accidentally let a float
|
50 |
-
* through.
|
51 |
-
*/
|
52 |
-
|
53 |
-
try {
|
54 |
-
$min = RandomCompat_intval($min);
|
55 |
-
} catch (TypeError $ex) {
|
56 |
-
throw new TypeError(
|
57 |
-
'random_int(): $min must be an integer'
|
58 |
-
);
|
59 |
-
}
|
60 |
-
|
61 |
-
try {
|
62 |
-
$max = RandomCompat_intval($max);
|
63 |
-
} catch (TypeError $ex) {
|
64 |
-
throw new TypeError(
|
65 |
-
'random_int(): $max must be an integer'
|
66 |
-
);
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Now that we've verified our weak typing system has given us an integer,
|
71 |
-
* let's validate the logic then we can move forward with generating random
|
72 |
-
* integers along a given range.
|
73 |
-
*/
|
74 |
-
if ($min > $max) {
|
75 |
-
throw new Error(
|
76 |
-
'Minimum value must be less than or equal to the maximum value'
|
77 |
-
);
|
78 |
-
}
|
79 |
-
|
80 |
-
if ($max === $min) {
|
81 |
-
return (int) $min;
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Initialize variables to 0
|
86 |
-
*
|
87 |
-
* We want to store:
|
88 |
-
* $bytes => the number of random bytes we need
|
89 |
-
* $mask => an integer bitmask (for use with the &) operator
|
90 |
-
* so we can minimize the number of discards
|
91 |
-
*/
|
92 |
-
$attempts = $bits = $bytes = $mask = $valueShift = 0;
|
93 |
-
|
94 |
-
/**
|
95 |
-
* At this point, $range is a positive number greater than 0. It might
|
96 |
-
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
|
97 |
-
* a float and we will lose some precision.
|
98 |
-
*/
|
99 |
-
$range = $max - $min;
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Test for integer overflow:
|
103 |
-
*/
|
104 |
-
if (!is_int($range)) {
|
105 |
-
|
106 |
-
/**
|
107 |
-
* Still safely calculate wider ranges.
|
108 |
-
* Provided by @CodesInChaos, @oittaa
|
109 |
-
*
|
110 |
-
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
|
111 |
-
*
|
112 |
-
* We use ~0 as a mask in this case because it generates all 1s
|
113 |
-
*
|
114 |
-
* @ref https://eval.in/400356 (32-bit)
|
115 |
-
* @ref http://3v4l.org/XX9r5 (64-bit)
|
116 |
-
*/
|
117 |
-
$bytes = PHP_INT_SIZE;
|
118 |
-
$mask = ~0;
|
119 |
-
|
120 |
-
} else {
|
121 |
-
|
122 |
-
/**
|
123 |
-
* $bits is effectively ceil(log($range, 2)) without dealing with
|
124 |
-
* type juggling
|
125 |
-
*/
|
126 |
-
while ($range > 0) {
|
127 |
-
if ($bits % 8 === 0) {
|
128 |
-
++$bytes;
|
129 |
-
}
|
130 |
-
++$bits;
|
131 |
-
$range >>= 1;
|
132 |
-
$mask = $mask << 1 | 1;
|
133 |
-
}
|
134 |
-
$valueShift = $min;
|
135 |
-
}
|
136 |
-
|
137 |
-
$val = 0;
|
138 |
-
/**
|
139 |
-
* Now that we have our parameters set up, let's begin generating
|
140 |
-
* random integers until one falls between $min and $max
|
141 |
-
*/
|
142 |
-
do {
|
143 |
-
/**
|
144 |
-
* The rejection probability is at most 0.5, so this corresponds
|
145 |
-
* to a failure probability of 2^-128 for a working RNG
|
146 |
-
*/
|
147 |
-
if ($attempts > 128) {
|
148 |
-
throw new Exception(
|
149 |
-
'random_int: RNG is broken - too many rejections'
|
150 |
-
);
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* Let's grab the necessary number of random bytes
|
155 |
-
*/
|
156 |
-
$randomByteString = random_bytes($bytes);
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Let's turn $randomByteString into an integer
|
160 |
-
*
|
161 |
-
* This uses bitwise operators (<< and |) to build an integer
|
162 |
-
* out of the values extracted from ord()
|
163 |
-
*
|
164 |
-
* Example: [9F] | [6D] | [32] | [0C] =>
|
165 |
-
* 159 + 27904 + 3276800 + 201326592 =>
|
166 |
-
* 204631455
|
167 |
-
*/
|
168 |
-
$val &= 0;
|
169 |
-
for ($i = 0; $i < $bytes; ++$i) {
|
170 |
-
$val |= ord($randomByteString[$i]) << ($i * 8);
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Apply mask
|
175 |
-
*/
|
176 |
-
$val &= $mask;
|
177 |
-
$val += $valueShift;
|
178 |
-
|
179 |
-
++$attempts;
|
180 |
-
/**
|
181 |
-
* If $val overflows to a floating point number,
|
182 |
-
* ... or is larger than $max,
|
183 |
-
* ... or smaller than $min,
|
184 |
-
* then try again.
|
185 |
-
*/
|
186 |
-
} while (!is_int($val) || $val > $max || $val < $min);
|
187 |
-
|
188 |
-
return (int) $val;
|
189 |
-
}
|
190 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/other/build_phar.php
DELETED
@@ -1,57 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
$dist = dirname(__DIR__).'/dist';
|
3 |
-
if (!is_dir($dist)) {
|
4 |
-
mkdir($dist, 0755);
|
5 |
-
}
|
6 |
-
if (file_exists($dist.'/random_compat.phar')) {
|
7 |
-
unlink($dist.'/random_compat.phar');
|
8 |
-
}
|
9 |
-
$phar = new Phar(
|
10 |
-
$dist.'/random_compat.phar',
|
11 |
-
FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME,
|
12 |
-
'random_compat.phar'
|
13 |
-
);
|
14 |
-
rename(
|
15 |
-
dirname(__DIR__).'/lib/random.php',
|
16 |
-
dirname(__DIR__).'/lib/index.php'
|
17 |
-
);
|
18 |
-
$phar->buildFromDirectory(dirname(__DIR__).'/lib');
|
19 |
-
rename(
|
20 |
-
dirname(__DIR__).'/lib/index.php',
|
21 |
-
dirname(__DIR__).'/lib/random.php'
|
22 |
-
);
|
23 |
-
|
24 |
-
/**
|
25 |
-
* If we pass an (optional) path to a private key as a second argument, we will
|
26 |
-
* sign the Phar with OpenSSL.
|
27 |
-
*
|
28 |
-
* If you leave this out, it will produce an unsigned .phar!
|
29 |
-
*/
|
30 |
-
if ($argc > 1) {
|
31 |
-
if (!@is_readable($argv[1])) {
|
32 |
-
echo 'Could not read the private key file:', $argv[1], "\n";
|
33 |
-
exit(255);
|
34 |
-
}
|
35 |
-
$pkeyFile = file_get_contents($argv[1]);
|
36 |
-
|
37 |
-
$private = openssl_get_privatekey($pkeyFile);
|
38 |
-
if ($private !== false) {
|
39 |
-
$pkey = '';
|
40 |
-
openssl_pkey_export($private, $pkey);
|
41 |
-
$phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Save the corresponding public key to the file
|
45 |
-
*/
|
46 |
-
if (!@is_readable($dist.'/random_compat.phar.pubkey')) {
|
47 |
-
$details = openssl_pkey_get_details($private);
|
48 |
-
file_put_contents(
|
49 |
-
$dist.'/random_compat.phar.pubkey',
|
50 |
-
$details['key']
|
51 |
-
);
|
52 |
-
}
|
53 |
-
} else {
|
54 |
-
echo 'An error occurred reading the private key from OpenSSL.', "\n";
|
55 |
-
exit(255);
|
56 |
-
}
|
57 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/psalm-autoload.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once 'lib/byte_safe_strings.php';
|
4 |
-
require_once 'lib/cast_to_int.php';
|
5 |
-
require_once 'lib/error_polyfill.php';
|
6 |
-
require_once 'other/ide_stubs/libsodium.php';
|
7 |
-
require_once 'lib/random.php';
|
8 |
-
|
9 |
-
$int = random_int(0, 65536);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/paragonie/random_compat/psalm.xml
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
<?xml version="1.0"?>
|
2 |
-
<psalm
|
3 |
-
autoloader="psalm-autoload.php"
|
4 |
-
stopOnFirstError="false"
|
5 |
-
useDocblockTypes="true"
|
6 |
-
>
|
7 |
-
<projectFiles>
|
8 |
-
<directory name="lib" />
|
9 |
-
</projectFiles>
|
10 |
-
<issueHandlers>
|
11 |
-
<RedundantConditionGivenDocblockType errorLevel="info" />
|
12 |
-
<UnresolvableInclude errorLevel="info" />
|
13 |
-
<DuplicateClass errorLevel="info" />
|
14 |
-
<InvalidOperand errorLevel="info" />
|
15 |
-
<UndefinedConstant errorLevel="info" />
|
16 |
-
<MissingReturnType errorLevel="info" />
|
17 |
-
<InvalidReturnType errorLevel="info" />
|
18 |
-
</issueHandlers>
|
19 |
-
</psalm>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/vakata/jstree/README.md
CHANGED
@@ -62,8 +62,8 @@ To get started you need 3 things in your page:
|
|
62 |
```html
|
63 |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
64 |
|
65 |
-
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.
|
66 |
-
<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.
|
67 |
```
|
68 |
|
69 |
_If you decide to host jstree yourself - the files are located in the `dist` folder. You can safely ignore the `dist/libs` folder._
|
62 |
```html
|
63 |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
64 |
|
65 |
+
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.5/themes/default/style.min.css" />
|
66 |
+
<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.5/jstree.min.js"></script>
|
67 |
```
|
68 |
|
69 |
_If you decide to host jstree yourself - the files are located in the `dist` folder. You can safely ignore the `dist/libs` folder._
|
vendor/vakata/jstree/bower.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
{
|
2 |
"name": "jstree",
|
3 |
"license": "MIT",
|
4 |
-
"version": "3.3.
|
5 |
"main" : [
|
6 |
"./dist/jstree.js",
|
7 |
"./dist/themes/default/style.css"
|
1 |
{
|
2 |
"name": "jstree",
|
3 |
"license": "MIT",
|
4 |
+
"version": "3.3.7",
|
5 |
"main" : [
|
6 |
"./dist/jstree.js",
|
7 |
"./dist/themes/default/style.css"
|
vendor/vakata/jstree/component.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"name": "jstree",
|
3 |
"repo": "vakata/jstree",
|
4 |
"description": "jsTree is jquery plugin, that provides interactive trees.",
|
5 |
-
"version": "3.3.
|
6 |
"license": "MIT",
|
7 |
"keywords": [
|
8 |
"ui",
|
2 |
"name": "jstree",
|
3 |
"repo": "vakata/jstree",
|
4 |
"description": "jsTree is jquery plugin, that provides interactive trees.",
|
5 |
+
"version": "3.3.7",
|
6 |
"license": "MIT",
|
7 |
"keywords": [
|
8 |
"ui",
|
vendor/vakata/jstree/dist/jstree.js
CHANGED
@@ -13,7 +13,7 @@
|
|
13 |
}(function ($, undefined) {
|
14 |
"use strict";
|
15 |
/*!
|
16 |
-
* jsTree 3.3.
|
17 |
* http://jstree.com/
|
18 |
*
|
19 |
* Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
|
@@ -54,7 +54,7 @@
|
|
54 |
* specifies the jstree version in use
|
55 |
* @name $.jstree.version
|
56 |
*/
|
57 |
-
version : '3.3.
|
58 |
/**
|
59 |
* holds all the default options used when creating new instances
|
60 |
* @name $.jstree.defaults
|
@@ -430,7 +430,7 @@
|
|
430 |
*/
|
431 |
force_text : false,
|
432 |
/**
|
433 |
-
* Should the node
|
434 |
* @name $.jstree.defaults.core.dblclick_toggle
|
435 |
*/
|
436 |
dblclick_toggle : true,
|
@@ -1023,6 +1023,9 @@
|
|
1023 |
if(obj && obj.id) {
|
1024 |
obj = obj.id;
|
1025 |
}
|
|
|
|
|
|
|
1026 |
var dom;
|
1027 |
try {
|
1028 |
if(this._model.data[obj]) {
|
@@ -1034,10 +1037,10 @@
|
|
1034 |
else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
|
1035 |
obj = this._model.data[dom.closest('.jstree-node').attr('id')];
|
1036 |
}
|
1037 |
-
else if((dom =
|
1038 |
obj = this._model.data[dom.closest('.jstree-node').attr('id')];
|
1039 |
}
|
1040 |
-
else if((dom =
|
1041 |
obj = this._model.data[$.jstree.root];
|
1042 |
}
|
1043 |
else {
|
@@ -1331,7 +1334,7 @@
|
|
1331 |
return true;
|
1332 |
},
|
1333 |
/**
|
1334 |
-
* load an array of nodes (will also load unavailable nodes as soon as
|
1335 |
* @private
|
1336 |
* @name _load_nodes(nodes [, callback])
|
1337 |
* @param {array} nodes
|
@@ -2325,7 +2328,7 @@
|
|
2325 |
this.element.empty().append(f);
|
2326 |
//this.get_container_ul()[0].appendChild(f);
|
2327 |
}
|
2328 |
-
if(fe !== null) {
|
2329 |
tmp = this.get_node(fe, true);
|
2330 |
if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) {
|
2331 |
tmp.children('.jstree-anchor').focus();
|
@@ -2608,7 +2611,7 @@
|
|
2608 |
return node;
|
2609 |
},
|
2610 |
/**
|
2611 |
-
* opens a node,
|
2612 |
* @name open_node(obj [, callback, animation])
|
2613 |
* @param {mixed} obj the node to open
|
2614 |
* @param {Function} callback a function to execute once the node is opened
|
@@ -2812,7 +2815,7 @@
|
|
2812 |
}
|
2813 |
},
|
2814 |
/**
|
2815 |
-
* opens all nodes within a node (or the tree),
|
2816 |
* @name open_all([obj, animation, original_obj])
|
2817 |
* @param {mixed} obj the node to open recursively, omit to open all nodes in the tree
|
2818 |
* @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation
|
@@ -2853,7 +2856,7 @@
|
|
2853 |
}
|
2854 |
},
|
2855 |
/**
|
2856 |
-
* closes all nodes within a node (or the tree),
|
2857 |
* @name close_all([obj, animation])
|
2858 |
* @param {mixed} obj the node to close recursively, omit to close all nodes in the tree
|
2859 |
* @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation
|
@@ -4491,7 +4494,7 @@
|
|
4491 |
w2 = ai.width() * ai.length,
|
4492 |
*/
|
4493 |
t = default_text;
|
4494 |
-
h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo(
|
4495 |
h2 = $("<"+"input />", {
|
4496 |
"value" : t,
|
4497 |
"class" : "jstree-rename-input",
|
@@ -4517,6 +4520,7 @@
|
|
4517 |
s.replaceWith(a);
|
4518 |
s.remove();
|
4519 |
t = f ? t : $('<div></div>').append($.parseHTML(t)).html();
|
|
|
4520 |
this.set_text(obj, t);
|
4521 |
nv = !!this.rename_node(obj, f ? $('<div></div>').text(v).text() : $('<div></div>').append($.parseHTML(v)).html()
|
13 |
}(function ($, undefined) {
|
14 |
"use strict";
|
15 |
/*!
|
16 |
+
* jsTree 3.3.7
|
17 |
* http://jstree.com/
|
18 |
*
|
19 |
* Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
|
54 |
* specifies the jstree version in use
|
55 |
* @name $.jstree.version
|
56 |
*/
|
57 |
+
version : '3.3.7',
|
58 |
/**
|
59 |
* holds all the default options used when creating new instances
|
60 |
* @name $.jstree.defaults
|
430 |
*/
|
431 |
force_text : false,
|
432 |
/**
|
433 |
+
* Should the node be toggled if the text is double clicked. Defaults to `true`
|
434 |
* @name $.jstree.defaults.core.dblclick_toggle
|
435 |
*/
|
436 |
dblclick_toggle : true,
|
1023 |
if(obj && obj.id) {
|
1024 |
obj = obj.id;
|
1025 |
}
|
1026 |
+
if (obj instanceof jQuery && obj.length && obj[0].id) {
|
1027 |
+
obj = obj[0].id;
|
1028 |
+
}
|
1029 |
var dom;
|
1030 |
try {
|
1031 |
if(this._model.data[obj]) {
|
1037 |
else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
|
1038 |
obj = this._model.data[dom.closest('.jstree-node').attr('id')];
|
1039 |
}
|
1040 |
+
else if((dom = this.element.find(obj)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
|
1041 |
obj = this._model.data[dom.closest('.jstree-node').attr('id')];
|
1042 |
}
|
1043 |
+
else if((dom = this.element.find(obj)).length && dom.hasClass('jstree')) {
|
1044 |
obj = this._model.data[$.jstree.root];
|
1045 |
}
|
1046 |
else {
|
1334 |
return true;
|
1335 |
},
|
1336 |
/**
|
1337 |
+
* load an array of nodes (will also load unavailable nodes as soon as they appear in the structure). Used internally.
|
1338 |
* @private
|
1339 |
* @name _load_nodes(nodes [, callback])
|
1340 |
* @param {array} nodes
|
2328 |
this.element.empty().append(f);
|
2329 |
//this.get_container_ul()[0].appendChild(f);
|
2330 |
}
|
2331 |
+
if(fe !== null && this.settings.core.restore_focus) {
|
2332 |
tmp = this.get_node(fe, true);
|
2333 |
if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) {
|
2334 |
tmp.children('.jstree-anchor').focus();
|
2611 |
return node;
|
2612 |
},
|
2613 |
/**
|
2614 |
+
* opens a node, revealing its children. If the node is not loaded it will be loaded and opened once ready.
|
2615 |
* @name open_node(obj [, callback, animation])
|
2616 |
* @param {mixed} obj the node to open
|
2617 |
* @param {Function} callback a function to execute once the node is opened
|
2815 |
}
|
2816 |
},
|
2817 |
/**
|
2818 |
+
* opens all nodes within a node (or the tree), revealing their children. If the node is not loaded it will be loaded and opened once ready.
|
2819 |
* @name open_all([obj, animation, original_obj])
|
2820 |
* @param {mixed} obj the node to open recursively, omit to open all nodes in the tree
|
2821 |
* @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation
|
2856 |
}
|
2857 |
},
|
2858 |
/**
|
2859 |
+
* closes all nodes within a node (or the tree), revealing their children
|
2860 |
* @name close_all([obj, animation])
|
2861 |
* @param {mixed} obj the node to close recursively, omit to close all nodes in the tree
|
2862 |
* @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation
|
4494 |
w2 = ai.width() * ai.length,
|
4495 |
*/
|
4496 |
t = default_text;
|
4497 |
+
h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo(document.body);
|
4498 |
h2 = $("<"+"input />", {
|
4499 |
"value" : t,
|
4500 |
"class" : "jstree-rename-input",
|
4520 |
s.replaceWith(a);
|
4521 |
s.remove();
|
4522 |
t = f ? t : $('<div></div>').append($.parseHTML(t)).html();
|
4523 |
+
obj = this.get_node(obj);
|
4524 |
this.set_text(obj, t);
|
4525 |
nv = !!this.rename_node(obj, f ? $('<div></div>').text(v).text() : $('<div></div>').append($.parseHTML(v)).html()
|