PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
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
mainwp / pages / page-mainwp-server-information.php

page-mainwp-server-information.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.2, at pages/page-mainwp-server-information.php

2,398 lines 116.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Info Page.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
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
18 // phpcs:disable Generic.Metrics.CyclomaticComplexity -- complexity.
19 /**
20 * Class MainWP_Server_Information
21 */
22 class MainWP_Server_Information { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 const WARNING = 1;
25 const ERROR = 2;
26
27 /**
28 * The Info page sub-pages.
29 *
30 * @static
31 * @var array Sub pages.
32 */
33 public static $subPages;
34
35 /**
36 * Get Class Name
37 *
38 * @return string __CLASS__
39 */
40 public static function get_class_name() {
41 return __CLASS__;
42 }
43
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 }
53
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 );
63
64 return is_array( static::$subPages ) ? static::$subPages : array();
65 }
66
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 );
176
177 $visible_pages = array();
178
179 foreach ( $pages as $page ) {
180 if ( 'ServerInformation' !== $page['slug'] && MainWP_Menu::is_disable_menu_item( 3, $page['slug'] ) ) {
181 continue;
182 }
183
184 if ( isset( $page['condition'] ) && is_callable( $page['condition'] ) && ! call_user_func( $page['condition'] ) ) {
185 continue;
186 }
187
188 $visible_pages[] = $page;
189 }
190
191 return $visible_pages;
192 }
193
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 ) );
203
204 if ( empty( $href ) ) {
205 return '';
206 }
207
208 if ( preg_match( '/^https?:\/\//i', $href ) ) {
209 return $href;
210 }
211
212 return admin_url( ltrim( $href, '/' ) );
213 }
214
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();
223
224 foreach ( static::get_navigation_items( 'left_menu_core' ) as $item ) {
225 if ( empty( $item['show_in_left_menu'] ) ) {
226 continue;
227 }
228
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 }
238
239 MainWP_Menu::init_subpages_left_menu( static::get_subpages(), $menu_items, 'ServerInformation', 'Server' );
240
241 $items = array();
242
243 foreach ( $menu_items as $menu_item ) {
244 if ( empty( $menu_item['slug'] ) || empty( $menu_item['title'] ) || empty( $menu_item['href'] ) ) {
245 continue;
246 }
247
248 if ( isset( $core_slugs[ $menu_item['slug'] ] ) ) {
249 continue;
250 }
251
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 }
259
260 $active_slug = 0 === strpos( $menu_item['slug'], 'Server' ) ? substr( $menu_item['slug'], strlen( 'Server' ) ) : $menu_item['slug'];
261
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 );
275
276 if ( isset( $menu_item['item_slug'] ) ) {
277 $item['item_slug'] = $menu_item['item_slug'];
278 }
279
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 }
284
285 $items[] = $item;
286 }
287
288 return $items;
289 }
290
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();
298
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 }
314
315 if ( 'left_menu_core' === $context ) {
316 return $items;
317 }
318
319 if ( 'command_palette' === $context ) {
320 return array_merge( $items, static::get_filtered_subpage_navigation_items() );
321 }
322
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 }
327
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 );
341
342 if ( isset( $subPage['item_slug'] ) ) {
343 $item['item_slug'] = $subPage['item_slug'];
344 }
345
346 $items[] = $item;
347 }
348
349 return $items;
350 }
351
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();
359
360 foreach ( static::get_navigation_items( 'command_palette' ) as $item ) {
361 if ( empty( $item['show_in_palette'] ) ) {
362 continue;
363 }
364
365 $items[] = array(
366 'slug' => $item['slug'],
367 'href' => $item['href'],
368 'path_titles' => $item['palette_titles'],
369 );
370 }
371
372 return $items;
373 }
374
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.
384
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' ) );
387
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 }
398
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 }
403
404 add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'Server' . $subPage['slug'], $subPage['callback'] );
405 }
406 }
407
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 }
429
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 );
451
452 $init_sub_subleftmenu = array();
453
454 foreach ( static::get_navigation_items( 'left_menu_core' ) as $item ) {
455 if ( empty( $item['show_in_left_menu'] ) ) {
456 continue;
457 }
458
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 }
467
468 if ( empty( $subPages ) ) {
469 $subPages = static::get_subpages();
470 }
471
472 MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'ServerInformation', 'Server' );
473
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 }
482
483 MainWP_Menu::add_left_menu( $item, 2 );
484 }
485 }
486
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 );
501
502 MainWP_UI::render_top_header( $params );
503
504 $renderItems = array();
505
506 foreach ( static::get_navigation_items() as $item ) {
507 if ( empty( $item['show_in_header_nav'] ) ) {
508 continue;
509 }
510
511 $renderItems[] = array(
512 'title' => $item['title'],
513 'href' => $item['href'],
514 'active' => in_array( $shownPage, $item['active_keys'], true ),
515 );
516 }
517
518 if ( isset( $_GET['page'] ) && 'PluginPrivacy' !== $_GET['page'] ) { //phpcs:ignore -- monce safe.
519 MainWP_UI::render_page_navigation( $renderItems );
520 }
521
522 static::render_actions_bar();
523
524 echo '<div>';
525 }
526
527 /**
528 * Renders Server Information footer.
529 */
530 public static function render_footer() {
531 echo '</div>';
532 }
533
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 }
557
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( '' );
604
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 }
620
621 // Detect issues before rendering.
622 $datatable_rows = MainWP_Server_Information_Handler::get_database_report_rows();
623
624 static::render_detected_issues_summary();
625 ?>
626 <style type="text/css">
627 #mainwp-system-report-page {
628 padding-top: 1rem !important;
629 }
630
631 #mainwp-system-report-page .mainwp-system-report-table {
632 table-layout: fixed;
633 width: 100%;
634 }
635
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 }
640
641 #mainwp-system-report-page .mainwp-system-info-table {
642 margin: 0 0 1rem 0 !important;
643 }
644
645 #mainwp-system-report-page .dt-container,
646 #mainwp-system-report-page .dataTables_wrapper {
647 margin: 0 0 1rem 0;
648 }
649
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>
668
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>
682
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>
696
697 <?php self::render_report_section_table( 'mainwp-system-report-mainwp-database-table', __( 'Database', 'mainwp' ), $datatable_rows, 'Database' ); ?>
698
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' ); ?>
700
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' ); ?>
702
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>
714
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' ); ?>
716
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' ); ?>
718
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' ); ?>
720
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' ); ?>
722
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' ); ?>
724
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' ); ?>
726
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' ); ?>
728
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' ); ?>
730
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' ); ?>
732
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' ); ?>
734
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' ); ?>
736
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>
750
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>
763
764 <div id="download-server-information" style="opacity:0">
765 <textarea readonly="readonly" contenteditable="true" wrap="off"></textarea>
766 </div>
767
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 } ) );
796
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>
806
807 <?php
808
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' );
817
818 static::render_footer( '' );
819 }
820
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 }
839
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 );
874
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
884
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 }
947
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 }
970
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 }
1064
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 }
1080
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 }
1115
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 }
1137
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 );
1167
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 }
1173
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 );
1184
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 }
1217
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 }
1234
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 }
1248
1249 static::render_header( 'ServerInformationCron' );
1250
1251 $local_timestamp = MainWP_Utility::get_timestamp();
1252
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 );
1258
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 );
1264
1265 $cron_jobs['Child site uptime monitoring'] = array( 'mainwp_uptime_lasttime_check', 'mainwp_cronuptimemonitoringcheck_action', esc_html__( 'Once every minute', 'mainwp' ), 'minutely' );
1266
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 }
2397 }
2398