diff --git a/class/class-mainwp-backup.php b/class/class-mainwp-backup.php index 4ed0543..9d9448c 100644 --- a/class/class-mainwp-backup.php +++ b/class/class-mainwp-backup.php @@ -2,7 +2,7 @@ namespace MainWP\Child; -//phpcs:disable WordPress.WP.AlternativeFunctions -- to custom functions. +//phpcs:disable WordPress.WP.AlternativeFunctions -- to custom file's functions. class MainWP_Backup { protected static $instance = null; @@ -774,7 +774,7 @@ class MainWP_Backup { $this->add_file_to_zipp( rtrim( $path, '/' ) . '/.htaccess', rtrim( str_replace( ABSPATH, '', $path ), '/' ) . '/mainwp-htaccess' ); } - $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ), RecursiveIteratorIterator::SELF_FIRST ); + $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $path ), \RecursiveIteratorIterator::SELF_FIRST ); foreach ( $iterator as $path ) { $name = $path->__toString(); diff --git a/class/class-mainwp-child-branding.php b/class/class-mainwp-child-branding.php index e1604f0..aaff4ef 100644 --- a/class/class-mainwp-child-branding.php +++ b/class/class-mainwp-child-branding.php @@ -1049,7 +1049,7 @@ class MainWP_Child_Branding { return; } - if ( ! function_exists( 'get_plugin_updates' ) ) { + if ( ! function_exists( '\get_plugin_updates' ) ) { include_once ABSPATH . '/wp-admin/includes/update.php'; } diff --git a/class/class-mainwp-child-comments.php b/class/class-mainwp-child-comments.php index c24c788..8b128ae 100644 --- a/class/class-mainwp-child-comments.php +++ b/class/class-mainwp-child-comments.php @@ -184,7 +184,7 @@ class MainWP_Child_Comments { * @return array $allComments Array of all comments found. */ public function get_recent_comments( $pAllowedStatuses, $pCount ) { - if ( ! function_exists( 'get_comment_author_url' ) ) { + if ( ! function_exists( '\get_comment_author_url' ) ) { include_once WPINC . '/comment-template.php'; } $allComments = array(); diff --git a/class/class-mainwp-child-install.php b/class/class-mainwp-child-install.php index 278cefc..168d18b 100644 --- a/class/class-mainwp-child-install.php +++ b/class/class-mainwp-child-install.php @@ -278,11 +278,11 @@ class MainWP_Child_Install { } /** - * Hook to set ssl verify. + * Hook to set ssl verify value. * - * @param array $r - * @param string $url - * @return array $r + * @param array $r Request's array values. + * @param string $url URL request. + * @return array $r Request's array values. */ public static function no_ssl_filter_function( $r, $url ) { $r['sslverify'] = false; diff --git a/class/class-mainwp-child-ithemes-security.php b/class/class-mainwp-child-ithemes-security.php index 8214dfa..ffac69c 100644 --- a/class/class-mainwp-child-ithemes-security.php +++ b/class/class-mainwp-child-ithemes-security.php @@ -1171,7 +1171,7 @@ class MainWP_Child_IThemes_Security { if ( is_callable( 'wp_roles' ) ) { $roles = wp_roles(); } else { - $roles = new WP_Roles(); + $roles = new \WP_Roles(); } $available_roles = array(); diff --git a/class/class-mainwp-child-misc.php b/class/class-mainwp-child-misc.php index 54f6960..174ee46 100644 --- a/class/class-mainwp-child-misc.php +++ b/class/class-mainwp-child-misc.php @@ -47,8 +47,8 @@ class MainWP_Child_Misc { $site_url .= '/'; } - if ( function_exists( 'get_site_icon_url' ) && has_site_icon() ) { - $favi = get_site_icon_url(); + if ( function_exists( '\get_site_icon_url' ) && \has_site_icon() ) { + $favi = \get_site_icon_url(); $favi_url = $favi; } diff --git a/class/class-mainwp-child-plugins-check.php b/class/class-mainwp-child-plugins-check.php index 82ff964..52a7379 100644 --- a/class/class-mainwp-child-plugins-check.php +++ b/class/class-mainwp-child-plugins-check.php @@ -179,7 +179,7 @@ class MainWP_Child_Plugins_Check { if ( ! is_array( $plugins_outdate ) ) { $plugins_outdate = array(); } - if ( ! function_exists( 'get_plugins' ) ) { + if ( ! function_exists( '\get_plugins' ) ) { require_once ABSPATH . '/wp-admin/includes/plugin.php'; } $plugins = get_plugins(); @@ -218,7 +218,7 @@ class MainWP_Child_Plugins_Check { * @throws \Exception Error message on failure. */ public function run_check() { - if ( ! function_exists( 'get_plugins' ) ) { + if ( ! function_exists( '\get_plugins' ) ) { require_once ABSPATH . '/wp-admin/includes/plugin.php'; } diff --git a/class/class-mainwp-child-posts.php b/class/class-mainwp-child-posts.php index 6ca7a1d..24a8647 100644 --- a/class/class-mainwp-child-posts.php +++ b/class/class-mainwp-child-posts.php @@ -683,11 +683,11 @@ class MainWP_Child_Posts { $wprocket_activated = false; if ( \MainWP_Child_WP_Rocket::instance()->is_activated() ) { - if ( function_exists( 'get_rocket_option' ) ) { + if ( function_exists( '\get_rocket_option' ) ) { $wprocket_activated = true; foreach ( $wprocket_fields as $field ) { if ( ! isset( $post_custom[ '_rocket_exclude_' . $field ] ) ) { - if ( ! get_rocket_option( $field ) ) { + if ( ! \get_rocket_option( $field ) ) { $post_custom[ '_rocket_exclude_' . $field ] = array( true ); } } @@ -919,21 +919,21 @@ class MainWP_Child_Posts { '_mainwp_post_dripper', '_bulkpost_do_not_del', '_mainwp_spin_me', - ); - $not_allowed[] = '_mainwp_boilerplate_sites_posts'; - $not_allowed[] = '_mainwp_post_plus'; - $not_allowed[] = '_saved_as_draft'; - $not_allowed[] = '_saved_draft_categories'; - $not_allowed[] = '_saved_draft_tags'; - $not_allowed[] = '_saved_draft_random_privelege'; - $not_allowed[] = '_saved_draft_random_category'; - $not_allowed[] = '_saved_draft_random_publish_date'; - $not_allowed[] = '_saved_draft_publish_date_from'; - $not_allowed[] = '_saved_draft_publish_date_to'; - $not_allowed[] = '_post_to_only_existing_categories'; - $not_allowed[] = '_mainwp_edit_post_site_id'; - $not_allowed[] = '_mainwp_edit_post_id'; - $not_allowed[] = '_edit_post_status'; + '_mainwp_boilerplate_sites_posts', + '_mainwp_post_plus', + '_saved_as_draft', + '_saved_draft_categories', + '_saved_draft_tags', + '_saved_draft_random_privelege', + '_saved_draft_random_category', + '_saved_draft_random_publish_date', + '_saved_draft_publish_date_from', + '_saved_draft_publish_date_to', + '_post_to_only_existing_categories', + '_mainwp_edit_post_site_id', + '_mainwp_edit_post_id', + '_edit_post_status' + ); if ( is_array( $post_custom ) ) { foreach ( $post_custom as $meta_key => $meta_values ) { diff --git a/class/class-mainwp-child-skeleton-key.php b/class/class-mainwp-child-skeleton-key.php index 96a9cca..964a327 100644 --- a/class/class-mainwp-child-skeleton-key.php +++ b/class/class-mainwp-child-skeleton-key.php @@ -59,8 +59,8 @@ class MainWP_Child_Skeleton_Key { MainWP_Helper::write( array( 'error' => 'MainWP_Child fatal error : ' . $error['message'] . ' Line: ' . $error['line'] . ' File: ' . $error['file'] ) ); } } - - register_shutdown_function( 'mainwp_skeleton_key_handle_fatal_error' ); + + register_shutdown_function( 'MainWP\Child\MainWP_Child_Skeleton_Key\mainwp_skeleton_key_handle_fatal_error' ); switch ( $_POST['action'] ) { case 'skeleton_key_visit_site_as_browser': @@ -100,7 +100,7 @@ class MainWP_Child_Skeleton_Key { $url = '/' . $_POST['url']; $expiration = time() + 600; - $manager = WP_Session_Tokens::get_instance( $current_user->ID ); + $manager = \WP_Session_Tokens::get_instance( $current_user->ID ); $token = $manager->create( $expiration ); $secure = is_ssl(); @@ -120,13 +120,13 @@ class MainWP_Child_Skeleton_Key { $post_args['redirection'] = 5; $post_args['decompress'] = false; $post_args['cookies'] = array( - new WP_Http_Cookie( + new \WP_Http_Cookie( array( 'name' => $auth_cookie_name, 'value' => $auth_cookie, ) ), - new WP_Http_Cookie( + new \WP_Http_Cookie( array( 'name' => LOGGED_IN_COOKIE, 'value' => $logged_in_cookie, diff --git a/class/class-mainwp-child-themes-check.php b/class/class-mainwp-child-themes-check.php index 301d793..284974c 100644 --- a/class/class-mainwp-child-themes-check.php +++ b/class/class-mainwp-child-themes-check.php @@ -101,10 +101,10 @@ class MainWP_Child_Themes_Check { if ( ! is_array( $themes_outdate ) ) { $themes_outdate = array(); } - if ( ! function_exists( 'wp_get_themes' ) ) { + if ( ! function_exists( '\wp_get_themes' ) ) { require_once ABSPATH . '/wp-admin/includes/theme.php'; } - $themes = wp_get_themes(); + $themes = \wp_get_themes(); $update = false; foreach ( $themes_outdate as $slug => $v ) { if ( ! isset( $themes[ $slug ] ) ) { @@ -120,7 +120,7 @@ class MainWP_Child_Themes_Check { } public function run_check() { - if ( ! function_exists( 'wp_get_themes' ) ) { + if ( ! function_exists( '\wp_get_themes' ) ) { require_once ABSPATH . '/wp-admin/includes/theme.php'; } @@ -135,7 +135,7 @@ class MainWP_Child_Themes_Check { // If there wasn't a previous cache. if ( false === $all_themes || ! is_array( $all_themes ) ) { $all_themes = array(); - $themes = wp_get_themes(); + $themes = \wp_get_themes(); if ( is_array( $themes ) ) { foreach ( $themes as $theme ) { $slug = $theme->get_stylesheet(); diff --git a/class/class-mainwp-child-updates.php b/class/class-mainwp-child-updates.php index c67c9a1..383af19 100644 --- a/class/class-mainwp-child-updates.php +++ b/class/class-mainwp-child-updates.php @@ -577,8 +577,8 @@ class MainWP_Child_Updates { } elseif ( 'upgrade' === $core_update->response && get_locale() === $core_update->locale && version_compare( $wp_version, $core_update->current, '<=' ) ) { // Upgrade! $upgrade = false; - if ( class_exists( 'Core_Upgrader' ) ) { - $core = new Core_Upgrader(); + if ( class_exists( '\Core_Upgrader' ) ) { + $core = new \Core_Upgrader(); $upgrade = $core->upgrade( $core_update ); } // If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions. @@ -599,8 +599,8 @@ class MainWP_Child_Updates { if ( 'upgrade' === $core_update->response && version_compare( $wp_version, $core_update->current, '<=' ) ) { // Upgrade! $upgrade = false; - if ( class_exists( 'Core_Upgrader' ) ) { - $core = new Core_Upgrader(); + if ( class_exists( '\Core_Upgrader' ) ) { + $core = new \Core_Upgrader(); $upgrade = $core->upgrade( $core_update ); } // If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions diff --git a/class/class-mainwp-client-report-base.php b/class/class-mainwp-client-report-base.php new file mode 100644 index 0000000..f460930 --- /dev/null +++ b/class/class-mainwp-client-report-base.php @@ -0,0 +1,796 @@ + 'comments', // actual context values: post, page. + 'plugin' => 'plugins', + 'users' => 'profiles', + 'user' => 'profiles', + 'session' => 'sessions', + 'setting' => 'settings', + 'theme' => 'themes', + 'posts' => 'post', + 'pages' => 'page', + 'widgets' => 'widgets', + 'widget' => 'widgets', + 'menu' => 'menus', + 'backups' => 'backups', + 'backup' => 'backups', + 'sucuri' => 'sucuri_scan', + 'maintenance' => 'mainwp_maintenance', + 'wordfence' => 'wordfence_scan', + 'backups' => 'backups', + 'backup' => 'backups', + 'media' => 'media', + ); + + $context = isset( $mapping_contexts[ $context ] ) ? $mapping_contexts[ $context ] : $context; + return strtolower( $context ); + } + + public function get_connector_by_compatible_context( $context ) { + + $connector = ''; + + $mapping_connectors = array( + 'plugins' => 'installer', + 'themes' => 'installer', + 'WordPress' => 'installer', + 'profiles' => 'users', + 'comments' => 'comments', + 'settings' => 'settings', + 'post' => 'posts', + 'page' => 'posts', + 'widgets' => 'widgets', + 'menus' => 'menus', + 'backups' => 'mainwp_backups', + 'sucuri_scan' => 'mainwp_sucuri', + 'mainwp_maintenance' => 'mainwp_maintenance', + 'wordfence_scan' => 'mainwp_wordfence', + 'media' => 'media', + ); + + if ( isset( $mapping_connectors[ $context ] ) ) { + $connector = $mapping_connectors[ $context ]; + } + + return $connector; + } + + public function get_compatible_action( $action, $context = '' ) { + + $mapping_actions = array( + 'restored' => 'untrashed', + 'spam' => 'spammed', + ); + + if ( isset( $mapping_actions[ $action ] ) ) { + return $mapping_actions[ $action ]; + } + + if ( 'mainwp_maintenance' == $context ) { + if ( 'process' == $action ) { + $action = 'maintenance'; + } + } elseif ( 'sucuri_scan' == $context ) { + if ( 'checks' == $action ) { + $action = 'sucuri_scan'; + } + } elseif ( 'wordfence_scan' == $context ) { + if ( 'scan' == $action ) { + $action = 'wordfence_scan'; + } + } + return $action; + } + + public function get_stream_get_params( $other_tokens, $sections ) { + + $allowed_params = array( + 'connector', + 'context', + 'action', + 'author', + 'author_role', + 'object_id', + 'search', + 'date', + 'date_from', + 'date_to', + 'record__in', + 'blog_id', + 'ip', + ); + + $args = array(); + foreach ( $allowed_params as $param ) { + $paramval = \wp_mainwp_stream_filter_input( INPUT_POST, $param ); + if ( $paramval || '0' === $paramval ) { + $args[ $param ] = $paramval; + } + } + + foreach ( $args as $arg => $val ) { + if ( ! in_array( $arg, $allowed_params ) ) { + unset( $args[ $arg ] ); + } + } + + $exclude_connector_posts = $this->get_stream_get_not_in_params( $sections, $other_tokens ); + if ( $exclude_connector_posts ) { + $args['connector__not_in'] = array( 'posts' ); + } + + $args['action__not_in'] = array( 'login' ); + + $args['with-meta'] = 1; + + if ( isset( $args['date_from'] ) ) { + $args['date_from'] = date( 'Y-m-d', $args['date_from'] ); // phpcs:ignore -- local time. + } + + if ( isset( $args['date_to'] ) ) { + $args['date_to'] = date( 'Y-m-d', $args['date_to'] ); // phpcs:ignore -- local time. + } + + if ( MainWP_Child_Branding::instance()->is_branding() ) { + $args['hide_child_reports'] = 1; + } + + $args['records_per_page'] = 9999; + + return $args; + } + + private function get_stream_get_not_in_params( $sections, $other_tokens ) { + + $exclude_connector_posts = true; + + $parts = array( 'header', 'body', 'footer' ); + foreach ( $parts as $part ) { + if ( isset( $sections[ $part ] ) && isset( $sections[ $part ]['section_token'] ) && is_array( $sections[ $part ]['section_token'] ) ) { + foreach ( $sections[ $part ]['section_token'] as $sec ) { + if ( false !== strpos( $sec, '[section.posts' ) || false !== strpos( $sec, '[section.pages' ) ) { + $exclude_connector_posts = false; + break; + } + } + } + if ( ! $exclude_connector_posts ) { + break; + } + } + + if ( $exclude_connector_posts ) { + foreach ( $parts as $part ) { + if ( isset( $other_tokens[ $part ] ) && is_array( $other_tokens[ $part ] ) ) { + foreach ( $other_tokens[ $part ] as $sec ) { + if ( false !== strpos( $sec, '[post.' ) || false !== strpos( $sec, '[page.' ) ) { + $exclude_connector_posts = false; + break; + } + } + } + if ( ! $exclude_connector_posts ) { + break; + } + } + } + return $exclude_connector_posts; + } + + public function get_stream_others_tokens( $records, $other_tokens, $skip_records ) { + $other_tokens_data = array(); + $parts = array( 'header', 'body', 'footer' ); + foreach ( $parts as $part ) { + if ( isset( $other_tokens[ $part ] ) && is_array( $other_tokens[ $part ] ) ) { + $other_tokens_data[ $part ] = $this->get_other_tokens_data( $records, $other_tokens[ $part ], $skip_records ); + } + } + return $other_tokens_data; + } + + public function get_stream_sections_data( $records, $sections, $skip_records ) { + $sections_data = array(); + $parts = array( 'header', 'body', 'footer' ); + foreach ( $parts as $part ) { + if ( isset( $sections[ $part ] ) && is_array( $sections[ $part ] ) && ! empty( $sections[ $part ] ) ) { + foreach ( $sections[ $part ]['section_token'] as $index => $sec ) { + $tokens = $sections[ $part ]['section_content_tokens'][ $index ]; + $sections_data[ $part ][ $index ] = $this->get_section_loop_data( $records, $tokens, $sec, $skip_records ); + } + } + } + return $sections_data; + } + + protected function fix_logs_posts_created( &$records, &$skip_records ) { + + $args = array( + 'post_type' => 'post', + 'post_status' => 'publish', + 'date_query' => array( + 'column' => 'post_date', + 'after' => $args['date_from'], + 'before' => $args['date_to'], + ), + ); + + $result = new \WP_Query( $args ); + $records_created_posts = $result->posts; + + if ( $records_created_posts ) { + + $count_records = count( $records ); + for ( $i = 0; $i < $count_records; $i++ ) { + $record = $records[ $i ]; + if ( 'posts' == $record->connector && 'post' == $record->context && 'created' == $record->action ) { + if ( ! in_array( $record->ID, $skip_records ) ) { + $skip_records[] = $record->ID; // so avoid this created logging, will use logging query from posts data. + } + } + } + + $post_authors = array(); + + foreach ( $records_created_posts as $_post ) { + $au_id = $_post->post_author; + if ( ! isset( $post_authors[ $au_id ] ) ) { + $au = get_user_by( 'id', $au_id ); + $post_authors[ $au_id ] = $au->display_name; + } + $au_name = $post_authors[ $au_id ]; + + // simulate logging created posts record. + $stdObj = new \stdClass(); + $stdObj->ID = 0; // simulate ID value. + $stdObj->connector = 'posts'; + $stdObj->context = 'post'; + $stdObj->action = 'created'; + $stdObj->created = $_post->post_date; + $stdObj->meta = array( + 'post_title' => array( $_post->post_title ), + 'user_meta' => array( $au_name ), + ); + + $records[] = $stdObj; + } + } + } + + public function get_other_tokens_data( $records, $tokens, &$skip_records ) { + + $token_values = array(); + + if ( ! is_array( $tokens ) ) { + $tokens = array(); + } + + $backups_created_time_to_fix = array(); + + foreach ( $tokens as $token ) { + if ( isset( $token_values[ $token ] ) ) { + continue; + } + $str_tmp = str_replace( array( '[', ']' ), '', $token ); + $array_tmp = explode( '.', $str_tmp ); + if ( is_array( $array_tmp ) ) { + $context = ''; + $action = ''; + $data = ''; + if ( 2 === count( $array_tmp ) ) { + list( $context, $data ) = $array_tmp; + } elseif ( 3 === count( $array_tmp ) ) { + list( $context, $action, $data ) = $array_tmp; + } + $context = $this->get_compatible_context( $context ); + // to compatible with new version of child report. + // to check condition for grabbing report data. + $connector = $this->get_connector_by_compatible_context( $context ); + $action = $this->get_compatible_action( $action, $context ); + // custom values. + if ( 'profiles' == $context ) { + if ( 'created' == $action || 'deleted' == $action ) { + $context = 'users'; // see class-connector-user.php. + } + } + switch ( $data ) { + case 'count': + $token_values[ $token ] = $this->get_other_tokens_count( $records, $connector, $context, $action, $skip_records, $backups_created_time_to_fix ); + break; + } + } + } + + return $token_values; + } + + private function get_other_tokens_count( $records, $connector, $context, $action, &$skip_records, &$backups_created_time_to_fix ) { // phpcs:ignore -- ignore complex method notice. + $count = 0; + + foreach ( $records as $record ) { + // check connector. + if ( 'editor' == $record->connector ) { + if ( ! in_array( $context, array( 'plugins', 'themes' ) ) || 'updated' !== $action ) { + continue; + } + } elseif ( $connector !== $record->connector ) { + continue; + } + + $valid_context = false; + // check context. + if ( 'comments' == $context ) { // multi values. + $comment_contexts = array( 'post', 'page' ); + if ( ! in_array( $record->context, $comment_contexts ) ) { + continue; + } + $valid_context = true; + } elseif ( 'post' === $context && 'created' === $action ) { + if ( in_array( $record->ID, $skip_records ) ) { + continue; + } + $valid_context = true; + } elseif ( 'menus' == $context ) { + $valid_context = true; // ok, pass, don't check context. + } elseif ( 'editor' == $record->connector ) { + $valid_context = true; // ok, pass, checked above. + } elseif ( 'media' == $connector && 'media' == $record->connector ) { + $valid_context = true; // ok, pass, do not check context. + } elseif ( 'widgets' == $connector && 'widgets' == $record->connector ) { + $valid_context = true; // ok, pass, don't check context. + } + + $valid_context = ( $valid_context || strtolower( $record->context ) == $context ) ? true : false; + if ( ! $valid_context ) { + continue; + } + // custom action value. + if ( 'widgets' == $connector ) { + if ( 'deleted' == $action ) { + $action = 'removed'; // action saved in database. + } + } + + // check action. + if ( 'backups' === $context ) { + if ( ! $this->is_backup_action( $record->action ) ) { + continue; + } + $created = strtotime( $record->created ); + if ( in_array( $created, $backups_created_time_to_fix ) ) { + if ( ! in_array( $record->ID, $skip_records ) ) { + $skip_records[] = $record->ID; + } + continue; + } else { + $backups_created_time_to_fix[] = $created; + } + } else { + if ( $action !== $record->action ) { + continue; + } + + if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) { + $new_status = $this->get_stream_meta_data( $record, 'new_status' ); + if ( 'draft' === $new_status ) { + continue; + } + } elseif ( 'updated' === $action && ( 'themes' === $context || 'plugins' === $context ) ) { + $name = $this->get_stream_meta_data( $record, 'name' ); + if ( empty( $name ) ) { + if ( ! in_array( $record->ID, $skip_records ) ) { + $skip_records[] = $record->ID; + } + continue; + } else { + $old_version = $this->get_stream_meta_data( $record, 'old_version' ); + $version = $this->get_stream_meta_data( $record, 'version' ); + if ( version_compare( $version, $old_version, '<=' ) ) { + if ( ! in_array( $record->ID, $skip_records ) ) { + $skip_records[] = $record->ID; + } + continue; + } + } + } + } + $count ++; + } + return $count; + } + + public function get_section_loop_data( $records, $tokens, $section, $skip_records = array() ) { + + $context = ''; + $action = ''; + + $str_tmp = str_replace( array( '[', ']' ), '', $section ); + $array_tmp = explode( '.', $str_tmp ); + if ( is_array( $array_tmp ) ) { + if ( 2 === count( $array_tmp ) ) { + list( $str1, $context ) = $array_tmp; + } elseif ( 3 === count( $array_tmp ) ) { + list( $str1, $context, $action ) = $array_tmp; + } + } + + // get db $context value by mapping. + $context = $this->get_compatible_context( $context ); + // to compatible with new version of child report. + // to check condition for grabbing report data. + $connector = $this->get_connector_by_compatible_context( $context ); + + $action = $this->get_compatible_action( $action, $context ); + + if ( 'profiles' == $context ) { + if ( 'created' == $action || 'deleted' == $action ) { + $context = 'users'; // see class-connector-user.php. + } + } + + return $this->get_section_loop_records( $records, $tokens, $connector, $context, $action, $skip_records ); + } + + public function get_section_loop_records( $records, $tokens, $connector, $context, $action, $skip_records ) { // phpcs:ignore -- ignore complex method notice. + + $loops = array(); + $loop_count = 0; + foreach ( $records as $record ) { + + if ( in_array( $record->ID, $skip_records ) ) { + continue; + } + + if ( 'editor' == $record->connector ) { + if ( ! in_array( $context, array( 'plugins', 'themes' ) ) || 'updated' !== $action ) { + continue; + } + } elseif ( $connector !== $record->connector ) { + continue; + } + + $valid_context = false; + + if ( 'comments' == $context ) { + $comment_contexts = array( 'post', 'page' ); + if ( ! in_array( $record->context, $comment_contexts ) ) { + continue; + } + $valid_context = true; + } elseif ( 'menus' == $context ) { + $valid_context = true; // ok, pass, don't check context. + } elseif ( 'editor' == $record->connector ) { + $valid_context = true; // ok, pass, checked above. + } elseif ( 'media' == $connector && 'media' == $record->connector ) { + $valid_context = true; // ok, pass, do not check context. + } elseif ( 'widgets' == $connector && 'widgets' == $record->connector ) { + $valid_context = true; // ok, pass, don't check context. + } + + $valid_context = ( $valid_context || strtolower( $record->context ) == $context ) ? true : false; + + if ( ! $valid_context ) { + continue; + } + + // custom action value! + if ( 'widgets' == $connector ) { + if ( 'deleted' == $action ) { + $action = 'removed'; // action saved in database! + } + } + + if ( 'backups' == $context ) { + if ( ! $this->is_backup_action( $record->action ) ) { + continue; + } + } elseif ( $action !== $record->action ) { + continue; + } + + if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) { + $new_status = $this->get_stream_meta_data( $record, 'new_status' ); + if ( 'draft' === $new_status ) { // avoid auto save post! + continue; + } + } + $token_values = $this->get_section_loop_token_values( $record, $context, $tokens ); + if ( ! empty( $token_values ) ) { + $loops[ $loop_count ] = $token_values; + $loop_count ++; + } + } + return $loops; + } + + public function is_backup_action( $action ) { + if ( in_array( $action, array( 'mainwp_backup', 'backupbuddy_backup', 'backupwordpress_backup', 'backwpup_backup', 'updraftplus_backup', 'wptimecapsule_backup', 'wpvivid_backup' ) ) ) { + return true; + } + return false; + } + + private function get_section_loop_token_values( $record, $context, $tokens ) { + + $token_values = array(); + foreach ( $tokens as $token ) { + $data = ''; + $token_name = str_replace( array( '[', ']' ), '', $token ); + $array_tmp = explode( '.', $token_name ); + + if ( 'user.name' === $token_name ) { + $data = 'display_name'; + } else { + if ( 1 === count( $array_tmp ) ) { + list( $data ) = $array_tmp; + } elseif ( 2 === count( $array_tmp ) ) { + list( $str1, $data ) = $array_tmp; + } elseif ( 3 === count( $array_tmp ) ) { + list( $str1, $str2, $data ) = $array_tmp; + } + + if ( 'version' === $data ) { + if ( 'old' === $str2 ) { + $data = 'old_version'; + } elseif ( 'current' === $str2 && 'WordPress' === $str1 ) { + $data = 'new_version'; + } + } + } + + if ( 'role' === $data ) { + $data = 'roles'; + } + + $tok_value = $this->get_section_token_value( $record, $data, $context, $token ); + + $token_values[ $token ] = $tok_value; + + if ( empty( $tok_value ) ) { + $msg = 'MainWP Child Report:: skip empty value :: token :: ' . $token . ' :: record :: ' . print_r( $record, true ); // phpcs:ignore -- debug mode only. + MainWP_Helper::log_debug( $msg ); + } + } + return $token_values; + } + + public function get_section_token_value( $record, $data, $context, $token ) { // phpcs:ignore -- ignore complex method notice. + $tok_value = ''; + switch ( $data ) { + case 'ID': + $tok_value = $record->ID; + break; + case 'date': + $tok_value = MainWP_Helper::format_date( MainWP_Helper::get_timestamp( strtotime( $record->created ) ) ); + break; + case 'time': + $tok_value = MainWP_Helper::format_time( MainWP_Helper::get_timestamp( strtotime( $record->created ) ) ); + break; + case 'area': + $data = 'sidebar_name'; + $tok_value = $this->get_stream_meta_data( $record, $data ); + break; + case 'name': + case 'version': + case 'old_version': + case 'new_version': + case 'display_name': + case 'roles': + if ( 'name' == $data ) { + if ( 'profiles' == $context ) { + $data = 'display_name'; + } + } + $tok_value = $this->get_stream_meta_data( $record, $data ); + break; + case 'title': + if ( 'comments' === $context ) { + $tok_value = $record->summary; + } else { + if ( 'page' === $context || 'post' === $context ) { + $data = 'post_title'; + } elseif ( 'menus' === $record->connector ) { + $data = 'name'; + } + $tok_value = $this->get_stream_meta_data( $record, $data ); + } + break; + case 'author': + $tok_value = $this->get_author_data_token_value( $record, $connector, $context, $data ); + + break; + case 'status': + case 'webtrust': + $value = ''; + if ( 'sucuri_scan' === $context ) { + $value = $this->get_sucuri_scan_token_value( $record, $data ); + } + $tok_value = $value; + break; + case 'details': + case 'result': + $tok_value = $this->get_result_data_token_value( $record, $context, $data ); + break; + case 'type': + if ( 'backups' === $context ) { + $tok_value = $this->get_stream_meta_data( $record, $data ); + } else { + $tok_value = $token; + } + break; + default: + $tok_value = 'N/A'; + break; + } + return $tok_value; + } + + public function get_stream_meta_data( $record, $data ) { + + if ( empty( $record ) ) { + return ''; + } + + $meta_key = $data; + + $value = ''; + + if ( isset( $record->meta ) ) { + $meta = $record->meta; + + if ( isset( $meta[ $meta_key ] ) ) { + $value = $meta[ $meta_key ]; + $value = ( 'user_meta' == $meta_key && isset( $value[1] ) ) ? $value[1] : current( $value ); + + if ( 'author_meta' === $meta_key ) { + $value = maybe_unserialize( $value ); + if ( is_array( $value ) ) { + $value = $value['display_name']; + // fix empty author value! + if ( empty( $value ) ) { + if ( isset( $value['agent'] ) && ! empty( $value['agent'] ) ) { + $value = $value['agent']; + } + } + } + if ( ! is_string( $value ) ) { + $value = ''; + } + } + } + } + + return $value; + } + + private function get_author_data_token_value( $record, $connector, $context, $data ) { + if ( 'comment' == $connector ) { + $data = 'user_name'; + } else { + $data = 'user_meta'; + } + $value = $this->get_stream_meta_data( $record, $data ); + + if ( empty( $value ) && 'comments' === $context ) { + $value = __( 'Guest', 'mainwp-child' ); + } + + // check compatibility with old meta data. + if ( empty( $value ) ) { + $value = $this->get_stream_meta_data( $record, 'author_meta' ); + } + + return $value; + } + + private function get_result_data_token_value( $record, $context, $data ) { + if ( 'mainwp_maintenance' === $context && 'details' == $data ) { + $tok_value = $this->get_mainwp_maintenance_token_value( $record, $data ); + } elseif ( 'wordfence_scan' === $context || 'mainwp_maintenance' === $context ) { + $meta_value = $this->get_stream_meta_data( $record, $data ); + if ( 'wordfence_scan' === $context && 'result' == $data ) { + // SUM_FINAL:Scan complete. You have xxx new issues to fix. See below. + // SUM_FINAL:Scan complete. Congratulations, no new problems found. + if ( stripos( $meta_value, 'Congratulations' ) ) { + $meta_value = 'No issues detected'; + } elseif ( stripos( $meta_value, 'You have' ) ) { + $meta_value = 'Issues Detected'; + } else { + $meta_value = ''; + } + } + $tok_value = $meta_value; + } + return $tok_value; + } + + private function get_sucuri_scan_token_value( $record, $data ) { + $tok_value = ''; + $scan_data = $this->get_stream_meta_data( $record, 'scan_data' ); + if ( ! empty( $scan_data ) ) { + $scan_data = maybe_unserialize( base64_decode( $scan_data ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode function is used for begin reasons. + if ( is_array( $scan_data ) ) { + + $blacklisted = $scan_data['blacklisted']; + $malware_exists = $scan_data['malware_exists']; + + $status = array(); + if ( $blacklisted ) { + $status[] = __( 'Site Blacklisted', 'mainwp-child' ); } + if ( $malware_exists ) { + $status[] = __( 'Site With Warnings', 'mainwp-child' ); } + + if ( 'status' == $data ) { + $tok_value = count( $status ) > 0 ? implode( ', ', $status ) : __( 'Verified Clear', 'mainwp-child' ); + } elseif ( 'webtrust' == $data ) { + $tok_value = $blacklisted ? __( 'Site Blacklisted', 'mainwp-child' ) : __( 'Trusted', 'mainwp-child' ); + } + } + } else { + $tok_value = $this->get_stream_meta_data( $record, $data ); + } + return $tok_value; + } + + private function get_mainwp_maintenance_token_value( $record, $data ) { + + $maintenance_details = array( + 'revisions' => __( 'Delete all post revisions', 'mainwp-child' ), + 'revisions_max' => __( 'Delete all post revisions, except for the last:', 'mainwp-child' ), + 'autodraft' => __( 'Delete all auto draft posts', 'mainwp-child' ), + 'trashpost' => __( 'Delete trash posts', 'mainwp-child' ), + 'spam' => __( 'Delete spam comments', 'mainwp-child' ), + 'pending' => __( 'Delete pending comments', 'mainwp-child' ), + 'trashcomment' => __( 'Delete trash comments', 'mainwp-child' ), + 'tags' => __( 'Delete tags with 0 posts associated', 'mainwp-child' ), + 'categories' => __( 'Delete categories with 0 posts associated', 'mainwp-child' ), + 'optimize' => __( 'Optimize database tables', 'mainwp-child' ), + ); + + $meta_value = $this->get_stream_meta_data( $record, $data ); + $meta_value = explode( ',', $meta_value ); + + $details = array(); + + if ( is_array( $meta_value ) ) { + foreach ( $meta_value as $mt ) { + if ( isset( $maintenance_details[ $mt ] ) ) { + if ( 'revisions_max' == $mt ) { + $max_revisions = $this->get_stream_meta_data( $record, 'revisions' ); + $dtl = $maintenance_details['revisions_max'] . ' ' . $max_revisions; + } else { + $dtl = $maintenance_details[ $mt ]; + } + $details[] = $dtl; + } + } + } + $tok_value = implode( ', ', $details ); + return $tok_value; + } +} diff --git a/class/class-mainwp-client-report.php b/class/class-mainwp-client-report.php index eb86011..3e811da 100644 --- a/class/class-mainwp-client-report.php +++ b/class/class-mainwp-client-report.php @@ -2,7 +2,7 @@ namespace MainWP\Child; -class MainWP_Client_Report { +class MainWP_Client_Report extends MainWP_Client_Report_Base { public static $instance = null; @@ -77,7 +77,7 @@ class MainWP_Client_Report { $information = array(); - if ( ! function_exists( 'wp_mainwp_stream_get_instance' ) ) { + if ( ! function_exists( '\wp_mainwp_stream_get_instance' ) ) { $information['error'] = __( 'No MainWP Child Reports plugin installed.', 'mainwp-child' ); MainWP_Helper::write( $information ); } @@ -112,101 +112,7 @@ class MainWP_Client_Report { return true; } - - public function is_backup_action( $action ) { - if ( in_array( $action, array( 'mainwp_backup', 'backupbuddy_backup', 'backupwordpress_backup', 'backwpup_backup', 'updraftplus_backup', 'wptimecapsule_backup', 'wpvivid_backup' ) ) ) { - return true; - } - return false; - } - - public function get_compatible_context( $context ) { - // convert context name of tokens to context name saved in child report. - // some context are not difference. - $mapping_contexts = array( - 'comment' => 'comments', // actual context values: post, page. - 'plugin' => 'plugins', - 'users' => 'profiles', - 'user' => 'profiles', - 'session' => 'sessions', - 'setting' => 'settings', - 'theme' => 'themes', - 'posts' => 'post', - 'pages' => 'page', - 'widgets' => 'widgets', - 'widget' => 'widgets', - 'menu' => 'menus', - 'backups' => 'backups', - 'backup' => 'backups', - 'sucuri' => 'sucuri_scan', - 'maintenance' => 'mainwp_maintenance', - 'wordfence' => 'wordfence_scan', - 'backups' => 'backups', - 'backup' => 'backups', - 'media' => 'media', - ); - - $context = isset( $mapping_contexts[ $context ] ) ? $mapping_contexts[ $context ] : $context; - return strtolower( $context ); - } - - - public function get_connector_by_compatible_context( $context ) { - - $connector = ''; - - $mapping_connectors = array( - 'plugins' => 'installer', - 'themes' => 'installer', - 'WordPress' => 'installer', - 'profiles' => 'users', - 'comments' => 'comments', - 'settings' => 'settings', - 'post' => 'posts', - 'page' => 'posts', - 'widgets' => 'widgets', - 'menus' => 'menus', - 'backups' => 'mainwp_backups', - 'sucuri_scan' => 'mainwp_sucuri', - 'mainwp_maintenance' => 'mainwp_maintenance', - 'wordfence_scan' => 'mainwp_wordfence', - 'media' => 'media', - ); - - if ( isset( $mapping_connectors[ $context ] ) ) { - $connector = $mapping_connectors[ $context ]; - } - - return $connector; - } - - public function get_compatible_action( $action, $context = '' ) { - - $mapping_actions = array( - 'restored' => 'untrashed', - 'spam' => 'spammed', - ); - - if ( isset( $mapping_actions[ $action ] ) ) { - return $mapping_actions[ $action ]; - } - - if ( 'mainwp_maintenance' == $context ) { - if ( 'process' == $action ) { - $action = 'maintenance'; - } - } elseif ( 'sucuri_scan' == $context ) { - if ( 'checks' == $action ) { - $action = 'sucuri_scan'; - } - } elseif ( 'wordfence_scan' == $context ) { - if ( 'scan' == $action ) { - $action = 'wordfence_scan'; - } - } - return $action; - } - + public function get_stream() { $sections = isset( $_POST['sections'] ) ? maybe_unserialize( base64_decode( $_POST['sections'] ) ) : array(); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode function is used for begin reasons. @@ -223,8 +129,8 @@ class MainWP_Client_Report { unset( $_POST['other_tokens'] ); $args = $this->get_stream_get_params( $other_tokens, $sections ); - $records = wp_mainwp_stream_get_instance()->db->query( $args ); - + $records = \wp_mainwp_stream_get_instance()->db->query( $args ); + if ( ! is_array( $records ) ) { $records = array(); } @@ -240,691 +146,14 @@ class MainWP_Client_Report { $other_tokens_data = $this->get_stream_others_tokens( $records, $other_tokens, $skip_records ); $sections_data = $this->get_stream_sections_data( $records, $sections, $skip_records ); - + $information = array( 'other_tokens_data' => $other_tokens_data, 'sections_data' => $sections_data, ); return $information; } - - private function get_stream_get_params( $other_tokens, $sections ) { - - $allowed_params = array( - 'connector', - 'context', - 'action', - 'author', - 'author_role', - 'object_id', - 'search', - 'date', - 'date_from', - 'date_to', - 'record__in', - 'blog_id', - 'ip', - ); - - $args = array(); - foreach ( $allowed_params as $param ) { - $paramval = wp_mainwp_stream_filter_input( INPUT_POST, $param ); - if ( $paramval || '0' === $paramval ) { - $args[ $param ] = $paramval; - } - } - - foreach ( $args as $arg => $val ) { - if ( ! in_array( $arg, $allowed_params ) ) { - unset( $args[ $arg ] ); - } - } - - $exclude_connector_posts = $this->get_stream_get_not_in_params( $sections, $other_tokens ); - if ( $exclude_connector_posts ) { - $args['connector__not_in'] = array( 'posts' ); - } - - $args['action__not_in'] = array( 'login' ); - - $args['with-meta'] = 1; - - if ( isset( $args['date_from'] ) ) { - $args['date_from'] = date( 'Y-m-d', $args['date_from'] ); // phpcs:ignore -- local time. - } - - if ( isset( $args['date_to'] ) ) { - $args['date_to'] = date( 'Y-m-d', $args['date_to'] ); // phpcs:ignore -- local time. - } - - if ( MainWP_Child_Branding::instance()->is_branding() ) { - $args['hide_child_reports'] = 1; - } - - $args['records_per_page'] = 9999; - - return $args; - } - - private function get_stream_get_not_in_params( $sections, $other_tokens ) { - - $exclude_connector_posts = true; - - $parts = array( 'header', 'body', 'footer' ); - foreach ( $parts as $part ) { - if ( isset( $sections[ $part ] ) && isset( $sections[ $part ]['section_token'] ) && is_array( $sections[ $part ]['section_token'] ) ) { - foreach ( $sections[ $part ]['section_token'] as $sec ) { - if ( false !== strpos( $sec, '[section.posts' ) || false !== strpos( $sec, '[section.pages' ) ) { - $exclude_connector_posts = false; - break; - } - } - } - if ( ! $exclude_connector_posts ) { - break; - } - } - - if ( $exclude_connector_posts ) { - foreach ( $parts as $part ) { - if ( isset( $other_tokens[ $part ] ) && is_array( $other_tokens[ $part ] ) ) { - foreach ( $other_tokens[ $part ] as $sec ) { - if ( false !== strpos( $sec, '[post.' ) || false !== strpos( $sec, '[page.' ) ) { - $exclude_connector_posts = false; - break; - } - } - } - if ( ! $exclude_connector_posts ) { - break; - } - } - } - return $exclude_connector_posts; - } - - private function get_stream_others_tokens( $records, $other_tokens, $skip_records ) { - $other_tokens_data = array(); - $parts = array( 'header', 'body', 'footer' ); - foreach ( $parts as $part ) { - if ( isset( $other_tokens[ $part ] ) && is_array( $other_tokens[ $part ] ) ) { - $other_tokens_data[ $part ] = $this->get_other_tokens_data( $records, $other_tokens[ $part ], $skip_records ); - } - } - return $other_tokens_data; - } - - private function get_stream_sections_data( $records, $sections, $skip_records ) { - $sections_data = array(); - $parts = array( 'header', 'body', 'footer' ); - foreach ( $parts as $part ) { - if ( isset( $sections[ $part ] ) && is_array( $sections[ $part ] ) && ! empty( $sections[ $part ] ) ) { - foreach ( $sections[ $part ]['section_token'] as $index => $sec ) { - $tokens = $sections[ $part ]['section_content_tokens'][ $index ]; - $sections_data[ $part ][ $index ] = $this->get_section_loop_data( $records, $tokens, $sec, $skip_records ); - } - } - } - return $sections_data; - } - - private function fix_logs_posts_created( &$records, &$skip_records ) { - - $args = array( - 'post_type' => 'post', - 'post_status' => 'publish', - 'date_query' => array( - 'column' => 'post_date', - 'after' => $args['date_from'], - 'before' => $args['date_to'], - ), - ); - - $result = new \WP_Query( $args ); - $records_created_posts = $result->posts; - - if ( $records_created_posts ) { - - $count_records = count( $records ); - for ( $i = 0; $i < $count_records; $i++ ) { - $record = $records[ $i ]; - if ( 'posts' == $record->connector && 'post' == $record->context && 'created' == $record->action ) { - if ( ! in_array( $record->ID, $skip_records ) ) { - $skip_records[] = $record->ID; // so avoid this created logging, will use logging query from posts data. - } - } - } - - $post_authors = array(); - - foreach ( $records_created_posts as $_post ) { - $au_id = $_post->post_author; - if ( ! isset( $post_authors[ $au_id ] ) ) { - $au = get_user_by( 'id', $au_id ); - $post_authors[ $au_id ] = $au->display_name; - } - $au_name = $post_authors[ $au_id ]; - - // simulate logging created posts record. - $stdObj = new \stdClass(); - $stdObj->ID = 0; // simulate ID value. - $stdObj->connector = 'posts'; - $stdObj->context = 'post'; - $stdObj->action = 'created'; - $stdObj->created = $_post->post_date; - $stdObj->meta = array( - 'post_title' => array( $_post->post_title ), - 'user_meta' => array( $au_name ), - ); - - $records[] = $stdObj; - } - } - } - - public function get_other_tokens_data( $records, $tokens, &$skip_records ) { - - $token_values = array(); - - if ( ! is_array( $tokens ) ) { - $tokens = array(); - } - - $backups_created_time_to_fix = array(); - - foreach ( $tokens as $token ) { - if ( isset( $token_values[ $token ] ) ) { - continue; - } - $str_tmp = str_replace( array( '[', ']' ), '', $token ); - $array_tmp = explode( '.', $str_tmp ); - if ( is_array( $array_tmp ) ) { - $context = ''; - $action = ''; - $data = ''; - if ( 2 === count( $array_tmp ) ) { - list( $context, $data ) = $array_tmp; - } elseif ( 3 === count( $array_tmp ) ) { - list( $context, $action, $data ) = $array_tmp; - } - $context = $this->get_compatible_context( $context ); - // to compatible with new version of child report. - // to check condition for grabbing report data. - $connector = $this->get_connector_by_compatible_context( $context ); - $action = $this->get_compatible_action( $action, $context ); - // custom values. - if ( 'profiles' == $context ) { - if ( 'created' == $action || 'deleted' == $action ) { - $context = 'users'; // see class-connector-user.php. - } - } - switch ( $data ) { - case 'count': - $token_values[ $token ] = $this->get_other_tokens_count( $records, $connector, $context, $action, $skip_records, $backups_created_time_to_fix ); - break; - } - } - } - - return $token_values; - } - - private function get_other_tokens_count( $records, $connector, $context, $action, &$skip_records, &$backups_created_time_to_fix ) { // phpcs:ignore -- ignore complex method notice. - $count = 0; - - foreach ( $records as $record ) { - // check connector. - if ( 'editor' == $record->connector ) { - if ( ! in_array( $context, array( 'plugins', 'themes' ) ) || 'updated' !== $action ) { - continue; - } - } elseif ( $connector !== $record->connector ) { - continue; - } - - $valid_context = false; - // check context. - if ( 'comments' == $context ) { // multi values. - $comment_contexts = array( 'post', 'page' ); - if ( ! in_array( $record->context, $comment_contexts ) ) { - continue; - } - $valid_context = true; - } elseif ( 'post' === $context && 'created' === $action ) { - if ( in_array( $record->ID, $skip_records ) ) { - continue; - } - $valid_context = true; - } elseif ( 'menus' == $context ) { - $valid_context = true; // ok, pass, don't check context. - } elseif ( 'editor' == $record->connector ) { - $valid_context = true; // ok, pass, checked above. - } elseif ( 'media' == $connector && 'media' == $record->connector ) { - $valid_context = true; // ok, pass, do not check context. - } elseif ( 'widgets' == $connector && 'widgets' == $record->connector ) { - $valid_context = true; // ok, pass, don't check context. - } - - if ( ! $valid_context || strtolower( $record->context ) !== $context ) { - continue; - } - - // custom action value. - if ( 'widgets' == $connector ) { - if ( 'deleted' == $action ) { - $action = 'removed'; // action saved in database. - } - } - - // check action. - if ( 'backups' === $context ) { - if ( ! $this->is_backup_action( $record->action ) ) { - continue; - } - $created = strtotime( $record->created ); - if ( in_array( $created, $backups_created_time_to_fix ) ) { - if ( ! in_array( $record->ID, $skip_records ) ) { - $skip_records[] = $record->ID; - } - continue; - } else { - $backups_created_time_to_fix[] = $created; - } - } else { - if ( $action !== $record->action ) { - continue; - } - - if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) { - $new_status = $this->get_stream_meta_data( $record, 'new_status' ); - if ( 'draft' === $new_status ) { - continue; - } - } elseif ( 'updated' === $action && ( 'themes' === $context || 'plugins' === $context ) ) { - $name = $this->get_stream_meta_data( $record, 'name' ); - if ( empty( $name ) ) { - if ( ! in_array( $record->ID, $skip_records ) ) { - $skip_records[] = $record->ID; - } - continue; - } else { - $old_version = $this->get_stream_meta_data( $record, 'old_version' ); - $version = $this->get_stream_meta_data( $record, 'version' ); - if ( version_compare( $version, $old_version, '<=' ) ) { - if ( ! in_array( $record->ID, $skip_records ) ) { - $skip_records[] = $record->ID; - } - continue; - } - } - } - } - $count ++; - } - return $count; - } - - public function get_section_loop_data( $records, $tokens, $section, $skip_records = array() ) { - - $context = ''; - $action = ''; - - $str_tmp = str_replace( array( '[', ']' ), '', $section ); - $array_tmp = explode( '.', $str_tmp ); - if ( is_array( $array_tmp ) ) { - if ( 2 === count( $array_tmp ) ) { - list( $str1, $context ) = $array_tmp; - } elseif ( 3 === count( $array_tmp ) ) { - list( $str1, $context, $action ) = $array_tmp; - } - } - - // get db $context value by mapping. - $context = $this->get_compatible_context( $context ); - // to compatible with new version of child report. - // to check condition for grabbing report data. - $connector = $this->get_connector_by_compatible_context( $context ); - - $action = $this->get_compatible_action( $action, $context ); - - if ( 'profiles' == $context ) { - if ( 'created' == $action || 'deleted' == $action ) { - $context = 'users'; // see class-connector-user.php. - } - } - - return $this->get_section_loop_records( $records, $tokens, $connector, $context, $action, $skip_records ); - } - - public function get_section_loop_records( $records, $tokens, $connector, $context, $action, $skip_records ) { // phpcs:ignore -- ignore complex method notice. - - $loops = array(); - $loop_count = 0; - foreach ( $records as $record ) { - - if ( in_array( $record->ID, $skip_records ) ) { - continue; - } - - if ( 'editor' == $record->connector ) { - if ( ! in_array( $context, array( 'plugins', 'themes' ) ) || 'updated' !== $action ) { - continue; - } - } elseif ( $connector !== $record->connector ) { - continue; - } - - $valid_context = false; - - if ( 'comments' == $context ) { - $comment_contexts = array( 'post', 'page' ); - if ( ! in_array( $record->context, $comment_contexts ) ) { - continue; - } - $valid_context = true; - } elseif ( 'menus' == $context ) { - $valid_context = true; // ok, pass, don't check context. - } elseif ( 'editor' == $record->connector ) { - $valid_context = true; // ok, pass, checked above. - } elseif ( 'media' == $connector && 'media' == $record->connector ) { - $valid_context = true; // ok, pass, do not check context. - } elseif ( 'widgets' == $connector && 'widgets' == $record->connector ) { - $valid_context = true; // ok, pass, don't check context. - } - - if ( ! $valid_context || strtolower( $record->context ) !== $context ) { - continue; - } - - // custom action value! - if ( 'widgets' == $connector ) { - if ( 'deleted' == $action ) { - $action = 'removed'; // action saved in database! - } - } - - if ( 'backups' == $context ) { - if ( ! $this->is_backup_action( $record->action ) ) { - continue; - } - } elseif ( $action !== $record->action ) { - continue; - } - - if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) { - $new_status = $this->get_stream_meta_data( $record, 'new_status' ); - if ( 'draft' === $new_status ) { // avoid auto save post! - continue; - } - } - $token_values = $this->get_section_loop_token_values( $record, $context, $tokens ); - if ( ! empty( $token_values ) ) { - $loops[ $loop_count ] = $token_values; - $loop_count ++; - } - } - return $loops; - } - - private function get_section_loop_token_values( $record, $context, $tokens ) { - - $token_values = array(); - foreach ( $tokens as $token ) { - $data = ''; - $token_name = str_replace( array( '[', ']' ), '', $token ); - $array_tmp = explode( '.', $token_name ); - - if ( 'user.name' === $token_name ) { - $data = 'display_name'; - } else { - if ( 1 === count( $array_tmp ) ) { - list( $data ) = $array_tmp; - } elseif ( 2 === count( $array_tmp ) ) { - list( $str1, $data ) = $array_tmp; - } elseif ( 3 === count( $array_tmp ) ) { - list( $str1, $str2, $data ) = $array_tmp; - } - - if ( 'version' === $data ) { - if ( 'old' === $str2 ) { - $data = 'old_version'; - } elseif ( 'current' === $str2 && 'WordPress' === $str1 ) { - $data = 'new_version'; - } - } - } - - if ( 'role' === $data ) { - $data = 'roles'; - } - - $tok_value = $this->get_section_token_value( $record, $data, $context, $token ); - - $token_values[ $token ] = $tok_value; - - if ( empty( $tok_value ) ) { - $msg = 'MainWP Child Report:: skip empty value :: token :: ' . $token . ' :: record :: ' . print_r( $record, true ); // phpcs:ignore -- debug mode only. - MainWP_Helper::log_debug( $msg ); - } - } - return $token_values; - } - - public function get_section_token_value( $record, $data, $context, $token ) { // phpcs:ignore -- ignore complex method notice. - $tok_value = ''; - switch ( $data ) { - case 'ID': - $tok_value = $record->ID; - break; - case 'date': - $tok_value = MainWP_Helper::format_date( MainWP_Helper::get_timestamp( strtotime( $record->created ) ) ); - break; - case 'time': - $tok_value = MainWP_Helper::format_time( MainWP_Helper::get_timestamp( strtotime( $record->created ) ) ); - break; - case 'area': - $data = 'sidebar_name'; - $tok_value = $this->get_stream_meta_data( $record, $data ); - break; - case 'name': - case 'version': - case 'old_version': - case 'new_version': - case 'display_name': - case 'roles': - if ( 'name' == $data ) { - if ( 'profiles' == $context ) { - $data = 'display_name'; - } - } - $tok_value = $this->get_stream_meta_data( $record, $data ); - break; - case 'title': - if ( 'comments' === $context ) { - $tok_value = $record->summary; - } else { - if ( 'page' === $context || 'post' === $context ) { - $data = 'post_title'; - } elseif ( 'menus' === $record->connector ) { - $data = 'name'; - } - $tok_value = $this->get_stream_meta_data( $record, $data ); - } - break; - case 'author': - $tok_value = $this->get_author_data_token_value( $record, $connector, $context, $data ); - - break; - case 'status': - case 'webtrust': - $value = ''; - if ( 'sucuri_scan' === $context ) { - $value = $this->get_sucuri_scan_token_value( $record, $data ); - } - $tok_value = $value; - break; - case 'details': - case 'result': - $tok_value = $this->get_result_data_token_value( $record, $context, $data ); - break; - case 'type': - if ( 'backups' === $context ) { - $tok_value = $this->get_stream_meta_data( $record, $data ); - } else { - $tok_value = $token; - } - break; - default: - $tok_value = 'N/A'; - break; - } - return $tok_value; - } - - public function get_stream_meta_data( $record, $data ) { - - if ( empty( $record ) ) { - return ''; - } - - $meta_key = $data; - - $value = ''; - - if ( isset( $record->meta ) ) { - $meta = $record->meta; - - if ( isset( $meta[ $meta_key ] ) ) { - $value = $meta[ $meta_key ]; - $value = ( 'user_meta' == $meta_key && isset( $value[1] ) ) ? $value[1] : current( $value ); - - if ( 'author_meta' === $meta_key ) { - $value = maybe_unserialize( $value ); - if ( is_array( $value ) ) { - $value = $value['display_name']; - // fix empty author value! - if ( empty( $value ) ) { - if ( isset( $value['agent'] ) && ! empty( $value['agent'] ) ) { - $value = $value['agent']; - } - } - } - if ( ! is_string( $value ) ) { - $value = ''; - } - } - } - } - - return $value; - } - - private function get_author_data_token_value( $record, $connector, $context, $data ) { - if ( 'comment' == $connector ) { - $data = 'user_name'; - } else { - $data = 'user_meta'; - } - $value = $this->get_stream_meta_data( $record, $data ); - - if ( empty( $value ) && 'comments' === $context ) { - $value = __( 'Guest', 'mainwp-child' ); - } - - // check compatibility with old meta data. - if ( empty( $value ) ) { - $value = $this->get_stream_meta_data( $record, 'author_meta' ); - } - - return $value; - } - - private function get_result_data_token_value( $record, $context, $data ) { - if ( 'mainwp_maintenance' === $context && 'details' == $data ) { - $tok_value = $this->get_mainwp_maintenance_token_value( $record, $data ); - } elseif ( 'wordfence_scan' === $context || 'mainwp_maintenance' === $context ) { - $meta_value = $this->get_stream_meta_data( $record, $data ); - if ( 'wordfence_scan' === $context && 'result' == $data ) { - // SUM_FINAL:Scan complete. You have xxx new issues to fix. See below. - // SUM_FINAL:Scan complete. Congratulations, no new problems found. - if ( stripos( $meta_value, 'Congratulations' ) ) { - $meta_value = 'No issues detected'; - } elseif ( stripos( $meta_value, 'You have' ) ) { - $meta_value = 'Issues Detected'; - } else { - $meta_value = ''; - } - } - $tok_value = $meta_value; - } - return $tok_value; - } - - private function get_sucuri_scan_token_value( $record, $data ) { - $tok_value = ''; - $scan_data = $this->get_stream_meta_data( $record, 'scan_data' ); - if ( ! empty( $scan_data ) ) { - $scan_data = maybe_unserialize( base64_decode( $scan_data ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode function is used for begin reasons. - if ( is_array( $scan_data ) ) { - - $blacklisted = $scan_data['blacklisted']; - $malware_exists = $scan_data['malware_exists']; - - $status = array(); - if ( $blacklisted ) { - $status[] = __( 'Site Blacklisted', 'mainwp-child' ); } - if ( $malware_exists ) { - $status[] = __( 'Site With Warnings', 'mainwp-child' ); } - - if ( 'status' == $data ) { - $tok_value = count( $status ) > 0 ? implode( ', ', $status ) : __( 'Verified Clear', 'mainwp-child' ); - } elseif ( 'webtrust' == $data ) { - $tok_value = $blacklisted ? __( 'Site Blacklisted', 'mainwp-child' ) : __( 'Trusted', 'mainwp-child' ); - } - } - } else { - $tok_value = $this->get_stream_meta_data( $record, $data ); - } - return $tok_value; - } - - private function get_mainwp_maintenance_token_value( $record, $data ) { - - $maintenance_details = array( - 'revisions' => __( 'Delete all post revisions', 'mainwp-child' ), - 'revisions_max' => __( 'Delete all post revisions, except for the last:', 'mainwp-child' ), - 'autodraft' => __( 'Delete all auto draft posts', 'mainwp-child' ), - 'trashpost' => __( 'Delete trash posts', 'mainwp-child' ), - 'spam' => __( 'Delete spam comments', 'mainwp-child' ), - 'pending' => __( 'Delete pending comments', 'mainwp-child' ), - 'trashcomment' => __( 'Delete trash comments', 'mainwp-child' ), - 'tags' => __( 'Delete tags with 0 posts associated', 'mainwp-child' ), - 'categories' => __( 'Delete categories with 0 posts associated', 'mainwp-child' ), - 'optimize' => __( 'Optimize database tables', 'mainwp-child' ), - ); - - $meta_value = $this->get_stream_meta_data( $record, $data ); - $meta_value = explode( ',', $meta_value ); - - $details = array(); - - if ( is_array( $meta_value ) ) { - foreach ( $meta_value as $mt ) { - if ( isset( $maintenance_details[ $mt ] ) ) { - if ( 'revisions_max' == $mt ) { - $max_revisions = $this->get_stream_meta_data( $record, 'revisions' ); - $dtl = $maintenance_details['revisions_max'] . ' ' . $max_revisions; - } else { - $dtl = $maintenance_details[ $mt ]; - } - $details[] = $dtl; - } - } - } - $tok_value = implode( ', ', $details ); - return $tok_value; - } - + public function set_showhide() { $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : ''; MainWP_Child_Branding::instance()->save_branding_options( 'hide_child_reports', $hide ); @@ -986,7 +215,6 @@ class MainWP_Client_Report { unset( $plugins[ $key ] ); } } - return $plugins; } diff --git a/class/class-mainwp-clone-install.php b/class/class-mainwp-clone-install.php index 1b8016c..49fdb55 100644 --- a/class/class-mainwp-clone-install.php +++ b/class/class-mainwp-clone-install.php @@ -6,7 +6,7 @@ */ namespace MainWP\Child; -// phpcs:disable WordPress.WP.AlternativeFunctions -- to custom functions. +// phpcs:disable WordPress.WP.AlternativeFunctions -- to custom file's functions. /** * Class MainWP_Clone_Install diff --git a/class/class-mainwp-clone-page.php b/class/class-mainwp-clone-page.php new file mode 100644 index 0000000..53ca1ea --- /dev/null +++ b/class/class-mainwp-clone-page.php @@ -0,0 +1,1137 @@ +query( 'jquery-ui-core' ); + $version = $ui->ver; + if ( MainWP_Helper::starts_with( $version, '1.10' ) ) { + wp_enqueue_style( 'jquery-ui-style', plugins_url( '/css/1.10.4/jquery-ui.min.css', dirname( __FILE__ ) ), array(), '1.10', 'all' ); + } else { + wp_enqueue_style( 'jquery-ui-style', plugins_url( '/css/1.11.1/jquery-ui.min.css', dirname( __FILE__ ) ), array(), '1.11', 'all' ); + } + + $branding_opts = MainWP_Child_Branding::instance()->get_branding_options(); + $hide_restore = isset( $branding_opts['remove_restore'] ) && $branding_opts['remove_restore'] ? true : false; + if ( ! $hide_restore ) { + if ( '' == session_id() ) { + session_start(); + } + } + } + + + public static function render() { + $uploadError = false; + $uploadFile = false; + if ( isset( $_REQUEST['upload'] ) && wp_verify_nonce( $_POST['_nonce'], 'cloneRestore' ) ) { + if ( isset( $_FILES['file'] ) ) { + if ( ! function_exists( 'wp_handle_upload' ) ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + } + $uploadedfile = $_FILES['file']; + $upload_overrides = array( 'test_form' => false ); + add_filter( 'upload_mimes', array( MainWP_Clone::get_class_name(), 'upload_mimes' ) ); + $movefile = wp_handle_upload( $uploadedfile, $upload_overrides ); + if ( $movefile ) { + $uploadFile = str_replace( ABSPATH, '', $movefile['file'] ); + } else { + $uploadError = __( 'File could not be uploaded.', 'mainwp-child' ); + } + } else { + $uploadError = __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.', 'mainwp-child' ); + } + } + + $sitesToClone = get_option( 'mainwp_child_clone_sites' ); + $uploadSizeInBytes = min( MainWP_Helper::return_bytes( ini_get( 'upload_max_filesize' ) ), MainWP_Helper::return_bytes( ini_get( 'post_max_size' ) ) ); + $uploadSize = MainWP_Helper::human_filesize( $uploadSizeInBytes ); + + self::render_style(); + + if ( '0' === $sitesToClone ) { + echo '
)
+ +)
+ get_branding_title(); + if ( '' != $branding_title ) { + $branding_msg = 'If you have a FULL backup created by basic ' . esc_html( stripslashes( $branding_title ) ) . ' Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.'; + } else { + $branding_msg = esc_html__( 'If you have a FULL backup created by basic MainWP Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.', 'mainwp-child' ); + } + ?> + +)
- -)
- get_branding_title(); - if ( '' != $branding_title ) { - $branding_msg = 'If you have a FULL backup created by basic ' . esc_html( stripslashes( $branding_title ) ) . ' Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.'; - } else { - $branding_msg = esc_html__( 'If you have a FULL backup created by basic MainWP Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.', 'mainwp-child' ); - } - ?> - -