Version Description
- Making Login Protection more configurable.
- Robust handling of requests params.
- Callback wing versioning.
Download this release
Release Info
Developer | ritesh.soni36 |
Plugin | The WP Remote WordPress Plugin |
Version | 4.65 |
Comparing to | |
See all releases |
Code changes from version 4.64 to 4.65
- callback/base.php +17 -0
- callback/request.php +47 -0
- callback/wings/account.php +2 -0
- callback/wings/actlog.php +2 -0
- callback/wings/brand.php +2 -0
- callback/wings/bv_upgrader_skin.php +2 -0
- callback/wings/db.php +2 -0
- callback/wings/dynsync.php +2 -0
- callback/wings/fs.php +1 -0
- callback/wings/fs_write.php +1 -0
- callback/wings/info.php +4 -2
- callback/wings/manage.php +2 -0
- callback/wings/misc.php +68 -0
- callback/wings/protect.php +2 -0
- callback/wings/watch.php +2 -0
- info.php +1 -1
- old_wpremote/cli/wprp.cli.php +0 -25
- old_wpremote/inc/class-wprp-automatic-upgrader-skin.php +0 -23
- old_wpremote/inc/class-wprp-core-upgrader-skin.php +0 -23
- old_wpremote/inc/class-wprp-plugin-upgrader-skin.php +0 -23
- old_wpremote/inc/class-wprp-theme-upgrader-skin.php +0 -24
- old_wpremote/languages/index.php +0 -6
- old_wpremote/languages/wp-remote-wordpress-plugin.mo +0 -0
- old_wpremote/languages/wp-remote-wordpress-plugin.pot +0 -148
- old_wpremote/plugin.php +0 -283
- old_wpremote/wprp.api.php +0 -726
- old_wpremote/wprp.backups.php +0 -698
- old_wpremote/wprp.compatability.php +0 -82
- old_wpremote/wprp.content.php +0 -31
- old_wpremote/wprp.hm.backup.php +0 -2279
- old_wpremote/wprp.integration.php +0 -16
- old_wpremote/wprp.log.php +0 -140
- old_wpremote/wprp.plugins.php +0 -394
- old_wpremote/wprp.themes.php +0 -246
- plugin.php +3 -9
- protect/wp/lp/config.php +6 -0
- protect/wp/lp/lp.php +15 -3
- readme.txt +6 -1
callback/base.php
CHANGED
@@ -4,6 +4,23 @@ if (!defined('ABSPATH')) exit;
|
|
4 |
if (!class_exists('BVCallbackBase')) :
|
5 |
|
6 |
class BVCallbackBase {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
public function objectToArray($obj) {
|
8 |
return json_decode(json_encode($obj), true);
|
9 |
}
|
4 |
if (!class_exists('BVCallbackBase')) :
|
5 |
|
6 |
class BVCallbackBase {
|
7 |
+
|
8 |
+
const WING_INFOS = array("MANAGE_WING_VERSION" => '1.0',
|
9 |
+
"ACTLOG_WING_VERSION" => '1.0',
|
10 |
+
"DYNSYNC_WING_VERSION" => '1.0',
|
11 |
+
"UPGRADER_WING_VERSION" => '1.0',
|
12 |
+
"BRAND_WING_VERSION" => '1.0',
|
13 |
+
"DB_WING_VERSION" => '1.0',
|
14 |
+
"ACCOUNT_WING_VERSION" => '1.0',
|
15 |
+
"MISC_WING_VERSION" => '1.0',
|
16 |
+
"FS_WING_VERSION" => '1.0',
|
17 |
+
"INFO_WING_VERSION" => '1.0',
|
18 |
+
"WATCH_WING_VERSION" => '1.0',
|
19 |
+
"FS_WRITE_WING_VERSION" => '1.0',
|
20 |
+
"IPSTORE_WING_VERSION" => '1.0',
|
21 |
+
"PROTECT_WING_VERSION" => '1.0',
|
22 |
+
);
|
23 |
+
|
24 |
public function objectToArray($obj) {
|
25 |
return json_decode(json_encode($obj), true);
|
26 |
}
|
callback/request.php
CHANGED
@@ -40,6 +40,46 @@ if (!class_exists('BVCallbackRequest')) :
|
|
40 |
return array_key_exists('apicall', $this->params);
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
public function info() {
|
44 |
$info = array(
|
45 |
"requestedsig" => $this->sig,
|
@@ -81,6 +121,13 @@ if (!class_exists('BVCallbackRequest')) :
|
|
81 |
}
|
82 |
}
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms']) &&
|
85 |
array_key_exists('bvprmsmac', $in_params) && isset($in_params['bvprmsmac'])) {
|
86 |
$digest_algo = 'SHA1';
|
40 |
return array_key_exists('apicall', $this->params);
|
41 |
}
|
42 |
|
43 |
+
public function curlRequest($url, $body) {
|
44 |
+
$ch = curl_init($url);
|
45 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
46 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
|
47 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($body));
|
48 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
49 |
+
return curl_exec($ch);
|
50 |
+
}
|
51 |
+
|
52 |
+
public function fileGetContentRequest($url, $body) {
|
53 |
+
$options = array(
|
54 |
+
'http' => array(
|
55 |
+
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
56 |
+
'method' => 'POST',
|
57 |
+
'content' => http_build_query($body)
|
58 |
+
)
|
59 |
+
);
|
60 |
+
|
61 |
+
$context = stream_context_create($options);
|
62 |
+
return file_get_contents($url, false, $context);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function http_request($url, $body) {
|
66 |
+
if (in_array('curl', get_loaded_extensions())) {
|
67 |
+
return $this->curlRequest($url, $body);
|
68 |
+
} else {
|
69 |
+
return $this->fileGetContentRequest($url, $body);
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
public function get_params_via_api($params_key, $apiurl) {
|
74 |
+
$res = $this->http_request($apiurl, array('bvkey' => $params_key));
|
75 |
+
|
76 |
+
if ($res === FALSE) {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
|
80 |
+
return $res;
|
81 |
+
}
|
82 |
+
|
83 |
public function info() {
|
84 |
$info = array(
|
85 |
"requestedsig" => $this->sig,
|
121 |
}
|
122 |
}
|
123 |
|
124 |
+
if (isset($in_params['bvpdataviaapi']) && isset($in_params['bvapiurl'])) {
|
125 |
+
$pdata = $this->get_params_via_api($in_params['bvpdataviaapi'], $in_params['bvapiurl']);
|
126 |
+
if ($pdata !== false) {
|
127 |
+
$in_params["bvprms"] = $pdata;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms']) &&
|
132 |
array_key_exists('bvprmsmac', $in_params) && isset($in_params['bvprmsmac'])) {
|
133 |
$digest_algo = 'SHA1';
|
callback/wings/account.php
CHANGED
@@ -5,6 +5,8 @@ if (!class_exists('BVAccountCallback')) :
|
|
5 |
class BVAccountCallback extends BVCallbackBase {
|
6 |
public $account;
|
7 |
public $settings;
|
|
|
|
|
8 |
|
9 |
public function __construct($callback_handler) {
|
10 |
$this->account = $callback_handler->account;
|
5 |
class BVAccountCallback extends BVCallbackBase {
|
6 |
public $account;
|
7 |
public $settings;
|
8 |
+
|
9 |
+
const ACCOUNT_WING_VERSION = 1.0;
|
10 |
|
11 |
public function __construct($callback_handler) {
|
12 |
$this->account = $callback_handler->account;
|
callback/wings/actlog.php
CHANGED
@@ -9,6 +9,8 @@ class BVActLogCallback extends BVCallbackBase {
|
|
9 |
public $db;
|
10 |
public $settings;
|
11 |
|
|
|
|
|
12 |
public function __construct($callback_handler) {
|
13 |
$this->db = $callback_handler->db;
|
14 |
$this->settings = $callback_handler->settings;
|
9 |
public $db;
|
10 |
public $settings;
|
11 |
|
12 |
+
const ACTLOG_WING_VERSION = 1.0;
|
13 |
+
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->settings = $callback_handler->settings;
|
callback/wings/brand.php
CHANGED
@@ -6,6 +6,8 @@ if (!class_exists('BVBrandCallback')) :
|
|
6 |
class BVBrandCallback extends BVCallbackBase {
|
7 |
public $settings;
|
8 |
|
|
|
|
|
9 |
public function __construct($callback_handler) {
|
10 |
$this->settings = $callback_handler->settings;
|
11 |
}
|
6 |
class BVBrandCallback extends BVCallbackBase {
|
7 |
public $settings;
|
8 |
|
9 |
+
const BRAND_WING_VERSION = 1.0;
|
10 |
+
|
11 |
public function __construct($callback_handler) {
|
12 |
$this->settings = $callback_handler->settings;
|
13 |
}
|
callback/wings/bv_upgrader_skin.php
CHANGED
@@ -9,6 +9,8 @@ class BVUpgraderSkin extends WP_Upgrader_Skin {
|
|
9 |
public $theme_info = array();
|
10 |
public $language_update = null;
|
11 |
|
|
|
|
|
12 |
function __construct($type, $package = '') {
|
13 |
$this->action = $type;
|
14 |
$this->package = $package;
|
9 |
public $theme_info = array();
|
10 |
public $language_update = null;
|
11 |
|
12 |
+
const UPGRADER_WING_VERSION = 1.0;
|
13 |
+
|
14 |
function __construct($type, $package = '') {
|
15 |
$this->action = $type;
|
16 |
$this->package = $package;
|
callback/wings/db.php
CHANGED
@@ -11,6 +11,8 @@ class BVDBCallback extends BVCallbackBase {
|
|
11 |
|
12 |
public static $bvTables = array("fw_requests", "lp_requests", "ip_store");
|
13 |
|
|
|
|
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->account = $callback_handler->account;
|
11 |
|
12 |
public static $bvTables = array("fw_requests", "lp_requests", "ip_store");
|
13 |
|
14 |
+
const DB_WING_VERSION = 1.0;
|
15 |
+
|
16 |
public function __construct($callback_handler) {
|
17 |
$this->db = $callback_handler->db;
|
18 |
$this->account = $callback_handler->account;
|
callback/wings/dynsync.php
CHANGED
@@ -9,6 +9,8 @@ class BVDynSyncCallback extends BVCallbackBase {
|
|
9 |
public $db;
|
10 |
public $settings;
|
11 |
|
|
|
|
|
12 |
public function __construct($callback_handler) {
|
13 |
$this->db = $callback_handler->db;
|
14 |
$this->settings = $callback_handler->settings;
|
9 |
public $db;
|
10 |
public $settings;
|
11 |
|
12 |
+
const DYNSYNC_WING_VERSION = 1.0;
|
13 |
+
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->settings = $callback_handler->settings;
|
callback/wings/fs.php
CHANGED
@@ -9,6 +9,7 @@ class BVFSCallback extends BVCallbackBase {
|
|
9 |
public $account;
|
10 |
|
11 |
public static $cwAllowedFiles = array(".htaccess", ".user.ini", "malcare-waf.php");
|
|
|
12 |
|
13 |
public function __construct($callback_handler) {
|
14 |
$this->account = $callback_handler->account;
|
9 |
public $account;
|
10 |
|
11 |
public static $cwAllowedFiles = array(".htaccess", ".user.ini", "malcare-waf.php");
|
12 |
+
const FS_WING_VERSION = 1.0;
|
13 |
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->account = $callback_handler->account;
|
callback/wings/fs_write.php
CHANGED
@@ -6,6 +6,7 @@ if (!class_exists('BVFSWriteCallback')) :
|
|
6 |
class BVFSWriteCallback extends BVCallbackBase {
|
7 |
|
8 |
const MEGABYTE = 1048576;
|
|
|
9 |
|
10 |
public function __construct() {
|
11 |
}
|
6 |
class BVFSWriteCallback extends BVCallbackBase {
|
7 |
|
8 |
const MEGABYTE = 1048576;
|
9 |
+
const FS_WRITE_WING_VERSION = 1.0;
|
10 |
|
11 |
public function __construct() {
|
12 |
}
|
callback/wings/info.php
CHANGED
@@ -8,6 +8,8 @@ class BVInfoCallback extends BVCallbackBase {
|
|
8 |
public $settings;
|
9 |
public $siteinfo;
|
10 |
public $bvinfo;
|
|
|
|
|
11 |
|
12 |
public function __construct($callback_handler) {
|
13 |
$this->db = $callback_handler->db;
|
@@ -156,7 +158,7 @@ class BVInfoCallback extends BVCallbackBase {
|
|
156 |
return array("wp" => $wp_info);
|
157 |
}
|
158 |
|
159 |
-
public function getUsers($args = array()
|
160 |
$results = array();
|
161 |
$users = get_users($args);
|
162 |
if ('true' == $full) {
|
@@ -301,7 +303,7 @@ class BVInfoCallback extends BVCallbackBase {
|
|
301 |
$full = false;
|
302 |
if (array_key_exists('full', $params))
|
303 |
$full = true;
|
304 |
-
$resp = $this->getUsers($params['args']
|
305 |
break;
|
306 |
case "gttrnsnt":
|
307 |
$transient = $this->settings->getTransient($params['name']);
|
8 |
public $settings;
|
9 |
public $siteinfo;
|
10 |
public $bvinfo;
|
11 |
+
|
12 |
+
const INFO_WING_VERSION = 1.0;
|
13 |
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->db = $callback_handler->db;
|
158 |
return array("wp" => $wp_info);
|
159 |
}
|
160 |
|
161 |
+
public function getUsers($full, $args = array()) {
|
162 |
$results = array();
|
163 |
$users = get_users($args);
|
164 |
if ('true' == $full) {
|
303 |
$full = false;
|
304 |
if (array_key_exists('full', $params))
|
305 |
$full = true;
|
306 |
+
$resp = $this->getUsers($full, $params['args']);
|
307 |
break;
|
308 |
case "gttrnsnt":
|
309 |
$transient = $this->settings->getTransient($params['name']);
|
callback/wings/manage.php
CHANGED
@@ -6,6 +6,8 @@ class BVManageCallback extends BVCallbackBase {
|
|
6 |
public $settings;
|
7 |
public $skin;
|
8 |
|
|
|
|
|
9 |
public function __construct($callback_handler) {
|
10 |
$this->settings = $callback_handler->settings;
|
11 |
}
|
6 |
public $settings;
|
7 |
public $skin;
|
8 |
|
9 |
+
const MANAGE_WING_VERSION = 1.0;
|
10 |
+
|
11 |
public function __construct($callback_handler) {
|
12 |
$this->settings = $callback_handler->settings;
|
13 |
}
|
callback/wings/misc.php
CHANGED
@@ -9,11 +9,15 @@ class BVMiscCallback extends BVCallbackBase {
|
|
9 |
public $siteinfo;
|
10 |
public $account;
|
11 |
public $bvapi;
|
|
|
|
|
|
|
12 |
|
13 |
public function __construct($callback_handler) {
|
14 |
$this->settings = $callback_handler->settings;
|
15 |
$this->siteinfo = $callback_handler->siteinfo;
|
16 |
$this->account = $callback_handler->account;
|
|
|
17 |
$this->bvinfo = new WPRInfo($callback_handler->settings);
|
18 |
$this->bvapi = new WPRWPAPI($callback_handler->settings);
|
19 |
}
|
@@ -44,6 +48,54 @@ class BVMiscCallback extends BVCallbackBase {
|
|
44 |
return array("wpupdatethemes" => true);
|
45 |
}
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
public function process($request) {
|
48 |
$bvinfo = $this->bvinfo;
|
49 |
$settings = $this->settings;
|
@@ -54,6 +106,7 @@ class BVMiscCallback extends BVCallbackBase {
|
|
54 |
$resp = array_merge($resp, $this->siteinfo->info());
|
55 |
$resp = array_merge($resp, $this->account->info());
|
56 |
$resp = array_merge($resp, $this->bvinfo->info());
|
|
|
57 |
break;
|
58 |
case "pngbv":
|
59 |
$info = array();
|
@@ -123,6 +176,21 @@ class BVMiscCallback extends BVCallbackBase {
|
|
123 |
$resp["updated_configs"] = $updated_configs;
|
124 |
$resp["deleted_configs"] = $deleted_configs;
|
125 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
default:
|
127 |
$resp = false;
|
128 |
}
|
9 |
public $siteinfo;
|
10 |
public $account;
|
11 |
public $bvapi;
|
12 |
+
public $db;
|
13 |
+
|
14 |
+
const MISC_WING_VERSION = 1.0;
|
15 |
|
16 |
public function __construct($callback_handler) {
|
17 |
$this->settings = $callback_handler->settings;
|
18 |
$this->siteinfo = $callback_handler->siteinfo;
|
19 |
$this->account = $callback_handler->account;
|
20 |
+
$this->db = $callback_handler->db;
|
21 |
$this->bvinfo = new WPRInfo($callback_handler->settings);
|
22 |
$this->bvapi = new WPRWPAPI($callback_handler->settings);
|
23 |
}
|
48 |
return array("wpupdatethemes" => true);
|
49 |
}
|
50 |
|
51 |
+
public function getWingInfo() {
|
52 |
+
return array('wing_info' => self::WING_INFOS);
|
53 |
+
}
|
54 |
+
|
55 |
+
public function post_types_data($post_params) {
|
56 |
+
$result = array();
|
57 |
+
$get_post_types_args = $post_params['get_post_types_args'];
|
58 |
+
$post_types = get_post_types($get_post_types_args);
|
59 |
+
$post_types = array_merge($post_types, $post_params['include_post_types']);
|
60 |
+
$post_types = array_diff( $post_types, $post_params['exclude_post_types']);
|
61 |
+
$result['post_types'] = $post_types;
|
62 |
+
$post_types = esc_sql($post_types);
|
63 |
+
$post_types = "'" . implode("','", $post_types) . "'";
|
64 |
+
$post_table = $post_params['table'];
|
65 |
+
$post_select_columns = implode(", ", $post_params['select_column']);
|
66 |
+
$post_query = "SELECT MAX(ID) as $post_select_columns FROM ( SELECT
|
67 |
+
$post_select_columns FROM $post_table WHERE post_type IN ( $post_types )
|
68 |
+
AND post_status='publish' ORDER BY post_date DESC ) AS posts GROUP BY post_type";
|
69 |
+
$posts = $this->db->getResult($post_query);
|
70 |
+
foreach ( $posts as $key => $post ) {
|
71 |
+
$posts[$key]['url'] = get_permalink($post);
|
72 |
+
}
|
73 |
+
$result['posts'] = $posts;
|
74 |
+
return $result;
|
75 |
+
}
|
76 |
+
|
77 |
+
public function taxonomy_data($taxonomy_params) {
|
78 |
+
$result = array();
|
79 |
+
$get_taxonomies_args = $taxonomy_params['get_taxonomies_args'];
|
80 |
+
$taxonomies = get_taxonomies($get_taxonomies_args);
|
81 |
+
$taxonomies = array_diff($taxonomies, $taxonomy_params['exclude_taxonomies']);
|
82 |
+
$result['taxonomies'] = $taxonomies;
|
83 |
+
$taxonomies = esc_sql( $taxonomies );
|
84 |
+
$taxonomies = "'" . implode( "','", $taxonomies ) . "'";
|
85 |
+
$taxonomy_table = $taxonomy_params['table'];
|
86 |
+
$taxonomy_select_columns = implode(", ", $taxonomy_params['select_column']);
|
87 |
+
$taxonomy_query = "SELECT MAX( term_id ) AS $taxonomy_select_columns FROM (
|
88 |
+
SELECT $taxonomy_select_columns FROM $taxonomy_table WHERE taxonomy IN (
|
89 |
+
$taxonomies ) AND count > 0) AS taxonomies GROUP BY taxonomy";
|
90 |
+
|
91 |
+
$taxonomies = $this->db->getResult($taxonomy_query);
|
92 |
+
foreach($taxonomies as $key => $taxonomy) {
|
93 |
+
$taxonomies[$key]['url'] = get_term_link((int)$taxonomy['term_id'], $taxonomy['taxonomy']);
|
94 |
+
}
|
95 |
+
$result['taxonomy_data'] = $taxonomies;
|
96 |
+
return $result;
|
97 |
+
}
|
98 |
+
|
99 |
public function process($request) {
|
100 |
$bvinfo = $this->bvinfo;
|
101 |
$settings = $this->settings;
|
106 |
$resp = array_merge($resp, $this->siteinfo->info());
|
107 |
$resp = array_merge($resp, $this->account->info());
|
108 |
$resp = array_merge($resp, $this->bvinfo->info());
|
109 |
+
$resp = array_merge($resp, $this->getWingInfo());
|
110 |
break;
|
111 |
case "pngbv":
|
112 |
$info = array();
|
176 |
$resp["updated_configs"] = $updated_configs;
|
177 |
$resp["deleted_configs"] = $deleted_configs;
|
178 |
break;
|
179 |
+
case "critical_css_data":
|
180 |
+
$resp = array();
|
181 |
+
if (array_key_exists('fetch_post_data', $params) && $params['fetch_post_data'] == true) {
|
182 |
+
$post_params = $params['post_params'];
|
183 |
+
$post_result = $this->post_types_data($post_params);
|
184 |
+
$resp['post_cp_results'] = $post_result['posts'];
|
185 |
+
$resp['post_types'] = $post_result['post_types'];
|
186 |
+
}
|
187 |
+
if (array_key_exists('fetch_taxonomy_data', $params) && $params['fetch_taxonomy_data'] == true) {
|
188 |
+
$taxonomy_params = $params['taxonomy_params'];
|
189 |
+
$taxonomy_result = $this->taxonomy_data($taxonomy_params);
|
190 |
+
$resp['taxonomy_cp_results'] = $taxonomy_result['taxonomy_data'];
|
191 |
+
$resp['taxonomies'] = $taxonomy_result['taxonomies'];
|
192 |
+
}
|
193 |
+
break;
|
194 |
default:
|
195 |
$resp = false;
|
196 |
}
|
callback/wings/protect.php
CHANGED
@@ -11,6 +11,8 @@ class BVProtectCallback extends BVCallbackBase {
|
|
11 |
public $db;
|
12 |
public $settings;
|
13 |
|
|
|
|
|
14 |
public function __construct($callback_handler) {
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->settings = $callback_handler->settings;
|
11 |
public $db;
|
12 |
public $settings;
|
13 |
|
14 |
+
const PROTECT_WING_VERSION = 1.0;
|
15 |
+
|
16 |
public function __construct($callback_handler) {
|
17 |
$this->db = $callback_handler->db;
|
18 |
$this->settings = $callback_handler->settings;
|
callback/wings/watch.php
CHANGED
@@ -7,6 +7,8 @@ class BVWatchCallback extends BVCallbackBase {
|
|
7 |
public $db;
|
8 |
public $settings;
|
9 |
|
|
|
|
|
10 |
public function __construct($callback_handler) {
|
11 |
$this->db = $callback_handler->db;
|
12 |
$this->settings = $callback_handler->settings;
|
7 |
public $db;
|
8 |
public $settings;
|
9 |
|
10 |
+
const WATCH_WING_VERSION = 1.0;
|
11 |
+
|
12 |
public function __construct($callback_handler) {
|
13 |
$this->db = $callback_handler->db;
|
14 |
$this->settings = $callback_handler->settings;
|
info.php
CHANGED
@@ -10,7 +10,7 @@ if (!class_exists('WPRInfo')) :
|
|
10 |
public $badgeinfo = 'wprbadge';
|
11 |
public $ip_header_option = 'wpripheader';
|
12 |
public $brand_option = 'wprbrand';
|
13 |
-
public $version = '4.
|
14 |
public $webpage = 'https://wpremote.com';
|
15 |
public $appurl = 'https://app.wpremote.com';
|
16 |
public $slug = 'wpremote/plugin.php';
|
10 |
public $badgeinfo = 'wprbadge';
|
11 |
public $ip_header_option = 'wpripheader';
|
12 |
public $brand_option = 'wprbrand';
|
13 |
+
public $version = '4.65';
|
14 |
public $webpage = 'https://wpremote.com';
|
15 |
public $appurl = 'https://app.wpremote.com';
|
16 |
public $slug = 'wpremote/plugin.php';
|
old_wpremote/cli/wprp.cli.php
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPRP_tasks extends WP_CLI_Command {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Find work for this process, will make this process now block
|
7 |
-
*
|
8 |
-
* @subcommand set-api
|
9 |
-
*/
|
10 |
-
public function send_emails( $args, $assoc_args ) {
|
11 |
-
$count = count($args);
|
12 |
-
if ($count == 0 || $count > 1) {
|
13 |
-
WP_CLI::line( 'Please set the args correctly' );
|
14 |
-
die();
|
15 |
-
}
|
16 |
-
delete_option( 'wpr_api_key' );
|
17 |
-
add_option( 'wpr_api_key', $args[0]);
|
18 |
-
WP_CLI::line( 'API Key Set' );
|
19 |
-
|
20 |
-
// WP_CLI::line( sprintf( "[%s] Worker %d completed its work.", date( 'Y-m-d H:i:s' ), getmypid() ) );
|
21 |
-
}
|
22 |
-
|
23 |
-
}
|
24 |
-
|
25 |
-
WP_CLI::add_command( 'wpremote', 'WPRP_tasks' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/inc/class-wprp-automatic-upgrader-skin.php
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPRP_Automatic_Upgrader_Skin extends Automatic_Upgrader_Skin {
|
4 |
-
|
5 |
-
var $feedback;
|
6 |
-
var $error;
|
7 |
-
|
8 |
-
function error( $error ) {
|
9 |
-
$this->error = $error;
|
10 |
-
}
|
11 |
-
|
12 |
-
function feedback( $feedback ) {
|
13 |
-
$this->feedback = $feedback;
|
14 |
-
}
|
15 |
-
|
16 |
-
function before() { }
|
17 |
-
|
18 |
-
function after() { }
|
19 |
-
|
20 |
-
function header() { }
|
21 |
-
|
22 |
-
function footer() { }
|
23 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/inc/class-wprp-core-upgrader-skin.php
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
class WPRP_Core_Upgrader_Skin extends WP_Upgrader_Skin {
|
3 |
-
|
4 |
-
var $feedback;
|
5 |
-
var $error;
|
6 |
-
|
7 |
-
function error( $error ) {
|
8 |
-
$this->error = $error;
|
9 |
-
}
|
10 |
-
|
11 |
-
function feedback( $feedback ) {
|
12 |
-
$this->feedback = $feedback;
|
13 |
-
}
|
14 |
-
|
15 |
-
function before() { }
|
16 |
-
|
17 |
-
function after() { }
|
18 |
-
|
19 |
-
function header() { }
|
20 |
-
|
21 |
-
function footer() { }
|
22 |
-
|
23 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/inc/class-wprp-plugin-upgrader-skin.php
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPRP_Plugin_Upgrader_Skin extends Plugin_Installer_Skin {
|
4 |
-
|
5 |
-
var $feedback;
|
6 |
-
var $error;
|
7 |
-
|
8 |
-
function error( $error ) {
|
9 |
-
$this->error = $error;
|
10 |
-
}
|
11 |
-
|
12 |
-
function feedback( $feedback ) {
|
13 |
-
$this->feedback = $feedback;
|
14 |
-
}
|
15 |
-
|
16 |
-
function before() { }
|
17 |
-
|
18 |
-
function after() { }
|
19 |
-
|
20 |
-
function header() { }
|
21 |
-
|
22 |
-
function footer() { }
|
23 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/inc/class-wprp-theme-upgrader-skin.php
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPRP_Theme_Upgrader_Skin extends Theme_Installer_Skin {
|
4 |
-
|
5 |
-
var $feedback;
|
6 |
-
var $error;
|
7 |
-
|
8 |
-
function error( $error ) {
|
9 |
-
$this->error = $error;
|
10 |
-
}
|
11 |
-
|
12 |
-
function feedback( $feedback ) {
|
13 |
-
$this->feedback = $feedback;
|
14 |
-
}
|
15 |
-
|
16 |
-
function before() { }
|
17 |
-
|
18 |
-
function after() { }
|
19 |
-
|
20 |
-
function header() { }
|
21 |
-
|
22 |
-
function footer() { }
|
23 |
-
|
24 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/languages/index.php
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Do not put custom translations here. They will be deleted when you update the WP Remote plugin!
|
4 |
-
*
|
5 |
-
* Keep custom translations for WP Remote Plugin For WordPress in '/wp-content/languages/wpremote/'
|
6 |
-
*/
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/languages/wp-remote-wordpress-plugin.mo
DELETED
Binary file
|
old_wpremote/languages/wp-remote-wordpress-plugin.pot
DELETED
@@ -1,148 +0,0 @@
|
|
1 |
-
# Copyright (C) 2013 Human Made Limited
|
2 |
-
# This file is distributed under the same license as the WP Remote plugin.
|
3 |
-
msgid ""
|
4 |
-
msgstr ""
|
5 |
-
"Project-Id-Version: WP Remote 2.6.1-alpha\n"
|
6 |
-
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-remote-wordpress-plugin\n"
|
7 |
-
"POT-Creation-Date: 2013-08-23 17:33:58+00:00\n"
|
8 |
-
"MIME-Version: 1.0\n"
|
9 |
-
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
-
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date: 2013-08-23 14:36-0300\n"
|
12 |
-
"Last-Translator: Human Made Limited <hello@hmn.md>\n"
|
13 |
-
"Language-Team: Human Made Limited <hello@hmn.md>\n"
|
14 |
-
"X-Generator: Poedit 1.5.7\n"
|
15 |
-
|
16 |
-
#: plugin.php:47
|
17 |
-
msgid "WP Remote requires PHP version 5.2.4 or greater."
|
18 |
-
msgstr ""
|
19 |
-
|
20 |
-
#: plugin.php:180
|
21 |
-
msgid "The filesystem is not writable with the supplied credentials"
|
22 |
-
msgstr ""
|
23 |
-
|
24 |
-
#: wprp.admin.php:29
|
25 |
-
msgid "WP Remote is almost ready"
|
26 |
-
msgstr ""
|
27 |
-
|
28 |
-
#: wprp.admin.php:29
|
29 |
-
msgid "enter your API key to continue"
|
30 |
-
msgstr ""
|
31 |
-
|
32 |
-
#: wprp.admin.php:33
|
33 |
-
msgid "Save API Key"
|
34 |
-
msgstr ""
|
35 |
-
|
36 |
-
#: wprp.admin.php:39
|
37 |
-
msgid "Don't have a WP Remote account yet?"
|
38 |
-
msgstr ""
|
39 |
-
|
40 |
-
#: wprp.admin.php:39
|
41 |
-
msgid "Sign up"
|
42 |
-
msgstr ""
|
43 |
-
|
44 |
-
#: wprp.admin.php:39
|
45 |
-
msgid "register your site, and report back once you've grabbed your API key."
|
46 |
-
msgstr ""
|
47 |
-
|
48 |
-
#: wprp.admin.php:71
|
49 |
-
msgid "WP Remote API Key successfully added"
|
50 |
-
msgstr ""
|
51 |
-
|
52 |
-
#: wprp.admin.php:71
|
53 |
-
msgid "WP Remote"
|
54 |
-
msgstr ""
|
55 |
-
|
56 |
-
#: wprp.backups.php:140
|
57 |
-
msgid "No backup was found"
|
58 |
-
msgstr ""
|
59 |
-
|
60 |
-
#: wprp.backups.php:190 wprp.backups.php:198
|
61 |
-
msgid "Calculating"
|
62 |
-
msgstr ""
|
63 |
-
|
64 |
-
#: wprp.backups.php:213
|
65 |
-
msgid "Dumping Database %s"
|
66 |
-
msgstr ""
|
67 |
-
|
68 |
-
#: wprp.backups.php:219
|
69 |
-
msgid "Verifying Database Dump %s"
|
70 |
-
msgstr ""
|
71 |
-
|
72 |
-
#: wprp.backups.php:225
|
73 |
-
msgid "Creating zip archive %s"
|
74 |
-
msgstr ""
|
75 |
-
|
76 |
-
#: wprp.backups.php:231
|
77 |
-
msgid "Verifying Zip Archive %s"
|
78 |
-
msgstr ""
|
79 |
-
|
80 |
-
#: wprp.backups.php:326
|
81 |
-
msgid ""
|
82 |
-
"This %s file ensures that other people cannot download your backup files."
|
83 |
-
msgstr ""
|
84 |
-
|
85 |
-
#: wprp.backups.php:335
|
86 |
-
msgid "WP Remote Backup"
|
87 |
-
msgstr ""
|
88 |
-
|
89 |
-
#: wprp.compatability.php:10
|
90 |
-
msgid "BulletProof Security"
|
91 |
-
msgstr ""
|
92 |
-
|
93 |
-
#: wprp.compatability.php:11
|
94 |
-
msgid "Wordfence Security"
|
95 |
-
msgstr ""
|
96 |
-
|
97 |
-
#: wprp.compatability.php:12
|
98 |
-
msgid "Better WP Security"
|
99 |
-
msgstr ""
|
100 |
-
|
101 |
-
#: wprp.compatability.php:13
|
102 |
-
msgid "Wordpress Firewall 2"
|
103 |
-
msgstr ""
|
104 |
-
|
105 |
-
#: wprp.compatability.php:48
|
106 |
-
msgid "Don't show again"
|
107 |
-
msgstr ""
|
108 |
-
|
109 |
-
#: wprp.compatability.php:52
|
110 |
-
msgid "The plugin"
|
111 |
-
msgstr ""
|
112 |
-
|
113 |
-
#: wprp.compatability.php:52
|
114 |
-
msgid "may cause issues with WP Remote."
|
115 |
-
msgstr ""
|
116 |
-
|
117 |
-
#: wprp.compatability.php:54
|
118 |
-
msgid "Click here for instructions on how to resolve this issue"
|
119 |
-
msgstr ""
|
120 |
-
|
121 |
-
#: wprp.hm.backup.php:289
|
122 |
-
msgid "archive filename must be a non empty string"
|
123 |
-
msgstr ""
|
124 |
-
|
125 |
-
#: wprp.hm.backup.php:292
|
126 |
-
msgid "invalid file extension for archive filename"
|
127 |
-
msgstr ""
|
128 |
-
|
129 |
-
#: wprp.hm.backup.php:334
|
130 |
-
msgid "database dump filename must be a non empty string"
|
131 |
-
msgstr ""
|
132 |
-
|
133 |
-
#: wprp.hm.backup.php:337
|
134 |
-
msgid "invalid file extension for database dump filename"
|
135 |
-
msgstr ""
|
136 |
-
|
137 |
-
#: wprp.hm.backup.php:370
|
138 |
-
msgid "Invalid root path %s must be a valid directory path"
|
139 |
-
msgstr ""
|
140 |
-
|
141 |
-
#: wprp.hm.backup.php:401
|
142 |
-
msgid "Invalid backup path %s must be a non empty (string)"
|
143 |
-
msgstr ""
|
144 |
-
|
145 |
-
#: wprp.hm.backup.php:456
|
146 |
-
msgid ""
|
147 |
-
"Invalid backup type %s must be one of (string) file, database or complete"
|
148 |
-
msgstr ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/plugin.php
DELETED
@@ -1,283 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( ! defined( 'WPR_URL' ) )
|
4 |
-
define( 'WPR_URL', 'https://wpremote.com/' );
|
5 |
-
|
6 |
-
if ( ! defined( 'WPR_LANG_DIR' ) )
|
7 |
-
define( 'WPR_LANG_DIR', apply_filters( 'wpr_filter_lang_dir', trailingslashit( WPRP_PLUGIN_PATH ) . trailingslashit( 'languages' ) ) );
|
8 |
-
|
9 |
-
// Don't activate on anything less than PHP 5.2.4
|
10 |
-
if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
|
11 |
-
|
12 |
-
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
13 |
-
deactivate_plugins( WPRP_PLUGIN_SLUG . '/wpremote.php' );
|
14 |
-
|
15 |
-
if ( isset( $_GET['action'] ) && ( $_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape' ) )
|
16 |
-
die( __( 'WP Remote requires PHP version 5.2.4 or greater.', 'wpremote' ) );
|
17 |
-
|
18 |
-
}
|
19 |
-
|
20 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.compatability.php' );
|
21 |
-
|
22 |
-
if ( get_option( 'wprp_enable_log' ) )
|
23 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.log.php' );
|
24 |
-
|
25 |
-
// Backups require 3.1
|
26 |
-
if ( version_compare( get_bloginfo( 'version' ), '3.1', '>=' ) ) {
|
27 |
-
|
28 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.hm.backup.php' );
|
29 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.backups.php' );
|
30 |
-
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Get a needed URL on the WP Remote site
|
35 |
-
*
|
36 |
-
* @param string $uri URI for the URL (optional)
|
37 |
-
* @return string $url Fully-qualified URL to WP Remote
|
38 |
-
*/
|
39 |
-
function wprp_get_wpr_url( $uri = '' ) {
|
40 |
-
|
41 |
-
if ( empty( $uri ) )
|
42 |
-
return WPR_URL;
|
43 |
-
|
44 |
-
$url = rtrim( WPR_URL, '/' );
|
45 |
-
$uri = trim( $uri, '/' );
|
46 |
-
return $url . '/' . $uri . '/';
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Catch the API calls and load the API
|
51 |
-
*
|
52 |
-
* @return null
|
53 |
-
*/
|
54 |
-
function wprp_catch_api_call() {
|
55 |
-
|
56 |
-
if ( empty( $_POST['wpr_verify_key'] ) )
|
57 |
-
return;
|
58 |
-
|
59 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.integration.php' );
|
60 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.plugins.php' );
|
61 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.themes.php' );
|
62 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.content.php' );
|
63 |
-
|
64 |
-
require_once( WPRP_PLUGIN_PATH . '/wprp.api.php' );
|
65 |
-
|
66 |
-
exit;
|
67 |
-
|
68 |
-
}
|
69 |
-
add_action( 'init', 'wprp_catch_api_call', 100 );
|
70 |
-
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Check for a bat signal from the mothership
|
74 |
-
*
|
75 |
-
* @since 2.7.0
|
76 |
-
*/
|
77 |
-
function wprp_check_bat_signal() {
|
78 |
-
|
79 |
-
$bat_signal_key = 'wprp_bat_signal';
|
80 |
-
|
81 |
-
if ( false === get_transient( $bat_signal_key ) ) {
|
82 |
-
|
83 |
-
$bat_signal_url = trailingslashit( WPR_URL ) . 'bat-signal/';
|
84 |
-
$response = wp_remote_get( $bat_signal_url );
|
85 |
-
$response_body = wp_remote_retrieve_body( $response );
|
86 |
-
if ( 'destroy the evidence!' == trim( $response_body ) )
|
87 |
-
delete_option( 'wpr_api_key' );
|
88 |
-
|
89 |
-
// One request per day
|
90 |
-
set_transient( $bat_signal_key, 'the coast is clear', 60 * 60 * 24 );
|
91 |
-
}
|
92 |
-
|
93 |
-
}
|
94 |
-
add_action( 'init', 'wprp_check_bat_signal' );
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Get the stored WPR API key
|
98 |
-
*
|
99 |
-
* @return mixed
|
100 |
-
*/
|
101 |
-
function wprp_get_api_keys() {
|
102 |
-
$keys = apply_filters( 'wpr_api_keys', get_option( 'wpr_api_key' ) );
|
103 |
-
if ( ! empty( $keys ) )
|
104 |
-
return (array)$keys;
|
105 |
-
else
|
106 |
-
return array();
|
107 |
-
}
|
108 |
-
|
109 |
-
function wprp_plugin_update_check() {
|
110 |
-
|
111 |
-
$plugin_data = get_plugin_data( __FILE__ );
|
112 |
-
|
113 |
-
// define the plugin version
|
114 |
-
define( 'WPRP_VERSION', $plugin_data['Version'] );
|
115 |
-
|
116 |
-
// Fire the update action
|
117 |
-
if ( WPRP_VERSION !== get_option( 'wprp_plugin_version' ) )
|
118 |
-
wprp_update();
|
119 |
-
|
120 |
-
}
|
121 |
-
add_action( 'admin_init', 'wprp_plugin_update_check' );
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Run any update code and update the current version in the db
|
125 |
-
*
|
126 |
-
* @access public
|
127 |
-
* @return void
|
128 |
-
*/
|
129 |
-
function wprp_update() {
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Remove the old _wpremote_backups directory
|
133 |
-
*/
|
134 |
-
$uploads_dir = wp_upload_dir();
|
135 |
-
|
136 |
-
$old_wpremote_dir = trailingslashit( $uploads_dir['basedir'] ) . '_wpremote_backups';
|
137 |
-
|
138 |
-
if ( file_exists( $old_wpremote_dir ) )
|
139 |
-
WPRP_Backups::rmdir_recursive( $old_wpremote_dir );
|
140 |
-
|
141 |
-
// If BackUpWordPress isn't installed then lets just delete the whole backups directory
|
142 |
-
if ( ! defined( 'HMBKP_PLUGIN_PATH' ) && $path = get_option( 'hmbkp_path' ) ) {
|
143 |
-
|
144 |
-
WPRP_Backups::rmdir_recursive( $path );
|
145 |
-
|
146 |
-
delete_option( 'hmbkp_path' );
|
147 |
-
delete_option( 'hmbkp_default_path' );
|
148 |
-
delete_option( 'hmbkp_plugin_version' );
|
149 |
-
|
150 |
-
}
|
151 |
-
|
152 |
-
// Update the version stored in the db
|
153 |
-
if ( get_option( 'wprp_plugin_version' ) !== WPRP_VERSION )
|
154 |
-
update_option( 'wprp_plugin_version', WPRP_VERSION );
|
155 |
-
|
156 |
-
}
|
157 |
-
|
158 |
-
function _wprp_upgrade_core() {
|
159 |
-
|
160 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
161 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
162 |
-
|
163 |
-
include_once ( ABSPATH . 'wp-admin/includes/admin.php' );
|
164 |
-
include_once ( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
165 |
-
include_once ( ABSPATH . 'wp-includes/update.php' );
|
166 |
-
require_once ( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
167 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-core-upgrader-skin.php';
|
168 |
-
|
169 |
-
// check for filesystem access
|
170 |
-
if ( ! _wpr_check_filesystem_access() )
|
171 |
-
return new WP_Error( 'filesystem-not-writable', __( 'The filesystem is not writable with the supplied credentials', 'wpremote' ) );
|
172 |
-
|
173 |
-
// force refresh
|
174 |
-
wp_version_check();
|
175 |
-
|
176 |
-
$updates = get_core_updates();
|
177 |
-
|
178 |
-
if ( is_wp_error( $updates ) || ! $updates )
|
179 |
-
return new WP_Error( 'no-update-available' );
|
180 |
-
|
181 |
-
$update = reset( $updates );
|
182 |
-
|
183 |
-
if ( ! $update )
|
184 |
-
return new WP_Error( 'no-update-available' );
|
185 |
-
|
186 |
-
$skin = new WPRP_Core_Upgrader_Skin();
|
187 |
-
|
188 |
-
$upgrader = new Core_Upgrader( $skin );
|
189 |
-
$result = $upgrader->upgrade($update);
|
190 |
-
|
191 |
-
if ( is_wp_error( $result ) )
|
192 |
-
return $result;
|
193 |
-
|
194 |
-
global $wp_current_db_version, $wp_db_version;
|
195 |
-
|
196 |
-
// we have to include version.php so $wp_db_version
|
197 |
-
// will take the version of the updated version of wordpress
|
198 |
-
require( ABSPATH . WPINC . '/version.php' );
|
199 |
-
|
200 |
-
wp_upgrade();
|
201 |
-
|
202 |
-
return true;
|
203 |
-
}
|
204 |
-
|
205 |
-
function _wpr_check_filesystem_access() {
|
206 |
-
|
207 |
-
ob_start();
|
208 |
-
$success = request_filesystem_credentials( '' );
|
209 |
-
ob_end_clean();
|
210 |
-
|
211 |
-
return (bool) $success;
|
212 |
-
}
|
213 |
-
|
214 |
-
function _wpr_set_filesystem_credentials( $credentials ) {
|
215 |
-
|
216 |
-
if ( empty( $_POST['filesystem_details'] ) )
|
217 |
-
return $credentials;
|
218 |
-
|
219 |
-
$_credentials = array(
|
220 |
-
'username' => $_POST['filesystem_details']['credentials']['username'],
|
221 |
-
'password' => $_POST['filesystem_details']['credentials']['password'],
|
222 |
-
'hostname' => $_POST['filesystem_details']['credentials']['hostname'],
|
223 |
-
'connection_type' => $_POST['filesystem_details']['method']
|
224 |
-
);
|
225 |
-
|
226 |
-
// check whether the credentials can be used
|
227 |
-
if ( ! WP_Filesystem( $_credentials ) ) {
|
228 |
-
return $credentials;
|
229 |
-
}
|
230 |
-
|
231 |
-
return $_credentials;
|
232 |
-
}
|
233 |
-
add_filter( 'request_filesystem_credentials', '_wpr_set_filesystem_credentials' );
|
234 |
-
|
235 |
-
/**
|
236 |
-
*
|
237 |
-
*/
|
238 |
-
function wprp_translations_init() {
|
239 |
-
|
240 |
-
if ( is_admin() ) {
|
241 |
-
|
242 |
-
/** Set unique textdomain string */
|
243 |
-
$wprp_textdomain = 'wpremote';
|
244 |
-
|
245 |
-
/** The 'plugin_locale' filter is also used by default in load_plugin_textdomain() */
|
246 |
-
$plugin_locale = apply_filters( 'plugin_locale', get_locale(), $wprp_textdomain );
|
247 |
-
|
248 |
-
/** Set filter for WordPress languages directory */
|
249 |
-
$wprp_wp_lang_dir = apply_filters(
|
250 |
-
'wprp_filter_wp_lang_dir',
|
251 |
-
trailingslashit( WP_LANG_DIR ) . trailingslashit( 'wp-remote' ) . $wprp_textdomain . '-' . $plugin_locale . '.mo'
|
252 |
-
);
|
253 |
-
|
254 |
-
/** Translations: First, look in WordPress' "languages" folder = custom & update-secure! */
|
255 |
-
load_textdomain( $wprp_textdomain, $wprp_wp_lang_dir );
|
256 |
-
|
257 |
-
/** Translations: Secondly, look in plugin's "languages" folder = default */
|
258 |
-
load_plugin_textdomain( $wprp_textdomain, FALSE, WPR_LANG_DIR );
|
259 |
-
}
|
260 |
-
}
|
261 |
-
add_action( 'plugins_loaded', 'wprp_translations_init' );
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Format a WP User object into a better
|
265 |
-
* object for the API
|
266 |
-
*/
|
267 |
-
function wprp_format_user_obj( $user_obj ) {
|
268 |
-
$new_user_obj = new stdClass;
|
269 |
-
|
270 |
-
foreach( $user_obj->data as $key => $value ) {
|
271 |
-
$new_user_obj->$key = $value;
|
272 |
-
}
|
273 |
-
|
274 |
-
$new_user_obj->roles = $user_obj->roles;
|
275 |
-
$new_user_obj->caps = $user_obj->caps;
|
276 |
-
|
277 |
-
return $new_user_obj;
|
278 |
-
}
|
279 |
-
|
280 |
-
// == CLI == //
|
281 |
-
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
282 |
-
require_once 'cli/wprp.cli.php';
|
283 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.api.php
DELETED
@@ -1,726 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPR_API_Request {
|
4 |
-
|
5 |
-
static $actions = array();
|
6 |
-
static $args = array();
|
7 |
-
|
8 |
-
static function verify_request() {
|
9 |
-
|
10 |
-
// Check the API Key
|
11 |
-
if ( ! wprp_get_api_keys() ) {
|
12 |
-
|
13 |
-
echo json_encode( 'blank-api-key' );
|
14 |
-
exit;
|
15 |
-
|
16 |
-
} elseif ( isset( $_POST['wpr_verify_key'] ) ) {
|
17 |
-
|
18 |
-
$verify = $_POST['wpr_verify_key'];
|
19 |
-
unset( $_POST['wpr_verify_key'] );
|
20 |
-
|
21 |
-
$hash = self::generate_hashes( $_POST );
|
22 |
-
|
23 |
-
if ( ! in_array( $verify, $hash, true ) ) {
|
24 |
-
echo json_encode( 'bad-verify-key' );
|
25 |
-
exit;
|
26 |
-
}
|
27 |
-
|
28 |
-
if ( (int) $_POST['timestamp'] > time() + 360 || (int) $_POST['timestamp'] < time() - 360 ) {
|
29 |
-
echo json_encode( 'bad-timstamp' );
|
30 |
-
exit;
|
31 |
-
}
|
32 |
-
|
33 |
-
self::$actions = $_POST['actions'];
|
34 |
-
self::$args = $_POST;
|
35 |
-
|
36 |
-
|
37 |
-
} else {
|
38 |
-
exit;
|
39 |
-
}
|
40 |
-
|
41 |
-
return true;
|
42 |
-
|
43 |
-
}
|
44 |
-
|
45 |
-
static function generate_hashes( $vars ) {
|
46 |
-
|
47 |
-
$api_key = wprp_get_api_keys();
|
48 |
-
if ( ! $api_key )
|
49 |
-
return array();
|
50 |
-
|
51 |
-
$hashes = array();
|
52 |
-
foreach( $api_key as $key ) {
|
53 |
-
$hashes[] = hash_hmac( 'sha256', serialize( $vars ), $key );
|
54 |
-
}
|
55 |
-
return $hashes;
|
56 |
-
|
57 |
-
}
|
58 |
-
|
59 |
-
static function get_actions() {
|
60 |
-
return self::$actions;
|
61 |
-
}
|
62 |
-
|
63 |
-
static function get_args() {
|
64 |
-
return self::$args;
|
65 |
-
}
|
66 |
-
|
67 |
-
static function get_arg( $arg ) {
|
68 |
-
return ( isset( self::$args[$arg] ) ) ? self::$args[$arg] : null;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
WPR_API_Request::verify_request();
|
73 |
-
|
74 |
-
// disable logging for anythign done in API requests
|
75 |
-
if ( class_exists( 'WPRP_Log' ) )
|
76 |
-
WPRP_Log::get_instance()->disable_logging();
|
77 |
-
|
78 |
-
// Disable error_reporting so they don't break the json request
|
79 |
-
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG )
|
80 |
-
error_reporting( 0 );
|
81 |
-
|
82 |
-
// Temp hack so our requests to verify file size are signed.
|
83 |
-
global $wprp_noauth_nonce;
|
84 |
-
$wprp_noauth_nonce = wp_create_nonce( 'wprp_calculate_backup_size' );
|
85 |
-
|
86 |
-
// Log in as admin
|
87 |
-
$users_query = new WP_User_Query( array(
|
88 |
-
'role' => 'administrator',
|
89 |
-
'orderby' => 'ID'
|
90 |
-
) );
|
91 |
-
wp_set_current_user(1);
|
92 |
-
if ($users_query->get_total()) {
|
93 |
-
foreach ($users_query->get_results() as $user) {
|
94 |
-
if (!$user) {
|
95 |
-
continue;
|
96 |
-
}
|
97 |
-
$currentUser = wp_set_current_user($user->ID);
|
98 |
-
break;
|
99 |
-
}
|
100 |
-
if (empty($currentUser)) {
|
101 |
-
wp_set_current_user(1);
|
102 |
-
}
|
103 |
-
}
|
104 |
-
|
105 |
-
include_once ( ABSPATH . 'wp-admin/includes/admin.php' );
|
106 |
-
|
107 |
-
$actions = array();
|
108 |
-
|
109 |
-
foreach( WPR_API_Request::get_actions() as $action ) {
|
110 |
-
|
111 |
-
// TODO Instead should just fire actions which we hook into.
|
112 |
-
// TODO should namespace api methods?
|
113 |
-
switch( $action ) {
|
114 |
-
|
115 |
-
// TODO should be dynamic
|
116 |
-
case 'get_plugin_version' :
|
117 |
-
|
118 |
-
$actions[$action] = '1.1';
|
119 |
-
|
120 |
-
break;
|
121 |
-
|
122 |
-
case 'get_filesystem_method' :
|
123 |
-
|
124 |
-
$actions[$action] = get_filesystem_method();
|
125 |
-
|
126 |
-
break;
|
127 |
-
|
128 |
-
case 'get_supported_filesystem_methods' :
|
129 |
-
|
130 |
-
$actions[$action] = array();
|
131 |
-
|
132 |
-
if ( extension_loaded( 'ftp' ) || extension_loaded( 'sockets' ) || function_exists( 'fsockopen' ) )
|
133 |
-
$actions[$action][] = 'ftp';
|
134 |
-
|
135 |
-
if ( extension_loaded( 'ftp' ) )
|
136 |
-
$actions[$action][] = 'ftps';
|
137 |
-
|
138 |
-
if ( extension_loaded( 'ssh2' ) && function_exists( 'stream_get_contents' ) )
|
139 |
-
$actions[$action][] = 'ssh';
|
140 |
-
|
141 |
-
break;
|
142 |
-
|
143 |
-
case 'get_wp_version' :
|
144 |
-
|
145 |
-
global $wp_version;
|
146 |
-
|
147 |
-
$actions[$action] = (string) $wp_version;
|
148 |
-
|
149 |
-
break;
|
150 |
-
|
151 |
-
case 'get_constants':
|
152 |
-
|
153 |
-
$constants = array();
|
154 |
-
if ( is_array( WPR_API_Request::get_arg( 'constants' ) ) ) {
|
155 |
-
|
156 |
-
foreach( WPR_API_Request::get_arg( 'constants' ) as $constant ) {
|
157 |
-
if ( defined( $constant ) )
|
158 |
-
$constants[$constant] = constant( $constant );
|
159 |
-
else
|
160 |
-
$constants[$constant] = null;
|
161 |
-
}
|
162 |
-
|
163 |
-
}
|
164 |
-
$actions[$action] = $constants;
|
165 |
-
|
166 |
-
break;
|
167 |
-
|
168 |
-
case 'upgrade_core' :
|
169 |
-
|
170 |
-
$actions[$action] = _wprp_upgrade_core();
|
171 |
-
|
172 |
-
break;
|
173 |
-
|
174 |
-
case 'get_plugins' :
|
175 |
-
|
176 |
-
$actions[$action] = _wprp_get_plugins();
|
177 |
-
|
178 |
-
break;
|
179 |
-
|
180 |
-
case 'update_plugin' :
|
181 |
-
case 'upgrade_plugin' :
|
182 |
-
|
183 |
-
$api_args = array(
|
184 |
-
'zip_url' => esc_url_raw( WPR_API_Request::get_arg( 'zip_url' ) ),
|
185 |
-
);
|
186 |
-
$actions[$action] = _wprp_update_plugin_wrap( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ), $api_args );
|
187 |
-
|
188 |
-
break;
|
189 |
-
|
190 |
-
case 'validate_plugin' :
|
191 |
-
$actions[$action] = _wprp_validate( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
|
192 |
-
break;
|
193 |
-
|
194 |
-
case 'install_plugin' :
|
195 |
-
|
196 |
-
$api_args = array(
|
197 |
-
'version' => sanitize_text_field( WPR_API_Request::get_arg( 'version' ) ),
|
198 |
-
);
|
199 |
-
$actions[$action] = _wprp_install_plugin( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ), $api_args );
|
200 |
-
|
201 |
-
break;
|
202 |
-
|
203 |
-
case 'activate_plugin' :
|
204 |
-
|
205 |
-
$actions[$action] = _wprp_activate_plugin( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
|
206 |
-
|
207 |
-
break;
|
208 |
-
|
209 |
-
case 'deactivate_plugin' :
|
210 |
-
|
211 |
-
$actions[$action] = _wprp_deactivate_plugin( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
|
212 |
-
|
213 |
-
break;
|
214 |
-
|
215 |
-
case 'uninstall_plugin' :
|
216 |
-
|
217 |
-
$actions[$action] = _wprp_uninstall_plugin( sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
|
218 |
-
|
219 |
-
break;
|
220 |
-
|
221 |
-
case 'get_themes' :
|
222 |
-
|
223 |
-
$actions[$action] = _wprp_get_themes();
|
224 |
-
|
225 |
-
break;
|
226 |
-
|
227 |
-
case 'install_theme':
|
228 |
-
|
229 |
-
$api_args = array(
|
230 |
-
'version' => sanitize_text_field( WPR_API_Request::get_arg( 'version' ) ),
|
231 |
-
);
|
232 |
-
$actions[$action] = _wprp_install_theme( sanitize_text_field( WPR_API_Request::get_arg( 'theme' ) ), $api_args );
|
233 |
-
|
234 |
-
break;
|
235 |
-
|
236 |
-
case 'activate_theme':
|
237 |
-
|
238 |
-
$actions[$action] = _wprp_activate_theme( sanitize_text_field( WPR_API_Request::get_arg( 'theme' ) ) );
|
239 |
-
|
240 |
-
break;
|
241 |
-
|
242 |
-
case 'update_theme' :
|
243 |
-
case 'upgrade_theme' : // 'upgrade' is deprecated
|
244 |
-
|
245 |
-
$actions[$action] = _wprp_update_theme( sanitize_text_field( WPR_API_Request::get_arg( 'theme' ) ) );
|
246 |
-
|
247 |
-
break;
|
248 |
-
|
249 |
-
case 'delete_theme':
|
250 |
-
|
251 |
-
$actions[$action] = _wprp_delete_theme( sanitize_text_field( WPR_API_Request::get_arg( 'theme' ) ) );
|
252 |
-
|
253 |
-
break;
|
254 |
-
|
255 |
-
case 'do_backup' :
|
256 |
-
|
257 |
-
if ( in_array( WPR_API_Request::get_arg( 'backup_type' ), array( 'complete', 'database', 'file' ) ) )
|
258 |
-
WPRP_Backups::get_instance()->set_type( WPR_API_Request::get_arg( 'backup_type' ) );
|
259 |
-
|
260 |
-
if ( WPR_API_Request::get_arg( 'backup_approach' ) && 'file_manifest' == WPR_API_Request::get_arg( 'backup_approach' ) )
|
261 |
-
WPRP_Backups::get_instance()->set_is_using_file_manifest( true );
|
262 |
-
|
263 |
-
$actions[$action] = WPRP_Backups::get_instance()->do_backup();
|
264 |
-
|
265 |
-
break;
|
266 |
-
|
267 |
-
case 'get_backup' :
|
268 |
-
|
269 |
-
$actions[$action] = WPRP_Backups::get_instance()->get_backup();
|
270 |
-
|
271 |
-
break;
|
272 |
-
|
273 |
-
case 'delete_backup' :
|
274 |
-
|
275 |
-
$actions[$action] = WPRP_Backups::get_instance()->cleanup();
|
276 |
-
|
277 |
-
break;
|
278 |
-
|
279 |
-
case 'backup_heartbeat' :
|
280 |
-
|
281 |
-
WPRP_Backups::get_instance()->set_is_using_file_manifest( true );
|
282 |
-
|
283 |
-
if ( in_array( WPR_API_Request::get_arg( 'backup_type' ), array( 'complete', 'database', 'file' ) ) )
|
284 |
-
WPRP_Backups::get_instance()->set_type( WPR_API_Request::get_arg( 'backup_type' ) );
|
285 |
-
|
286 |
-
$actions[$action] = WPRP_Backups::get_instance()->backup_heartbeat();
|
287 |
-
|
288 |
-
break;
|
289 |
-
|
290 |
-
case 'supports_backups' :
|
291 |
-
|
292 |
-
$actions[$action] = true;
|
293 |
-
|
294 |
-
break;
|
295 |
-
|
296 |
-
case 'get_site_info' :
|
297 |
-
|
298 |
-
$actions[$action] = array(
|
299 |
-
'site_url' => get_site_url(),
|
300 |
-
'home_url' => get_home_url(),
|
301 |
-
'admin_url' => get_admin_url(),
|
302 |
-
'backups' => function_exists( '_wprp_get_backups_info' ) ? _wprp_get_backups_info() : array(),
|
303 |
-
'web_host' => _wprp_integration_get_web_host(),
|
304 |
-
'summary' => _wprp_get_content_summary(),
|
305 |
-
);
|
306 |
-
|
307 |
-
break;
|
308 |
-
|
309 |
-
case 'get_option':
|
310 |
-
|
311 |
-
$actions[$action] = get_option( sanitize_text_field( WPR_API_Request::get_arg( 'option_name' ) ) );
|
312 |
-
|
313 |
-
break;
|
314 |
-
|
315 |
-
case 'update_option':
|
316 |
-
|
317 |
-
$actions[$action] = update_option( sanitize_text_field( WPR_API_Request::get_arg( 'option_name' ) ), WPR_API_Request::get_arg( 'option_value' ) );
|
318 |
-
|
319 |
-
break;
|
320 |
-
|
321 |
-
case 'delete_option':
|
322 |
-
|
323 |
-
$actions[$action] = delete_option( sanitize_text_field( WPR_API_Request::get_arg( 'option_name' ) ) );
|
324 |
-
|
325 |
-
break;
|
326 |
-
|
327 |
-
case 'get_posts':
|
328 |
-
|
329 |
-
$arg_keys = array(
|
330 |
-
/** Author **/
|
331 |
-
'author',
|
332 |
-
'author_name',
|
333 |
-
'author__in',
|
334 |
-
'author__not_in',
|
335 |
-
|
336 |
-
/** Category **/
|
337 |
-
'cat',
|
338 |
-
'category_name',
|
339 |
-
'category__and',
|
340 |
-
'category__in',
|
341 |
-
'category__not_in',
|
342 |
-
|
343 |
-
/** Tag **/
|
344 |
-
'tag',
|
345 |
-
'tag_id',
|
346 |
-
'tag__and',
|
347 |
-
'tag__in',
|
348 |
-
'tag__not_in',
|
349 |
-
'tag_slug__and',
|
350 |
-
'tag_slug__in',
|
351 |
-
|
352 |
-
/** Search **/
|
353 |
-
's',
|
354 |
-
|
355 |
-
/** Post Attributes **/
|
356 |
-
'name',
|
357 |
-
'pagename',
|
358 |
-
'post_parent',
|
359 |
-
'post_parent__in',
|
360 |
-
'post_parent__not_in',
|
361 |
-
'post__in',
|
362 |
-
'post__not_in',
|
363 |
-
'post_status',
|
364 |
-
'post_type',
|
365 |
-
|
366 |
-
/** Order / Pagination / Etc. **/
|
367 |
-
'order',
|
368 |
-
'orderby',
|
369 |
-
'nopaging',
|
370 |
-
'posts_per_page',
|
371 |
-
'offset',
|
372 |
-
'paged',
|
373 |
-
'page',
|
374 |
-
'ignore_sticky_posts',
|
375 |
-
);
|
376 |
-
$args = array();
|
377 |
-
foreach( $arg_keys as $arg_key ) {
|
378 |
-
// Note: WP_Query() supports validation / sanitization
|
379 |
-
if ( null !== ( $value = WPR_API_Request::get_arg( $arg_key ) ) )
|
380 |
-
$args[$arg_key] = $value;
|
381 |
-
}
|
382 |
-
|
383 |
-
$query = new WP_Query;
|
384 |
-
$query->query( $args );
|
385 |
-
$actions[$action] = $query->posts;
|
386 |
-
|
387 |
-
break;
|
388 |
-
|
389 |
-
case 'get_post':
|
390 |
-
case 'delete_post':
|
391 |
-
|
392 |
-
$post_id = (int)WPR_API_Request::get_arg( 'post_id' );
|
393 |
-
$post = get_post( $post_id );
|
394 |
-
|
395 |
-
if ( ! $post ) {
|
396 |
-
$actions[$action] = new WP_Error( 'missing-post', __( "No post found.", 'wpremote' ) );
|
397 |
-
break;
|
398 |
-
}
|
399 |
-
|
400 |
-
if ( 'get_post' == $action ) {
|
401 |
-
|
402 |
-
$actions[$action] = $post;
|
403 |
-
|
404 |
-
} else if ( 'delete_post' == $action ) {
|
405 |
-
|
406 |
-
$actions[$action] = wp_delete_post( $post_id );
|
407 |
-
|
408 |
-
}
|
409 |
-
|
410 |
-
break;
|
411 |
-
|
412 |
-
case 'create_post':
|
413 |
-
case 'update_post':
|
414 |
-
|
415 |
-
$arg_keys = array(
|
416 |
-
'menu_order',
|
417 |
-
'comment_status',
|
418 |
-
'ping_status',
|
419 |
-
'post_author',
|
420 |
-
'post_content',
|
421 |
-
'post_date',
|
422 |
-
'post_date_gmt',
|
423 |
-
'post_excerpt',
|
424 |
-
'post_name',
|
425 |
-
'post_parent',
|
426 |
-
'post_password',
|
427 |
-
'post_status',
|
428 |
-
'post_title',
|
429 |
-
'post_type',
|
430 |
-
'tags_input',
|
431 |
-
);
|
432 |
-
$args = array();
|
433 |
-
foreach( $arg_keys as $arg_key ) {
|
434 |
-
// Note: wp_update_post() supports validation / sanitization
|
435 |
-
if ( null !== ( $value = WPR_API_Request::get_arg( $arg_key ) ) )
|
436 |
-
$args[$arg_key] = $value;
|
437 |
-
}
|
438 |
-
|
439 |
-
if ( 'create_post' == $action ) {
|
440 |
-
|
441 |
-
if ( $post_id = wp_insert_post( $args ) )
|
442 |
-
$actions[$action] = get_post( $post_id );
|
443 |
-
else
|
444 |
-
$actions[$action] = new WP_Error( 'create-post', __( "Error creating post.", 'wpremote' ) );
|
445 |
-
|
446 |
-
} else if ( 'update_post' == $action ) {
|
447 |
-
|
448 |
-
$args['ID'] = (int)WPR_API_Request::get_arg( 'post_id' );
|
449 |
-
|
450 |
-
if ( ! get_post( $args['ID'] ) ) {
|
451 |
-
$actions[$action] = new WP_Error( 'missing-post', __( "No post found.", 'wpremote' ) );
|
452 |
-
break;
|
453 |
-
}
|
454 |
-
|
455 |
-
if ( wp_update_post( $args ) )
|
456 |
-
$actions[$action] = get_post( $args['ID'] );
|
457 |
-
else
|
458 |
-
$actions[$action] = new WP_Error( 'update-post', __( "Error updating post.", 'wpremote' ) );
|
459 |
-
|
460 |
-
}
|
461 |
-
|
462 |
-
break;
|
463 |
-
|
464 |
-
case 'get_metadata':
|
465 |
-
|
466 |
-
$actions[$action] = get_metadata( WPR_API_Request::get_arg( 'meta_type' ), WPR_API_Request::get_arg( 'object_id' ), WPR_API_Request::get_arg( 'meta_key' ), false );
|
467 |
-
|
468 |
-
break;
|
469 |
-
|
470 |
-
case 'add_metadata':
|
471 |
-
|
472 |
-
$actions[$action] = add_metadata( WPR_API_Request::get_arg( 'meta_type' ), WPR_API_Request::get_arg( 'object_id' ), WPR_API_Request::get_arg( 'meta_key' ), WPR_API_Request::get_arg( 'meta_value' ) );
|
473 |
-
|
474 |
-
break;
|
475 |
-
|
476 |
-
case 'update_metadata':
|
477 |
-
|
478 |
-
$actions[$action] = update_metadata( WPR_API_Request::get_arg( 'meta_type' ), WPR_API_Request::get_arg( 'object_id' ), WPR_API_Request::get_arg( 'meta_key' ), WPR_API_Request::get_arg( 'meta_value' ) );
|
479 |
-
|
480 |
-
break;
|
481 |
-
|
482 |
-
case 'delete_metadata':
|
483 |
-
|
484 |
-
$actions[$action] = delete_metadata( WPR_API_Request::get_arg( 'meta_type' ), WPR_API_Request::get_arg( 'object_id' ), WPR_API_Request::get_arg( 'meta_key' ) );
|
485 |
-
|
486 |
-
break;
|
487 |
-
|
488 |
-
case 'get_comments':
|
489 |
-
|
490 |
-
$arg_keys = array(
|
491 |
-
'status',
|
492 |
-
'orderby',
|
493 |
-
'order',
|
494 |
-
'post_id',
|
495 |
-
);
|
496 |
-
$args = array();
|
497 |
-
foreach( $arg_keys as $arg_key ) {
|
498 |
-
// Note: get_comments() supports validation / sanitization
|
499 |
-
if ( null !== ( $value = WPR_API_Request::get_arg( $arg_key ) ) )
|
500 |
-
$args[$arg_key] = $value;
|
501 |
-
}
|
502 |
-
$actions[$action] = get_comments( $args );
|
503 |
-
|
504 |
-
break;
|
505 |
-
|
506 |
-
case 'get_comment':
|
507 |
-
case 'delete_comment':
|
508 |
-
|
509 |
-
$comment_id = (int)WPR_API_Request::get_arg( 'comment_id' );
|
510 |
-
$comment = get_comment( $comment_id );
|
511 |
-
|
512 |
-
if ( ! $comment ) {
|
513 |
-
$actions[$action] = new WP_Error( 'missing-comment', __( "No comment found.", 'wpremote' ) );
|
514 |
-
break;
|
515 |
-
}
|
516 |
-
|
517 |
-
if ( 'get_comment' == $action ) {
|
518 |
-
|
519 |
-
$actions[$action] = $comment;
|
520 |
-
|
521 |
-
} else if ( 'delete_comment' == $action ) {
|
522 |
-
|
523 |
-
$actions[$action] = wp_delete_comment( $comment_id );
|
524 |
-
|
525 |
-
}
|
526 |
-
|
527 |
-
break;
|
528 |
-
|
529 |
-
case 'create_comment':
|
530 |
-
case 'update_comment':
|
531 |
-
|
532 |
-
$arg_keys = array(
|
533 |
-
'comment_post_ID',
|
534 |
-
'comment_author',
|
535 |
-
'comment_author_email',
|
536 |
-
'comment_author_url',
|
537 |
-
'comment_date',
|
538 |
-
'comment_date_gmt',
|
539 |
-
'comment_content',
|
540 |
-
'comment_approved',
|
541 |
-
'comment_type',
|
542 |
-
'comment_parent',
|
543 |
-
'user_id'
|
544 |
-
);
|
545 |
-
$args = array();
|
546 |
-
foreach( $arg_keys as $arg_key ) {
|
547 |
-
// Note: wp_update_comment() supports validation / sanitization
|
548 |
-
if ( null !== ( $value = WPR_API_Request::get_arg( $arg_key ) ) )
|
549 |
-
$args[$arg_key] = $value;
|
550 |
-
}
|
551 |
-
|
552 |
-
if ( 'create_comment' == $action ) {
|
553 |
-
|
554 |
-
if ( $comment_id = wp_insert_comment( $args ) )
|
555 |
-
$actions[$action] = get_comment( $comment_id );
|
556 |
-
else
|
557 |
-
$actions[$action] = new WP_Error( 'create-comment', __( "Error creating comment.", 'wpremote' ) );
|
558 |
-
|
559 |
-
} else if ( 'update_comment' == $action ) {
|
560 |
-
|
561 |
-
$args['comment_ID'] = (int)WPR_API_Request::get_arg( 'comment_id' );
|
562 |
-
|
563 |
-
if ( ! get_comment( $args['comment_ID'] ) ) {
|
564 |
-
$actions[$action] = new WP_Error( 'missing-comment', __( "No comment found.", 'wpremote' ) );
|
565 |
-
break;
|
566 |
-
}
|
567 |
-
|
568 |
-
if ( wp_update_comment( $args ) )
|
569 |
-
$actions[$action] = get_comment( $args['comment_ID'] );
|
570 |
-
else
|
571 |
-
$actions[$action] = new WP_Error( 'update-comment', __( "Error updating comment.", 'wpremote' ) );
|
572 |
-
|
573 |
-
}
|
574 |
-
|
575 |
-
break;
|
576 |
-
|
577 |
-
case 'get_users':
|
578 |
-
|
579 |
-
$arg_keys = array(
|
580 |
-
'include',
|
581 |
-
'exclude',
|
582 |
-
'search',
|
583 |
-
'orderby',
|
584 |
-
'order',
|
585 |
-
'offset',
|
586 |
-
'number',
|
587 |
-
);
|
588 |
-
$args = array();
|
589 |
-
foreach( $arg_keys as $arg_key ) {
|
590 |
-
// Note: get_users() supports validation / sanitization
|
591 |
-
if ( $value = WPR_API_Request::get_arg( $arg_key ) )
|
592 |
-
$args[$arg_key] = $value;
|
593 |
-
}
|
594 |
-
|
595 |
-
$users = array_map( 'wprp_format_user_obj', get_users( $args ) );
|
596 |
-
$actions[$action] = $users;
|
597 |
-
|
598 |
-
break;
|
599 |
-
|
600 |
-
case 'get_user':
|
601 |
-
case 'update_user':
|
602 |
-
case 'delete_user':
|
603 |
-
|
604 |
-
$user_id = (int)WPR_API_Request::get_arg( 'user_id' );
|
605 |
-
$user = get_user_by( 'id', $user_id );
|
606 |
-
|
607 |
-
if ( ! $user ) {
|
608 |
-
$actions[$action] = new WP_Error( 'missing-user', "No user found." );
|
609 |
-
break;
|
610 |
-
}
|
611 |
-
|
612 |
-
require_once ABSPATH . '/wp-admin/includes/user.php';
|
613 |
-
|
614 |
-
if ( 'get_user' == $action ) {
|
615 |
-
|
616 |
-
$actions[$action] = wprp_format_user_obj( $user );
|
617 |
-
|
618 |
-
} else if ( 'update_user' == $action ) {
|
619 |
-
|
620 |
-
$fields = array(
|
621 |
-
'user_email',
|
622 |
-
'display_name',
|
623 |
-
'first_name',
|
624 |
-
'last_name',
|
625 |
-
'user_nicename',
|
626 |
-
'user_pass',
|
627 |
-
'user_url',
|
628 |
-
'description'
|
629 |
-
);
|
630 |
-
$args = array();
|
631 |
-
foreach( $fields as $field ) {
|
632 |
-
// Note: wp_update_user() handles sanitization / validation
|
633 |
-
if ( null !== ( $value = WPR_API_Request::get_arg( $field ) ) )
|
634 |
-
$args[$field] = $value;
|
635 |
-
}
|
636 |
-
$args['ID'] = $user->ID;
|
637 |
-
$ret = wp_update_user( $args );
|
638 |
-
if ( is_wp_error( $ret ) )
|
639 |
-
$actions[$action] = $ret;
|
640 |
-
else
|
641 |
-
$actions[$action] = wprp_format_user_obj( get_user_by( 'id', $ret ) );
|
642 |
-
|
643 |
-
} else if ( 'delete_user' == $action ) {
|
644 |
-
|
645 |
-
$actions[$action] = wp_delete_user( $user->ID );
|
646 |
-
|
647 |
-
}
|
648 |
-
|
649 |
-
|
650 |
-
break;
|
651 |
-
|
652 |
-
case 'create_user':
|
653 |
-
|
654 |
-
$args = array(
|
655 |
-
// Note: wp_insert_user() handles sanitization / validation
|
656 |
-
'user_login' => WPR_API_Request::get_arg( 'user_login' ),
|
657 |
-
'user_email' => WPR_API_Request::get_arg( 'user_email' ),
|
658 |
-
'role' => get_option('default_role'),
|
659 |
-
'user_pass' => false,
|
660 |
-
'user_registered' => strftime( "%F %T", time() ),
|
661 |
-
'display_name' => false,
|
662 |
-
);
|
663 |
-
foreach( $args as $key => $value ) {
|
664 |
-
// Note: wp_insert_user() handles sanitization / validation
|
665 |
-
if ( null !== ( $new_value = WPR_API_Request::get_arg( $key ) ) )
|
666 |
-
$args[$key] = $new_value;
|
667 |
-
}
|
668 |
-
|
669 |
-
if ( ! $args['user_pass'] ) {
|
670 |
-
$args['user_pass'] = wp_generate_password();
|
671 |
-
}
|
672 |
-
|
673 |
-
$user_id = wp_insert_user( $args );
|
674 |
-
|
675 |
-
if ( is_wp_error( $user_id ) ) {
|
676 |
-
$actions[$action] = array( 'status' => 'error', 'error' => $user_id->get_error_message() );
|
677 |
-
} else {
|
678 |
-
$actions[$action] = wprp_format_user_obj( get_user_by( 'id', $user_id ) );
|
679 |
-
}
|
680 |
-
|
681 |
-
break;
|
682 |
-
|
683 |
-
case 'enable_log' :
|
684 |
-
update_option( 'wprp_enable_log', true );
|
685 |
-
$actions[$action] = true;
|
686 |
-
break;
|
687 |
-
|
688 |
-
case 'disable_log' :
|
689 |
-
delete_option( 'wprp_enable_log' );
|
690 |
-
$actions[$action] = true;
|
691 |
-
break;
|
692 |
-
|
693 |
-
case 'get_log' :
|
694 |
-
|
695 |
-
if ( class_exists( 'WPRP_Log' ) ) {
|
696 |
-
$actions[$action] = WPRP_Log::get_instance()->get_items();
|
697 |
-
WPRP_Log::get_instance()->delete_items();
|
698 |
-
} else {
|
699 |
-
$actions[$action] = new WP_Error( 'log-not-enabled', 'Logging is not enabled' );
|
700 |
-
}
|
701 |
-
|
702 |
-
break;
|
703 |
-
|
704 |
-
default :
|
705 |
-
|
706 |
-
$actions[$action] = 'not-implemented';
|
707 |
-
|
708 |
-
break;
|
709 |
-
|
710 |
-
}
|
711 |
-
|
712 |
-
}
|
713 |
-
|
714 |
-
foreach ( $actions as $key => $action ) {
|
715 |
-
|
716 |
-
if ( is_wp_error( $action ) ) {
|
717 |
-
|
718 |
-
$actions[$key] = (object) array(
|
719 |
-
'errors' => $action->errors
|
720 |
-
);
|
721 |
-
}
|
722 |
-
}
|
723 |
-
|
724 |
-
echo json_encode( $actions );
|
725 |
-
|
726 |
-
exit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.backups.php
DELETED
@@ -1,698 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* WPRP_Backups
|
5 |
-
*
|
6 |
-
* Singleton class for creating backups, all scheduling is handled by WP Remote
|
7 |
-
*/
|
8 |
-
class WPRP_Backups extends WPRP_HM_Backup {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Contains the current instance
|
12 |
-
*
|
13 |
-
* @static
|
14 |
-
* @access private
|
15 |
-
*/
|
16 |
-
private static $instance;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Return the current instance of WPRP_Backups
|
20 |
-
*
|
21 |
-
* @static
|
22 |
-
* @access public
|
23 |
-
*/
|
24 |
-
public static function get_instance() {
|
25 |
-
|
26 |
-
if ( empty( self::$instance ) ) {
|
27 |
-
self::$instance = new WPRP_Backups();
|
28 |
-
}
|
29 |
-
|
30 |
-
return self::$instance;
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Setup HM Backup
|
36 |
-
*
|
37 |
-
* @access publics
|
38 |
-
* @see HM_Backup
|
39 |
-
*/
|
40 |
-
public function __construct() {
|
41 |
-
|
42 |
-
parent::__construct();
|
43 |
-
|
44 |
-
// Set the backup path
|
45 |
-
$this->set_path( $this->path() );
|
46 |
-
|
47 |
-
// Set the excludes
|
48 |
-
if ( class_exists( 'WPR_API_Request' ) && WPR_API_Request::get_arg( 'backup_excludes' ) )
|
49 |
-
$backup_excludes = WPR_API_Request::get_arg( 'backup_excludes' );
|
50 |
-
else if ( isset( $_GET['backup_excludes'] ) )
|
51 |
-
$backup_excludes = $_GET['backup_excludes'];
|
52 |
-
|
53 |
-
if ( ! empty( $backup_excludes ) )
|
54 |
-
$this->set_excludes( apply_filters( 'wprp_backup_excludes', $backup_excludes ) );
|
55 |
-
|
56 |
-
$this->filesize_transient = 'wprp_' . '_' . $this->get_type() . '_' . substr( md5( $this->exclude_string() ), 20 ) . '_filesize';
|
57 |
-
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Perform a backup of the site
|
62 |
-
* @return bool|WP_Error
|
63 |
-
*/
|
64 |
-
public function do_backup() {
|
65 |
-
|
66 |
-
@ignore_user_abort( true );
|
67 |
-
|
68 |
-
$this->set_status( 'Starting backup...' );
|
69 |
-
|
70 |
-
$this->set_start_timestamp();
|
71 |
-
|
72 |
-
$this->backup();
|
73 |
-
|
74 |
-
if ( ! file_exists( $this->get_archive_filepath() ) ) {
|
75 |
-
|
76 |
-
$errors = $this->get_errors();
|
77 |
-
if ( ! empty( $errors ) )
|
78 |
-
return new WP_Error( 'backup-failed', implode( ', ', $errors ) );
|
79 |
-
else
|
80 |
-
return new WP_Error( 'backup-failed', __( 'Backup file is missing.', 'wpremote' ) );
|
81 |
-
|
82 |
-
}
|
83 |
-
|
84 |
-
return true;
|
85 |
-
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Get the backup once it has run, will return status running as a WP Error
|
90 |
-
*
|
91 |
-
* @return WP_Error|string
|
92 |
-
*/
|
93 |
-
public function get_backup() {
|
94 |
-
|
95 |
-
global $is_apache;
|
96 |
-
|
97 |
-
// Restore the start timestamp to global scope so HM Backup recognizes the proper archive file
|
98 |
-
$this->restore_start_timestamp();
|
99 |
-
|
100 |
-
if ( $status = $this->get_status() ) {
|
101 |
-
|
102 |
-
if ( $this->is_backup_still_running() )
|
103 |
-
return new WP_Error( 'error-status', $status );
|
104 |
-
else
|
105 |
-
return new WP_Error( 'backup-process-killed', __( 'Backup process failed or was killed.', 'wpremote' ) );
|
106 |
-
}
|
107 |
-
|
108 |
-
$backup = $this->get_archive_filepath();
|
109 |
-
|
110 |
-
if ( file_exists( $backup ) ) {
|
111 |
-
|
112 |
-
// Append the secret key on apache servers
|
113 |
-
if ( $is_apache && $this->key() ) {
|
114 |
-
|
115 |
-
$backup = add_query_arg( 'key', $this->key(), $backup );
|
116 |
-
|
117 |
-
// Force the .htaccess to be rebuilt
|
118 |
-
if ( file_exists( $this->get_path() . '/.htaccess' ) )
|
119 |
-
unlink( $this->get_path() . '/.htaccess' );
|
120 |
-
|
121 |
-
$this->path();
|
122 |
-
|
123 |
-
}
|
124 |
-
|
125 |
-
$response = new stdClass;
|
126 |
-
$response->url = str_replace( parent::conform_dir( WP_CONTENT_DIR ), WP_CONTENT_URL, $backup );
|
127 |
-
$response->seconds_elapsed = time() - $this->start_timestamp;
|
128 |
-
return $response;
|
129 |
-
|
130 |
-
}
|
131 |
-
|
132 |
-
return new WP_Error( 'backup-failed', __( 'No backup was found', 'wpremote' ) );
|
133 |
-
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Remove the backups directoy and everything it contains
|
138 |
-
*
|
139 |
-
* @access public
|
140 |
-
* @return void
|
141 |
-
*/
|
142 |
-
public function cleanup() {
|
143 |
-
|
144 |
-
$this->rmdir_recursive( $this->get_path() );
|
145 |
-
|
146 |
-
delete_option( 'wprp_backup_path' );
|
147 |
-
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* Cleanup old ZipArchive partials that may have been left by old processes
|
152 |
-
*/
|
153 |
-
public function cleanup_ziparchive_partials() {
|
154 |
-
|
155 |
-
foreach( glob( $this->get_path() . '/*.zip.*' ) as $ziparchive_partial ) {
|
156 |
-
unlink( $ziparchive_partial );
|
157 |
-
}
|
158 |
-
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Get the estimated size of the sites files and database
|
163 |
-
*
|
164 |
-
* If the size hasn't been calculated yet then it fires an API request
|
165 |
-
* to calculate the size and returns string 'Calculating'
|
166 |
-
*
|
167 |
-
* @access public
|
168 |
-
* @return string $size|Calculating
|
169 |
-
*/
|
170 |
-
public function get_estimate_size() {
|
171 |
-
|
172 |
-
// Check the cache
|
173 |
-
if ( $size = get_transient( $this->filesize_transient ) ) {
|
174 |
-
|
175 |
-
// If we have a number, format it and return
|
176 |
-
if ( is_numeric( $size ) )
|
177 |
-
return size_format( $size, null, '%01u %s' );
|
178 |
-
|
179 |
-
// Otherwise the filesize must still be calculating
|
180 |
-
else
|
181 |
-
return __( 'Calculating', 'wpremote' );
|
182 |
-
|
183 |
-
}
|
184 |
-
|
185 |
-
// we dont know the size yet, fire off a remote request to get it for later
|
186 |
-
// it can take some time so we have a small timeout then return "Calculating"
|
187 |
-
global $wprp_noauth_nonce;
|
188 |
-
wp_remote_get( add_query_arg( array( 'action' => 'wprp_calculate_backup_size', 'backup_excludes' => $this->get_excludes() ), add_query_arg( '_wpnonce', $wprp_noauth_nonce, admin_url( 'admin-ajax.php' ) ) ), array( 'timeout' => 0.1, 'sslverify' => false ) );
|
189 |
-
|
190 |
-
return __( 'Calculating', 'wpremote' );
|
191 |
-
|
192 |
-
}
|
193 |
-
|
194 |
-
/**
|
195 |
-
* Hook into the actions fired in HM Backup and set the status
|
196 |
-
*
|
197 |
-
* @param $action
|
198 |
-
*/
|
199 |
-
protected function do_action( $action ) {
|
200 |
-
|
201 |
-
$this->update_heartbeat_timestamp();
|
202 |
-
|
203 |
-
switch ( $action ) :
|
204 |
-
|
205 |
-
case 'hmbkp_backup_started':
|
206 |
-
|
207 |
-
$this->save_backup_process_id();
|
208 |
-
|
209 |
-
break;
|
210 |
-
|
211 |
-
case 'hmbkp_mysqldump_started' :
|
212 |
-
|
213 |
-
$this->set_status( sprintf( __( 'Dumping Database %s', 'wpremote' ), '(<code>' . $this->get_mysqldump_method() . '</code>)' ) );
|
214 |
-
|
215 |
-
break;
|
216 |
-
|
217 |
-
case 'hmbkp_mysqldump_verify_started' :
|
218 |
-
|
219 |
-
$this->set_status( sprintf( __( 'Verifying Database Dump %s', 'wpremote' ), '(<code>' . $this->get_mysqldump_method() . '</code>)' ) );
|
220 |
-
|
221 |
-
break;
|
222 |
-
|
223 |
-
case 'hmbkp_archive_started' :
|
224 |
-
|
225 |
-
if ( $this->is_using_file_manifest() )
|
226 |
-
$status = sprintf( __( '%d files remaining to archive %s', 'wpremote' ), $this->file_manifest_remaining, '(<code>' . $this->get_archive_method() . '</code>)' );
|
227 |
-
else
|
228 |
-
$status = sprintf( __( 'Creating zip archive %s', 'wpremote' ), '(<code>' . $this->get_archive_method() . '</code>)' );
|
229 |
-
|
230 |
-
$this->set_status( $status );
|
231 |
-
|
232 |
-
break;
|
233 |
-
|
234 |
-
case 'hmbkp_archive_verify_started' :
|
235 |
-
|
236 |
-
$this->set_status( sprintf( __( 'Verifying Zip Archive %s', 'wpremote' ), '(<code>' . $this->get_archive_method() . '</code>)' ) );
|
237 |
-
|
238 |
-
break;
|
239 |
-
|
240 |
-
case 'hmbkp_backup_complete' :
|
241 |
-
|
242 |
-
if ( file_exists( $this->get_schedule_running_path() ) )
|
243 |
-
unlink( $this->get_schedule_running_path() );
|
244 |
-
|
245 |
-
$this->clear_backup_process_id();
|
246 |
-
|
247 |
-
break;
|
248 |
-
|
249 |
-
case 'hmbkp_error' :
|
250 |
-
|
251 |
-
if ( $this->get_errors() ) {
|
252 |
-
|
253 |
-
$file = $this->get_path() . '/.backup_errors';
|
254 |
-
|
255 |
-
if ( file_exists( $file ) )
|
256 |
-
unlink( $file );
|
257 |
-
|
258 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
259 |
-
return;
|
260 |
-
|
261 |
-
fwrite( $handle, json_encode( $this->get_errors() ) );
|
262 |
-
|
263 |
-
fclose( $handle );
|
264 |
-
|
265 |
-
}
|
266 |
-
|
267 |
-
break;
|
268 |
-
|
269 |
-
case 'hmbkp_warning' :
|
270 |
-
|
271 |
-
if ( $this->get_warnings() ) {
|
272 |
-
|
273 |
-
$file = $this->get_path() . '/.backup_warnings';
|
274 |
-
|
275 |
-
if ( file_exists( $file ) )
|
276 |
-
unlink( $file );
|
277 |
-
|
278 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
279 |
-
return;
|
280 |
-
|
281 |
-
fwrite( $handle, json_encode( $this->get_warnings() ) );
|
282 |
-
|
283 |
-
fclose( $handle );
|
284 |
-
|
285 |
-
}
|
286 |
-
|
287 |
-
break;
|
288 |
-
|
289 |
-
endswitch;
|
290 |
-
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* Get the path to the backups directory
|
295 |
-
*
|
296 |
-
* Will try to create it if it doesn't exist
|
297 |
-
* and will fallback to default if a custom dir
|
298 |
-
* isn't writable.
|
299 |
-
*
|
300 |
-
* @access private
|
301 |
-
* @see default_path()
|
302 |
-
* @return string $path
|
303 |
-
*/
|
304 |
-
private function path() {
|
305 |
-
|
306 |
-
global $is_apache;
|
307 |
-
|
308 |
-
$path = get_option( 'wprp_backup_path' );
|
309 |
-
|
310 |
-
// If the dir doesn't exist or isn't writable then use the default path instead instead
|
311 |
-
if ( ! $path || ( is_dir( $path ) && ! is_writable( $path ) ) || ( ! is_dir( $path ) && ! is_writable( dirname( $path ) ) ) )
|
312 |
-
$path = $this->path_default();
|
313 |
-
|
314 |
-
// Create the backups directory if it doesn't exist
|
315 |
-
if ( ! is_dir( $path ) && is_writable( dirname( $path ) ) )
|
316 |
-
mkdir( $path, 0755 );
|
317 |
-
|
318 |
-
// If the path has changed then cache it
|
319 |
-
if ( get_option( 'wprp_backup_path' ) !== $path )
|
320 |
-
update_option( 'wprp_backup_path', $path );
|
321 |
-
|
322 |
-
// Protect against directory browsing by including a index.html file
|
323 |
-
$index = $path . '/index.html';
|
324 |
-
|
325 |
-
if ( ! file_exists( $index ) && is_writable( $path ) )
|
326 |
-
file_put_contents( $index, '' );
|
327 |
-
|
328 |
-
$htaccess = $path . '/.htaccess';
|
329 |
-
|
330 |
-
// Protect the directory with a .htaccess file on Apache servers
|
331 |
-
if ( $is_apache && function_exists( 'insert_with_markers' ) && ! file_exists( $htaccess ) && is_writable( $path ) ) {
|
332 |
-
|
333 |
-
$contents[] = '# ' . sprintf( __( 'This %s file ensures that other people cannot download your backup files.', 'wpremote' ), '.htaccess' );
|
334 |
-
$contents[] = '';
|
335 |
-
$contents[] = '<IfModule mod_rewrite.c>';
|
336 |
-
$contents[] = 'RewriteEngine On';
|
337 |
-
$contents[] = 'RewriteCond %{QUERY_STRING} !key=' . $this->key();
|
338 |
-
$contents[] = 'RewriteRule (.*) - [F]';
|
339 |
-
$contents[] = '</IfModule>';
|
340 |
-
$contents[] = '';
|
341 |
-
|
342 |
-
insert_with_markers( $htaccess, __( 'WP Remote Backup', 'wpremote' ), $contents );
|
343 |
-
|
344 |
-
}
|
345 |
-
|
346 |
-
return parent::conform_dir( $path );
|
347 |
-
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Return the default backup path
|
352 |
-
*
|
353 |
-
* @access private
|
354 |
-
* @return string $path
|
355 |
-
*/
|
356 |
-
private function path_default() {
|
357 |
-
|
358 |
-
$dirname = substr( $this->key(), 0, 10 ) . '-wprbackups';
|
359 |
-
$path = parent::conform_dir( trailingslashit( WP_CONTENT_DIR ) . $dirname );
|
360 |
-
|
361 |
-
$upload_dir = wp_upload_dir();
|
362 |
-
|
363 |
-
// If the backups dir can't be created in WP_CONTENT_DIR then fallback to uploads
|
364 |
-
if ( ( ( ! is_dir( $path ) && ! is_writable( dirname( $path ) ) ) || ( is_dir( $path ) && ! is_writable( $path ) ) ) && strpos( $path, $upload_dir['basedir'] ) === false )
|
365 |
-
$path = parent::conform_dir( trailingslashit( $upload_dir['basedir'] ) . $dirname );
|
366 |
-
|
367 |
-
return $path;
|
368 |
-
}
|
369 |
-
|
370 |
-
/**
|
371 |
-
* Calculate and generate the private key
|
372 |
-
*
|
373 |
-
* @access private
|
374 |
-
* @return string $key
|
375 |
-
*/
|
376 |
-
private function key() {
|
377 |
-
|
378 |
-
if ( ! empty( $this->key ) )
|
379 |
-
return $this->key;
|
380 |
-
|
381 |
-
$key = array( ABSPATH, time() );
|
382 |
-
|
383 |
-
foreach ( array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT', 'SECRET_KEY' ) as $constant )
|
384 |
-
if ( defined( $constant ) )
|
385 |
-
$key[] = constant( $constant );
|
386 |
-
|
387 |
-
shuffle( $key );
|
388 |
-
|
389 |
-
$this->key = md5( serialize( $key ) );
|
390 |
-
return $this->key;
|
391 |
-
}
|
392 |
-
|
393 |
-
/**
|
394 |
-
* Get the status of the running backup.
|
395 |
-
*
|
396 |
-
* @access public
|
397 |
-
* @return string
|
398 |
-
*/
|
399 |
-
private function get_status() {
|
400 |
-
|
401 |
-
if ( ! file_exists( $this->get_schedule_running_path() ) )
|
402 |
-
return '';
|
403 |
-
|
404 |
-
$status = file_get_contents( $this->get_schedule_running_path() );
|
405 |
-
|
406 |
-
return $status;
|
407 |
-
|
408 |
-
}
|
409 |
-
|
410 |
-
/**
|
411 |
-
* Get the path to the backup running file that stores the running backup status
|
412 |
-
*
|
413 |
-
* @access private
|
414 |
-
* @return string
|
415 |
-
*/
|
416 |
-
private function get_schedule_running_path() {
|
417 |
-
return $this->get_path() . '/.backup-running';
|
418 |
-
}
|
419 |
-
|
420 |
-
/**
|
421 |
-
* Set the status of the running backup
|
422 |
-
*
|
423 |
-
* @access public
|
424 |
-
* @param string $message
|
425 |
-
* @return void
|
426 |
-
*/
|
427 |
-
private function set_status( $message ) {
|
428 |
-
|
429 |
-
if ( ! $handle = fopen( $this->get_schedule_running_path(), 'w' ) )
|
430 |
-
return;
|
431 |
-
|
432 |
-
fwrite( $handle, $message );
|
433 |
-
|
434 |
-
fclose( $handle );
|
435 |
-
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Set the start timestamp for the backup
|
440 |
-
*/
|
441 |
-
private function set_start_timestamp() {
|
442 |
-
$this->start_timestamp = current_time( 'timestamp' );
|
443 |
-
file_put_contents( $this->get_path() . '/.start-timestamp', $this->start_timestamp );
|
444 |
-
}
|
445 |
-
|
446 |
-
/**
|
447 |
-
* Restore the start timestamp for the backup
|
448 |
-
*/
|
449 |
-
private function restore_start_timestamp() {
|
450 |
-
if ( $start_timestamp = file_get_contents( $this->get_path() . '/.start-timestamp' ) )
|
451 |
-
$this->start_timestamp = (int) $start_timestamp;
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* Update the heartbeat timestamp to the current time.
|
456 |
-
*/
|
457 |
-
private function update_heartbeat_timestamp() {
|
458 |
-
file_put_contents( $this->get_path() . '/.heartbeat-timestamp', time() );
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Get the heartbeat timestamp.
|
463 |
-
*/
|
464 |
-
private function get_heartbeat_timestamp() {
|
465 |
-
|
466 |
-
$heartbeat = $this->get_path() . '/.heartbeat-timestamp';
|
467 |
-
|
468 |
-
if ( file_exists( $heartbeat ) )
|
469 |
-
return (int) file_get_contents( $heartbeat );
|
470 |
-
|
471 |
-
return false;
|
472 |
-
}
|
473 |
-
|
474 |
-
/**
|
475 |
-
* Get the file path to the backup process ID log
|
476 |
-
*
|
477 |
-
* @access private
|
478 |
-
*/
|
479 |
-
private function get_backup_process_id_path() {
|
480 |
-
return $this->get_path() . '/.backup-process-id';
|
481 |
-
}
|
482 |
-
|
483 |
-
/**
|
484 |
-
* Get the current backup process ID
|
485 |
-
*
|
486 |
-
* @access private
|
487 |
-
*/
|
488 |
-
private function get_backup_process_id() {
|
489 |
-
$file = $this->get_backup_process_id_path();
|
490 |
-
if ( file_exists( $file ) )
|
491 |
-
return (int) trim( file_get_contents( $file ) );
|
492 |
-
else
|
493 |
-
return false;
|
494 |
-
}
|
495 |
-
|
496 |
-
/**
|
497 |
-
* Save this current backup process ID in case
|
498 |
-
* we need to check later whether it was killed in action
|
499 |
-
*
|
500 |
-
* @access private
|
501 |
-
*/
|
502 |
-
private function save_backup_process_id() {
|
503 |
-
|
504 |
-
if ( ! $handle = fopen( $this->get_backup_process_id_path(), 'w' ) )
|
505 |
-
return;
|
506 |
-
|
507 |
-
fwrite( $handle, getmypid() );
|
508 |
-
|
509 |
-
fclose( $handle );
|
510 |
-
|
511 |
-
}
|
512 |
-
|
513 |
-
/**
|
514 |
-
* Clear the backup process ID
|
515 |
-
*
|
516 |
-
* @access private
|
517 |
-
*/
|
518 |
-
private function clear_backup_process_id() {
|
519 |
-
|
520 |
-
if ( file_exists( $this->get_backup_process_id_path() ) )
|
521 |
-
unlink( $this->get_backup_process_id_path() );
|
522 |
-
}
|
523 |
-
|
524 |
-
/**
|
525 |
-
* Whether or not a backup appears to be in progress
|
526 |
-
*
|
527 |
-
* @access private
|
528 |
-
*/
|
529 |
-
private function is_backup_still_running( $context = 'get_backup' ) {
|
530 |
-
|
531 |
-
// Check whether there's supposed to be a backup in progress
|
532 |
-
if ( false === ( $process_id = $this->get_backup_process_id() ) )
|
533 |
-
return false;
|
534 |
-
|
535 |
-
// When safe mode is enabled, WPRP can't modify max_execution_time
|
536 |
-
if ( self::is_safe_mode_active() && ini_get( 'max_execution_time' ) )
|
537 |
-
$time_to_wait = ini_get( 'max_execution_time' );
|
538 |
-
else
|
539 |
-
$time_to_wait = 90;
|
540 |
-
|
541 |
-
// Give heartbeat requests a little bit of time to restart
|
542 |
-
if ( 'get_backup' == $context )
|
543 |
-
$time_to_wait += 15;
|
544 |
-
|
545 |
-
// If the heartbeat has been modified in the last 90 seconds, we might not be dead
|
546 |
-
if ( ( time() - $this->get_heartbeat_timestamp() ) < $time_to_wait )
|
547 |
-
return true;
|
548 |
-
|
549 |
-
// Check if there's any file being modified.
|
550 |
-
$backup_file_dirs = array( $this->get_path() );
|
551 |
-
|
552 |
-
if ( $this->is_using_file_manifest() ) {
|
553 |
-
$backup_file_dirs[] = $this->get_file_manifest_dirpath();
|
554 |
-
}
|
555 |
-
|
556 |
-
foreach ( $backup_file_dirs as $backup_file_dir ) {
|
557 |
-
$backup_files = glob( $backup_file_dir . '/*' );
|
558 |
-
|
559 |
-
$file_mtimes = array();
|
560 |
-
foreach( $backup_files as $backup_file ) {
|
561 |
-
$file_mtimes[] = filemtime( $backup_file );
|
562 |
-
}
|
563 |
-
if ( ! empty( $file_mtimes ) ) {
|
564 |
-
$latest_file_mtime = max( $file_mtimes );
|
565 |
-
if ( ( time() - $latest_file_mtime ) < $time_to_wait )
|
566 |
-
return true;
|
567 |
-
}
|
568 |
-
}
|
569 |
-
|
570 |
-
return false;
|
571 |
-
|
572 |
-
}
|
573 |
-
|
574 |
-
/**
|
575 |
-
* Check if there's a backup in progress, whether it's running,
|
576 |
-
* and restart it if it's not running
|
577 |
-
*
|
578 |
-
* @todo support checking whether the database should exist
|
579 |
-
*/
|
580 |
-
public function backup_heartbeat() {
|
581 |
-
|
582 |
-
// Restore the start timestamp to global scope so HM Backup recognizes the proper archive file
|
583 |
-
$this->restore_start_timestamp();
|
584 |
-
|
585 |
-
// No process means no backup in progress
|
586 |
-
if ( ! $this->get_backup_process_id() )
|
587 |
-
return false;
|
588 |
-
|
589 |
-
// No file manifest directory means this wasn't a file manifest approach
|
590 |
-
if ( ! is_dir( $this->get_file_manifest_dirpath() ) )
|
591 |
-
return false;
|
592 |
-
|
593 |
-
// Check whether there's supposed to be a backup in progress
|
594 |
-
if ( $this->get_backup_process_id() && $this->is_backup_still_running( 'backup_heartbeat' ) )
|
595 |
-
return false;
|
596 |
-
|
597 |
-
// Uh oh, needs to be restarted
|
598 |
-
$this->cleanup_ziparchive_partials();
|
599 |
-
|
600 |
-
$this->save_backup_process_id();
|
601 |
-
|
602 |
-
$this->restart_archive();
|
603 |
-
|
604 |
-
}
|
605 |
-
|
606 |
-
/**
|
607 |
-
* Calculate the size of the backup
|
608 |
-
*
|
609 |
-
* Doesn't account for compression
|
610 |
-
*
|
611 |
-
* @access public
|
612 |
-
* @return string
|
613 |
-
*/
|
614 |
-
public function get_filesize() {
|
615 |
-
|
616 |
-
$filesize = 0;
|
617 |
-
|
618 |
-
// Only try to calculate once per hour
|
619 |
-
set_transient( $this->filesize_transient, 'Calculating', time() + 60 * 60 );
|
620 |
-
|
621 |
-
// Don't include database if file only
|
622 |
-
if ( $this->get_type() != 'file' ) {
|
623 |
-
|
624 |
-
global $wpdb;
|
625 |
-
|
626 |
-
$res = $wpdb->get_results( 'SHOW TABLE STATUS FROM `' . DB_NAME . '`', ARRAY_A );
|
627 |
-
|
628 |
-
foreach ( $res as $r )
|
629 |
-
$filesize += (float) $r['Data_length'];
|
630 |
-
|
631 |
-
}
|
632 |
-
|
633 |
-
// Don't include files if database only
|
634 |
-
if ( $this->get_type() != 'database' ) {
|
635 |
-
|
636 |
-
// Get rid of any cached filesizes
|
637 |
-
clearstatcache();
|
638 |
-
|
639 |
-
$excludes = $this->exclude_string( 'regex' );
|
640 |
-
|
641 |
-
foreach ( $this->get_files() as $file ) {
|
642 |
-
|
643 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
644 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
645 |
-
continue;
|
646 |
-
|
647 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
648 |
-
continue;
|
649 |
-
|
650 |
-
// Excludes
|
651 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', parent::conform_dir( $file->getPathname() ) ) ) )
|
652 |
-
continue;
|
653 |
-
|
654 |
-
$filesize += (float) $file->getSize();
|
655 |
-
|
656 |
-
}
|
657 |
-
|
658 |
-
}
|
659 |
-
|
660 |
-
// Cache for a day
|
661 |
-
set_transient( $this->filesize_transient, $filesize, time() + 60 * 60 * 24 );
|
662 |
-
|
663 |
-
}
|
664 |
-
|
665 |
-
}
|
666 |
-
|
667 |
-
/*
|
668 |
-
* Return an array of back meta information
|
669 |
-
*
|
670 |
-
* @return array
|
671 |
-
*/
|
672 |
-
function _wprp_get_backups_info() {
|
673 |
-
|
674 |
-
$hm_backup = new WPRP_HM_Backup();
|
675 |
-
|
676 |
-
return array(
|
677 |
-
'mysqldump_path' => $hm_backup->get_mysqldump_command_path(),
|
678 |
-
'zip_path' => $hm_backup->get_zip_command_path(),
|
679 |
-
'estimated_size' => WPRP_Backups::get_instance()->get_estimate_size()
|
680 |
-
);
|
681 |
-
|
682 |
-
}
|
683 |
-
|
684 |
-
/**
|
685 |
-
* Calculate the filesize of the site
|
686 |
-
*
|
687 |
-
* The calculated size is stored in a transient
|
688 |
-
*/
|
689 |
-
function wprp_ajax_calculate_backup_size() {
|
690 |
-
|
691 |
-
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'wprp_calculate_backup_size' ) )
|
692 |
-
exit;
|
693 |
-
|
694 |
-
WPRP_Backups::get_instance()->get_filesize();
|
695 |
-
|
696 |
-
exit;
|
697 |
-
}
|
698 |
-
add_action( 'wp_ajax_nopriv_wprp_calculate_backup_size', 'wprp_ajax_calculate_backup_size' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.compatability.php
DELETED
@@ -1,82 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Function which takes active plugins and foreaches them though our list of security plugins
|
4 |
-
* @return array
|
5 |
-
*/
|
6 |
-
function wprp_get_incompatible_plugins() {
|
7 |
-
|
8 |
-
// Plugins to check for.
|
9 |
-
$security_plugins = array(
|
10 |
-
__( 'Wordfence Security', 'wpremote' ),
|
11 |
-
__( 'iThemes Security', 'wpremote' ),
|
12 |
-
__( 'Wordpress Firewall 2', 'wpremote' )
|
13 |
-
);
|
14 |
-
|
15 |
-
$active_plugins = get_option( 'active_plugins', array() );
|
16 |
-
$dismissed_plugins = get_option( 'dismissed-plugins', array() );
|
17 |
-
|
18 |
-
$plugin_matches = array();
|
19 |
-
|
20 |
-
// foreach through activated plugins and split the string to have one name to check results against.
|
21 |
-
foreach ( $active_plugins as $active_plugin ) {
|
22 |
-
|
23 |
-
$plugin = get_plugin_data( WP_PLUGIN_DIR . '/' . $active_plugin );
|
24 |
-
|
25 |
-
if ( in_array( $plugin['Name'], $security_plugins ) && ! in_array( $active_plugin, $dismissed_plugins ) )
|
26 |
-
$plugin_matches[$active_plugin] = $plugin['Name'];
|
27 |
-
|
28 |
-
}
|
29 |
-
|
30 |
-
return $plugin_matches;
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* foreach through array of matched plugins and for each print the notice.
|
35 |
-
*/
|
36 |
-
function wprp_security_admin_notice() {
|
37 |
-
|
38 |
-
if ( ! current_user_can( 'install_plugins' ) )
|
39 |
-
return;
|
40 |
-
|
41 |
-
foreach ( wprp_get_incompatible_plugins() as $plugin_path => $plugin_name ) :
|
42 |
-
|
43 |
-
?>
|
44 |
-
|
45 |
-
<div class="error">
|
46 |
-
|
47 |
-
<a class="close-button button" style="float: right; margin-top: 4px; color: inherit; text-decoration: none; " href="<?php echo add_query_arg( 'wpr_dismiss_plugin_warning', $plugin_path ); ?>"><?php _e( 'Don\'t show again','wpremote' ); ?></a>
|
48 |
-
|
49 |
-
<p>
|
50 |
-
|
51 |
-
<?php _e( 'The plugin', 'wpremote' );?> <strong><?php echo esc_attr( $plugin_name ); ?></strong> <?php _e( 'may cause issues with WP Remote.', 'wpremote' ); ?>
|
52 |
-
|
53 |
-
<a href="https://wpremote.com/support-center/troubleshooting/incorrect-version-numbers-false-positives/" target="_blank"> <?php _e( 'Click here for instructions on how to resolve this issue', 'wpremote' ); ?> </a>
|
54 |
-
|
55 |
-
</p>
|
56 |
-
|
57 |
-
</div>
|
58 |
-
|
59 |
-
<?php endforeach;
|
60 |
-
|
61 |
-
}
|
62 |
-
|
63 |
-
add_action( 'admin_notices', 'wprp_security_admin_notice' );
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Function which checks to see if the plugin was dismissed.
|
67 |
-
*/
|
68 |
-
function wprp_dismissed_plugin_notice_check() {
|
69 |
-
|
70 |
-
if ( current_user_can( 'install_plugins' ) && ! empty( $_GET['wpr_dismiss_plugin_warning'] ) ) {
|
71 |
-
|
72 |
-
$dismissed = get_option( 'dismissed-plugins', array() );
|
73 |
-
$dismissed[] = sanitize_text_field( $_GET['wpr_dismiss_plugin_warning'] );
|
74 |
-
|
75 |
-
update_option( 'dismissed-plugins', $dismissed );
|
76 |
-
|
77 |
-
wp_safe_redirect( remove_query_arg( 'wpr_dismiss_plugin_warning' ) );
|
78 |
-
exit;
|
79 |
-
|
80 |
-
}
|
81 |
-
}
|
82 |
-
add_action( 'admin_init', 'wprp_dismissed_plugin_notice_check' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.content.php
DELETED
@@ -1,31 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Return an array of content summary information
|
5 |
-
*
|
6 |
-
* @return array
|
7 |
-
*/
|
8 |
-
function _wprp_get_content_summary() {
|
9 |
-
|
10 |
-
$num_posts = wp_count_posts( 'post' );
|
11 |
-
$num_pages = wp_count_posts( 'page' );
|
12 |
-
$num_categories = count( get_categories( array( 'hide_empty' => 0 ) ) );
|
13 |
-
$num_comments = wp_count_comments();
|
14 |
-
$num_themes = count( wp_get_themes() );
|
15 |
-
$num_plugins = count( get_plugins() );
|
16 |
-
$num_users = count_users();
|
17 |
-
|
18 |
-
$content_summary = array(
|
19 |
-
'post_count' => ( ! empty( $num_posts->publish ) ) ? $num_posts->publish : 0,
|
20 |
-
'page_count' => ( ! empty( $num_pages->publish ) ) ? $num_pages->publish : 0,
|
21 |
-
'category_count' => $num_categories,
|
22 |
-
'comment_count' => ( ! empty( $num_comments->total_comments ) ) ? $num_comments->total_comments: 0,
|
23 |
-
'theme_count' => $num_themes,
|
24 |
-
'plugin_count' => $num_plugins,
|
25 |
-
'user_count' => ( ! empty( $num_users['total_users'] ) ) ? $num_users['total_users'] : 0
|
26 |
-
);
|
27 |
-
|
28 |
-
return $content_summary;
|
29 |
-
}
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.hm.backup.php
DELETED
@@ -1,2279 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Generic file and database backup class
|
5 |
-
*
|
6 |
-
* @version 2.3
|
7 |
-
*/
|
8 |
-
class WPRP_HM_Backup {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* The path where the backup file should be saved
|
12 |
-
*
|
13 |
-
* @string
|
14 |
-
* @access private
|
15 |
-
*/
|
16 |
-
private $path = '';
|
17 |
-
|
18 |
-
/**
|
19 |
-
* The backup type, must be either complete, file or database
|
20 |
-
*
|
21 |
-
* @string
|
22 |
-
* @access private
|
23 |
-
*/
|
24 |
-
private $type = '';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* The start timestamp of the backup
|
28 |
-
*
|
29 |
-
* @int
|
30 |
-
* @access protected
|
31 |
-
*/
|
32 |
-
protected $start_timestamp;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* The filename of the backup file
|
36 |
-
*
|
37 |
-
* @string
|
38 |
-
* @access private
|
39 |
-
*/
|
40 |
-
private $archive_filename = '';
|
41 |
-
|
42 |
-
/**
|
43 |
-
* The filename of the database dump
|
44 |
-
*
|
45 |
-
* @string
|
46 |
-
* @access private
|
47 |
-
*/
|
48 |
-
private $database_dump_filename = '';
|
49 |
-
|
50 |
-
/**
|
51 |
-
* The path to the zip command
|
52 |
-
*
|
53 |
-
* @string
|
54 |
-
* @access private
|
55 |
-
*/
|
56 |
-
private $zip_command_path;
|
57 |
-
|
58 |
-
/**
|
59 |
-
* The path to the mysqldump command
|
60 |
-
*
|
61 |
-
* @string
|
62 |
-
* @access private
|
63 |
-
*/
|
64 |
-
private $mysqldump_command_path;
|
65 |
-
|
66 |
-
/**
|
67 |
-
* An array of exclude rules
|
68 |
-
*
|
69 |
-
* @array
|
70 |
-
* @access private
|
71 |
-
*/
|
72 |
-
private $excludes = array();
|
73 |
-
|
74 |
-
/**
|
75 |
-
* The path that should be backed up
|
76 |
-
*
|
77 |
-
* @var string
|
78 |
-
* @access private
|
79 |
-
*/
|
80 |
-
private $root = '';
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Holds the current db connection
|
84 |
-
*
|
85 |
-
* @var resource
|
86 |
-
* @access private
|
87 |
-
*/
|
88 |
-
private $db;
|
89 |
-
|
90 |
-
/**
|
91 |
-
* An array of all the files in root
|
92 |
-
* excluding excludes and unreadable files
|
93 |
-
*
|
94 |
-
* @var array
|
95 |
-
* @access private
|
96 |
-
*/
|
97 |
-
private $files = array();
|
98 |
-
|
99 |
-
/**
|
100 |
-
* An array of all the files in root
|
101 |
-
* that match the exclude rules
|
102 |
-
*
|
103 |
-
* @var array
|
104 |
-
* @access private
|
105 |
-
*/
|
106 |
-
private $excluded_files = array();
|
107 |
-
|
108 |
-
/**
|
109 |
-
* An array of all the files in root
|
110 |
-
* that are unreadable
|
111 |
-
*
|
112 |
-
* @var array
|
113 |
-
* @access private
|
114 |
-
*/
|
115 |
-
private $unreadable_files = array();
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Contains an array of errors
|
119 |
-
*
|
120 |
-
* @var mixed
|
121 |
-
* @access private
|
122 |
-
*/
|
123 |
-
private $errors = array();
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Contains an array of warnings
|
127 |
-
*
|
128 |
-
* @var mixed
|
129 |
-
* @access private
|
130 |
-
*/
|
131 |
-
private $warnings = array();
|
132 |
-
|
133 |
-
/**
|
134 |
-
* The archive method used
|
135 |
-
*
|
136 |
-
* @var string
|
137 |
-
* @access private
|
138 |
-
*/
|
139 |
-
private $archive_method = '';
|
140 |
-
|
141 |
-
/**
|
142 |
-
* The mysqldump method used
|
143 |
-
*
|
144 |
-
* @var string
|
145 |
-
* @access private
|
146 |
-
*/
|
147 |
-
private $mysqldump_method = '';
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Whether or not to use a file manifest (more write-intensive)
|
151 |
-
*
|
152 |
-
* @var bool
|
153 |
-
* @access private
|
154 |
-
*/
|
155 |
-
private $using_file_manifest = false;
|
156 |
-
|
157 |
-
/**
|
158 |
-
* The current file manifest file.
|
159 |
-
*
|
160 |
-
* @access private
|
161 |
-
*/
|
162 |
-
private $current_file_manifest = false;
|
163 |
-
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Files of the file manifest that have already been archived
|
167 |
-
*
|
168 |
-
* @access private
|
169 |
-
*/
|
170 |
-
private $file_manifest_already_archived = array();
|
171 |
-
|
172 |
-
/**
|
173 |
-
* When using the file manifest, the number of files that should be
|
174 |
-
* archived per batch.
|
175 |
-
*
|
176 |
-
* @access private
|
177 |
-
*/
|
178 |
-
private $file_manifest_per_batch = 200;
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Files remaining to be achived in the file manifest.
|
182 |
-
*
|
183 |
-
* @access protected
|
184 |
-
*/
|
185 |
-
protected $file_manifest_remaining = 0;
|
186 |
-
|
187 |
-
/**
|
188 |
-
* A ZipArchive instance for this instance
|
189 |
-
*/
|
190 |
-
private $ziparchive = false;
|
191 |
-
|
192 |
-
/**
|
193 |
-
* A PclZip instance for this instance
|
194 |
-
*/
|
195 |
-
private $pclzip = false;
|
196 |
-
|
197 |
-
/**
|
198 |
-
* Check whether safe mode is active or not
|
199 |
-
*
|
200 |
-
* @param string $ini_get_callback
|
201 |
-
* @return bool
|
202 |
-
*/
|
203 |
-
public static function is_safe_mode_active( $ini_get_callback = 'ini_get' ) {
|
204 |
-
|
205 |
-
if ( ( $safe_mode = @call_user_func( $ini_get_callback, 'safe_mode' ) ) && strtolower( $safe_mode ) != 'off' )
|
206 |
-
return true;
|
207 |
-
|
208 |
-
return false;
|
209 |
-
|
210 |
-
}
|
211 |
-
|
212 |
-
/**
|
213 |
-
* Check whether shell_exec has been disabled.
|
214 |
-
*
|
215 |
-
* @access public
|
216 |
-
* @static
|
217 |
-
* @return bool
|
218 |
-
*/
|
219 |
-
public static function is_shell_exec_available() {
|
220 |
-
|
221 |
-
// Are we in Safe Mode
|
222 |
-
if ( self::is_safe_mode_active() )
|
223 |
-
return false;
|
224 |
-
|
225 |
-
// Is shell_exec or escapeshellcmd or escapeshellarg disabled?
|
226 |
-
if ( array_intersect( array( 'shell_exec', 'escapeshellarg', 'escapeshellcmd' ), array_map( 'trim', explode( ',', @ini_get( 'disable_functions' ) ) ) ) )
|
227 |
-
return false;
|
228 |
-
|
229 |
-
// Functions can also be disabled via suhosin
|
230 |
-
if ( array_intersect( array( 'shell_exec', 'escapeshellarg', 'escapeshellcmd' ), array_map( 'trim', explode( ',', @ini_get( 'suhosin.executor.func.blacklist' ) ) ) ) )
|
231 |
-
return false;
|
232 |
-
|
233 |
-
// Can we issue a simple echo command?
|
234 |
-
if ( ! @shell_exec( 'echo backupwordpress' ) )
|
235 |
-
return false;
|
236 |
-
|
237 |
-
return true;
|
238 |
-
|
239 |
-
}
|
240 |
-
|
241 |
-
|
242 |
-
/**
|
243 |
-
* Attempt to work out the root directory of the site, that
|
244 |
-
* is, the path equivelant of home_url().
|
245 |
-
*
|
246 |
-
* @access public
|
247 |
-
* @static
|
248 |
-
* @return string $home_path
|
249 |
-
*/
|
250 |
-
public static function get_home_path() {
|
251 |
-
|
252 |
-
$home_url = home_url();
|
253 |
-
$site_url = site_url();
|
254 |
-
|
255 |
-
$home_path = ABSPATH;
|
256 |
-
|
257 |
-
// If site_url contains home_url and they differ then assume WordPress is installed in a sub directory
|
258 |
-
if ( $home_url !== $site_url && strpos( $site_url, $home_url ) === 0 )
|
259 |
-
$home_path = trailingslashit( substr( self::conform_dir( ABSPATH ), 0, strrpos( self::conform_dir( ABSPATH ), str_replace( $home_url, '', $site_url ) ) ) );
|
260 |
-
|
261 |
-
return self::conform_dir( $home_path );
|
262 |
-
|
263 |
-
}
|
264 |
-
|
265 |
-
/**
|
266 |
-
* Sanitize a directory path
|
267 |
-
*
|
268 |
-
* @param string $dir
|
269 |
-
* @param bool $recursive (default: false)
|
270 |
-
* @return string $dir
|
271 |
-
*/
|
272 |
-
public static function conform_dir( $dir, $recursive = false ) {
|
273 |
-
|
274 |
-
// Assume empty dir is root
|
275 |
-
if ( ! $dir )
|
276 |
-
$dir = '/';
|
277 |
-
|
278 |
-
// Replace single forward slash (looks like double slash because we have to escape it)
|
279 |
-
$dir = str_replace( '\\', '/', $dir );
|
280 |
-
$dir = str_replace( '//', '/', $dir );
|
281 |
-
|
282 |
-
// Remove the trailing slash
|
283 |
-
if ( $dir !== '/' )
|
284 |
-
$dir = untrailingslashit( $dir );
|
285 |
-
|
286 |
-
// Carry on until completely normalized
|
287 |
-
if ( ! $recursive && self::conform_dir( $dir, true ) != $dir )
|
288 |
-
return self::conform_dir( $dir );
|
289 |
-
|
290 |
-
return (string) $dir;
|
291 |
-
|
292 |
-
}
|
293 |
-
|
294 |
-
/**
|
295 |
-
* Sets up the default properties
|
296 |
-
*
|
297 |
-
* @access public
|
298 |
-
*/
|
299 |
-
public function __construct() {
|
300 |
-
|
301 |
-
// Raise the memory limit and max_execution time
|
302 |
-
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
303 |
-
@set_time_limit( 0 );
|
304 |
-
|
305 |
-
// Set a custom error handler so we can track errors
|
306 |
-
set_error_handler( array( &$this, 'error_handler' ) );
|
307 |
-
|
308 |
-
}
|
309 |
-
|
310 |
-
/**
|
311 |
-
* Get the full filepath to the archive file
|
312 |
-
*
|
313 |
-
* @access public
|
314 |
-
* @return string
|
315 |
-
*/
|
316 |
-
public function get_archive_filepath() {
|
317 |
-
|
318 |
-
return trailingslashit( $this->get_path() ) . $this->get_archive_filename();
|
319 |
-
|
320 |
-
}
|
321 |
-
|
322 |
-
/**
|
323 |
-
* Get the filename of the archive file
|
324 |
-
*
|
325 |
-
* @access public
|
326 |
-
* @return string
|
327 |
-
*/
|
328 |
-
public function get_archive_filename() {
|
329 |
-
|
330 |
-
if ( empty( $this->archive_filename ) ) {
|
331 |
-
|
332 |
-
if ( empty( $this->start_timestamp ) )
|
333 |
-
$this->start_timestamp = current_time( 'timestamp' );
|
334 |
-
|
335 |
-
$this->set_archive_filename( implode( '-', array( sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ), 'backup', date( 'Y-m-d-H-i-s', $this->start_timestamp ) ) ) . '.zip' );
|
336 |
-
}
|
337 |
-
|
338 |
-
return $this->archive_filename;
|
339 |
-
|
340 |
-
}
|
341 |
-
|
342 |
-
/**
|
343 |
-
* Set the filename of the archive file
|
344 |
-
*
|
345 |
-
* @param string $filename
|
346 |
-
* @throws Exception
|
347 |
-
*/
|
348 |
-
public function set_archive_filename( $filename ) {
|
349 |
-
|
350 |
-
if ( empty( $filename ) || ! is_string( $filename ) )
|
351 |
-
throw new Exception( __( 'archive filename must be a non empty string', 'wpremote' ) );
|
352 |
-
|
353 |
-
if ( pathinfo( $filename, PATHINFO_EXTENSION ) !== 'zip' )
|
354 |
-
throw new Exception( __( 'invalid file extension for archive filename', 'wpremote' ) . '<code>' . $filename . '</code>' );
|
355 |
-
|
356 |
-
$this->archive_filename = strtolower( sanitize_file_name( remove_accents( $filename ) ) );
|
357 |
-
|
358 |
-
}
|
359 |
-
|
360 |
-
/**
|
361 |
-
* Get the full filepath to the database dump file.
|
362 |
-
*
|
363 |
-
* @access public
|
364 |
-
* @return string
|
365 |
-
*/
|
366 |
-
public function get_database_dump_filepath() {
|
367 |
-
|
368 |
-
return trailingslashit( $this->get_path() ) . $this->get_database_dump_filename();
|
369 |
-
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Get the filename of the database dump file
|
374 |
-
*
|
375 |
-
* @access public
|
376 |
-
* @return string
|
377 |
-
*/
|
378 |
-
public function get_database_dump_filename() {
|
379 |
-
|
380 |
-
if ( empty( $this->database_dump_filename ) )
|
381 |
-
$this->set_database_dump_filename( 'database_' . DB_NAME . '.sql' );
|
382 |
-
|
383 |
-
return $this->database_dump_filename;
|
384 |
-
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Set the filename of the database dump file
|
389 |
-
*
|
390 |
-
* @param string $filename
|
391 |
-
* @throws Exception
|
392 |
-
*/
|
393 |
-
public function set_database_dump_filename( $filename ) {
|
394 |
-
|
395 |
-
if ( empty( $filename ) || ! is_string( $filename ) )
|
396 |
-
throw new Exception( __( 'database dump filename must be a non empty string', 'wpremote' ) );
|
397 |
-
|
398 |
-
if ( pathinfo( $filename, PATHINFO_EXTENSION ) !== 'sql' )
|
399 |
-
throw new Exception( __( 'invalid file extension for database dump filename', 'wpremote' ) . '<code>' . $filename . '</code>' );
|
400 |
-
|
401 |
-
$this->database_dump_filename = strtolower( sanitize_file_name( remove_accents( $filename ) ) );
|
402 |
-
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* Get the root directory to backup from
|
407 |
-
*
|
408 |
-
* Defaults to the root of the path equivalent of your home_url
|
409 |
-
*
|
410 |
-
* @access public
|
411 |
-
* @return string
|
412 |
-
*/
|
413 |
-
public function get_root() {
|
414 |
-
|
415 |
-
if ( empty( $this->root ) )
|
416 |
-
$this->set_root( self::conform_dir( self::get_home_path() ) );
|
417 |
-
|
418 |
-
return $this->root;
|
419 |
-
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* Set the root directory to backup from
|
424 |
-
*
|
425 |
-
* @param string $path
|
426 |
-
* @throws Exception
|
427 |
-
*/
|
428 |
-
public function set_root( $path ) {
|
429 |
-
|
430 |
-
if ( empty( $path ) || ! is_string( $path ) || ! is_dir ( $path ) )
|
431 |
-
throw new Exception( sprintf( __( 'Invalid root path %s must be a valid directory path', 'wpremote' ), '<code>' . $path . '</code>' ) );
|
432 |
-
|
433 |
-
$this->root = self::conform_dir( $path );
|
434 |
-
|
435 |
-
}
|
436 |
-
|
437 |
-
/**
|
438 |
-
* Get the directory backups are saved to
|
439 |
-
*
|
440 |
-
* @access public
|
441 |
-
* @return string
|
442 |
-
*/
|
443 |
-
public function get_path() {
|
444 |
-
|
445 |
-
if ( empty( $this->path ) )
|
446 |
-
$this->set_path( self::conform_dir( self::get_path_default() ) );
|
447 |
-
|
448 |
-
return $this->path;
|
449 |
-
|
450 |
-
}
|
451 |
-
|
452 |
-
/**
|
453 |
-
* Get default backup path to save to.
|
454 |
-
*
|
455 |
-
* @return string
|
456 |
-
*/
|
457 |
-
protected function get_path_default() {
|
458 |
-
return WP_CONTENT_DIR . '/backups';
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Set the directory backups are saved to
|
463 |
-
*
|
464 |
-
* @param string $path
|
465 |
-
* @throws Exception
|
466 |
-
*/
|
467 |
-
public function set_path( $path ) {
|
468 |
-
|
469 |
-
if ( empty( $path ) || ! is_string( $path ) )
|
470 |
-
throw new Exception( sptrinf( __( 'Invalid backup path %s must be a non empty (string)', wpremote ), '<code>' . $path . '</code>' ) );
|
471 |
-
|
472 |
-
$this->path = self::conform_dir( $path );
|
473 |
-
|
474 |
-
}
|
475 |
-
|
476 |
-
/**
|
477 |
-
* Get the archive method that was used for the backup
|
478 |
-
*
|
479 |
-
* Will be either zip, ZipArchive or PclZip
|
480 |
-
*
|
481 |
-
* @access public
|
482 |
-
*/
|
483 |
-
public function get_archive_method() {
|
484 |
-
return $this->archive_method;
|
485 |
-
}
|
486 |
-
|
487 |
-
/**
|
488 |
-
* Get the database dump method that was used for the backup
|
489 |
-
*
|
490 |
-
* Will be either mysqldump or mysqldump_fallback
|
491 |
-
*
|
492 |
-
* @access public
|
493 |
-
*/
|
494 |
-
public function get_mysqldump_method() {
|
495 |
-
return $this->mysqldump_method;
|
496 |
-
}
|
497 |
-
|
498 |
-
/**
|
499 |
-
* Whether or not to use the file manifest
|
500 |
-
*
|
501 |
-
* @access public
|
502 |
-
*/
|
503 |
-
public function is_using_file_manifest() {
|
504 |
-
return apply_filters( 'hmbkp_use_file_manifest', (bool)$this->using_file_manifest );
|
505 |
-
}
|
506 |
-
|
507 |
-
/**
|
508 |
-
* Set whether or not to use the file manifest
|
509 |
-
*
|
510 |
-
* @access public
|
511 |
-
*/
|
512 |
-
public function set_is_using_file_manifest( $val ) {
|
513 |
-
$this->using_file_manifest = (bool)$val;
|
514 |
-
}
|
515 |
-
|
516 |
-
/**
|
517 |
-
* Create a series of file manifests for the backup
|
518 |
-
*
|
519 |
-
* @access private
|
520 |
-
*/
|
521 |
-
private function create_file_manifests() {
|
522 |
-
|
523 |
-
if ( is_dir( $this->get_file_manifest_dirpath() ) )
|
524 |
-
$this->rmdir_recursive( $this->get_file_manifest_dirpath() );
|
525 |
-
|
526 |
-
mkdir( $this->get_file_manifest_dirpath(), 0755 );
|
527 |
-
|
528 |
-
// Protect against directory browsing by including a index.html file
|
529 |
-
$index = $this->get_file_manifest_dirpath() . '/index.html';
|
530 |
-
if ( ! file_exists( $index ) && is_writable( $this->get_file_manifest_dirpath() ) )
|
531 |
-
file_put_contents( $index, '' );
|
532 |
-
|
533 |
-
$excludes = $this->exclude_string( 'regex' );
|
534 |
-
|
535 |
-
$file_manifest = array();
|
536 |
-
$this->file_manifest_remaining = 0;
|
537 |
-
$file_manifest_file_count = 0;
|
538 |
-
$current_batch = 0;
|
539 |
-
foreach( $this->get_files() as $file ) {
|
540 |
-
|
541 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
542 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
543 |
-
continue;
|
544 |
-
|
545 |
-
// Skip unreadable files
|
546 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
547 |
-
continue;
|
548 |
-
|
549 |
-
// Excludes
|
550 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
551 |
-
continue;
|
552 |
-
|
553 |
-
if ( $file->isDir() )
|
554 |
-
$line = trailingslashit( str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) );
|
555 |
-
|
556 |
-
elseif ( $file->isFile() )
|
557 |
-
$line = str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) );
|
558 |
-
|
559 |
-
// File manifest is full
|
560 |
-
if ( ! empty( $current_file ) && $current_batch >= $this->file_manifest_per_batch ) {
|
561 |
-
|
562 |
-
@fclose( $current_file );
|
563 |
-
$current_file = false;
|
564 |
-
|
565 |
-
}
|
566 |
-
|
567 |
-
// Create a new file manifest
|
568 |
-
if ( empty( $current_file ) ) {
|
569 |
-
|
570 |
-
$file_manifest_file_count++;
|
571 |
-
$file_manifest_filename = str_pad( $file_manifest_file_count, 10, "0", STR_PAD_LEFT );
|
572 |
-
if ( ! $current_file = @fopen( $this->get_file_manifest_dirpath() . '/' . $file_manifest_filename . '.txt', 'w' ) )
|
573 |
-
return false;
|
574 |
-
|
575 |
-
$current_batch = 0;
|
576 |
-
}
|
577 |
-
|
578 |
-
// Write the line to the file manifest if it isn't empty for some reason
|
579 |
-
if ( ! empty( $line ) ) {
|
580 |
-
@fwrite( $current_file, $line . PHP_EOL );
|
581 |
-
unset( $line );
|
582 |
-
$this->file_manifest_remaining++;
|
583 |
-
$current_batch++;
|
584 |
-
}
|
585 |
-
|
586 |
-
}
|
587 |
-
|
588 |
-
@file_put_contents( $this->get_path() . '/.file-manifest-remaining', $this->file_manifest_remaining );
|
589 |
-
|
590 |
-
return true;
|
591 |
-
}
|
592 |
-
|
593 |
-
/**
|
594 |
-
* Delete the current file manifest
|
595 |
-
*
|
596 |
-
* @access private
|
597 |
-
*/
|
598 |
-
private function delete_current_file_manifest() {
|
599 |
-
|
600 |
-
if ( ! file_exists( $this->current_file_manifest ) )
|
601 |
-
return false;
|
602 |
-
|
603 |
-
// Remove the file manifest because it's already been archived
|
604 |
-
unlink( $this->current_file_manifest );
|
605 |
-
|
606 |
-
// Update the count of remaining files.
|
607 |
-
$this->file_manifest_remaining = $this->file_manifest_remaining - count( $this->file_manifest_already_archived );
|
608 |
-
if ( $this->file_manifest_remaining < 0 )
|
609 |
-
$this->file_manifest_remaining = 0;
|
610 |
-
file_put_contents( $this->get_path() . '/.file-manifest-remaining', $this->file_manifest_remaining );
|
611 |
-
|
612 |
-
$this->file_manifest_already_archived = array();
|
613 |
-
|
614 |
-
}
|
615 |
-
|
616 |
-
|
617 |
-
/**
|
618 |
-
* Get the path to the file manifest directory
|
619 |
-
*
|
620 |
-
* @access private
|
621 |
-
*/
|
622 |
-
protected function get_file_manifest_dirpath() {
|
623 |
-
return $this->get_path() . '/.file-manifests';
|
624 |
-
}
|
625 |
-
|
626 |
-
/**
|
627 |
-
* Get batch of files to archive from the file manifest
|
628 |
-
* Ignore any files that already have been archived
|
629 |
-
*
|
630 |
-
* @access private
|
631 |
-
*/
|
632 |
-
private function get_next_files_from_file_manifest() {
|
633 |
-
|
634 |
-
if ( ! is_dir( $this->get_file_manifest_dirpath() ) )
|
635 |
-
return array();
|
636 |
-
|
637 |
-
$files = glob( $this->get_file_manifest_dirpath() . '/*.txt' );
|
638 |
-
if ( empty( $files ) )
|
639 |
-
return array();
|
640 |
-
|
641 |
-
$this->current_file_manifest = array_shift( $files );
|
642 |
-
|
643 |
-
$files = file_get_contents( $this->current_file_manifest );
|
644 |
-
$files = array_map( 'trim', explode( PHP_EOL, $files ) );
|
645 |
-
if ( empty( $files ) )
|
646 |
-
return array();
|
647 |
-
|
648 |
-
$this->file_manifest_remaining = (int)file_get_contents( $this->get_path() . '/.file-manifest-remaining' );
|
649 |
-
|
650 |
-
return $files;
|
651 |
-
}
|
652 |
-
|
653 |
-
/**
|
654 |
-
* Get the backup type
|
655 |
-
*
|
656 |
-
* Defaults to complete
|
657 |
-
*
|
658 |
-
* @access public
|
659 |
-
*/
|
660 |
-
public function get_type() {
|
661 |
-
|
662 |
-
if ( empty( $this->type ) )
|
663 |
-
$this->set_type( 'complete' );
|
664 |
-
|
665 |
-
return $this->type;
|
666 |
-
|
667 |
-
}
|
668 |
-
|
669 |
-
/**
|
670 |
-
* Set the backup type
|
671 |
-
*
|
672 |
-
* $type must be one of complete, database or file
|
673 |
-
* @param string $type
|
674 |
-
* @throws Exception
|
675 |
-
*/
|
676 |
-
public function set_type( $type ) {
|
677 |
-
|
678 |
-
if ( ! is_string( $type ) || ! in_array( $type, array( 'file', 'database', 'complete' ) ) )
|
679 |
-
throw new Exception( sprintf( __( 'Invalid backup type %s must be one of (string) file, database or complete', 'wpremote' ), '<code>' . $type . '</code>' ) );
|
680 |
-
|
681 |
-
$this->type = $type;
|
682 |
-
|
683 |
-
}
|
684 |
-
|
685 |
-
/**
|
686 |
-
* Get the path to the mysqldump bin
|
687 |
-
*
|
688 |
-
* If not explicitly set will attempt to work
|
689 |
-
* it out by checking common locations
|
690 |
-
*
|
691 |
-
* @access public
|
692 |
-
* @return string
|
693 |
-
*/
|
694 |
-
public function get_mysqldump_command_path() {
|
695 |
-
|
696 |
-
// Check shell_exec is available
|
697 |
-
if ( ! self::is_shell_exec_available() )
|
698 |
-
return '';
|
699 |
-
|
700 |
-
// Return now if it's already been set
|
701 |
-
if ( isset( $this->mysqldump_command_path ) )
|
702 |
-
return $this->mysqldump_command_path;
|
703 |
-
|
704 |
-
$this->mysqldump_command_path = '';
|
705 |
-
|
706 |
-
// Does mysqldump work
|
707 |
-
if ( is_null( shell_exec( 'hash mysqldump 2>&1' ) ) ) {
|
708 |
-
|
709 |
-
// If so store it for later
|
710 |
-
$this->set_mysqldump_command_path( 'mysqldump' );
|
711 |
-
|
712 |
-
// And return now
|
713 |
-
return $this->mysqldump_command_path;
|
714 |
-
|
715 |
-
}
|
716 |
-
|
717 |
-
// List of possible mysqldump locations
|
718 |
-
$mysqldump_locations = array(
|
719 |
-
'/usr/local/bin/mysqldump',
|
720 |
-
'/usr/local/mysql/bin/mysqldump',
|
721 |
-
'/usr/mysql/bin/mysqldump',
|
722 |
-
'/usr/bin/mysqldump',
|
723 |
-
'/opt/local/lib/mysql6/bin/mysqldump',
|
724 |
-
'/opt/local/lib/mysql5/bin/mysqldump',
|
725 |
-
'/opt/local/lib/mysql4/bin/mysqldump',
|
726 |
-
'/xampp/mysql/bin/mysqldump',
|
727 |
-
'/Program Files/xampp/mysql/bin/mysqldump',
|
728 |
-
'/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
|
729 |
-
'/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
|
730 |
-
'/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
|
731 |
-
'/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
|
732 |
-
'/Program Files/MySQL/MySQL Server 5.0/bin/mysqldump',
|
733 |
-
'/Program Files/MySQL/MySQL Server 4.1/bin/mysqldump',
|
734 |
-
'/opt/local/bin/mysqldump',
|
735 |
-
);
|
736 |
-
|
737 |
-
// Find the one which works
|
738 |
-
foreach ( $mysqldump_locations as $location )
|
739 |
-
if ( @is_executable( self::conform_dir( $location ) ) )
|
740 |
-
$this->set_mysqldump_command_path( $location );
|
741 |
-
|
742 |
-
return $this->mysqldump_command_path;
|
743 |
-
|
744 |
-
}
|
745 |
-
|
746 |
-
/**
|
747 |
-
* Set the path to the mysqldump bin
|
748 |
-
*
|
749 |
-
* Setting the path to false will cause the database
|
750 |
-
* dump to use the php fallback
|
751 |
-
*
|
752 |
-
* @access public
|
753 |
-
* @param mixed $path
|
754 |
-
*/
|
755 |
-
public function set_mysqldump_command_path( $path ) {
|
756 |
-
|
757 |
-
$this->mysqldump_command_path = $path;
|
758 |
-
|
759 |
-
}
|
760 |
-
|
761 |
-
/**
|
762 |
-
* Get the path to the zip bin
|
763 |
-
*
|
764 |
-
* If not explicitly set will attempt to work
|
765 |
-
* it out by checking common locations
|
766 |
-
*
|
767 |
-
* @access public
|
768 |
-
* @return string
|
769 |
-
*/
|
770 |
-
public function get_zip_command_path() {
|
771 |
-
|
772 |
-
// Check shell_exec is available
|
773 |
-
if ( ! self::is_shell_exec_available() )
|
774 |
-
return '';
|
775 |
-
|
776 |
-
// Return now if it's already been set
|
777 |
-
if ( isset( $this->zip_command_path ) )
|
778 |
-
return $this->zip_command_path;
|
779 |
-
|
780 |
-
$this->zip_command_path = '';
|
781 |
-
|
782 |
-
// Does zip work
|
783 |
-
if ( is_null( shell_exec( 'hash zip 2>&1' ) ) ) {
|
784 |
-
|
785 |
-
// If so store it for later
|
786 |
-
$this->set_zip_command_path( 'zip' );
|
787 |
-
|
788 |
-
// And return now
|
789 |
-
return $this->zip_command_path;
|
790 |
-
|
791 |
-
}
|
792 |
-
|
793 |
-
// List of possible zip locations
|
794 |
-
$zip_locations = array(
|
795 |
-
'/usr/bin/zip',
|
796 |
-
'/opt/local/bin/zip',
|
797 |
-
);
|
798 |
-
|
799 |
-
// Find the one which works
|
800 |
-
foreach ( $zip_locations as $location )
|
801 |
-
if ( @is_executable( self::conform_dir( $location ) ) )
|
802 |
-
$this->set_zip_command_path( $location );
|
803 |
-
|
804 |
-
return $this->zip_command_path;
|
805 |
-
|
806 |
-
}
|
807 |
-
|
808 |
-
/**
|
809 |
-
* Set the path to the zip bin
|
810 |
-
*
|
811 |
-
* Setting the path to false will cause the database
|
812 |
-
* dump to use the php fallback
|
813 |
-
*
|
814 |
-
* @access public
|
815 |
-
* @param mixed $path
|
816 |
-
*/
|
817 |
-
public function set_zip_command_path( $path ) {
|
818 |
-
|
819 |
-
$this->zip_command_path = $path;
|
820 |
-
|
821 |
-
}
|
822 |
-
|
823 |
-
/**
|
824 |
-
* Set up the ZipArchive instance if ZipArchive is available
|
825 |
-
*/
|
826 |
-
protected function &setup_ziparchive() {
|
827 |
-
|
828 |
-
// Instance is already open
|
829 |
-
if ( ! empty( $this->ziparchive ) ) {
|
830 |
-
$this->ziparchive->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE );
|
831 |
-
return $this->ziparchive;
|
832 |
-
}
|
833 |
-
|
834 |
-
$ziparchive = new ZipArchive;
|
835 |
-
|
836 |
-
// Try opening ZipArchive
|
837 |
-
if ( ! file_exists( $this->get_archive_filepath() ) )
|
838 |
-
$ret = $ziparchive->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE );
|
839 |
-
else
|
840 |
-
$ret = $ziparchive->open( $this->get_archive_filepath() );
|
841 |
-
|
842 |
-
// File couldn't be opened
|
843 |
-
if ( ! $ret )
|
844 |
-
return false;
|
845 |
-
|
846 |
-
// Try closing ZipArchive
|
847 |
-
$ret = $ziparchive->close();
|
848 |
-
|
849 |
-
// File couldn't be closed
|
850 |
-
if ( ! $ret )
|
851 |
-
return false;
|
852 |
-
|
853 |
-
// Open it once more
|
854 |
-
if ( ! file_exists( $this->get_archive_filepath() ) )
|
855 |
-
$ziparchive->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE );
|
856 |
-
else
|
857 |
-
$ziparchive->open( $this->get_archive_filepath() );
|
858 |
-
|
859 |
-
$this->ziparchive = $ziparchive;
|
860 |
-
return $this->ziparchive;
|
861 |
-
}
|
862 |
-
|
863 |
-
/**
|
864 |
-
* Set up the PclZip instance
|
865 |
-
*
|
866 |
-
* @access protected
|
867 |
-
*/
|
868 |
-
protected function &setup_pclzip() {
|
869 |
-
|
870 |
-
if ( empty( $this->pclzip ) ) {
|
871 |
-
$this->load_pclzip();
|
872 |
-
$this->pclzip = new PclZip( $this->get_archive_filepath() );
|
873 |
-
}
|
874 |
-
return $this->pclzip;
|
875 |
-
}
|
876 |
-
|
877 |
-
protected function do_action( $action ) {
|
878 |
-
|
879 |
-
do_action( $action, $this );
|
880 |
-
|
881 |
-
}
|
882 |
-
|
883 |
-
/**
|
884 |
-
* Kick off a backup
|
885 |
-
*
|
886 |
-
* @access public
|
887 |
-
* @return bool
|
888 |
-
*/
|
889 |
-
public function backup() {
|
890 |
-
|
891 |
-
$this->do_action( 'hmbkp_backup_started' );
|
892 |
-
|
893 |
-
// Backup database
|
894 |
-
if ( $this->get_type() !== 'file' )
|
895 |
-
$this->dump_database();
|
896 |
-
|
897 |
-
// Zip everything up
|
898 |
-
$this->archive();
|
899 |
-
|
900 |
-
$this->do_action( 'hmbkp_backup_complete' );
|
901 |
-
|
902 |
-
}
|
903 |
-
|
904 |
-
/**
|
905 |
-
* Create the mysql backup
|
906 |
-
*
|
907 |
-
* Uses mysqldump if available, falls back to PHP
|
908 |
-
* if not.
|
909 |
-
*
|
910 |
-
* @access public
|
911 |
-
*/
|
912 |
-
public function dump_database() {
|
913 |
-
|
914 |
-
if ( $this->get_mysqldump_command_path() )
|
915 |
-
$this->mysqldump();
|
916 |
-
|
917 |
-
if ( empty( $this->mysqldump_verified ) )
|
918 |
-
$this->mysqldump_fallback();
|
919 |
-
|
920 |
-
$this->do_action( 'hmbkp_mysqldump_finished' );
|
921 |
-
|
922 |
-
}
|
923 |
-
|
924 |
-
public function mysqldump() {
|
925 |
-
|
926 |
-
$this->mysqldump_method = 'mysqldump';
|
927 |
-
|
928 |
-
$this->do_action( 'hmbkp_mysqldump_started' );
|
929 |
-
|
930 |
-
$host = explode( ':', DB_HOST );
|
931 |
-
|
932 |
-
$host = reset( $host );
|
933 |
-
$port = strpos( DB_HOST, ':' ) ? end( explode( ':', DB_HOST ) ) : '';
|
934 |
-
|
935 |
-
// Path to the mysqldump executable
|
936 |
-
$cmd = escapeshellarg( $this->get_mysqldump_command_path() );
|
937 |
-
|
938 |
-
// We don't want to create a new DB
|
939 |
-
$cmd .= ' --no-create-db';
|
940 |
-
|
941 |
-
// Allow lock-tables to be overridden
|
942 |
-
if ( ! defined( 'HMBKP_MYSQLDUMP_SINGLE_TRANSACTION' ) || HMBKP_MYSQLDUMP_SINGLE_TRANSACTION !== false )
|
943 |
-
$cmd .= ' --single-transaction';
|
944 |
-
|
945 |
-
// Make sure binary data is exported properly
|
946 |
-
$cmd .= ' --hex-blob';
|
947 |
-
|
948 |
-
// Username
|
949 |
-
$cmd .= ' -u ' . escapeshellarg( DB_USER );
|
950 |
-
|
951 |
-
// Don't pass the password if it's blank
|
952 |
-
if ( DB_PASSWORD )
|
953 |
-
$cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
|
954 |
-
|
955 |
-
// Set the host
|
956 |
-
$cmd .= ' -h ' . escapeshellarg( $host );
|
957 |
-
|
958 |
-
// Set the port if it was set
|
959 |
-
if ( ! empty( $port ) && is_numeric( $port ) )
|
960 |
-
$cmd .= ' -P ' . $port;
|
961 |
-
|
962 |
-
// The file we're saving too
|
963 |
-
$cmd .= ' -r ' . escapeshellarg( $this->get_database_dump_filepath() );
|
964 |
-
|
965 |
-
// The database we're dumping
|
966 |
-
$cmd .= ' ' . escapeshellarg( DB_NAME );
|
967 |
-
|
968 |
-
// Pipe STDERR to STDOUT
|
969 |
-
$cmd .= ' 2>&1';
|
970 |
-
|
971 |
-
// Store any returned data in an error
|
972 |
-
$stderr = shell_exec( $cmd );
|
973 |
-
|
974 |
-
// Skip the new password warning that is output in mysql > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
|
975 |
-
if ( trim( $stderr ) === 'Warning: Using a password on the command line interface can be insecure.' ) {
|
976 |
-
$stderr = '';
|
977 |
-
}
|
978 |
-
|
979 |
-
if ( $stderr ) {
|
980 |
-
$this->error( $this->get_mysqldump_method(), $stderr );
|
981 |
-
}
|
982 |
-
|
983 |
-
$this->verify_mysqldump();
|
984 |
-
|
985 |
-
}
|
986 |
-
|
987 |
-
/**
|
988 |
-
* PHP mysqldump fallback functions, exports the database to a .sql file
|
989 |
-
*
|
990 |
-
* @access public
|
991 |
-
*/
|
992 |
-
public function mysqldump_fallback() {
|
993 |
-
|
994 |
-
$this->errors_to_warnings( $this->get_mysqldump_method() );
|
995 |
-
|
996 |
-
$this->mysqldump_method = 'mysqldump_fallback';
|
997 |
-
|
998 |
-
$this->do_action( 'hmbkp_mysqldump_started' );
|
999 |
-
|
1000 |
-
$this->db = @mysqli_connect( 'p:'.DB_HOST, DB_USER, DB_PASSWORD, DB_NAME );
|
1001 |
-
|
1002 |
-
if ( ! $this->db )
|
1003 |
-
$this->db = mysqli_connect( DB_HOST, DB_USER, DB_PASSWORD, DB_NAME );
|
1004 |
-
|
1005 |
-
if ( ! $this->db )
|
1006 |
-
return;
|
1007 |
-
|
1008 |
-
// mysql_select_db( DB_NAME, $this->db );
|
1009 |
-
|
1010 |
-
if ( function_exists( 'mysqli_set_charset') )
|
1011 |
-
mysqli_set_charset( $this->db, DB_CHARSET );
|
1012 |
-
|
1013 |
-
// Begin new backup of MySql
|
1014 |
-
$tables = mysqli_query( $this->db, 'SHOW TABLES' );
|
1015 |
-
|
1016 |
-
$sql_file = "# WordPress : " . get_bloginfo( 'url' ) . " MySQL database backup\n";
|
1017 |
-
$sql_file .= "#\n";
|
1018 |
-
$sql_file .= "# Generated: " . date( 'l j. F Y H:i T' ) . "\n";
|
1019 |
-
$sql_file .= "# Hostname: " . DB_HOST . "\n";
|
1020 |
-
$sql_file .= "# Database: " . $this->sql_backquote( DB_NAME ) . "\n";
|
1021 |
-
$sql_file .= "# --------------------------------------------------------\n";
|
1022 |
-
|
1023 |
-
while ( $row = mysqli_fetch_array($tables) ) {
|
1024 |
-
$curr_table = $row[0];
|
1025 |
-
|
1026 |
-
// Create the SQL statements
|
1027 |
-
$sql_file .= "# --------------------------------------------------------\n";
|
1028 |
-
$sql_file .= "# Table: " . $this->sql_backquote( $curr_table ) . "\n";
|
1029 |
-
$sql_file .= "# --------------------------------------------------------\n";
|
1030 |
-
|
1031 |
-
$this->make_sql( $sql_file, $curr_table );
|
1032 |
-
|
1033 |
-
}
|
1034 |
-
|
1035 |
-
}
|
1036 |
-
|
1037 |
-
/**
|
1038 |
-
* Zip up all the files.
|
1039 |
-
*
|
1040 |
-
* Attempts to use the shell zip command, if
|
1041 |
-
* thats not available then it falls back to
|
1042 |
-
* PHP ZipArchive and finally PclZip.
|
1043 |
-
*
|
1044 |
-
* @access public
|
1045 |
-
*/
|
1046 |
-
public function archive() {
|
1047 |
-
|
1048 |
-
// If using a manifest, perform the backup in chunks
|
1049 |
-
if ( 'database' !== $this->get_type()
|
1050 |
-
&& $this->is_using_file_manifest()
|
1051 |
-
&& $this->create_file_manifests() ) {
|
1052 |
-
|
1053 |
-
$this->archive_via_file_manifest();
|
1054 |
-
|
1055 |
-
} else {
|
1056 |
-
|
1057 |
-
$this->archive_via_single_request();
|
1058 |
-
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
/**
|
1064 |
-
* Archive with a file manifest
|
1065 |
-
*
|
1066 |
-
* @access private
|
1067 |
-
*/
|
1068 |
-
private function archive_via_file_manifest() {
|
1069 |
-
|
1070 |
-
$errors = array();
|
1071 |
-
|
1072 |
-
// Back up files from the file manifest in chunks
|
1073 |
-
$next_files = $this->get_next_files_from_file_manifest();
|
1074 |
-
do {
|
1075 |
-
|
1076 |
-
$this->do_action( 'hmbkp_archive_started' );
|
1077 |
-
|
1078 |
-
// `zip` is the most performant archive method
|
1079 |
-
if ( $this->get_zip_command_path() ) {
|
1080 |
-
$this->archive_method = 'zip_files';
|
1081 |
-
$error = $this->zip_files( $next_files );
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
// ZipArchive is also pretty fast for chunked backups
|
1085 |
-
else if ( class_exists( 'ZipArchive' ) && empty( $this->skip_zip_archive ) ) {
|
1086 |
-
$this->archive_method = 'zip_archive_files';
|
1087 |
-
|
1088 |
-
$ret = $this->zip_archive_files( $next_files );
|
1089 |
-
if ( ! $ret ) {
|
1090 |
-
$this->skip_zip_archive = true;
|
1091 |
-
continue;
|
1092 |
-
}
|
1093 |
-
}
|
1094 |
-
|
1095 |
-
// Last opportunity
|
1096 |
-
else {
|
1097 |
-
$this->archive_method = 'pcl_zip_files';
|
1098 |
-
$error = $this->pcl_zip_files( $next_files );
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
if ( ! empty( $error ) ) {
|
1102 |
-
$errors[] = $error;
|
1103 |
-
unset( $error );
|
1104 |
-
}
|
1105 |
-
|
1106 |
-
// Update the file manifest with these files that were archived
|
1107 |
-
$this->file_manifest_already_archived = array_merge( $this->file_manifest_already_archived, $next_files );
|
1108 |
-
$this->delete_current_file_manifest();
|
1109 |
-
|
1110 |
-
// Get the next set of files to archive
|
1111 |
-
$next_files = $this->get_next_files_from_file_manifest();
|
1112 |
-
|
1113 |
-
} while( ! empty( $next_files ) );
|
1114 |
-
|
1115 |
-
// If the database should be included in the backup, it's included last
|
1116 |
-
if ( 'file' !== $this->get_type() && file_exists( $this->get_database_dump_filepath() ) ) {
|
1117 |
-
|
1118 |
-
switch ( $this->archive_method ) {
|
1119 |
-
|
1120 |
-
case 'zip_archive_files':
|
1121 |
-
|
1122 |
-
$zip = &$this->setup_ziparchive();
|
1123 |
-
|
1124 |
-
$zip->addFile( $this->get_database_dump_filepath(), $this->get_database_dump_filename() );
|
1125 |
-
|
1126 |
-
$zip->close();
|
1127 |
-
|
1128 |
-
break;
|
1129 |
-
|
1130 |
-
case 'zip_files':
|
1131 |
-
|
1132 |
-
$error = shell_exec( 'cd ' . escapeshellarg( $this->get_path() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -uq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . escapeshellarg( $this->get_database_dump_filename() ) . ' 2>&1' );
|
1133 |
-
|
1134 |
-
break;
|
1135 |
-
|
1136 |
-
case 'pcl_zip_files':
|
1137 |
-
|
1138 |
-
$pclzip = &$this->setup_pclzip();
|
1139 |
-
|
1140 |
-
if ( ! $pclzip->add( $this->get_database_dump_filepath(), PCLZIP_OPT_REMOVE_PATH, $this->get_path() ) )
|
1141 |
-
$this->warning( $this->get_archive_method(), $pclzip->errorInfo( true ) );
|
1142 |
-
|
1143 |
-
break;
|
1144 |
-
}
|
1145 |
-
|
1146 |
-
if ( ! empty( $error ) ) {
|
1147 |
-
$errors[] = $error;
|
1148 |
-
unset( $error );
|
1149 |
-
}
|
1150 |
-
}
|
1151 |
-
|
1152 |
-
// If the methods produced any errors, log them
|
1153 |
-
if ( ! empty( $errors ) )
|
1154 |
-
$this->warning( $this->get_archive_method(), implode( ', ', $errors ) );
|
1155 |
-
|
1156 |
-
// ZipArchive has some special reporting requirements
|
1157 |
-
if ( ! empty( $this->ziparchive ) ) {
|
1158 |
-
|
1159 |
-
if ( $this->ziparchive->status )
|
1160 |
-
$this->warning( $this->get_archive_method(), $this->ziparchive->status );
|
1161 |
-
|
1162 |
-
if ( $this->ziparchive->statusSys )
|
1163 |
-
$this->warning( $this->get_archive_method(), $this->ziparchive->statusSys );
|
1164 |
-
|
1165 |
-
}
|
1166 |
-
|
1167 |
-
// Verify and remove if errors
|
1168 |
-
$this->verify_archive();
|
1169 |
-
|
1170 |
-
// Remove the file manifest
|
1171 |
-
if ( is_dir( $this->get_file_manifest_dirpath() ) )
|
1172 |
-
$this->rmdir_recursive( $this->get_file_manifest_dirpath() );
|
1173 |
-
|
1174 |
-
// Delete the database dump file
|
1175 |
-
if ( file_exists( $this->get_database_dump_filepath() ) )
|
1176 |
-
unlink( $this->get_database_dump_filepath() );
|
1177 |
-
|
1178 |
-
$this->do_action( 'hmbkp_archive_finished' );
|
1179 |
-
|
1180 |
-
}
|
1181 |
-
|
1182 |
-
/**
|
1183 |
-
* Archive using our traditional method of one request
|
1184 |
-
*
|
1185 |
-
* @access private
|
1186 |
-
*/
|
1187 |
-
private function archive_via_single_request() {
|
1188 |
-
|
1189 |
-
// Do we have the path to the zip command
|
1190 |
-
if ( $this->get_zip_command_path() )
|
1191 |
-
$this->zip();
|
1192 |
-
|
1193 |
-
// If not or if the shell zip failed then use ZipArchive
|
1194 |
-
if ( empty( $this->archive_verified ) && class_exists( 'ZipArchive' ) && empty( $this->skip_zip_archive ) )
|
1195 |
-
$this->zip_archive();
|
1196 |
-
|
1197 |
-
// If ZipArchive is unavailable or one of the above failed
|
1198 |
-
if ( empty( $this->archive_verified ) )
|
1199 |
-
$this->pcl_zip();
|
1200 |
-
|
1201 |
-
// Delete the database dump file
|
1202 |
-
if ( file_exists( $this->get_database_dump_filepath() ) )
|
1203 |
-
unlink( $this->get_database_dump_filepath() );
|
1204 |
-
|
1205 |
-
$this->do_action( 'hmbkp_archive_finished' );
|
1206 |
-
|
1207 |
-
}
|
1208 |
-
|
1209 |
-
/**
|
1210 |
-
* Restart a failed archive process
|
1211 |
-
*
|
1212 |
-
* @access public
|
1213 |
-
*/
|
1214 |
-
public function restart_archive() {
|
1215 |
-
|
1216 |
-
if ( $this->is_using_file_manifest() ) {
|
1217 |
-
|
1218 |
-
$this->archive_via_file_manifest();
|
1219 |
-
|
1220 |
-
} else {
|
1221 |
-
|
1222 |
-
$this->archive_via_single_request();
|
1223 |
-
|
1224 |
-
}
|
1225 |
-
|
1226 |
-
$this->do_action( 'hmbkp_backup_complete' );
|
1227 |
-
}
|
1228 |
-
|
1229 |
-
/**
|
1230 |
-
* Zip using the native zip command
|
1231 |
-
*
|
1232 |
-
* @access public
|
1233 |
-
*/
|
1234 |
-
public function zip() {
|
1235 |
-
|
1236 |
-
$this->archive_method = 'zip';
|
1237 |
-
|
1238 |
-
$this->do_action( 'hmbkp_archive_started' );
|
1239 |
-
|
1240 |
-
// Zip up $this->root with excludes
|
1241 |
-
if ( $this->get_type() !== 'database' && $this->exclude_string( 'zip' ) ) {
|
1242 |
-
$stderr = shell_exec( 'cd ' . escapeshellarg( $this->get_root() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -rq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ./' . ' -x ' . $this->exclude_string( 'zip' ) . ' 2>&1' );
|
1243 |
-
|
1244 |
-
// Zip up $this->root without excludes
|
1245 |
-
} elseif ( $this->get_type() !== 'database' ) {
|
1246 |
-
$stderr = shell_exec( 'cd ' . escapeshellarg( $this->get_root() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -rq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ./' . ' 2>&1' );
|
1247 |
-
|
1248 |
-
}
|
1249 |
-
|
1250 |
-
// Add the database dump to the archive
|
1251 |
-
if ( $this->get_type() !== 'file' && file_exists( $this->get_database_dump_filepath() ) )
|
1252 |
-
$stderr = shell_exec( 'cd ' . escapeshellarg( $this->get_path() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -uq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . escapeshellarg( $this->get_database_dump_filename() ) . ' 2>&1' );
|
1253 |
-
|
1254 |
-
if ( ! empty( $stderr ) )
|
1255 |
-
$this->warning( $this->get_archive_method(), $stderr );
|
1256 |
-
|
1257 |
-
$this->verify_archive();
|
1258 |
-
}
|
1259 |
-
|
1260 |
-
/**
|
1261 |
-
* Zip one or more files
|
1262 |
-
*
|
1263 |
-
* @access private
|
1264 |
-
*/
|
1265 |
-
private function zip_files( $files ) {
|
1266 |
-
|
1267 |
-
// Not necessary to include directories when using `zip`
|
1268 |
-
foreach( $files as $key => $file ) {
|
1269 |
-
|
1270 |
-
if ( ! is_dir( $file ) )
|
1271 |
-
continue;
|
1272 |
-
|
1273 |
-
unset( $files[$key] );
|
1274 |
-
}
|
1275 |
-
|
1276 |
-
return shell_exec( 'cd ' . escapeshellarg( $this->get_root() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . implode( ' ', $files ) . ' -q 2>&1' );
|
1277 |
-
}
|
1278 |
-
|
1279 |
-
/**
|
1280 |
-
* Fallback for creating zip archives if zip command is
|
1281 |
-
* unavailable.
|
1282 |
-
*/
|
1283 |
-
public function zip_archive() {
|
1284 |
-
|
1285 |
-
$this->errors_to_warnings( $this->get_archive_method() );
|
1286 |
-
$this->archive_method = 'ziparchive';
|
1287 |
-
|
1288 |
-
$this->do_action( 'hmbkp_archive_started' );
|
1289 |
-
|
1290 |
-
if ( false === ( $zip = &$this->setup_ziparchive() ) )
|
1291 |
-
return;
|
1292 |
-
|
1293 |
-
$excludes = $this->exclude_string( 'regex' );
|
1294 |
-
|
1295 |
-
if ( $this->get_type() !== 'database' ) {
|
1296 |
-
|
1297 |
-
$files_added = 0;
|
1298 |
-
|
1299 |
-
foreach ( $this->get_files() as $file ) {
|
1300 |
-
|
1301 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1302 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1303 |
-
continue;
|
1304 |
-
|
1305 |
-
// Skip unreadable files
|
1306 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1307 |
-
continue;
|
1308 |
-
|
1309 |
-
// Excludes
|
1310 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
1311 |
-
continue;
|
1312 |
-
|
1313 |
-
if ( $file->isDir() )
|
1314 |
-
$zip->addEmptyDir( trailingslashit( str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) );
|
1315 |
-
|
1316 |
-
elseif ( $file->isFile() )
|
1317 |
-
$zip->addFile( $file->getPathname(), str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) );
|
1318 |
-
|
1319 |
-
if ( ++$files_added % 500 === 0 )
|
1320 |
-
if ( ! $zip->close() || ! $zip->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE ) )
|
1321 |
-
return;
|
1322 |
-
|
1323 |
-
}
|
1324 |
-
|
1325 |
-
}
|
1326 |
-
|
1327 |
-
// Add the database
|
1328 |
-
if ( $this->get_type() !== 'file' && file_exists( $this->get_database_dump_filepath() ) )
|
1329 |
-
$zip->addFile( $this->get_database_dump_filepath(), $this->get_database_dump_filename() );
|
1330 |
-
|
1331 |
-
if ( $zip->status )
|
1332 |
-
$this->warning( $this->get_archive_method(), $zip->status );
|
1333 |
-
|
1334 |
-
if ( $zip->statusSys )
|
1335 |
-
$this->warning( $this->get_archive_method(), $zip->statusSys );
|
1336 |
-
|
1337 |
-
$zip->close();
|
1338 |
-
|
1339 |
-
$this->verify_archive();
|
1340 |
-
|
1341 |
-
}
|
1342 |
-
|
1343 |
-
/**
|
1344 |
-
* Zip Archive one or more files
|
1345 |
-
*
|
1346 |
-
* @access private
|
1347 |
-
*/
|
1348 |
-
private function zip_archive_files( $files ) {
|
1349 |
-
|
1350 |
-
if ( false === ( $zip = &$this->setup_ziparchive() ) )
|
1351 |
-
return false;
|
1352 |
-
|
1353 |
-
foreach( $files as $file ) {
|
1354 |
-
|
1355 |
-
$full_path = trailingslashit( $this->get_root() ) . $file;
|
1356 |
-
if ( is_dir( $full_path ) )
|
1357 |
-
$zip->addEmptyDir( $file );
|
1358 |
-
else
|
1359 |
-
$zip->addFile( $full_path, $file );
|
1360 |
-
|
1361 |
-
}
|
1362 |
-
|
1363 |
-
// Avoid limitations in ZipArchive by making sure we save each batch to disk
|
1364 |
-
$zip->close();
|
1365 |
-
return true;
|
1366 |
-
}
|
1367 |
-
|
1368 |
-
/**
|
1369 |
-
* Fallback for creating zip archives if zip command and ZipArchive are
|
1370 |
-
* unavailable.
|
1371 |
-
*
|
1372 |
-
* Uses the PclZip library that ships with WordPress
|
1373 |
-
*/
|
1374 |
-
public function pcl_zip() {
|
1375 |
-
|
1376 |
-
$this->errors_to_warnings( $this->get_archive_method() );
|
1377 |
-
$this->archive_method = 'pclzip';
|
1378 |
-
|
1379 |
-
$this->do_action( 'hmbkp_archive_started' );
|
1380 |
-
|
1381 |
-
global $_wprp_hmbkp_exclude_string;
|
1382 |
-
|
1383 |
-
$_wprp_hmbkp_exclude_string = $this->exclude_string( 'regex' );
|
1384 |
-
|
1385 |
-
$archive = &$this->setup_pclzip();
|
1386 |
-
|
1387 |
-
// Zip up everything
|
1388 |
-
if ( $this->get_type() !== 'database' )
|
1389 |
-
if ( ! $archive->add( $this->get_root(), PCLZIP_OPT_REMOVE_PATH, $this->get_root(), PCLZIP_CB_PRE_ADD, 'wprp_hmbkp_pclzip_callback' ) )
|
1390 |
-
$this->warning( $this->get_archive_method(), $archive->errorInfo( true ) );
|
1391 |
-
|
1392 |
-
// Add the database
|
1393 |
-
if ( $this->get_type() !== 'file' && file_exists( $this->get_database_dump_filepath() ) )
|
1394 |
-
if ( ! $archive->add( $this->get_database_dump_filepath(), PCLZIP_OPT_REMOVE_PATH, $this->get_path() ) )
|
1395 |
-
$this->warning( $this->get_archive_method(), $archive->errorInfo( true ) );
|
1396 |
-
|
1397 |
-
unset( $GLOBALS['_wprp_hmbkp_exclude_string'] );
|
1398 |
-
|
1399 |
-
$this->verify_archive();
|
1400 |
-
|
1401 |
-
}
|
1402 |
-
|
1403 |
-
/**
|
1404 |
-
* Use PclZip to archive batches of files
|
1405 |
-
*/
|
1406 |
-
private function pcl_zip_files( $files ) {
|
1407 |
-
|
1408 |
-
$this->errors_to_warnings( $this->get_archive_method() );
|
1409 |
-
|
1410 |
-
$pclzip = &$this->setup_pclzip();
|
1411 |
-
|
1412 |
-
foreach( $files as $file ) {
|
1413 |
-
|
1414 |
-
$full_path = trailingslashit( $this->get_root() ) . $file;
|
1415 |
-
if ( is_dir( $full_path ) )
|
1416 |
-
continue;
|
1417 |
-
|
1418 |
-
if ( ! $pclzip->add( $full_path, PCLZIP_OPT_REMOVE_PATH, $this->get_root() ) )
|
1419 |
-
$this->warning( $this->get_archive_method(), $pclzip->errorInfo( true ) );
|
1420 |
-
|
1421 |
-
}
|
1422 |
-
|
1423 |
-
}
|
1424 |
-
|
1425 |
-
public function verify_mysqldump() {
|
1426 |
-
|
1427 |
-
$this->do_action( 'hmbkp_mysqldump_verify_started' );
|
1428 |
-
|
1429 |
-
// If we've already passed then no need to check again
|
1430 |
-
if ( ! empty( $this->mysqldump_verified ) )
|
1431 |
-
return true;
|
1432 |
-
|
1433 |
-
// If there are mysqldump errors delete the database dump file as mysqldump will still have written one
|
1434 |
-
if ( $this->get_errors( $this->get_mysqldump_method() ) && file_exists( $this->get_database_dump_filepath() ) )
|
1435 |
-
unlink( $this->get_database_dump_filepath() );
|
1436 |
-
|
1437 |
-
// If we have an empty file delete it
|
1438 |
-
if ( @filesize( $this->get_database_dump_filepath() ) === 0 )
|
1439 |
-
unlink( $this->get_database_dump_filepath() );
|
1440 |
-
|
1441 |
-
// If the file still exists then it must be good
|
1442 |
-
if ( file_exists( $this->get_database_dump_filepath() ) )
|
1443 |
-
return $this->mysqldump_verified = true;
|
1444 |
-
|
1445 |
-
return false;
|
1446 |
-
|
1447 |
-
|
1448 |
-
}
|
1449 |
-
|
1450 |
-
/**
|
1451 |
-
* Verify that the archive is valid and contains all the files it should contain.
|
1452 |
-
*
|
1453 |
-
* @access public
|
1454 |
-
* @return bool
|
1455 |
-
*/
|
1456 |
-
public function verify_archive() {
|
1457 |
-
|
1458 |
-
$this->do_action( 'hmbkp_archive_verify_started' );
|
1459 |
-
|
1460 |
-
// If we've already passed then no need to check again
|
1461 |
-
if ( ! empty( $this->archive_verified ) )
|
1462 |
-
return true;
|
1463 |
-
|
1464 |
-
// If there are errors delete the backup file.
|
1465 |
-
if ( $this->get_errors( $this->get_archive_method() ) && file_exists( $this->get_archive_filepath() ) )
|
1466 |
-
unlink( $this->get_archive_filepath() );
|
1467 |
-
|
1468 |
-
// If the archive file still exists assume it's good
|
1469 |
-
if ( file_exists( $this->get_archive_filepath() ) )
|
1470 |
-
return $this->archive_verified = true;
|
1471 |
-
|
1472 |
-
return false;
|
1473 |
-
|
1474 |
-
}
|
1475 |
-
|
1476 |
-
/**
|
1477 |
-
* Return an array of all files in the filesystem
|
1478 |
-
*
|
1479 |
-
* @access public
|
1480 |
-
* @return array
|
1481 |
-
*/
|
1482 |
-
public function get_files() {
|
1483 |
-
|
1484 |
-
if ( ! empty( $this->files ) )
|
1485 |
-
return $this->files;
|
1486 |
-
|
1487 |
-
$this->files = array();
|
1488 |
-
|
1489 |
-
// We only want to use the RecursiveDirectoryIterator if the FOLLOW_SYMLINKS flag is available
|
1490 |
-
if ( defined( 'RecursiveDirectoryIterator::FOLLOW_SYMLINKS' ) ) {
|
1491 |
-
|
1492 |
-
$this->files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->get_root(), RecursiveDirectoryIterator::FOLLOW_SYMLINKS ), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
1493 |
-
|
1494 |
-
// Skip dot files if the SKIP_Dots flag is available
|
1495 |
-
if ( defined( 'RecursiveDirectoryIterator::SKIP_DOTS' ) )
|
1496 |
-
$this->files->setFlags( RecursiveDirectoryIterator::SKIP_DOTS + RecursiveDirectoryIterator::FOLLOW_SYMLINKS );
|
1497 |
-
|
1498 |
-
|
1499 |
-
// If RecursiveDirectoryIterator::FOLLOW_SYMLINKS isn't available then fallback to a less memory efficient method
|
1500 |
-
} else {
|
1501 |
-
|
1502 |
-
$this->files = $this->get_files_fallback( $this->get_root() );
|
1503 |
-
|
1504 |
-
}
|
1505 |
-
|
1506 |
-
return $this->files;
|
1507 |
-
|
1508 |
-
}
|
1509 |
-
|
1510 |
-
/**
|
1511 |
-
* Fallback function for generating a filesystem
|
1512 |
-
* array
|
1513 |
-
*
|
1514 |
-
* Used if RecursiveDirectoryIterator::FOLLOW_SYMLINKS isn't available
|
1515 |
-
*
|
1516 |
-
* @access private
|
1517 |
-
* @param string $dir
|
1518 |
-
* @param array $files. (default: array())
|
1519 |
-
* @return array
|
1520 |
-
*/
|
1521 |
-
private function get_files_fallback( $dir, $files = array() ) {
|
1522 |
-
|
1523 |
-
$handle = opendir( $dir );
|
1524 |
-
|
1525 |
-
$excludes = $this->exclude_string( 'regex' );
|
1526 |
-
|
1527 |
-
while ( $file = readdir( $handle ) ) :
|
1528 |
-
|
1529 |
-
// Ignore current dir and containing dir
|
1530 |
-
if ( $file === '.' || $file === '..' )
|
1531 |
-
continue;
|
1532 |
-
|
1533 |
-
$filepath = self::conform_dir( trailingslashit( $dir ) . $file );
|
1534 |
-
$file = str_ireplace( trailingslashit( $this->get_root() ), '', $filepath );
|
1535 |
-
|
1536 |
-
$files[] = new SplFileInfo( $filepath );
|
1537 |
-
|
1538 |
-
if ( is_dir( $filepath ) )
|
1539 |
-
$files = $this->get_files_fallback( $filepath, $files );
|
1540 |
-
|
1541 |
-
endwhile;
|
1542 |
-
|
1543 |
-
return $files;
|
1544 |
-
|
1545 |
-
}
|
1546 |
-
|
1547 |
-
/**
|
1548 |
-
* Returns an array of files that will be included in the backup.
|
1549 |
-
*
|
1550 |
-
* @access public
|
1551 |
-
* @return array
|
1552 |
-
*/
|
1553 |
-
public function get_included_files() {
|
1554 |
-
|
1555 |
-
if ( ! empty( $this->included_files ) )
|
1556 |
-
return $this->included_files;
|
1557 |
-
|
1558 |
-
$this->included_files = array();
|
1559 |
-
|
1560 |
-
$excludes = $this->exclude_string( 'regex' );
|
1561 |
-
|
1562 |
-
foreach ( $this->get_files() as $file ) {
|
1563 |
-
|
1564 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1565 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1566 |
-
continue;
|
1567 |
-
|
1568 |
-
// Skip unreadable files
|
1569 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1570 |
-
continue;
|
1571 |
-
|
1572 |
-
// Excludes
|
1573 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
1574 |
-
continue;
|
1575 |
-
|
1576 |
-
$this->included_files[] = $file;
|
1577 |
-
|
1578 |
-
}
|
1579 |
-
|
1580 |
-
return $this->included_files;
|
1581 |
-
|
1582 |
-
}
|
1583 |
-
|
1584 |
-
/**
|
1585 |
-
* Return the number of files included in the backup
|
1586 |
-
*
|
1587 |
-
* @access public
|
1588 |
-
* @return array
|
1589 |
-
*/
|
1590 |
-
public function get_included_file_count() {
|
1591 |
-
|
1592 |
-
if ( ! empty( $this->included_file_count ) )
|
1593 |
-
return $this->included_file_count;
|
1594 |
-
|
1595 |
-
$this->included_file_count = 0;
|
1596 |
-
|
1597 |
-
$excludes = $this->exclude_string( 'regex' );
|
1598 |
-
|
1599 |
-
foreach ( $this->get_files() as $file ) {
|
1600 |
-
|
1601 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1602 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1603 |
-
continue;
|
1604 |
-
|
1605 |
-
// Skip unreadable files
|
1606 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1607 |
-
continue;
|
1608 |
-
|
1609 |
-
// Excludes
|
1610 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
1611 |
-
continue;
|
1612 |
-
|
1613 |
-
$this->included_file_count++;
|
1614 |
-
|
1615 |
-
}
|
1616 |
-
|
1617 |
-
return $this->included_file_count;
|
1618 |
-
|
1619 |
-
}
|
1620 |
-
|
1621 |
-
/**
|
1622 |
-
* Returns an array of files that match the exclude rules.
|
1623 |
-
*
|
1624 |
-
* @access public
|
1625 |
-
* @return array
|
1626 |
-
*/
|
1627 |
-
public function get_excluded_files() {
|
1628 |
-
|
1629 |
-
if ( ! empty( $this->excluded_files ) )
|
1630 |
-
return $this->excluded_files;
|
1631 |
-
|
1632 |
-
$this->excluded_files = array();
|
1633 |
-
|
1634 |
-
$excludes = $this->exclude_string( 'regex' );
|
1635 |
-
|
1636 |
-
foreach ( $this->get_files() as $file ) {
|
1637 |
-
|
1638 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1639 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1640 |
-
continue;
|
1641 |
-
|
1642 |
-
// Skip unreadable files
|
1643 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1644 |
-
continue;
|
1645 |
-
|
1646 |
-
// Excludes
|
1647 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
1648 |
-
$this->excluded_files[] = $file;
|
1649 |
-
|
1650 |
-
}
|
1651 |
-
|
1652 |
-
return $this->excluded_files;
|
1653 |
-
|
1654 |
-
}
|
1655 |
-
|
1656 |
-
/**
|
1657 |
-
* Return the number of files excluded from the backup
|
1658 |
-
*
|
1659 |
-
* @access public
|
1660 |
-
* @return array
|
1661 |
-
*/
|
1662 |
-
public function get_excluded_file_count() {
|
1663 |
-
|
1664 |
-
if ( ! empty( $this->excluded_file_count ) )
|
1665 |
-
return $this->excluded_file_count;
|
1666 |
-
|
1667 |
-
$this->excluded_file_count = 0;
|
1668 |
-
|
1669 |
-
$excludes = $this->exclude_string( 'regex' );
|
1670 |
-
|
1671 |
-
foreach ( $this->get_files() as $file ) {
|
1672 |
-
|
1673 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1674 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1675 |
-
continue;
|
1676 |
-
|
1677 |
-
// Skip unreadable files
|
1678 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1679 |
-
continue;
|
1680 |
-
|
1681 |
-
// Excludes
|
1682 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) )
|
1683 |
-
$this->excluded_file_count++;
|
1684 |
-
|
1685 |
-
}
|
1686 |
-
|
1687 |
-
return $this->excluded_file_count;
|
1688 |
-
|
1689 |
-
}
|
1690 |
-
|
1691 |
-
/**
|
1692 |
-
* Returns an array of unreadable files.
|
1693 |
-
*
|
1694 |
-
* @access public
|
1695 |
-
* @return array
|
1696 |
-
*/
|
1697 |
-
public function get_unreadable_files() {
|
1698 |
-
|
1699 |
-
if ( ! empty( $this->unreadable_files ) )
|
1700 |
-
return $this->unreadable_files;
|
1701 |
-
|
1702 |
-
$this->unreadable_files = array();
|
1703 |
-
|
1704 |
-
foreach ( $this->get_files() as $file ) {
|
1705 |
-
|
1706 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1707 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1708 |
-
continue;
|
1709 |
-
|
1710 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1711 |
-
$this->unreadable_files[] = $file;
|
1712 |
-
|
1713 |
-
}
|
1714 |
-
|
1715 |
-
return $this->unreadable_files;
|
1716 |
-
|
1717 |
-
}
|
1718 |
-
|
1719 |
-
/**
|
1720 |
-
* Return the number of unreadable files.
|
1721 |
-
*
|
1722 |
-
* @access public
|
1723 |
-
* @return array
|
1724 |
-
*/
|
1725 |
-
public function get_unreadable_file_count() {
|
1726 |
-
|
1727 |
-
if ( ! empty( $this->get_unreadable_file_count ) )
|
1728 |
-
return $this->get_unreadable_file_count;
|
1729 |
-
|
1730 |
-
$this->get_unreadable_file_count = 0;
|
1731 |
-
|
1732 |
-
foreach ( $this->get_files() as $file ) {
|
1733 |
-
|
1734 |
-
// Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
|
1735 |
-
if ( method_exists( $file, 'isDot' ) && $file->isDot() )
|
1736 |
-
continue;
|
1737 |
-
|
1738 |
-
if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() )
|
1739 |
-
$this->get_unreadable_file_count++;
|
1740 |
-
|
1741 |
-
}
|
1742 |
-
|
1743 |
-
return $this->get_unreadable_file_count;
|
1744 |
-
|
1745 |
-
}
|
1746 |
-
|
1747 |
-
private function load_pclzip() {
|
1748 |
-
|
1749 |
-
// Load PclZip
|
1750 |
-
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
|
1751 |
-
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( $this->get_path() ) );
|
1752 |
-
|
1753 |
-
require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
1754 |
-
|
1755 |
-
}
|
1756 |
-
|
1757 |
-
/**
|
1758 |
-
* Get an array of exclude rules
|
1759 |
-
*
|
1760 |
-
* The backup path is automatically excluded
|
1761 |
-
*
|
1762 |
-
* @access public
|
1763 |
-
* @return array
|
1764 |
-
*/
|
1765 |
-
public function get_excludes() {
|
1766 |
-
|
1767 |
-
$excludes = array();
|
1768 |
-
|
1769 |
-
if ( isset( $this->excludes ) )
|
1770 |
-
$excludes = $this->excludes;
|
1771 |
-
|
1772 |
-
// If path() is inside root(), exclude it
|
1773 |
-
if ( strpos( $this->get_path(), $this->get_root() ) !== false )
|
1774 |
-
array_unshift( $excludes, trailingslashit( $this->get_path() ) );
|
1775 |
-
|
1776 |
-
return array_unique( $excludes );
|
1777 |
-
|
1778 |
-
}
|
1779 |
-
|
1780 |
-
/**
|
1781 |
-
* Set the excludes, expects and array
|
1782 |
-
*
|
1783 |
-
* @access public
|
1784 |
-
* @param Array $excludes
|
1785 |
-
* @param Bool $append
|
1786 |
-
*/
|
1787 |
-
public function set_excludes( $excludes, $append = false ) {
|
1788 |
-
|
1789 |
-
if ( is_string( $excludes ) )
|
1790 |
-
$excludes = explode( ',', $excludes );
|
1791 |
-
|
1792 |
-
if ( $append )
|
1793 |
-
$excludes = array_merge( $this->excludes, $excludes );
|
1794 |
-
|
1795 |
-
$this->excludes = array_filter( array_unique( array_map( 'trim', $excludes ) ) );
|
1796 |
-
|
1797 |
-
}
|
1798 |
-
|
1799 |
-
/**
|
1800 |
-
* Generate the exclude param string for the zip backup
|
1801 |
-
*
|
1802 |
-
* Takes the exclude rules and formats them for use with either
|
1803 |
-
* the shell zip command or pclzip
|
1804 |
-
*
|
1805 |
-
* @access public
|
1806 |
-
* @param string $context. (default: 'zip')
|
1807 |
-
* @return string
|
1808 |
-
*/
|
1809 |
-
public function exclude_string( $context = 'zip' ) {
|
1810 |
-
|
1811 |
-
// Return a comma separated list by default
|
1812 |
-
$separator = ', ';
|
1813 |
-
$wildcard = '';
|
1814 |
-
|
1815 |
-
// The zip command
|
1816 |
-
if ( $context === 'zip' ) {
|
1817 |
-
$wildcard = '*';
|
1818 |
-
$separator = ' -x ';
|
1819 |
-
|
1820 |
-
// The PclZip fallback library
|
1821 |
-
} elseif ( $context === 'regex' ) {
|
1822 |
-
$wildcard = '([\s\S]*?)';
|
1823 |
-
$separator = '|';
|
1824 |
-
|
1825 |
-
}
|
1826 |
-
|
1827 |
-
$excludes = $this->get_excludes();
|
1828 |
-
|
1829 |
-
foreach( $excludes as $key => &$rule ) {
|
1830 |
-
|
1831 |
-
$file = $absolute = $fragment = false;
|
1832 |
-
|
1833 |
-
// Files don't end with /
|
1834 |
-
if ( ! in_array( substr( $rule, -1 ), array( '\\', '/' ) ) )
|
1835 |
-
$file = true;
|
1836 |
-
|
1837 |
-
// If rule starts with a / then treat as absolute path
|
1838 |
-
elseif ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
|
1839 |
-
$absolute = true;
|
1840 |
-
|
1841 |
-
// Otherwise treat as dir fragment
|
1842 |
-
else
|
1843 |
-
$fragment = true;
|
1844 |
-
|
1845 |
-
// Strip $this->root and conform
|
1846 |
-
$rule = str_ireplace( $this->get_root(), '', untrailingslashit( self::conform_dir( $rule ) ) );
|
1847 |
-
|
1848 |
-
// Strip the preceeding slash
|
1849 |
-
if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
|
1850 |
-
$rule = substr( $rule, 1 );
|
1851 |
-
|
1852 |
-
// Escape string for regex
|
1853 |
-
if ( $context === 'regex' )
|
1854 |
-
$rule = str_replace( '.', '\.', $rule );
|
1855 |
-
|
1856 |
-
// Convert any existing wildcards
|
1857 |
-
if ( $wildcard !== '*' && strpos( $rule, '*' ) !== false )
|
1858 |
-
$rule = str_replace( '*', $wildcard, $rule );
|
1859 |
-
|
1860 |
-
// Wrap directory fragments and files in wildcards for zip
|
1861 |
-
if ( $context === 'zip' && ( $fragment || $file ) )
|
1862 |
-
$rule = $wildcard . $rule . $wildcard;
|
1863 |
-
|
1864 |
-
// Add a wildcard to the end of absolute url for zips
|
1865 |
-
if ( $context === 'zip' && $absolute )
|
1866 |
-
$rule .= $wildcard;
|
1867 |
-
|
1868 |
-
// Add and end carrot to files for pclzip but only if it doesn't end in a wildcard
|
1869 |
-
if ( $file && $context === 'regex' )
|
1870 |
-
$rule .= '$';
|
1871 |
-
|
1872 |
-
// Add a start carrot to absolute urls for pclzip
|
1873 |
-
if ( $absolute && $context === 'regex' )
|
1874 |
-
$rule = '^' . $rule;
|
1875 |
-
|
1876 |
-
}
|
1877 |
-
|
1878 |
-
// Escape shell args for zip command
|
1879 |
-
if ( $context === 'zip' )
|
1880 |
-
$excludes = array_map( 'escapeshellarg', array_unique( $excludes ) );
|
1881 |
-
|
1882 |
-
return implode( $separator, $excludes );
|
1883 |
-
|
1884 |
-
}
|
1885 |
-
|
1886 |
-
/**
|
1887 |
-
* Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
|
1888 |
-
*
|
1889 |
-
* @param $a_name
|
1890 |
-
* @return array|string
|
1891 |
-
*/
|
1892 |
-
private function sql_backquote( $a_name ) {
|
1893 |
-
|
1894 |
-
if ( ! empty( $a_name ) && $a_name !== '*' ) {
|
1895 |
-
|
1896 |
-
if ( is_array( $a_name ) ) {
|
1897 |
-
|
1898 |
-
$result = array();
|
1899 |
-
|
1900 |
-
reset( $a_name );
|
1901 |
-
|
1902 |
-
while ( list( $key, $val ) = each( $a_name ) )
|
1903 |
-
$result[$key] = '`' . $val . '`';
|
1904 |
-
|
1905 |
-
return $result;
|
1906 |
-
|
1907 |
-
} else {
|
1908 |
-
|
1909 |
-
return '`' . $a_name . '`';
|
1910 |
-
|
1911 |
-
}
|
1912 |
-
|
1913 |
-
} else {
|
1914 |
-
|
1915 |
-
return $a_name;
|
1916 |
-
|
1917 |
-
}
|
1918 |
-
|
1919 |
-
}
|
1920 |
-
|
1921 |
-
/**
|
1922 |
-
* Reads the Database table in $table and creates
|
1923 |
-
* SQL Statements for recreating structure and data
|
1924 |
-
* Taken partially from phpMyAdmin and partially from
|
1925 |
-
* Alain Wolf, Zurich - Switzerland
|
1926 |
-
* Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
|
1927 |
-
*
|
1928 |
-
* @access private
|
1929 |
-
* @param string $sql_file
|
1930 |
-
* @param string $table
|
1931 |
-
*/
|
1932 |
-
private function make_sql( $sql_file, $table ) {
|
1933 |
-
|
1934 |
-
// Add SQL statement to drop existing table
|
1935 |
-
$sql_file .= "\n";
|
1936 |
-
$sql_file .= "\n";
|
1937 |
-
$sql_file .= "#\n";
|
1938 |
-
$sql_file .= "# Delete any existing table " . $this->sql_backquote( $table ) . "\n";
|
1939 |
-
$sql_file .= "#\n";
|
1940 |
-
$sql_file .= "\n";
|
1941 |
-
$sql_file .= "DROP TABLE IF EXISTS " . $this->sql_backquote( $table ) . ";\n";
|
1942 |
-
|
1943 |
-
/* Table Structure */
|
1944 |
-
|
1945 |
-
// Comment in SQL-file
|
1946 |
-
$sql_file .= "\n";
|
1947 |
-
$sql_file .= "\n";
|
1948 |
-
$sql_file .= "#\n";
|
1949 |
-
$sql_file .= "# Table structure of table " . $this->sql_backquote( $table ) . "\n";
|
1950 |
-
$sql_file .= "#\n";
|
1951 |
-
$sql_file .= "\n";
|
1952 |
-
|
1953 |
-
// Get table structure
|
1954 |
-
$query = 'SHOW CREATE TABLE ' . $this->sql_backquote( $table );
|
1955 |
-
$result = mysqli_query( $this->db, $query );
|
1956 |
-
|
1957 |
-
if ( $result ) {
|
1958 |
-
|
1959 |
-
if ( mysqli_num_rows( $result ) > 0 ) {
|
1960 |
-
$sql_create_arr = mysqli_fetch_array( $result );
|
1961 |
-
$sql_file .= $sql_create_arr[1];
|
1962 |
-
}
|
1963 |
-
|
1964 |
-
mysqli_free_result( $result );
|
1965 |
-
$sql_file .= ' ;';
|
1966 |
-
|
1967 |
-
}
|
1968 |
-
|
1969 |
-
/* Table Contents */
|
1970 |
-
|
1971 |
-
// Get table contents
|
1972 |
-
$query = 'SELECT * FROM ' . $this->sql_backquote( $table );
|
1973 |
-
$result = mysqli_query( $this->db, $query );
|
1974 |
-
|
1975 |
-
if ( $result ) {
|
1976 |
-
$fields_cnt = mysqli_num_fields( $result );
|
1977 |
-
$rows_cnt = mysqli_num_rows( $result );
|
1978 |
-
}
|
1979 |
-
|
1980 |
-
// Comment in SQL-file
|
1981 |
-
$sql_file .= "\n";
|
1982 |
-
$sql_file .= "\n";
|
1983 |
-
$sql_file .= "#\n";
|
1984 |
-
$sql_file .= "# Data contents of table " . $table . " (" . $rows_cnt . " records)\n";
|
1985 |
-
$sql_file .= "#\n";
|
1986 |
-
|
1987 |
-
// Checks whether the field is an integer or not
|
1988 |
-
for ( $j = 0; $j < $fields_cnt; $j++ ) {
|
1989 |
-
|
1990 |
-
$field_obj = mysqli_fetch_field_direct( $result, $j );
|
1991 |
-
|
1992 |
-
$field_set[$j] = $this->sql_backquote( $field_obj->name );
|
1993 |
-
$type = $field_obj->type;
|
1994 |
-
|
1995 |
-
if ( $type === 'tinyint' || $type === 'smallint' || $type === 'mediumint' || $type === 'int' || $type === 'bigint' )
|
1996 |
-
$field_num[$j] = true;
|
1997 |
-
|
1998 |
-
else
|
1999 |
-
$field_num[$j] = false;
|
2000 |
-
|
2001 |
-
}
|
2002 |
-
|
2003 |
-
// Sets the scheme
|
2004 |
-
$entries = 'INSERT INTO ' . $this->sql_backquote( $table ) . ' VALUES (';
|
2005 |
-
$search = array( '\x00', '\x0a', '\x0d', '\x1a' ); //\x08\\x09, not required
|
2006 |
-
$replace = array( '\0', '\n', '\r', '\Z' );
|
2007 |
-
$current_row = 0;
|
2008 |
-
$batch_write = 0;
|
2009 |
-
|
2010 |
-
while ( $row = mysqli_fetch_row( $result ) ) {
|
2011 |
-
|
2012 |
-
$current_row++;
|
2013 |
-
|
2014 |
-
// build the statement
|
2015 |
-
for ( $j = 0; $j < $fields_cnt; $j++ ) {
|
2016 |
-
|
2017 |
-
if ( ! isset($row[$j] ) ) {
|
2018 |
-
$values[] = 'NULL';
|
2019 |
-
|
2020 |
-
} elseif ( $row[$j] === '0' || $row[$j] !== '' ) {
|
2021 |
-
|
2022 |
-
// a number
|
2023 |
-
if ( $field_num[$j] )
|
2024 |
-
$values[] = $row[$j];
|
2025 |
-
|
2026 |
-
else
|
2027 |
-
$values[] = "'" . str_replace( $search, $replace, $this->sql_addslashes( $row[$j] ) ) . "'";
|
2028 |
-
|
2029 |
-
} else {
|
2030 |
-
$values[] = "''";
|
2031 |
-
|
2032 |
-
}
|
2033 |
-
|
2034 |
-
}
|
2035 |
-
|
2036 |
-
$sql_file .= " \n" . $entries . implode( ', ', $values ) . ") ;";
|
2037 |
-
|
2038 |
-
// write the rows in batches of 100
|
2039 |
-
if ( $batch_write === 100 ) {
|
2040 |
-
$batch_write = 0;
|
2041 |
-
$this->write_sql( $sql_file );
|
2042 |
-
$sql_file = '';
|
2043 |
-
}
|
2044 |
-
|
2045 |
-
$batch_write++;
|
2046 |
-
|
2047 |
-
unset( $values );
|
2048 |
-
|
2049 |
-
}
|
2050 |
-
|
2051 |
-
mysqli_free_result( $result );
|
2052 |
-
|
2053 |
-
// Create footer/closing comment in SQL-file
|
2054 |
-
$sql_file .= "\n";
|
2055 |
-
$sql_file .= "#\n";
|
2056 |
-
$sql_file .= "# End of data contents of table " . $table . "\n";
|
2057 |
-
$sql_file .= "# --------------------------------------------------------\n";
|
2058 |
-
$sql_file .= "\n";
|
2059 |
-
|
2060 |
-
$this->write_sql( $sql_file );
|
2061 |
-
|
2062 |
-
}
|
2063 |
-
|
2064 |
-
/**
|
2065 |
-
* Better addslashes for SQL queries.
|
2066 |
-
* Taken from phpMyAdmin.
|
2067 |
-
*
|
2068 |
-
* @param string $a_string
|
2069 |
-
* @param bool $is_like
|
2070 |
-
* @return mixed
|
2071 |
-
*/
|
2072 |
-
private function sql_addslashes( $a_string = '', $is_like = false ) {
|
2073 |
-
|
2074 |
-
if ( $is_like )
|
2075 |
-
$a_string = str_replace( '\\', '\\\\\\\\', $a_string );
|
2076 |
-
|
2077 |
-
else
|
2078 |
-
$a_string = str_replace( '\\', '\\\\', $a_string );
|
2079 |
-
|
2080 |
-
$a_string = str_replace( '\'', '\\\'', $a_string );
|
2081 |
-
|
2082 |
-
return $a_string;
|
2083 |
-
}
|
2084 |
-
|
2085 |
-
/**
|
2086 |
-
* Write the SQL file
|
2087 |
-
* @param string $sql
|
2088 |
-
* @return bool
|
2089 |
-
*/
|
2090 |
-
private function write_sql( $sql ) {
|
2091 |
-
|
2092 |
-
$sqlname = $this->get_database_dump_filepath();
|
2093 |
-
|
2094 |
-
// Actually write the sql file
|
2095 |
-
if ( is_writable( $sqlname ) || ! file_exists( $sqlname ) ) {
|
2096 |
-
|
2097 |
-
if ( ! $handle = @fopen( $sqlname, 'a' ) )
|
2098 |
-
return;
|
2099 |
-
|
2100 |
-
if ( ! @fwrite( $handle, $sql ) )
|
2101 |
-
return;
|
2102 |
-
|
2103 |
-
@fclose( $handle );
|
2104 |
-
|
2105 |
-
return true;
|
2106 |
-
|
2107 |
-
}
|
2108 |
-
|
2109 |
-
}
|
2110 |
-
|
2111 |
-
/**
|
2112 |
-
* Get the errors
|
2113 |
-
*
|
2114 |
-
* @access public
|
2115 |
-
*/
|
2116 |
-
public function get_errors( $context = null ) {
|
2117 |
-
|
2118 |
-
if ( ! empty( $context ) )
|
2119 |
-
return isset( $this->errors[$context] ) ? $this->errors[$context] : array();
|
2120 |
-
|
2121 |
-
return $this->errors;
|
2122 |
-
|
2123 |
-
}
|
2124 |
-
|
2125 |
-
/**
|
2126 |
-
* Add an error to the errors stack
|
2127 |
-
*
|
2128 |
-
* @access private
|
2129 |
-
* @param string $context
|
2130 |
-
* @param mixed $error
|
2131 |
-
*/
|
2132 |
-
public function error( $context, $error ) {
|
2133 |
-
|
2134 |
-
if ( empty( $context ) || empty( $error ) )
|
2135 |
-
return;
|
2136 |
-
|
2137 |
-
$this->errors[$context][$_key = md5( implode( ':' , (array) $error ) )] = $error;
|
2138 |
-
|
2139 |
-
$this->do_action( 'hmbkp_error' );
|
2140 |
-
|
2141 |
-
}
|
2142 |
-
|
2143 |
-
/**
|
2144 |
-
* Migrate errors to warnings
|
2145 |
-
*
|
2146 |
-
* @access private
|
2147 |
-
* @param string $context. (default: null)
|
2148 |
-
*/
|
2149 |
-
private function errors_to_warnings( $context = null ) {
|
2150 |
-
|
2151 |
-
$errors = empty( $context ) ? $this->get_errors() : array( $context => $this->get_errors( $context ) );
|
2152 |
-
|
2153 |
-
if ( empty( $errors ) )
|
2154 |
-
return;
|
2155 |
-
|
2156 |
-
foreach ( $errors as $error_context => $context_errors )
|
2157 |
-
foreach( $context_errors as $error )
|
2158 |
-
$this->warning( $error_context, $error );
|
2159 |
-
|
2160 |
-
if ( $context )
|
2161 |
-
unset( $this->errors[$context] );
|
2162 |
-
|
2163 |
-
else
|
2164 |
-
$this->errors = array();
|
2165 |
-
|
2166 |
-
}
|
2167 |
-
|
2168 |
-
/**
|
2169 |
-
* Get the warnings
|
2170 |
-
*
|
2171 |
-
* @access public
|
2172 |
-
*/
|
2173 |
-
public function get_warnings( $context = null ) {
|
2174 |
-
|
2175 |
-
if ( ! empty( $context ) )
|
2176 |
-
return isset( $this->warnings[$context] ) ? $this->warnings[$context] : array();
|
2177 |
-
|
2178 |
-
return $this->warnings;
|
2179 |
-
|
2180 |
-
}
|
2181 |
-
|
2182 |
-
/**
|
2183 |
-
* Add an warning to the warnings stack
|
2184 |
-
*
|
2185 |
-
* @access private
|
2186 |
-
* @param string $context
|
2187 |
-
* @param mixed $warning
|
2188 |
-
*/
|
2189 |
-
private function warning( $context, $warning ) {
|
2190 |
-
|
2191 |
-
if ( empty( $context ) || empty( $warning ) )
|
2192 |
-
return;
|
2193 |
-
|
2194 |
-
$this->do_action( 'hmbkp_warning' );
|
2195 |
-
|
2196 |
-
$this->warnings[$context][$_key = md5( implode( ':' , (array) $warning ) )] = $warning;
|
2197 |
-
|
2198 |
-
}
|
2199 |
-
|
2200 |
-
/**
|
2201 |
-
* Custom error handler for catching php errors
|
2202 |
-
*
|
2203 |
-
* @param string $type
|
2204 |
-
* @return bool
|
2205 |
-
*/
|
2206 |
-
public function error_handler( $type ) {
|
2207 |
-
|
2208 |
-
// Skip strict & deprecated warnings
|
2209 |
-
if ( ( defined( 'E_DEPRECATED' ) && $type === E_DEPRECATED ) || ( defined( 'E_STRICT' ) && $type === E_STRICT ) || error_reporting() === 0 )
|
2210 |
-
return false;
|
2211 |
-
|
2212 |
-
$args = func_get_args();
|
2213 |
-
|
2214 |
-
array_shift( $args );
|
2215 |
-
|
2216 |
-
$this->warning( 'php', implode( ', ', array_splice( $args, 0, 3 ) ) );
|
2217 |
-
|
2218 |
-
return false;
|
2219 |
-
|
2220 |
-
}
|
2221 |
-
|
2222 |
-
/**
|
2223 |
-
* Recursively delete a directory including
|
2224 |
-
* all the files and sub-directories.
|
2225 |
-
*
|
2226 |
-
* @param string $dir
|
2227 |
-
* @return bool
|
2228 |
-
*/
|
2229 |
-
public static function rmdir_recursive( $dir ) {
|
2230 |
-
|
2231 |
-
if ( is_file( $dir ) )
|
2232 |
-
@unlink( $dir );
|
2233 |
-
|
2234 |
-
if ( ! is_dir( $dir ) )
|
2235 |
-
return false;
|
2236 |
-
|
2237 |
-
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
2238 |
-
|
2239 |
-
foreach ( $files as $file ) {
|
2240 |
-
|
2241 |
-
if ( $file->isDir() )
|
2242 |
-
@rmdir( $file->getPathname() );
|
2243 |
-
|
2244 |
-
else
|
2245 |
-
@unlink( $file->getPathname() );
|
2246 |
-
|
2247 |
-
}
|
2248 |
-
|
2249 |
-
@rmdir( $dir );
|
2250 |
-
|
2251 |
-
}
|
2252 |
-
|
2253 |
-
}
|
2254 |
-
|
2255 |
-
/**
|
2256 |
-
* Add file callback for PclZip, excludes files
|
2257 |
-
* and sets the database dump to be stored in the root
|
2258 |
-
* of the zip
|
2259 |
-
*
|
2260 |
-
* @access private
|
2261 |
-
* @param string $event
|
2262 |
-
* @param array &$file
|
2263 |
-
* @return bool
|
2264 |
-
*/
|
2265 |
-
function wprp_hmbkp_pclzip_callback( $event, &$file ) {
|
2266 |
-
|
2267 |
-
global $_wprp_hmbkp_exclude_string;
|
2268 |
-
|
2269 |
-
// Don't try to add unreadable files.
|
2270 |
-
if ( ! is_readable( $file['filename'] ) || ! file_exists( $file['filename'] ) )
|
2271 |
-
return false;
|
2272 |
-
|
2273 |
-
// Match everything else past the exclude list
|
2274 |
-
elseif ( $_wprp_hmbkp_exclude_string && preg_match( '(' . $_wprp_hmbkp_exclude_string . ')', $file['stored_filename'] ) )
|
2275 |
-
return false;
|
2276 |
-
|
2277 |
-
return true;
|
2278 |
-
|
2279 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.integration.php
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Integration compatibility with hosts, plugins, and themes
|
4 |
-
*/
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Get the likely web host for this site.
|
8 |
-
*/
|
9 |
-
function _wprp_integration_get_web_host() {
|
10 |
-
|
11 |
-
// WP Engine
|
12 |
-
if ( defined( 'WPE_APIKEY' ) && WPE_APIKEY )
|
13 |
-
return 'wpengine';
|
14 |
-
|
15 |
-
return 'unknown';
|
16 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.log.php
DELETED
@@ -1,140 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WPRP_Log {
|
4 |
-
|
5 |
-
static $instance;
|
6 |
-
|
7 |
-
private $is_logging_enabled = true;
|
8 |
-
|
9 |
-
static function get_instance() {
|
10 |
-
|
11 |
-
if ( empty( self::$instance ) )
|
12 |
-
self::$instance = new WPRP_Log();
|
13 |
-
|
14 |
-
return self::$instance;
|
15 |
-
}
|
16 |
-
|
17 |
-
public function __construct() {
|
18 |
-
|
19 |
-
$this->setup_actions();
|
20 |
-
}
|
21 |
-
|
22 |
-
public function disable_logging() {
|
23 |
-
$this->is_logging_enabled = false;
|
24 |
-
}
|
25 |
-
|
26 |
-
public function setup_actions() {
|
27 |
-
|
28 |
-
if ( ! $this->is_logging_enabled )
|
29 |
-
return;
|
30 |
-
|
31 |
-
add_action( 'wp_login', array( $this, 'action_wp_login' ), 10, 2 );
|
32 |
-
add_action( 'user_register', array( $this, 'action_user_register' ) );
|
33 |
-
add_action( 'profile_update', array( $this, 'action_profile_updated' ), 10, 2 );
|
34 |
-
|
35 |
-
|
36 |
-
add_action( 'update_option_current_theme', array( $this, 'updated_option_current_theme' ), 10, 2 );
|
37 |
-
}
|
38 |
-
|
39 |
-
public function action_wp_login( $user_login, $user ) {
|
40 |
-
|
41 |
-
// we are only interested in administators
|
42 |
-
if ( ! array_intersect( $user->roles, array( 'administrator' ) ) )
|
43 |
-
return;
|
44 |
-
|
45 |
-
$this->add_item( array(
|
46 |
-
'type' => 'user',
|
47 |
-
'action' => 'login',
|
48 |
-
'remote_user' => array( 'user_login' => $user_login, 'display_name' => $user->display_name ),
|
49 |
-
));
|
50 |
-
}
|
51 |
-
|
52 |
-
public function action_user_register( $user_id ) {
|
53 |
-
|
54 |
-
$new_user = get_user_by( 'id', $user_id );
|
55 |
-
|
56 |
-
// we are only interested in administators
|
57 |
-
if ( ! array_intersect( $new_user->roles, array( 'administrator' ) ) )
|
58 |
-
return;
|
59 |
-
|
60 |
-
$this->add_item( array(
|
61 |
-
'type' => 'user',
|
62 |
-
'action' => 'create',
|
63 |
-
'user_login' => $new_user->user_login,
|
64 |
-
'display_name' => $new_user->display_name,
|
65 |
-
'role' => $new_user->roles[0],
|
66 |
-
/** remote_user is added in the `add_item()` method **/
|
67 |
-
));
|
68 |
-
}
|
69 |
-
|
70 |
-
public function action_profile_updated( $user_id, $old_user_data ) {
|
71 |
-
|
72 |
-
$user_data = get_user_by( 'id', $user_id );
|
73 |
-
|
74 |
-
// we are only interested in administators
|
75 |
-
if ( ! array_intersect( $user_data->roles, array( 'administrator' ) ) )
|
76 |
-
return;
|
77 |
-
|
78 |
-
|
79 |
-
if ( $user_data->user_email !== $old_user_data->user_email ) {
|
80 |
-
$this->add_item( array(
|
81 |
-
'type' => 'user',
|
82 |
-
'action' => 'email-update',
|
83 |
-
'old_email' => $old_user_data->user_email,
|
84 |
-
'new_email' => $user_data->user_email,
|
85 |
-
/** remote_user is added in the `add_item()` method **/
|
86 |
-
));
|
87 |
-
}
|
88 |
-
|
89 |
-
if ( $user_data->user_pass !== $old_user_data->user_pass ) {
|
90 |
-
$this->add_item( array(
|
91 |
-
'type' => 'user',
|
92 |
-
'action' => 'password-update',
|
93 |
-
/** remote_user is added in the `add_item()` method **/
|
94 |
-
));
|
95 |
-
}
|
96 |
-
}
|
97 |
-
|
98 |
-
public function updated_option_current_theme( $old_theme, $new_theme ) {
|
99 |
-
|
100 |
-
$this->add_item( array(
|
101 |
-
'type' => 'theme',
|
102 |
-
'action' => 'switch',
|
103 |
-
'old_theme' => $old_theme,
|
104 |
-
'new_theme' => $new_theme,
|
105 |
-
/** remote_user is added in the `add_item()` method **/
|
106 |
-
));
|
107 |
-
}
|
108 |
-
|
109 |
-
public function add_item( $item ) {
|
110 |
-
|
111 |
-
if ( ! $this->is_logging_enabled )
|
112 |
-
return;
|
113 |
-
|
114 |
-
$item = wp_parse_args( $item, array(
|
115 |
-
'date' => time(),
|
116 |
-
'remote_user' => is_user_logged_in() ? array( 'user_login' => wp_get_current_user()->user_login, 'display_name' => wp_get_current_user()->display_name ) : array(),
|
117 |
-
));
|
118 |
-
|
119 |
-
$items = $this->get_items();
|
120 |
-
$items[] = $item;
|
121 |
-
|
122 |
-
// only store the last 100 items
|
123 |
-
if ( count( $items ) > 100 )
|
124 |
-
$items = array_slice( $items, 0, 100 );
|
125 |
-
|
126 |
-
update_option( 'wprp_log', $items );
|
127 |
-
}
|
128 |
-
|
129 |
-
public function get_items() {
|
130 |
-
|
131 |
-
return get_option( 'wprp_log', array() );
|
132 |
-
}
|
133 |
-
|
134 |
-
public function delete_items() {
|
135 |
-
|
136 |
-
delete_option( 'wprp_log' );
|
137 |
-
}
|
138 |
-
}
|
139 |
-
|
140 |
-
add_action( 'plugins_loaded', array( 'WPRP_Log', 'get_instance' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.plugins.php
DELETED
@@ -1,394 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Return an array of installed plugins
|
5 |
-
*
|
6 |
-
* @return array
|
7 |
-
*/
|
8 |
-
function _wprp_get_plugins() {
|
9 |
-
|
10 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
11 |
-
|
12 |
-
// Get all plugins
|
13 |
-
$plugins = get_plugins();
|
14 |
-
|
15 |
-
// Get the list of active plugins
|
16 |
-
$active = get_option( 'active_plugins', array() );
|
17 |
-
|
18 |
-
// Delete the transient so wp_update_plugins can get fresh data
|
19 |
-
if ( function_exists( 'get_site_transient' ) )
|
20 |
-
delete_site_transient( 'update_plugins' );
|
21 |
-
|
22 |
-
else
|
23 |
-
delete_transient( 'update_plugins' );
|
24 |
-
|
25 |
-
// Force a plugin update check
|
26 |
-
wp_update_plugins();
|
27 |
-
|
28 |
-
// Different versions of wp store the updates in different places
|
29 |
-
// TODO can we depreciate
|
30 |
-
if( function_exists( 'get_site_transient' ) && $transient = get_site_transient( 'update_plugins' ) )
|
31 |
-
$current = $transient;
|
32 |
-
|
33 |
-
elseif( $transient = get_transient( 'update_plugins' ) )
|
34 |
-
$current = $transient;
|
35 |
-
|
36 |
-
else
|
37 |
-
$current = get_option( 'update_plugins' );
|
38 |
-
|
39 |
-
// Premium plugins that have adopted the ManageWP API report new plugins by this filter
|
40 |
-
$manage_wp_updates = apply_filters( 'mwp_premium_update_notification', array() );
|
41 |
-
|
42 |
-
foreach ( (array) $plugins as $plugin_file => $plugin ) {
|
43 |
-
|
44 |
-
if ( is_plugin_active( $plugin_file ) )
|
45 |
-
$plugins[$plugin_file]['active'] = true;
|
46 |
-
else
|
47 |
-
$plugins[$plugin_file]['active'] = false;
|
48 |
-
|
49 |
-
$manage_wp_plugin_update = false;
|
50 |
-
foreach( $manage_wp_updates as $manage_wp_update ) {
|
51 |
-
|
52 |
-
if ( ! empty( $manage_wp_update['Name'] ) && $plugin['Name'] == $manage_wp_update['Name'] )
|
53 |
-
$manage_wp_plugin_update = $manage_wp_update;
|
54 |
-
|
55 |
-
}
|
56 |
-
|
57 |
-
if ( $manage_wp_plugin_update ) {
|
58 |
-
|
59 |
-
$plugins[$plugin_file]['latest_version'] = $manage_wp_plugin_update['new_version'];
|
60 |
-
|
61 |
-
} else if ( isset( $current->response[$plugin_file] ) ) {
|
62 |
-
|
63 |
-
$plugins[$plugin_file]['latest_version'] = $current->response[$plugin_file]->new_version;
|
64 |
-
$plugins[$plugin_file]['latest_package'] = $current->response[$plugin_file]->package;
|
65 |
-
$plugins[$plugin_file]['slug'] = $current->response[$plugin_file]->slug;
|
66 |
-
|
67 |
-
} else {
|
68 |
-
|
69 |
-
$plugins[$plugin_file]['latest_version'] = $plugin['Version'];
|
70 |
-
|
71 |
-
}
|
72 |
-
|
73 |
-
}
|
74 |
-
|
75 |
-
return $plugins;
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Wrap the Update Plugin function with a failsafe fallback
|
80 |
-
*
|
81 |
-
* @param $plugin_file
|
82 |
-
* @param $args
|
83 |
-
* @return array|bool|WP_Error
|
84 |
-
*/
|
85 |
-
function _wprp_update_plugin_wrap( $plugin_file, $args )
|
86 |
-
{
|
87 |
-
@ignore_user_abort( true );
|
88 |
-
|
89 |
-
$response = false;
|
90 |
-
$is_active = is_plugin_active( $plugin_file );
|
91 |
-
$is_active_network = is_plugin_active_for_network( $plugin_file );
|
92 |
-
|
93 |
-
try {
|
94 |
-
$response = _wprp_update_plugin($plugin_file, $args);
|
95 |
-
} catch (\Exception $exception) {}
|
96 |
-
|
97 |
-
// FALLBACK for when the plugin is deleted. Just re-install.
|
98 |
-
if ( ! file_exists(WP_PLUGIN_DIR . '/' . $plugin_file) ){
|
99 |
-
$plugin_slug = rtrim(plugin_dir_path($plugin_file), '/');
|
100 |
-
|
101 |
-
_wprp_install_plugin($plugin_slug);
|
102 |
-
|
103 |
-
if ($is_active) {
|
104 |
-
activate_plugin($plugin_file, '', $is_active_network, true);
|
105 |
-
}
|
106 |
-
|
107 |
-
$response = new WP_Error('rollback','Plugin update failed. Plugin has been re-installed.');
|
108 |
-
}
|
109 |
-
|
110 |
-
if ($response === false) {
|
111 |
-
return new WP_Error('update-failed', 'No message was set.');
|
112 |
-
}
|
113 |
-
|
114 |
-
return $response;
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Update a plugin
|
119 |
-
*
|
120 |
-
* @access private
|
121 |
-
* @param $plugin_file
|
122 |
-
* @param $args
|
123 |
-
* @return array|WP_Error
|
124 |
-
*/
|
125 |
-
function _wprp_update_plugin( $plugin_file, $args ) {
|
126 |
-
global $wprp_zip_update;
|
127 |
-
|
128 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
129 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
130 |
-
|
131 |
-
include_once ( ABSPATH . 'wp-admin/includes/admin.php' );
|
132 |
-
require_once ( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
133 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-plugin-upgrader-skin.php';
|
134 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-automatic-upgrader-skin.php';
|
135 |
-
|
136 |
-
// check for filesystem access
|
137 |
-
if ( ! _wpr_check_filesystem_access() )
|
138 |
-
return new WP_Error( 'filesystem-not-writable', __( 'The filesystem is not writable with the supplied credentials', 'wpremote' ) );
|
139 |
-
|
140 |
-
$is_active = is_plugin_active( $plugin_file );
|
141 |
-
$is_active_network = is_plugin_active_for_network( $plugin_file );
|
142 |
-
|
143 |
-
foreach( get_plugins() as $path => $maybe_plugin ) {
|
144 |
-
|
145 |
-
if ( $path == $plugin_file ) {
|
146 |
-
$plugin = $maybe_plugin;
|
147 |
-
break;
|
148 |
-
}
|
149 |
-
|
150 |
-
}
|
151 |
-
|
152 |
-
// Permit specifying a zip URL to update the plugin with
|
153 |
-
if ( ! empty( $args['zip_url'] ) ) {
|
154 |
-
|
155 |
-
$zip_url = $args['zip_url'];
|
156 |
-
|
157 |
-
} else {
|
158 |
-
|
159 |
-
// Check to see if this is a premium plugin that supports the ManageWP implementation
|
160 |
-
$manage_wp_updates = apply_filters( 'mwp_premium_perform_update', array() );
|
161 |
-
$manage_wp_plugin_update = false;
|
162 |
-
foreach( $manage_wp_updates as $manage_wp_update ) {
|
163 |
-
|
164 |
-
if ( ! empty( $manage_wp_update['Name'] )
|
165 |
-
&& $plugin['Name'] == $manage_wp_update['Name']
|
166 |
-
&& ! empty( $manage_wp_update['url'] ) ) {
|
167 |
-
$zip_url = $manage_wp_update['url'];
|
168 |
-
break;
|
169 |
-
}
|
170 |
-
|
171 |
-
}
|
172 |
-
|
173 |
-
}
|
174 |
-
|
175 |
-
$skin = new WPRP_Plugin_Upgrader_Skin();
|
176 |
-
$upgrader = new Plugin_Upgrader( $skin );
|
177 |
-
|
178 |
-
// Fake out the plugin upgrader with our package url
|
179 |
-
if ( ! empty( $zip_url ) ) {
|
180 |
-
$wprp_zip_update = array(
|
181 |
-
'plugin_file' => $plugin_file,
|
182 |
-
'package' => $zip_url,
|
183 |
-
);
|
184 |
-
add_filter( 'pre_site_transient_update_plugins', '_wprp_forcably_filter_update_plugins' );
|
185 |
-
} else {
|
186 |
-
wp_update_plugins();
|
187 |
-
}
|
188 |
-
|
189 |
-
// Remove the Language Upgrader
|
190 |
-
remove_action('upgrader_process_complete', array('Language_Pack_Upgrader', 'async_upgrade'), 20);
|
191 |
-
|
192 |
-
// Do the upgrade
|
193 |
-
ob_start();
|
194 |
-
$result = $upgrader->upgrade($plugin_file);
|
195 |
-
if ($data = ob_get_contents()) {
|
196 |
-
ob_end_clean();
|
197 |
-
}
|
198 |
-
|
199 |
-
// Run the language upgrader
|
200 |
-
ob_start();
|
201 |
-
$skin2 = new WPRP_Automatic_Upgrader_Skin();
|
202 |
-
$lang_upgrader = new Language_Pack_Upgrader($skin2);
|
203 |
-
$result2 = $lang_upgrader->upgrade($upgrader);
|
204 |
-
if ($data2 = ob_get_contents()) {
|
205 |
-
ob_end_clean();
|
206 |
-
}
|
207 |
-
|
208 |
-
if ( isset($manage_wp_plugin_update) && $manage_wp_plugin_update )
|
209 |
-
remove_filter( 'pre_site_transient_update_plugins', '_wprp_forcably_filter_update_plugins' );
|
210 |
-
|
211 |
-
// If the plugin was activited, we have to re-activate it
|
212 |
-
// but if activate_plugin() fatals, then we'll just have to return 500
|
213 |
-
if ( $is_active )
|
214 |
-
activate_plugin( $plugin_file, '', $is_active_network, true );
|
215 |
-
|
216 |
-
if ( ! empty( $skin->error ) ) {
|
217 |
-
if (is_wp_error($skin->error)) {
|
218 |
-
return $skin->error;
|
219 |
-
}
|
220 |
-
if ($skin->error == 'up_to_date') {
|
221 |
-
return new WP_Error('up_to_date', __('Plugin already up to date.', 'wpremote'));
|
222 |
-
}
|
223 |
-
$msg = __('Unknown error updating plugin.', 'wpremote');
|
224 |
-
if (is_string($skin->error)) {
|
225 |
-
$msg = $skin->error;
|
226 |
-
}
|
227 |
-
return new WP_Error('plugin-upgrader-skin', $msg);
|
228 |
-
} else if ( is_wp_error( $result ) ) {
|
229 |
-
return $result;
|
230 |
-
} else if ( ( ! $result && ! is_null( $result ) ) || $data ) {
|
231 |
-
return new WP_Error('plugin-update', __('Unknown error updating plugin.', 'wpremote'));
|
232 |
-
}
|
233 |
-
|
234 |
-
$active_status = array(
|
235 |
-
'was_active' => $is_active,
|
236 |
-
'was_active_network' => $is_active_network,
|
237 |
-
'is_active' => is_plugin_active( $plugin_file ),
|
238 |
-
'is_active_network' => is_plugin_active_for_network( $plugin_file ),
|
239 |
-
);
|
240 |
-
|
241 |
-
return array( 'status' => 'success', 'active_status' => $active_status );
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* Validate Plugin Update
|
246 |
-
*
|
247 |
-
* @param $plugin_file
|
248 |
-
* @return array|WP_Error
|
249 |
-
*/
|
250 |
-
function _wprp_validate($plugin_file)
|
251 |
-
{
|
252 |
-
$plugin_status = false;
|
253 |
-
foreach( get_plugins() as $path => $maybe_plugin ) {
|
254 |
-
if ( $path == $plugin_file ) {
|
255 |
-
$plugin_status = true;
|
256 |
-
break;
|
257 |
-
}
|
258 |
-
}
|
259 |
-
if (!$plugin_status) {
|
260 |
-
return new WP_Error('plugin-missing', __('Plugin has gone missing.', 'wpremote'));
|
261 |
-
}
|
262 |
-
return array(
|
263 |
-
'status' => 'success',
|
264 |
-
'plugin_status' => is_plugin_active( $plugin_file )
|
265 |
-
);
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Filter `update_plugins` to produce a response it will understand
|
270 |
-
* so we can have the Upgrader skin handle the update
|
271 |
-
*/
|
272 |
-
function _wprp_forcably_filter_update_plugins() {
|
273 |
-
global $wprp_zip_update;
|
274 |
-
|
275 |
-
$current = new stdClass;
|
276 |
-
$current->response = array();
|
277 |
-
|
278 |
-
$plugin_file = $wprp_zip_update['plugin_file'];
|
279 |
-
$current->response[$plugin_file] = new stdClass;
|
280 |
-
$current->response[$plugin_file]->package = $wprp_zip_update['package'];
|
281 |
-
|
282 |
-
return $current;
|
283 |
-
}
|
284 |
-
|
285 |
-
/**
|
286 |
-
* Install a plugin on this site
|
287 |
-
*/
|
288 |
-
function _wprp_install_plugin( $plugin, $args = array() ) {
|
289 |
-
|
290 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
291 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
292 |
-
|
293 |
-
include_once ABSPATH . 'wp-admin/includes/admin.php';
|
294 |
-
include_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
295 |
-
include_once ABSPATH . 'wp-includes/update.php';
|
296 |
-
require_once ( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
297 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-plugin-upgrader-skin.php';
|
298 |
-
|
299 |
-
// Access the plugins_api() helper function
|
300 |
-
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
301 |
-
$api_args = array(
|
302 |
-
'slug' => $plugin,
|
303 |
-
'fields' => array( 'sections' => false )
|
304 |
-
);
|
305 |
-
$api = plugins_api( 'plugin_information', $api_args );
|
306 |
-
|
307 |
-
if ( is_wp_error( $api ) )
|
308 |
-
return $api;
|
309 |
-
|
310 |
-
$skin = new WPRP_Plugin_Upgrader_Skin();
|
311 |
-
$upgrader = new Plugin_Upgrader( $skin );
|
312 |
-
|
313 |
-
// The best way to get a download link for a specific version :(
|
314 |
-
// Fortunately, we can depend on a relatively consistent naming pattern
|
315 |
-
if ( ! empty( $args['version'] ) && 'stable' != $args['version'] )
|
316 |
-
$api->download_link = str_replace( $api->version . '.zip', $args['version'] . '.zip', $api->download_link );
|
317 |
-
|
318 |
-
$result = $upgrader->install( $api->download_link );
|
319 |
-
if ( is_wp_error( $result ) )
|
320 |
-
return $result;
|
321 |
-
else if ( ! $result )
|
322 |
-
return new WP_Error( 'plugin-install', __( 'Unknown error installing plugin.', 'wpremote' ) );
|
323 |
-
|
324 |
-
return array( 'status' => 'success' );
|
325 |
-
}
|
326 |
-
|
327 |
-
function _wprp_activate_plugin( $plugin ) {
|
328 |
-
|
329 |
-
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
330 |
-
|
331 |
-
$result = activate_plugin( $plugin );
|
332 |
-
|
333 |
-
if ( is_wp_error( $result ) )
|
334 |
-
return $result;
|
335 |
-
|
336 |
-
return array( 'status' => 'success' );
|
337 |
-
}
|
338 |
-
|
339 |
-
/**
|
340 |
-
* Deactivate a plugin on this site.
|
341 |
-
*/
|
342 |
-
function _wprp_deactivate_plugin( $plugin ) {
|
343 |
-
|
344 |
-
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
345 |
-
|
346 |
-
if ( is_plugin_active( $plugin ) )
|
347 |
-
deactivate_plugins( $plugin );
|
348 |
-
|
349 |
-
return array( 'status' => 'success' );
|
350 |
-
}
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Uninstall a plugin on this site.
|
354 |
-
*/
|
355 |
-
function _wprp_uninstall_plugin( $plugin ) {
|
356 |
-
global $wp_filesystem;
|
357 |
-
|
358 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
359 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
360 |
-
|
361 |
-
include_once ABSPATH . 'wp-admin/includes/admin.php';
|
362 |
-
include_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
363 |
-
include_once ABSPATH . 'wp-includes/update.php';
|
364 |
-
|
365 |
-
if ( ! _wpr_check_filesystem_access() || ! WP_Filesystem() )
|
366 |
-
return new WP_Error( 'filesystem-not-writable', __( 'The filesystem is not writable with the supplied credentials', 'wpremote' ) );
|
367 |
-
|
368 |
-
$plugins_dir = $wp_filesystem->wp_plugins_dir();
|
369 |
-
if ( empty( $plugins_dir ) )
|
370 |
-
return new WP_Error( 'missing-plugin-dir', __( 'Unable to locate WordPress Plugin directory.' , 'wpremote' ) );
|
371 |
-
|
372 |
-
$plugins_dir = trailingslashit( $plugins_dir );
|
373 |
-
|
374 |
-
if ( is_uninstallable_plugin( $plugin ) )
|
375 |
-
uninstall_plugin( $plugin );
|
376 |
-
|
377 |
-
$this_plugin_dir = trailingslashit( dirname( $plugins_dir . $plugin ) );
|
378 |
-
// If plugin is in its own directory, recursively delete the directory.
|
379 |
-
if ( strpos( $plugin, '/' ) && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory separator AND that it's not the root plugin folder
|
380 |
-
$deleted = $wp_filesystem->delete( $this_plugin_dir, true );
|
381 |
-
else
|
382 |
-
$deleted = $wp_filesystem->delete( $plugins_dir . $plugin );
|
383 |
-
|
384 |
-
if ( $deleted ) {
|
385 |
-
if ( $current = get_site_transient('update_plugins') ) {
|
386 |
-
unset( $current->response[$plugin] );
|
387 |
-
set_site_transient('update_plugins', $current);
|
388 |
-
}
|
389 |
-
return array( 'status' => 'success' );
|
390 |
-
} else {
|
391 |
-
return new WP_Error( 'plugin-uninstall', __( 'Plugin uninstalled, but not deleted.', 'wpremote' ) );
|
392 |
-
}
|
393 |
-
|
394 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
old_wpremote/wprp.themes.php
DELETED
@@ -1,246 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Return an array of installed themes
|
5 |
-
*
|
6 |
-
* @return array
|
7 |
-
*/
|
8 |
-
function _wprp_get_themes() {
|
9 |
-
|
10 |
-
require_once( ABSPATH . '/wp-admin/includes/theme.php' );
|
11 |
-
|
12 |
-
// Get all themes
|
13 |
-
if ( function_exists( 'wp_get_themes' ) )
|
14 |
-
$themes = wp_get_themes();
|
15 |
-
else
|
16 |
-
$themes = get_themes();
|
17 |
-
|
18 |
-
// Get the active theme
|
19 |
-
$active = get_option( 'current_theme' );
|
20 |
-
|
21 |
-
// Delete the transient so wp_update_themes can get fresh data
|
22 |
-
if ( function_exists( 'get_site_transient' ) )
|
23 |
-
delete_site_transient( 'update_themes' );
|
24 |
-
|
25 |
-
else
|
26 |
-
delete_transient( 'update_themes' );
|
27 |
-
|
28 |
-
// Force a theme update check
|
29 |
-
wp_update_themes();
|
30 |
-
|
31 |
-
// Different versions of wp store the updates in different places
|
32 |
-
// TODO can we depreciate
|
33 |
-
if ( function_exists( 'get_site_transient' ) && $transient = get_site_transient( 'update_themes' ) )
|
34 |
-
$current = $transient;
|
35 |
-
|
36 |
-
elseif ( $transient = get_transient( 'update_themes' ) )
|
37 |
-
$current = $transient;
|
38 |
-
|
39 |
-
else
|
40 |
-
$current = get_option( 'update_themes' );
|
41 |
-
|
42 |
-
foreach ( (array) $themes as $key => $theme ) {
|
43 |
-
|
44 |
-
// WordPress 3.4+
|
45 |
-
if ( is_object( $theme ) && is_a( $theme, 'WP_Theme' ) ) {
|
46 |
-
|
47 |
-
/* @var $theme WP_Theme */
|
48 |
-
$new_version = isset( $current->response[$theme->get_stylesheet()] ) ? $current->response[$theme->get_stylesheet()]['new_version'] : null;
|
49 |
-
|
50 |
-
$theme_array = array(
|
51 |
-
'Name' => $theme->get( 'Name' ),
|
52 |
-
'active' => $active == $theme->get( 'Name' ),
|
53 |
-
'Template' => $theme->get_template(),
|
54 |
-
'Stylesheet' => $theme->get_stylesheet(),
|
55 |
-
'Screenshot' => $theme->get_screenshot(),
|
56 |
-
'AuthorURI' => $theme->get( 'AuthorURI' ),
|
57 |
-
'Author' => $theme->get( 'Author' ),
|
58 |
-
'latest_version' => $new_version ? $new_version : $theme->get( 'Version' ),
|
59 |
-
'Version' => $theme->get( 'Version' ),
|
60 |
-
'ThemeURI' => $theme->get( 'ThemeURI' )
|
61 |
-
);
|
62 |
-
|
63 |
-
$themes[$key] = $theme_array;
|
64 |
-
|
65 |
-
} else {
|
66 |
-
|
67 |
-
$new_version = isset( $current->response[$theme['Stylesheet']] ) ? $current->response[$theme['Stylesheet']]['new_version'] : null;
|
68 |
-
|
69 |
-
if ( $active == $theme['Name'] )
|
70 |
-
$themes[$key]['active'] = true;
|
71 |
-
|
72 |
-
else
|
73 |
-
$themes[$key]['active'] = false;
|
74 |
-
|
75 |
-
if ( $new_version ) {
|
76 |
-
|
77 |
-
$themes[$key]['latest_version'] = $new_version;
|
78 |
-
$themes[$key]['latest_package'] = $current->response[$theme['Template']]['package'];
|
79 |
-
|
80 |
-
} else {
|
81 |
-
|
82 |
-
$themes[$key]['latest_version'] = $theme['Version'];
|
83 |
-
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
return $themes;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Install a theme
|
93 |
-
*
|
94 |
-
* @param mixed $theme
|
95 |
-
* @param array $args
|
96 |
-
* @return array|bool
|
97 |
-
*/
|
98 |
-
function _wprp_install_theme( $theme, $args = array() ) {
|
99 |
-
|
100 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
101 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
102 |
-
|
103 |
-
if ( wp_get_theme( $theme )->exists() )
|
104 |
-
return new WP_Error( 'theme-installed', __( 'Theme is already installed.' ) );
|
105 |
-
|
106 |
-
include_once ABSPATH . 'wp-admin/includes/admin.php';
|
107 |
-
include_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
108 |
-
include_once ABSPATH . 'wp-includes/update.php';
|
109 |
-
require_once ( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
110 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-theme-upgrader-skin.php';
|
111 |
-
|
112 |
-
// Access the themes_api() helper function
|
113 |
-
include_once ABSPATH . 'wp-admin/includes/theme-install.php';
|
114 |
-
$api_args = array(
|
115 |
-
'slug' => $theme,
|
116 |
-
'fields' => array( 'sections' => false )
|
117 |
-
);
|
118 |
-
$api = themes_api( 'theme_information', $api_args );
|
119 |
-
|
120 |
-
if ( is_wp_error( $api ) )
|
121 |
-
return $api;
|
122 |
-
|
123 |
-
$skin = new WPRP_Theme_Upgrader_Skin();
|
124 |
-
$upgrader = new Theme_Upgrader( $skin );
|
125 |
-
|
126 |
-
// The best way to get a download link for a specific version :(
|
127 |
-
// Fortunately, we can depend on a relatively consistent naming pattern
|
128 |
-
if ( ! empty( $args['version'] ) && 'stable' != $args['version'] )
|
129 |
-
$api->download_link = str_replace( $api->version . '.zip', $args['version'] . '.zip', $api->download_link );
|
130 |
-
|
131 |
-
$result = $upgrader->install( $api->download_link );
|
132 |
-
if ( is_wp_error( $result ) )
|
133 |
-
return $result;
|
134 |
-
else if ( ! $result )
|
135 |
-
return new WP_Error( 'unknown-install-error', __( 'Unknown error installing theme.', 'wpremote' ) );
|
136 |
-
|
137 |
-
return array( 'status' => 'success' );
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Activate a theme
|
142 |
-
*
|
143 |
-
* @param mixed $theme
|
144 |
-
* @return array
|
145 |
-
*/
|
146 |
-
function _wprp_activate_theme( $theme ) {
|
147 |
-
|
148 |
-
if ( ! wp_get_theme( $theme )->exists() )
|
149 |
-
return new WP_Error( 'theme-not-installed', __( 'Theme is not installed.', 'wpremote' ) );
|
150 |
-
|
151 |
-
switch_theme( $theme );
|
152 |
-
return array( 'status' => 'success' );
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Update a theme
|
157 |
-
*
|
158 |
-
* @param mixed $theme
|
159 |
-
* @return array|WP_Error
|
160 |
-
*/
|
161 |
-
function _wprp_update_theme( $theme ) {
|
162 |
-
|
163 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
164 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
165 |
-
|
166 |
-
include_once ( ABSPATH . 'wp-admin/includes/admin.php' );
|
167 |
-
require_once ( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
168 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-theme-upgrader-skin.php';
|
169 |
-
require_once WPRP_PLUGIN_PATH . 'inc/class-wprp-automatic-upgrader-skin.php';
|
170 |
-
|
171 |
-
// check for filesystem access
|
172 |
-
if ( ! _wpr_check_filesystem_access() )
|
173 |
-
return new WP_Error( 'filesystem-not-writable', __( 'The filesystem is not writable with the supplied credentials', 'wpremote' ) );
|
174 |
-
|
175 |
-
$skin = new WPRP_Theme_Upgrader_Skin();
|
176 |
-
$upgrader = new Theme_Upgrader( $skin );
|
177 |
-
|
178 |
-
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
179 |
-
|
180 |
-
// Do the upgrade
|
181 |
-
ob_start();
|
182 |
-
$result = $upgrader->upgrade( $theme );
|
183 |
-
$data = ob_get_contents();
|
184 |
-
ob_clean();
|
185 |
-
|
186 |
-
// Run the language upgrader
|
187 |
-
try {
|
188 |
-
ob_start();
|
189 |
-
$skin2 = new WPRP_Automatic_Upgrader_Skin();
|
190 |
-
$lang_upgrader = new Language_Pack_Upgrader($skin2);
|
191 |
-
$result2 = $lang_upgrader->upgrade($upgrader);
|
192 |
-
if ($data2 = ob_get_contents()) {
|
193 |
-
ob_end_clean();
|
194 |
-
}
|
195 |
-
} catch (\Exception $e) {} // Fail silently
|
196 |
-
|
197 |
-
if ( ! empty( $skin->error ) ){
|
198 |
-
return new WP_Error( 'theme-upgrader-skin', $upgrader->strings[$skin->error] );
|
199 |
-
} elseif ( is_wp_error( $result ) ) {
|
200 |
-
return $result;
|
201 |
-
} elseif ( ( ! $result && ! is_null( $result ) ) || $data ) {
|
202 |
-
return new WP_Error('theme-update', __('Unknown error updating theme.', 'wpremote'));
|
203 |
-
}
|
204 |
-
|
205 |
-
return array( 'status' => 'success' );
|
206 |
-
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Delete a theme.
|
211 |
-
*
|
212 |
-
* @param mixed $theme
|
213 |
-
* @return array
|
214 |
-
*/
|
215 |
-
function _wprp_delete_theme( $theme ) {
|
216 |
-
global $wp_filesystem;
|
217 |
-
|
218 |
-
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
219 |
-
return new WP_Error( 'disallow-file-mods', __( "File modification is disabled with the DISALLOW_FILE_MODS constant.", 'wpremote' ) );
|
220 |
-
|
221 |
-
if ( ! wp_get_theme( $theme )->exists() )
|
222 |
-
return new WP_Error( 'theme-missing', __( 'Theme is not installed.', 'wpremote' ) );
|
223 |
-
|
224 |
-
include_once ABSPATH . 'wp-admin/includes/admin.php';
|
225 |
-
include_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
226 |
-
include_once ABSPATH . 'wp-includes/update.php';
|
227 |
-
|
228 |
-
if ( ! _wpr_check_filesystem_access() || ! WP_Filesystem() )
|
229 |
-
return new WP_Error( 'filesystem-not-writable', __( 'The filesystem is not writable with the supplied credentials', 'wpremote' ) );
|
230 |
-
|
231 |
-
$themes_dir = $wp_filesystem->wp_themes_dir();
|
232 |
-
if ( empty( $themes_dir ) )
|
233 |
-
return new WP_Error( 'theme-dir-missing', __( 'Unable to locate WordPress theme directory', 'wpremote' ) );
|
234 |
-
|
235 |
-
$themes_dir = trailingslashit( $themes_dir );
|
236 |
-
$theme_dir = trailingslashit( $themes_dir . $theme );
|
237 |
-
$deleted = $wp_filesystem->delete( $theme_dir, true );
|
238 |
-
|
239 |
-
if ( ! $deleted )
|
240 |
-
return new WP_Error( 'theme-delete', sprintf( __( 'Could not fully delete the theme: %s.', 'wpremote' ), $theme ) );
|
241 |
-
|
242 |
-
// Force refresh of theme update information
|
243 |
-
delete_site_transient('update_themes');
|
244 |
-
|
245 |
-
return array( 'status' => 'success' );
|
246 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plugin.php
CHANGED
@@ -5,7 +5,7 @@ Plugin URI: https://wpremote.com
|
|
5 |
Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>.
|
6 |
Author: WP Remote
|
7 |
Author URI: https://wpremote.com
|
8 |
-
Version: 4.
|
9 |
Network: True
|
10 |
*/
|
11 |
|
@@ -28,14 +28,7 @@ Network: True
|
|
28 |
/* Global response array */
|
29 |
|
30 |
if (!defined('ABSPATH')) exit;
|
31 |
-
|
32 |
-
if (get_option( 'wpr_api_key' ) !== false) {
|
33 |
-
define( 'WPRP_PLUGIN_SLUG', 'wpremote' );
|
34 |
-
define( 'WPRP_PLUGIN_BASE', plugin_basename(__FILE__) );
|
35 |
-
define( 'WPRP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) . 'old_wpremote/' );
|
36 |
-
require 'old_wpremote/plugin.php';
|
37 |
-
}
|
38 |
-
|
39 |
|
40 |
require_once dirname( __FILE__ ) . '/wp_settings.php';
|
41 |
require_once dirname( __FILE__ ) . '/wp_site_info.php';
|
@@ -107,6 +100,7 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
|
|
107 |
|
108 |
|
109 |
require_once dirname( __FILE__ ) . '/callback/handler.php';
|
|
|
110 |
$params = $request->processParams($_REQUEST);
|
111 |
if ($params === false) {
|
112 |
$resp = array(
|
5 |
Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>.
|
6 |
Author: WP Remote
|
7 |
Author URI: https://wpremote.com
|
8 |
+
Version: 4.65
|
9 |
Network: True
|
10 |
*/
|
11 |
|
28 |
/* Global response array */
|
29 |
|
30 |
if (!defined('ABSPATH')) exit;
|
31 |
+
##OLDWPR##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
require_once dirname( __FILE__ ) . '/wp_settings.php';
|
34 |
require_once dirname( __FILE__ ) . '/wp_site_info.php';
|
100 |
|
101 |
|
102 |
require_once dirname( __FILE__ ) . '/callback/handler.php';
|
103 |
+
|
104 |
$params = $request->processParams($_REQUEST);
|
105 |
if ($params === false) {
|
106 |
$resp = array(
|
protect/wp/lp/config.php
CHANGED
@@ -7,6 +7,9 @@ class BVWPLPConfig {
|
|
7 |
public $captchaLimit;
|
8 |
public $tempBlockLimit;
|
9 |
public $blockAllLimit;
|
|
|
|
|
|
|
10 |
|
11 |
public static $requests_table = 'lp_requests';
|
12 |
|
@@ -20,6 +23,9 @@ class BVWPLPConfig {
|
|
20 |
$this->captchaLimit = array_key_exists('captchalimit', $confHash) ? intval($confHash['captchalimit']) : 3;
|
21 |
$this->tempBlockLimit = array_key_exists('tempblocklimit', $confHash) ? intval($confHash['tempblocklimit']) : 10;
|
22 |
$this->blockAllLimit = array_key_exists('blockalllimit', $confHash) ? intval($confHash['blockalllimit']) : 100;
|
|
|
|
|
|
|
23 |
}
|
24 |
}
|
25 |
endif;
|
7 |
public $captchaLimit;
|
8 |
public $tempBlockLimit;
|
9 |
public $blockAllLimit;
|
10 |
+
public $failedLoginGap;
|
11 |
+
public $successLoginGap;
|
12 |
+
public $allBlockedGap;
|
13 |
|
14 |
public static $requests_table = 'lp_requests';
|
15 |
|
23 |
$this->captchaLimit = array_key_exists('captchalimit', $confHash) ? intval($confHash['captchalimit']) : 3;
|
24 |
$this->tempBlockLimit = array_key_exists('tempblocklimit', $confHash) ? intval($confHash['tempblocklimit']) : 10;
|
25 |
$this->blockAllLimit = array_key_exists('blockalllimit', $confHash) ? intval($confHash['blockalllimit']) : 100;
|
26 |
+
$this->failedLoginGap = array_key_exists('failedlogingap', $confHash) ? intval($confHash['failedlogingap']) : 1800;
|
27 |
+
$this->successLoginGap = array_key_exists('successlogingap', $confHash) ? intval($confHash['successlogingap']) : 1800;
|
28 |
+
$this->allBlockedGap = array_key_exists('allblockedgap', $confHash) ? intval($confHash['allblockedgap']) : 1800;
|
29 |
}
|
30 |
}
|
31 |
endif;
|
protect/wp/lp/lp.php
CHANGED
@@ -83,6 +83,18 @@ class BVWPLP {
|
|
83 |
return $this->config->captchaLimit;
|
84 |
}
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
public function getTempBlockLimit() {
|
87 |
return $this->config->tempBlockLimit;
|
88 |
}
|
@@ -149,7 +161,7 @@ class BVWPLP {
|
|
149 |
|
150 |
public function isLoginBlocked() {
|
151 |
if ($this->getAllowLoginsTransient() ||
|
152 |
-
($this->getLoginCount(BVWPLP::LOGINFAILURE) < $this->getBlockAllLimit())) {
|
153 |
return false;
|
154 |
}
|
155 |
return true;
|
@@ -184,7 +196,7 @@ class BVWPLP {
|
|
184 |
if ($this->isUnBlockedIP()) {
|
185 |
$this->setCategory(BVWPLP::UNBLOCKED);
|
186 |
} else {
|
187 |
-
$failed_attempts = $this->getLoginCount(BVWPLP::LOGINFAILURE, $this->ip);
|
188 |
if ($this->isWhitelistedIP()) {
|
189 |
$this->setCategory(BVWPLP::BYPASSED);
|
190 |
} else if ($this->isBlacklistedIP()) {
|
@@ -221,7 +233,7 @@ class BVWPLP {
|
|
221 |
}
|
222 |
|
223 |
public function isKnownLogin() {
|
224 |
-
return $this->getLoginCount(BVWPLP::LOGINSUCCESS, $this->ip,
|
225 |
}
|
226 |
|
227 |
public function getLoginCount($status, $ip = null, $gap = 1800) {
|
83 |
return $this->config->captchaLimit;
|
84 |
}
|
85 |
|
86 |
+
public function getFailedLoginGap() {
|
87 |
+
return $this->config->failedLoginGap;
|
88 |
+
}
|
89 |
+
|
90 |
+
public function getSuccessLoginGap() {
|
91 |
+
return $this->config->successLoginGap;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function getAllBlockedGap() {
|
95 |
+
return $this->config->allBlockedGap;
|
96 |
+
}
|
97 |
+
|
98 |
public function getTempBlockLimit() {
|
99 |
return $this->config->tempBlockLimit;
|
100 |
}
|
161 |
|
162 |
public function isLoginBlocked() {
|
163 |
if ($this->getAllowLoginsTransient() ||
|
164 |
+
($this->getLoginCount(BVWPLP::LOGINFAILURE, null, $this->getAllBlockedGap()) < $this->getBlockAllLimit())) {
|
165 |
return false;
|
166 |
}
|
167 |
return true;
|
196 |
if ($this->isUnBlockedIP()) {
|
197 |
$this->setCategory(BVWPLP::UNBLOCKED);
|
198 |
} else {
|
199 |
+
$failed_attempts = $this->getLoginCount(BVWPLP::LOGINFAILURE, $this->ip, $this->getFailedLoginGap());
|
200 |
if ($this->isWhitelistedIP()) {
|
201 |
$this->setCategory(BVWPLP::BYPASSED);
|
202 |
} else if ($this->isBlacklistedIP()) {
|
233 |
}
|
234 |
|
235 |
public function isKnownLogin() {
|
236 |
+
return $this->getLoginCount(BVWPLP::LOGINSUCCESS, $this->ip, $this->getSuccessLoginGap()) > 0;
|
237 |
}
|
238 |
|
239 |
public function getLoginCount($status, $ip = null, $gap = 1800) {
|
readme.txt
CHANGED
@@ -6,7 +6,7 @@ Donate link: https://app.wpremote.com/home/signup
|
|
6 |
Requires at least: 4.0
|
7 |
Tested up to: 5.8
|
8 |
Requires PHP: 5.4.0
|
9 |
-
Stable tag: 4.
|
10 |
License: GPLv2 or later
|
11 |
License URI: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html)
|
12 |
|
@@ -32,6 +32,11 @@ You can email us at support@wpremote.com for support.
|
|
32 |
3. Sign up for an account at wpremote.com and add your site.
|
33 |
|
34 |
== CHANGELOG ==
|
|
|
|
|
|
|
|
|
|
|
35 |
= 4.64 =
|
36 |
* Added latest WooCommerce Real-Time-Backup support.
|
37 |
|
6 |
Requires at least: 4.0
|
7 |
Tested up to: 5.8
|
8 |
Requires PHP: 5.4.0
|
9 |
+
Stable tag: 4.65
|
10 |
License: GPLv2 or later
|
11 |
License URI: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html)
|
12 |
|
32 |
3. Sign up for an account at wpremote.com and add your site.
|
33 |
|
34 |
== CHANGELOG ==
|
35 |
+
= 4.65 =
|
36 |
+
* Making Login Protection more configurable.
|
37 |
+
* Robust handling of requests params.
|
38 |
+
* Callback wing versioning.
|
39 |
+
|
40 |
= 4.64 =
|
41 |
* Added latest WooCommerce Real-Time-Backup support.
|
42 |
|