diff --git a/class/class-mainwp-child-back-up-buddy.php b/class/class-mainwp-child-back-up-buddy.php index 0da6ac8..3b4eb9d 100644 --- a/class/class-mainwp-child-back-up-buddy.php +++ b/class/class-mainwp-child-back-up-buddy.php @@ -23,10 +23,6 @@ class MainWP_Child_Back_Up_Buddy { return; } - if ( get_option( 'mainwp_backupbuddy_ext_enabled' ) !== 'Y' ) { - return; - } - add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 ); add_action( 'wp_ajax_mainwp_backupbuddy_download_archive', array( $this, 'download_archive' ) ); @@ -195,9 +191,6 @@ class MainWP_Child_Back_Up_Buddy { MainWP_Helper::write( array( 'error' => __( 'Please install the BackupBuddy plugin on the child site.', $this->plugin_translate ) ) ); } - if (get_option( 'mainwp_backupbuddy_ext_enabled' ) !== 'Y') - MainWP_Helper::update_option( 'mainwp_backupbuddy_ext_enabled', 'Y' ); - if ( ! class_exists( 'backupbuddy_core' ) ) { require_once( pb_backupbuddy::plugin_path() . '/classes/core.php' ); } @@ -757,7 +750,7 @@ class MainWP_Child_Back_Up_Buddy { $data['media_root'] = backupbuddy_core::get_media_root(); $data['additional_tables'] = $this->pb_additional_tables(); $data['abspath'] = ABSPATH; - + $getOverview = backupbuddy_api::getOverview(); $data['editsSinceLastBackup'] = $getOverview['editsSinceLastBackup'] ; diff --git a/class/class-mainwp-child-back-up-wordpress.php b/class/class-mainwp-child-back-up-wordpress.php index d6e0b9e..f705534 100644 --- a/class/class-mainwp-child-back-up-wordpress.php +++ b/class/class-mainwp-child-back-up-wordpress.php @@ -26,7 +26,7 @@ class MainWP_Child_Back_Up_Wordpress { if ( version_compare( phpversion(), '5.3', '<' ) ) { return; } - if ( get_option( 'mainwp_backupwordpress_ext_enabled' ) !== 'Y' ) return; + if (!$this->is_plugin_installed) return; add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) ); @@ -56,9 +56,6 @@ class MainWP_Child_Back_Up_Wordpress { MainWP_Helper::write( $information ); } - if (false === get_option('mainwp_backupwordpress_ext_enabled')) - MainWP_Helper::update_option( 'mainwp_backupwordpress_ext_enabled', 'Y' ); - if ( isset( $_POST['mwp_action'] ) ) { switch ( $_POST['mwp_action'] ) { case 'set_showhide': diff --git a/class/class-mainwp-child-back-wp-up.php b/class/class-mainwp-child-back-wp-up.php index 8a15427..71772ad 100644 --- a/class/class-mainwp-child-back-wp-up.php +++ b/class/class-mainwp-child-back-wp-up.php @@ -110,7 +110,7 @@ class MainWP_Child_Back_WP_Up { if ( ! isset( $_POST['action'] ) ) { $information = array( 'error' => __( 'Missing action.', $this->plugin_translate ) ); } else { - MainWP_Helper::update_option( 'mainwp_backwpup_ext_enabled', 'Y' ); + switch ( $_POST['action'] ) { case 'backwpup_update_settings': $information = $this->update_settings(); @@ -194,9 +194,6 @@ class MainWP_Child_Back_WP_Up { } public function init() { - if ( get_option( 'mainwp_backwpup_ext_enabled' ) !== 'Y' ) { - return; - } if (!$this->is_backwpup_installed) return; @@ -223,14 +220,44 @@ class MainWP_Child_Back_WP_Up { return; try { - MainWP_Helper::check_classes_exists(array('BackWPup')); - MainWP_Helper::check_methods('BackWPup', array( 'get_registered_destinations', 'get_destination' )); + MainWP_Helper::check_classes_exists(array('BackWPup_File', 'BackWPup_Job')); + MainWP_Helper::check_methods('BackWPup_File', array( 'get_absolute_path' )); + MainWP_Helper::check_methods('BackWPup_Job', array( 'read_logheader' )); - $destinations = BackWPup::get_registered_destinations(); - $jobdests = $this->get_destinations_list(); + $lasttime_logged = MainWP_Helper::get_lasttime_backup('backwpup'); - if ( !empty( $jobdests ) ) { + $log_folder = get_site_option( 'backwpup_cfg_logfolder' ); + $log_folder = BackWPup_File::get_absolute_path( $log_folder ); + $log_folder = untrailingslashit( $log_folder ); + + //load logs + $logfiles = array(); + if ( is_readable( $log_folder ) && $dir = opendir( $log_folder ) ) { + while ( ( $file = readdir( $dir ) ) !== FALSE ) { + $log_file = $log_folder . '/' . $file; + if ( is_file( $log_file ) && is_readable( $log_file ) && FALSE !== strpos( $file, 'backwpup_log_' ) && FALSE !== strpos( $file, '.html' ) ) { + $logfiles[] = $file; + } + } + closedir( $dir ); + } + + $log_items = array(); + foreach ( $logfiles as $mtime => $logfile ) { + $meta = BackWPup_Job::read_logheader( $log_folder . '/' . $logfile ); + if (!isset($meta['logtime']) || $meta['logtime'] < $lasttime_logged) + continue; + + if (isset($meta['errors']) && !empty($meta['errors'])) { + continue; // do not logging backups have errors + } + + $log_items[$mtime] = $meta; + $log_items[$mtime]['file'] = $logfile; + } + + if ( !empty( $log_items ) ) { $job_types = array( 'DBDUMP' => __('Database backup', 'mainwp-child'), 'FILE' => __('File backup', 'mainwp-child'), @@ -239,41 +266,36 @@ class MainWP_Child_Back_WP_Up { 'DBCHECK' => __('Check database tables', 'mainwp-child') ); - foreach ($jobdests as $jobdest) { - list( $jobid, $dest ) = explode( '_', $jobdest ); - if ( ! empty( $destinations[ $dest ][ 'class' ] ) ) { + $new_lasttime_logged = $lasttime_logged; - $job_job_types = BackWPup_Option::get( $jobid, 'type' ); - - $backup_type = ''; - foreach($job_job_types as $typeid) { - if (isset( $job_types[$typeid] )) { - $backup_type .= ' + ' . $job_types[$typeid]; - } - } - if (empty($backup_type)) - $backup_type = 'BackWPup'; - else { - $backup_type = ltrim($backup_type, ' + '); - } - - $dest_object = BackWPup::get_destination( $dest ); - $items = $dest_object->file_get_list( $jobdest ); - //if no items brake - if ( $items ) { - foreach ( $items as $ma ) { - if (isset($ma['time'])) { - $backup_time = $ma[ "time" ]; - $message = 'BackWPup backup finished (' . $backup_type . ')'; - $destination = "N/A"; - if (!empty($backup_time)) { - do_action( 'mainwp_backwpup_backup', $message, $backup_type, $backup_time ); - MainWP_Helper::update_lasttime_backup( 'backwpup', $backup_time ); // to support backup before update feature - } - } - } + foreach ($log_items as $log) { + $backup_time = $log[ "logtime" ]; + if ($backup_time < $lasttime_logged) { + // small than last backup time then skip + continue; + } + $job_job_types = explode('+', $log['type']); + $backup_type = ''; + foreach($job_job_types as $typeid) { + if (isset( $job_types[$typeid] )) { + $backup_type .= ' + ' . $job_types[$typeid]; } } + + if (empty($backup_type)) { + continue; + } else { + $backup_type = ltrim($backup_type, ' + '); + } + $message = 'BackWPup backup finished (' . $backup_type . ')'; + do_action( 'mainwp_backwpup_backup', $message, $backup_type, $backup_time ); + + if ($new_lasttime_logged < $backup_time) + $new_lasttime_logged = $backup_time; + } + + if ($new_lasttime_logged > $lasttime_logged ) { + MainWP_Helper::update_lasttime_backup( 'backwpup', $new_lasttime_logged ); // to support backup before update feature } } } catch (Exception $ex) { diff --git a/class/class-mainwp-child-ithemes-security.php b/class/class-mainwp-child-ithemes-security.php index f7268a3..609eb52 100644 --- a/class/class-mainwp-child-ithemes-security.php +++ b/class/class-mainwp-child-ithemes-security.php @@ -47,7 +47,7 @@ class MainWP_Child_iThemes_Security { global $mainwp_itsec_modules_path; $mainwp_itsec_modules_path = ITSEC_Core::get_core_dir() . '/modules/'; - MainWP_Helper::update_option( 'mainwp_ithemes_ext_enabled', 'Y', 'yes' ); + if ( isset( $_POST['mwp_action'] ) ) { switch ( $_POST['mwp_action'] ) { @@ -116,9 +116,8 @@ class MainWP_Child_iThemes_Security { } public function ithemes_init() { - if ( get_option( 'mainwp_ithemes_ext_enabled' ) !== 'Y' ) { + if (!$this->is_plugin_installed) return; - } if ( get_option( 'mainwp_ithemes_hide_plugin' ) === 'hide' ) { add_filter( 'all_plugins', array( $this, 'all_plugins' ) ); diff --git a/class/class-mainwp-child-pagespeed.php b/class/class-mainwp-child-pagespeed.php index e06a553..a87093d 100644 --- a/class/class-mainwp-child-pagespeed.php +++ b/class/class-mainwp-child-pagespeed.php @@ -18,12 +18,12 @@ class MainWP_Child_Pagespeed { if ( is_plugin_active( 'google-pagespeed-insights/google-pagespeed-insights.php' ) ) { $this->is_plugin_installed = true; } - + if (!$this->is_plugin_installed) return; - + add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 ); - + add_action( 'mainwp_child_deactivation', array( $this, 'child_deactivation' ) ); } @@ -34,7 +34,7 @@ class MainWP_Child_Pagespeed { MainWP_Helper::write( $information ); } if ( isset( $_POST['mwp_action'] ) ) { - MainWP_Helper::update_option('mainwp_pagespeed_ext_enabled', 'Y', 'yes'); + switch ( $_POST['mwp_action'] ) { case 'save_settings': $information = $this->save_settings(); @@ -60,13 +60,12 @@ class MainWP_Child_Pagespeed { } public function init() { - if ( get_option( 'mainwp_pagespeed_ext_enabled' ) !== 'Y' ) { - return; - } - + if (!$this->is_plugin_installed) + return; + if ( get_option( 'mainwp_pagespeed_hide_plugin' ) === 'hide' ) { add_filter( 'all_plugins', array( $this, 'hide_plugin' ) ); - add_action('admin_menu', array($this, 'hide_menu'), 999); + add_action('admin_menu', array($this, 'hide_menu'), 999); } $this->init_cron(); } @@ -261,14 +260,14 @@ class MainWP_Child_Pagespeed { return $information; } - public function syncOthersData( $information, $data = array() ) { - if ( isset( $data['syncPageSpeedData'] ) && $data['syncPageSpeedData'] ) { + public function syncOthersData( $information, $data = array() ) { + if ( isset( $data['syncPageSpeedData'] ) && $data['syncPageSpeedData'] ) { try{ $information['syncPageSpeedData'] = $this->get_sync_data(); } catch(Exception $e) { - + } - } + } return $information; } // ok diff --git a/class/class-mainwp-child-staging.php b/class/class-mainwp-child-staging.php index 3666be2..a1f22df 100644 --- a/class/class-mainwp-child-staging.php +++ b/class/class-mainwp-child-staging.php @@ -1,10 +1,10 @@ is_plugin_installed = true; - } - + $this->is_plugin_installed = true; + } + if (!$this->is_plugin_installed) - return; - - add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 ); + return; + + add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 ); } - - public function init() { - if ( get_option( 'mainwp_wp_staging_ext_enabled' ) !== 'Y' ) - return; - - if (!$this->is_plugin_installed) - return; - + + public function init() { + if ( get_option( 'mainwp_wp_staging_ext_enabled' ) !== 'Y' ) + return; + + if (!$this->is_plugin_installed) + return; + if ( get_option( 'mainwp_wp_staging_hide_plugin' ) === 'hide' ) { add_filter( 'all_plugins', array( $this, 'all_plugins' ) ); add_action( 'admin_menu', array( $this, 'remove_menu' ) ); @@ -39,44 +39,44 @@ class MainWP_Child_Staging { } } - public function syncOthersData( $information, $data = array() ) { - if ( isset( $data['syncWPStaging'] ) && $data['syncWPStaging'] ) { + public function syncOthersData( $information, $data = array() ) { + if ( isset( $data['syncWPStaging'] ) && $data['syncWPStaging'] ) { try{ $information['syncWPStaging'] = $this->get_sync_data(); } catch(Exception $e) { // do not exit } - } + } return $information; } // ok - public function get_sync_data() { + public function get_sync_data() { return $this->get_overview(); } - + public function action() { if (!$this->is_plugin_installed) { MainWP_Helper::write( array('error' => 'Please install WP Staging plugin on child website') ); } - + if (!class_exists( 'WPStaging\WPStaging' )){ require_once WPSTG_PLUGIN_DIR . "apps/Core/WPStaging.php"; } \WPStaging\WPStaging::getInstance(); - $information = array(); + $information = array(); if (get_option( 'mainwp_wp_staging_ext_enabled' ) !== 'Y') { - MainWP_Helper::update_option( 'mainwp_wp_staging_ext_enabled', 'Y', 'yes' ); + MainWP_Helper::update_option( 'mainwp_wp_staging_ext_enabled', 'Y', 'yes' ); } - + if ( isset( $_POST['mwp_action'] ) ) { switch ( $_POST['mwp_action'] ) { case 'set_showhide': $information = $this->set_showhide(); - break; + break; case 'save_settings': $information = $this->save_settings(); - break; + break; case 'get_overview': $information = $this->get_overview(); break; @@ -106,7 +106,7 @@ class MainWP_Child_Staging { break; case 'clone_finish': $information = $this->ajaxFinish(); - break; + break; case 'delete_confirmation': $information = $this->ajaxDeleteConfirmation(); break; @@ -121,35 +121,37 @@ class MainWP_Child_Staging { break; case 'cancel_update': $information = $this->ajaxCancelUpdate(); - break; + break; } } MainWP_Helper::write( $information ); - } - + } + function set_showhide() { $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : ''; MainWP_Helper::update_option( 'mainwp_wp_staging_hide_plugin', $hide, 'yes' ); $information['result'] = 'SUCCESS'; return $information; } - + function save_settings() { - $settings = $_POST['settings']; + $settings = $_POST['settings']; $filters = array( 'queryLimit', 'fileLimit', 'batchSize', 'cpuLoad', 'disableAdminLogin', - 'wpSubDirectory', + 'querySRLimit', + 'maxFileSize', + //'wpSubDirectory', // removed 'debugMode', 'unInstallOnDelete', 'checkDirectorySize', 'optimizer', - 'loginSlug' + //'loginSlug' // removed ); - + $save_fields = array(); foreach($filters as $field) { if (isset($settings[$field])) { @@ -158,15 +160,15 @@ class MainWP_Child_Staging { } update_option('wpstg_settings', $save_fields ); return array('result' => 'success'); - } - - public function get_overview() { + } + + public function get_overview() { $return = array( 'availableClones' => get_option( "wpstg_existing_clones_beta", array()) ); return $return; } - + public function get_scan() { // Scan $scan = new WPStaging\Backend\Modules\Jobs\Scan(); @@ -178,12 +180,12 @@ class MainWP_Child_Staging { $return = array( 'options' => serialize($options), 'directoryListing' => $scan->directoryListing(), - 'prefix' => WPStaging\WPStaging::getTablePrefix() + 'prefix' => WPStaging\WPStaging::getTablePrefix() ); return $return; } - + public function ajaxCheckCloneName() { $cloneName = sanitize_key( $_POST["cloneID"] ); $cloneNameLength = strlen( $cloneName ); @@ -204,23 +206,23 @@ class MainWP_Child_Staging { return array("status" => "success"); } - + public function ajaxStartClone() { $this->url = ''; // to fix warning $cloning = new WPStaging\Backend\Modules\Jobs\Cloning(); - - + + if( !$cloning->save() ) { return; } - + ob_start(); require_once WPSTG_PLUGIN_DIR . "apps/Backend/views/clone/ajax/start.php"; $result = ob_get_clean(); return $result; } - + public function ajaxCloneDatabase() { $cloning = new WPStaging\Backend\Modules\Jobs\Cloning(); @@ -232,7 +234,7 @@ class MainWP_Child_Staging { * Ajax Prepare Directories (get listing of files) */ public function ajaxPrepareDirectories() { - + $cloning = new WPStaging\Backend\Modules\Jobs\Cloning(); return $cloning->start(); @@ -265,7 +267,7 @@ class MainWP_Child_Staging { $this->url = ''; // to fix warning $return = $cloning->start(); $return->blogInfoName = get_bloginfo("name"); - + return $return; } @@ -276,12 +278,12 @@ class MainWP_Child_Staging { $delete = new WPStaging\Backend\Modules\Jobs\Delete(); $delete->setData(); - $clone = $delete->getClone(); + $clone = $delete->getClone(); $result = array( 'clone' => $clone, 'deleteTables' => $delete->getTables() - ); - return $result; + ); + return $result; } /** @@ -300,15 +302,15 @@ class MainWP_Child_Staging { $cancel = new WPStaging\Backend\Modules\Jobs\Cancel(); return $cancel->start(); } - - public function ajaxCancelUpdate() { + + public function ajaxCancelUpdate() { $cancel = new WPStaging\Backend\Modules\Jobs\CancelUpdate(); return $cancel->start(); } public function ajaxUpdateProcess() { - - $cloning = new WPStaging\Backend\Modules\Jobs\Updating(); + + $cloning = new WPStaging\Backend\Modules\Jobs\Updating(); if( !$cloning->save() ) { return; @@ -317,13 +319,13 @@ class MainWP_Child_Staging { ob_start(); require_once WPSTG_PLUGIN_DIR . "apps/Backend/views/clone/ajax/update.php"; $result = ob_get_clean(); - return $result; + return $result; } - - public function ajaxCheckFreeSpace() { + + public function ajaxCheckFreeSpace() { return $this->hasFreeDiskSpace(); } - + // from wp-staging plugin public function hasFreeDiskSpace() { if( !function_exists( "disk_free_space" ) ) { @@ -335,15 +337,15 @@ class MainWP_Child_Staging { 'freespace' => false, 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH)) ); - return $data; + return $data; } $data = array( 'freespace' => $this->formatSize($freeSpace), 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH)) ); - return $data; + return $data; } - + // from wp-staging plugin function getDirectorySizeInclSubdirs( $dir ) { $size = 0; @@ -352,7 +354,7 @@ class MainWP_Child_Staging { } return $size; } - + // from wp-staging plugin public function formatSize($bytes, $precision = 2) { @@ -369,8 +371,8 @@ class MainWP_Child_Staging { return round($pow, $precision) . ' ' . $units[(int) floor($base)]; } - - + + public function all_plugins( $plugins ) { foreach ( $plugins as $key => $value ) { $plugin_slug = basename( $key, '.php' ); @@ -390,7 +392,7 @@ class MainWP_Child_Staging { exit(); } } - + function remove_update_nag( $value ) { if ( isset( $_POST['mainwpsignature'] ) ) { return $value; diff --git a/class/class-mainwp-child-timecapsule.php b/class/class-mainwp-child-timecapsule.php index 27e3532..67e0e0c 100644 --- a/class/class-mainwp-child-timecapsule.php +++ b/class/class-mainwp-child-timecapsule.php @@ -531,7 +531,7 @@ function get_sibling_files_callback_wptc() { $detailed = $this->get_activity_log($sub_records); if (isset($load_more) && $load_more) { - $detailed .= 'Load more'; + $detailed .= 'Load more'; } return array( 'result' => $detailed); diff --git a/class/class-mainwp-child-updraft-plus-backups.php b/class/class-mainwp-child-updraft-plus-backups.php index 91a4382..42bac13 100644 --- a/class/class-mainwp-child-updraft-plus-backups.php +++ b/class/class-mainwp-child-updraft-plus-backups.php @@ -75,11 +75,6 @@ class MainWP_Child_Updraft_Plus_Backups { } if ( isset( $_POST['mwp_action'] ) ) { - - if ( get_option( 'mainwp_updraftplus_ext_enabled' ) !== 'Y' ) { - MainWP_Helper::update_option( 'mainwp_updraftplus_ext_enabled', 'Y', 'yes' ); - } - try { switch ( $_POST['mwp_action'] ) { case 'set_showhide': @@ -3071,14 +3066,19 @@ class MainWP_Child_Updraft_Plus_Backups { $entities = ''; $non = $backup['nonce']; - $rawbackup = "

$esc_pretty_date ($key)

" . esc_attr( print_r( $backup, true ) ); - if ( ! empty( $non ) ) { - $jd = $updraftplus->jobdata_getarray( $non ); - if ( ! empty( $jd ) && is_array( $jd ) ) { - $rawbackup .= '

' . esc_attr( print_r( $jd, true ) ); - } - } - $rawbackup .= '

'; + + +// $rawbackup = "

$esc_pretty_date ($key)

" . esc_attr( print_r( $backup, true ) ); +// if ( ! empty( $non ) ) { +// $jd = $updraftplus->jobdata_getarray( $non ); +// if ( ! empty( $jd ) && is_array( $jd ) ) { +// $rawbackup .= '

' . esc_attr( print_r( $jd, true ) ); +// } +// } +// $rawbackup .= '

'; + + // to fix + $rawbackup = '' ; //$updraftplus_admin->raw_backup_info($backup_history, $key, $non); $jobdata = $updraftplus->jobdata_getarray( $non ); @@ -3908,9 +3908,8 @@ ENDHERE; } public function updraftplus_init() { - if ( get_option( 'mainwp_updraftplus_ext_enabled' ) !== 'Y' ) { - return; - } + if (!$this->is_plugin_installed) + return; if ( get_option( 'mainwp_updraftplus_hide_plugin' ) === 'hide' ) { add_filter( 'all_plugins', array( $this, 'all_plugins' ) ); diff --git a/class/class-mainwp-child-wordfence.php b/class/class-mainwp-child-wordfence.php index d2a3040..badb9d7 100644 --- a/class/class-mainwp-child-wordfence.php +++ b/class/class-mainwp-child-wordfence.php @@ -1,10 +1,10 @@ start_scan(); @@ -227,25 +227,22 @@ class MainWP_Child_Wordfence { break; case 'killScan': $information = $this->killScan(); - break; + break; case 'set_showhide': $information = $this->set_showhide(); break; case 'get_log': $information = $this->get_log(); - break; + break; case 'update_log': $information = $this->update_log(); break; - case 'get_summary': - $information = $this->get_summary(); - break; case 'load_issues': // not used in from version 2.0 of WF ext $information = $this->load_issues(); break; case 'loadIssues': $information = $this->ajax_loadIssues_callback(); - break; + break; case 'load_wafData': $information = $this->load_wafData(); break; @@ -266,7 +263,7 @@ class MainWP_Child_Wordfence { break; case 'bulkOperation': // new $information = $this->bulkOperation(); - break; + break; case 'delete_file': $information = $this->delete_file(); break; @@ -281,10 +278,10 @@ class MainWP_Child_Wordfence { break; case 'saveOptions': $information = $this->saveOptions(); - break; + break; case 'recentTraffic': $information = $this->recentTraffic(); - break; + break; case 'ticker': $information = $this->ticker(); break; @@ -296,10 +293,10 @@ class MainWP_Child_Wordfence { break; case 'whois': $information = $this->whois(); - break; - case 'createBlock': // new version blockIP, blockIPUARange + break; + case 'createBlock': // new version blockIP, blockIPUARange $information = $this->ajax_createBlock_callback(); - break; + break; case 'getBlocks': $information = $this->ajax_getBlocks_callback(); break; @@ -308,7 +305,7 @@ class MainWP_Child_Wordfence { break; case 'makePermanentBlocks': $information = $this->ajax_makePermanentBlocks_callback(); - break; + break; case 'unblock_ip': $information = $this->unblock_ip(); break; @@ -359,7 +356,7 @@ class MainWP_Child_Wordfence { break; case 'update_waf_rules_new': $information = $this->updateWAFRules_New(); - break; + break; case 'save_debugging_config': $information = $this->save_debugging_config(); break; @@ -368,10 +365,10 @@ class MainWP_Child_Wordfence { break; case 'white_list_waf': $information = $this->whitelistWAFParamKey(); - break; + break; case 'hide_file_htaccess': $information = $this->hideFileHtaccess(); - break; + break; case 'fix_fpd': $information = $this->fixFPD(); break; @@ -383,7 +380,7 @@ class MainWP_Child_Wordfence { break; case 'misconfigured_howget_ips_choice': $information = $this->misconfiguredHowGetIPsChoice(); - break; + break; case 'delete_admin_user': $information = $this->deleteAdminUser(); break; @@ -401,7 +398,7 @@ class MainWP_Child_Wordfence { break; case 'unblock_range': $information = $this->unblockRange(); - break; + break; case 'block_ip_ua_range': $information = $this->blockIPUARange(); break; @@ -419,7 +416,7 @@ class MainWP_Child_Wordfence { break; case 'whitelist_bulk_disable': $information = $this->whitelistBulkDisable(); - break; + break; case 'update_config': $information = $this->updateConfig(); break; @@ -429,9 +426,9 @@ class MainWP_Child_Wordfence { } } MainWP_Helper::write( $information ); - } - - + } + + public static function getSectionSettings($section) { $general_opts = array( 'scheduleScan', @@ -473,9 +470,9 @@ class MainWP_Child_Wordfence { 'email_summary_dashboard_widget_enabled', 'other_noAnonMemberComments', 'other_scanComments', - 'advancedCommentScanning' // paid + 'advancedCommentScanning' // paid ); - + $traffic_opts = array( 'liveTrafficEnabled', 'liveTraf_ignorePublishers', @@ -486,7 +483,7 @@ class MainWP_Child_Wordfence { 'liveTraf_maxRows', 'displayTopLevelLiveTraffic' ); - + $firewall_opts = array( 'disableWAFIPBlocking', 'whitelisted', @@ -516,10 +513,10 @@ class MainWP_Child_Wordfence { 'loginSec_lockoutMins', 'loginSec_lockInvalidUsers', 'loginSec_breachPasswds_enabled', - 'loginSec_breachPasswds', + 'loginSec_breachPasswds', 'loginSec_userBlacklist', 'loginSec_strongPasswds_enabled', - 'loginSec_strongPasswds', + 'loginSec_strongPasswds', 'loginSec_maskLoginErrors', 'loginSec_blockAdminReg', 'loginSec_disableAuthorScan', @@ -528,9 +525,9 @@ class MainWP_Child_Wordfence { 'other_WFNet', 'wafStatus', 'learningModeGracePeriodEnabled', - 'learningModeGracePeriod' + 'learningModeGracePeriod' ); - + $scan_opts = array( 'scansEnabled_checkGSB', //paid 'spamvertizeCheck', //paid @@ -573,13 +570,13 @@ class MainWP_Child_Wordfence { 'ssl_verify', 'betaThreatDefenseFeed' ); - + $blocking_opts = array( - 'displayTopLevelBlocking', + 'displayTopLevelBlocking', ); - + $options = array(); - + switch($section) { case self::OPTIONS_TYPE_GLOBAL: $options = $general_opts; @@ -591,7 +588,7 @@ class MainWP_Child_Wordfence { $options = $firewall_opts; break; case self::OPTIONS_TYPE_SCANNER: - $options = $scan_opts; + $options = $scan_opts; break; case self::OPTIONS_TYPE_DIAGNOSTICS: $options = $diagnostics_opts; @@ -602,37 +599,37 @@ class MainWP_Child_Wordfence { case self::OPTIONS_TYPE_ALL: $options = array_merge($general_opts, $traffic_opts, $firewall_opts, $scan_opts, $diagnostics_opts, $blocking_opts); break; - } + } return $options; } - - - private function start_scan() { + + + private function start_scan() { $information = wordfence::ajax_scan_callback(); - if ( is_array($information) && isset($information['ok']) ) + if ( is_array($information) && isset($information['ok']) ) $information['result'] = 'SUCCESS'; - + return $information; } - private function kill_scan() { + private function kill_scan() { wordfence::status(1, 'info', "Scan kill request received."); wordfence::status(10, 'info', "SUM_KILLED:A request was received to kill the previous scan."); wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock wfScanEngine::requestKill(); return array( 'ok' => 1, - ); - } - - private function requestScan() { - return wordfence::ajax_scan_callback(); + ); } - private function killScan() { - return wordfence::ajax_killScan_callback(); + private function requestScan() { + return wordfence::ajax_scan_callback(); } - + + private function killScan() { + return wordfence::ajax_killScan_callback(); + } + function set_showhide() { $hide = isset( $_POST['showhide'] ) && ( $_POST['showhide'] === 'hide' ) ? 'hide' : ''; MainWP_Helper::update_option( 'mainwp_wordfence_hide_plugin', $hide, 'yes' ); @@ -642,7 +639,7 @@ class MainWP_Child_Wordfence { } public function wordfence_init() { - if ( get_option( 'mainwp_wordfence_ext_enabled' ) !== 'Y' ) return; + if ( ! $this->is_wordfence_installed ) return; add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) ); @@ -728,7 +725,7 @@ class MainWP_Child_Wordfence { public function wfc_cron_scan() { if ( ! class_exists( 'wordfence' ) || ! class_exists( 'wfScanEngine' ) ) { return; - } + } $this->start_scan(); } @@ -750,9 +747,9 @@ class MainWP_Child_Wordfence { public function get_log() { $information = array(); $wfLog = wordfence::getLog(); - if ( $wfLog ) { + if ( $wfLog ) { $information['events'] = $wfLog->getStatusEvents( 0 ); - + if (method_exists($wfLog, 'getSummaryEvents')) { $information['summary'] = $wfLog->getSummaryEvents(); } else { @@ -764,22 +761,23 @@ class MainWP_Child_Wordfence { return $information; } - + public function update_log() { return wordfence::ajax_activityLogUpdate_callback(); } + // not used public function load_issues() { $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0; $limit = isset($_POST['limit']) ? intval($_POST['limit']) : WORDFENCE_SCAN_ISSUES_PER_PAGE; - + $i = new wfIssues(); $iss = $i->getIssues($offset, $limit); $counts = $i->getIssueCounts(); - + return array( 'issuesLists' => $iss, - 'issueCounts' => $counts, + 'issueCounts' => $counts, 'lastScanCompleted' => wfConfig::get( 'lastScanCompleted' ), 'apiKey' => wfConfig::get( 'apiKey' ), 'isPaid' => wfConfig::get('isPaid'), @@ -791,37 +789,38 @@ class MainWP_Child_Wordfence { 'wafData' => $this->_getWAFData() ); } - + public static function ajax_loadIssues_callback(){ $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0; $limit = isset($_POST['limit']) ? intval($_POST['limit']) : WORDFENCE_SCAN_ISSUES_PER_PAGE; - + $i = new wfIssues(); $iss = $i->getIssues($offset, $limit); $counts = $i->getIssueCounts(); $return = array( 'issuesLists' => $iss, 'issueCounts' => $counts, - 'lastScanCompleted' => wfConfig::get('lastScanCompleted'), + 'lastScanCompleted' => wfConfig::get('lastScanCompleted'), 'apiKey' => wfConfig::get( 'apiKey' ), 'isPaid' => wfConfig::get('isPaid'), - 'lastscan_timestamp' => MainWP_Child_Wordfence::Instance()->get_lastscan(), + 'lastscan_timestamp' => MainWP_Child_Wordfence::Instance()->get_lastscan(), 'todayAttBlocked' => MainWP_Child_Wordfence::Instance()->count_attacks_blocked(1), 'weekAttBlocked' => MainWP_Child_Wordfence::Instance()->count_attacks_blocked(7), - 'monthAttBlocked' => MainWP_Child_Wordfence::Instance()->count_attacks_blocked(30), - ); + 'monthAttBlocked' => MainWP_Child_Wordfence::Instance()->count_attacks_blocked(30), + 'issueCount' => $i->getIssueCount(), + ); return $return; } - + public function load_wafData() { - - $return = array( + + $return = array( 'wafData' => $this->_getWAFData(), - 'ip' => wfUtils::getIP(), + 'ip' => wfUtils::getIP(), 'ajaxWatcherDisabled_front' => (bool)wfConfig::get('ajaxWatcherDisabled_front'), - 'ajaxWatcherDisabled_admin' => (bool)wfConfig::get('ajaxWatcherDisabled_admin') + 'ajaxWatcherDisabled_admin' => (bool)wfConfig::get('ajaxWatcherDisabled_admin') ); - + if (class_exists('wfFirewall')) { $firewall = new wfFirewall(); $return['isSubDirectoryInstallation'] = $firewall->isSubDirectoryInstallation(); @@ -874,15 +873,15 @@ SQL } $wfIssues->updateIssue($issueID, $status); wfScanEngine::refreshScanNotification($wfIssues); - + $counts = $wfIssues->getIssueCounts(); return array( 'ok' => 1, 'issueCounts' => $counts, ); } - - function update_issues_status() { + + function update_issues_status() { $wfIssues = new wfIssues(); $status = $_POST['status']; $issueID = $_POST['id']; @@ -994,8 +993,8 @@ SQL function bulkOperation() { return wordfence::ajax_bulkOperation_callback(); - } - + } + function delete_file() { $issueID = $_POST['issueID']; $wfIssues = new wfIssues(); @@ -1096,25 +1095,25 @@ SQL } return $res; } - - function save_settings_new() - { + + function save_settings_new() + { if (isset($_POST['encrypted'])) - $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost + $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost else { $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) ); } - + $section = isset($_POST['savingSection']) ? $_POST['savingSection'] : ''; $saving_opts = self::getSectionSettings($section); - + $result = array(); - + if ( is_array( $settings ) && count( $settings ) > 0 && count($saving_opts) > 0 ) { - + $reload = ''; $opts = $settings; - + // if saving then validate data if (in_array('liveTraf_ignoreUsers', $saving_opts)) { $validUsers = array(); @@ -1142,7 +1141,7 @@ SQL } } - // if saving then validate data + // if saving then validate data if (in_array('other_WFNet', $saving_opts)) { if ( ! $opts['other_WFNet'] ) { $wfdb = new wfDB(); @@ -1153,15 +1152,15 @@ SQL } $regenerateHtaccess = false; - // if saving then validate data + // if saving then validate data if (in_array('bannedURLs', $saving_opts)) { if ( wfConfig::get( 'bannedURLs', false ) !== $opts['bannedURLs'] ) { $regenerateHtaccess = true; } - } - //error_log(print_r($opts, true)); + } + //error_log(print_r($opts, true)); // $to_fix_boolean_values = array( -// 'scansEnabled_checkGSB', +// 'scansEnabled_checkGSB', // 'spamvertizeCheck', // 'checkSpamIP', // 'scansEnabled_checkHowGetIPs', @@ -1186,29 +1185,29 @@ SQL // 'scansEnabled_scanImages', // 'scansEnabled_highSense', // 'scheduledScansEnabled', -// 'lowResourceScansEnabled', +// 'lowResourceScansEnabled', // ); -// +// // save the settings - foreach ( $opts as $key => $val ) { + foreach ( $opts as $key => $val ) { // check saving section fields if ( in_array( $key, $saving_opts ) ) { if ( 'apiKey' == $key ) { //Don't save API key yet continue; - } + } if (in_array( $key, self::$firewall_options_filter ) ) { wfWAF::getInstance()->getStorageEngine()->setConfig($key, $val); - } else { - wfConfig::set( $key, $val ); // save it - } - } + } else { + wfConfig::set( $key, $val ); // save it + } + } } - + if ( $regenerateHtaccess && ( wfConfig::get('cacheType') == 'falcon' ) ) { wfCache::addHtaccessCode('add'); } - - // if saving then validate data + + // if saving then validate data if (in_array('autoUpdate', $saving_opts)) { if ( '1' === $opts['autoUpdate'] ) { wfConfig::enableAutoUpdate(); @@ -1216,8 +1215,8 @@ SQL wfConfig::disableAutoUpdate(); } } - - // if saving then validate data + + // if saving then validate data if (in_array('disableCodeExecutionUploads', $saving_opts)) { if (isset($opts['disableCodeExecutionUploads'])) { try { @@ -1232,8 +1231,8 @@ SQL } } - // if saving then validate data - if (in_array('email_summary_enabled', $saving_opts)) { + // if saving then validate data + if (in_array('email_summary_enabled', $saving_opts)) { if (isset($opts['email_summary_enabled'])) { if ( ! empty( $opts['email_summary_enabled'] ) ) { wfConfig::set( 'email_summary_enabled', 1 ); @@ -1246,9 +1245,9 @@ SQL } } } - - // if saving then validate data - if (in_array('scheduleScan', $saving_opts)) { + + // if saving then validate data + if (in_array('scheduleScan', $saving_opts)) { $sch = isset( $opts['scheduleScan'] ) ? $opts['scheduleScan'] : ''; if ( get_option( 'mainwp_child_wordfence_cron_time' ) !== $sch ) { update_option( 'mainwp_child_wordfence_cron_time', $sch ); @@ -1258,17 +1257,17 @@ SQL } } } - + // Finished saving settings ///////////////////// - - + + $result['cacheType'] = wfConfig::get( 'cacheType' ); $result['paidKeyMsg'] = false; - + // if saving then validate data - if (in_array('apiKey', $saving_opts)) { - $apiKey = trim( $_POST['apiKey'] ); + if (in_array('apiKey', $saving_opts)) { + $apiKey = trim( $_POST['apiKey'] ); if ( ! $apiKey ) { //Empty API key (after trim above), then try to get one. $api = new wfAPI( '', wfUtils::getWPVersion() ); try { @@ -1319,26 +1318,26 @@ SQL } } } - + $result['ok'] = 1; $result['reload'] = $reload; - + return $result; } else { $result['error'] = 'Empty settings'; - } - + } + return $result; - } - - - public static function recentTraffic(){ - return wordfence::ajax_recentTraffic_callback(); + } + + + public static function recentTraffic(){ + return wordfence::ajax_recentTraffic_callback(); } - + function save_setting() { if (isset($_POST['encrypted'])) - $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost + $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost else { $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) ); } @@ -1433,7 +1432,7 @@ SQL wp_unschedule_event( $sched, 'mainwp_child_wordfence_cron_scan' ); } } - + $result['cacheType'] = wfConfig::get( 'cacheType' ); $result['paidKeyMsg'] = false; $apiKey = trim( $_POST['apiKey'] ); @@ -1488,7 +1487,7 @@ SQL } $result['ok'] = 1; $result['reload'] = $reload; - + return $result; } } @@ -1558,15 +1557,15 @@ SQL $p = $wpdb->base_prefix; $serverTime = $wfdb->querySingle( 'select unix_timestamp()' ); - + $jsonData = array( 'serverTime' => $serverTime, 'serverMicrotime' => microtime(true), 'msg' => $wfdb->querySingle( "select msg from $p" . 'wfStatus where level < 3 order by ctime desc limit 1' ), ); - + $events = array(); - $alsoGet = $_POST['alsoGet']; + $alsoGet = $_POST['alsoGet']; if ( preg_match( '/^logList_(404|hit|human|ruser|crawler|gCrawler|loginLogout)$/', $alsoGet, $m ) ) { $type = $m[1]; $newestEventTime = $_POST['otherParams']; @@ -1587,7 +1586,7 @@ SQL if (isset($results['sql'])) { $jsonData['sql'] = $results['sql']; } - } + } $jsonData['events'] = $events; $jsonData['alsoGet'] = $alsoGet; //send it back so we don't load data if panel has changed $jsonData['cacheType'] = wfConfig::get( 'cacheType' ); @@ -1597,116 +1596,116 @@ SQL public static function loadLiveTraffic() { $wfdb = new wfDB(); $serverTime = $wfdb->querySingle( 'select unix_timestamp()' ); - $return = wordfence::ajax_loadLiveTraffic_callback(); + $return = wordfence::ajax_loadLiveTraffic_callback(); $return['serverTime'] = $serverTime; $return['serverMicrotime'] = microtime(true); - return $return; + return $return; } - function whitelistWAFParamKey() { + function whitelistWAFParamKey() { $return = wordfence::ajax_whitelistWAFParamKey_callback(); - return $return; + return $return; } - function hideFileHtaccess() { + function hideFileHtaccess() { $return = wordfence::ajax_hideFileHtaccess_callback(); - return $return; - } - + return $return; + } + public static function fixFPD(){ $return = wordfence::ajax_fixFPD_callback(); - return $return; + return $return; } - + public static function disableDirectoryListing() { $return = wordfence::ajax_disableDirectoryListing_callback(); - return $return; - } - + return $return; + } + public static function deleteDatabaseOption() { $return = wordfence::ajax_deleteDatabaseOption_callback(); - return $return; - } + return $return; + } public static function misconfiguredHowGetIPsChoice() { $return = wordfence::ajax_misconfiguredHowGetIPsChoice_callback(); return $return; } - + public static function deleteAdminUser() { $return = wordfence::ajax_deleteAdminUser_callback(); - return $return; - } - + return $return; + } + public static function revokeAdminUser() { $return = wordfence::ajax_revokeAdminUser_callback(); - return $return; + return $return; } public static function clearAllBlocked() { $return = wordfence::ajax_clearAllBlocked_callback(); - return $return; - } - + return $return; + } + public static function permanentlyBlockAllIPs() { $return = wordfence::ajax_permanentlyBlockAllIPs_callback(); - return $return; - } - + return $return; + } + public static function unlockOutIP() { $return = wordfence::ajax_unlockOutIP_callback(); - return $return; - } - + return $return; + } + public static function unblockRange() { $return = wordfence::ajax_unblockRange_callback(); - return $return; - } - + return $return; + } + public static function blockIPUARange() { $return = wordfence::ajax_blockIPUARange_callback(); - return $return; - } - + return $return; + } + public static function loadBlockRanges() { $return = wordfence::ajax_loadBlockRanges_callback(); - return $return; + return $return; } - - public static function saveWAFConfig() { + + public static function saveWAFConfig() { $return = wordfence::ajax_saveWAFConfig_callback(); - if (is_array($return) && isset($return['data'])) { + if (is_array($return) && isset($return['data'])) { $return['learningModeGracePeriod'] = wfWAF::getInstance()->getStorageEngine()->getConfig('learningModeGracePeriod'); } - return $return; - } - + return $return; + } + public static function whitelistBulkDelete() { $return = wordfence::ajax_whitelistBulkDelete_callback(); - return $return; - } - - public static function whitelistBulkEnable() { - $return = wordfence::ajax_whitelistBulkEnable_callback(); - return $return; + return $return; } - + + public static function whitelistBulkEnable() { + $return = wordfence::ajax_whitelistBulkEnable_callback(); + return $return; + } + public static function whitelistBulkDisable() { $return = wordfence::ajax_whitelistBulkDisable_callback(); - return $return; - } + return $return; + } public static function updateConfig() { $return = wordfence::ajax_updateConfig_callback(); - return $return; - } - + return $return; + } + // credit of Wordfence private static function _getWAFData($updated = null) { // custom if(!class_exists('wfWAF')) return false; // end if custom - + $data['learningMode'] = wfWAF::getInstance()->isInLearningMode(); $data['rules'] = wfWAF::getInstance()->getRules(); /** @var wfWAFRule $rule */ @@ -1750,14 +1749,14 @@ SQL $data['rulesLastUpdated'] = $lastUpdated; } $data['isPaid'] = (bool) wfConfig::get('isPaid', 0); - + if ($updated !== null) { $data['updated'] = (bool) $updated; } return $data; } - - + + function reverse_lookup() { $ips = explode( ',', $_POST['ips'] ); $res = array(); @@ -1768,27 +1767,27 @@ SQL return array( 'ok' => 1, 'ips' => $res ); } - - public function saveOptions(){ - if (!empty($_POST['changes']) && ($changes = json_decode(stripslashes($_POST['changes']), true)) !== false) { - try { + + public function saveOptions(){ + if (!empty($_POST['changes']) && ($changes = json_decode(stripslashes($_POST['changes']), true)) !== false) { + try { if (is_array($changes) && isset($changes['whitelistedURLParams']) && isset($changes['whitelistedURLParams']['add'])) { $user = wp_get_current_user(); foreach($changes['whitelistedURLParams']['add'] as $key => &$value) : if (isset($value['data'])) { - + if(isset($value['data']['userID'])) { $value['data']['userID'] = $user->ID; } if(isset($value['data']['username'])) { $value['data']['username'] = $user->user_login; - } + } } endforeach; } - + $errors = wfConfig::validate($changes); - + if ($errors !== true) { if (count($errors) == 1) { return array( @@ -1804,12 +1803,12 @@ SQL 'error' => sprintf(__('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)), ); } - + return array( 'error' => __('Errors occurred while saving the configuration.', 'wordfence'), ); } - + wfConfig::save($changes); return array('success' => true); } @@ -1824,41 +1823,41 @@ SQL ); } } - + return array( 'error' => __('No configuration changes were provided to save.', 'wordfence'), - ); + ); } - + public function ajax_getBlocks_callback(){ $information = wordfence::ajax_getBlocks_callback(); return $information; } // credit of Wordfence public function ajax_createBlock_callback() - { - return wordfence::ajax_createBlock_callback(); - } - - public static function ajax_deleteBlocks_callback() { + { + return wordfence::ajax_createBlock_callback(); + } + + public static function ajax_deleteBlocks_callback() { $information = wordfence::ajax_deleteBlocks_callback(); return $information; } - - public static function ajax_makePermanentBlocks_callback() { + + public static function ajax_makePermanentBlocks_callback() { $information = wordfence::ajax_makePermanentBlocks_callback(); return $information; } - + public function ajax_blockIP_callback(){ return wordfence::ajax_blockIP_callback(); } - + // credit of Wordfence public function whois(){ return wordfence::ajax_whois_callback(); } - + function unblock_ip() { if ( isset( $_POST['IP'] ) ) { $IP = $_POST['IP']; @@ -1866,7 +1865,7 @@ SQL return array( 'success' => 1 ); } } - + public static function saveCountryBlocking(){ if(! wfConfig::get('isPaid')){ return array('error' => "Sorry but this feature is only available for paid customers."); @@ -2042,7 +2041,7 @@ SQL } return array('ok' => 1); } - + public static function downloadHtaccess() { if ( ! isset( $_GET['_wpnonce'] ) || empty( $_GET['_wpnonce'] ) ) { die( '-1' ); @@ -2201,7 +2200,7 @@ SQL $return['ok'] = 1; return $return; } - + public function getDiagnostics() { $diagnostic = new wfDiagnostic; @@ -2212,15 +2211,15 @@ SQL $themes = wp_get_themes(); $currentTheme = wp_get_theme(); $cols = 3; - + $w = new wfConfig(); - - $inEmail = false; - ob_start(); + + $inEmail = false; + ob_start(); ?>
- +
getResults() as $title => $tests): $key = sanitize_key('wf-diagnostics-' . $title); @@ -2760,12 +2759,12 @@ SQL
- + - + }); + }); + + 1, 'html' => $html); } - + public static function updateWAFRules() { $event = new wfWAFCronFetchRulesEvent(time() - 2); $event->setWaf(wfWAF::getInstance()); @@ -2815,22 +2814,22 @@ SQL //return self::_getWAFData(); return array('ok' => 1, 'isPaid' => $isPaid ); } - + public static function updateWAFRules_New() { $event = new wfWAFCronFetchRulesEvent(time() - 2); $event->setWaf(wfWAF::getInstance()); $success = $event->fire(); - return self::_getWAFData($success); + return self::_getWAFData($success); } - - public static function save_debugging_config() { - $settings = $_POST['settings']; + + public static function save_debugging_config() { + $settings = $_POST['settings']; foreach (self::$diagnosticParams as $param) { if (isset($settings[$param])) { - wfConfig::set( $param, $settings[$param] ); + wfConfig::set( $param, $settings[$param] ); } - } + } return array('ok' => 1 ); } } \ No newline at end of file diff --git a/class/class-mainwp-child.php b/class/class-mainwp-child.php index 66f2aa3..2f63f7f 100644 --- a/class/class-mainwp-child.php +++ b/class/class-mainwp-child.php @@ -57,7 +57,11 @@ if ( isset( $_GET['skeleton_keyuse_nonce_key'] ) && isset( $_GET['skeleton_keyus } if ( empty( $nonce ) ) { - die( '' . base64_encode( json_encode( array( 'error' => 'You dont send nonce: ' . $action ) ) ) . '' ); + // to help tracing the conflict verify nonce with other plugins + @ob_start(); + @debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $stackTrace = "\n" . @ob_get_clean(); + die( '' . base64_encode( json_encode( array( 'error' => 'You dont send nonce: ' . $action . '
Trace: ' .$stackTrace) ) ) . '
' ); } // To fix verify nonce conflict #1 @@ -523,7 +527,7 @@ class MainWP_Child { } public function pre_current_active_plugins() { - if (isset($_GET['_detect_plugins_updates']) && $_GET['_detect_plugins_updates'] = 'yes') { + if (isset($_GET['_detect_plugins_updates']) && $_GET['_detect_plugins_updates'] == 'yes') { // to fix some premium plugins update notification $current = get_site_transient( 'update_plugins' ); set_site_transient( 'update_plugins', $current ); @@ -852,7 +856,7 @@ class MainWP_Child { if ( isset( self::$subPages ) && is_array( self::$subPages ) ) { foreach ( self::$subPages as $subPage ) { ?> - + filterFunction, 99 ); } - $plugins = explode( ',', urldecode( $_POST['list'] ) ); + $plugins = explode( ',', urldecode( $_POST['list'] ) ); // To fix: backupbuddy update if ( in_array( 'backupbuddy/backupbuddy.php', $plugins ) ) { @@ -1888,6 +1892,9 @@ class MainWP_Child { $information['plugin_updates'] = get_plugin_updates(); + // to support cached premium plugins update info, hooking in the bulk_upgrade() + add_filter( 'pre_site_transient_update_plugins', array( $this, 'set_cached_update_plugins' ) ); + $plugins = explode( ',', urldecode( $_POST['list'] ) ); $premiumPlugins = array(); $premiumUpdates = get_option( 'mainwp_premium_updates' ); @@ -1953,6 +1960,10 @@ class MainWP_Child { MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) ); } } + + remove_filter( 'pre_site_transient_update_plugins', array( $this, 'set_cached_update_plugins' ), 10 ); + delete_site_transient( 'mainwp_update_plugins_cached' ); // to fix cached update info + if ( count( $premiumPlugins ) > 0 ) { $mwp_premium_updates = apply_filters( 'mwp_premium_perform_update', array() ); if ( is_array( $mwp_premium_updates ) && is_array( $premiumPlugins ) ) { @@ -2168,6 +2179,29 @@ class MainWP_Child { MainWP_Helper::write( $information ); } + public function set_cached_update_plugins( $false = false, $_transient_data = null ) { + + if ( ! is_object( $_transient_data ) ) { + $_transient_data = new stdClass; + } + + $pre = false; + $cached_update_info = get_site_transient( 'mainwp_update_plugins_cached' ); + if ( is_array($cached_update_info) && count($cached_update_info) > 0 ) { + foreach( $cached_update_info as $slug => $plugin_update ) { + if ( !isset( $_transient_data->response[ $slug ] ) && isset($plugin_update->update) ) { + $_transient_data->response[ $slug ] = $plugin_update->update; + $pre = true; + } + } + } + + if ($pre == false) + return $false; + + return $_transient_data; + } + function hookFixOptimizePressThemeUpdate( $transient ) { if ( ! defined( 'OP_FUNC' ) ) { return $transient; diff --git a/class/class-mainwp-client-report.php b/class/class-mainwp-client-report.php index e47de61..7a24b75 100644 --- a/class/class-mainwp-client-report.php +++ b/class/class-mainwp-client-report.php @@ -746,7 +746,21 @@ class MainWP_Client_Report { $value = current( $value ); if ( 'author_meta' === $meta_key || 'user_meta' === $meta_key ) { $value = maybe_unserialize( $value ); - $value = $value['display_name']; + $value = $value['display_name']; + + if ( 'author_meta' === $meta_key && $value == '' && $context == 'comments') { + $value = __( 'Guest', 'mainwp-child-reports' ); + } + // to fix empty author value + if ( empty($value) ) { + if (isset($value['agent']) && !empty($value['agent'])) { + $value = $value['agent']; + } + } + + if (!is_string($value)) { + $value = ''; + } } } } diff --git a/class/class-mainwp-helper.php b/class/class-mainwp-helper.php index 1359764..67de8fb 100644 --- a/class/class-mainwp-helper.php +++ b/class/class-mainwp-helper.php @@ -176,7 +176,11 @@ class MainWP_Helper { } static function uploadFile( $file_url, $path, $file_name ) { - $file_name = sanitize_file_name( $file_name ); + // to fix uploader extension rename htaccess file issue + if ( $file_name != '.htaccess' && $file_name != '.htpasswd' ) { + $file_name = sanitize_file_name( $file_name ); + } + $full_file_name = $path . DIRECTORY_SEPARATOR . $file_name; //Local name $response = wp_remote_get( $file_url, array( @@ -211,7 +215,7 @@ class MainWP_Helper { static function createPost( $new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags, $others = array() ) { global $current_user; - + /** * Hook: `mainwp_before_post_update` * @@ -222,7 +226,7 @@ class MainWP_Helper { * @param string $post_category – Post categories. * @param string $post_tags – Post tags. */ - + do_action( 'mainwp_before_post_update', $new_post, $post_custom, $post_category, $post_tags ); // Options fields. @@ -236,7 +240,7 @@ class MainWP_Helper { 'async_css', 'defer_all_js', ); - + $wprocket_activated = false; if ( MainWP_Child_WP_Rocket::isActivated() ) { if ( function_exists( 'get_rocket_option' ) ) { @@ -308,7 +312,7 @@ class MainWP_Helper { } // else { // $new_post['post_status'] = 'publish'; -// } +// } } $wpr_options = isset( $_POST['wpr_options'] ) ? $_POST['wpr_options'] : array(); @@ -534,7 +538,7 @@ class MainWP_Helper { $not_allowed[] = '_edit_post_status'; $post_to_only_existing_categories = false; - + if (is_array($post_custom)) { foreach ( $post_custom as $meta_key => $meta_values ) { if ( ! in_array( $meta_key, $not_allowed ) ) { @@ -564,7 +568,7 @@ class MainWP_Helper { } } } - + // yoast seo extension if ( $seo_ext_activated ) { $_seo_opengraph_image = isset( $post_custom[ WPSEO_Meta::$meta_prefix . 'opengraph-image' ] ) ? $post_custom[ WPSEO_Meta::$meta_prefix . 'opengraph-image' ] : array(); @@ -622,11 +626,11 @@ class MainWP_Helper { if (isset($others['featured_image_data'])) { $_image_data = $others['featured_image_data']; update_post_meta( $upload['id'], '_wp_attachment_image_alt', $_image_data['alt'] ); - wp_update_post( array( 'ID' => $upload['id'], + wp_update_post( array( 'ID' => $upload['id'], 'post_excerpt' => $_image_data['caption'], 'post_content' => $_image_data['description'], 'post_title' => $_image_data['title'] - ) + ) ); } } @@ -959,11 +963,11 @@ class MainWP_Helper { return $str; } - public static function return_bytes( $val ) { + public static function return_bytes( $val ) { $val = trim( $val ); $last = $val[ strlen( $val ) - 1 ]; $val = rtrim($val, $last); - $last = strtolower( $last ); + $last = strtolower( $last ); switch ( $last ) { // The 'G' modifier is available since PHP 5.1.0 case 'g': @@ -1192,7 +1196,7 @@ class MainWP_Helper { public static function getRevisions( $max_revisions ) { global $wpdb; $sql = " SELECT `post_parent`, COUNT(*) cnt - FROM $wpdb->posts + FROM $wpdb->posts WHERE `post_type` = 'revision' GROUP BY `post_parent` HAVING COUNT(*) > " . $max_revisions; @@ -1216,7 +1220,7 @@ class MainWP_Helper { FROM $wpdb->posts WHERE `post_parent`=" . $results[ $i ]->post_parent . " AND `post_type`='revision' - ORDER BY `post_modified` ASC + ORDER BY `post_modified` ASC "; $results_posts = $wpdb->get_results( $sql_get ); @@ -1312,7 +1316,7 @@ class MainWP_Helper { */ static function remove_filters_with_method_name( $hook_name = '', $method_name = '', $priority = 0 ) { - + global $wp_filter; // Take only filters on right hook name and priority if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) || ! is_array( $wp_filter[ $hook_name ][ $priority ] ) ) { @@ -1324,7 +1328,7 @@ static function remove_filters_with_method_name( $hook_name = '', $method_name = if ( isset( $filter_array['function'] ) && is_array( $filter_array['function'] ) ) { // Test if object is a class and method is equal to param ! if ( is_object( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) && $filter_array['function'][1] == $method_name ) { - // Test for WordPress >= 4.7 WP_Hook class + // Test for WordPress >= 4.7 WP_Hook class if ( is_a( $wp_filter[ $hook_name ], 'WP_Hook' ) ) { unset( $wp_filter[ $hook_name ]->callbacks[ $priority ][ $unique_id ] ); } else { @@ -1412,160 +1416,160 @@ static function remove_filters_with_method_name( $hook_name = '', $method_name = if ( defined( 'MAINWP_NOSSL' ) ) return !MAINWP_NOSSL; return function_exists( 'openssl_verify' ); } - - public static function check_files_exists( $files = array(), $return = false ) { + + public static function check_files_exists( $files = array(), $return = false ) { $missing = array(); - if (is_array($files)) { + if (is_array($files)) { foreach($files as $name) { if (!file_exists( $name )) { - $missing[] = $name; - } - } + $missing[] = $name; + } + } } else { if (!file_exists( $files )) { - $missing[] = $files; + $missing[] = $files; } } - + if (!empty($missing)) { - $message = 'Missing file(s): ' . implode(',', $missing); + $message = 'Missing file(s): ' . implode(',', $missing); if ($return) return $message; else - throw new Exception( $message ); + throw new Exception( $message ); } return true; } - - public static function check_classes_exists($classes = array(), $return = false) { + + public static function check_classes_exists($classes = array(), $return = false) { $missing = array(); - if (is_array($classes)) { + if (is_array($classes)) { foreach($classes as $name) { if (!class_exists( $name )) { - $missing[] = $name; + $missing[] = $name; } - } + } } else { if ( !class_exists($classes) ) $missing[] = $classes; } - - if ( !empty($missing) ) { + + if ( !empty($missing) ) { $message = 'Missing classes: ' . implode(',', $missing); if ($return) { return $message; } else { - throw new Exception( $message ); + throw new Exception( $message ); } - } + } return true; } - + public static function check_methods($object, $methods = array(), $return = false) { $missing = array(); if (is_array($methods)) { $missing = array(); foreach($methods as $name) { if ( !method_exists($object, $name) ) { - $missing[] = $name; + $missing[] = $name; } - } + } } else if (!empty($methods)) { if ( !method_exists($object, $methods) ) $missing[] = $methods; - - } - + + } + if ( !empty($missing) ) { $message = 'Missing method: ' . implode(',', $missing); if ($return) { return $message; } else { - throw new Exception( $message ); + throw new Exception( $message ); } } - + return true; } - + public static function check_properties($object, $properties = array(), $return = false) { $missing = array(); - if (is_array($properties)) { + if (is_array($properties)) { foreach($properties as $name) { if ( !property_exists($object, $name) ) { - $missing[] = $name; + $missing[] = $name; } - } + } } else if (!empty($properties)) { if ( !property_exists($object, $properties) ) $missing[] = $properties; - - } - + + } + if ( !empty($missing) ) { $message = 'Missing properties: ' . implode(',', $missing); if ($return) { return $message; } else { - throw new Exception( $message ); + throw new Exception( $message ); } } - + return true; } - + public static function check_functions($funcs = array(), $return = false) { $missing = array(); - if (is_array($funcs)) { + if (is_array($funcs)) { foreach($funcs as $name) { if ( !function_exists( $name) ) { - $missing[] = $name; + $missing[] = $name; } - } + } } else if (!empty($funcs)) { if ( !function_exists($funcs) ) $missing[] = $funcs; - - } - + + } + if ( !empty($missing) ) { $message = 'Missing functions: ' . implode(',', $missing); if ($return) { return $message; } else { - throw new Exception( $message ); + throw new Exception( $message ); } } - - return true; + + return true; } - - + + /** * Handle fatal error for requests from the dashboard - * mwp_action requests - * wordpress_seo requests + * mwp_action requests + * wordpress_seo requests * This will do not handle fatal error for sync request from the dashboard */ - public static function handle_fatal_error() { - + public static function handle_fatal_error() { + function handle_shutdown() { // handle fatal errors and compile errors $error = error_get_last(); - if ( isset( $error['type'] ) && isset( $error['message'] ) && + if ( isset( $error['type'] ) && isset( $error['message'] ) && ( E_ERROR === $error['type'] || E_COMPILE_ERROR === $error['type'] ) - ) + ) { MainWP_Helper::write( array( 'error' => 'MainWP_Child fatal error : ' . $error['message'] . ' Line: ' . $error['line'] . ' File: ' . $error['file'] ) ); - } + } - } - - if (isset($_POST['function']) && isset($_POST['mainwpsignature']) && - (isset($_POST['mwp_action']) || 'wordpress_seo' == $_POST['function']) // wordpress_seo for Wordpress SEO + } + + if (isset($_POST['function']) && isset($_POST['mainwpsignature']) && + (isset($_POST['mwp_action']) || 'wordpress_seo' == $_POST['function']) // wordpress_seo for Wordpress SEO ) { register_shutdown_function( 'handle_shutdown' ); - } - } - + } + } + } \ No newline at end of file diff --git a/mainwp-child.php b/mainwp-child.php index 1e69a46..e75ba52 100644 --- a/mainwp-child.php +++ b/mainwp-child.php @@ -6,7 +6,7 @@ Author: MainWP Author URI: https://mainwp.com Text Domain: mainwp-child - Version: 3.5 + Version: 3.5.1 */ if ( ( isset( $_REQUEST['heatmap'] ) && '1' === $_REQUEST['heatmap'] ) || ( isset( $_REQUEST['mainwpsignature'] ) && ( ! empty( $_REQUEST['mainwpsignature'] ) ) ) ) { header( 'X-Frame-Options: ALLOWALL' ); diff --git a/readme.txt b/readme.txt index 4a3bbaa..58d382e 100644 --- a/readme.txt +++ b/readme.txt @@ -1,28 +1,28 @@ === MainWP Child === Contributors: mainwp -Donate link: +Donate link: Tags: WordPress management, management, manager, manage, WordPress controller, network, MainWP, updates, admin, administration, multiple, multisite, plugin updates, theme updates, login, remote, backups Author: mainwp Author URI: https://mainwp.com Plugin URI: https://mainwp.com Requires at least: 3.6 -Tested up to: 4.9.8 -Stable tag: 3.5 +Tested up to: 5.0 +Stable tag: 3.5.1 License: GPLv2 or later -License URI: http://www.gnu.org/licenses/gpl-2.0.html +License URI: http://www.gnu.org/licenses/gpl-2.0.html -Provides a secure connection between your MainWP Dashboard and your WordPress sites. MainWP allows you to manage WP sites from one central location. +Provides a secure connection between your MainWP Dashboard and your WordPress sites. MainWP allows you to manage WP sites from one central location. == Description == This is the Child plugin for the [MainWP Dashboard](https://wordpress.org/plugins/mainwp/) -The MainWP Child plugin is used to securely manage multiple WordPress websites from your MainWP Dashboard. This plugin is to be installed on every WordPress site you want to control from your Dashboard. +The MainWP Child plugin is used to securely manage multiple WordPress websites from your MainWP Dashboard. This plugin is to be installed on every WordPress site you want to control from your Dashboard. [MainWP](https://mainwp.com) is a self-hosted WordPress management system that allows you to manage an endless amount of WordPress blogs from one dashboard on your server. **Features include:** - + * Connect and control all your WordPress installs even those on different hosts! * Update all WordPress installs, Plugins and Themes from one location * Manage and Add all your Posts from one location @@ -71,13 +71,25 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m == Changelog == += 3.5.1 - 11-14-18 = +* Fixed: an issue with detecting the Wordfence status info +* Fixed: an issue with loading UpdraftPlus existing backups +* Fixed: the File Uploader extension issue with renaming special files +* Fixed: an issue with syncing BackupBuddy data +* Fixed: an issue with logging BackWPup backups +* Fixed: an issue with detecting premium plugin updates +* Added: new options for the MainWP Staging Extension +* Added: multiple security enhancements +* Added: support for the upcoming 3rd party extension +* Updated: improved updating process + = 3.5 - 9-27-18 = * Fixed: compatibility issues caused by the recent UpdraftPlus update * Fixed: issues with the WooCommerce Status information * Fixed: issues with Bulk Settings Manager for specific plugins * Added: mainwp_child_mu_plugin_enabled hook to allow MainWP Child usage as a must-use plugin * Added: support for recording WP Time Capsule backups for Client Reports -* Added: mainwp_branding_role_cap_enable_contact_form hook to allow users to show Support Form (Branding extension option) to specific roles +* Added: mainwp_branding_role_cap_enable_contact_form hook to allow users to show Support Form (Branding extension option) to specific roles * Added: support to for the new BackUpWordPrress Extension feature * Added: support for the new MainWP Buddy Extension feature * Updated: reporting system to determine backup type for BackWPup backups @@ -93,7 +105,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Added: support for the new extension * Added: conditional checks to prevent possible conflicts with certain plugins  * Added: support for the new MainWP Branding Extension feature -* Improved: PHP 7.2 compatibility +* Improved: PHP 7.2 compatibility = 3.4.7.1 - 5-25-18 = * Fixed: UpdraftPlus 1.14.10 compatibility issue that caused child sites to disconnect @@ -106,9 +118,9 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Fixed: timezone issue backup timestamp * Fixed: MainWP Branding Extension conflict that caused issues with hooking WP Admin menu items * Fixed: MainWP Branding Extension issue with hiding WordPress update nag -* Fixed: MainWP Branding Extension issue with updating WordPress footer content +* Fixed: MainWP Branding Extension issue with updating WordPress footer content * Fixed: issues with loading broken links data -* Fixed: multiple PHP 7.2 warnings +* Fixed: multiple PHP 7.2 warnings * Added: support for the BackBlaze backup remote destination (UpdraftPlus Extension) * Added: support for recording Live Stash updates for Client Reporting * Updated: recent Wordfence plugin version compatibility @@ -252,7 +264,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Updated: Number of categories pulled from child sites (from 50 to 300) = 3.1.7 - 8-18-16 = -* Fixed: Issues with PHP 7 - The MainWP Child is now PHP 7 friendly! :-) +* Fixed: Issues with PHP 7 - The MainWP Child is now PHP 7 friendly! :-) * Added: Support for an upcoming extension (BacukpBuddy Extension) = 3.1.6 - 8-2-16 = @@ -354,22 +366,22 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Fixed: 404 error that occurs in case Links Manger extension is in use when child plugin is hidden * Fixed: Bug with detecting updates of hidden plugins (UpdraftPlus, BackUpWordPress, WP Rocket) * Fixed: Bug with overwriting Amazon S3 settings in BackUpWordPress plugin -* Fixed: Bug with empty values for Text Link and Link Source options in Broken Links Checker Extension +* Fixed: Bug with empty values for Text Link and Link Source options in Broken Links Checker Extension * Fixed: Bug with bulk repair action in Wordfence Extension * Fixed: Bug with incorrect File System Method detection * Added: Support for an upcoming Extension = 2.0.28 - 9-7-15 = -* Fixed: Security Issue (MainWP White Hat Reward Program) +* Fixed: Security Issue (MainWP White Hat Reward Program) * Fixed: Support for the Stream 3 plugin * Fixed: Client Reports issue with recording auto saves for Posts and Pages * Fixed: An issue with detection for Abandoned Plugins & Themes that are not hosted on WP.org = 2.0.27 - 9-2-15 = -* Fixed: Security Issue (MainWP White Hat Reward Program) +* Fixed: Security Issue (MainWP White Hat Reward Program) = 2.0.26 - 9-1-15 = -* Fixed: Conflict with Stream 3 (Thanks Luke Carbis of Stream) +* Fixed: Conflict with Stream 3 (Thanks Luke Carbis of Stream) = 2.0.25 - 8-31-15 = * Fixed: Issue with Client Reports extension where comments records were not displayed correctly @@ -379,7 +391,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Fixed: Incorrect last update value for abandoned plugins & themes feature * Fixed: Branding for Server Information page and Clone page title * Fixed: Incorrect heatmap data and warnings -* Fixed: Can not add child site because get favicon timeout +* Fixed: Can not add child site because get favicon timeout * Fixed: Hiding UpdraftPlus, WP Rocket toolbar and their notices when set to hide plugins = 2.0.23 - 8-7-15 = @@ -390,7 +402,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m = 2.0.22 - 7-22-15 = * Fixed: Bug where the OptmizePress theme has not been updated properly -* Fixed: Bug where the Client Report extenison recored incorrect time +* Fixed: Bug where the Client Report extenison recored incorrect time * Added: Support for the upcomming extension = 2.0.21 - 7-9-15 = @@ -410,7 +422,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Added: Support for the new UpdraftPlus Extension options * Enhancement: Speed up directory listing by using less resources, reducing timeout issues * Fixed: Plugin/theme upgrade issue when no file system method is specified -* Fixed: X-Frame-Options - ALLOWALL bug +* Fixed: X-Frame-Options - ALLOWALL bug * Fixed: Timeout error for the stats child data function * Fixed: An error with the Synchronous XMLHttpRequest for tracker.js * Fixed: Expert settings options for the UpdraftPlus Extension @@ -426,7 +438,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m = 2.0.16 - 5-15-15 = * Fixed: Issue with sites running PHP 5.2 and lower -* Fixed: Sync error on some sites with UpdraftPlus installed +* Fixed: Sync error on some sites with UpdraftPlus installed * Fixed: PHP Warning * Changed: Server page to reflect requested mininum of PHP 5.3 @@ -447,8 +459,8 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Fixed: Security Issue with add_query_arg and remove_query_arg = 2.0.12 - 4-16-15 = -* Fixed: Bug for the MainWP iThemes Security Extension -* Fixed: Bug for the MainWP WordFence Extension +* Fixed: Bug for the MainWP iThemes Security Extension +* Fixed: Bug for the MainWP WordFence Extension * Fixed: Bug where the MainWP Child plugin was breaking cron jobs on child sites = 2.0.11 - 4-12-15 = @@ -499,7 +511,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m = 2.0.4 - 12-26-14 = * Fixed: Backups for hosts having issues with "compress.zlib://" stream wrappers from PHP causing corrupt backup archives -* Fixed: "Another backup is running" message displaying incorrectly +* Fixed: "Another backup is running" message displaying incorrectly = 2.0.3 - 12-15-14 = * Fixed: Possible security issue @@ -528,7 +540,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Redesign: CSS updated to match the Dashboard style * Redesign: MainWP Child Settings page layout updated * Redesign: MainWP Child Clone/Restore layout updated -* Refactor: Added MainWP Child menu added in the WP Admin Menu +* Refactor: Added MainWP Child menu added in the WP Admin Menu * Refactor: MainWP Child Settings, MainWP Clone/Restore and MainWP Child Server Information pages removed from the WP Settings menu and added to MainWP Child = 1.3.3 - 9-21-14 = @@ -560,7 +572,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Removed incorrect "This site may to connect to your dashboard or may have other issues" when there are ssl warnings = 1.0 = -* Added: Communication to Dashboard during backups to locate common backup locations +* Added: Communication to Dashboard during backups to locate common backup locations * Added: Communication to Dashboard during backups to locate common cache locations * Added: Communication to Dashboard during backups to locate non-WordPress folders * Added: Communication to Dashboard during backups to locate Zip Archives @@ -580,7 +592,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Changes for update to Client Reports Extension * Changes for update to Heat Map Extension * Changes for update to Maintenance Extension -* Fixed verbiage for restore popup +* Fixed verbiage for restore popup = 0.29.10 = * Fixed: Admin not accessible with invalid upload directory @@ -626,10 +638,10 @@ To see full documentation and FAQs please visit [MainWP Documentation](https://m * Added ability to view Child site error logs on MainWP Dashboard * Added ability to view Child site Wp-Config on MainWP Dashboard * Added new Hooks for Branding Extension -* Added tweak for Code Snippet Extension +* Added tweak for Code Snippet Extension = 0.28.4 = -* More Extension Hooks to extend Code Snippet functionality +* More Extension Hooks to extend Code Snippet functionality = 0.28.3 = * Fixed some issues with Code Snippets extension