MainWP Child - Version 4.0.7.1

Version Description

  • 4-30-20 =
  • Fixed: JSON decoding issues on specific setups
  • Fixed: an issue with incorrect images URL
  • Fixed: conflict with the Download Manager plugin
  • Fixed: multiple PHP warnings
  • Fixed: MySQL query compatibility problems
  • Fixed: an issue with saving Wordfence settings
  • Fixed: an issue with showing correct post and page creating time
  • Fixed: an issue with displaying correct author in reports
  • Added: support for WPVivid backups in the reporting system
  • Preventative: security improvements
Download this release

Release Info

Developer mainwp
Plugin Icon 128x128 MainWP Child
Version 4.0.7.1
Comparing to
See all releases

Code changes from version 4.0.7 to 4.0.7.1

class/class-mainwp-child-branding.php CHANGED
@@ -1149,7 +1149,7 @@ class MainWP_Child_Branding {
1149
  return $plugins;
1150
  }
1151
 
1152
- if ( is_array( $branding_header ) && ! empty( $branding_header['name'] ) ) {
1153
  return $this->update_plugin_header( $plugins, $branding_header );
1154
  } else {
1155
  return $plugins;
1149
  return $plugins;
1150
  }
1151
 
1152
+ if ( is_array( $branding_header ) && ! empty( $branding_header['name'] ) && is_array( $plugins ) ) {
1153
  return $this->update_plugin_header( $plugins, $branding_header );
1154
  } else {
1155
  return $plugins;
class/class-mainwp-child-server-information.php CHANGED
@@ -1154,7 +1154,7 @@ class MainWP_Child_Server_Information {
1154
  /** @var $wpdb wpdb */
1155
  global $wpdb;
1156
 
1157
- return $wpdb->get_var( 'SHOW VARIABLES LIKE "version"', 1 );
1158
  }
1159
 
1160
  protected static function getMaxInputTime() {
1154
  /** @var $wpdb wpdb */
1155
  global $wpdb;
1156
 
1157
+ return $wpdb->get_var( "SHOW VARIABLES LIKE 'version'", 1 );
1158
  }
1159
 
1160
  protected static function getMaxInputTime() {
class/class-mainwp-child-timecapsule.php CHANGED
@@ -301,7 +301,7 @@ class MainWP_Child_Timecapsule {
301
  global $wpdb;
302
  $all_backups = $wpdb->get_results(
303
  $wpdb->prepare("
304
- SELECT *
305
  FROM {$wpdb->base_prefix}wptc_processed_files
306
  WHERE backupID > %s ", $last_time)
307
  );
@@ -533,10 +533,8 @@ function get_sibling_files_callback_wptc() {
533
  $load_more = false;
534
  $current_limit = WPTC_Factory::get('config')->get_option('activity_log_lazy_load_limit');
535
  $to_limit = $from_limit + $current_limit;
536
-
537
- $sql = "SELECT * FROM " . $wpdb->base_prefix . "wptc_activity_log WHERE action_id=" . $action_id . ' AND show_user = 1 ORDER BY id DESC LIMIT '.$from_limit.' , '.$current_limit;
538
-
539
- $sub_records = $wpdb->get_results($sql);
540
  $row_count = count($sub_records);
541
 
542
  if ($row_count == $current_limit) {
@@ -573,8 +571,8 @@ function get_sibling_files_callback_wptc() {
573
 
574
  $more_logs = false;
575
  $load_more = false;
576
- if ($rec->action_id != '') {
577
- $sql = "SELECT * FROM " . $wpdb->base_prefix . "wptc_activity_log WHERE action_id=" . $rec->action_id . ' AND show_user = 1 ORDER BY id DESC LIMIT 0 , '.$limit;
578
  $sub_records = $wpdb->get_results($sql);
579
  $row_count = count($sub_records);
580
  if ($row_count == $limit) {
301
  global $wpdb;
302
  $all_backups = $wpdb->get_results(
303
  $wpdb->prepare("
304
+ SELECT backupID
305
  FROM {$wpdb->base_prefix}wptc_processed_files
306
  WHERE backupID > %s ", $last_time)
307
  );
533
  $load_more = false;
534
  $current_limit = WPTC_Factory::get('config')->get_option('activity_log_lazy_load_limit');
535
  $to_limit = $from_limit + $current_limit;
536
+ $sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->base_prefix . "wptc_activity_log WHERE action_id='%s' AND show_user = 1 ORDER BY id DESC LIMIT %d, %d", $action_id, $from_limit, $current_limit );
537
+ $sub_records = $wpdb->get_results( $sql );
 
 
538
  $row_count = count($sub_records);
539
 
540
  if ($row_count == $current_limit) {
571
 
572
  $more_logs = false;
573
  $load_more = false;
574
+ if ($rec->action_id != '') {
575
+ $sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->base_prefix . "wptc_activity_log WHERE action_id='%s' AND show_user = 1 ORDER BY id DESC LIMIT 0, %d", $rec->action_id, $limit );
576
  $sub_records = $wpdb->get_results($sql);
577
  $row_count = count($sub_records);
578
  if ($row_count == $limit) {
class/class-mainwp-child-updraft-plus-backups.php CHANGED
@@ -201,7 +201,7 @@ class MainWP_Child_Updraft_Plus_Backups {
201
  'updraft_include_mu-plugins',
202
  'updraft_include_others_exclude',
203
  'updraft_include_uploads_exclude',
204
- 'updraft_adminlocking',
205
  'updraft_starttime_files',
206
  'updraft_starttime_db',
207
  'updraft_startday_db',
201
  'updraft_include_mu-plugins',
202
  'updraft_include_others_exclude',
203
  'updraft_include_uploads_exclude',
204
+ //'updraft_adminlocking',
205
  'updraft_starttime_files',
206
  'updraft_starttime_db',
207
  'updraft_startday_db',
class/class-mainwp-child.php CHANGED
@@ -117,7 +117,7 @@ if ( isset( $_GET['skeleton_keyuse_nonce_key'] ) && isset( $_GET['skeleton_keyus
117
  }
118
 
119
  class MainWP_Child {
120
- public static $version = '4.0.7';
121
  private $update_version = '1.5';
122
 
123
  private $callableFunctions = array(
@@ -1104,6 +1104,10 @@ class MainWP_Child {
1104
  }
1105
 
1106
  function check_login() {
 
 
 
 
1107
  $file = '';
1108
  if ( isset( $_REQUEST['f'] ) ) {
1109
  $file = $_REQUEST['f'];
@@ -1592,14 +1596,15 @@ class MainWP_Child {
1592
  }
1593
 
1594
  function auth( $signature, $func, $nonce, $pNossl ) {
1595
- if ( ! isset( $signature ) || ! isset( $func ) || ( ! get_option( 'mainwp_child_pubkey' ) && ! get_option( 'mainwp_child_nossl_key' ) ) ) {
1596
  $auth = false;
1597
  } else {
1598
  $nossl = get_option( 'mainwp_child_nossl' );
1599
  $serverNoSsl = ( isset( $pNossl ) && 1 === (int) $pNossl );
1600
 
1601
- if ( ( 1 === (int) $nossl ) || $serverNoSsl ) {
1602
- $auth = hash_equals( md5( $func . $nonce . get_option( 'mainwp_child_nossl_key' ) ), base64_decode( $signature ) );
 
1603
  } else {
1604
  $auth = openssl_verify( $func . $nonce, base64_decode( $signature ), base64_decode( get_option( 'mainwp_child_pubkey' ) ) );
1605
  if ($auth !== 1) {
@@ -2441,7 +2446,14 @@ class MainWP_Child {
2441
 
2442
  MainWP_Helper::update_option( 'mainwp_child_nossl', ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 ), 'yes' );
2443
  $information['nossl'] = ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 );
2444
- $nossl_key = uniqid( '', true );
 
 
 
 
 
 
 
2445
  MainWP_Helper::update_option( 'mainwp_child_nossl_key', $nossl_key, 'yes' );
2446
  $information['nosslkey'] = $nossl_key;
2447
 
117
  }
118
 
119
  class MainWP_Child {
120
+ public static $version = '4.0.7.1';
121
  private $update_version = '1.5';
122
 
123
  private $callableFunctions = array(
1104
  }
1105
 
1106
  function check_login() {
1107
+
1108
+ if ( !isset( $_POST['mainwpsignature'] ) || empty( $_POST['mainwpsignature'] ) )
1109
+ return false;
1110
+
1111
  $file = '';
1112
  if ( isset( $_REQUEST['f'] ) ) {
1113
  $file = $_REQUEST['f'];
1596
  }
1597
 
1598
  function auth( $signature, $func, $nonce, $pNossl ) {
1599
+ if ( empty( $signature ) || ! isset( $func ) || ( ! get_option( 'mainwp_child_pubkey' ) && ! get_option( 'mainwp_child_nossl_key' ) ) ) {
1600
  $auth = false;
1601
  } else {
1602
  $nossl = get_option( 'mainwp_child_nossl' );
1603
  $serverNoSsl = ( isset( $pNossl ) && 1 === (int) $pNossl );
1604
 
1605
+ if ( ( 1 === (int) $nossl ) || $serverNoSsl ) {
1606
+ $nossl_key = get_option( 'mainwp_child_nossl_key' );
1607
+ $auth = hash_equals( md5( $func . $nonce . $nossl_key ), base64_decode( $signature ) );
1608
  } else {
1609
  $auth = openssl_verify( $func . $nonce, base64_decode( $signature ), base64_decode( get_option( 'mainwp_child_pubkey' ) ) );
1610
  if ($auth !== 1) {
2446
 
2447
  MainWP_Helper::update_option( 'mainwp_child_nossl', ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 ), 'yes' );
2448
  $information['nossl'] = ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 );
2449
+
2450
+ if ( function_exists( 'random_bytes' ) ) {
2451
+ $nossl_key = random_bytes( 32 );
2452
+ $nossl_key = bin2hex( $nossl_key );
2453
+ } else {
2454
+ $nossl_key = uniqid( '', true );
2455
+ }
2456
+
2457
  MainWP_Helper::update_option( 'mainwp_child_nossl_key', $nossl_key, 'yes' );
2458
  $information['nosslkey'] = $nossl_key;
2459
 
class/class-mainwp-client-report.php CHANGED
@@ -102,7 +102,7 @@ class MainWP_Client_Report {
102
  }
103
 
104
  public function is_backup_action( $action ) {
105
- if ( in_array( $action, array( 'mainwp_backup', 'backupbuddy_backup', 'backupwordpress_backup', 'backwpup_backup', 'updraftplus_backup', 'wptimecapsule_backup' ) ) )
106
  return true;
107
  return false;
108
  }
@@ -333,8 +333,64 @@ class MainWP_Client_Report {
333
  $records = array();
334
  }
335
 
336
- // to fix invalid data
 
337
  $skip_records = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  if ( isset( $other_tokens['header'] ) && is_array( $other_tokens['header'] ) ) {
339
  $other_tokens_data['header'] = $this->get_other_tokens_data( $records, $other_tokens['header'], $skip_records);
340
  }
@@ -437,6 +493,10 @@ class MainWP_Client_Report {
437
  if ( ! in_array( $record->context, $comment_contexts ) ) {
438
  continue;
439
  }
 
 
 
 
440
  } else if ( $context == "menus") {
441
  // ok, pass, don't check context
442
  } else if ( $record->connector == 'editor' ) {
@@ -818,8 +878,9 @@ class MainWP_Client_Report {
818
  $meta = $record->meta;
819
 
820
  if ( isset( $meta[ $meta_key ] ) ) {
 
821
  $value = $meta[ $meta_key ];
822
- $value = current( $value );
823
 
824
  // to compatible with old meta data
825
  if ( 'author_meta' === $meta_key ) {
102
  }
103
 
104
  public function is_backup_action( $action ) {
105
+ if ( in_array( $action, array( 'mainwp_backup', 'backupbuddy_backup', 'backupwordpress_backup', 'backwpup_backup', 'updraftplus_backup', 'wptimecapsule_backup', 'wpvivid_backup' ) ) )
106
  return true;
107
  return false;
108
  }
333
  $records = array();
334
  }
335
 
336
+
337
+ // to fix invalid data, or skip records
338
  $skip_records = array();
339
+
340
+ // to fix for incorrect posts created logging
341
+ // query created posts from WP posts data to simulate records logging for created posts
342
+ if ( isset($_POST['direct_posts']) && !empty($_POST['direct_posts']) ) {
343
+ $query_string = array(
344
+ 'post_type' => 'post',
345
+ 'date_query' => array(
346
+ 'column' => 'post_date',
347
+ 'after' => $args['date_from'],
348
+ 'before' => $args['date_to']
349
+ ),
350
+ 'post_status' => 'publish'
351
+ );
352
+
353
+ $records_created_posts = query_posts( $query_string );
354
+
355
+ if ($records_created_posts) {
356
+
357
+ for( $i = 0; $i < count($records); $i++ ) {
358
+ $record = $records[$i];
359
+ if ($record->connector == 'posts' && $record->context == 'post' && $record->action == 'created') {
360
+ if (!in_array($record->ID, $skip_records)) {
361
+ $skip_records[] = $record->ID; // so avoid this created logging, will use logging query from posts data
362
+ }
363
+ }
364
+ }
365
+
366
+ $post_authors = array();
367
+
368
+ foreach( $records_created_posts as $_post){
369
+ $au_id = $_post->post_author;
370
+ if ( !isset($post_authors[$au_id]) ) {
371
+ $au = get_user_by( 'id', $au_id );
372
+ $post_authors[$au_id] = $au->display_name;
373
+ }
374
+ $au_name = $post_authors[$au_id];
375
+
376
+ //simulate logging created posts record
377
+ $stdObj = new stdClass;
378
+ $stdObj->ID = 0; // simulate ID value
379
+ $stdObj->connector = 'posts';
380
+ $stdObj->context = 'post';
381
+ $stdObj->action = 'created';
382
+ $stdObj->created = $_post->post_date;
383
+ $stdObj->meta = array(
384
+ 'post_title' => array( $_post->post_title ),
385
+ 'user_meta' => array( $au_name )
386
+ );
387
+
388
+ $records[] = $stdObj;
389
+ }
390
+ }
391
+
392
+ }
393
+
394
  if ( isset( $other_tokens['header'] ) && is_array( $other_tokens['header'] ) ) {
395
  $other_tokens_data['header'] = $this->get_other_tokens_data( $records, $other_tokens['header'], $skip_records);
396
  }
493
  if ( ! in_array( $record->context, $comment_contexts ) ) {
494
  continue;
495
  }
496
+ } else if ( 'post' === $context && 'created' === $action ) {
497
+ if ( in_array($record->ID, $skip_records) ) {
498
+ continue;
499
+ }
500
  } else if ( $context == "menus") {
501
  // ok, pass, don't check context
502
  } else if ( $record->connector == 'editor' ) {
878
  $meta = $record->meta;
879
 
880
  if ( isset( $meta[ $meta_key ] ) ) {
881
+
882
  $value = $meta[ $meta_key ];
883
+ $value = ( $meta_key == 'user_meta' && isset($value[1]) ) ? $value[1] : current( $value ); // display name
884
 
885
  // to compatible with old meta data
886
  if ( 'author_meta' === $meta_key ) {
class/class-mainwp-helper.php CHANGED
@@ -12,23 +12,67 @@ class MainWP_Helper {
12
  die( '<mainwp>' . base64_encode( $output ) . '</mainwp>' );
13
  }
14
 
15
- public static function utf8ize($mixed) {
16
- if (is_array($mixed)) {
17
- foreach ($mixed as $key => $value) {
18
- $mixed[$key] = self::utf8ize($value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
- } elseif (is_string($mixed)) {
 
 
 
 
 
 
 
 
 
 
21
  if ( function_exists( 'mb_convert_encoding' )) {
22
- return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
 
 
 
 
23
  }
24
  }
25
- return $mixed;
26
  }
27
 
28
  public static function safe_json_encode($value, $options = 0, $depth = 512) {
29
  $encoded = @json_encode($value, $options, $depth);
30
- if ($encoded === false && $value && json_last_error() == JSON_ERROR_UTF8) {
31
- $encoded = @json_encode(self::utf8ize($value), $options, $depth);
32
  }
33
  return $encoded;
34
  }
@@ -158,10 +202,15 @@ class MainWP_Helper {
158
  static function uploadImage( $img_url, $img_data = array() , $check_file_existed = false, $parent_id = 0 ) {
159
  if ( !is_array($img_data) )
160
  $img_data = array();
 
 
 
161
  include_once( ABSPATH . 'wp-admin/includes/file.php' ); //Contains download_url
162
  $upload_dir = wp_upload_dir();
 
163
  //Download $img_url
164
- $temporary_file = download_url( $img_url );
 
165
 
166
  if ( is_wp_error( $temporary_file ) ) {
167
  throw new Exception( 'Error: ' . $temporary_file->get_error_message() );
@@ -170,7 +219,7 @@ class MainWP_Helper {
170
  $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . $filename; //Local name
171
  $local_img_url = $upload_dir['url'] . '/' . basename( $local_img_path );
172
 
173
- $gen_unique_fn = true;
174
 
175
  // to fix issue re-create new attachment
176
  if ( $check_file_existed ) {
@@ -210,7 +259,9 @@ class MainWP_Helper {
210
  }
211
  }
212
 
213
- if ( $gen_unique_fn ) {
 
 
214
  $local_img_path = dirname( $local_img_path ) . '/' . wp_unique_filename( dirname( $local_img_path ), basename( $local_img_path ) );
215
  $local_img_url = $upload_dir['url'] . '/' . basename( $local_img_path );
216
  }
@@ -475,7 +526,7 @@ class MainWP_Helper {
475
  $new_post['post_content'] = str_replace( $lnkToReplace, $linkToReplaceWith, $new_post['post_content'] );
476
  }
477
  } catch ( Exception $e ) {
478
-
479
  }
480
  }
481
  }
12
  die( '<mainwp>' . base64_encode( $output ) . '</mainwp>' );
13
  }
14
 
15
+ public static function json_valid_check( $data ) {
16
+
17
+ if (is_array( $data )) {
18
+ $output = array();
19
+ foreach ( $data as $key => $value) {
20
+ if ( is_string( $key ) ) {
21
+ $id = self::json_convert_string( $key );
22
+ } else {
23
+ $id = $key;
24
+ }
25
+ if ( is_array( $value ) || is_object( $value ) ) {
26
+ $output[ $id ] = self::json_valid_check( $value );
27
+ } elseif ( is_string( $value ) ) {
28
+ $output[ $id ] = self::json_convert_string( $value );
29
+ } else {
30
+ $output[ $id ] = $value;
31
+ }
32
+ }
33
+ }
34
+ elseif ( is_object( $data ) ) {
35
+ $output = new stdClass;
36
+ foreach ( $data as $key => $value ) {
37
+ if ( is_string( $key ) ) {
38
+ $id = self::json_convert_string( $key );
39
+ } else {
40
+ $id = $key;
41
+ }
42
+ if ( is_array( $value ) || is_object( $value ) ) {
43
+ $output->$id = self::json_valid_check($value);
44
+ } elseif ( is_string( $value ) ) {
45
+ $output->$id = self::json_convert_string( $value );
46
+ } else {
47
+ $output->$id = $value;
48
+ }
49
  }
50
+ }
51
+ elseif (is_string( $data )) {
52
+ return self::json_convert_string( $data );
53
+ } else {
54
+ return $data;
55
+ }
56
+
57
+ return $output;
58
+ }
59
+
60
+ public function json_convert_string( $str ) {
61
  if ( function_exists( 'mb_convert_encoding' )) {
62
+ $encoding = mb_detect_encoding( $str, mb_detect_order(), true );
63
+ if ( $encoding ) {
64
+ return mb_convert_encoding( $str, 'UTF-8', $encoding );
65
+ } else {
66
+ return mb_convert_encoding( $str, 'UTF-8', 'UTF-8' );
67
  }
68
  }
69
+ return $str;
70
  }
71
 
72
  public static function safe_json_encode($value, $options = 0, $depth = 512) {
73
  $encoded = @json_encode($value, $options, $depth);
74
+ if ($encoded === false && !empty( $value ) && json_last_error() == JSON_ERROR_UTF8 ) {
75
+ $encoded = @json_encode(self::json_valid_check($value), $options, $depth);
76
  }
77
  return $encoded;
78
  }
202
  static function uploadImage( $img_url, $img_data = array() , $check_file_existed = false, $parent_id = 0 ) {
203
  if ( !is_array($img_data) )
204
  $img_data = array();
205
+
206
+ global $mainWPChild;
207
+
208
  include_once( ABSPATH . 'wp-admin/includes/file.php' ); //Contains download_url
209
  $upload_dir = wp_upload_dir();
210
+ add_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
211
  //Download $img_url
212
+ $temporary_file = download_url( $img_url );
213
+ remove_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
214
 
215
  if ( is_wp_error( $temporary_file ) ) {
216
  throw new Exception( 'Error: ' . $temporary_file->get_error_message() );
219
  $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . $filename; //Local name
220
  $local_img_url = $upload_dir['url'] . '/' . basename( $local_img_path );
221
 
222
+ //$gen_unique_fn = true;
223
 
224
  // to fix issue re-create new attachment
225
  if ( $check_file_existed ) {
259
  }
260
  }
261
 
262
+ // file exists, do not overwrite, generate unique file name
263
+ // this may causing of issue incorrect source of image in post content
264
+ if ( file_exists( $local_img_path ) ) {
265
  $local_img_path = dirname( $local_img_path ) . '/' . wp_unique_filename( dirname( $local_img_path ), basename( $local_img_path ) );
266
  $local_img_url = $upload_dir['url'] . '/' . basename( $local_img_path );
267
  }
526
  $new_post['post_content'] = str_replace( $lnkToReplace, $linkToReplaceWith, $new_post['post_content'] );
527
  }
528
  } catch ( Exception $e ) {
529
+ error_log( $e->getMessage() );
530
  }
531
  }
532
  }
class/class-mainwp-wordpress-seo.php CHANGED
@@ -57,9 +57,14 @@ class MainWP_Wordpress_SEO {
57
  if ( isset($_POST['file_url']) ) {
58
  $file_url = base64_decode( $_POST['file_url'] );
59
  $temporary_file = '';
 
 
 
60
  try {
61
  include_once( ABSPATH . 'wp-admin/includes/file.php' ); //Contains download_url
 
62
  $temporary_file = download_url( $file_url );
 
63
 
64
  if ( is_wp_error( $temporary_file ) ) {
65
  throw new Exception( 'Error: ' . $temporary_file->get_error_message() );
57
  if ( isset($_POST['file_url']) ) {
58
  $file_url = base64_decode( $_POST['file_url'] );
59
  $temporary_file = '';
60
+
61
+ global $mainWPChild;
62
+
63
  try {
64
  include_once( ABSPATH . 'wp-admin/includes/file.php' ); //Contains download_url
65
+ add_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
66
  $temporary_file = download_url( $file_url );
67
+ remove_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
68
 
69
  if ( is_wp_error( $temporary_file ) ) {
70
  throw new Exception( 'Error: ' . $temporary_file->get_error_message() );
mainwp-child.php CHANGED
@@ -6,7 +6,7 @@
6
  Author: MainWP
7
  Author URI: https://mainwp.com
8
  Text Domain: mainwp-child
9
- Version: 4.0.7
10
  */
11
  include_once( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'version.php' ); //Version information from wordpress
12
 
6
  Author: MainWP
7
  Author URI: https://mainwp.com
8
  Text Domain: mainwp-child
9
+ Version: 4.0.7.1
10
  */
11
  include_once( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'version.php' ); //Version information from wordpress
12
 
readme.txt CHANGED
@@ -5,9 +5,9 @@ Author: mainwp
5
  Author URI: https://mainwp.com
6
  Plugin URI: https://mainwp.com
7
  Requires at least: 3.6
8
- Tested up to: 5.4
9
  Requires PHP: 5.6
10
- Stable tag: 4.0.7
11
  License: GPLv3 or later
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
13
 
@@ -71,6 +71,18 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m
71
 
72
  == Changelog ==
73
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  = 4.0.7 - 2-25-20 =
75
  * Fixed: an issue with saving Bulk Setting Manager keys
76
  * Fixed: an issue with saving Wordfence extension settings
5
  Author URI: https://mainwp.com
6
  Plugin URI: https://mainwp.com
7
  Requires at least: 3.6
8
+ Tested up to: 5.4.1
9
  Requires PHP: 5.6
10
+ Stable tag: 4.0.7.1
11
  License: GPLv3 or later
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
13
 
71
 
72
  == Changelog ==
73
 
74
+ = 4.0.7.1 - 4-30-20 =
75
+ * Fixed: JSON decoding issues on specific setups
76
+ * Fixed: an issue with incorrect images URL
77
+ * Fixed: conflict with the Download Manager plugin
78
+ * Fixed: multiple PHP warnings
79
+ * Fixed: MySQL query compatibility problems
80
+ * Fixed: an issue with saving Wordfence settings
81
+ * Fixed: an issue with showing correct post and page creating time
82
+ * Fixed: an issue with displaying correct author in reports
83
+ * Added: support for WPVivid backups in the reporting system
84
+ * Preventative: security improvements
85
+
86
  = 4.0.7 - 2-25-20 =
87
  * Fixed: an issue with saving Bulk Setting Manager keys
88
  * Fixed: an issue with saving Wordfence extension settings