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
*
2014-11-30 06:52:32 +00:00
* @ author WooThemes
* @ category Admin
* @ package WooCommerce / Admin / System Status
2014-06-04 17:25:49 +00:00
* @ version 2.2 . 0
2013-07-18 14:22:05 +00:00
*/
2014-09-20 19:52:30 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
2015-03-07 03:16:08 +00:00
exit ;
2014-09-20 19:52:30 +00:00
}
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 () {
2013-07-18 14:22:05 +00:00
include_once ( 'views/html-admin-page-status.php' );
}
/**
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 () {
2013-07-18 14:22:05 +00:00
include_once ( 'views/html-admin-page-status-report.php' );
}
/**
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 () {
2015-01-20 10:41:26 +00:00
global $wpdb ;
2013-07-18 14:22:05 +00:00
2014-06-04 10:16:19 +00:00
$tools = self :: get_tools ();
2013-07-18 14:22:05 +00:00
if ( ! empty ( $_GET [ 'action' ] ) && ! empty ( $_REQUEST [ '_wpnonce' ] ) && wp_verify_nonce ( $_REQUEST [ '_wpnonce' ], 'debug_action' ) ) {
switch ( $_GET [ 'action' ] ) {
2014-06-04 17:25:49 +00:00
case 'clear_transients' :
2013-08-09 16:11:15 +00:00
wc_delete_product_transients ();
2015-01-08 15:47:58 +00:00
wc_delete_shop_order_transients ();
2015-01-19 13:19:41 +00:00
WC_Cache_Helper :: get_transient_version ( 'shipping' , true );
2013-07-18 14:22:05 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Product Transients Cleared' , 'woocommerce' ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
break ;
2014-06-04 17:25:49 +00:00
case 'clear_expired_transients' :
2013-07-18 14:22:05 +00:00
2015-06-01 10:38:43 +00:00
/*
2015-11-03 12:28:01 +00:00
* Deletes all expired transients . The multi - table delete syntax is used .
* to delete the transient record from table a , and the corresponding .
2015-06-01 10:38:43 +00:00
* transient_timeout record from table b .
*
* Based on code inside core ' s upgrade_network () function .
*/
$sql = " DELETE a, b FROM $wpdb->options a, $wpdb->options b
WHERE a . option_name LIKE % s
AND a . option_name NOT LIKE % s
AND b . option_name = CONCAT ( '_transient_timeout_' , SUBSTRING ( a . option_name , 12 ) )
AND b . option_value < % d " ;
$rows = $wpdb -> query ( $wpdb -> prepare ( $sql , $wpdb -> esc_like ( '_transient_' ) . '%' , $wpdb -> esc_like ( '_transient_timeout_' ) . '%' , time () ) );
2013-07-18 14:22:05 +00:00
2015-06-01 10:38:43 +00:00
$sql = " DELETE a, b FROM $wpdb->options a, $wpdb->options b
WHERE a . option_name LIKE % s
AND a . option_name NOT LIKE % s
AND b . option_name = CONCAT ( '_site_transient_timeout_' , SUBSTRING ( a . option_name , 17 ) )
AND b . option_value < % d " ;
$rows2 = $wpdb -> query ( $wpdb -> prepare ( $sql , $wpdb -> esc_like ( '_site_transient_' ) . '%' , $wpdb -> esc_like ( '_site_transient_timeout_' ) . '%' , time () ) );
2013-07-18 14:22:05 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . sprintf ( __ ( '%d Transients Rows Cleared' , 'woocommerce' ), $rows + $rows2 ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
break ;
2014-06-04 17:25:49 +00:00
case 'reset_roles' :
2013-07-18 14:22:05 +00:00
// Remove then re-add caps and roles
2014-11-25 17:09:19 +00:00
WC_Install :: remove_roles ();
WC_Install :: create_roles ();
2013-07-18 14:22:05 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Roles successfully reset' , 'woocommerce' ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
break ;
2014-06-04 17:25:49 +00:00
case 'recount_terms' :
2013-07-18 14:22:05 +00:00
$product_cats = get_terms ( 'product_cat' , array ( 'hide_empty' => false , 'fields' => 'id=>parent' ) );
2014-04-24 15:09:03 +00:00
_wc_term_recount ( $product_cats , get_taxonomy ( 'product_cat' ), true , false );
2013-07-18 14:22:05 +00:00
$product_tags = get_terms ( 'product_tag' , array ( 'hide_empty' => false , 'fields' => 'id=>parent' ) );
2014-04-24 15:09:03 +00:00
_wc_term_recount ( $product_tags , get_taxonomy ( 'product_tag' ), true , false );
2013-07-18 14:22:05 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Terms successfully recounted' , 'woocommerce' ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
break ;
2014-06-04 17:25:49 +00:00
case 'clear_sessions' :
2013-07-18 14:22:05 +00:00
2016-03-25 04:24:36 +00:00
$wpdb -> query ( " TRUNCATE { $wpdb -> prefix } woocommerce_sessions " );
2013-07-18 14:22:05 +00:00
wp_cache_flush ();
2013-11-14 19:20:18 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Sessions successfully cleared' , 'woocommerce' ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
break ;
2014-06-04 17:25:49 +00:00
case 'install_pages' :
2013-11-14 19:20:18 +00:00
WC_Install :: create_pages ();
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'All missing WooCommerce pages was installed successfully.' , 'woocommerce' ) . '</p></div>' ;
2014-06-04 17:25:49 +00:00
break ;
case 'delete_taxes' :
2014-01-06 14:42:54 +00:00
2016-01-08 14:53:24 +00:00
$wpdb -> query ( " TRUNCATE TABLE { $wpdb -> prefix } woocommerce_tax_rates; " );
$wpdb -> query ( " TRUNCATE TABLE { $wpdb -> prefix } woocommerce_tax_rate_locations; " );
2015-12-02 15:53:46 +00:00
WC_Cache_Helper :: incr_cache_prefix ( 'taxes' );
2014-01-06 14:42:54 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Tax rates successfully deleted' , 'woocommerce' ) . '</p></div>' ;
2014-01-06 14:42:54 +00:00
break ;
2014-11-27 07:43:43 +00:00
case 'reset_tracking' :
2015-01-23 16:36:52 +00:00
delete_option ( 'woocommerce_allow_tracking' );
WC_Admin_Notices :: add_notice ( 'tracking' );
2014-11-27 07:43:43 +00:00
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Usage tracking settings successfully reset.' , 'woocommerce' ) . '</p></div>' ;
2014-11-27 07:43:43 +00:00
break ;
2014-06-04 17:25:49 +00:00
default :
2013-07-18 14:22:05 +00:00
$action = esc_attr ( $_GET [ 'action' ] );
2014-06-04 17:25:49 +00:00
if ( isset ( $tools [ $action ][ 'callback' ] ) ) {
2013-07-18 14:22:05 +00:00
$callback = $tools [ $action ][ 'callback' ];
$return = call_user_func ( $callback );
2014-06-04 17:25:49 +00:00
if ( $return === false ) {
2016-04-25 12:07:38 +00:00
$callback_string = is_array ( $callback ) ? get_class ( $callback [ 0 ] ) . '::' . $callback [ 1 ] : $callback ;
echo '<div class="error inline"><p>' . sprintf ( __ ( 'There was an error calling %s' , 'woocommerce' ), $callback_string ) . '</p></div>' ;
2013-07-18 14:22:05 +00:00
}
}
break ;
}
}
2014-05-28 13:46:11 +00:00
2014-06-04 17:25:49 +00:00
// Display message if settings settings have been saved
if ( isset ( $_REQUEST [ 'settings-updated' ] ) ) {
2016-02-23 08:33:11 +00:00
echo '<div class="updated inline"><p>' . __ ( 'Your changes have been saved.' , 'woocommerce' ) . '</p></div>' ;
2013-11-14 19:31:08 +00:00
}
2013-07-18 14:22:05 +00:00
include_once ( 'views/html-admin-page-status-tools.php' );
}
/**
2015-11-03 12:28:01 +00:00
* Get tools .
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 () {
2014-06-04 17:25:49 +00:00
$tools = array (
2013-07-18 14:22:05 +00:00
'clear_transients' => array (
2015-03-07 03:16:08 +00:00
'name' => __ ( 'WC Transients' , 'woocommerce' ),
'button' => __ ( 'Clear transients' , 'woocommerce' ),
2014-11-30 06:52:32 +00:00
'desc' => __ ( 'This tool will clear the product/shop transients cache.' , 'woocommerce' ),
2013-07-18 14:22:05 +00:00
),
'clear_expired_transients' => array (
2015-03-07 03:16:08 +00:00
'name' => __ ( 'Expired Transients' , 'woocommerce' ),
'button' => __ ( 'Clear expired transients' , 'woocommerce' ),
2014-11-30 06:52:32 +00:00
'desc' => __ ( 'This tool will clear ALL expired transients from WordPress.' , 'woocommerce' ),
2013-07-18 14:22:05 +00:00
),
'recount_terms' => array (
2015-03-07 03:16:08 +00:00
'name' => __ ( 'Term counts' , 'woocommerce' ),
'button' => __ ( 'Recount terms' , 'woocommerce' ),
2014-11-30 06:52:32 +00:00
'desc' => __ ( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.' , 'woocommerce' ),
2013-07-18 14:22:05 +00:00
),
'reset_roles' => array (
2015-03-07 03:16:08 +00:00
'name' => __ ( 'Capabilities' , 'woocommerce' ),
'button' => __ ( 'Reset capabilities' , 'woocommerce' ),
2014-11-30 06:52:32 +00:00
'desc' => __ ( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.' , 'woocommerce' ),
2013-07-18 14:22:05 +00:00
),
'clear_sessions' => array (
2015-03-07 03:16:08 +00:00
'name' => __ ( 'Customer Sessions' , 'woocommerce' ),
'button' => __ ( 'Clear all sessions' , 'woocommerce' ),
2014-11-30 06:52:32 +00:00
'desc' => __ ( '<strong class="red">Warning:</strong> This tool will delete all customer session data from the database, including any current live carts.' , 'woocommerce' ),
2013-07-18 14:22:05 +00:00
),
2013-11-14 19:20:18 +00:00
'install_pages' => array (
'name' => __ ( 'Install WooCommerce Pages' , 'woocommerce' ),
'button' => __ ( 'Install pages' , 'woocommerce' ),
2014-01-08 18:03:36 +00:00
'desc' => __ ( '<strong class="red">Note:</strong> This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.' , 'woocommerce' ),
2013-11-14 19:20:18 +00:00
),
2014-01-06 14:42:54 +00:00
'delete_taxes' => array (
'name' => __ ( 'Delete all WooCommerce tax rates' , 'woocommerce' ),
'button' => __ ( 'Delete ALL tax rates' , 'woocommerce' ),
2014-01-08 18:03:36 +00:00
'desc' => __ ( '<strong class="red">Note:</strong> This option will delete ALL of your tax rates, use with caution.' , 'woocommerce' ),
2014-11-27 07:43:43 +00:00
),
'reset_tracking' => array (
'name' => __ ( 'Reset Usage Tracking Settings' , 'woocommerce' ),
'button' => __ ( 'Reset usage tracking settings' , 'woocommerce' ),
'desc' => __ ( 'This will reset your usage tracking settings, causing it to show the opt-in banner again and not sending any data.' , 'woocommerce' ),
2016-07-03 06:16:11 +00:00
),
'delete_geoip_log' => array (
'name' => __ ( 'Delete GeoIP Log' , 'woocommerce' ),
'button' => __ ( 'Delete GeoIP Log' , 'woocommerce' ),
'desc' => __ ( 'This will delete the GeoIP log created by WooCommerce.' , 'woocommerce' ),
2014-06-04 17:25:49 +00:00
)
);
return apply_filters ( 'woocommerce_debug_tools' , $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 () {
2014-11-30 06:52:32 +00:00
2014-06-04 10:16:19 +00:00
$logs = self :: scan_log_files ();
2014-11-30 06:52:32 +00:00
2015-02-02 23:58:25 +00:00
if ( ! empty ( $_REQUEST [ 'log_file' ] ) && isset ( $logs [ sanitize_title ( $_REQUEST [ 'log_file' ] ) ] ) ) {
$viewed_log = $logs [ sanitize_title ( $_REQUEST [ 'log_file' ] ) ];
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 ) : '' ;
if ( ! empty ( $_REQUEST [ 'handle' ] ) ) {
self :: remove_log ();
}
2014-05-28 10:12:35 +00:00
include_once ( 'views/html-admin-page-status-logs.php' );
}
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 .
2015-03-07 03:16:08 +00:00
* @ since 2.1 . 1
* @ 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
2014-10-28 00:21:33 +00:00
// Avoid notices if file does not exist
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.
$fp = fopen ( $file , 'r' );
// Pull only the first 8kiB of the file in.
$file_data = fread ( $fp , 8192 );
// PHP will close file handle, but we are good citizens.
fclose ( $fp );
// Make sure we catch CR-only line endings.
$file_data = str_replace ( " \r " , " \n " , $file_data );
$version = '' ;
if ( preg_match ( '/^[ \t\/*#@]*' . preg_quote ( '@version' , '/' ) . '(.*)$/mi' , $file_data , $match ) && $match [ 1 ] )
$version = _cleanup_header_comment ( $match [ 1 ] );
return $version ;
}
2014-05-28 13:46:11 +00:00
2016-07-05 00:10:17 +00:00
/**
* Return the log file handle .
*
* @ param string $filename
* @ return string
*/
public static function get_log_file_handle ( $filename ) {
return substr ( $filename , 0 , strlen ( $filename ) > 37 ? strlen ( $filename ) - 37 : strlen ( $filename ) - 4 );
}
2013-07-18 14:22:05 +00:00
/**
2015-11-03 12:28:01 +00:00
* Scan the template files .
2015-03-07 03:16:08 +00:00
* @ param string $template_path
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 ) {
2014-11-30 06:52:32 +00:00
2015-04-01 13:33:56 +00:00
$files = @ scandir ( $template_path );
$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
2013-07-18 14:22:05 +00:00
if ( ! in_array ( $value , array ( " . " , " .. " ) ) ) {
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 .
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 () {
2015-04-01 13:33:56 +00:00
$files = @ scandir ( WC_LOG_DIR );
$result = array ();
2014-11-30 06:52:32 +00:00
2016-06-06 18:39:23 +00:00
if ( ! empty ( $files ) ) {
2014-11-30 06:52:32 +00:00
2014-05-28 10:12:35 +00:00
foreach ( $files as $key => $value ) {
2014-11-30 06:52:32 +00:00
2014-05-28 13:46:11 +00:00
if ( ! in_array ( $value , array ( '.' , '..' ) ) ) {
2014-05-28 10:12:35 +00:00
if ( ! is_dir ( $value ) && strstr ( $value , '.log' ) ) {
$result [ sanitize_title ( $value ) ] = $value ;
}
}
}
2015-04-01 13:33:56 +00:00
2014-05-28 10:12:35 +00:00
}
2015-04-01 13:33:56 +00:00
2014-05-28 10:12:35 +00:00
return $result ;
}
2015-11-02 10:01:42 +00:00
/**
2015-11-03 12:28:01 +00:00
* Get latest version of a theme by slug .
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 ) {
$api = themes_api ( 'theme_information' , array (
'slug' => $theme -> get_stylesheet (),
'fields' => array (
2016-02-05 19:48:45 +00:00
'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 ;
2016-02-05 19:48:45 +00:00
// Check WooThemes Theme Version.
2015-11-02 10:01:42 +00:00
} elseif ( strstr ( $theme -> { 'Author URI' }, 'woothemes' ) ) {
$theme_dir = substr ( strtolower ( str_replace ( ' ' , '' , $theme -> Name ) ), 0 , 45 );
if ( false === ( $theme_version_data = get_transient ( $theme_dir . '_version_data' ) ) ) {
$theme_changelog = wp_safe_remote_get ( 'http://dzv365zjfbd8v.cloudfront.net/changelogs/' . $theme_dir . '/changelog.txt' );
$cl_lines = explode ( " \n " , wp_remote_retrieve_body ( $theme_changelog ) );
if ( ! empty ( $cl_lines ) ) {
foreach ( $cl_lines as $line_num => $cl_line ) {
if ( preg_match ( '/^[0-9]/' , $cl_line ) ) {
$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 );
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 .
*/
public function remove_log () {
if ( empty ( $_REQUEST [ '_wpnonce' ] ) || ! wp_verify_nonce ( $_REQUEST [ '_wpnonce' ], 'remove_log' ) ) {
wp_die ( __ ( 'Action failed. Please refresh the page and retry.' , 'woocommerce' ) );
}
if ( ! empty ( $_REQUEST [ 'handle' ] ) ) {
$logger = new WC_Logger ();
$logger -> remove ( $_REQUEST [ 'handle' ] );
}
wp_safe_redirect ( esc_url_raw ( admin_url ( 'admin.php?page=wc-status&tab=logs' ) ) );
exit ();
}
2014-06-04 17:25:49 +00:00
}