2013-07-18 14:22:05 +00:00
< ? php
/**
2015-11-03 13:53:50 +00:00
* Debug / Status page
2013-07-18 14:22:05 +00:00
*
2020-08-05 16:36:24 +00:00
* @ package WooCommerce\Admin\System Status
2018-05-01 15:37:44 +00:00
* @ version 2.2 . 0
2013-07-18 14:22:05 +00:00
*/
2020-01-29 05:21:29 +00:00
use Automattic\Jetpack\Constants ;
2018-05-01 15:37:44 +00:00
defined ( 'ABSPATH' ) || exit ;
2013-07-18 14:22:05 +00:00
/**
2015-11-03 12:28:01 +00:00
* WC_Admin_Status Class .
2013-07-18 14:22:05 +00:00
*/
class WC_Admin_Status {
/**
* Handles output of the reports page in admin .
*/
2014-06-04 10:16:19 +00:00
public static function output () {
2018-03-05 18:59:17 +00:00
include_once dirname ( __FILE__ ) . '/views/html-admin-page-status.php' ;
2013-07-18 14:22:05 +00:00
}
/**
2015-11-03 12:28:01 +00:00
* Handles output of report .
2013-07-18 14:22:05 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function status_report () {
2018-03-05 18:59:17 +00:00
include_once dirname ( __FILE__ ) . '/views/html-admin-page-status-report.php' ;
2013-07-18 14:22:05 +00:00
}
/**
2015-11-03 12:28:01 +00:00
* Handles output of tools .
2013-07-18 14:22:05 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function status_tools () {
2019-06-21 12:59:40 +00:00
if ( ! class_exists ( 'WC_REST_System_Status_Tools_Controller' ) ) {
2019-02-04 16:04:25 +00:00
wp_die ( 'Cannot load the REST API to access WC_REST_System_Status_Tools_Controller.' );
}
2014-06-04 10:16:19 +00:00
$tools = self :: get_tools ();
2013-07-18 14:22:05 +00:00
2018-05-01 15:37:44 +00:00
if ( ! empty ( $_GET [ 'action' ] ) && ! empty ( $_REQUEST [ '_wpnonce' ] ) && wp_verify_nonce ( wp_unslash ( $_REQUEST [ '_wpnonce' ] ), 'debug_action' ) ) { // WPCS: input var ok, sanitization ok.
2018-03-05 18:59:17 +00:00
$tools_controller = new WC_REST_System_Status_Tools_Controller ();
2018-05-01 15:37:44 +00:00
$action = wc_clean ( wp_unslash ( $_GET [ 'action' ] ) ); // WPCS: input var ok.
2016-08-09 17:14:47 +00:00
if ( array_key_exists ( $action , $tools ) ) {
$response = $tools_controller -> execute_tool ( $action );
2018-09-05 11:34:52 +00:00
$tool = $tools [ $action ];
$tool = array (
'id' => $action ,
'name' => $tool [ 'name' ],
'action' => $tool [ 'button' ],
'description' => $tool [ 'desc' ],
);
$tool = array_merge ( $tool , $response );
/**
* Fires after a WooCommerce system status tool has been executed .
*
* @ param array $tool Details about the tool that has been executed .
*/
do_action ( 'woocommerce_system_status_tool_executed' , $tool );
2016-08-09 17:14:47 +00:00
} else {
2018-03-05 18:59:17 +00:00
$response = array (
'success' => false ,
'message' => __ ( 'Tool does not exist.' , 'woocommerce' ),
);
2016-08-09 17:14:47 +00:00
}
2013-07-18 14:22:05 +00:00
2016-08-05 21:22:34 +00:00
if ( $response [ 'success' ] ) {
2016-08-09 17:14:47 +00:00
echo '<div class="updated inline"><p>' . esc_html ( $response [ 'message' ] ) . '</p></div>' ;
2016-08-05 21:22:34 +00:00
} else {
2016-08-09 17:14:47 +00:00
echo '<div class="error inline"><p>' . esc_html ( $response [ 'message' ] ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
}
}
2014-05-28 13:46:11 +00:00
2018-05-01 15:37:44 +00:00
// Display message if settings settings have been saved.
if ( isset ( $_REQUEST [ 'settings-updated' ] ) ) { // WPCS: input var ok.
echo '<div class="updated inline"><p>' . esc_html__ ( 'Your changes have been saved.' , 'woocommerce' ) . '</p></div>' ;
2013-11-14 19:31:08 +00:00
}
2013-07-18 14:22:05 +00:00
2018-03-05 18:59:17 +00:00
include_once dirname ( __FILE__ ) . '/views/html-admin-page-status-tools.php' ;
2013-07-18 14:22:05 +00:00
}
/**
2015-11-03 12:28:01 +00:00
* Get tools .
2018-03-05 18:59:17 +00:00
*
2013-07-18 14:22:05 +00:00
* @ return array of tools
*/
2014-06-04 10:16:19 +00:00
public static function get_tools () {
2018-03-05 18:59:17 +00:00
$tools_controller = new WC_REST_System_Status_Tools_Controller ();
2016-08-05 21:22:34 +00:00
return $tools_controller -> get_tools ();
2013-07-18 14:22:05 +00:00
}
2014-05-28 10:12:35 +00:00
/**
2015-11-03 12:28:01 +00:00
* Show the logs page .
2014-05-28 10:12:35 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function status_logs () {
2020-01-29 05:21:29 +00:00
$log_handler = Constants :: get_constant ( 'WC_LOG_HANDLER' );
if ( 'WC_Log_Handler_DB' === $log_handler ) {
2016-12-03 17:23:52 +00:00
self :: status_logs_db ();
} else {
self :: status_logs_file ();
}
}
/**
* Show the log page contents for file log handler .
*/
public static function status_logs_file () {
2014-06-04 10:16:19 +00:00
$logs = self :: scan_log_files ();
2014-11-30 06:52:32 +00:00
2018-05-01 15:37:44 +00:00
if ( ! empty ( $_REQUEST [ 'log_file' ] ) && isset ( $logs [ sanitize_title ( wp_unslash ( $_REQUEST [ 'log_file' ] ) ) ] ) ) { // WPCS: input var ok, CSRF ok.
$viewed_log = $logs [ sanitize_title ( wp_unslash ( $_REQUEST [ 'log_file' ] ) ) ]; // WPCS: input var ok, CSRF ok.
2015-04-01 13:33:56 +00:00
} elseif ( ! empty ( $logs ) ) {
2014-05-28 10:12:35 +00:00
$viewed_log = current ( $logs );
}
2014-11-30 06:52:32 +00:00
2016-07-05 00:10:17 +00:00
$handle = ! empty ( $viewed_log ) ? self :: get_log_file_handle ( $viewed_log ) : '' ;
2018-05-01 15:37:44 +00:00
if ( ! empty ( $_REQUEST [ 'handle' ] ) ) { // WPCS: input var ok, CSRF ok.
2016-07-05 00:10:17 +00:00
self :: remove_log ();
}
2018-03-05 18:59:17 +00:00
include_once 'views/html-admin-page-status-logs.php' ;
2014-05-28 10:12:35 +00:00
}
2016-11-20 17:56:12 +00:00
/**
2016-12-03 17:23:52 +00:00
* Show the log page contents for db log handler .
2016-11-20 17:56:12 +00:00
*/
public static function status_logs_db () {
2018-05-01 15:37:44 +00:00
if ( ! empty ( $_REQUEST [ 'flush-logs' ] ) ) { // WPCS: input var ok, CSRF ok.
2016-11-26 19:05:59 +00:00
self :: flush_db_logs ();
}
2016-12-15 21:03:12 +00:00
2018-05-01 15:37:44 +00:00
if ( isset ( $_REQUEST [ 'action' ] ) && isset ( $_REQUEST [ 'log' ] ) ) { // WPCS: input var ok, CSRF ok.
2016-12-15 21:03:12 +00:00
self :: log_table_bulk_actions ();
}
2016-11-20 17:56:12 +00:00
$log_table_list = new WC_Admin_Log_Table_List ();
$log_table_list -> prepare_items ();
2018-03-05 18:59:17 +00:00
include_once 'views/html-admin-page-status-logs-db.php' ;
2016-11-20 17:56:12 +00:00
}
2014-02-11 13:33:56 +00:00
/**
2015-11-03 12:28:01 +00:00
* Retrieve metadata from a file . Based on WP Core ' s get_file_data function .
2018-03-05 18:59:17 +00:00
*
2015-03-07 03:16:08 +00:00
* @ since 2.1 . 1
2018-05-01 15:37:44 +00:00
* @ param string $file Path to the file .
2014-09-07 23:37:55 +00:00
* @ return string
2014-02-11 13:33:56 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function get_file_version ( $file ) {
2014-11-30 06:52:32 +00:00
2018-05-01 15:37:44 +00:00
// Avoid notices if file does not exist.
2014-10-28 00:21:33 +00:00
if ( ! file_exists ( $file ) ) {
return '' ;
}
2014-02-11 13:33:56 +00:00
// We don't need to write to the file, so just open for reading.
2018-05-01 15:37:44 +00:00
$fp = fopen ( $file , 'r' ); // @codingStandardsIgnoreLine.
2014-02-11 13:33:56 +00:00
// Pull only the first 8kiB of the file in.
2018-05-01 15:37:44 +00:00
$file_data = fread ( $fp , 8192 ); // @codingStandardsIgnoreLine.
2014-02-11 13:33:56 +00:00
// PHP will close file handle, but we are good citizens.
2018-05-01 15:37:44 +00:00
fclose ( $fp ); // @codingStandardsIgnoreLine.
2014-02-11 13:33:56 +00:00
// Make sure we catch CR-only line endings.
$file_data = str_replace ( " \r " , " \n " , $file_data );
$version = '' ;
2017-03-07 20:24:24 +00:00
if ( preg_match ( '/^[ \t\/*#@]*' . preg_quote ( '@version' , '/' ) . '(.*)$/mi' , $file_data , $match ) && $match [ 1 ] ) {
2014-02-11 13:33:56 +00:00
$version = _cleanup_header_comment ( $match [ 1 ] );
2017-03-07 20:24:24 +00:00
}
2014-02-11 13:33:56 +00:00
2018-03-05 18:59:17 +00:00
return $version ;
2014-02-11 13:33:56 +00:00
}
2014-05-28 13:46:11 +00:00
2016-07-05 00:10:17 +00:00
/**
* Return the log file handle .
*
2018-05-01 15:37:44 +00:00
* @ param string $filename Filename to get the handle for .
2016-07-05 00:10:17 +00:00
* @ return string
*/
public static function get_log_file_handle ( $filename ) {
2018-07-09 11:01:23 +00:00
return substr ( $filename , 0 , strlen ( $filename ) > 48 ? strlen ( $filename ) - 48 : strlen ( $filename ) - 4 );
2016-07-05 00:10:17 +00:00
}
2013-07-18 14:22:05 +00:00
/**
2015-11-03 12:28:01 +00:00
* Scan the template files .
2018-03-05 18:59:17 +00:00
*
2018-05-01 15:37:44 +00:00
* @ param string $template_path Path to the template directory .
2014-06-04 17:25:49 +00:00
* @ return array
2013-07-18 14:22:05 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function scan_template_files ( $template_path ) {
2018-05-01 15:37:44 +00:00
$files = @ scandir ( $template_path ); // @codingStandardsIgnoreLine.
2015-04-01 13:33:56 +00:00
$result = array ();
2014-11-30 06:52:32 +00:00
2015-04-01 13:33:56 +00:00
if ( ! empty ( $files ) ) {
2014-11-30 06:52:32 +00:00
2013-07-18 14:22:05 +00:00
foreach ( $files as $key => $value ) {
2014-11-30 06:52:32 +00:00
2018-05-01 15:37:44 +00:00
if ( ! in_array ( $value , array ( '.' , '..' ), true ) ) {
2014-11-30 06:52:32 +00:00
2013-07-18 14:22:05 +00:00
if ( is_dir ( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
2014-06-04 10:16:19 +00:00
$sub_files = self :: scan_template_files ( $template_path . DIRECTORY_SEPARATOR . $value );
2013-07-18 14:22:05 +00:00
foreach ( $sub_files as $sub_file ) {
$result [] = $value . DIRECTORY_SEPARATOR . $sub_file ;
}
} else {
$result [] = $value ;
}
}
}
}
return $result ;
}
2014-05-28 10:12:35 +00:00
/**
2015-11-03 12:28:01 +00:00
* Scan the log files .
2018-03-05 18:59:17 +00:00
*
2014-06-04 17:25:49 +00:00
* @ return array
2014-05-28 10:12:35 +00:00
*/
2014-06-04 10:16:19 +00:00
public static function scan_log_files () {
2018-05-01 15:37:44 +00:00
return WC_Log_Handler_File :: get_log_files ();
2014-05-28 10:12:35 +00:00
}
2015-11-02 10:01:42 +00:00
/**
2015-11-03 12:28:01 +00:00
* Get latest version of a theme by slug .
2018-03-05 18:59:17 +00:00
*
2016-02-05 19:48:45 +00:00
* @ param object $theme WP_Theme object .
* @ return string Version number if found .
2015-11-02 10:01:42 +00:00
*/
public static function get_latest_theme_version ( $theme ) {
2018-03-05 18:59:17 +00:00
include_once ABSPATH . 'wp-admin/includes/theme.php' ;
$api = themes_api (
'theme_information' ,
array (
'slug' => $theme -> get_stylesheet (),
'fields' => array (
'sections' => false ,
'tags' => false ,
),
)
);
2015-11-02 10:01:42 +00:00
$update_theme_version = 0 ;
2016-02-05 19:48:45 +00:00
// Check .org for updates.
if ( is_object ( $api ) && ! is_wp_error ( $api ) ) {
2015-11-02 10:01:42 +00:00
$update_theme_version = $api -> version ;
2018-03-05 18:59:17 +00:00
} elseif ( strstr ( $theme -> { 'Author URI' }, 'woothemes' ) ) { // Check WooThemes Theme Version.
2018-05-01 15:37:44 +00:00
$theme_dir = substr ( strtolower ( str_replace ( ' ' , '' , $theme -> Name ) ), 0 , 45 ); // @codingStandardsIgnoreLine.
$theme_version_data = get_transient ( $theme_dir . '_version_data' );
2015-11-02 10:01:42 +00:00
2018-05-01 15:37:44 +00:00
if ( false === $theme_version_data ) {
2015-11-02 10:01:42 +00:00
$theme_changelog = wp_safe_remote_get ( 'http://dzv365zjfbd8v.cloudfront.net/changelogs/' . $theme_dir . '/changelog.txt' );
2018-03-05 18:59:17 +00:00
$cl_lines = explode ( " \n " , wp_remote_retrieve_body ( $theme_changelog ) );
2015-11-02 10:01:42 +00:00
if ( ! empty ( $cl_lines ) ) {
foreach ( $cl_lines as $line_num => $cl_line ) {
if ( preg_match ( '/^[0-9]/' , $cl_line ) ) {
2018-03-05 18:59:17 +00:00
$theme_date = str_replace ( '.' , '-' , trim ( substr ( $cl_line , 0 , strpos ( $cl_line , '-' ) ) ) );
$theme_version = preg_replace ( '~[^0-9,.]~' , '' , stristr ( $cl_line , 'version' ) );
$theme_update = trim ( str_replace ( '*' , '' , $cl_lines [ $line_num + 1 ] ) );
$theme_version_data = array (
'date' => $theme_date ,
'version' => $theme_version ,
'update' => $theme_update ,
'changelog' => $theme_changelog ,
);
set_transient ( $theme_dir . '_version_data' , $theme_version_data , DAY_IN_SECONDS );
2015-11-02 10:01:42 +00:00
break ;
}
}
}
}
if ( ! empty ( $theme_version_data [ 'version' ] ) ) {
$update_theme_version = $theme_version_data [ 'version' ];
}
}
return $update_theme_version ;
}
2016-07-05 00:10:17 +00:00
/**
* Remove / delete the chosen file .
*/
2016-08-02 13:42:27 +00:00
public static function remove_log () {
2018-05-01 15:37:44 +00:00
if ( empty ( $_REQUEST [ '_wpnonce' ] ) || ! wp_verify_nonce ( wp_unslash ( $_REQUEST [ '_wpnonce' ] ), 'remove_log' ) ) { // WPCS: input var ok, sanitization ok.
wp_die ( esc_html__ ( 'Action failed. Please refresh the page and retry.' , 'woocommerce' ) );
2016-07-05 00:10:17 +00:00
}
2018-05-01 15:37:44 +00:00
if ( ! empty ( $_REQUEST [ 'handle' ] ) ) { // WPCS: input var ok.
2016-11-19 17:10:55 +00:00
$log_handler = new WC_Log_Handler_File ();
2018-05-01 15:37:44 +00:00
$log_handler -> remove ( wp_unslash ( $_REQUEST [ 'handle' ] ) ); // WPCS: input var ok, sanitization ok.
2016-07-05 00:10:17 +00:00
}
wp_safe_redirect ( esc_url_raw ( admin_url ( 'admin.php?page=wc-status&tab=logs' ) ) );
exit ();
}
2016-11-26 19:05:59 +00:00
/**
* Clear DB log table .
*
2017-03-15 16:36:53 +00:00
* @ since 3.0 . 0
2016-11-26 19:05:59 +00:00
*/
2016-12-15 21:03:12 +00:00
private static function flush_db_logs () {
2018-05-01 15:37:44 +00:00
if ( empty ( $_REQUEST [ '_wpnonce' ] ) || ! wp_verify_nonce ( $_REQUEST [ '_wpnonce' ], 'woocommerce-status-logs' ) ) { // WPCS: input var ok, sanitization ok.
wp_die ( esc_html__ ( 'Action failed. Please refresh the page and retry.' , 'woocommerce' ) );
2016-11-26 19:05:59 +00:00
}
2016-12-15 21:03:12 +00:00
WC_Log_Handler_DB :: flush ();
2016-12-03 21:26:36 +00:00
wp_safe_redirect ( esc_url_raw ( admin_url ( 'admin.php?page=wc-status&tab=logs' ) ) );
2016-11-26 19:05:59 +00:00
exit ();
}
2016-12-15 21:03:12 +00:00
/**
2016-12-18 20:02:20 +00:00
* Bulk DB log table actions .
2016-12-15 21:03:12 +00:00
*
2017-03-15 16:36:53 +00:00
* @ since 3.0 . 0
2016-12-15 21:03:12 +00:00
*/
private static function log_table_bulk_actions () {
2018-05-01 15:37:44 +00:00
if ( empty ( $_REQUEST [ '_wpnonce' ] ) || ! wp_verify_nonce ( $_REQUEST [ '_wpnonce' ], 'woocommerce-status-logs' ) ) { // WPCS: input var ok, sanitization ok.
wp_die ( esc_html__ ( 'Action failed. Please refresh the page and retry.' , 'woocommerce' ) );
2016-12-15 21:03:12 +00:00
}
2018-05-01 15:37:44 +00:00
$log_ids = array_map ( 'absint' , ( array ) isset ( $_REQUEST [ 'log' ] ) ? wp_unslash ( $_REQUEST [ 'log' ] ) : array () ); // WPCS: input var ok, sanitization ok.
2016-12-15 21:03:12 +00:00
2018-05-01 15:37:44 +00:00
if ( ( isset ( $_REQUEST [ 'action' ] ) && 'delete' === $_REQUEST [ 'action' ] ) || ( isset ( $_REQUEST [ 'action2' ] ) && 'delete' === $_REQUEST [ 'action2' ] ) ) { // WPCS: input var ok, sanitization ok.
2016-12-15 21:03:12 +00:00
WC_Log_Handler_DB :: delete ( $log_ids );
wp_safe_redirect ( esc_url_raw ( admin_url ( 'admin.php?page=wc-status&tab=logs' ) ) );
exit ();
}
}
2020-03-12 13:37:55 +00:00
2020-05-11 18:10:58 +00:00
/**
* Prints table info if a base table is not present .
*/
private static function output_tables_info () {
$missing_tables = WC_Install :: verify_base_tables ( false );
if ( 0 === count ( $missing_tables ) ) {
return ;
}
?>
< br >
< strong style = " color:#a00; " >
< span class = " dashicons dashicons-warning " ></ span >
< ? php
2020-06-15 13:39:52 +00:00
echo esc_html (
sprintf (
// translators: Comma seperated list of missing tables.
__ ( 'Missing base tables: %s. Some WooCommerce functionality may not work as expected.' , 'woocommerce' ),
implode ( ', ' , $missing_tables )
)
);
2020-05-11 18:10:58 +00:00
?>
</ strong >
< ? php
}
2020-03-12 13:37:55 +00:00
/**
* Prints the information about plugins for the system status report .
* Used for both active and inactive plugins sections .
*
* @ param array $plugins List of plugins to display .
* @ param array $untested_plugins List of plugins that haven ' t been tested with the current WooCommerce version .
* @ return void
*/
private static function output_plugins_info ( $plugins , $untested_plugins ) {
2020-04-02 17:17:38 +00:00
$wc_version = Constants :: get_constant ( 'WC_VERSION' );
2020-03-12 13:37:55 +00:00
foreach ( $plugins as $plugin ) {
if ( ! empty ( $plugin [ 'name' ] ) ) {
// Link the plugin name to the plugin url if available.
$plugin_name = esc_html ( $plugin [ 'name' ] );
if ( ! empty ( $plugin [ 'url' ] ) ) {
$plugin_name = '<a href="' . esc_url ( $plugin [ 'url' ] ) . '" aria-label="' . esc_attr__ ( 'Visit plugin homepage' , 'woocommerce' ) . '" target="_blank">' . $plugin_name . '</a>' ;
}
2020-03-12 14:54:18 +00:00
$has_newer_version = false ;
2020-04-02 17:17:38 +00:00
$version_string = $plugin [ 'version' ];
2020-03-12 14:54:18 +00:00
$network_string = '' ;
2020-03-12 13:37:55 +00:00
if ( strstr ( $plugin [ 'url' ], 'woothemes.com' ) || strstr ( $plugin [ 'url' ], 'woocommerce.com' ) ) {
if ( ! empty ( $plugin [ 'version_latest' ] ) && version_compare ( $plugin [ 'version_latest' ], $plugin [ 'version' ], '>' ) ) {
2020-04-02 17:17:38 +00:00
/* translators: 1: current version. 2: latest version */
$version_string = sprintf ( __ ( '%1$s (update to version %2$s is available)' , 'woocommerce' ), $plugin [ 'version' ], $plugin [ 'version_latest' ] );
2020-03-12 13:37:55 +00:00
}
if ( false !== $plugin [ 'network_activated' ] ) {
2020-04-02 17:17:38 +00:00
$network_string = ' – <strong style="color: black;">' . esc_html__ ( 'Network enabled' , 'woocommerce' ) . '</strong>' ;
2020-03-12 13:37:55 +00:00
}
}
$untested_string = '' ;
if ( array_key_exists ( $plugin [ 'plugin' ], $untested_plugins ) ) {
2020-04-02 17:17:38 +00:00
$untested_string = ' – <strong style="color: #a00;">' ;
2020-03-12 14:54:18 +00:00
2020-04-02 17:17:38 +00:00
/* translators: %s: version */
$untested_string .= esc_html ( sprintf ( __ ( 'Installed version not tested with active version of WooCommerce %s' , 'woocommerce' ), $wc_version ) );
2020-03-12 14:54:18 +00:00
$untested_string .= '</strong>' ;
2020-03-12 13:37:55 +00:00
}
?>
< tr >
< td >< ? php echo wp_kses_post ( $plugin_name ); ?> </td>
< td class = " help " >& nbsp ; </ td >
< td >
< ? php
/* translators: %s: plugin author */
printf ( esc_html__ ( 'by %s' , 'woocommerce' ), esc_html ( $plugin [ 'author_name' ] ) );
2020-04-02 17:17:38 +00:00
echo ' – ' . esc_html ( $version_string ) . $untested_string . $network_string ; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2020-03-12 13:37:55 +00:00
?>
</ td >
</ tr >
< ? php
}
}
}
2014-06-04 17:25:49 +00:00
}