PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | pages/page-mainwp-server-information.php +2261 -1757 5.0 → 6.2.1 View file →
@@ -6,1888 +6,2392 @@
6 6 */
7 7
8 8 namespace MainWP\Dashboard;
9 9
10 +use MainWP\Dashboard\Module\Log\Log_DB_Helper;
11 +
12 +// Exit if accessed directly.
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
16 +
17 +
10 18 // phpcs:disable Generic.Metrics.CyclomaticComplexity -- complexity.
11 19 /**
12 20 * Class MainWP_Server_Information
13 21 */
14 -class MainWP_Server_Information {
22 +class MainWP_Server_Information { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
15 23
16 - const WARNING = 1;
17 - const ERROR = 2;
24 + const WARNING = 1;
25 + const ERROR = 2;
18 26
19 - /**
20 - * The Info page sub-pages.
21 - *
22 - * @static
23 - * @var array Sub pages.
24 - */
25 - public static $subPages;
27 + /**
28 + * The Info page sub-pages.
29 + *
30 + * @static
31 + * @var array Sub pages.
32 + */
33 + public static $subPages;
26 34
27 - /**
28 - * Get Class Name
29 - *
30 - * @return string __CLASS__
31 - */
32 - public static function get_class_name() {
33 - return __CLASS__;
34 - }
35 + /**
36 + * Get Class Name
37 + *
38 + * @return string __CLASS__
39 + */
40 + public static function get_class_name() {
41 + return __CLASS__;
42 + }
35 43
36 - /**
37 - * Method init_menu()
38 - *
39 - * Initiate Info subPage menu.
40 - *
41 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
42 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
43 - */
44 - public static function init_menu() {
44 + /**
45 + * Get the registered Info subpages.
46 + *
47 + * @return array<int, array<string, mixed>> Info subpages.
48 + */
49 + private static function get_subpages() {
50 + if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
51 + return static::$subPages;
52 + }
45 53
46 - add_action( 'mainwp_pageheader_infor', array( self::get_class_name(), 'render_header' ) );
47 - add_action( 'mainwp_pagefooter_infor', array( self::get_class_name(), 'render_footer' ) );
54 + /**
55 + * Filter mainwp_getsubpages_server
56 + *
57 + * Filters subpages for the Info page.
58 + *
59 + * @since Unknown
60 + */
61 + $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-server', array( array() ), '4.0.7.2', 'mainwp_getsubpages_server' ); // NOSONAR - not IP.
62 + static::$subPages = apply_filters( 'mainwp_getsubpages_server', $sub_pages );
48 63
49 - add_submenu_page(
50 - 'mainwp_tab',
51 - __( 'Info', 'mainwp' ),
52 - ' <span id="mainwp-ServerInformation">' . esc_html__( 'Info', 'mainwp' ) . '</span>',
53 - 'read',
54 - 'ServerInformation',
55 - array(
56 - self::get_class_name(),
57 - 'render',
58 - )
59 - );
60 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ServerInformationCron' ) ) {
61 - add_submenu_page(
62 - 'mainwp_tab',
63 - __( 'Cron Schedules', 'mainwp' ),
64 - '<div class="mainwp-hidden">' . esc_html__( 'Cron Schedules', 'mainwp' ) . '</div>',
65 - 'read',
66 - 'ServerInformationCron',
67 - array(
68 - self::get_class_name(),
69 - 'render_cron',
70 - )
71 - );
72 - }
64 + return is_array( static::$subPages ) ? static::$subPages : array();
65 + }
73 66
74 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ErrorLog' ) ) {
75 - add_submenu_page(
76 - 'mainwp_tab',
77 - __( 'Error Log', 'mainwp' ),
78 - '<div class="mainwp-hidden">' . esc_html__( 'Error Log', 'mainwp' ) . '</div>',
79 - 'read',
80 - 'ErrorLog',
81 - array(
82 - self::get_class_name(),
83 - 'render_error_log_page',
84 - )
85 - );
86 - }
87 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'WPConfig' ) ) {
88 - add_submenu_page(
89 - 'mainwp_tab',
90 - __( 'WP-Config File', 'mainwp' ),
91 - '<div class="mainwp-hidden">' . esc_html__( 'WP-Config File', 'mainwp' ) . '</div>',
92 - 'read',
93 - 'WPConfig',
94 - array(
95 - self::get_class_name(),
96 - 'render_wp_config',
97 - )
98 - );
99 - }
100 - if ( ! MainWP_Menu::is_disable_menu_item( 3, '.htaccess' ) ) {
101 - if ( MainWP_Server_Information_Handler::is_apache_server_software() ) {
102 - add_submenu_page(
103 - 'mainwp_tab',
104 - __( '.htaccess File', 'mainwp' ),
105 - '<div class="mainwp-hidden">' . esc_html__( '.htaccess File', 'mainwp' ) . '</div>',
106 - 'read',
107 - '.htaccess',
108 - array(
109 - self::get_class_name(),
110 - 'render_htaccess',
111 - )
112 - );
113 - }
114 - }
115 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ActionLogs' ) ) {
116 - add_submenu_page(
117 - 'mainwp_tab',
118 - __( 'Custom Event Monitor', 'mainwp' ),
119 - '<div class="mainwp-hidden">' . esc_html__( 'Custom Event Monitor', 'mainwp' ) . '</div>',
120 - 'read',
121 - 'ActionLogs',
122 - array(
123 - self::get_class_name(),
124 - 'render_action_logs',
125 - )
126 - );
127 - }
67 + /**
68 + * Get the built-in Info pages used across menu registration and navigation rendering.
69 + *
70 + * @return array<int, array<string, mixed>> Info page definitions.
71 + */
72 + private static function get_core_pages() {
73 + $pages = array(
74 + array(
75 + 'slug' => 'ServerInformation',
76 + 'page_title' => __( 'Info', 'mainwp' ),
77 + 'menu_title' => ' <span id="mainwp-ServerInformation">' . esc_html__( 'Info', 'mainwp' ) . '</span>',
78 + 'nav_title' => esc_html__( 'Server', 'mainwp' ),
79 + 'callback' => array( static::get_class_name(), 'render' ),
80 + 'active_keys' => array( '', 'ServerInformation' ),
81 + 'show_in_header_nav' => true,
82 + 'show_in_subpages_menu' => true,
83 + 'show_in_left_menu' => true,
84 + 'show_in_palette' => true,
85 + 'left_menu_parent' => 'ServerInformation',
86 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ) ),
87 + ),
88 + array(
89 + 'slug' => 'ServerInformationCron',
90 + 'page_title' => __( 'Cron Schedules', 'mainwp' ),
91 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( 'Cron Schedules', 'mainwp' ) . '</div>',
92 + 'nav_title' => esc_html__( 'Cron Schedules', 'mainwp' ),
93 + 'callback' => array( static::get_class_name(), 'render_cron' ),
94 + 'active_keys' => array( 'ServerInformationCron' ),
95 + 'show_in_header_nav' => true,
96 + 'show_in_subpages_menu' => true,
97 + 'show_in_left_menu' => true,
98 + 'show_in_palette' => true,
99 + 'left_menu_parent' => 'ServerInformation',
100 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), esc_html__( 'Cron Schedules', 'mainwp' ) ),
101 + ),
102 + array(
103 + 'slug' => 'ErrorLog',
104 + 'page_title' => __( 'Error Log', 'mainwp' ),
105 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( 'Error Log', 'mainwp' ) . '</div>',
106 + 'nav_title' => esc_html__( 'Error Log', 'mainwp' ),
107 + 'callback' => array( static::get_class_name(), 'render_error_log_page' ),
108 + 'active_keys' => array( 'ErrorLog' ),
109 + 'show_in_header_nav' => true,
110 + 'show_in_subpages_menu' => true,
111 + 'show_in_left_menu' => true,
112 + 'show_in_palette' => true,
113 + 'left_menu_parent' => 'ServerInformation',
114 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), esc_html__( 'Error Log', 'mainwp' ) ),
115 + ),
116 + array(
117 + 'slug' => 'WPConfig',
118 + 'page_title' => __( 'WP-Config File', 'mainwp' ),
119 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( 'WP-Config File', 'mainwp' ) . '</div>',
120 + 'nav_title' => esc_html__( 'WP-Config File', 'mainwp' ),
121 + 'callback' => array( static::get_class_name(), 'render_wp_config' ),
122 + 'active_keys' => array( 'WPConfig' ),
123 + 'show_in_header_nav' => false,
124 + 'show_in_subpages_menu' => true,
125 + 'show_in_left_menu' => false,
126 + 'show_in_palette' => true,
127 + 'left_menu_parent' => 'ServerInformation',
128 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), esc_html__( 'WP-Config File', 'mainwp' ) ),
129 + ),
130 + array(
131 + 'slug' => '.htaccess',
132 + 'page_title' => __( '.htaccess File', 'mainwp' ),
133 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( '.htaccess File', 'mainwp' ) . '</div>',
134 + 'nav_title' => esc_html__( '.htaccess File', 'mainwp' ),
135 + 'callback' => array( static::get_class_name(), 'render_htaccess' ),
136 + 'active_keys' => array( '.htaccess' ),
137 + 'show_in_header_nav' => false,
138 + 'show_in_subpages_menu' => true,
139 + 'show_in_left_menu' => false,
140 + 'show_in_palette' => true,
141 + 'left_menu_parent' => 'ServerInformation',
142 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), esc_html__( '.htaccess File', 'mainwp' ) ),
143 + 'condition' => static function() {
144 + return MainWP_Server_Information_Handler::is_apache_server_software();
145 + },
146 + ),
147 + array(
148 + 'slug' => 'ActionLogs',
149 + 'page_title' => __( 'Custom Event Monitor', 'mainwp' ),
150 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( 'Custom Event Monitor', 'mainwp' ) . '</div>',
151 + 'nav_title' => esc_html__( 'Custom Event Monitor', 'mainwp' ),
152 + 'callback' => array( static::get_class_name(), 'render_action_logs' ),
153 + 'active_keys' => array( 'ActionLogs' ),
154 + 'show_in_header_nav' => true,
155 + 'show_in_subpages_menu' => false,
156 + 'show_in_left_menu' => true,
157 + 'show_in_palette' => true,
158 + 'left_menu_parent' => 'ServerInformation',
159 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), esc_html__( 'Custom Event Monitor', 'mainwp' ) ),
160 + ),
161 + array(
162 + 'slug' => 'PluginPrivacy',
163 + 'page_title' => __( 'Plugin Privacy', 'mainwp' ),
164 + 'menu_title' => '<div class="mainwp-hidden">' . esc_html__( 'Plugin Privacy', 'mainwp' ) . '</div>',
165 + 'nav_title' => esc_html__( 'Plugin Privacy', 'mainwp' ),
166 + 'callback' => array( static::get_class_name(), 'render_plugin_privacy_page' ),
167 + 'active_keys' => array( 'PluginPrivacy' ),
168 + 'show_in_header_nav' => false,
169 + 'show_in_subpages_menu' => false,
170 + 'show_in_left_menu' => true,
171 + 'show_in_palette' => true,
172 + 'left_menu_parent' => 'mainwp_tab',
173 + 'palette_titles' => array( esc_html__( 'Privacy Policy', 'mainwp' ) ),
174 + ),
175 + );
128 176
129 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginPrivacy' ) ) {
130 - add_submenu_page(
131 - 'mainwp_tab',
132 - __( 'Plugin Privacy', 'mainwp' ),
133 - '<div class="mainwp-hidden">' . esc_html__( 'Plugin Privacy', 'mainwp' ) . '</div>',
134 - 'read',
135 - 'PluginPrivacy',
136 - array(
137 - self::get_class_name(),
138 - 'render_plugin_privacy_page',
139 - )
140 - );
141 - }
177 + $visible_pages = array();
142 178
143 - /**
144 - * Filter mainwp_getsubpages_server
145 - *
146 - * Filters subpages for the Info page.
147 - *
148 - * @since Unknown
149 - */
150 - $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-server', array( array() ), '4.0.7.2', 'mainwp_getsubpages_server' );
151 - self::$subPages = apply_filters( 'mainwp_getsubpages_server', $sub_pages );
179 + foreach ( $pages as $page ) {
180 + if ( 'ServerInformation' !== $page['slug'] && MainWP_Menu::is_disable_menu_item( 3, $page['slug'] ) ) {
181 + continue;
182 + }
152 183
153 - if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
154 - foreach ( self::$subPages as $subPage ) {
155 - if ( ! isset( $subPage['slug'] ) ) {
156 - continue;
157 - }
158 - if ( MainWP_Menu::is_disable_menu_item( 3, 'Server' . $subPage['slug'] ) ) {
159 - continue;
160 - }
161 - add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'Server' . $subPage['slug'], $subPage['callback'] );
162 - }
163 - }
164 - }
184 + if ( isset( $page['condition'] ) && is_callable( $page['condition'] ) && ! call_user_func( $page['condition'] ) ) {
185 + continue;
186 + }
165 187
166 - /**
167 - * Renders Sub Pages Menu.
168 - *
169 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
170 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
171 - */
172 - public static function init_subpages_menu() {
173 - ?>
174 - <div id="menu-mainwp-ServerInformation" class="mainwp-submenu-wrapper">
175 - <div class="wp-submenu sub-open">
176 - <div class="mainwp_boxout">
177 - <div class="mainwp_boxoutin"></div>
178 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ServerInformation' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Server', 'mainwp' ); ?></a>
179 - <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ServerInformationCron' ) ) { ?>
180 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ServerInformationCron' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Cron Schedules', 'mainwp' ); ?></a>
181 - <?php } ?>
182 - <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ErrorLog' ) ) { ?>
183 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ErrorLog' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Error Log', 'mainwp' ); ?></a>
184 - <?php } ?>
185 - <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'WPConfig' ) ) { ?>
186 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=WPConfig' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'WP-Config File', 'mainwp' ); ?></a>
187 - <?php } ?>
188 - <?php
189 - if ( ! MainWP_Menu::is_disable_menu_item( 3, '.htaccess' ) ) {
190 - if ( MainWP_Server_Information_Handler::is_apache_server_software() ) {
191 - ?>
192 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=.htaccess' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( '.htaccess File', 'mainwp' ); ?></a>
193 - <?php
194 - }
195 - }
196 - ?>
197 - <?php
198 - if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
199 - foreach ( self::$subPages as $subPage ) {
200 - if ( ! isset( $subPage['menu_hidden'] ) || ( isset( $subPage['menu_hidden'] ) && true !== $subPage['menu_hidden'] ) ) {
201 - if ( MainWP_Menu::is_disable_menu_item( 3, 'Server' . $subPage['slug'] ) ) {
202 - continue;
203 - }
204 - ?>
205 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=Server' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $subPage['title'] ); ?></a>
206 - <?php
207 - }
208 - }
209 - }
210 - ?>
211 - </div>
212 - </div>
213 - </div>
214 - <?php
215 - }
188 + $visible_pages[] = $page;
189 + }
216 190
217 - /**
218 - * Initiates Server Information left menu.
219 - *
220 - * @param array $subPages array of subpages.
221 - *
222 - * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
223 - * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
224 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
225 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
226 - */
227 - public static function init_left_menu( $subPages = array() ) {
228 - MainWP_Menu::add_left_menu(
229 - array(
230 - 'title' => esc_html__( 'Info', 'mainwp' ),
231 - 'parent_key' => 'mainwp_tab',
232 - 'slug' => 'ServerInformation',
233 - 'href' => 'admin.php?page=ServerInformation',
234 - 'icon' => '<i class="info circle icon"></i>',
235 - ),
236 - 0
237 - );
191 + return $visible_pages;
192 + }
238 193
239 - /**
240 - * MainWP active menu slugs array.
241 - *
242 - * @global object
243 - */
244 - global $_mainwp_menu_active_slugs;
194 + /**
195 + * Convert a navigation href into a usable URL.
196 + *
197 + * @param string $href Navigation href.
198 + *
199 + * @return string Navigation URL.
200 + */
201 + private static function get_navigation_item_url( $href ) {
202 + $href = trim( wp_specialchars_decode( (string) $href, ENT_QUOTES ) );
245 203
246 - $_mainwp_menu_active_slugs['ActionLogs'] = 'ServerInformation';
204 + if ( empty( $href ) ) {
205 + return '';
206 + }
247 207
248 - $init_sub_subleftmenu = array(
249 - array(
250 - 'title' => esc_html__( 'Server', 'mainwp' ),
251 - 'parent_key' => 'ServerInformation',
252 - 'href' => 'admin.php?page=ServerInformation',
253 - 'slug' => 'ServerInformation',
254 - 'right' => '',
255 - ),
256 - array(
257 - 'title' => esc_html__( 'Cron Schedules', 'mainwp' ),
258 - 'parent_key' => 'ServerInformation',
259 - 'href' => 'admin.php?page=ServerInformationCron',
260 - 'slug' => 'ServerInformationCron',
261 - 'right' => '',
262 - ),
263 - array(
264 - 'title' => esc_html__( 'Error Log', 'mainwp' ),
265 - 'parent_key' => 'ServerInformation',
266 - 'href' => 'admin.php?page=ErrorLog',
267 - 'slug' => 'ErrorLog',
268 - 'right' => '',
269 - ),
270 - array(
271 - 'title' => esc_html__( 'Custom Event Monitor', 'mainwp' ),
272 - 'parent_key' => 'ServerInformation',
273 - 'href' => 'admin.php?page=ActionLogs',
274 - 'slug' => 'ActionLogs',
275 - 'right' => '',
276 - ),
277 - array(
278 - 'title' => esc_html__( 'Plugin Privacy', 'mainwp' ),
279 - 'parent_key' => 'ServerInformation',
280 - 'href' => 'admin.php?page=PluginPrivacy',
281 - 'slug' => 'PluginPrivacy',
282 - 'right' => '',
283 - ),
284 - );
208 + if ( preg_match( '/^https?:\/\//i', $href ) ) {
209 + return $href;
210 + }
285 211
286 - MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'ServerInformation', 'Server' );
287 - foreach ( $init_sub_subleftmenu as $item ) {
288 - if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
289 - continue;
290 - }
291 - MainWP_Menu::add_left_menu( $item, 2 );
292 - }
293 - }
212 + return admin_url( ltrim( $href, '/' ) );
213 + }
294 214
295 - /**
296 - * Renders Info header.
297 - *
298 - * @param string $shownPage Current page.
299 - *
300 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
301 - * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
302 - * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
303 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
304 - */
305 - public static function render_header( $shownPage = '' ) {
306 - $params = array(
307 - 'title' => esc_html__( 'Info', 'mainwp' ),
308 - );
215 + /**
216 + * Get dynamic Info subpage items using the legacy left-menu normalization path.
217 + *
218 + * @return array<int, array<string, mixed>> Info navigation items.
219 + */
220 + private static function get_filtered_subpage_navigation_items() {
221 + $menu_items = array();
222 + $core_slugs = array();
309 223
310 - MainWP_UI::render_top_header( $params );
224 + foreach ( static::get_navigation_items( 'left_menu_core' ) as $item ) {
225 + if ( empty( $item['show_in_left_menu'] ) ) {
226 + continue;
227 + }
311 228
312 - $renderItems = array();
229 + $core_slugs[ $item['slug'] ] = true;
230 + $menu_items[] = array(
231 + 'title' => $item['title'],
232 + 'parent_key' => $item['left_menu_parent'],
233 + 'href' => $item['href'],
234 + 'slug' => $item['slug'],
235 + 'right' => '',
236 + );
237 + }
313 238
314 - $renderItems[] = array(
315 - 'title' => esc_html__( 'Server', 'mainwp' ),
316 - 'href' => 'admin.php?page=ServerInformation',
317 - 'active' => ( '' === $shownPage ) ? true : false,
318 - );
239 + MainWP_Menu::init_subpages_left_menu( static::get_subpages(), $menu_items, 'ServerInformation', 'Server' );
319 240
320 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ServerInformationCron' ) ) {
321 - $renderItems[] = array(
322 - 'title' => esc_html__( 'Cron Schedules', 'mainwp' ),
323 - 'href' => 'admin.php?page=ServerInformationCron',
324 - 'active' => ( 'ServerInformationCron' === $shownPage ) ? true : false,
325 - );
326 - }
241 + $items = array();
327 242
328 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ErrorLog' ) ) {
329 - $renderItems[] = array(
330 - 'title' => esc_html__( 'Error Log', 'mainwp' ),
331 - 'href' => 'admin.php?page=ErrorLog',
332 - 'active' => ( 'ErrorLog' === $shownPage ) ? true : false,
333 - );
334 - }
243 + foreach ( $menu_items as $menu_item ) {
244 + if ( empty( $menu_item['slug'] ) || empty( $menu_item['title'] ) || empty( $menu_item['href'] ) ) {
245 + continue;
246 + }
335 247
336 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ActionLogs' ) ) {
337 - $renderItems[] = array(
338 - 'title' => esc_html__( 'Custom Event Monitor', 'mainwp' ),
339 - 'href' => 'admin.php?page=ActionLogs',
340 - 'active' => ( 'ActionLogs' === $shownPage ) ? true : false,
341 - );
342 - }
248 + if ( isset( $core_slugs[ $menu_item['slug'] ] ) ) {
249 + continue;
250 + }
343 251
344 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginPrivacy' ) ) {
345 - $renderItems[] = array(
346 - 'title' => esc_html__( 'Plugin Privacy', 'mainwp' ),
347 - 'href' => 'admin.php?page=PluginPrivacy',
348 - 'active' => ( 'PluginPrivacy' === $shownPage ) ? true : false,
349 - );
350 - }
252 + if ( isset( $menu_item['item_slug'] ) ) {
253 + if ( MainWP_Menu::is_disable_menu_item( 3, $menu_item['item_slug'] ) ) {
254 + continue;
255 + }
256 + } elseif ( MainWP_Menu::is_disable_menu_item( 3, $menu_item['slug'] ) ) {
257 + continue;
258 + }
351 259
352 - MainWP_UI::render_page_navigation( $renderItems );
260 + $active_slug = 0 === strpos( $menu_item['slug'], 'Server' ) ? substr( $menu_item['slug'], strlen( 'Server' ) ) : $menu_item['slug'];
353 261
354 - self::render_actions_bar();
262 + $item = array(
263 + 'slug' => $menu_item['slug'],
264 + 'title' => $menu_item['title'],
265 + 'href' => $menu_item['href'],
266 + 'active_keys' => array( $active_slug, $menu_item['slug'] ),
267 + 'show_in_header_nav' => false,
268 + 'show_in_subpages_menu' => true,
269 + 'show_in_left_menu' => true,
270 + 'show_in_palette' => true,
271 + 'left_menu_parent' => isset( $menu_item['parent_key'] ) ? $menu_item['parent_key'] : 'ServerInformation',
272 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), $menu_item['title'] ),
273 + 'menu_hidden' => false,
274 + );
355 275
356 - echo '<div>';
357 - }
276 + if ( isset( $menu_item['item_slug'] ) ) {
277 + $item['item_slug'] = $menu_item['item_slug'];
278 + }
358 279
359 - /**
360 - * Renders Server Information footer.
361 - */
362 - public static function render_footer() {
363 - echo '</div>';
364 - }
280 + if ( ! empty( $menu_item['before_title'] ) ) {
281 + $item['before_title'] = $menu_item['before_title'];
282 + $item['palette_titles'][1] = trim( wp_strip_all_tags( $menu_item['before_title'] ) . ' ' . $menu_item['title'] );
283 + }
365 284
366 - /**
367 - * Renders Server Information action bar element.
368 - */
369 - public static function render_actions_bar() {
370 - if ( isset( $_GET['page'] ) && 'ServerInformation' === $_GET['page'] ) : // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
371 - ?>
372 - <div class="mainwp-actions-bar">
373 - <div class="ui two column grid">
374 - <div class="column"></div>
375 - <div class="right aligned column">
376 - <a href="#" style="margin-left:5px" class="ui mini basic green button" id="mainwp-copy-meta-system-report" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Copy the system report to paste it to the MainWP Community.', 'mainwp' ); ?>"><?php esc_html_e( 'Copy System Report for the MainWP Community', 'mainwp' ); ?></a>
377 - <a href="#" class="ui mini green button" id="mainwp-download-system-report"><?php esc_html_e( 'Download System Report', 'mainwp' ); ?></a>
378 - </div>
379 - </div>
380 - </div>
381 - <?php
382 - endif;
383 - }
285 + $items[] = $item;
286 + }
384 287
385 - /**
386 - * Renders Server Information page.
387 - *
388 - * @return void
389 - *
390 - * @uses \MainWP\Dashboard\MainWP_Extensions_View::get_available_extensions()
391 - * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_extensions()
392 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_mainwp_version()
393 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_current_version()
394 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_file_system_method()
395 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_allow_url_fopen()
396 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_exif()
397 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_iptc()
398 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_xml()
399 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_loaded_php_extensions()
400 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_sql_mode()
401 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_wp_root()
402 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_name()
403 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_software()
404 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_os()
405 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_architecture()
406 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_ip()
407 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_protocol()
408 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_http_host()
409 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_https()
410 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::server_self_connect()
411 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_user_agent()
412 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_port()
413 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_gateway_interface()
414 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::memory_usage()
415 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_complete_url()
416 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_request_time()
417 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_http_accept()
418 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_accept_charset()
419 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_script_file_name()
420 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_current_page_uri()
421 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_address()
422 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_host()
423 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_port()
424 - */
425 - public static function render() {
426 - if ( ! mainwp_current_user_have_right( 'dashboard', 'see_server_information' ) ) {
427 - mainwp_do_not_have_permissions( 'server information', 'mainwp' );
428 - return;
429 - }
430 - self::render_header( '' );
288 + return $items;
289 + }
431 290
432 - /**
433 - * Action: mainwp_before_server_info_table
434 - *
435 - * Fires on the top of the Info page, before the Server Info table.
436 - *
437 - * @since 4.0
438 - */
439 - do_action( 'mainwp_before_server_info_table' );
440 - ?>
441 - <div class="ui segment">
442 - <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-server-info-info-message' ) ) : ?>
443 - <div class="ui info message">
444 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-server-info-info-message"></i>
445 - <?php printf( esc_html__( 'Check your system configuration and make sure your MainWP Dashboard passes all system requirements. If you need help with resolving specific errors, please review this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/resolving-system-requirement-issues/" target="_blank">', '</a> <i class="external alternate icon"></i>' ); ?>
446 - </div>
447 - <?php endif; ?>
448 - <?php
449 - if ( function_exists( 'curl_version' ) ) {
450 - if ( ! MainWP_Server_Information_Handler::curlssl_compare( 'OpenSSL/1.1.0', '>=' ) ) {
451 - echo "<div class='ui yellow message'>" . sprintf( esc_html__( 'Your host needs to update OpenSSL to at least version 1.1.0 which is already over 4 years old and contains patches for over 60 vulnerabilities.%1$sThese range from Denial of Service to Remote Code Execution. %2$sClick here for more information.%3$s', 'mainwp' ), '<br/>', '<a href="https://community.letsencrypt.org/t/openssl-client-compatibility-changes-for-let-s-encrypt-certificates/143816" target="_blank">', '</a>' ) . '</div>';
452 - }
453 - }
454 - ?>
455 - <table id="mainwp-system-report-wordpress-table" class="ui unstackable table single line mainwp-system-report-table mainwp-system-info-table">
456 - <thead>
457 - <tr>
458 - <th><?php esc_html_e( 'WordPress Check', 'mainwp' ); ?></th>
459 - <th><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
460 - <th><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
461 - <th class="right aligned"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
462 - </tr>
463 - </thead>
464 - <tbody>
465 - <?php self::render_wordpress_check_tbody(); ?>
466 - </tbody>
467 - </table>
291 + /**
292 + * Get the Info navigation items.
293 + *
294 + * @return array<int, array<string, mixed>> Info navigation items.
295 + */
296 + public static function get_navigation_items( $context = 'default' ) {
297 + $items = array();
468 298
469 - <table id="mainwp-system-report-php-table" class="ui unstackable table fixed mainwp-system-report-table mainwp-system-info-table">
470 - <thead>
471 - <tr>
472 - <th><?php esc_html_e( 'PHP', 'mainwp' ); ?></th>
473 - <th><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
474 - <th><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
475 - <th class="right aligned"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
476 - </tr>
477 - </thead>
478 - <tbody>
479 - <?php self::render_php_check_tbody(); ?>
480 - </tbody>
481 - </table>
299 + foreach ( static::get_core_pages() as $page ) {
300 + $items[] = array(
301 + 'slug' => $page['slug'],
302 + 'title' => $page['nav_title'],
303 + 'href' => 'admin.php?page=' . $page['slug'],
304 + 'active_keys' => $page['active_keys'],
305 + 'show_in_header_nav' => $page['show_in_header_nav'],
306 + 'show_in_subpages_menu' => $page['show_in_subpages_menu'],
307 + 'show_in_left_menu' => $page['show_in_left_menu'],
308 + 'show_in_palette' => $page['show_in_palette'],
309 + 'left_menu_parent' => $page['left_menu_parent'],
310 + 'palette_titles' => $page['palette_titles'],
311 + 'menu_hidden' => false,
312 + );
313 + }
482 314
483 - <table id="mainwp-system-report-mysql-table" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
484 - <thead>
485 - <tr>
486 - <th><?php esc_html_e( 'MySQL', 'mainwp' ); ?></th>
487 - <th><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
488 - <th><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
489 - <th class="right aligned"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
490 - </tr>
491 - </thead>
492 - <tbody>
493 - <?php self::render_mysql_check_tbody(); ?>
494 - </tbody>
495 - </table>
315 + if ( 'left_menu_core' === $context ) {
316 + return $items;
317 + }
496 318
497 - <table id="mainwp-system-report-server-table" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
498 - <thead>
499 - <tr>
500 - <th><?php esc_html_e( 'Server Configuration', 'mainwp' ); ?></th>
501 - <th><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
502 - </tr>
503 - </thead>
504 - <tbody>
505 - <?php self::render_server_check_tbody(); ?>
506 - </tbody>
507 - </table>
319 + if ( 'command_palette' === $context ) {
320 + return array_merge( $items, static::get_filtered_subpage_navigation_items() );
321 + }
508 322
509 - <table id="mainwp-system-report-dashboard-table" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
510 - <thead>
511 - <tr>
512 - <th><?php esc_html_e( 'MainWP Dashboard Settings', 'mainwp' ); ?></th>
513 - <th><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
514 - </tr>
515 - </thead>
516 - <tbody>
517 - <?php self::render_dashboard_check_tbody(); ?>
518 - </tbody>
519 - </table>
323 + foreach ( static::get_subpages() as $subPage ) {
324 + if ( empty( $subPage['slug'] ) || MainWP_Menu::is_disable_menu_item( 3, 'Server' . $subPage['slug'] ) ) {
325 + continue;
326 + }
520 327
521 - <table id="mainwp-system-report-extensions-table" class="ui unstackable table single line mainwp-system-report-table mainwp-system-info-table">
522 - <thead>
523 - <tr>
524 - <th><?php esc_html_e( 'Extensions', 'mainwp' ); ?></th>
525 - <th><?php esc_html_e( 'Version', 'mainwp' ); ?></th>
526 - <th><?php esc_html_e( 'License', 'mainwp' ); ?></th>
527 - <th class="right aligned"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
528 - </tr>
529 - </thead>
530 - <tbody>
531 - <?php self::render_extensions_license_check_tbody(); ?>
532 - </tbody>
533 - </table>
328 + $item = array(
329 + 'slug' => 'Server' . $subPage['slug'],
330 + 'title' => $subPage['title'],
331 + 'href' => ! empty( $subPage['href'] ) ? $subPage['href'] : 'admin.php?page=Server' . $subPage['slug'],
332 + 'active_keys' => array( $subPage['slug'], 'Server' . $subPage['slug'] ),
333 + 'show_in_header_nav' => false,
334 + 'show_in_subpages_menu' => empty( $subPage['menu_hidden'] ),
335 + 'show_in_left_menu' => empty( $subPage['menu_hidden'] ),
336 + 'show_in_palette' => empty( $subPage['menu_hidden'] ),
337 + 'left_menu_parent' => 'ServerInformation',
338 + 'palette_titles' => array( esc_html__( 'System Info', 'mainwp' ), $subPage['title'] ),
339 + 'menu_hidden' => ! empty( $subPage['menu_hidden'] ),
340 + );
534 341
535 - <table id="mainwp-system-report-plugins-table" class="ui single line table unstackable mainwp-system-report-table mainwp-system-info-table">
536 - <thead>
537 - <tr>
538 - <th><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
539 - <th><?php esc_html_e( 'Version', 'mainwp' ); ?></th>
540 - <th><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
541 - </tr>
542 - </thead>
543 - <tbody>
544 - <?php self::render_plugins_check_tbody(); ?>
545 - </tbody>
546 - </table>
342 + if ( isset( $subPage['item_slug'] ) ) {
343 + $item['item_slug'] = $subPage['item_slug'];
344 + }
547 345
548 - <div id="download-server-information" style="opacity:0">
549 - <textarea readonly="readonly" wrap="off"></textarea>
550 - </div>
346 + $items[] = $item;
347 + }
551 348
552 - <script type="text/javascript">
553 - var responsive = true;
554 - if( jQuery( window ).width() > 1140 ) {
555 - responsive = false;
556 - }
557 - jQuery( document ).ready( function() {
558 - jQuery( '.mainwp-system-info-table' ).DataTable( {
559 - responsive: responsive,
560 - colreorder: true,
561 - paging: false,
562 - info: false,
563 - } );
564 - } );
565 - </script>
566 - </div>
349 + return $items;
350 + }
567 351
568 - <?php
352 + /**
353 + * Get the Info command palette items.
354 + *
355 + * @return array<int, array<string, mixed>> Command palette item definitions.
356 + */
357 + public static function get_command_palette_items() {
358 + $items = array();
569 359
570 - /**
571 - * Action: mainwp_after_server_info_table
572 - *
573 - * Fires on the bottom of the Info page, after the Server Info table.
574 - *
575 - * @since 4.0
576 - */
577 - do_action( 'mainwp_after_server_info_table' );
360 + foreach ( static::get_navigation_items( 'command_palette' ) as $item ) {
361 + if ( empty( $item['show_in_palette'] ) ) {
362 + continue;
363 + }
578 364
579 - self::render_footer( '' );
580 - }
365 + $items[] = array(
366 + 'slug' => $item['slug'],
367 + 'href' => $item['href'],
368 + 'path_titles' => $item['palette_titles'],
369 + );
370 + }
581 371
582 - /**
583 - * Renders WordPress checks table body.
584 - *
585 - * @return void
586 - */
587 - public static function render_wordpress_check_tbody() {
588 - self::render_row( 'WordPress Version', '>=', '6.2', 'get_wordpress_version', '', '', null, null, self::ERROR );
589 - self::render_row( 'WordPress Memory Limit', '>=', '64M', 'get_wordpress_memory_limit', '', '', null );
590 - self::render_row( 'MultiSite Disabled', '=', true, 'check_if_multisite', '', '', null );
591 - ?>
592 - <tr>
593 - <td><?php esc_html_e( 'FileSystem Method', 'mainwp' ); ?></td>
594 - <td><?php echo esc_html( '= direct' ); ?></td>
595 - <td><?php echo MainWP_Server_Information_Handler::get_file_system_method(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
596 - <td class="right aligned"><?php echo self::get_file_system_method_check(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
597 - </tr>
598 - <?php
599 - }
372 + return $items;
373 + }
600 374
601 - /**
602 - * Renders PHP checks table body.
603 - *
604 - * @return void
605 - */
606 - public static function render_php_check_tbody() {
607 - self::render_row( 'PHP Version', '>=', '7.4', 'get_php_version', '', '', null, null, self::ERROR );
608 - self::render_row( 'PHP Safe Mode Disabled', '=', true, 'get_php_safe_mode', '', '', null );
609 - self::render_row( 'PHP Max Execution Time', '>=', '30', 'get_max_execution_time', 'seconds', '=', '0' );
610 - self::render_row( 'PHP Max Input Time', '>=', '30', 'get_max_input_time', 'seconds', '=', '0' );
611 - self::render_row( 'PHP Memory Limit', '>=', '256M', 'get_php_memory_limit', '', '', null, 'filesize' );
612 - self::render_row( 'PCRE Backtracking Limit', '>=', '10000', 'get_output_buffer_size', '', '', null );
613 - self::render_row( 'PHP Upload Max Filesize', '>=', '2M', 'get_upload_max_filesize', '', '', null, 'filesize' );
614 - self::render_row( 'PHP Post Max Size', '>=', '2M', 'get_post_max_size', '', '', null, 'filesize' );
615 - self::render_row( 'SSL Extension Enabled', '=', true, 'get_ssl_support', '', '', null );
616 - self::render_row( 'SSL Warnings', '=', '', 'get_ssl_warning', 'empty', '', null );
617 - self::render_row( 'cURL Extension Enabled', '=', true, 'get_curl_support', '', '', null, null, self::ERROR );
618 - self::render_row( 'cURL Timeout', '>=', '300', 'get_curl_timeout', 'seconds', '=', '0' );
619 - if ( function_exists( 'curl_version' ) ) {
620 - $reuire_curl = '7.18.1';
621 - if ( version_compare( MainWP_Server_Information_Handler::get_php_version(), '8.0.0' ) >= 0 ) {
622 - $reuire_curl = '7.29.0';
623 - }
624 - self::render_row( 'cURL Version', '>=', $reuire_curl, 'get_curl_version', '', '', null );
625 - $openssl_version = 'OpenSSL/1.1.0';
626 - self::render_row(
627 - 'OpenSSL Version',
628 - '>=',
629 - $openssl_version,
630 - 'get_curl_ssl_version',
631 - '',
632 - '',
633 - null,
634 - 'curlssl'
635 - );
375 + /**
376 + * Method init_menu()
377 + *
378 + * Initiate Info subPage menu.
379 + *
380 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
381 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
382 + */
383 + public static function init_menu() { // phpcs:ignore -- NOSONAR - complex.
636 384
637 - $wk = MainWP_Server_Information_Handler::get_openssl_working_status();
638 - ?>
639 - <tr>
640 - <td>OpenSSL Working Status</td>
641 - <td>Yes</td>
642 - <td><?php echo( $wk ? 'Yes' : 'No' ); ?></td>
643 - <td class="right aligned"><?php echo ( $wk ? self::get_pass_html() : self::get_warning_html() ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
644 - </tr>
645 - <?php
385 + add_action( 'mainwp_pageheader_infor', array( static::get_class_name(), 'render_header' ) );
386 + add_action( 'mainwp_pagefooter_infor', array( static::get_class_name(), 'render_footer' ) );
646 387
647 - }
648 - ?>
649 - <tr>
650 - <td><?php esc_html_e( 'PHP Allow URL fopen', 'mainwp' ); ?></td>
651 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
652 - <td><?php MainWP_Server_Information_Handler::get_php_allow_url_fopen(); ?></td>
653 - <td></td>
654 - </tr>
655 - <tr>
656 - <td><?php esc_html_e( 'PHP Exif Support', 'mainwp' ); ?></td>
657 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
658 - <td><?php MainWP_Server_Information_Handler::get_php_exif(); ?></td>
659 - <td></td>
660 - </tr>
661 - <tr>
662 - <td><?php esc_html_e( 'PHP IPTC Support', 'mainwp' ); ?></td>
663 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
664 - <td><?php MainWP_Server_Information_Handler::get_php_iptc(); ?></td>
665 - <td></td>
666 - </tr>
667 - <tr>
668 - <td><?php esc_html_e( 'PHP XML Support', 'mainwp' ); ?></td>
669 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
670 - <td><?php MainWP_Server_Information_Handler::get_php_xml(); ?></td>
671 - <td></td>
672 - </tr>
673 - <tr>
674 - <td><?php esc_html_e( 'PHP Disabled Functions', 'mainwp' ); ?></td>
675 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
676 - <td><?php self::php_disabled_functions(); ?></td>
677 - <td></td>
678 - </tr>
679 - <tr>
680 - <td><?php esc_html_e( 'PHP Loaded Extensions', 'mainwp' ); ?></td>
681 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
682 - <td><?php MainWP_Server_Information_Handler::get_loaded_php_extensions(); ?></td>
683 - <td></td>
684 - </tr>
685 - <?php
686 - }
388 + foreach ( static::get_core_pages() as $page ) {
389 + add_submenu_page(
390 + 'mainwp_tab',
391 + $page['page_title'],
392 + $page['menu_title'],
393 + 'read',
394 + $page['slug'],
395 + $page['callback']
396 + );
397 + }
687 398
688 - /**
689 - * Renders MySQL checks table body.
690 - *
691 - * @return void
692 - */
693 - public static function render_mysql_check_tbody() {
694 - self::render_row( 'MySQL Version', '>=', '5.0', 'get_mysql_version', '', '', null, null, self::ERROR );
695 - ?>
696 - <tr>
697 - <td><?php esc_html_e( 'MySQL Mode', 'mainwp' ); ?></td>
698 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
699 - <td><?php MainWP_Server_Information_Handler::get_sql_mode(); ?></td>
700 - <td></td>
701 - </tr>
702 - <tr>
703 - <td><?php esc_html_e( 'MySQL Client Encoding', 'mainwp' ); ?></td>
704 - <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
705 - <td><?php echo defined( 'DB_CHARSET' ) ? esc_html( DB_CHARSET ) : ''; ?></td>
706 - <td></td>
707 - </tr>
708 - <?php
709 - }
399 + foreach ( static::get_subpages() as $subPage ) {
400 + if ( empty( $subPage['slug'] ) || MainWP_Menu::is_disable_menu_item( 3, 'Server' . $subPage['slug'] ) ) {
401 + continue;
402 + }
710 403
711 - /**
712 - * Renders Server checks table body.
713 - *
714 - * @return void
715 - */
716 - public static function render_server_check_tbody() {
717 - ?>
718 - <tr class="mwp-not-generate-row">
719 - <td><?php esc_html_e( 'WordPress Root Directory', 'mainwp' ); ?></td>
720 - <td><?php MainWP_Server_Information_Handler::get_wp_root(); ?></td>
721 - </tr>
722 - <tr class="mwp-not-generate-row">
723 - <td><?php esc_html_e( 'Server Name', 'mainwp' ); ?></td>
724 - <td><?php MainWP_Server_Information_Handler::get_server_name(); ?></td>
725 - </tr>
726 - <tr>
727 - <td><?php esc_html_e( 'Server Software', 'mainwp' ); ?></td>
728 - <td><?php MainWP_Server_Information_Handler::get_server_software(); ?></td>
729 - </tr>
730 - <tr>
731 - <td><?php esc_html_e( 'Operating System', 'mainwp' ); ?></td>
732 - <td><?php MainWP_Server_Information_Handler::get_os(); ?></td>
733 - </tr>
734 - <tr>
735 - <td><?php esc_html_e( 'Architecture', 'mainwp' ); ?></td>
736 - <td><?php MainWP_Server_Information_Handler::get_architecture(); ?></td>
737 - </tr>
738 - <tr class="mwp-not-generate-row">
739 - <td><?php esc_html_e( 'Server IP', 'mainwp' ); ?></td>
740 - <td><?php MainWP_Server_Information_Handler::get_server_ip(); ?></td>
741 - </tr>
742 - <tr>
743 - <td><?php esc_html_e( 'Server Protocol', 'mainwp' ); ?></td>
744 - <td><?php MainWP_Server_Information_Handler::get_server_protocol(); ?></td>
745 - </tr>
746 - <tr class="mwp-not-generate-row">
747 - <td><?php esc_html_e( 'HTTP Host', 'mainwp' ); ?></td>
748 - <td><?php MainWP_Server_Information_Handler::get_http_host(); ?></td>
749 - </tr>
750 - <tr>
751 - <td><?php esc_html_e( 'HTTPS', 'mainwp' ); ?></td>
752 - <td><?php MainWP_Server_Information_Handler::get_https(); ?></td>
753 - </tr>
754 - <tr>
755 - <td><?php esc_html_e( 'Server self connect', 'mainwp' ); ?></td>
756 - <td><?php MainWP_Server_Information_Handler::server_self_connect(); ?></td>
757 - </tr>
758 - <tr>
759 - <td><?php esc_html_e( 'User Agent', 'mainwp' ); ?></td>
760 - <td><?php MainWP_Server_Information_Handler::get_user_agent(); ?></td>
761 - </tr>
762 - <tr class="mwp-not-generate-row">
763 - <td><?php esc_html_e( 'Server Port', 'mainwp' ); ?></td>
764 - <td><?php MainWP_Server_Information_Handler::get_server_port(); ?></td>
765 - </tr>
766 - <tr>
767 - <td><?php esc_html_e( 'Gateway Interface', 'mainwp' ); ?></td>
768 - <td><?php MainWP_Server_Information_Handler::get_server_gateway_interface(); ?></td>
769 - </tr>
770 - <tr>
771 - <td><?php esc_html_e( 'Memory Usage', 'mainwp' ); ?></td>
772 - <td><?php MainWP_Server_Information_Handler::memory_usage(); ?></td>
773 - </tr>
774 - <tr class="mwp-not-generate-row">
775 - <td><?php esc_html_e( 'Complete URL', 'mainwp' ); ?></td>
776 - <td><?php MainWP_Server_Information_Handler::get_complete_url(); ?></td>
777 - </tr>
778 - <tr>
779 - <td><?php esc_html_e( 'Request Time', 'mainwp' ); ?></td>
780 - <td><?php MainWP_Server_Information_Handler::get_server_request_time(); ?></td>
781 - </tr>
782 - <tr>
783 - <td><?php esc_html_e( 'Accept Content', 'mainwp' ); ?></td>
784 - <td><?php MainWP_Server_Information_Handler::get_server_http_accept(); ?></td>
785 - </tr>
786 - <tr>
787 - <td><?php esc_html_e( 'Accept-Charset Content', 'mainwp' ); ?></td>
788 - <td><?php MainWP_Server_Information_Handler::get_server_accept_charset(); ?></td>
789 - </tr>
790 - <tr class="mwp-not-generate-row">
791 - <td><?php esc_html_e( 'Currently Executing Script Pathname', 'mainwp' ); ?></td>
792 - <td><?php MainWP_Server_Information_Handler::get_script_file_name(); ?></td>
793 - </tr>
794 - <tr class="mwp-not-generate-row">
795 - <td><?php esc_html_e( 'Current Page URI', 'mainwp' ); ?></td>
796 - <td><?php MainWP_Server_Information_Handler::get_current_page_uri(); ?></td>
797 - </tr>
798 - <tr class="mwp-not-generate-row">
799 - <td><?php esc_html_e( 'Remote Address', 'mainwp' ); ?></td>
800 - <td><?php MainWP_Server_Information_Handler::get_remote_address(); ?></td>
801 - </tr>
802 - <tr class="mwp-not-generate-row">
803 - <td><?php esc_html_e( 'Remote Host', 'mainwp' ); ?></td>
804 - <td><?php MainWP_Server_Information_Handler::get_remote_host(); ?></td>
805 - </tr>
806 - <tr class="mwp-not-generate-row">
807 - <td><?php esc_html_e( 'Remote Port', 'mainwp' ); ?></td>
808 - <td><?php MainWP_Server_Information_Handler::get_remote_port(); ?></td>
809 - </tr>
810 - <?php
811 - }
404 + add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'Server' . $subPage['slug'], $subPage['callback'] );
405 + }
406 + }
812 407
813 - /**
814 - * Renders MainWP Dashboard checks table body.
815 - *
816 - * @return void
817 - */
818 - public static function render_dashboard_check_tbody() {
819 - ?>
820 - <tr>
821 - <td><?php esc_html_e( 'MainWP Dashboard Version', 'mainwp' ); ?></td>
822 - <td><?php echo 'Latest: ' . MainWP_Server_Information_Handler::get_mainwp_version(); ?> | <?php echo 'Detected: ' . MainWP_Server_Information_Handler::get_current_version(); ?> <?php echo self::get_mainwp_version_check(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
823 - </tr>
824 - <?php
825 - self::check_directory_mainwp_directory();
826 - self::display_mainwp_options();
827 - }
408 + /**
409 + * Renders Sub Pages Menu.
410 + *
411 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
412 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
413 + */
414 + public static function init_subpages_menu() { // phpcs:ignore -- NOSONAR - complex.
415 + ?>
416 + <div id="menu-mainwp-ServerInformation" class="mainwp-submenu-wrapper">
417 + <div class="wp-submenu sub-open">
418 + <div class="mainwp_boxout">
419 + <div class="mainwp_boxoutin"></div>
420 + <?php foreach ( static::get_navigation_items() as $item ) { ?>
421 + <?php if ( empty( $item['show_in_subpages_menu'] ) ) { continue; } ?>
422 + <a href="<?php echo esc_url( static::get_navigation_item_url( $item['href'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $item['title'] ); ?></a>
423 + <?php } ?>
424 + </div>
425 + </div>
426 + </div>
427 + <?php
428 + }
828 429
829 - /**
830 - * Renders extensions API License status table body.
831 - *
832 - * @return void
833 - */
834 - public static function render_extensions_license_check_tbody() {
835 - $extensions = MainWP_Extensions_Handler::get_extensions();
836 - $extensions_slugs = array();
837 - if ( 0 === count( $extensions ) ) {
838 - echo '<tr><td colspan="4">' . esc_html__( 'No installed extensions', 'mainwp' ) . '</td></tr>';
839 - }
840 - foreach ( $extensions as $extension ) {
841 - $extensions_slugs[] = $extension['slug'];
842 - ?>
843 - <tr>
844 - <td><?php echo esc_html( $extension['name'] ); ?></td>
845 - <td><?php echo esc_html( $extension['version'] ); ?></td>
846 - <?php
847 - if ( isset( $extension['mainwp'] ) && $extension['mainwp'] ) {
848 - ?>
849 - <td><?php echo isset( $extension['activated_key'] ) && 'Activated' === $extension['activated_key'] ? esc_html__( 'Active', 'mainwp' ) : esc_html__( 'Inactive', 'mainwp' ); ?></td>
850 - <td class="right aligned"><?php echo isset( $extension['activated_key'] ) && 'Activated' === $extension['activated_key'] ? self::get_pass_html() : self::get_warning_html( self::WARNING ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
851 - <?php
852 - } else {
853 - ?>
854 - <td></td>
855 - <td></td>
856 - <?php
857 - }
858 - ?>
859 - </tr>
860 - <?php
861 - }
862 - }
430 + /**
431 + * Initiates Server Information left menu.
432 + *
433 + * @param array $subPages array of subpages.
434 + *
435 + * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
436 + * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
437 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
438 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
439 + */
440 + public static function init_left_menu( $subPages = array() ) {
441 + MainWP_Menu::add_left_menu(
442 + array(
443 + 'title' => esc_html__( 'Info', 'mainwp' ),
444 + 'parent_key' => 'mainwp_tab',
445 + 'slug' => 'ServerInformation',
446 + 'href' => 'admin.php?page=ServerInformation',
447 + 'icon' => '<i class="info circle icon"></i>',
448 + ),
449 + 0
450 + );
863 451
864 - /**
865 - * Renders plugins check table body.
866 - *
867 - * @return void
868 - */
869 - public static function render_plugins_check_tbody() {
870 - $all_extensions = MainWP_Extensions_View::get_available_extensions();
871 - $all_plugins = get_plugins();
872 - foreach ( $all_plugins as $slug => $plugin ) {
873 - if ( isset( $all_extensions[ dirname( $slug ) ] ) ) {
874 - continue;
875 - }
876 - ?>
877 - <tr>
878 - <td><?php echo esc_html( $plugin['Name'] ); ?></td>
879 - <td><?php echo esc_html( $plugin['Version'] ); ?></td>
880 - <td class="right aligned"><?php echo is_plugin_active( $slug ) ? esc_html__( 'Active', 'mainwp' ) : esc_html__( 'Inactive', 'mainwp' ); ?></td>
881 - </tr>
882 - <?php
883 - }
884 - }
452 + $init_sub_subleftmenu = array();
885 453
886 - /**
887 - * Renders MainWP system requirements check.
888 - *
889 - * @return void
890 - */
891 - public static function render_quick_setup_system_check() {
892 - /**
893 - * Action: mainwp_before_system_requirements_check
894 - *
895 - * Fires on the bottom of the System Requirements page, in Quick Setup Wizard.
896 - *
897 - * @since 4.1
898 - */
899 - do_action( 'mainwp_before_system_requirements_check' );
900 - ?>
901 - <table id="mainwp-quick-system-requirements-check" class="ui single line table">
902 - <thead>
903 - <tr>
904 - <th><?php esc_html_e( 'Check', 'mainwp' ); ?></th>
905 - <th><?php esc_html_e( 'Required Value', 'mainwp' ); ?></th>
906 - <th><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
907 - <th class="collapsing"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
908 - </tr>
909 - </thead>
910 - <tbody>
911 - <?php
912 - self::render_row_with_description( esc_html__( 'PHP Version', 'mainwp' ), '>=', '7.4', 'get_php_version', '', '', null );
913 - self::render_row_with_description( esc_html__( 'SSL Extension Enabled', 'mainwp' ), '=', true, 'get_ssl_support', '', '', null );
914 - self::render_row_with_description( esc_html__( 'cURL Extension Enabled', 'mainwp' ), '=', true, 'get_curl_support', '', '', null );
915 - $openssl_version = 'OpenSSL/1.1.0';
916 - self::render_row_with_description(
917 - 'cURL SSL Version',
918 - '>=',
919 - $openssl_version,
920 - 'get_curl_ssl_version',
921 - '',
922 - '',
923 - null,
924 - 'curlssl'
925 - );
454 + foreach ( static::get_navigation_items( 'left_menu_core' ) as $item ) {
455 + if ( empty( $item['show_in_left_menu'] ) ) {
456 + continue;
457 + }
926 458
927 - if ( ! MainWP_Server_Information_Handler::curlssl_compare( $openssl_version, '>=' ) ) {
928 - echo "<tr class='warning'><td colspan='4'><i class='attention icon'></i>" . sprintf( esc_html__( 'Your host needs to update OpenSSL to at least version 1.1.0 which is already over 4 years old and contains patches for over 60 vulnerabilities.%1$sThese range from Denial of Service to Remote Code Execution. %2$sClick here for more information.%3$s', 'mainwp' ), '<br/>', '<a href="https://community.letsencrypt.org/t/openssl-client-compatibility-changes-for-let-s-encrypt-certificates/143816" target="_blank">', '</a>' ) . '</td></tr>';
929 - }
930 - self::render_row_with_description( esc_html__( 'MySQL Version', 'mainwp' ), '>=', '5.0', 'get_mysql_version', '', '', null );
931 - ?>
932 - </tbody>
933 - </table>
934 - <?php
935 - /**
936 - * Action: mainwp_after_system_requirements_check
937 - *
938 - * Fires on the bottom of the System Requirements page, in Quick Setup Wizard.
939 - *
940 - * @since 4.1
941 - */
942 - do_action( 'mainwp_after_system_requirements_check' );
943 - }
459 + $init_sub_subleftmenu[] = array(
460 + 'title' => $item['title'],
461 + 'parent_key' => $item['left_menu_parent'],
462 + 'href' => $item['href'],
463 + 'slug' => $item['slug'],
464 + 'right' => '',
465 + );
466 + }
944 467
945 - /**
946 - * Compares the detected MainWP Dashboard version agains the verion in WP.org.
947 - *
948 - * @return mixed Pass|self::get_warning_html().
949 - *
950 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_mainwp_version()
951 - */
952 - public static function get_mainwp_version_check() {
953 - $current = get_option( 'mainwp_plugin_version' );
954 - $latest = MainWP_Server_Information_Handler::get_mainwp_version();
955 - if ( $current === $latest ) {
956 - return self::get_pass_html();
957 - } else {
958 - return self::get_warning_html();
959 - }
960 - }
468 + if ( empty( $subPages ) ) {
469 + $subPages = static::get_subpages();
470 + }
961 471
962 - /**
963 - * Renders the Cron Schedule page.
964 - *
965 - * @return void
966 - *
967 - * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
968 - * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
969 - */
970 - public static function render_cron() {
971 - if ( ! mainwp_current_user_have_right( 'dashboard', 'see_server_information' ) ) {
972 - mainwp_do_not_have_permissions( 'cron schedules', 'mainwp' );
973 - return;
974 - }
472 + MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'ServerInformation', 'Server' );
975 473
976 - self::render_header( 'ServerInformationCron' );
474 + foreach ( $init_sub_subleftmenu as $item ) {
475 + if ( isset( $item['item_slug'] ) ) {
476 + if ( MainWP_Menu::is_disable_menu_item( 3, $item['item_slug'] ) ) {
477 + continue;
478 + }
479 + } elseif ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
480 + continue;
481 + }
977 482
978 - $local_timestamp = MainWP_Utility::get_timestamp();
483 + MainWP_Menu::add_left_menu( $item, 2 );
484 + }
485 + }
979 486
980 - $freq = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
981 - if ( $freq <= 0 ) {
982 - $freq = 1;
983 - }
984 - $auto_update_text = self::get_schedule_auto_update_label( $freq );
487 + /**
488 + * Renders Info header.
489 + *
490 + * @param string $shownPage Current page.
491 + *
492 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
493 + * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
494 + * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
495 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_apache_server_software()
496 + */
497 + public static function render_header( $shownPage = '' ) {
498 + $params = array(
499 + 'title' => esc_html__( 'Info', 'mainwp' ),
500 + );
985 501
986 - $cron_jobs = array(
987 - 'Check for available updates' => array( 'mainwp_updatescheck_start_last_timestamp', 'mainwp_cronupdatescheck_action', $auto_update_text ),
988 - 'Check for reconnect sites' => array( 'mainwp_cron_last_stats', 'mainwp_cronreconnect_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' ),
989 - 'Ping childs sites' => array( 'mainwp_cron_last_ping', 'mainwp_cronpingchilds_action', esc_html__( 'Once daily', 'mainwp' ), 'daily' ),
990 - );
502 + MainWP_UI::render_top_header( $params );
991 503
992 - $disableSitesMonitoring = get_option( 'mainwp_disableSitesChecking', 1 );
993 - if ( ! $disableSitesMonitoring ) {
994 - $cron_jobs['Child site uptime monitoring'] = array( 'mainwp_cron_checksites_last_timestamp', 'mainwp_croncheckstatus_action', esc_html__( 'Once every minute', 'mainwp' ), 'minutely' );
995 - }
504 + $renderItems = array();
996 505
997 - $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default.
998 - if ( ! $disableHealthChecking ) {
999 - $cron_jobs['Site Health monitoring'] = array( 'mainwp_cron_checksiteshealth_last_timestamp', 'mainwp_cronsitehealthcheck_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' );
1000 - }
506 + foreach ( static::get_navigation_items() as $item ) {
507 + if ( empty( $item['show_in_header_nav'] ) ) {
508 + continue;
509 + }
1001 510
1002 - if ( get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
1003 - $cron_jobs['Start backups (Legacy)'] = array( 'mainwp_cron_last_backups', 'mainwp_cronbackups_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' );
1004 - $cron_jobs['Continue backups (Legacy)'] = array( 'mainwp_cron_last_backups_continue', 'mainwp_cronbackups_continue_action', esc_html__( 'Once every five minutes', 'mainwp' ), '5minutely' );
1005 - }
511 + $renderItems[] = array(
512 + 'title' => $item['title'],
513 + 'href' => $item['href'],
514 + 'active' => in_array( $shownPage, $item['active_keys'], true ),
515 + );
516 + }
1006 517
1007 - /**
1008 - * Action: mainwp_before_cron_jobs_table
1009 - *
1010 - * Renders on the top of the Cron Jobs page, before the Schedules table.
1011 - *
1012 - * @since 4.0
1013 - */
1014 - do_action( 'mainwp_before_cron_jobs_table' );
1015 - ?>
1016 - <div class="ui segment">
1017 - <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-cron-info-message' ) ) : ?>
1018 - <div class="ui info message">
1019 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-cron-info-message"></i>
1020 - <?php printf( esc_html__( 'Make sure scheduled actions are working correctly. If scheduled actions do not run normally, please review this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/scheduled-events-not-occurring/" target="_blank">', '</a> <i class="external alternate icon"></i>' ); ?>
1021 - </div>
1022 - <?php endif; ?>
1023 - <table class="ui single line unstackable table" id="mainwp-cron-jobs-table">
1024 - <thead>
1025 - <tr>
1026 - <th><?php esc_html_e( 'Cron Job', 'mainwp' ); ?></th>
1027 - <th><?php esc_html_e( 'Hook', 'mainwp' ); ?></th>
1028 - <th><?php esc_html_e( 'Schedule', 'mainwp' ); ?></th>
1029 - <th><?php esc_html_e( 'Last Run', 'mainwp' ); ?></th>
1030 - <th><?php esc_html_e( 'Next Run', 'mainwp' ); ?></th>
1031 - </tr>
1032 - </thead>
1033 - <tbody>
1034 - <?php
1035 - $useWPCron = ( false === get_option( 'mainwp_wp_cron' ) ) || ( 1 === (int) get_option( 'mainwp_wp_cron' ) );
518 + if ( isset( $_GET['page'] ) && 'PluginPrivacy' !== $_GET['page'] ) { //phpcs:ignore -- monce safe.
519 + MainWP_UI::render_page_navigation( $renderItems );
520 + }
1036 521
1037 - foreach ( $cron_jobs as $cron_job => $hook ) {
522 + static::render_actions_bar();
1038 523
1039 - $is_auto_update_job = false;
1040 - $lasttime_run = 0;
1041 - if ( 'mainwp_updatescheck_start_last_timestamp' === $hook[0] ) {
1042 - $update_time = MainWP_Settings::get_websites_automatic_update_time();
1043 - $last_run = $update_time['last'];
1044 - $next_run = $update_time['next'];
1045 - $is_auto_update_job = true;
1046 - } elseif ( false === get_option( $hook[0] ) ) {
1047 - $last_run = esc_html__( 'Never', 'mainwp' );
1048 - } else {
1049 - $lasttime_run = get_option( $hook[0] );
1050 - if ( $lasttime_run ) {
1051 - $last_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $lasttime_run ) );
1052 - } else {
1053 - $last_run = esc_html__( 'Never', 'mainwp' );
1054 - }
1055 - }
524 + echo '<div>';
525 + }
1056 526
1057 - if ( $useWPCron && 'mainwp_updatescheck_start_last_timestamp' !== $hook[0] ) {
1058 - $next_run = wp_next_scheduled( $hook[1] );
1059 - if ( ! empty( $next_run ) ) {
1060 - $next_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $next_run ) );
1061 - }
1062 - }
527 + /**
528 + * Renders Server Information footer.
529 + */
530 + public static function render_footer() {
531 + echo '</div>';
532 + }
1063 533
1064 - if ( empty( $next_run ) || ( ! $useWPCron && ! $is_auto_update_job && isset( $hook[3] ) ) ) {
1065 - $nexttime_run = self::get_schedule_next_time_to_show( $hook[3], $lasttime_run, $local_timestamp );
1066 - if ( $nexttime_run < $local_timestamp + 3 * MINUTE_IN_SECONDS ) {
1067 - $next_run = esc_html__( 'Any minute', 'mainwp' );
1068 - } else {
1069 - $next_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $nexttime_run ) );
1070 - }
1071 - }
534 + /**
535 + * Renders Server Information action bar element.
536 + */
537 + public static function render_actions_bar() {
538 + if ( isset( $_GET['page'] ) && 'ServerInformation' === $_GET['page'] ) : // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
539 + ?>
540 + <div class="mainwp-actions-bar">
541 + <div class="ui stackable middle aligned two column grid">
542 + <div class="column">
543 + <a href="#" class="ui mini green button" id="mainwp-download-system-report"><?php esc_html_e( 'Download Full System Report', 'mainwp' ); ?></a>
544 + <a href="#" style="margin-left:5px" class="ui mini basic green button" id="mainwp-download-community-system-report"><?php esc_html_e( 'Download Community System Report', 'mainwp' ); ?></a>
545 + </div>
546 + <div class="right aligned column">
547 + <div class="ui icon input">
548 + <input type="search" id="mainwp-system-report-global-search" placeholder="<?php esc_attr_e( 'Search system report', 'mainwp' ); ?>" aria-label="<?php esc_attr_e( 'Search system report', 'mainwp' ); ?>">
549 + <i class="search icon"></i>
550 + </div>
551 + </div>
552 + </div>
553 + </div>
554 + <?php
555 + endif;
556 + }
1072 557
1073 - // phpcs:disable WordPress.Security.EscapeOutput
1074 - ?>
1075 - <tr>
1076 - <td><?php echo $cron_job; ?></td>
1077 - <td><?php echo $hook[1]; ?></td>
1078 - <td><?php echo $hook[2]; ?></td>
1079 - <td><?php echo esc_html( $last_run ); ?></td>
1080 - <td><?php echo ! empty( $next_run ) ? esc_html( $next_run ) : ''; ?></td>
1081 - </tr>
1082 - <?php
1083 - // phpcs:enable
1084 - }
1085 - /**
1086 - * Action: mainwp_cron_jobs_list
1087 - *
1088 - * Renders as the last row of the Schedules table.
1089 - *
1090 - * @since 4.0
1091 - */
1092 - do_action( 'mainwp_cron_jobs_list' );
1093 - ?>
1094 - </tbody>
1095 - </table>
1096 - <?php
1097 - $table_features = array(
1098 - 'searching' => 'true',
1099 - 'paging' => 'false',
1100 - 'info' => 'false',
1101 - 'responsive' => 'true',
1102 - );
1103 - /**
1104 - * Filter: mainwp_cron_jobs_table_features
1105 - *
1106 - * Filters the Cron Schedules table features.
1107 - *
1108 - * @since 4.1
1109 - */
1110 - $table_features = apply_filters( 'mainwp_cron_jobs_table_features', $table_features );
1111 - ?>
1112 - <script type="text/javascript">
1113 - var responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
1114 - if( jQuery( window ).width() > 1140 ) {
1115 - responsive = false;
1116 - }
1117 - jQuery( document ).ready( function() {
1118 - jQuery( '#mainwp-cron-jobs-table' ).DataTable( {
1119 - "searching": <?php echo esc_html( $table_features['searching'] ); ?>,
1120 - "paging": <?php echo esc_html( $table_features['paging'] ); ?>,
1121 - "info": <?php echo esc_html( $table_features['info'] ); ?>,
1122 - "responsive": responsive,
1123 - } );
1124 - } );
1125 - </script>
1126 - </div>
1127 - <?php
558 + /**
559 + * Renders Server Information page.
560 + *
561 + * @return void
562 + *
563 + * @uses \MainWP\Dashboard\MainWP_Extensions_View::get_available_extensions()
564 + * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_extensions()
565 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_mainwp_version()
566 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_current_version()
567 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_file_system_method()
568 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_allow_url_fopen()
569 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_exif()
570 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_iptc()
571 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_php_xml()
572 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_loaded_php_extensions()
573 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_sql_mode()
574 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_wp_root()
575 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_name()
576 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_software()
577 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_os()
578 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_architecture()
579 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_ip()
580 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_protocol()
581 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_http_host()
582 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_https()
583 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::server_self_connect()
584 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_user_agent()
585 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_port()
586 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_gateway_interface()
587 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::memory_usage()
588 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_complete_url()
589 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_request_time()
590 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_http_accept()
591 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_server_accept_charset()
592 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_script_file_name()
593 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_current_page_uri()
594 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_address()
595 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_host()
596 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_remote_port()
597 + */
598 + public static function render() {
599 + if ( ! \mainwp_current_user_can( 'dashboard', 'see_server_information' ) ) {
600 + \mainwp_do_not_have_permissions( 'server information', 'mainwp' );
601 + return;
602 + }
603 + static::render_header( '' );
1128 604
1129 - /**
1130 - * Action: mainwp_after_cron_jobs_table
1131 - *
1132 - * Renders on the bottom of the Cron Jobs page, after the Schedules table.
1133 - *
1134 - * @since 4.0
1135 - */
1136 - do_action( 'mainwp_after_cron_jobs_table' );
605 + /**
606 + * Action: mainwp_before_server_info_table
607 + *
608 + * Fires on the top of the Info page, before the Server Info table.
609 + *
610 + * @since 4.0
611 + */
612 + do_action( 'mainwp_before_server_info_table' );
613 + ?>
614 + <div id="mainwp-system-report-page" class="ui padded segment">
615 + <?php
616 + if ( function_exists( 'curl_version' ) && ! MainWP_Server_Information_Handler::curlssl_compare( 'OpenSSL/1.1.0', '>=' ) ) {
617 + /* translators: 1: line break tag, 2: opening anchor tag, 3: closing anchor tag */
618 + echo "<div class='ui yellow message'>" . sprintf( esc_html__( 'Your host needs to update OpenSSL to at least version 1.1.0 which is already over 4 years old and contains patches for over 60 vulnerabilities.%1$sThese range from Denial of Service to Remote Code Execution. %2$sClick here for more information.%3$s', 'mainwp' ), '<br/>', '<a href="https://community.letsencrypt.org/t/openssl-client-compatibility-changes-for-let-s-encrypt-certificates/143816" target="_blank">', '</a>' ) . '</div>';
619 + }
1137 620
1138 - self::render_footer( 'ServerInformationCron' );
1139 - }
621 + // Detect issues before rendering.
622 + $datatable_rows = MainWP_Server_Information_Handler::get_database_report_rows();
1140 623
1141 - /**
1142 - * Get frequency auto update to show.
1143 - *
1144 - * @param int $freq frequency of auto update.
1145 - *
1146 - * @return string label of frequency.
1147 - */
1148 - public static function get_schedule_auto_update_label( $freq ) {
1149 - $freq = intval( $freq );
1150 - $text = '';
1151 - switch ( $freq ) {
1152 - case 1:
1153 - $text = esc_html__( 'Once per day', 'mainwp' );
1154 - break;
1155 - case 2:
1156 - $text = esc_html__( 'Twice per day', 'mainwp' );
1157 - break;
1158 - case 3:
1159 - $text = esc_html__( 'Three times per day', 'mainwp' );
1160 - break;
1161 - case 4:
1162 - $text = esc_html__( 'Four times per day', 'mainwp' );
1163 - break;
1164 - case 5:
1165 - $text = esc_html__( 'Five times per day', 'mainwp' );
1166 - break;
1167 - case 6:
1168 - $text = esc_html__( 'Six times per day', 'mainwp' );
1169 - break;
1170 - case 7:
1171 - $text = esc_html__( 'Seven times per day', 'mainwp' );
1172 - break;
1173 - case 8:
1174 - $text = esc_html__( 'Eight times per day', 'mainwp' );
1175 - break;
1176 - case 9:
1177 - $text = esc_html__( 'Nine times per day', 'mainwp' );
1178 - break;
1179 - case 10:
1180 - $text = esc_html__( 'Ten times per day', 'mainwp' );
1181 - break;
1182 - case 11:
1183 - $text = esc_html__( 'Eleven times per day', 'mainwp' );
1184 - break;
1185 - case 12:
1186 - $text = esc_html__( 'Twelve times per day', 'mainwp' );
1187 - break;
1188 - }
1189 - return $text;
1190 - }
624 + static::render_detected_issues_summary();
625 + ?>
626 + <style type="text/css">
627 + #mainwp-system-report-page {
628 + padding-top: 1rem !important;
629 + }
1191 630
1192 - /**
1193 - * Get next time of schedule job to show.
1194 - *
1195 - * @param string $job_freq frequency of schedule job.
1196 - * @param int $lasttime_run Lasttime to run.
1197 - * @param int $local_timestamp current local time.
1198 - *
1199 - * @return int next run time of schedule job.
1200 - */
1201 - public static function get_schedule_next_time_to_show( $job_freq, $lasttime_run, $local_timestamp ) {
1202 - $next_time = $local_timestamp;
1203 - $lasttime_run = is_numeric( $lasttime_run ) ? intval( $lasttime_run ) : false;
1204 - switch ( $job_freq ) {
1205 - case 'daily':
1206 - $next_time = $lasttime_run ? $lasttime_run + DAY_IN_SECONDS : $local_timestamp + DAY_IN_SECONDS;
1207 - break;
1208 - case 'hourly':
1209 - $next_time = $lasttime_run ? $lasttime_run + HOUR_IN_SECONDS : $local_timestamp + HOUR_IN_SECONDS;
1210 - break;
1211 - case '5minutely':
1212 - $next_time = $lasttime_run ? $lasttime_run + 5 * MINUTE_IN_SECONDS : $local_timestamp + 5 * MINUTE_IN_SECONDS;
1213 - break;
1214 - case 'minutely':
1215 - $next_time = $lasttime_run ? $lasttime_run + MINUTE_IN_SECONDS : $local_timestamp + MINUTE_IN_SECONDS;
1216 - break;
1217 - }
631 + #mainwp-system-report-page .mainwp-system-report-table {
632 + table-layout: fixed;
633 + width: 100%;
634 + }
1218 635
1219 - if ( $next_time < $local_timestamp ) { // to fix next time in past.
1220 - $next_time = $local_timestamp;
1221 - }
636 + #mainwp-system-report-page .mainwp-system-report-issues-message {
637 + margin: 0 0 1rem 0;
638 + border-radius: var(--area-radius, 0.28571429rem) !important;
639 + }
1222 640
1223 - return $next_time;
1224 - }
641 + #mainwp-system-report-page .mainwp-system-info-table {
642 + margin: 0 0 1rem 0 !important;
643 + }
1225 644
1226 - /**
1227 - * Checks if the ../wp-content/uploads/mainwp/ directory is writable.
1228 - *
1229 - * @return bool True if writable, false if not.
1230 - *
1231 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
1232 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
1233 - */
1234 - public static function check_directory_mainwp_directory() {
1235 - $dirs = MainWP_System_Utility::get_mainwp_dir();
1236 - $path = $dirs[0];
645 + #mainwp-system-report-page .dt-container,
646 + #mainwp-system-report-page .dataTables_wrapper {
647 + margin: 0 0 1rem 0;
648 + }
1237 649
1238 - $mess = 'Writable';
650 + #mainwp-system-report-page .dt-container .mainwp-system-info-table,
651 + #mainwp-system-report-page .dataTables_wrapper .mainwp-system-info-table {
652 + margin-bottom: 0 !important;
653 + }
654 + </style>
655 + <table id="mainwp-system-report-wordpress-table" class="ui unstackable table single line mainwp-system-report-table mainwp-system-info-table">
656 + <thead>
657 + <tr>
658 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'WordPress Check' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'WordPress Check', 'mainwp' ); ?></th>
659 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Required' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
660 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Detected' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
661 + <th scope="col" class="four wide right aligned"></th>
662 + </tr>
663 + </thead>
664 + <tbody>
665 + <?php static::render_wordpress_check_tbody(); ?>
666 + </tbody>
667 + </table>
1239 668
1240 - if ( ! is_dir( dirname( $path ) ) ) {
1241 - $mess = 'Not Found';
1242 - }
669 + <table id="mainwp-system-report-php-table" class="ui unstackable table fixed mainwp-system-report-table mainwp-system-info-table">
670 + <thead>
671 + <tr>
672 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'PHP' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP', 'mainwp' ); ?></th>
673 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Required' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
674 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Detected' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
675 + <th scope="col" class="four wide right aligned"></th>
676 + </tr>
677 + </thead>
678 + <tbody>
679 + <?php static::render_php_check_tbody(); ?>
680 + </tbody>
681 + </table>
1243 682
1244 - $is_writable = MainWP_System_Utility::is_writable( $path );
683 + <table id="mainwp-system-report-mysql-table" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
684 + <thead>
685 + <tr>
686 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'MySQL' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'MySQL', 'mainwp' ); ?></th>
687 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Required' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Required', 'mainwp' ); ?></th>
688 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Detected' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Detected', 'mainwp' ); ?></th>
689 + <th scope="col" class="four wide right aligned"></th>
690 + </tr>
691 + </thead>
692 + <tbody>
693 + <?php static::render_mysql_check_tbody(); ?>
694 + </tbody>
695 + </table>
1245 696
1246 - if ( $is_writable ) {
1247 - $mess = 'Not Writable';
1248 - }
697 + <?php self::render_report_section_table( 'mainwp-system-report-mainwp-database-table', __( 'Database', 'mainwp' ), $datatable_rows, 'Database' ); ?>
1249 698
1250 - $output = '<tr><td>MainWP Upload Directory</td><td>' . $mess . '</td></tr>';
1251 - return $output;
1252 - }
699 + <?php self::render_report_section_table( 'mainwp-system-report-connectivity-table', __( 'Connectivity & Authentication', 'mainwp' ), MainWP_Server_Information_Handler::get_connectivity_report_rows(), 'Connectivity & Authentication' ); ?>
1253 700
1254 - /**
1255 - * Renders the directory check row.
1256 - *
1257 - * @param string $name check name.
1258 - * @param string $check desired result.
1259 - * @param string $result detected result.
1260 - * @param bool $passed true|false check result.
1261 - *
1262 - * @return bool true.
1263 - */
1264 - public static function render_directory_row( $name, $check, $result, $passed ) {
1265 - // phpcs:disable WordPress.Security.EscapeOutput
1266 - ?>
1267 - <tr>
1268 - <td><?php echo esc_html( $name ); ?></td>
1269 - <td><?php echo esc_html( $check ); ?></td>
1270 - <td><?php echo esc_html( $result ); ?></td>
1271 - <td class="right aligned"><?php echo ( $passed ? self::get_pass_html() : self::get_warning_html( self::ERROR ) ); ?></td>
1272 - </tr>
1273 - <?php
1274 - // phpcs:enable
1275 - return true;
1276 - }
701 + <?php self::render_report_section_table( 'mainwp-system-report-scheduler-table', __( 'Scheduler & Background Jobs', 'mainwp' ), MainWP_Server_Information_Handler::get_scheduler_report_rows(), 'Scheduler & Background Jobs' ); ?>
1277 702
1278 - /**
1279 - * Renders server information table row.
1280 - *
1281 - * @param string $config configuraion check.
1282 - * @param string $compare comparison operator.
1283 - * @param mixed $version reqiored minium version number.
1284 - * @param mixed $getter detected version number.
1285 - * @param string $extraText additionl text.
1286 - * @param null $extraCompare extra compare.
1287 - * @param null $extraVersion extra version.
1288 - * @param null $whatType comparison type.
1289 - * @param int $errorType global variable self::WARNING = 1.
1290 - *
1291 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::filesize_compare()
1292 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::curlssl_compare()
1293 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1294 - */
1295 - public static function render_row( $config, $compare, $version, $getter, $extraText = '', $extraCompare = null, $extraVersion = null, $whatType = null, $errorType = self::WARNING ) {
1296 - $currentVersion = call_user_func( array( MainWP_Server_Information_Handler::get_class_name(), $getter ) );
1297 - // phpcs:disable WordPress.Security.EscapeOutput
1298 - ?>
1299 - <tr>
1300 - <td><?php echo esc_html( $config ); ?></td>
1301 - <td><?php echo esc_html( $compare ); ?><?php echo ( true === $version ? 'true' : ( is_array( $version ) && isset( $version['version'] ) ? esc_html( $version['version'] ) : esc_html( $version ) ) ) . ' ' . $extraText; ?></td>
1302 - <td><?php echo( true === $currentVersion ? 'true' : $currentVersion ); ?></td>
1303 - <?php if ( 'filesize' === $whatType ) { ?>
1304 - <td class="right aligned"><?php echo ( MainWP_Server_Information_Handler::filesize_compare( $currentVersion, $version, $compare ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1305 - <?php } elseif ( 'get_curl_ssl_version' === $getter ) { ?>
1306 - <td class="right aligned"><?php echo ( MainWP_Server_Information_Handler::curlssl_compare( $version, $compare ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1307 - <?php } elseif ( ( 'get_max_input_time' === $getter || 'get_max_execution_time' === $getter ) && -1 === (int) $currentVersion ) { ?>
1308 - <td class="right aligned"><?php echo self::get_pass_html(); ?></td>
1309 - <?php } else { ?>
1310 - <td class="right aligned"><?php echo ( version_compare( $currentVersion, $version, $compare ) || ( ! empty( $extraCompare ) && version_compare( $currentVersion, $extraVersion, $extraCompare ) ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1311 - <?php } ?>
1312 - </tr>
1313 - <?php
1314 - // phpcs:enable
1315 - }
703 + <table id="mainwp-system-report-server-table" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
704 + <thead>
705 + <tr>
706 + <th scope="col" class="seven wide"<?php echo self::get_export_text_attr( 'Server Configuration' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server Configuration', 'mainwp' ); ?></th>
707 + <th scope="col" class="nine wide"<?php echo self::get_export_text_attr( 'Detected Value' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
708 + </tr>
709 + </thead>
710 + <tbody>
711 + <?php static::render_server_check_tbody(); ?>
712 + </tbody>
713 + </table>
1316 714
1317 - /**
1318 - * Renders server information table row with description.
1319 - *
1320 - * @param string $config configuraion check.
1321 - * @param string $compare comparison operator.
1322 - * @param mixed $version reqiored minium version number.
1323 - * @param mixed $getter detected version number.
1324 - * @param string $extraText additionl text.
1325 - * @param null $extraCompare extra compare.
1326 - * @param null $extraVersion extra version.
1327 - * @param null $whatType comparison type.
1328 - * @param int $errorType global variable self::WARNING = 1.
1329 - *
1330 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1331 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::filesize_compare()
1332 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::curlssl_compare()
1333 - */
1334 - public static function render_row_with_description( $config, $compare, $version, $getter, $extraText = '', $extraCompare = null, $extraVersion = null, $whatType = null, $errorType = self::WARNING ) {
1335 - $currentVersion = call_user_func( array( MainWP_Server_Information_Handler::get_class_name(), $getter ) );
1336 - // phpcs:disable WordPress.Security.EscapeOutput
1337 - ?>
1338 - <tr>
1339 - <td><?php echo esc_html( $config ); ?></td>
1340 - <td><?php echo esc_html( $compare ); ?> <?php echo ( true === $version ? 'true' : ( is_array( $version ) && isset( $version['version'] ) ? esc_html( $version['version'] ) : esc_html( $version ) ) ) . ' ' . $extraText; ?></td>
1341 - <td><?php echo ( true === $currentVersion ? 'true' : $currentVersion ); ?></td>
1342 - <?php if ( 'filesize' === $whatType ) { ?>
1343 - <td class="right aligned"><?php echo ( MainWP_Server_Information_Handler::filesize_compare( $currentVersion, $version, $compare ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1344 - <?php } elseif ( 'get_curl_ssl_version' === $getter ) { ?>
1345 - <td class="right aligned"><?php echo ( MainWP_Server_Information_Handler::curlssl_compare( $version, $compare ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1346 - <?php } elseif ( 'get_max_input_time' === $getter && -1 === (int) $currentVersion ) { ?>
1347 - <td class="right aligned"><?php echo self::get_pass_html(); ?></td>
1348 - <?php } else { ?>
1349 - <td class="right aligned"><?php echo( version_compare( $currentVersion, $version, $compare ) || ( ! empty( $extraCompare ) && version_compare( $currentVersion, $extraVersion, $extraCompare ) ) ? self::get_pass_html() : self::get_warning_html( $errorType ) ); ?></td>
1350 - <?php } ?>
1351 - </tr>
1352 - <?php
1353 - // phpcs:enable
1354 - }
715 + <?php self::render_report_section_table( 'mainwp-system-report-overview-table', __( 'MainWP Overview', 'mainwp' ), MainWP_Server_Information_Handler::get_mainwp_overview_report_rows(), 'MainWP Overview' ); ?>
1355 716
1356 - /**
1357 - * Checks if file system method is direct.
1358 - *
1359 - * @return mixed html|self::get_warning_html().
1360 - *
1361 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_file_system_method()
1362 - */
1363 - public static function get_file_system_method_check() {
1364 - $fsmethod = MainWP_Server_Information_Handler::get_file_system_method();
1365 - if ( 'direct' === $fsmethod ) {
1366 - return self::get_pass_html();
1367 - } else {
1368 - return self::get_warning_html();
1369 - }
1370 - }
717 + <?php self::render_report_section_table( 'mainwp-system-report-general-settings-table', __( 'MainWP General Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_general_settings_report_rows(), 'MainWP General Settings' ); ?>
1371 718
1372 - /**
1373 - * Renders Error Log page.
1374 - *
1375 - * Plugin-Name: Error Log Dashboard Widget
1376 - * Plugin URI: http://wordpress.org/extend/plugins/error-log-dashboard-widget/
1377 - * Description: Robust zero-configuration and low-memory way to keep an eye on error log.
1378 - * Author: Andrey "Rarst" Savchenko
1379 - * Author URI: http://www.rarst.net/
1380 - * Version: 1.0.2
1381 - * License: GPLv2 or later
719 + <?php self::render_report_section_table( 'mainwp-system-report-advanced-settings-table', __( 'MainWP Advanced Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_advanced_settings_report_rows(), 'MainWP Advanced Settings' ); ?>
1382 720
1383 - * Includes last_lines() function by phant0m, licensed under cc-wiki and GPLv2+
1384 - */
1385 - public static function render_error_log_page() {
1386 - if ( ! mainwp_current_user_have_right( 'dashboard', 'see_server_information' ) ) {
1387 - mainwp_do_not_have_permissions( 'error log', 'mainwp' );
1388 - return;
1389 - }
1390 - self::render_header( 'ErrorLog' );
721 + <?php self::render_report_section_table( 'mainwp-system-report-monitoring-settings-table', __( 'MainWP Monitoring Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_monitoring_settings_report_rows(), 'MainWP Monitoring Settings' ); ?>
1391 722
1392 - /**
1393 - * Action: mainwp_before_error_log_table
1394 - *
1395 - * Fires before the Error Log table.
1396 - *
1397 - * @since 4.1
1398 - */
1399 - do_action( 'mainwp_before_error_log_table' );
1400 - ?>
1401 - <div class="ui segment">
1402 - <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-error-log-info-message' ) ) : ?>
1403 - <div class="ui info message">
1404 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-error-log-info-message"></i>
1405 - <?php echo esc_html__( 'See the WordPress error log to fix problems that arise on your MainWP Dashboard site.', 'mainwp' ); ?>
1406 - </div>
1407 - <?php endif; ?>
1408 - <table class="ui unstackable table" id="mainwp-error-log-table">
1409 - <thead>
1410 - <tr>
1411 - <th><?php esc_html_e( 'Time', 'mainwp' ); ?></th>
1412 - <th><?php esc_html_e( 'Error', 'mainwp' ); ?></th>
1413 - </tr>
1414 - </thead>
1415 - <tbody>
1416 - <?php self::render_error_log(); ?>
1417 - </tbody>
1418 - </table>
1419 - <script type="text/javascript">
1420 - var responsive = true;
1421 - if( jQuery( window ).width() > 1140 ) {
1422 - responsive = false;
1423 - }
1424 - jQuery( document ).ready( function() {
1425 - jQuery( '#mainwp-error-log-table' ).DataTable( {
1426 - "responsive": responsive,
1427 - "ordering": false,
1428 - "stateSave": true,
1429 - "stateDuration": 0,
1430 - "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
1431 - } );
1432 - } );
1433 - </script>
1434 - </div>
1435 - <?php
1436 - /**
1437 - * Action: mainwp_after_error_log_table
1438 - *
1439 - * Fires after the Error Log table.
1440 - *
1441 - * @since 4.1
1442 - */
1443 - do_action( 'mainwp_after_error_log_table' );
723 + <?php self::render_report_section_table( 'mainwp-system-report-email-settings-table', __( 'MainWP Email Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_email_settings_report_rows(), 'MainWP Email Settings' ); ?>
1444 724
1445 - self::render_footer( 'ErrorLog' );
1446 - }
725 + <?php self::render_report_section_table( 'mainwp-system-report-cost-tracker-settings-table', __( 'MainWP Cost Tracker Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_cost_tracker_report_rows(), 'MainWP Cost Tracker Settings' ); ?>
1447 726
1448 - /**
1449 - * Renders error log page.
1450 - *
1451 - * @return void
1452 - *
1453 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::last_lines()
1454 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1455 - */
1456 - public static function render_error_log() {
1457 - $tbody = '';
1458 - $log_errors = ini_get( 'log_errors' );
1459 - if ( ! $log_errors ) {
1460 - echo '<tr><td colspan="2">' . esc_html__( 'Error logging disabled.', 'mainwp' );
1461 - echo '<br/>' . sprintf( esc_html__( 'To enable error logging, please check this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">', '</a>' );
1462 - echo '</td></tr>';
1463 - }
727 + <?php self::render_report_section_table( 'mainwp-system-report-network-activity-settings-table', __( 'MainWP Network Activity Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_insights_report_rows(), 'MainWP Network Activity Settings' ); ?>
1464 728
1465 - $error_log = ini_get( 'error_log' );
1466 - /**
1467 - * Filter: error_log_mainwp_logs
1468 - *
1469 - * Filters the error log files to show.
1470 - *
1471 - * @since Unknown
1472 - */
1473 - $logs = apply_filters( 'error_log_mainwp_logs', array( $error_log ) );
729 + <?php self::render_report_section_table( 'mainwp-system-report-api-backups-settings-table', __( 'MainWP API Backups Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_api_backups_report_rows(), 'MainWP API Backups Settings' ); ?>
1474 730
1475 - /**
1476 - * Filter: error_log_mainwp_lines
1477 - *
1478 - * Limits the number of error log records to be displayed. Default value, 50.
1479 - *
1480 - * @since Unknown
1481 - */
1482 - $count = apply_filters( 'error_log_mainwp_lines', 100 );
1483 - $lines = array();
731 + <?php self::render_report_section_table( 'mainwp-system-report-tools-settings-table', __( 'MainWP Tools Settings', 'mainwp' ), MainWP_Server_Information_Handler::get_tools_report_rows(), 'MainWP Tools Settings' ); ?>
1484 732
1485 - foreach ( $logs as $log ) {
1486 - if ( is_readable( $log ) ) {
1487 - $lines = array_merge( $lines, MainWP_Server_Information_Handler::last_lines( $log, $count ) );
1488 - }
1489 - }
733 + <?php self::render_report_section_table( 'mainwp-system-report-debug-settings-table', __( 'Debug & Logs', 'mainwp' ), MainWP_Server_Information_Handler::get_debug_report_rows(), 'Debug & Logs' ); ?>
1490 734
1491 - $lines = array_map( 'trim', $lines );
1492 - $lines = array_filter( $lines );
735 + <?php self::render_report_section_table( 'mainwp-system-report-conflict-signals-table', __( 'Potential Conflicts', 'mainwp' ), MainWP_Server_Information_Handler::get_conflict_signal_report_rows(), 'Potential Conflicts' ); ?>
1493 736
1494 - if ( empty( $lines ) ) {
737 + <table id="mainwp-system-report-extensions-table" class="ui unstackable table single line mainwp-system-report-table mainwp-system-info-table">
738 + <thead>
739 + <tr>
740 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Extensions' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Extensions', 'mainwp' ); ?></th>
741 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Version' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Version', 'mainwp' ); ?></th>
742 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'License' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'License', 'mainwp' ); ?></th>
743 + <th scope="col" class="four wide right aligned"></th>
744 + </tr>
745 + </thead>
746 + <tbody>
747 + <?php static::render_extensions_license_check_tbody(); ?>
748 + </tbody>
749 + </table>
1495 750
1496 - echo '<tr><td colspan="2">' . esc_html__( 'MainWP is unable to find your error logs, please contact your host for server error logs.', 'mainwp' ) . '</td></tr>';
751 + <table id="mainwp-system-report-plugins-table" class="ui single line table unstackable mainwp-system-report-table mainwp-system-info-table">
752 + <thead>
753 + <tr>
754 + <th scope="col" class="eight wide"<?php echo self::get_export_text_attr( 'Plugin' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
755 + <th scope="col" class="four wide"<?php echo self::get_export_text_attr( 'Version' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Version', 'mainwp' ); ?></th>
756 + <th scope="col" class="four wide right aligned"></th>
757 + </tr>
758 + </thead>
759 + <tbody>
760 + <?php static::render_plugins_check_tbody(); ?>
761 + </tbody>
762 + </table>
1497 763
1498 - return;
1499 - }
764 + <div id="download-server-information" style="opacity:0">
765 + <textarea readonly="readonly" contenteditable="true" wrap="off"></textarea>
766 + </div>
1500 767
1501 - foreach ( $lines as $key => $line ) {
1502 - if ( false !== strpos( $line, ']' ) ) {
1503 - list( $time, $error ) = explode( ']', $line, 2 );
1504 - } else {
1505 - list( $time, $error ) = array( '', $line );
1506 - }
1507 - $time = trim( $time, '[]' );
1508 - $error = trim( $error );
1509 - $lines[ $key ] = compact( 'time', 'error' );
1510 - }
768 + <script type="text/javascript">
769 + let responsive = true;
770 + if( jQuery( window ).width() > 1140 ) {
771 + responsive = false;
772 + }
773 + jQuery( document ).ready( function() {
774 + const mainwpSystemReportTables = [];
775 + jQuery( '.mainwp-system-info-table:not(#mainwp-system-report-extensions-table)' ).each( function() {
776 + mainwpSystemReportTables.push( jQuery( this ).DataTable( {
777 + responsive: responsive,
778 + colReorder: true,
779 + paging: false,
780 + info: false,
781 + autoWidth: false,
782 + dom: 't',
783 + } ) );
784 + } );
785 + mainwpSystemReportTables.push( jQuery( '#mainwp-system-report-extensions-table' ).DataTable( {
786 + responsive: responsive,
787 + colReorder: true,
788 + paging: false,
789 + info: false,
790 + autoWidth: false,
791 + dom: 't',
792 + "language": {
793 + "emptyTable": "<?php esc_html_e( 'No installed extensions', 'mainwp' ); ?>"
794 + },
795 + } ) );
1511 796
1512 - if ( 1 < count( $lines ) ) {
1513 - // phpcs:ignore -- ok.
1514 - //uasort( $lines, array( MainWP_Server_Information_Handler::get_class_name(), 'time_compare' ) );
1515 - $lines = array_slice( $lines, 0, $count );
1516 - }
797 + jQuery( '#mainwp-system-report-global-search' ).on( 'input', function() {
798 + const searchValue = jQuery( this ).val();
799 + mainwpSystemReportTables.forEach( function( table ) {
800 + table.search( searchValue ).draw();
801 + } );
802 + } );
803 + } );
804 + </script>
805 + </div>
1517 806
1518 - // phpcs:disable WordPress.Security.EscapeOutput
1519 - foreach ( $lines as $line ) {
1520 - $error = esc_html( $line['error'] );
1521 - $time = esc_html( $line['time'] );
1522 - if ( ! empty( $error ) ) {
1523 - echo '<tr><td>' . $time . '</td><td>' . $error . '</td></tr>';
1524 - }
1525 - }
1526 - // phpcs:enable
1527 - }
807 + <?php
1528 808
1529 - /**
1530 - * Renders the WP Config page.
1531 - *
1532 - * @return void
1533 - */
1534 - public static function render_wp_config() {
1535 - if ( ! mainwp_current_user_have_right( 'dashboard', 'see_server_information' ) ) {
1536 - mainwp_do_not_have_permissions( 'WP-Config.php', 'mainwp' );
1537 - return;
1538 - }
809 + /**
810 + * Action: mainwp_after_server_info_table
811 + *
812 + * Fires on the bottom of the Info page, after the Server Info table.
813 + *
814 + * @since 4.0
815 + */
816 + do_action( 'mainwp_after_server_info_table' );
1539 817
1540 - self::render_header( 'WPConfig' );
1541 - /**
1542 - * Action: mainwp_before_wp_config_section
1543 - *
1544 - * Fires before the WP Config section.
1545 - *
1546 - * @since 4.1
1547 - */
1548 - do_action( 'mainwp_before_wp_config_section' );
1549 - ?>
1550 - <div id="mainwp-show-wp-config">
1551 - <?php
1552 - if ( false !== strpos( ini_get( 'disable_functions' ), 'show_source' ) ) {
1553 - esc_html_e( 'File content could not be displayed.', 'mainwp' );
1554 - echo '<br />';
1555 - esc_html_e( 'It appears that the show_source() PHP function has been disabled on the servre.', 'mainwp' );
1556 - echo '<br />';
1557 - esc_html_e( 'Please, contact your host support and have them enable the show_source() function for the proper functioning of this feature.', 'mainwp' );
1558 - } elseif ( file_exists( ABSPATH . 'wp-config.php' ) ) {
1559 - show_source( ABSPATH . 'wp-config.php' );
1560 - } else {
1561 - $files = get_included_files();
1562 - $configFound = false;
1563 - if ( is_array( $files ) ) {
1564 - foreach ( $files as $file ) {
1565 - if ( stristr( $file, 'wp-config.php' ) ) {
1566 - $configFound = true;
1567 - show_source( $file );
1568 - break;
1569 - }
1570 - }
1571 - }
1572 - if ( ! $configFound ) {
1573 - esc_html_e( 'wp-config.php not found', 'mainwp' );
1574 - }
1575 - }
1576 - ?>
1577 - </div>
1578 - <?php
1579 - /**
1580 - * Action: mainwp_after_wp_config_section
1581 - *
1582 - * Fires after the WP Config section.
1583 - *
1584 - * @since 4.1
1585 - */
1586 - do_action( 'mainwp_after_wp_config_section' );
818 + static::render_footer( '' );
819 + }
1587 820
1588 - self::render_footer( 'WPConfig' );
1589 - }
821 + /**
822 + * Renders WordPress checks table body.
823 + *
824 + * @return void
825 + */
826 + public static function render_wordpress_check_tbody() {
827 + static::render_row( 'WordPress Version', '>=', '6.2', 'get_wordpress_version', '', '', null, null, static::ERROR );
828 + static::render_row( 'WordPress Memory Limit', '>=', '64M', 'get_wordpress_memory_limit', '', '', null );
829 + static::render_row( 'MultiSite Disabled', '=', true, 'check_if_multisite', '', '', null );
830 + ?>
831 + <tr>
832 + <td<?php echo self::get_export_text_attr( 'FileSystem Method' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'FileSystem Method', 'mainwp' ); ?></td>
833 + <td><?php echo esc_html( '= direct' ); ?></td>
834 + <td><?php echo MainWP_Server_Information_Handler::get_file_system_method(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
835 + <td class="right aligned"><?php echo static::get_file_system_method_check(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
836 + </tr>
837 + <?php
838 + }
1590 839
1591 - /**
1592 - * Renders action logs page.
1593 - *
1594 - * @uses \MainWP\Dashboard\MainWP_Logger
1595 - * @uses \MainWP\Dashboard\MainWP_Logger::clear_log()
1596 - * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1597 - */
1598 - public static function render_action_logs() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1599 - self::render_header( 'ActionLogs' );
840 + /**
841 + * Renders PHP checks table body.
842 + *
843 + * @return void
844 + */
845 + public static function render_php_check_tbody() {
846 + static::render_row( 'PHP Version', '>=', '7.4', 'get_php_version', '', '', null, null, static::ERROR );
847 + static::render_row( 'PHP Max Execution Time', '>=', '30', 'get_max_execution_time', 'seconds', '=', '0' );
848 + static::render_row( 'PHP Max Input Time', '>=', '30', 'get_max_input_time', 'seconds', '=', '0' );
849 + static::render_row( 'PHP Memory Limit', '>=', '256M', 'get_php_memory_limit', '', '', null, 'filesize' );
850 + static::render_row( 'PCRE Backtracking Limit', '>=', '10000', 'get_output_buffer_size', '', '', null );
851 + static::render_row( 'PHP Upload Max Filesize', '>=', '2M', 'get_upload_max_filesize', '', '', null, 'filesize' );
852 + static::render_row( 'PHP Post Max Size', '>=', '2M', 'get_post_max_size', '', '', null, 'filesize' );
853 + static::render_row( 'SSL Extension Enabled', '=', true, 'get_ssl_support', '', '', null );
854 + static::render_row( 'SSL Warnings', '=', '', 'get_ssl_warning', 'empty', '', null );
855 + static::render_row( 'cURL Extension Enabled', '=', true, 'get_curl_support', '', '', null, null, static::ERROR );
856 + static::render_row( 'cURL Timeout', '>=', '300', 'get_curl_timeout', 'seconds', '=', '0' );
857 + if ( function_exists( 'curl_version' ) ) {
858 + $reuire_curl = '7.18.1';
859 + if ( version_compare( MainWP_Server_Information_Handler::get_php_version(), '8.0.0' ) >= 0 ) {
860 + $reuire_curl = '7.29.0';
861 + }
862 + static::render_row( 'cURL Version', '>=', $reuire_curl, 'get_curl_version', '', '', null );
863 + $openssl_version = 'OpenSSL/1.1.0';
864 + static::render_row(
865 + 'OpenSSL Version',
866 + '>=',
867 + $openssl_version,
868 + 'get_curl_ssl_version',
869 + '',
870 + '',
871 + null,
872 + 'curlssl'
873 + );
1600 874
1601 - if ( isset( $_REQUEST['actionlogs_status'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1602 - $act_log = isset( $_REQUEST['actionlogs_status'] ) ? wp_unslash( $_REQUEST['actionlogs_status'] ) : MainWP_Logger::DISABLED; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1603 - $spec_log = 0;
1604 - if ( is_string( $act_log ) && false !== strpos( $act_log, 'specific_' ) ) {
1605 - $act_log = str_replace( 'specific_', '', $act_log );
1606 - $spec_log = 1;
1607 - }
875 + $wk = MainWP_Server_Information_Handler::get_openssl_working_status();
876 + ?>
877 + <tr>
878 + <td>OpenSSL Working Status</td>
879 + <td>Yes</td>
880 + <td><?php echo $wk ? 'Yes' : 'No'; ?></td>
881 + <td class="right aligned"><?php $wk ? static::get_pass_html( true ) : static::get_warning_html( self::WARNING, true ); ?></td>
882 + </tr>
883 + <?php
1608 884
1609 - $act_log = intval( $act_log );
885 + }
886 + ?>
887 + <tr>
888 + <td<?php echo self::get_export_text_attr( 'PHP Allow URL fopen' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP Allow URL fopen', 'mainwp' ); ?></td>
889 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
890 + <td><?php MainWP_Server_Information_Handler::get_php_allow_url_fopen(); ?></td>
891 + <td></td>
892 + </tr>
893 + <tr>
894 + <td<?php echo self::get_export_text_attr( 'PHP Exif Support' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP Exif Support', 'mainwp' ); ?></td>
895 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
896 + <td><?php MainWP_Server_Information_Handler::get_php_exif(); ?></td>
897 + <td></td>
898 + </tr>
899 + <tr>
900 + <td<?php echo self::get_export_text_attr( 'PHP IPTC Support' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP IPTC Support', 'mainwp' ); ?></td>
901 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
902 + <td><?php MainWP_Server_Information_Handler::get_php_iptc(); ?></td>
903 + <td></td>
904 + </tr>
905 + <tr>
906 + <td<?php echo self::get_export_text_attr( 'PHP XML Support' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP XML Support', 'mainwp' ); ?></td>
907 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
908 + <td><?php MainWP_Server_Information_Handler::get_php_xml(); ?></td>
909 + <td></td>
910 + </tr>
911 + <tr>
912 + <td<?php echo self::get_export_text_attr( 'Function `tmpfile` enabled' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Function `tmpfile` enabled', 'mainwp' ); ?></td>
913 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
914 + <td>
915 + <?php
916 + $tmpfile_enabled = MainWP_System_View::is_tmpfile_enable();
917 + echo $tmpfile_enabled ? esc_html__( 'Enabled', 'mainwp' ) : esc_html__( 'Disabled', 'mainwp' );
918 + ?>
919 + </td>
920 + <td class="right aligned"><?php $tmpfile_enabled ? static::get_pass_html( true ) : static::get_warning_html( self::WARNING, true ); ?></td>
921 + </tr>
922 + <tr>
923 + <td<?php echo self::get_export_text_attr( 'PHP Session enabled' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP Session enabled', 'mainwp' ); ?></td>
924 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
925 + <td>
926 + <?php
927 + $session_disable = MainWP_Cache::is_session_disable();
928 + echo $session_disable ? esc_html__( 'Disabled', 'mainwp' ) : esc_html__( 'Enabled', 'mainwp' );
929 + ?>
930 + </td>
931 + <td class="right aligned"><?php echo ! $session_disable ? static::get_pass_html() : static::get_warning_html(); //phpcs:ignore -- ok. ?></td>
932 + </tr>
933 + <tr>
934 + <td<?php echo self::get_export_text_attr( 'PHP Disabled Functions' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP Disabled Functions', 'mainwp' ); ?></td>
935 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
936 + <td><?php static::php_disabled_functions(); ?></td>
937 + <td></td>
938 + </tr>
939 + <tr>
940 + <td<?php echo self::get_export_text_attr( 'PHP Loaded Extensions' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'PHP Loaded Extensions', 'mainwp' ); ?></td>
941 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
942 + <td><?php MainWP_Server_Information_Handler::get_loaded_php_extensions(); ?></td>
943 + <td></td>
944 + </tr>
945 + <?php
946 + }
1610 947
1611 - MainWP_Utility::update_option( 'mainwp_specific_logs', $spec_log );
948 + /**
949 + * Renders MySQL checks table body.
950 + *
951 + * @return void
952 + */
953 + public static function render_mysql_check_tbody() {
954 + static::render_row( 'MySQL Version', '>=', '5.0', 'get_mysql_version', '', '', null, null, static::ERROR );
955 + ?>
956 + <tr>
957 + <td<?php echo self::get_export_text_attr( 'MySQL Mode' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'MySQL Mode', 'mainwp' ); ?></td>
958 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
959 + <td><?php MainWP_Server_Information_Handler::get_sql_mode(); ?></td>
960 + <td></td>
961 + </tr>
962 + <tr>
963 + <td<?php echo self::get_export_text_attr( 'MySQL Client Encoding' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'MySQL Client Encoding', 'mainwp' ); ?></td>
964 + <td><?php esc_html_e( 'N/A', 'mainwp' ); ?></td>
965 + <td><?php echo defined( 'DB_CHARSET' ) ? esc_html( DB_CHARSET ) : ''; ?></td>
966 + <td></td>
967 + </tr>
968 + <?php
969 + }
1612 970
1613 - MainWP_Logger::instance()->log_action( 'Action logs set to: ' . MainWP_Logger::instance()->get_log_text( $act_log ), ( $spec_log ? $act_log : MainWP_Logger::LOG ), 2, true );
971 + /**
972 + * Renders Server checks table body.
973 + *
974 + * @return void
975 + */
976 + public static function render_server_check_tbody() {
977 + ?>
978 + <tr class="mwp-not-generate-row">
979 + <td<?php echo self::get_export_text_attr( 'WordPress Root Directory' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'WordPress Root Directory', 'mainwp' ); ?></td>
980 + <td><?php MainWP_Server_Information_Handler::get_wp_root(); ?></td>
981 + </tr>
982 + <tr class="mwp-not-generate-row">
983 + <td<?php echo self::get_export_text_attr( 'Server Name' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server Name', 'mainwp' ); ?></td>
984 + <td><?php MainWP_Server_Information_Handler::get_server_name(); ?></td>
985 + </tr>
986 + <tr>
987 + <td<?php echo self::get_export_text_attr( 'Server Software' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server Software', 'mainwp' ); ?></td>
988 + <td><?php MainWP_Server_Information_Handler::get_server_software(); ?></td>
989 + </tr>
990 + <tr>
991 + <td<?php echo self::get_export_text_attr( 'Operating System' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Operating System', 'mainwp' ); ?></td>
992 + <td><?php MainWP_Server_Information_Handler::get_os(); ?></td>
993 + </tr>
994 + <tr>
995 + <td<?php echo self::get_export_text_attr( 'Architecture' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Architecture', 'mainwp' ); ?></td>
996 + <td><?php MainWP_Server_Information_Handler::get_architecture(); ?></td>
997 + </tr>
998 + <tr class="mwp-not-generate-row">
999 + <td<?php echo self::get_export_text_attr( 'Server IP' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server IP', 'mainwp' ); ?></td>
1000 + <td><?php MainWP_Server_Information_Handler::get_server_ip(); ?></td>
1001 + </tr>
1002 + <tr>
1003 + <td<?php echo self::get_export_text_attr( 'Server Protocol' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server Protocol', 'mainwp' ); ?></td>
1004 + <td><?php MainWP_Server_Information_Handler::get_server_protocol(); ?></td>
1005 + </tr>
1006 + <tr class="mwp-not-generate-row">
1007 + <td<?php echo self::get_export_text_attr( 'HTTP Host' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'HTTP Host', 'mainwp' ); ?></td>
1008 + <td><?php MainWP_Server_Information_Handler::get_http_host(); ?></td>
1009 + </tr>
1010 + <tr>
1011 + <td<?php echo self::get_export_text_attr( 'User Agent' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'User Agent', 'mainwp' ); ?></td>
1012 + <td><?php MainWP_Server_Information_Handler::get_user_agent(); ?></td>
1013 + </tr>
1014 + <tr class="mwp-not-generate-row">
1015 + <td<?php echo self::get_export_text_attr( 'Server Port' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Server Port', 'mainwp' ); ?></td>
1016 + <td><?php MainWP_Server_Information_Handler::get_server_port(); ?></td>
1017 + </tr>
1018 + <tr>
1019 + <td<?php echo self::get_export_text_attr( 'Gateway Interface' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Gateway Interface', 'mainwp' ); ?></td>
1020 + <td><?php MainWP_Server_Information_Handler::get_server_gateway_interface(); ?></td>
1021 + </tr>
1022 + <tr>
1023 + <td<?php echo self::get_export_text_attr( 'Memory Usage' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Memory Usage', 'mainwp' ); ?></td>
1024 + <td><?php MainWP_Server_Information_Handler::memory_usage(); ?></td>
1025 + </tr>
1026 + <tr class="mwp-not-generate-row">
1027 + <td<?php echo self::get_export_text_attr( 'Referrer URL' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Referrer URL', 'mainwp' ); ?></td>
1028 + <td><?php MainWP_Server_Information_Handler::get_complete_url(); ?></td>
1029 + </tr>
1030 + <tr>
1031 + <td<?php echo self::get_export_text_attr( 'Request Time' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Request Time', 'mainwp' ); ?></td>
1032 + <td><?php MainWP_Server_Information_Handler::get_server_request_time(); ?></td>
1033 + </tr>
1034 + <tr>
1035 + <td<?php echo self::get_export_text_attr( 'Accept Content' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Accept Content', 'mainwp' ); ?></td>
1036 + <td><?php MainWP_Server_Information_Handler::get_server_http_accept(); ?></td>
1037 + </tr>
1038 + <tr>
1039 + <td<?php echo self::get_export_text_attr( 'Accept-Charset Content' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Accept-Charset Content', 'mainwp' ); ?></td>
1040 + <td><?php MainWP_Server_Information_Handler::get_server_accept_charset(); ?></td>
1041 + </tr>
1042 + <tr class="mwp-not-generate-row">
1043 + <td<?php echo self::get_export_text_attr( 'Currently Executing Script Pathname' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Currently Executing Script Pathname', 'mainwp' ); ?></td>
1044 + <td><?php MainWP_Server_Information_Handler::get_script_file_name(); ?></td>
1045 + </tr>
1046 + <tr class="mwp-not-generate-row">
1047 + <td<?php echo self::get_export_text_attr( 'Current Page URI' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Current Page URI', 'mainwp' ); ?></td>
1048 + <td><?php MainWP_Server_Information_Handler::get_current_page_uri(); ?></td>
1049 + </tr>
1050 + <tr class="mwp-not-generate-row">
1051 + <td<?php echo self::get_export_text_attr( 'Remote Address' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Remote Address', 'mainwp' ); ?></td>
1052 + <td><?php MainWP_Server_Information_Handler::get_remote_address(); ?></td>
1053 + </tr>
1054 + <tr class="mwp-not-generate-row">
1055 + <td<?php echo self::get_export_text_attr( 'Remote Host' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Remote Host', 'mainwp' ); ?></td>
1056 + <td><?php MainWP_Server_Information_Handler::get_remote_host(); ?></td>
1057 + </tr>
1058 + <tr class="mwp-not-generate-row">
1059 + <td<?php echo self::get_export_text_attr( 'Remote Port' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Remote Port', 'mainwp' ); ?></td>
1060 + <td><?php MainWP_Server_Information_Handler::get_remote_port(); ?></td>
1061 + </tr>
1062 + <?php
1063 + }
1614 1064
1615 - if ( MainWP_Logger::DISABLED === $act_log ) {
1616 - MainWP_Logger::instance()->set_log_priority( $act_log, $spec_log );
1617 - }
1065 + /**
1066 + * Renders MainWP Dashboard checks table body.
1067 + *
1068 + * @return void
1069 + */
1070 + public static function render_dashboard_check_tbody() {
1071 + ?>
1072 + <tr>
1073 + <td><?php esc_html_e( 'MainWP Dashboard Version', 'mainwp' ); ?></td>
1074 + <td><?php echo 'Latest: ' . MainWP_Server_Information_Handler::get_mainwp_version(); ?> | <?php echo 'Detected: ' . MainWP_Server_Information_Handler::get_current_version(); ?> <?php echo static::get_mainwp_version_check(); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
1075 + </tr>
1076 + <?php
1077 + static::check_directory_mainwp_directory();
1078 + static::display_mainwp_options();
1079 + }
1618 1080
1619 - MainWP_Utility::update_option( 'mainwp_actionlogs', $act_log );
1620 - MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
1621 - }
1081 + /**
1082 + * Renders extensions API License status table body.
1083 + *
1084 + * @return void
1085 + */
1086 + public static function render_extensions_license_check_tbody() {
1087 + $extensions = MainWP_Extensions_Handler::get_extensions();
1088 + $extensions_slugs = array();
1089 + if ( empty( $extensions ) ) {
1090 + return;
1091 + }
1092 + foreach ( $extensions as $extension ) {
1093 + $extensions_slugs[] = $extension['slug'];
1094 + ?>
1095 + <tr>
1096 + <td><?php echo esc_html( $extension['name'] ); ?></td>
1097 + <td><?php echo esc_html( $extension['version'] ); ?></td>
1098 + <?php
1099 + if ( isset( $extension['mainwp'] ) && $extension['mainwp'] ) {
1100 + ?>
1101 + <td><?php echo isset( $extension['activated_key'] ) && 'Activated' === $extension['activated_key'] ? esc_html__( 'Active', 'mainwp' ) : esc_html__( 'Inactive', 'mainwp' ); ?></td>
1102 + <td class="right aligned"><?php echo isset( $extension['activated_key'] ) && 'Activated' === $extension['activated_key'] ? static::get_pass_html() : static::get_warning_html( static::WARNING ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
1103 + <?php
1104 + } else {
1105 + ?>
1106 + <td></td>
1107 + <td></td>
1108 + <?php
1109 + }
1110 + ?>
1111 + </tr>
1112 + <?php
1113 + }
1114 + }
1622 1115
1623 - if ( isset( $_REQUEST['actionlogs_clear'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1624 - $log_to_db = apply_filters( 'mainwp_logger_to_db', true );
1625 - if ( $log_to_db ) {
1626 - MainWP_Logger::instance()->clear_log_db();
1627 - } else {
1628 - MainWP_Logger::instance()->clear_log();
1629 - }
1630 - }
1116 + /**
1117 + * Renders plugins check table body.
1118 + *
1119 + * @return void
1120 + */
1121 + public static function render_plugins_check_tbody() {
1122 + $all_extensions = MainWP_Extensions_View::get_available_extensions();
1123 + $all_plugins = get_plugins();
1124 + foreach ( $all_plugins as $slug => $plugin ) {
1125 + if ( isset( $all_extensions[ dirname( $slug ) ] ) ) {
1126 + continue;
1127 + }
1128 + ?>
1129 + <tr>
1130 + <td><?php echo esc_html( $plugin['Name'] ); ?></td>
1131 + <td><?php echo esc_html( $plugin['Version'] ); ?></td>
1132 + <td class="right aligned"><?php echo is_plugin_active( $slug ) ? esc_html__( 'Active', 'mainwp' ) : esc_html__( 'Inactive', 'mainwp' ); ?></td>
1133 + </tr>
1134 + <?php
1135 + }
1136 + }
1631 1137
1632 - $enabled = (int) MainWP_Logger::instance()->get_log_status();
1633 - $specific_default = array(
1634 - MainWP_Logger::UPDATE_CHECK_LOG_PRIORITY => esc_html__( 'Update Checking', 'mainwp' ),
1635 - MainWP_Logger::EXECUTION_TIME_LOG_PRIORITY => esc_html__( 'Execution time', 'mainwp' ),
1636 - MainWP_Logger::LOGS_AUTO_PURGE_LOG_PRIORITY => esc_html__( 'Logs Auto Purge', 'mainwp' ),
1637 - );
1638 - $specific_logs = apply_filters( 'mainwp_specific_action_logs', $specific_default ); // deprecated since 4.3.1, use 'mainwp_log_specific_actions' instead.
1639 - $specific_logs = apply_filters( 'mainwp_log_specific_actions', $specific_logs );
1138 + /**
1139 + * Renders MainWP system requirements check.
1140 + *
1141 + * @return void
1142 + */
1143 + public static function render_quick_setup_system_check() {
1144 + /**
1145 + * Action: mainwp_before_system_requirements_check
1146 + *
1147 + * Fires on the bottom of the System Requirements page, in Quick Setup Wizard.
1148 + *
1149 + * @since 4.1
1150 + */
1151 + do_action( 'mainwp_before_system_requirements_check' );
1152 + ?>
1153 + <table id="mainwp-quick-system-requirements-check" class="ui single line table">
1154 + <thead>
1155 + <tr>
1156 + <th scope="col" ><?php esc_html_e( 'Check', 'mainwp' ); ?></th>
1157 + <th scope="col" ><?php esc_html_e( 'Required Value', 'mainwp' ); ?></th>
1158 + <th scope="col" ><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
1159 + <th scope="col" class="collapsing"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
1160 + </tr>
1161 + </thead>
1162 + <tbody>
1163 + <?php
1164 + static::render_row_with_description( esc_html__( 'PHP Version', 'mainwp' ), '>=', '7.4', 'get_php_version', '', '', null );
1165 + static::render_row_with_description( esc_html__( 'SSL Extension Enabled', 'mainwp' ), '=', true, 'get_ssl_support', '', '', null );
1166 + static::render_row_with_description( esc_html__( 'cURL Extension Enabled', 'mainwp' ), '=', true, 'get_curl_support', '', '', null );
1640 1167
1641 - ?>
1642 - <div class="mainwp-sub-header">
1643 - <div class="ui mini form two column stackable grid">
1644 - <div class="column">
1645 - <form method="POST" action="">
1646 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
1647 - <?php // phpcs:disable WordPress.Security.EscapeOutput ?>
1648 - <select name="actionlogs_status" class="ui mini dropdown">
1649 - <option value="<?php echo MainWP_Logger::DISABLED; ?>" <?php echo ( MainWP_Logger::DISABLED === $enabled ? 'selected' : '' ); ?>>
1650 - <?php esc_html_e( 'Disabled', 'mainwp' ); ?>
1651 - </option>
1652 - <option value="<?php echo MainWP_Logger::INFO; ?>" <?php echo ( MainWP_Logger::INFO === $enabled ? 'selected' : '' ); ?>>
1653 - <?php esc_html_e( 'Info', 'mainwp' ); ?>
1654 - </option>
1655 - <option value="<?php echo MainWP_Logger::WARNING; ?>" <?php echo ( MainWP_Logger::WARNING === $enabled ? 'selected' : '' ); ?>>
1656 - <?php esc_html_e( 'Warning', 'mainwp' ); ?>
1657 - </option>
1658 - <option value="<?php echo MainWP_Logger::DEBUG; ?>" <?php echo ( MainWP_Logger::DEBUG === $enabled ? 'selected' : '' ); ?>>
1659 - <?php esc_html_e( 'Debug', 'mainwp' ); ?>
1660 - </option>
1661 - <?php
1662 - // phpcs:enable
1663 - if ( is_array( $specific_logs ) && ! empty( $specific_logs ) ) {
1664 - foreach ( $specific_logs as $spec_log => $spec_title ) {
1665 - ?>
1666 - <option value="specific_<?php echo intval( $spec_log ); ?>" <?php echo ( (int) $spec_log === (int) $enabled ? 'selected' : '' ); ?>>
1667 - <?php echo esc_html( $spec_title ); ?>
1668 - </option>
1669 - <?php
1670 - }
1671 - }
1672 - ?>
1673 - </select>
1674 - <input type="submit" class="ui green mini button" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>" />
1675 - <input type="submit" class="ui mini button" name="actionlogs_clear" value="<?php esc_attr_e( 'Delete Log', 'mainwp' ); ?>" />
1676 - </form>
1677 - </div>
1678 - <div class="column">
1168 + $ssl_version = MainWP_Server_Information_Handler::get_curl_ssl_version();
1169 + $openssl_version = 'OpenSSL/1.1.0';
1170 + if ( false !== strpos( $ssl_version, 'LibreSSL' ) ) {
1171 + $openssl_version = 'LibreSSL/2.5.0';
1172 + }
1679 1173
1680 - </div>
1681 - </div>
1682 - </div>
1683 - <div class="ui segment">
1684 - <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-action-logs-info-message' ) ) : ?>
1685 - <div class="ui info message">
1686 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-action-logs-info-message"></i>
1687 - <div><?php echo esc_html__( 'Enable a specific logging system.', 'mainwp' ); ?></div>
1688 - <p><?php echo esc_html__( 'Each specific log type changes only the type of information logged. It does not change the log view.', 'mainwp' ); ?></p>
1689 - <p><?php echo esc_html__( 'After disabling the Action Log, logs will still be visible. To remove records, click the Delete Logs button.', 'mainwp' ); ?></p>
1690 - <p><?php printf( esc_html__( 'For additional help, please review this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/action-logs/" target="_blank">', '</a> <i class="external alternate icon"></i>' ); ?></p>
1691 - </div>
1692 - <?php endif; ?>
1693 - <?php
1694 - $log_to_db = apply_filters( 'mainwp_logger_to_db', true );
1695 - if ( $log_to_db ) {
1696 - return MainWP_Logger::instance()->show_log_db();
1697 - } else {
1698 - MainWP_Logger::instance()->show_log_file();
1699 - }
1700 - ?>
1701 - </div>
1702 - <?php
1703 - self::render_footer( 'ActionLogs' );
1704 - }
1174 + static::render_row_with_description(
1175 + 'cURL SSL Version',
1176 + '>=',
1177 + $openssl_version,
1178 + 'get_curl_ssl_version',
1179 + '',
1180 + '',
1181 + null,
1182 + 'curlssl'
1183 + );
1705 1184
1706 - /**
1707 - * Renders the Plugin Privacy page.
1708 - *
1709 - * @return void
1710 - */
1711 - public static function render_plugin_privacy_page() {
1185 + if ( ! MainWP_Server_Information_Handler::curlssl_compare( $openssl_version, '>=' ) ) {
1186 + ?>
1187 + <tr class='warning'>
1188 + <td colspan='4'>
1189 + <i class='attention icon'></i>
1190 + <?php
1191 + if ( false !== strpos( $ssl_version, 'LibreSSL' ) ) {
1192 + /* translators: 1: line break tag, 2: opening anchor tag, 3: closing anchor tag */
1193 + printf( esc_html__( 'Your host needs to update LibreSSL to at least version 2.5.0 which is already over 4 years old and contains patches for over 60 vulnerabilities.%1$sThese range from Denial of Service to Remote Code Execution. %2$sClick here for more information.%3$s', 'mainwp' ), '<br/>', '<a href="https://www.libressl.org/" target="_blank">', '</a>' );
1194 + } else {
1195 + /* translators: 1: line break tag, 2: opening anchor tag, 3: closing anchor tag */
1196 + printf( esc_html__( 'Your host needs to update OpenSSL to at least version 1.1.0 which is already over 4 years old and contains patches for over 60 vulnerabilities.%1$sThese range from Denial of Service to Remote Code Execution. %2$sClick here for more information.%3$s', 'mainwp' ), '<br/>', '<a href="https://community.letsencrypt.org/t/openssl-client-compatibility-changes-for-let-s-encrypt-certificates/143816" target="_blank">', '</a>' );
1197 + }
1198 + ?>
1199 + </td>
1200 + </tr>
1201 + <?php
1202 + }
1203 + static::render_row_with_description( esc_html__( 'MySQL Version', 'mainwp' ), '>=', '5.0', 'get_mysql_version', '', '', null );
1204 + ?>
1205 + </tbody>
1206 + </table>
1207 + <?php
1208 + /**
1209 + * Action: mainwp_after_system_requirements_check
1210 + *
1211 + * Fires on the bottom of the System Requirements page, in Quick Setup Wizard.
1212 + *
1213 + * @since 4.1
1214 + */
1215 + do_action( 'mainwp_after_system_requirements_check' );
1216 + }
1712 1217
1713 - self::render_header( 'PluginPrivacy' );
1714 - /**
1715 - * Action: mainwp_before_plugin_privacy_section
1716 - *
1717 - * Fires before the Plugin Privacy section.
1718 - *
1719 - * @since 4.2
1720 - */
1721 - do_action( 'mainwp_before_plugin_privacy_section' );
1722 - ?>
1723 - <div class="ui segment">
1724 - <div id="mainwp-plugin-privacy">
1725 - <h2 class="ui header">
1726 - <?php echo esc_html__( 'MainWP Dashboard Plugin Privacy Policy', 'mainwp' ); ?>
1727 - <div class="sub header"><em><?php echo esc_html__( 'Last updated: April 14, 2022', 'mainwp' ); ?></em></div>
1728 - </h2>
1729 - <p><?php echo esc_html__( 'We value your privacy very highly. Please read this Privacy Policy carefully before using the MainWP Dashboard Plugin ("Plugin") operated by Sick Marketing, LLC d/b/a MainWP, a Limited Liability Company formed in Nevada, United States ("us","we","our") as this Privacy Policy contains important information regarding your privacy.', 'mainwp' ); ?></p>
1730 - <p><?php echo esc_html__( 'Your access to and use of the Plugin is conditional upon your acceptance of and compliance with this Privacy Policy. This Privacy Policy applies to everyone accessing or using the Plugin.', 'mainwp' ); ?></p>
1731 - <p><?php echo esc_html__( 'By accessing or using the Plugin, you agree to be bound by this Privacy Policy. If you disagree with any part of this Privacy Policy, then you do not have our permission to access or use the Plugin.', 'mainwp' ); ?></p>
1732 - <h3 class="ui header"><?php echo esc_html__( 'What personal data we collect', 'mainwp' ); ?></h3>
1733 - <p><?php echo esc_html__( 'We do not collect, store, nor process any personal data through this Plugin.', 'mainwp' ); ?></p>
1734 - <h3 class="ui header"><?php echo esc_html__( 'Third-party extensions and integrations', 'mainwp' ); ?></h3>
1735 - <p><?php echo esc_html__( 'This Plugin may be used with extensions that are operated by parties other than us. We may also provide extensions that have integrations with third party services. We do not control such extensions and integrations and are not responsible for their contents or the privacy or other practices of such extensions or integrations. Further, it is up to you to take precautions to ensure that whatever extensions or integrations you use adequately protect your privacy. Please review the Privacy Policies of such extensions or integrations before using them.', 'mainwp' ); ?></p>
1736 - <div class="ui hidden divider"></div>
1737 - <div class="ui two columns stackable grid">
1738 - <div class="column">
1739 - <h3 class="ui header"><?php echo esc_html__( 'Our contact information', 'mainwp' ); ?></h3>
1740 - <p><?php echo esc_html__( 'If you have any questions regarding our privacy practices, please do not hesitate to contact us at the following:', 'mainwp' ); ?></p>
1741 - <div class="ui list">
1742 - <div class="item"><?php echo esc_html__( 'Sick Marketing, LLC d/b/a MainWP', 'mainwp' ); ?></div>
1743 - <div class="item"><?php echo esc_html__( '[email protected]', 'mainwp' ); ?></div>
1744 - <div class="item"><?php echo esc_html__( '4730 S. Fort Apache Road', 'mainwp' ); ?></div>
1745 - <div class="item"><?php echo esc_html__( 'Suite 300', 'mainwp' ); ?></div>
1746 - <div class="item"><?php echo esc_html__( 'PO Box 27740', 'mainwp' ); ?></div>
1747 - <div class="item"><?php echo esc_html__( 'Las Vegas, NV 89126', 'mainwp' ); ?></div>
1748 - <div class="item"><?php echo esc_html__( 'United States', 'mainwp' ); ?></div>
1749 - </div>
1750 - </div>
1751 - <div class="column">
1752 - <h3 class="ui header"><?php echo esc_html__( 'Our representative\'s contact information', 'mainwp' ); ?></h3>
1753 - <p><?php echo esc_html__( 'If you are a resident of the European Union or the European Economic Area, you may also contact our representative at the following:', 'mainwp' ); ?></p>
1754 - <div class="item"><?php echo esc_html__( 'Ametros Ltd', 'mainwp' ); ?></div>
1755 - <div class="item"><?php echo esc_html__( 'Unit 3D', 'mainwp' ); ?></div>
1756 - <div class="item"><?php echo esc_html__( 'North Point House', 'mainwp' ); ?></div>
1757 - <div class="item"><?php echo esc_html__( 'North Point Business Park', 'mainwp' ); ?></div>
1758 - <div class="item"><?php echo esc_html__( 'New Mallow Road', 'mainwp' ); ?></div>
1759 - <div class="item"><?php echo esc_html__( 'Cork', 'mainwp' ); ?></div>
1760 - <div class="item"><?php echo esc_html__( 'Ireland', 'mainwp' ); ?></div>
1761 - <div class="ui hidden divider"></div>
1762 - <p><?php echo esc_html__( 'If you are a resident of the United Kingdom, you may contact our representative at the following:', 'mainwp' ); ?></p>
1763 - <div class="item"><?php echo esc_html__( 'Ametros Group Ltd', 'mainwp' ); ?></div>
1764 - <div class="item"><?php echo esc_html__( 'Lakeside Offices', 'mainwp' ); ?></div>
1765 - <div class="item"><?php echo esc_html__( 'Thorn Business Park', 'mainwp' ); ?></div>
1766 - <div class="item"><?php echo esc_html__( 'Hereford', 'mainwp' ); ?></div>
1767 - <div class="item"><?php echo esc_html__( 'Herefordshire', 'mainwp' ); ?></div>
1768 - <div class="item"><?php echo esc_html__( 'HR2 6JT', 'mainwp' ); ?></div>
1769 - <div class="item"><?php echo esc_html__( 'England', 'mainwp' ); ?></div>
1770 - </div>
1771 - </div>
1772 - <div class="ui divider"></div>
1773 - </div>
1774 -
1775 - <a href="<?php echo esc_url( get_site_url() ) . '/wp-content/plugins/mainwp/privacy-policy.txt'; ?>" class="ui green basic button" target="_blank"><?php echo esc_html__( 'Download MainWP Dashboard Privacy Policy', 'mainwp' ); ?></a> <a href="<?php echo esc_url( get_site_url() ) . '/wp-content/plugins/mainwp/mainwp-child-privacy-policy.txt'; ?>" class="ui green basic button" target="_blank"><?php echo esc_html__( 'Download MainWP Child Privacy Policy', 'mainwp' ); ?></a>
1776 - </div>
1218 + /**
1219 + * Compares the detected MainWP Dashboard version agains the verion in WP.org.
1220 + *
1221 + * @return mixed Pass|static::get_warning_html().
1222 + *
1223 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_mainwp_version()
1224 + */
1225 + public static function get_mainwp_version_check() {
1226 + $current = get_option( 'mainwp_plugin_version' );
1227 + $latest = MainWP_Server_Information_Handler::get_mainwp_version();
1228 + if ( $current === $latest ) {
1229 + return static::get_pass_html();
1230 + } else {
1231 + return static::get_warning_html();
1232 + }
1233 + }
1777 1234
1778 - <?php
1779 - /**
1780 - * Action: mainwp_after_plugin_privacy_section
1781 - *
1782 - * Fires after the Plugin Privacy section.
1783 - *
1784 - * @since 4.2
1785 - */
1786 - do_action( 'mainwp_after_plugin_privacy_section' );
1235 + /**
1236 + * Renders the Cron Schedule page.
1237 + *
1238 + * @return void
1239 + *
1240 + * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
1241 + * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
1242 + */
1243 + public static function render_cron() { // phpcs:ignore -- NOSONAR - complex.
1244 + if ( ! \mainwp_current_user_can( 'dashboard', 'see_server_information' ) ) {
1245 + \mainwp_do_not_have_permissions( 'cron schedules', 'mainwp' );
1246 + return;
1247 + }
1787 1248
1788 - self::render_footer( 'PluginPrivacy' );
1789 - }
1249 + static::render_header( 'ServerInformationCron' );
1790 1250
1791 - /**
1792 - * Renders .htaccess File page.
1793 - *
1794 - * @return void
1795 - */
1796 - public static function render_htaccess() {
1797 - if ( ! mainwp_current_user_have_right( 'dashboard', 'see_server_information' ) ) {
1798 - mainwp_do_not_have_permissions( '.htaccess', 'mainwp' );
1799 - return;
1800 - }
1801 - self::render_header( '.htaccess' );
1802 - /**
1803 - * Action: mainwp_before_htaccess_section
1804 - *
1805 - * Fires before the .htaccess file section.
1806 - *
1807 - * @since 4.1
1808 - */
1809 - do_action( 'mainwp_before_htaccess_section' );
1810 - ?>
1811 - <div id="mainwp-show-htaccess">
1812 - <?php
1813 - if ( false !== strpos( ini_get( 'disable_functions' ), 'show_source' ) ) {
1814 - esc_html_e( 'File content could not be displayed.', 'mainwp' );
1815 - echo '<br />';
1816 - esc_html_e( 'It appears that the show_source() PHP function has been disabled on the servre.', 'mainwp' );
1817 - echo '<br />';
1818 - esc_html_e( 'Please, contact your host support and have them enable the show_source() function for the proper functioning of this feature.', 'mainwp' );
1819 - } else {
1820 - show_source( ABSPATH . '.htaccess' );
1821 - }
1822 - ?>
1823 - </div>
1824 - <?php
1825 - /**
1826 - * Action: mainwp_after_htaccess_section
1827 - *
1828 - * Fires after the .htaccess file section.
1829 - *
1830 - * @since 4.1
1831 - */
1832 - do_action( 'mainwp_after_htaccess_section' );
1833 - self::render_footer( '.htaccess' );
1834 - }
1251 + $local_timestamp = MainWP_Utility::get_timestamp();
1835 1252
1836 - /**
1837 - * Checks for disable PHP Functions.
1838 - *
1839 - * @return void
1840 - */
1841 - public static function php_disabled_functions() {
1842 - $disabled_functions = ini_get( 'disable_functions' );
1843 - if ( '' !== $disabled_functions ) {
1844 - $arr = explode( ',', $disabled_functions );
1845 - sort( $arr );
1846 - $_count = count( $arr );
1847 - for ( $i = 0; $i < $_count; $i++ ) {
1848 - echo esc_html( $arr[ $i ] ) . ', ';
1849 - }
1850 - } else {
1851 - esc_html_e( 'No functions disabled.', 'mainwp' );
1852 - }
1853 - }
1253 + $freq = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
1254 + if ( $freq <= 0 ) {
1255 + $freq = 1;
1256 + }
1257 + $auto_update_text = static::get_schedule_auto_update_label( $freq );
1854 1258
1855 - /**
1856 - * Renders MainWP Settings 'Options'.
1857 - *
1858 - * @return void
1859 - *
1860 - * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::mainwp_options()
1861 - */
1862 - public static function display_mainwp_options() {
1863 - $options = MainWP_Server_Information_Handler::mainwp_options();
1864 - // phpcs:disable WordPress.Security.EscapeOutput
1865 - foreach ( $options as $option ) {
1866 - echo '<tr><td>' . $option['label'] . '</td><td>' . $option['value'] . '</td></tr>';
1867 - }
1868 - // phpcs:enable
1869 - }
1259 + $cron_jobs = array(
1260 + 'Check for available updates' => array( 'mainwp_updatescheck_start_last_timestamp', 'mainwp_cronupdatescheck_action', $auto_update_text ),
1261 + 'Check for reconnect sites' => array( 'mainwp_cron_last_stats', 'mainwp_cronreconnect_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' ),
1262 + 'Ping childs sites' => array( 'mainwp_cron_last_ping', 'mainwp_cronpingchilds_action', esc_html__( 'Once daily', 'mainwp' ), 'daily' ),
1263 + );
1870 1264
1871 - /**
1872 - * Renders PHP Warning HTML.
1873 - *
1874 - * @param int $errorType Global variable self::WARNING = 1.
1875 - *
1876 - * @return string PHP Warning html.
1877 - */
1878 - private static function get_warning_html( $errorType = self::WARNING ) {
1879 - if ( self::WARNING === $errorType ) {
1880 - return '<i class="large yellow exclamation icon"></i><span style="display:none">' . esc_html__( 'Warning', 'mainwp' ) . '</span>';
1881 - }
1882 - return '<i class="large red times icon"></i><span style="display:none">' . esc_html__( 'Fail', 'mainwp' ) . '</span>';
1883 - }
1265 + $cron_jobs['Child site uptime monitoring'] = array( 'mainwp_uptime_lasttime_check', 'mainwp_cronuptimemonitoringcheck_action', esc_html__( 'Once every minute', 'mainwp' ), 'minutely' );
1884 1266
1885 - /**
1886 - * Renders PHP Pass HTML.
1887 - *
1888 - * @return string PHP Pass html.
1889 - */
1890 - private static function get_pass_html() {
1891 - return '<i class="large green check icon"></i><span style="display:none">' . esc_html__( 'Pass', 'mainwp' ) . '</span>';
1892 - }
1267 + $disableHealthChecking = get_option( 'mainwp_disableSitesHealthMonitoring', 1 ); // disabled by default.
1268 + if ( ! $disableHealthChecking ) {
1269 + $cron_jobs['Site Health monitoring'] = array( 'mainwp_cron_checksiteshealth_last_timestamp', 'mainwp_cronsitehealthcheck_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' );
1270 + }
1271 +
1272 + if ( get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
1273 + $cron_jobs['Start backups (Legacy)'] = array( 'mainwp_cron_last_backups', 'mainwp_cronbackups_action', esc_html__( 'Once hourly', 'mainwp' ), 'hourly' );
1274 + $cron_jobs['Continue backups (Legacy)'] = array( 'mainwp_cron_last_backups_continue', 'mainwp_cronbackups_continue_action', esc_html__( 'Once every five minutes', 'mainwp' ), '5minutely' );
1275 + }
1276 +
1277 + $cron_jobs = apply_filters( 'mainwp_info_schedules_cron_listing', $cron_jobs );
1278 +
1279 + /**
1280 + * Action: mainwp_before_cron_jobs_table
1281 + *
1282 + * Renders on the top of the Cron Jobs page, before the Schedules table.
1283 + *
1284 + * @since 4.0
1285 + */
1286 + do_action( 'mainwp_before_cron_jobs_table' );
1287 + ?>
1288 + <div class="ui padded segment">
1289 + <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-cron-info-message' ) ) : ?>
1290 + <div class="ui info message">
1291 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-cron-info-message"></i>
1292 + <?php /* translators: 1: opening anchor tag, 2: closing anchor tag */ printf( esc_html__( 'Make sure scheduled actions are working correctly. If scheduled actions do not run normally, please review this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/customization/disable-wp-cron" target="_blank">', '</a> <i class="external alternate icon"></i>' ); ?>
1293 + </div>
1294 + <?php endif; ?>
1295 + <table class="ui single line unstackable table" id="mainwp-cron-jobs-table">
1296 + <thead>
1297 + <tr>
1298 + <th scope="col" ><?php esc_html_e( 'Cron Job', 'mainwp' ); ?></th>
1299 + <th scope="col" ><?php esc_html_e( 'Hook', 'mainwp' ); ?></th>
1300 + <th scope="col" ><?php esc_html_e( 'Schedule', 'mainwp' ); ?></th>
1301 + <th scope="col" ><?php esc_html_e( 'Last Run', 'mainwp' ); ?></th>
1302 + <th scope="col" ><?php esc_html_e( 'Next Run', 'mainwp' ); ?></th>
1303 + </tr>
1304 + </thead>
1305 + <tbody>
1306 + <?php
1307 + $useWPCron = ( false === get_option( 'mainwp_wp_cron' ) ) || ( 1 === (int) get_option( 'mainwp_wp_cron' ) );
1308 +
1309 + foreach ( $cron_jobs as $cron_job => $hook ) {
1310 +
1311 + if ( is_array( $hook ) && isset( $hook['title'] ) && isset( $hook['action'] ) ) {
1312 + $job_title = $hook['title'];
1313 + $job_action = $hook['action'];
1314 + $job_freq = isset( $hook['frequency'] ) ? $hook['frequency'] : '';
1315 + $job_last_run = isset( $hook['last_run'] ) ? $hook['last_run'] : '';
1316 + $job_next_run = isset( $hook['next_run'] ) ? $hook['next_run'] : '';
1317 + } else {
1318 +
1319 + $is_auto_update_job = false;
1320 + $lasttime_run = 0;
1321 + $next_run = 0;
1322 +
1323 + if ( 'mainwp_updatescheck_start_last_timestamp' === $hook[0] ) {
1324 + $update_time = MainWP_Settings::get_websites_automatic_update_time();
1325 + $last_run = $update_time['last'];
1326 + $next_run = $update_time['next'];
1327 + $is_auto_update_job = true;
1328 + } elseif ( false === get_option( $hook[0] ) ) {
1329 + $last_run = esc_html__( 'Never', 'mainwp' );
1330 + } else {
1331 + $lasttime_run = get_option( $hook[0] );
1332 + if ( $lasttime_run ) {
1333 + if ( 'mainwp_uptime_lasttime_check' === $hook[0] ) {
1334 + $last_run = MainWP_Utility::format_timestamp( $lasttime_run );
1335 + } else {
1336 + $last_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $lasttime_run ) );
1337 + }
1338 + } else {
1339 + $last_run = esc_html__( 'Never', 'mainwp' );
1340 + }
1341 + }
1342 +
1343 + if ( $useWPCron && 'mainwp_updatescheck_start_last_timestamp' !== $hook[0] ) {
1344 + $next_run = wp_next_scheduled( $hook[1] );
1345 + if ( ! empty( $next_run ) ) {
1346 + $next_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $next_run ) );
1347 + }
1348 + }
1349 +
1350 + if ( empty( $next_run ) || ( ! $useWPCron && ! $is_auto_update_job && isset( $hook[3] ) ) ) {
1351 + $nexttime_run = static::get_schedule_next_time_to_show( $hook[3], $lasttime_run, $local_timestamp );
1352 + if ( $nexttime_run < $local_timestamp + 3 * MINUTE_IN_SECONDS ) {
1353 + $next_run = esc_html__( 'Any minute', 'mainwp' );
1354 + } else {
1355 + $next_run = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $nexttime_run ) );
1356 + }
1357 + }
1358 +
1359 + $job_title = $cron_job;
1360 + $job_action = $hook[1];
1361 + $job_freq = $hook[2];
1362 + $job_last_run = $last_run;
1363 + $job_next_run = $next_run;
1364 + }
1365 +
1366 + // phpcs:disable WordPress.Security.EscapeOutput
1367 + ?>
1368 + <tr>
1369 + <td><?php echo esc_html( $job_title ); ?></td>
1370 + <td><?php echo esc_html( $job_action ); ?></td>
1371 + <td><?php echo esc_html( $job_freq ); ?></td>
1372 + <td><?php echo esc_html( $job_last_run ); ?></td>
1373 + <td><?php echo ! empty( $job_next_run ) ? esc_html( $job_next_run ) : ''; ?></td>
1374 + </tr>
1375 + <?php
1376 + // phpcs:enable
1377 + }
1378 + /**
1379 + * Action: mainwp_cron_jobs_list
1380 + *
1381 + * Renders as the last row of the Schedules table.
1382 + *
1383 + * @since 4.0
1384 + */
1385 + do_action( 'mainwp_cron_jobs_list' );
1386 + ?>
1387 + </tbody>
1388 + </table>
1389 + <?php
1390 + $table_features = array(
1391 + 'searching' => 'true',
1392 + 'paging' => 'false',
1393 + 'info' => 'false',
1394 + 'responsive' => 'true',
1395 + );
1396 + /**
1397 + * Filter: mainwp_cron_jobs_table_features
1398 + *
1399 + * Filters the Cron Schedules table features.
1400 + *
1401 + * @since 4.1
1402 + */
1403 + $table_features = apply_filters( 'mainwp_cron_jobs_table_features', $table_features );
1404 + ?>
1405 + <script type="text/javascript">
1406 + jQuery( document ).ready( function() {
1407 + let responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
1408 + if( jQuery( window ).width() > 1140 ) {
1409 + responsive = false;
1410 + }
1411 + jQuery( '#mainwp-cron-jobs-table' ).DataTable( {
1412 + "searching": <?php echo esc_html( $table_features['searching'] ); ?>,
1413 + "paging": <?php echo esc_html( $table_features['paging'] ); ?>,
1414 + "info": <?php echo esc_html( $table_features['info'] ); ?>,
1415 + "responsive": responsive,
1416 + });
1417 + } );
1418 + </script>
1419 + </div>
1420 + <?php
1421 +
1422 + /**
1423 + * Action: mainwp_after_cron_jobs_table
1424 + *
1425 + * Renders on the bottom of the Cron Jobs page, after the Schedules table.
1426 + *
1427 + * @since 4.0
1428 + */
1429 + do_action( 'mainwp_after_cron_jobs_table' );
1430 +
1431 + static::render_footer( 'ServerInformationCron' );
1432 + }
1433 +
1434 + /**
1435 + * Get frequency auto update to show.
1436 + *
1437 + * @param int $freq frequency of auto update.
1438 + *
1439 + * @return string label of frequency.
1440 + */
1441 + public static function get_schedule_auto_update_label( $freq ) {
1442 + $freq = intval( $freq );
1443 + $text = '';
1444 + switch ( $freq ) {
1445 + case 1:
1446 + $text = esc_html__( 'Once per day', 'mainwp' );
1447 + break;
1448 + case 2:
1449 + $text = esc_html__( 'Twice per day', 'mainwp' );
1450 + break;
1451 + case 3:
1452 + $text = esc_html__( 'Three times per day', 'mainwp' );
1453 + break;
1454 + case 4:
1455 + $text = esc_html__( 'Four times per day', 'mainwp' );
1456 + break;
1457 + case 5:
1458 + $text = esc_html__( 'Five times per day', 'mainwp' );
1459 + break;
1460 + case 6:
1461 + $text = esc_html__( 'Six times per day', 'mainwp' );
1462 + break;
1463 + case 7:
1464 + $text = esc_html__( 'Seven times per day', 'mainwp' );
1465 + break;
1466 + case 8:
1467 + $text = esc_html__( 'Eight times per day', 'mainwp' );
1468 + break;
1469 + case 9:
1470 + $text = esc_html__( 'Nine times per day', 'mainwp' );
1471 + break;
1472 + case 10:
1473 + $text = esc_html__( 'Ten times per day', 'mainwp' );
1474 + break;
1475 + case 11:
1476 + $text = esc_html__( 'Eleven times per day', 'mainwp' );
1477 + break;
1478 + case 12:
1479 + $text = esc_html__( 'Twelve times per day', 'mainwp' );
1480 + break;
1481 + default:
1482 + break;
1483 + }
1484 + return $text;
1485 + }
1486 +
1487 + /**
1488 + * Get next time of schedule job to show.
1489 + *
1490 + * @param string $job_freq frequency of schedule job.
1491 + * @param int $lasttime_run Lasttime to run.
1492 + * @param int $local_timestamp current local time.
1493 + *
1494 + * @return int next run time of schedule job.
1495 + */
1496 + public static function get_schedule_next_time_to_show( $job_freq, $lasttime_run, $local_timestamp ) {
1497 + $next_time = $local_timestamp;
1498 + $lasttime_run = is_numeric( $lasttime_run ) ? intval( $lasttime_run ) : false;
1499 + switch ( $job_freq ) {
1500 + case 'daily':
1501 + $next_time = $lasttime_run ? $lasttime_run + DAY_IN_SECONDS : $local_timestamp + DAY_IN_SECONDS;
1502 + break;
1503 + case 'hourly':
1504 + $next_time = $lasttime_run ? $lasttime_run + HOUR_IN_SECONDS : $local_timestamp + HOUR_IN_SECONDS;
1505 + break;
1506 + case '5minutely':
1507 + $next_time = $lasttime_run ? $lasttime_run + 5 * MINUTE_IN_SECONDS : $local_timestamp + 5 * MINUTE_IN_SECONDS;
1508 + break;
1509 + case 'minutely':
1510 + $next_time = $lasttime_run ? $lasttime_run + MINUTE_IN_SECONDS : $local_timestamp + MINUTE_IN_SECONDS;
1511 + break;
1512 + default:
1513 + break;
1514 + }
1515 +
1516 + if ( $next_time < $local_timestamp ) { // to fix next time in past.
1517 + $next_time = $local_timestamp;
1518 + }
1519 +
1520 + return $next_time;
1521 + }
1522 +
1523 + /**
1524 + * Checks if the ../wp-content/uploads/mainwp/ directory is writable.
1525 + *
1526 + * @return bool True if writable, false if not.
1527 + *
1528 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
1529 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
1530 + */
1531 + public static function check_directory_mainwp_directory() {
1532 + $dirs = MainWP_System_Utility::get_mainwp_dir();
1533 + $path = $dirs[0];
1534 +
1535 + $mess = 'Writable';
1536 +
1537 + if ( ! is_dir( dirname( $path ) ) ) {
1538 + $mess = 'Not Found';
1539 + }
1540 +
1541 + $is_writable = MainWP_System_Utility::is_writable( $path );
1542 +
1543 + if ( $is_writable ) {
1544 + $mess = 'Not Writable';
1545 + }
1546 +
1547 + return '<tr><td>MainWP Upload Directory</td><td>' . $mess . '</td></tr>';
1548 + }
1549 +
1550 + /**
1551 + * Renders the directory check row.
1552 + *
1553 + * @param string $name check name.
1554 + * @param string $check desired result.
1555 + * @param string $result detected result.
1556 + * @param bool $passed true|false check result.
1557 + *
1558 + * @return bool true.
1559 + */
1560 + public static function render_directory_row( $name, $check, $result, $passed ) {
1561 + // phpcs:disable WordPress.Security.EscapeOutput
1562 + ?>
1563 + <tr>
1564 + <td><?php echo esc_html( $name ); ?></td>
1565 + <td><?php echo esc_html( $check ); ?></td>
1566 + <td><?php echo esc_html( $result ); ?></td>
1567 + <td class="right aligned"><?php echo $passed ? static::get_pass_html() : static::get_warning_html( static::ERROR ); ?></td>
1568 + </tr>
1569 + <?php
1570 + // phpcs:enable
1571 + return true;
1572 + }
1573 +
1574 + /**
1575 + * Renders server information table row.
1576 + *
1577 + * @param string $config configuraion check.
1578 + * @param string $compare comparison operator.
1579 + * @param mixed $version reqiored minium version number.
1580 + * @param mixed $getter detected version number.
1581 + * @param string $extraText additionl text.
1582 + * @param null $extraCompare extra compare.
1583 + * @param null $extraVersion extra version.
1584 + * @param null $whatType comparison type.
1585 + * @param int $errorType global variable static::WARNING = 1.
1586 + *
1587 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::filesize_compare()
1588 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::curlssl_compare()
1589 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1590 + */
1591 + public static function render_row( $config, $compare, $version, $getter, $extraText = '', $extraCompare = null, $extraVersion = null, $whatType = null, $errorType = self::WARNING ) { //phpcs:ignore -- NOSONAR - complex.
1592 + $currentVersion = call_user_func( array( MainWP_Server_Information_Handler::get_class_name(), $getter ) );
1593 + // phpcs:disable WordPress.Security.EscapeOutput
1594 + $ver = is_array( $version ) && isset( $version['version'] ) ? esc_html( $version['version'] ) : esc_html( $version );
1595 + ?>
1596 + <tr>
1597 + <td><?php echo esc_html( $config ); ?></td>
1598 + <td><?php echo esc_html( $compare ); ?><?php echo ( true === $version ? 'true' : $ver ) . ' ' . $extraText; ?></td>
1599 + <td><?php echo true === $currentVersion ? 'true' : $currentVersion; ?></td>
1600 + <?php if ( 'filesize' === $whatType ) { ?>
1601 + <td class="right aligned"><?php echo MainWP_Server_Information_Handler::filesize_compare( $currentVersion, $version, $compare ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1602 + <?php } elseif ( 'get_curl_ssl_version' === $getter ) { ?>
1603 + <td class="right aligned"><?php echo MainWP_Server_Information_Handler::curlssl_compare( $version, $compare ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1604 + <?php } elseif ( ( 'get_max_input_time' === $getter || 'get_max_execution_time' === $getter ) && -1 === (int) $currentVersion ) { ?>
1605 + <td class="right aligned"><?php echo static::get_pass_html(); ?></td>
1606 + <?php } else { ?>
1607 + <td class="right aligned"><?php echo version_compare( $currentVersion, $version, $compare ) || ( ! empty( $extraCompare ) && version_compare( $currentVersion, $extraVersion, $extraCompare ) ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1608 + <?php } ?>
1609 + </tr>
1610 + <?php
1611 + // phpcs:enable
1612 + }
1613 +
1614 + /**
1615 + * Renders server information table row with description.
1616 + *
1617 + * @param string $config configuraion check.
1618 + * @param string $compare comparison operator.
1619 + * @param mixed $version reqiored minium version number.
1620 + * @param mixed $getter detected version number.
1621 + * @param string $extraText additionl text.
1622 + * @param null $extraCompare extra compare.
1623 + * @param null $extraVersion extra version.
1624 + * @param null $whatType comparison type.
1625 + * @param int $errorType global variable static::WARNING = 1.
1626 + *
1627 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1628 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::filesize_compare()
1629 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::curlssl_compare()
1630 + */
1631 + public static function render_row_with_description( $config, $compare, $version, $getter, $extraText = '', $extraCompare = null, $extraVersion = null, $whatType = null, $errorType = self::WARNING ) { // phpcs:ignore -- NOSONAR - complex.
1632 + $currentVersion = call_user_func( array( MainWP_Server_Information_Handler::get_class_name(), $getter ) );
1633 + // phpcs:disable WordPress.Security.EscapeOutput
1634 + $ver = is_array( $version ) && isset( $version['version'] ) ? esc_html( $version['version'] ) : esc_html( $version );
1635 + ?>
1636 + <tr>
1637 + <td><?php echo esc_html( $config ); ?></td>
1638 + <td><?php echo esc_html( $compare ); ?> <?php echo ( true === $version ? 'true' : $ver ) . ' ' . $extraText; ?></td>
1639 + <td><?php echo true === $currentVersion ? 'true' : $currentVersion; ?></td>
1640 + <?php if ( 'filesize' === $whatType ) { ?>
1641 + <td class="right aligned"><?php echo MainWP_Server_Information_Handler::filesize_compare( $currentVersion, $version, $compare ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1642 + <?php } elseif ( 'get_curl_ssl_version' === $getter ) { ?>
1643 + <td class="right aligned"><?php echo MainWP_Server_Information_Handler::curlssl_compare( $version, $compare ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1644 + <?php } elseif ( 'get_max_input_time' === $getter && -1 === (int) $currentVersion ) { ?>
1645 + <td class="right aligned"><?php echo static::get_pass_html(); ?></td>
1646 + <?php } else { ?>
1647 + <td class="right aligned"><?php echo version_compare( $currentVersion, $version, $compare ) || ( ! empty( $extraCompare ) && version_compare( $currentVersion, $extraVersion, $extraCompare ) ) ? static::get_pass_html() : static::get_warning_html( $errorType ); ?></td>
1648 + <?php } ?>
1649 + </tr>
1650 + <?php
1651 + // phpcs:enable
1652 + }
1653 +
1654 + /**
1655 + * Checks if file system method is direct.
1656 + *
1657 + * @return mixed html|static::get_warning_html().
1658 + *
1659 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_file_system_method()
1660 + */
1661 + public static function get_file_system_method_check() {
1662 + $fsmethod = MainWP_Server_Information_Handler::get_file_system_method();
1663 + if ( 'direct' === $fsmethod ) {
1664 + return static::get_pass_html();
1665 + } else {
1666 + return static::get_warning_html();
1667 + }
1668 + }
1669 +
1670 + /**
1671 + * Renders Error Log page.
1672 + *
1673 + * Plugin-Name: Error Log Dashboard Widget
1674 + * Plugin URI: http://wordpress.org/extend/plugins/error-log-dashboard-widget/
1675 + * Description: Robust zero-configuration and low-memory way to keep an eye on error log.
1676 + * Author: Andrey "Rarst" Savchenko
1677 + * Author URI: http://www.rarst.net/
1678 + * Version: 1.0.2
1679 + * License: GPLv2 or later
1680 +
1681 + * Includes last_lines() function by phant0m, licensed under cc-wiki and GPLv2+
1682 + */
1683 + public static function render_error_log_page() {
1684 + if ( ! \mainwp_current_user_can( 'dashboard', 'see_server_information' ) ) {
1685 + \mainwp_do_not_have_permissions( 'error log', 'mainwp' );
1686 + return;
1687 + }
1688 + static::render_header( 'ErrorLog' );
1689 +
1690 + /**
1691 + * Action: mainwp_before_error_log_table
1692 + *
1693 + * Fires before the Error Log table.
1694 + *
1695 + * @since 4.1
1696 + */
1697 + do_action( 'mainwp_before_error_log_table' );
1698 + ?>
1699 + <div class="ui padded segment">
1700 + <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-error-log-info-message' ) ) : ?>
1701 + <div class="ui info message">
1702 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-error-log-info-message"></i>
1703 + <?php echo esc_html__( 'See the WordPress error log to fix problems that arise on your MainWP Dashboard site.', 'mainwp' ); ?>
1704 + </div>
1705 + <?php endif; ?>
1706 + <table class="ui unstackable table" id="mainwp-error-log-table">
1707 + <thead>
1708 + <tr>
1709 + <th scope="col" ><?php esc_html_e( 'Time', 'mainwp' ); ?></th>
1710 + <th scope="col" ><?php esc_html_e( 'Error', 'mainwp' ); ?></th>
1711 + </tr>
1712 + </thead>
1713 + <tbody>
1714 + <?php static::render_error_log(); ?>
1715 + </tbody>
1716 + </table>
1717 + <script type="text/javascript">
1718 + let responsive = true;
1719 + if( jQuery( window ).width() > 1140 ) {
1720 + responsive = false;
1721 + }
1722 +
1723 + jQuery( document ).ready( function() {
1724 + jQuery( '#mainwp-error-log-table' ).DataTable( {
1725 + "responsive": responsive,
1726 + "ordering": false,
1727 + "stateSave": true,
1728 + "stateDuration": 0,
1729 + "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
1730 + "language": {
1731 + "emptyTable": '<?php esc_html_e( 'Error logging disabled.', 'mainwp' ); ?><?php /* translators: 1: opening anchor tag, 2: closing anchor tag */ echo '<br/>' . sprintf( esc_html__( 'To enable error logging, please check this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">', '</a>' ); ?>'
1732 + },
1733 + columnDefs: [{
1734 + "defaultContent": "-",
1735 + "targets": "_all"
1736 + }]
1737 + } );
1738 + } );
1739 + </script>
1740 + </div>
1741 + <?php
1742 + /**
1743 + * Action: mainwp_after_error_log_table
1744 + *
1745 + * Fires after the Error Log table.
1746 + *
1747 + * @since 4.1
1748 + */
1749 + do_action( 'mainwp_after_error_log_table' );
1750 +
1751 + static::render_footer( 'ErrorLog' );
1752 + }
1753 +
1754 + /**
1755 + * Renders error log page.
1756 + *
1757 + * @return void
1758 + *
1759 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::last_lines()
1760 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::get_class_name()
1761 + */
1762 + public static function render_error_log() {
1763 + $log_errors = ini_get( 'log_errors' );
1764 + if ( ! $log_errors ) {
1765 + return;
1766 + }
1767 +
1768 + $error_log = ini_get( 'error_log' );
1769 + /**
1770 + * Filter: error_log_mainwp_logs
1771 + *
1772 + * Filters the error log files to show.
1773 + *
1774 + * @since Unknown
1775 + */
1776 + $logs = apply_filters( 'error_log_mainwp_logs', array( $error_log ) );
1777 +
1778 + /**
1779 + * Filter: error_log_mainwp_lines
1780 + *
1781 + * Limits the number of error log records to be displayed. Default value, 50.
1782 + *
1783 + * @since Unknown
1784 + */
1785 + $count = apply_filters( 'error_log_mainwp_lines', 100 );
1786 + $lines = array();
1787 +
1788 + foreach ( $logs as $log ) {
1789 + if ( is_readable( $log ) ) {
1790 + $lines = array_merge( $lines, MainWP_Server_Information_Handler::last_lines( $log, $count ) );
1791 + }
1792 + }
1793 +
1794 + $lines = array_map( 'trim', $lines );
1795 + $lines = array_filter( $lines );
1796 +
1797 + if ( empty( $lines ) ) {
1798 + echo '<tr><td colspan="2">' . esc_html__( 'MainWP is unable to find your error logs, please contact your host for server error logs.', 'mainwp' ) . '</td></tr>';
1799 + return;
1800 + }
1801 +
1802 + foreach ( $lines as $key => $line ) {
1803 + if ( false !== strpos( $line, ']' ) ) {
1804 + list( $time, $error ) = explode( ']', $line, 2 );
1805 + } else {
1806 + list( $time, $error ) = array( '', $line );
1807 + }
1808 + $time = trim( $time, '[]' );
1809 + $error = trim( $error );
1810 + $lines[ $key ] = compact( 'time', 'error' );
1811 + }
1812 +
1813 + if ( 1 < count( $lines ) ) {
1814 + // phpcs:ignore -- ok.
1815 + //uasort( $lines, array( MainWP_Server_Information_Handler::get_class_name(), 'time_compare' ) );
1816 + $lines = array_slice( $lines, 0, $count );
1817 + }
1818 +
1819 + // phpcs:disable WordPress.Security.EscapeOutput
1820 + foreach ( $lines as $line ) {
1821 + $error = esc_html( $line['error'] );
1822 + $time = esc_html( $line['time'] );
1823 + if ( ! empty( $error ) ) {
1824 + echo '<tr><td>' . $time . '</td><td>' . $error . '</td></tr>';
1825 + }
1826 + }
1827 + // phpcs:enable
1828 + }
1829 +
1830 + /**
1831 + * Renders the WP Config page.
1832 + *
1833 + * @return void
1834 + */
1835 + public static function render_wp_config() {
1836 + if ( ! \mainwp_current_user_can( 'dashboard', 'see_server_information' ) ) {
1837 + \mainwp_do_not_have_permissions( 'WP-Config.php', 'mainwp' );
1838 + return;
1839 + }
1840 +
1841 + static::render_header( 'WPConfig' );
1842 + /**
1843 + * Action: mainwp_before_wp_config_section
1844 + *
1845 + * Fires before the WP Config section.
1846 + *
1847 + * @since 4.1
1848 + */
1849 + do_action( 'mainwp_before_wp_config_section' );
1850 + ?>
1851 + <div id="mainwp-show-wp-config">
1852 + <?php
1853 + if ( false !== strpos( ini_get( 'disable_functions' ), 'show_source' ) ) {
1854 + esc_html_e( 'File content could not be displayed.', 'mainwp' );
1855 + echo '<br />';
1856 + esc_html_e( 'It appears that the show_source() PHP function has been disabled on the servre.', 'mainwp' );
1857 + echo '<br />';
1858 + esc_html_e( 'Please, contact your host support and have them enable the show_source() function for the proper functioning of this feature.', 'mainwp' );
1859 + } elseif ( file_exists( ABSPATH . 'wp-config.php' ) ) {
1860 + show_source( ABSPATH . 'wp-config.php' );
1861 + } else {
1862 + $files = get_included_files();
1863 + $configFound = false;
1864 + if ( is_array( $files ) ) {
1865 + foreach ( $files as $file ) {
1866 + if ( stristr( $file, 'wp-config.php' ) ) {
1867 + $configFound = true;
1868 + show_source( $file );
1869 + break;
1870 + }
1871 + }
1872 + }
1873 + if ( ! $configFound ) {
1874 + esc_html_e( 'wp-config.php not found', 'mainwp' );
1875 + }
1876 + }
1877 + ?>
1878 + </div>
1879 + <?php
1880 + /**
1881 + * Action: mainwp_after_wp_config_section
1882 + *
1883 + * Fires after the WP Config section.
1884 + *
1885 + * @since 4.1
1886 + */
1887 + do_action( 'mainwp_after_wp_config_section' );
1888 +
1889 + static::render_footer( 'WPConfig' );
1890 + }
1891 +
1892 + /**
1893 + * Renders action logs page.
1894 + *
1895 + * @uses \MainWP\Dashboard\MainWP_Logger
1896 + * @uses \MainWP\Dashboard\MainWP_Logger::clear_log()
1897 + * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1898 + */
1899 + public static function render_action_logs() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1900 + static::render_header( 'ActionLogs' );
1901 +
1902 + if ( isset( $_REQUEST['actionlogs_status'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1903 + $act_log = isset( $_REQUEST['actionlogs_status'] ) ? wp_unslash( $_REQUEST['actionlogs_status'] ) : MainWP_Logger::DISABLED; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1904 + $spec_log = 0;
1905 + if ( is_string( $act_log ) && false !== strpos( $act_log, 'specific_' ) ) {
1906 + $act_log = str_replace( 'specific_', '', $act_log );
1907 + $spec_log = 1;
1908 + }
1909 +
1910 + $act_log = intval( $act_log );
1911 +
1912 + MainWP_Utility::update_option( 'mainwp_specific_logs', $spec_log );
1913 +
1914 + MainWP_Logger::instance()->log_action( 'Action logs set to: ' . MainWP_Logger::instance()->get_log_text( $act_log ), ( $spec_log ? $act_log : MainWP_Logger::LOG ), 2, true );
1915 +
1916 + if ( MainWP_Logger::DISABLED === $act_log ) {
1917 + MainWP_Logger::instance()->set_log_priority( $act_log, $spec_log );
1918 + }
1919 +
1920 + MainWP_Utility::update_option( 'mainwp_actionlogs', $act_log );
1921 + MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
1922 + }
1923 +
1924 + if ( isset( $_REQUEST['actionlogs_clear'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1925 + $log_to_db = apply_filters( 'mainwp_logger_to_db', true );
1926 + if ( $log_to_db ) {
1927 + MainWP_Logger::instance()->clear_log_db();
1928 + } else {
1929 + MainWP_Logger::instance()->clear_log();
1930 + }
1931 + }
1932 +
1933 + $enabled = (int) MainWP_Logger::instance()->get_log_status();
1934 + $specific_default = array(
1935 + MainWP_Logger::UPDATE_CHECK_LOG_PRIORITY => esc_html__( 'Update Checking', 'mainwp' ),
1936 + MainWP_Logger::UPTIME_CHECK_LOG_PRIORITY => esc_html__( 'Uptime monitoring', 'mainwp' ),
1937 + MainWP_Logger::UPTIME_NOTICE_LOG_PRIORITY => esc_html__( 'Uptime notification', 'mainwp' ),
1938 + MainWP_Logger::LOGS_REGULAR_SCHEDULE => esc_html__( 'Regular Schedule', 'mainwp' ),
1939 + MainWP_Logger::DEBUG_UPDATES_SCHEDULE => esc_html__( 'Debug updates crons', 'mainwp' ),
1940 + MainWP_Logger::EXECUTION_TIME_LOG_PRIORITY => esc_html__( 'Execution time', 'mainwp' ),
1941 + MainWP_Logger::EXECUTION_SYNC_LOG_PRIORITY => esc_html__( 'Execution Sync', 'mainwp' ),
1942 + MainWP_Logger::EXECUTION_SYNC_DETAILS_LOG_PRIORITY => esc_html__( 'Execution Sync Details', 'mainwp' ),
1943 + MainWP_Logger::LOGS_AUTO_PURGE_LOG_PRIORITY => esc_html__( 'Auto Archive Network Activity', 'mainwp' ),
1944 + MainWP_Logger::CONNECT_LOG_PRIORITY => esc_html__( 'Dashboard Connect', 'mainwp' ),
1945 + MainWP_Logger::SITES_CHANGES_LOG_PRIORITY => esc_html__( 'Network Activity', 'mainwp' ),
1946 + MainWP_Logger::UNHOOKS_LOG_PRIORITY => esc_html__( 'Unhooks Info', 'mainwp' ),
1947 + MainWP_Logger::CACHE_METRICS_LOG_PRIORITY => esc_html__( 'Cache Metrics', 'mainwp' ),
1948 + MainWP_Logger::DB_QUERIES_LOG_PRIORITY => esc_html__( 'DB Queries', 'mainwp' ),
1949 + MainWP_Logger::WARM_CACHE_LOG_PRIORITY => esc_html__( 'Warm Cache', 'mainwp' ),
1950 + MainWP_Logger::EXTENSION_UPDATES_CHECK_LOG_PRIORITY => esc_html__( 'Extension Updates Check', 'mainwp' ),
1951 + MainWP_Logger::AUTO_UPDATES_LOG_PRIORITY => esc_html__( 'Auto Updates', 'mainwp' ),
1952 + );
1953 + $specific_logs = apply_filters( 'mainwp_specific_action_logs', $specific_default ); // deprecated since 4.3.1, use 'mainwp_log_specific_actions' instead.
1954 + $specific_logs = apply_filters( 'mainwp_log_specific_actions', $specific_logs );
1955 +
1956 + ?>
1957 + <div class="mainwp-actions-bar">
1958 + <div class="ui mini form two column stackable grid">
1959 + <div class="column">
1960 + <form method="POST" action="">
1961 + <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1962 + <?php // phpcs:disable WordPress.Security.EscapeOutput ?>
1963 + <select name="actionlogs_status" class="ui mini dropdown">
1964 + <option value="<?php echo MainWP_Logger::DISABLED; ?>" <?php echo MainWP_Logger::DISABLED === $enabled ? 'selected' : ''; ?>>
1965 + <?php esc_html_e( 'Disabled', 'mainwp' ); ?>
1966 + </option>
1967 + <option value="<?php echo MainWP_Logger::INFO; ?>" <?php echo MainWP_Logger::INFO === $enabled ? 'selected' : ''; ?>>
1968 + <?php esc_html_e( 'Info', 'mainwp' ); ?>
1969 + </option>
1970 + <option value="<?php echo MainWP_Logger::WARNING; ?>" <?php echo MainWP_Logger::WARNING === $enabled ? 'selected' : ''; ?>>
1971 + <?php esc_html_e( 'Warning', 'mainwp' ); ?>
1972 + </option>
1973 + <option value="<?php echo MainWP_Logger::DEBUG; ?>" <?php echo MainWP_Logger::DEBUG === $enabled ? 'selected' : ''; ?>>
1974 + <?php esc_html_e( 'Debug', 'mainwp' ); ?>
1975 + </option>
1976 + <?php
1977 + // phpcs:enable
1978 + if ( is_array( $specific_logs ) && ! empty( $specific_logs ) ) {
1979 + asort( $specific_logs );
1980 + foreach ( $specific_logs as $spec_log => $spec_title ) {
1981 + ?>
1982 + <option value="specific_<?php echo intval( $spec_log ); ?>" <?php echo (int) $spec_log === (int) $enabled ? 'selected' : ''; ?>>
1983 + <?php echo esc_html( $spec_title ); ?>
1984 + </option>
1985 + <?php
1986 + }
1987 + }
1988 + ?>
1989 + </select>
1990 + <input type="submit" class="ui green mini button" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>" />
1991 + <input type="submit" class="ui mini button" name="actionlogs_clear" value="<?php esc_attr_e( 'Delete Log', 'mainwp' ); ?>" />
1992 + </form>
1993 + </div>
1994 + <div class="column">
1995 +
1996 + </div>
1997 + </div>
1998 + </div>
1999 + <div class="ui padded segment">
2000 + <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-action-logs-info-message' ) ) : ?>
2001 + <div class="ui info message">
2002 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-action-logs-info-message"></i>
2003 + <div class="header"><?php echo esc_html__( 'Enable a specific logging system.', 'mainwp' ); ?></div>
2004 + <p><?php echo esc_html__( 'Each specific log type changes only the type of information logged. It does not change the log view.', 'mainwp' ); ?></p>
2005 + <p><?php echo esc_html__( 'After disabling the Action Log, logs will still be visible. To remove records, click the Delete Logs button.', 'mainwp' ); ?></p>
2006 + </div>
2007 + <?php endif; ?>
2008 + <?php
2009 + static::pre_load_logs_page();
2010 +
2011 + $log_to_db = apply_filters( 'mainwp_logger_to_db', true );
2012 + if ( $log_to_db ) {
2013 + return MainWP_Logger::instance()->show_log_db();
2014 + } else {
2015 + MainWP_Logger::instance()->show_log_file();
2016 + }
2017 + ?>
2018 + </div>
2019 + <?php
2020 + static::render_footer( 'ActionLogs' );
2021 + }
2022 +
2023 + /**
2024 + * Method pre_load_logs_page().
2025 + *
2026 + * @return void
2027 + */
2028 + public static function pre_load_logs_page() {
2029 + if ( MainWP_Logger::instance()->enabled_log_priority( MainWP_Logger::SITES_CHANGES_LOG_PRIORITY ) ) {
2030 + $stats = Log_DB_Helper::instance()->get_logs_db_stats();
2031 + MainWP_Logger::instance()->log_events( 'sites-changes', 'DB Info :: ' . print_r( $stats, true ) ); //phpcs:ignore --ok.
2032 + }
2033 + }
2034 +
2035 + /**
2036 + * Renders the Plugin Privacy page.
2037 + *
2038 + * @return void
2039 + */
2040 + public static function render_plugin_privacy_page() {
2041 +
2042 + static::render_header( 'PluginPrivacy' );
2043 + /**
2044 + * Action: mainwp_before_plugin_privacy_section
2045 + *
2046 + * Fires before the Plugin Privacy section.
2047 + *
2048 + * @since 4.2
2049 + */
2050 + do_action( 'mainwp_before_plugin_privacy_section' );
2051 + ?>
2052 + <div class="ui padded segment">
2053 + <div id="mainwp-plugin-privacy">
2054 + <h2 class="ui header">
2055 + <?php echo esc_html__( 'MainWP Dashboard Plugin Privacy Policy', 'mainwp' ); ?>
2056 + <div class="sub header"><em><?php echo esc_html__( 'Last updated: April 14, 2022', 'mainwp' ); ?></em></div>
2057 + </h2>
2058 + <p><?php echo esc_html__( 'We value your privacy very highly. Please read this Privacy Policy carefully before using the MainWP Dashboard Plugin ("Plugin") operated by Sick Marketing, LLC d/b/a MainWP, a Limited Liability Company formed in Nevada, United States ("us","we","our") as this Privacy Policy contains important information regarding your privacy.', 'mainwp' ); ?></p>
2059 + <p><?php echo esc_html__( 'Your access to and use of the Plugin is conditional upon your acceptance of and compliance with this Privacy Policy. This Privacy Policy applies to everyone accessing or using the Plugin.', 'mainwp' ); ?></p>
2060 + <p><?php echo esc_html__( 'By accessing or using the Plugin, you agree to be bound by this Privacy Policy. If you disagree with any part of this Privacy Policy, then you do not have our permission to access or use the Plugin.', 'mainwp' ); ?></p>
2061 + <h3 class="ui header"><?php echo esc_html__( 'What personal data we collect', 'mainwp' ); ?></h3>
2062 + <p><?php echo esc_html__( 'We do not collect, store, nor process any personal data through this Plugin.', 'mainwp' ); ?></p>
2063 + <h3 class="ui header"><?php echo esc_html__( 'Third-party extensions and integrations', 'mainwp' ); ?></h3>
2064 + <p><?php echo esc_html__( 'This Plugin may be used with extensions that are operated by parties other than us. We may also provide extensions that have integrations with third party services. We do not control such extensions and integrations and are not responsible for their contents or the privacy or other practices of such extensions or integrations. Further, it is up to you to take precautions to ensure that whatever extensions or integrations you use adequately protect your privacy. Please review the Privacy Policies of such extensions or integrations before using them.', 'mainwp' ); ?></p>
2065 + <div class="ui hidden divider"></div>
2066 + <div class="ui two columns stackable grid">
2067 + <div class="column">
2068 + <h3 class="ui header"><?php echo esc_html__( 'Our contact information', 'mainwp' ); ?></h3>
2069 + <p><?php echo esc_html__( 'If you have any questions regarding our privacy practices, please do not hesitate to contact us at the following:', 'mainwp' ); ?></p>
2070 + <div class="ui list">
2071 + <div class="item"><?php echo esc_html__( 'Sick Marketing, LLC d/b/a MainWP', 'mainwp' ); ?></div>
2072 + <div class="item"><?php echo esc_html__( '[email protected]', 'mainwp' ); ?></div>
2073 + <div class="item"><?php echo esc_html__( '4730 S. Fort Apache Road', 'mainwp' ); ?></div>
2074 + <div class="item"><?php echo esc_html__( 'Suite 300', 'mainwp' ); ?></div>
2075 + <div class="item"><?php echo esc_html__( 'PO Box 27740', 'mainwp' ); ?></div>
2076 + <div class="item"><?php echo esc_html__( 'Las Vegas, NV 89147-7947', 'mainwp' ); ?></div>
2077 + <div class="item"><?php echo esc_html__( 'United States', 'mainwp' ); ?></div>
2078 + </div>
2079 + </div>
2080 + <div class="column">
2081 + <h3 class="ui header"><?php echo esc_html__( 'Our representative\'s contact information', 'mainwp' ); ?></h3>
2082 + <p><?php echo esc_html__( 'If you are a resident of the European Union or the European Economic Area, you may also contact our representative at the following:', 'mainwp' ); ?></p>
2083 + <div class="item"><?php echo esc_html__( 'Ametros Ltd', 'mainwp' ); ?></div>
2084 + <div class="item"><?php echo esc_html__( 'Unit 3D', 'mainwp' ); ?></div>
2085 + <div class="item"><?php echo esc_html__( 'North Point House', 'mainwp' ); ?></div>
2086 + <div class="item"><?php echo esc_html__( 'North Point Business Park', 'mainwp' ); ?></div>
2087 + <div class="item"><?php echo esc_html__( 'New Mallow Road', 'mainwp' ); ?></div>
2088 + <div class="item"><?php echo esc_html__( 'Cork', 'mainwp' ); ?></div>
2089 + <div class="item"><?php echo esc_html__( 'Ireland', 'mainwp' ); ?></div>
2090 + <div class="ui hidden divider"></div>
2091 + <p><?php echo esc_html__( 'If you are a resident of the United Kingdom, you may contact our representative at the following:', 'mainwp' ); ?></p>
2092 + <div class="item"><?php echo esc_html__( 'Ametros Group Ltd', 'mainwp' ); ?></div>
2093 + <div class="item"><?php echo esc_html__( 'Lakeside Offices', 'mainwp' ); ?></div>
2094 + <div class="item"><?php echo esc_html__( 'Thorn Business Park', 'mainwp' ); ?></div>
2095 + <div class="item"><?php echo esc_html__( 'Hereford', 'mainwp' ); ?></div>
2096 + <div class="item"><?php echo esc_html__( 'Herefordshire', 'mainwp' ); ?></div>
2097 + <div class="item"><?php echo esc_html__( 'HR2 6JT', 'mainwp' ); ?></div>
2098 + <div class="item"><?php echo esc_html__( 'England', 'mainwp' ); ?></div>
2099 + </div>
2100 + </div>
2101 + <div class="ui divider"></div>
2102 + </div>
2103 + <a href="<?php echo esc_url( get_site_url() ) . '/wp-content/plugins/mainwp/privacy-policy.txt'; ?>" class="ui green basic button" target="_blank"><?php echo esc_html__( 'Download MainWP Dashboard Privacy Policy', 'mainwp' ); ?></a> <a href="<?php echo esc_url( get_site_url() ) . '/wp-content/plugins/mainwp/mainwp-child-privacy-policy.txt'; ?>" class="ui green basic button" target="_blank"><?php echo esc_html__( 'Download MainWP Child Privacy Policy', 'mainwp' ); ?></a>
2104 + </div>
2105 +
2106 + <?php
2107 + /**
2108 + * Action: mainwp_after_plugin_privacy_section
2109 + *
2110 + * Fires after the Plugin Privacy section.
2111 + *
2112 + * @since 4.2
2113 + */
2114 + do_action( 'mainwp_after_plugin_privacy_section' );
2115 +
2116 + static::render_footer( 'PluginPrivacy' );
2117 + }
2118 +
2119 + /**
2120 + * Renders .htaccess File page.
2121 + *
2122 + * @return void
2123 + */
2124 + public static function render_htaccess() {
2125 + if ( ! \mainwp_current_user_can( 'dashboard', 'see_server_information' ) ) {
2126 + \mainwp_do_not_have_permissions( '.htaccess', 'mainwp' );
2127 + return;
2128 + }
2129 + static::render_header( '.htaccess' );
2130 + /**
2131 + * Action: mainwp_before_htaccess_section
2132 + *
2133 + * Fires before the .htaccess file section.
2134 + *
2135 + * @since 4.1
2136 + */
2137 + do_action( 'mainwp_before_htaccess_section' );
2138 + ?>
2139 + <div id="mainwp-show-htaccess">
2140 + <?php
2141 + if ( false !== strpos( ini_get( 'disable_functions' ), 'show_source' ) ) {
2142 + esc_html_e( 'File content could not be displayed.', 'mainwp' );
2143 + echo '<br />';
2144 + esc_html_e( 'It appears that the show_source() PHP function has been disabled on the servre.', 'mainwp' );
2145 + echo '<br />';
2146 + esc_html_e( 'Please, contact your host support and have them enable the show_source() function for the proper functioning of this feature.', 'mainwp' );
2147 + } else {
2148 + show_source( ABSPATH . '.htaccess' );
2149 + }
2150 + ?>
2151 + </div>
2152 + <?php
2153 + /**
2154 + * Action: mainwp_after_htaccess_section
2155 + *
2156 + * Fires after the .htaccess file section.
2157 + *
2158 + * @since 4.1
2159 + */
2160 + do_action( 'mainwp_after_htaccess_section' );
2161 + static::render_footer( '.htaccess' );
2162 + }
2163 +
2164 + /**
2165 + * Checks for disable PHP Functions.
2166 + *
2167 + * @return void
2168 + */
2169 + public static function php_disabled_functions() {
2170 + $disabled_functions = ini_get( 'disable_functions' );
2171 + if ( '' !== $disabled_functions ) {
2172 + $arr = explode( ',', $disabled_functions );
2173 + sort( $arr );
2174 + $_count = count( $arr );
2175 + for ( $i = 0; $i < $_count; $i++ ) {
2176 + echo esc_html( $arr[ $i ] ) . ', ';
2177 + }
2178 + } else {
2179 + esc_html_e( 'No functions disabled.', 'mainwp' );
2180 + }
2181 + }
2182 +
2183 + /**
2184 + * Renders MainWP Settings 'Options'.
2185 + *
2186 + * @return void
2187 + *
2188 + * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::mainwp_options()
2189 + */
2190 + public static function display_mainwp_options() {
2191 + $options = MainWP_Server_Information_Handler::mainwp_options();
2192 +
2193 + $enable_individual_uptime_monitoring = false;
2194 + if ( get_option( 'mainwp_individual_uptime_monitoring_schedule_enabled' ) ) {
2195 + $enable_individual_uptime_monitoring = true;
2196 + }
2197 +
2198 + // phpcs:disable WordPress.Security.EscapeOutput
2199 + foreach ( $options as $option ) {
2200 + $addition_info = '';
2201 + if ( 'is_enable_automatic_check_uptime_monitoring' === $option['name'] && empty( $option['save_value'] ) && $enable_individual_uptime_monitoring ) { // global monitoring disabled.
2202 + $addition_info = '<br><em>' . esc_html__( 'Individual uptime monitoring is running', 'mainwp' ) . '</em>';
2203 + }
2204 + echo '<tr><td>' . $option['label'] . '</td><td>' . $option['value'] . $addition_info . '</td></tr>';
2205 + }
2206 + // phpcs:enable
2207 + }
2208 +
2209 + /**
2210 + * Render detected issues summary.
2211 + *
2212 + * @return void
2213 + */
2214 + private static function render_detected_issues_summary() {
2215 + $issues = MainWP_Server_Information_Handler::get_primary_issues();
2216 +
2217 + if ( empty( $issues ) ) {
2218 + ?>
2219 + <div class="ui positive message mainwp-system-report-issues-message">
2220 + <div class="header"><?php esc_html_e( 'No high-priority issues detected', 'mainwp' ); ?></div>
2221 + <p><?php esc_html_e( 'This summary only highlights the most common problems. Review the tables below for full context.', 'mainwp' ); ?></p>
2222 + </div>
2223 + <?php
2224 + return;
2225 + }
2226 +
2227 + $has_error = false;
2228 + foreach ( $issues as $issue ) {
2229 + if ( isset( $issue['severity'] ) && 'error' === $issue['severity'] ) {
2230 + $has_error = true;
2231 + break;
2232 + }
2233 + }
2234 + ?>
2235 + <div class="ui <?php echo $has_error ? 'negative' : 'warning'; ?> message mainwp-system-report-issues-message">
2236 + <div class="header"><?php esc_html_e( 'Detected Issues', 'mainwp' ); ?></div>
2237 + <div class="ui list">
2238 + <?php foreach ( $issues as $issue ) : ?>
2239 + <div class="item">
2240 + <div class="content">
2241 + <div style="display:flex;align-items:center;gap:0.5rem;flex-wrap:wrap;">
2242 + <?php echo static::get_report_status_html( isset( $issue['severity'] ) ? $issue['severity'] : '' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>
2243 + <?php if ( ! empty( $issue['anchor'] ) ) : ?>
2244 + <a href="#<?php echo esc_attr( $issue['anchor'] ); ?>"><span style="font-weight:600;"><?php echo esc_html( $issue['title'] ); ?></span></a>
2245 + <?php else : ?>
2246 + <span style="font-weight:600;"><?php echo esc_html( $issue['title'] ); ?></span>
2247 + <?php endif; ?>
2248 + <?php if ( ! empty( $issue['detail_html'] ) ) : ?>
2249 + <span><?php echo wp_kses_post( $issue['detail_html'] ); ?></span>
2250 + <?php elseif ( ! empty( $issue['detail'] ) ) : ?>
2251 + <span><?php echo esc_html( $issue['detail'] ); ?></span>
2252 + <?php endif; ?>
2253 + <?php if ( ! empty( $issue['kb_url'] ) ) : ?>
2254 + <a href="<?php echo esc_url( $issue['kb_url'] ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Help document', 'mainwp' ); ?></a>
2255 + <i class="external alternate icon"></i>
2256 + <?php endif; ?>
2257 + </div>
2258 + </div>
2259 + </div>
2260 + <?php endforeach; ?>
2261 + </div>
2262 + </div>
2263 + <?php
2264 + }
2265 +
2266 + /**
2267 + * Get export text attribute HTML.
2268 + *
2269 + * @param string $text English export text.
2270 + *
2271 + * @return string
2272 + */
2273 + private static function get_export_text_attr( $text ) {
2274 + return '' !== (string) $text ? ' data-export-text="' . esc_attr( $text ) . '"' : '';
2275 + }
2276 +
2277 + /**
2278 + * Render generic report table.
2279 + *
2280 + * @param string $table_id Table id.
2281 + * @param string $title Table title.
2282 + * @param array $rows Table rows.
2283 + * @param string $export_title English export title.
2284 + *
2285 + * @return void
2286 + */
2287 + private static function render_report_section_table( $table_id, $title, $rows, $export_title = '' ) {
2288 + if ( empty( $rows ) || ! is_array( $rows ) ) {
2289 + return;
2290 + }
2291 + ?>
2292 + <table id="<?php echo esc_attr( $table_id ); ?>" class="ui unstackable table mainwp-system-report-table mainwp-system-info-table">
2293 + <thead>
2294 + <tr>
2295 + <th scope="col" class="seven wide"<?php echo self::get_export_text_attr( $export_title ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php echo esc_html( $title ); ?></th>
2296 + <th scope="col" class="seven wide"<?php echo self::get_export_text_attr( 'Detected Value' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php esc_html_e( 'Detected Value', 'mainwp' ); ?></th>
2297 + <th scope="col" class="two wide right aligned"></th>
2298 + </tr>
2299 + </thead>
2300 + <tbody>
2301 + <?php foreach ( $rows as $row ) : ?>
2302 + <?php static::render_report_row( $row ); ?>
2303 + <?php endforeach; ?>
2304 + </tbody>
2305 + </table>
2306 + <?php
2307 + }
2308 +
2309 + /**
2310 + * Render a generic report row.
2311 + *
2312 + * @param array $row Row data.
2313 + *
2314 + * @return void
2315 + */
2316 + private static function render_report_row( $row ) {
2317 + $visibility = isset( $row['visibility'] ) ? $row['visibility'] : 'community_safe';
2318 + $community_value = isset( $row['community_value'] ) ? $row['community_value'] : null;
2319 + $export_label = isset( $row['export_label'] ) ? $row['export_label'] : '';
2320 + $row_classes = array();
2321 +
2322 + if ( 'full_only' === $visibility ) {
2323 + $row_classes[] = 'mwp-not-generate-row';
2324 + }
2325 +
2326 + $value_attr = '';
2327 + if ( 'community_masked' === $visibility && null !== $community_value ) {
2328 + $value_attr = ' data-community-value="' . esc_attr( $community_value ) . '"';
2329 + }
2330 + ?>
2331 + <tr class="<?php echo esc_attr( implode( ' ', $row_classes ) ); ?>">
2332 + <td<?php echo self::get_export_text_attr( $export_label ); // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php echo esc_html( isset( $row['label'] ) ? $row['label'] : '' ); ?></td>
2333 + <td<?php echo $value_attr; //phpcs:ignore -- escaped. ?>><?php echo esc_html( isset( $row['value'] ) ? $row['value'] : '' ); ?></td>
2334 + <td class="right aligned"><?php echo static::get_report_status_html( isset( $row['status'] ) ? $row['status'] : '' ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
2335 + </tr>
2336 + <?php
2337 + }
2338 +
2339 + /**
2340 + * Get report status html.
2341 + *
2342 + * @param string $status Status.
2343 + *
2344 + * @return string
2345 + */
2346 + private static function get_report_status_html( $status ) {
2347 + switch ( $status ) {
2348 + case 'pass':
2349 + return static::get_pass_html();
2350 + case 'error':
2351 + return static::get_warning_html( static::ERROR );
2352 + case 'warning':
2353 + return static::get_warning_html( static::WARNING );
2354 + default:
2355 + return '';
2356 + }
2357 + }
2358 +
2359 + /**
2360 + * Renders PHP Warning HTML.
2361 + *
2362 + * @param int $errorType Global variable static::WARNING = 1.
2363 + * @param bool $ech echo or return.
2364 + *
2365 + * @return string PHP Warning html.
2366 + */
2367 + private static function get_warning_html( $errorType = self::WARNING, $ech = false ) {
2368 + $msg = '';
2369 + if ( static::WARNING === $errorType ) {
2370 + $msg = '<i class="large yellow exclamation icon"></i><span style="display:none" data-export-text="Warning">' . esc_html__( 'Warning', 'mainwp' ) . '</span>';
2371 + } else {
2372 + $msg = '<i class="large red times icon"></i><span style="display:none" data-export-text="Fail">' . esc_html__( 'Fail', 'mainwp' ) . '</span>';
2373 + }
2374 +
2375 + if ( $ech ) {
2376 + echo $msg; //phpcs:ignore -- escaped.
2377 + } else {
2378 + return $msg;
2379 + }
2380 + }
2381 +
2382 + /**
2383 + * Renders PHP Pass HTML.
2384 + *
2385 + * @param bool $ech echo or return.
2386 + *
2387 + * @return string PHP Pass html.
2388 + */
2389 + private static function get_pass_html( $ech = false ) {
2390 + $msg = '<i class="large green check icon"></i><span style="display:none" data-export-text="Pass">' . esc_html__( 'Pass', 'mainwp' ) . '</span>';
2391 + if ( $ech ) {
2392 + echo $msg; //phpcs:ignore -- escaped.
2393 + } else {
2394 + return $msg;
2395 + }
2396 + }
1893 2397 }