The WP Remote WordPress Plugin - Version 4.65

Version Description

  • Making Login Protection more configurable.
  • Robust handling of requests params.
  • Callback wing versioning.
Download this release

Release Info

Developer ritesh.soni36
Plugin Icon 128x128 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 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(), $full) {
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'], $full);
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.64';
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.64
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, 3600) > 0;
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.64
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