diff --git a/class/MainWPChild.class.php b/class/MainWPChild.class.php
index d4cedba..9fe2538 100644
--- a/class/MainWPChild.class.php
+++ b/class/MainWPChild.class.php
@@ -11,7 +11,7 @@ include_once(ABSPATH . '/wp-admin/includes/plugin.php');
class MainWPChild
{
- private $version = '2.0.22';
+ private $version = '2.0.23';
private $update_version = '1.2';
private $callableFunctions = array(
@@ -69,7 +69,8 @@ class MainWPChild
'updraftplus' => 'updraftplus',
'backup_wp' => 'backup_wp',
'backwpup' => 'backwpup',
- 'wp_rocket' => 'wp_rocket'
+ 'wp_rocket' => 'wp_rocket',
+ 'settings_tools' => 'settings_tools'
);
private $FTP_ERROR = 'Failed, please add FTP details for automatic upgrades.';
@@ -92,7 +93,7 @@ class MainWPChild
public function __construct($plugin_file)
{
$this->update();
-
+
$this->filterFunction = create_function( '$a', 'if ($a == null) { return false; } return $a;' );
$this->plugin_dir = dirname($plugin_file);
$this->plugin_slug = plugin_basename($plugin_file);
@@ -115,7 +116,10 @@ class MainWPChild
MainWPClone::init();
MainWPChildServerInformation::init();
- MainWPClientReport::init();
+ MainWPClientReport::init();
+ MainWPChildPluginsCheck::Instance();
+ MainWPChildThemesCheck::Instance();
+
$this->run_saved_snippets();
if (!get_option('mainwp_child_pubkey'))
@@ -846,8 +850,8 @@ class MainWPChild
MainWPChildWPRocket::Instance()->init();
MainWPChildBackWPup::Instance()->init();
-
- //Call the function required
+
+ //Call the function required
if (isset($_POST['function']) && isset($this->callableFunctions[$_POST['function']]))
{
call_user_func(array($this, ($auth ? $this->callableFunctions[$_POST['function']]
@@ -2434,7 +2438,19 @@ class MainWPChild
if ($exit) $this->updateExternalSettings();
MainWPHelper::update_option('mainwp_child_branding_disconnected', '', 'yes');
-
+ if (isset($_POST['server']))
+ MainWPHelper::update_option('mainwp_child_server', $_POST['server']);
+
+ if (isset($_POST['numberdaysOutdatePluginTheme']) && !empty($_POST['numberdaysOutdatePluginTheme'])) {
+ $days_outdate = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
+ if ($days_outdate != $_POST['numberdaysOutdatePluginTheme']) {
+ $days_outdate = $_POST['numberdaysOutdatePluginTheme'];
+ MainWPHelper::update_option('mainwp_child_plugintheme_days_outdate', $days_outdate);
+ MainWPChildPluginsCheck::Instance()->cleanup_deactivation(false);
+ MainWPChildThemesCheck::Instance()->cleanup_deactivation(false);
+ }
+ }
+
$information['version'] = $this->version;
$information['wpversion'] = $wp_version;
$information['siteurl'] = get_option('siteurl');
@@ -2695,6 +2711,9 @@ class MainWPChild
if (isset($last_post) && isset($last_post['post_modified_gmt'])) $information['last_post_gmt'] = strtotime($last_post['post_modified_gmt']);
$information['mainwpdir'] = (MainWPHelper::validateMainWPDir() ? 1 : -1);
$information['uniqueId'] = get_option('mainwp_child_uniqueId', '');
+ $information['plugins_outdate_info'] = MainWPChildPluginsCheck::Instance()->get_plugins_outdate_info();
+ $information['themes_outdate_info'] = MainWPChildThemesCheck::Instance()->get_themes_outdate_info();
+
if ($exit) MainWPHelper::write($information);
return $information;
@@ -3059,115 +3078,6 @@ class MainWPChild
}
}
- // function get_next_time_of_post_to_post()
- // {
- // /** @var $wpdb wpdb */
- // global $wpdb;
- // try
- // {
- // $ct = current_time('mysql');
- // $next_post = $wpdb->get_row("
- // SELECT *
- // FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id
- // WHERE
- // pm.meta_key='_ezine_keyword' AND
- // p.post_status='future' AND
- // p.post_type='post' AND
- // p.post_date>'$ct'
- // ORDER BY p.post_date
- // LIMIT 1");
-
- // if (!$next_post)
- // {
- // $information['error'] = "Can not get next schedule post";
- // }
- // else
- // {
- // $information['next_post_date'] = $next_post->post_date;
- // $information['next_post_id'] = $next_post->ID;
-
- // $next_posts = $wpdb->get_results("
- // SELECT DISTINCT `ID`
- // FROM $wpdb->posts p
- // JOIN $wpdb->postmeta pm ON p.ID = pm.post_id
- // WHERE pm.meta_key = '_ezine_keyword'
- // AND p.post_status = 'future'
- // AND p.post_date > NOW( )
- // ORDER BY p.post_date
- // ");
-
- // if (!$next_posts)
- // $information['error'] = "Can not get all next schedule post";
- // else
- // $information['next_posts'] = $next_posts;
-
- // }
-
- // MainWPHelper::write($information);
- // }
- // catch (Exception $e)
- // {
- // $information['error'] = $e->getMessage();
- // MainWPHelper::write($information);
- // }
- // }
-
- // function get_next_time_of_page_to_post()
- // {
- // /** @var $wpdb wpdb */
- // global $wpdb;
- // try
- // {
-
- // $ct = current_time('mysql');
- // $next_post = $wpdb->get_row("
- // SELECT *
- // FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id
- // WHERE
- // pm.meta_key='_ezine_keyword' AND
- // p.post_status='future' AND
- // p.post_type='page' AND
- // p.post_date>'$ct'
- // ORDER BY p.post_date
- // LIMIT 1");
-
- // if (!$next_post)
- // {
- // $information['error'] = "Can not get next schedule post";
- // }
- // else
- // {
-
- // $information['next_post_date'] = $next_post->post_date;
- // $information['next_post_id'] = $next_post->ID;
-
- // $next_posts = $wpdb->get_results("
- // SELECT DISTINCT `ID`
- // FROM $wpdb->posts p
- // JOIN $wpdb->postmeta pm ON p.ID = pm.post_id
- // WHERE pm.meta_key = '_ezine_keyword'
- // AND p.post_status = 'future'
- // AND p.post_date > NOW( )
- // ORDER BY p.post_date
- // ");
-
- // if (!$next_posts)
- // $information['error'] = "Can not get all next schedule post";
- // else
- // $information['next_posts'] = $next_posts;
-
- // }
-
- // MainWPHelper::write($information);
- // }
- // catch (Exception $e)
- // {
- // $information['error'] = $e->getMessage();
- // MainWPHelper::write($information);
- // }
-
- // }
-
function get_all_pages()
{
$this->get_all_posts_by_type('page');
@@ -3681,7 +3591,7 @@ class MainWPChild
foreach ($to_delete as $delete)
{
delete_option($delete);
- }
+ }
}
function deactivation()
@@ -4276,8 +4186,8 @@ class MainWPChild
function backwpup() {
MainWPChildBackWPup::Instance()->action();
}
-
-
+
+
function delete_backup()
{
$dirs = MainWPHelper::getMainWPDir('backup');
@@ -4344,5 +4254,33 @@ class MainWPChild
}
return @fclose($handle);
}
+
+ function settings_tools() {
+ if (isset($_POST['action'])) {
+ switch ($_POST['action']) {
+ case 'force_destroy_sessions';
+ if (get_current_user_id() == 0) {
+ MainWPHelper::write(array('error' => __( 'Cannot get user_id', 'mainwp-child' ) ) );
+ }
+
+ wp_destroy_all_sessions();
+
+ $sessions = wp_get_all_sessions();
+
+ if (empty($sessions)) {
+ MainWPHelper::write(array('success' => 1));
+ } else {
+ MainWPHelper::write(array('error' => __( 'Cannot destroy sessions', 'mainwp-child' ) ) );
+ }
+ break;
+
+ default:
+ MainWPHelper::write(array('error' => __( 'Invalid action', 'mainwp-child' ) ) );
+ }
+ } else {
+ MainWPHelper::write(array('error' => __( 'Missing action', 'mainwp-child' ) ) );
+ }
+ }
+
}
?>
\ No newline at end of file
diff --git a/class/MainWPChildPluginsCheck.class.php b/class/MainWPChildPluginsCheck.class.php
new file mode 100644
index 0000000..37d9680
--- /dev/null
+++ b/class/MainWPChildPluginsCheck.class.php
@@ -0,0 +1,396 @@
+schedule_watchdog();
+
+ add_action( $this->cron_name_batching, array( $this, 'run_check' ) );
+ add_action( $this->cron_name_daily, array( $this, 'run_check' ) );
+
+ add_action( $this->cron_name_watcher, array( $this, 'perform_watchdog' ) );
+
+// add_filter( 'plugin_row_meta', array( $this, 'change_plugin_row_meta' ), 10, 4 );
+
+ add_filter( 'plugins_api_args', array( $this, 'modify_plugin_api_search_query' ), 10, 2 );
+
+ add_action('mainwp_child_deactivation', array($this, 'cleanup_deactivation'));
+
+ }
+
+ private function cleanup_basic()
+ {
+ wp_clear_scheduled_hook( $this->cron_name_daily );
+ wp_clear_scheduled_hook( $this->cron_name_batching );
+ delete_transient( $this->tran_name_plugins_to_batch );
+ }
+
+
+ public function cleanup_deactivation($del = true)
+ {
+ $this->cleanup_basic();
+ wp_clear_scheduled_hook( $this->cron_name_watcher );
+ delete_option( $this->option_name_last_daily_run );
+ if ($del)
+ delete_transient( $this->tran_name_plugin_timestamps );
+ }
+
+
+ public function modify_plugin_api_search_query( $args, $action )
+ {
+ if( isset( $action ) && 'query_plugins' === $action )
+ {
+
+ if( ! is_object( $args ) )
+ {
+ $args = new \stdClass();
+ }
+
+ if( ! property_exists( $args, 'fields' ) )
+ {
+ $args->fields = array();
+ }
+
+ $args->fields = array_merge( $args->fields, array( 'last_updated' => true ) );
+ }
+
+ return $args;
+ }
+
+ public function perform_watchdog()
+ {
+ if ( false === wp_next_scheduled( $this->cron_name_daily ) && false === wp_next_scheduled( $this->cron_name_batching ) )
+ {
+ $last_run = get_option( $this->option_name_last_daily_run );
+
+ if( false === $last_run || ! is_integer( $last_run ) )
+ {
+ $last_run = false;
+ }
+ else
+ {
+ $last_run = new \DateTime( '@' . $last_run );
+ }
+
+ //Get now
+ $now = new \DateTime();
+
+ if( false === $last_run || (int)$now->diff( $last_run )->format( '%h' ) >= 24 )
+ {
+ $this->cleanup_basic( );
+
+ wp_schedule_event( time(), 'daily', $this->cron_name_daily );
+
+ update_option( $this->option_name_last_daily_run, $now->getTimestamp( ) );
+
+ }
+ }
+ }
+
+ public function schedule_watchdog()
+ {
+ //For testing
+ //$this->cleanup_deactivation();
+
+ //Schedule a global watching cron just in case both other crons get killed
+ if ( ! wp_next_scheduled( $this->cron_name_watcher ) )
+ {
+ wp_schedule_event( time(), 'hourly', $this->cron_name_watcher );
+ }
+
+ }
+
+ public function get_plugins_outdate_info() {
+ $plugins_outdate = get_transient( $this->tran_name_plugin_timestamps );
+ if( ! function_exists( 'get_plugins' ) )
+ {
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
+ }
+ $plugins = get_plugins();
+ $update = false;
+ foreach($plugins_outdate as $slug => $v) {
+ if (!isset($plugins[$slug])) {
+ unset($plugins_outdate[$slug]);
+ $update = true;
+ }
+ }
+ if ($update) {
+ set_transient( $this->tran_name_plugin_timestamps, $plugins_outdate, DAY_IN_SECONDS );
+ }
+ return $plugins_outdate;
+
+ }
+
+ public function change_plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status )
+ {
+// //Grab our previously stored array of known last modified dates
+// //Requires WP 2.8.0
+// $plugin_info = get_transient( $this->tran_name_plugin_timestamps );
+//
+// //Sanity check the response
+// if( false === $plugin_info || ! is_array( $plugin_info ) && 0 === count( $plugin_info ) )
+// {
+// return $plugin_meta;
+// }
+//
+// //See if this specific plugin is in the known list
+// if( array_key_exists( $plugin_file, $plugin_info ) )
+// {
+// //Get now
+// $now = new \DateTime();
+// $last_updated = $plugin_info[ $plugin_file ]['last_updated'];
+//
+// //Last updated is stored as timestamp, get a real date
+// $plugin_last_updated_date = new \DateTime( '@' . $last_updated );
+//
+// //Compute days between now and plugin last updated
+// $diff_in_days = $now->diff( $plugin_last_updated_date )->format( '%a' );
+//
+// //Customizable number of days for tolerance
+// $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
+//
+// //If we're outside the window for tolerance show a message
+// if( $diff_in_days > $tolerance_in_days )
+// {
+// $plugin_meta[] = sprintf( 'This plugin has not been updated by the author in %1$d days!', $diff_in_days );
+// }
+// else
+// {
+// $plugin_meta[] = sprintf( 'This plugin was last updated by the author in %1$d days ago.', $diff_in_days );
+// }
+// }
+//
+// return $plugin_meta;
+ }
+
+ public function run_check()
+ {
+ if( ! function_exists( 'get_plugins' ) )
+ {
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
+ }
+
+ //Get our previous results
+ $responses = get_transient( $this->tran_name_plugin_timestamps );
+
+ if( false === $responses || ! is_array( $responses ) )
+ {
+ $responses = array();
+ }
+
+ //Get our previous cache of plugins for batching
+ $all_plugins = get_transient( $this->tran_name_plugins_to_batch );
+
+ //If there wasn't a previous cache
+ if( false === $all_plugins || ! is_array( $all_plugins ) )
+ {
+ $plugins = get_plugins();
+ if (is_array($plugins)) {
+ foreach($plugins as $slug => $plugin) {
+ if (isset($plugin['Name']) && !empty($plugin['Name'])) {
+ $all_plugins[$slug] = array(
+ 'Name' => $plugin['Name'],
+ 'PluginURI' => $plugin['PluginURI'],
+ 'Version' => $plugin['Version']
+ );
+
+ }
+ }
+ }
+ $responses = array();
+ }
+
+ //Grab a small number of plugins to scan
+ $plugins_to_scan = array_splice( $all_plugins, 0, apply_filters( 'mainwp_child_plugin_health_check_max_plugins_to_batch', 10 ) );
+
+ //Loop through each known plugin
+ foreach( $plugins_to_scan as $slug => $v )
+ {
+ //Try to get the raw information for this plugin
+ $body = $this->try_get_response_body( $slug, false );
+
+ //We couldn't get any information, skip this plugin
+ if( false === $body )
+ {
+ continue;
+ }
+
+ //Deserialize the response
+ $obj = unserialize( $body );
+
+ $now = new \DateTime();
+
+ //Sanity check that deserialization worked and that our property exists
+ if( false !== $obj && is_object( $obj ) && property_exists( $obj, 'last_updated' ) )
+ {
+ $last_updated = strtotime( $obj->last_updated );
+ $plugin_last_updated_date = new \DateTime( '@'. $last_updated );
+
+ $diff_in_days = $now->diff( $plugin_last_updated_date )->format( '%a' );
+
+
+ $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
+
+ if ($diff_in_days < $tolerance_in_days)
+ continue;
+ $v['last_updated'] = $last_updated;
+ $responses[ $slug ] = $v;
+ }
+ }
+
+ if( ! defined( 'MINUTE_IN_SECONDS' ) )
+ {
+ define( 'MINUTE_IN_SECONDS', 60 );
+ }
+
+ if( ! defined( 'HOUR_IN_SECONDS' ) )
+ {
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS);
+ }
+
+ if( ! defined( 'DAY_IN_SECONDS' ) )
+ {
+ define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS );
+ }
+
+ //Store the master response for usage in the plugin table
+ set_transient( $this->tran_name_plugin_timestamps, $responses, DAY_IN_SECONDS );
+
+ if( 0 === count( $all_plugins ) )
+ {
+ delete_transient( $this->tran_name_plugins_to_batch );
+ wp_schedule_single_event( time() + DAY_IN_SECONDS, $this->cron_name_daily );
+ }
+ else
+ {
+ set_transient( $this->tran_name_plugins_to_batch, $all_plugins, DAY_IN_SECONDS );
+ wp_schedule_single_event( time(), $this->cron_name_batching );
+ }
+ }
+
+ private function try_get_response_body( $plugin, $second_pass )
+ {
+ //Some of this code is lifted from class-wp-upgrader
+
+ //Get the WordPress current version to be polite in the API call
+ include( ABSPATH . WPINC . '/version.php' );
+
+ if( ! defined( 'MINUTE_IN_SECONDS' ) )
+ {
+ define( 'MINUTE_IN_SECONDS', 60 );
+ }
+
+ if( ! defined( 'HOUR_IN_SECONDS' ) )
+ {
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS);
+ }
+ global $wp_version;
+
+ //General options to be passed to wp_remote_get
+ $options = array(
+ 'timeout' => HOUR_IN_SECONDS,
+ 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
+ );
+
+ //The URL for the endpoint
+ $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
+
+ //If we support SSL
+ //Requires WP 3.2.0
+ if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
+ {
+ //Requires WP 3.4.0
+ $url = set_url_scheme( $url, 'https' );
+ }
+
+ //Try to get the response (usually the SSL version)
+ //Requires WP 2.7.0
+ $raw_response = wp_remote_get( $url . $plugin, $options );
+
+ //If we don't have an error and we received a valid response code
+ //Requires WP 2.7.0
+ if( ! is_wp_error( $raw_response ) && 200 == wp_remote_retrieve_response_code( $raw_response ) )
+ {
+ //Get the actual body
+ //Requires WP 2.7.0
+ $body = wp_remote_retrieve_body( $raw_response );
+
+ //Make sure that it isn't empty and also not an empty serialized object
+ if( '' != $body && 'N;' != $body )
+ {
+ //If valid, return that
+ return $body;
+ }
+ }
+
+ //The above valid
+ //If we previously tried an SSL version try without SSL
+ //Code below same as above block
+ if( $ssl )
+ {
+ $raw_response = wp_remote_get( $http_url . $plugin, $options );
+ if( ! is_wp_error( $raw_response ) && 200 == wp_remote_retrieve_response_code( $raw_response ) )
+ {
+ $body = wp_remote_retrieve_body( $raw_response );
+ if( '' != $body && 'N;' != $body )
+ {
+ return $body;
+ }
+ }
+ }
+
+ //The above failed
+ //If we're on a second pass already then there's nothing left to do but bail
+ if( true === $second_pass )
+ {
+ return false;
+ }
+
+ //We're still on the first pass, try to get just the name of the directory of the plugin
+ $parts = explode( '/', $plugin );
+
+ //Sanity check that we have two parts, a directory and a file name
+ if( 2 === count( $parts ) )
+ {
+ //Try this entire function using just the directory name
+ return $this->try_get_response_body( $parts[0], true );
+ }
+
+ //Everything above failed, bail
+ return false;
+ }
+
+
+}
+
diff --git a/class/MainWPChildThemesCheck.class.php b/class/MainWPChildThemesCheck.class.php
new file mode 100644
index 0000000..1d42b40
--- /dev/null
+++ b/class/MainWPChildThemesCheck.class.php
@@ -0,0 +1,326 @@
+schedule_watchdog();
+ add_action( $this->cron_name_batching, array( $this, 'run_check' ) );
+ add_action( $this->cron_name_daily, array( $this, 'run_check' ) );
+
+ add_action( $this->cron_name_watcher, array( $this, 'perform_watchdog' ) );
+
+ add_filter( 'themes_api_args', array( $this, 'modify_theme_api_search_query' ), 10, 2 );
+
+ add_action('mainwp_child_deactivation', array($this, 'cleanup_deactivation'));
+ }
+
+ private function cleanup_basic()
+ {
+ wp_clear_scheduled_hook( $this->cron_name_daily );
+ wp_clear_scheduled_hook( $this->cron_name_batching );
+ delete_transient( $this->tran_name_themes_to_batch );
+ }
+
+
+ public function cleanup_deactivation($del = true)
+ {
+ $this->cleanup_basic();
+ wp_clear_scheduled_hook( $this->cron_name_watcher );
+ delete_option( $this->option_name_last_daily_run );
+ if ($del)
+ delete_transient( $this->tran_name_theme_timestamps );
+ }
+
+
+ public function modify_theme_api_search_query( $args, $action )
+ {
+ if( isset( $action ) && 'query_themes' === $action )
+ {
+
+ if( ! is_object( $args ) )
+ {
+ $args = new \stdClass();
+ }
+
+ if( ! property_exists( $args, 'fields' ) )
+ {
+ $args->fields = array();
+ }
+
+ $args->fields = array_merge( $args->fields, array( 'last_updated' => true ) );
+ }
+
+ return $args;
+ }
+
+ public function perform_watchdog()
+ {
+ if ( false === wp_next_scheduled( $this->cron_name_daily ) && false === wp_next_scheduled( $this->cron_name_batching ) )
+ {
+ $last_run = get_option( $this->option_name_last_daily_run );
+
+ if( false === $last_run || ! is_integer( $last_run ) )
+ {
+ $last_run = false;
+ }
+ else
+ {
+ $last_run = new \DateTime( '@' . $last_run );
+ }
+
+ //Get now
+ $now = new \DateTime();
+
+ if( false === $last_run || (int)$now->diff( $last_run )->format( '%h' ) >= 24 )
+ {
+ $this->cleanup_basic( );
+
+ wp_schedule_event( time(), 'daily', $this->cron_name_daily );
+
+ update_option( $this->option_name_last_daily_run, $now->getTimestamp( ) );
+
+
+ }
+ }
+ }
+
+ public function schedule_watchdog()
+ {
+ //For testing
+ //$this->cleanup_deactivation();
+
+ //Schedule a global watching cron just in case both other crons get killed
+ if ( ! wp_next_scheduled( $this->cron_name_watcher ) )
+ {
+ wp_schedule_event( time(), 'hourly', $this->cron_name_watcher );
+ }
+
+
+ }
+
+ public function get_themes_outdate_info() {
+ $themes_outdate = get_transient( $this->tran_name_theme_timestamps );
+ if( ! function_exists( 'wp_get_themes' ) )
+ {
+ require_once(ABSPATH . '/wp-admin/includes/theme.php');
+ }
+ $themes = wp_get_themes();
+ $update = false;
+ foreach($themes_outdate as $slug => $v) {
+ if (!isset($themes[$slug])) {
+ unset($themes_outdate[$slug]);
+ $update = true;
+ }
+ }
+ if ($update) {
+ set_transient( $this->tran_name_theme_timestamps, $themes_outdate, DAY_IN_SECONDS );
+ }
+ return $themes_outdate;
+ }
+
+ public function run_check()
+ {
+ if( ! function_exists( 'wp_get_themes' ) )
+ {
+ require_once(ABSPATH . '/wp-admin/includes/theme.php');
+ }
+
+ //Get our previous results
+ $responses = get_transient( $this->tran_name_theme_timestamps );
+
+ if( false === $responses || ! is_array( $responses ) )
+ {
+ $responses = array();
+ }
+
+ $all_themes = get_transient( $this->tran_name_themes_to_batch );
+ //If there wasn't a previous cache
+ if( false === $all_themes || ! is_array( $all_themes ) )
+ {
+ $themes = wp_get_themes();
+ if (is_array($themes)) {
+ foreach ($themes as $theme)
+ {
+ $slug = $theme->get_stylesheet();
+ $all_themes[$slug] = array(
+ 'Name' => $theme->get('Name'),
+ 'Version' => $theme->display('Version', true, false)
+ );
+
+ }
+ }
+ $responses = array();
+ }
+
+ $themes_to_scan = array_splice( $all_themes, 0, apply_filters( 'mainwp_child_theme_health_check_max_themes_to_batch', 10 ) );
+
+ foreach( $themes_to_scan as $slug => $v )
+ {
+
+ $body = $this->try_get_response_body( $slug, false );
+
+ if( false === $body )
+ {
+ continue;
+ }
+
+ //Deserialize the response
+ $obj = unserialize( $body );
+
+ $now = new \DateTime();
+
+ //Sanity check that deserialization worked and that our property exists
+ if( false !== $obj && is_object( $obj ) && property_exists( $obj, 'last_updated' ) )
+ {
+ $last_updated = strtotime( $obj->last_updated );
+ $theme_last_updated_date = new \DateTime( '@'. $last_updated );
+
+ $diff_in_days = $now->diff( $theme_last_updated_date )->format( '%a' );
+
+
+ $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
+
+ if ($diff_in_days < $tolerance_in_days)
+ continue;
+
+ $v['last_updated'] = $last_updated;
+
+ $responses[ $slug ] = $v;
+ }
+ }
+
+ if( ! defined( 'MINUTE_IN_SECONDS' ) )
+ {
+ define( 'MINUTE_IN_SECONDS', 60 );
+ }
+
+ if( ! defined( 'HOUR_IN_SECONDS' ) )
+ {
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS);
+ }
+
+ if( ! defined( 'DAY_IN_SECONDS' ) )
+ {
+ define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS );
+ }
+
+ //Store the master response for usage in the plugin table
+ set_transient( $this->tran_name_theme_timestamps, $responses, DAY_IN_SECONDS );
+
+ if( 0 === count( $all_themes ) )
+ {
+ delete_transient( $this->tran_name_themes_to_batch );
+ wp_schedule_single_event( time() + DAY_IN_SECONDS, $this->cron_name_daily );
+ }
+ else
+ {
+ set_transient( $this->tran_name_themes_to_batch, $all_themes, DAY_IN_SECONDS );
+ wp_schedule_single_event( time(), $this->cron_name_batching );
+
+ }
+ }
+
+
+ private function try_get_response_body( $theme )
+ {
+ //Some of this code is lifted from class-wp-upgrader
+
+ //Get the WordPress current version to be polite in the API call
+ include( ABSPATH . WPINC . '/version.php' );
+
+ if( ! defined( 'MINUTE_IN_SECONDS' ) )
+ {
+ define( 'MINUTE_IN_SECONDS', 60 );
+ }
+
+ if( ! defined( 'HOUR_IN_SECONDS' ) )
+ {
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS);
+ }
+
+ $url = $http_url = 'http://api.wordpress.org/themes/info/1.0/';
+ if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
+ $url = set_url_scheme( $url, 'https' );
+
+ $args = array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ;
+ $args = (object)$args;
+
+ $http_args = array(
+ 'body' => array(
+ 'action' => 'theme_information',
+ 'request' => serialize( $args )
+ )
+ );
+
+
+ $raw_response = wp_remote_post( $url, $http_args );
+
+ if( ! is_wp_error( $raw_response ) && 200 == wp_remote_retrieve_response_code( $raw_response ) )
+ {
+ //Get the actual body
+ //Requires WP 2.7.0
+ $body = wp_remote_retrieve_body( $raw_response );
+
+ //Make sure that it isn't empty and also not an empty serialized object
+ if( '' != $body && 'N;' != $body )
+ {
+ //If valid, return that
+ return $body;
+ }
+ }
+
+ //The above valid
+ //If we previously tried an SSL version try without SSL
+ //Code below same as above block
+ if( $ssl )
+ {
+ $raw_response = wp_remote_post( $http_url, $http_args );
+
+ if( ! is_wp_error( $raw_response ) && 200 == wp_remote_retrieve_response_code( $raw_response ) )
+ {
+ $body = wp_remote_retrieve_body( $raw_response );
+ if( '' != $body && 'N;' != $body )
+ {
+ return $body;
+ }
+ }
+ }
+
+ //Everything above failed, bail
+ return false;
+ }
+
+
+}
+
diff --git a/mainwp-child.php b/mainwp-child.php
index d64a1a3..efedcce 100644
--- a/mainwp-child.php
+++ b/mainwp-child.php
@@ -5,7 +5,7 @@
Description: Child Plugin for MainWP. The plugin is used so the installed blog can be securely managed remotely by your network. Plugin documentation and options can be found here http://docs.mainwp.com
Author: MainWP
Author URI: http://mainwp.com
- Version: 2.0.22
+ Version: 2.0.23
*/
if ((isset($_REQUEST['heatmap']) && $_REQUEST['heatmap'] == '1') || (isset($_REQUEST['mainwpsignature']) && (!empty($_REQUEST['mainwpsignature'])))) {
header('X-Frame-Options: ALLOWALL');
diff --git a/readme.txt b/readme.txt
index a196211..a794a46 100644
--- a/readme.txt
+++ b/readme.txt
@@ -58,7 +58,7 @@ To see full documentation and FAQs please visit [MainWP Documentation](http://do
== Changelog ==
-= 2.0.22 - 8-7-15 =
+= 2.0.23 - 8-7-15 =
* Fixed: An issue with Heatmaps not loading
* Added: Support for the Establish New Connection feature
* Added: Support for the Abandoned plugins detection feature