Create a wrapper function for all external dependency function calls for safety
This commit is contained in:
parent
f529d927a2
commit
be81f7eabf
|
@ -6,9 +6,10 @@ namespace Automattic\WooCommerce\Internal\Logging;
|
|||
use Automattic\WooCommerce\Utilities\FeaturesUtil;
|
||||
use Automattic\WooCommerce\Utilities\StringUtil;
|
||||
use Automattic\WooCommerce\Internal\McStats;
|
||||
use Jetpack_Options;
|
||||
use WC_Rate_Limiter;
|
||||
use WC_Log_Levels;
|
||||
use Jetpack_Options;
|
||||
use WC_Site_Tracking;
|
||||
|
||||
/**
|
||||
* WooCommerce Remote Logger
|
||||
|
@ -22,6 +23,8 @@ use Jetpack_Options;
|
|||
* @package WooCommerce\Classes
|
||||
*/
|
||||
class RemoteLogger extends \WC_Log_Handler {
|
||||
use UseNonBuiltInFunctions;
|
||||
|
||||
const LOG_ENDPOINT = 'https://public-api.wordpress.com/rest/v1.1/logstash';
|
||||
const RATE_LIMIT_ID = 'woocommerce_remote_logging';
|
||||
const RATE_LIMIT_DELAY = 60; // 1 minute.
|
||||
|
@ -40,11 +43,17 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return bool False if value was not handled and true if value was handled.
|
||||
*/
|
||||
public function handle( $timestamp, $level, $message, $context ) {
|
||||
if ( ! $this->should_handle( $level, $message, $context ) ) {
|
||||
try {
|
||||
if ( ! $this->should_handle( $level, $message, $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->log( $level, $message, $context );
|
||||
} catch ( \Throwable $e ) {
|
||||
// Log the error to the local logger so we can investigate.
|
||||
$this->wc_get_logger()->error( 'Failed to handle the log: ' . $e->getMessage(), array( 'source' => 'remote-logging' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->log( $level, $message, $context );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,14 +75,14 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
'feature' => 'woocommerce_core',
|
||||
'severity' => $level,
|
||||
'message' => $this->sanitize( $message ),
|
||||
'host' => wp_parse_url( home_url(), PHP_URL_HOST ),
|
||||
'host' => $this->wp_parse_url( $this->home_url(), PHP_URL_HOST ),
|
||||
'tags' => array( 'woocommerce', 'php' ),
|
||||
'properties' => array(
|
||||
'wc_version' => WC()->version,
|
||||
'wc_version' => $this->get_wc_version(),
|
||||
'php_version' => phpversion(),
|
||||
'wp_version' => get_bloginfo( 'version' ),
|
||||
'wp_version' => $this->get_bloginfo( 'version' ),
|
||||
'request_uri' => $this->sanitize_request_uri( filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL ) ),
|
||||
'store_id' => get_option( \WC_Install::STORE_ID_OPTION, null ),
|
||||
'store_id' => $this->get_option( \WC_Install::STORE_ID_OPTION, null ),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -140,7 +149,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( ! \WC_Site_Tracking::is_tracking_enabled() ) {
|
||||
if ( ! WC_Site_Tracking::is_tracking_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -193,11 +202,12 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
}
|
||||
|
||||
if ( WC_Rate_Limiter::retried_too_soon( self::RATE_LIMIT_ID ) ) {
|
||||
error_log( 'Remote logging throttled.' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
||||
// Log locally that the remote logging is throttled.
|
||||
$this->wc_get_logger()->warning( 'Remote logging throttled.', array( 'source' => 'remote-logging' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,46 +222,41 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return bool
|
||||
*/
|
||||
private function log( $level, $message, $context ) {
|
||||
try {
|
||||
$log_data = $this->get_formatted_log( $level, $message, $context );
|
||||
$log_data = $this->get_formatted_log( $level, $message, $context );
|
||||
|
||||
// Ensure the log data is valid.
|
||||
if ( ! is_array( $log_data ) || empty( $log_data['message'] ) || empty( $log_data['feature'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$body = array(
|
||||
'params' => wp_json_encode( $log_data ),
|
||||
);
|
||||
|
||||
WC_Rate_Limiter::set_rate_limit( self::RATE_LIMIT_ID, self::RATE_LIMIT_DELAY );
|
||||
|
||||
if ( $this->is_dev_or_local_environment() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = wp_safe_remote_post(
|
||||
self::LOG_ENDPOINT,
|
||||
array(
|
||||
'body' => wp_json_encode( $body ),
|
||||
'timeout' => 3,
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'blocking' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
throw new \Exception( $response->get_error_message() );
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch ( \Throwable $e ) {
|
||||
// Log the error locally if the remote logging fails.
|
||||
error_log( 'Remote logging failed: ' . $e->getMessage() ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
||||
if ( ! is_array( $log_data ) || empty( $log_data['message'] ) || empty( $log_data['feature'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$body = array(
|
||||
'params' => $this->wp_json_encode( $log_data ),
|
||||
);
|
||||
|
||||
WC_Rate_Limiter::set_rate_limit( self::RATE_LIMIT_ID, self::RATE_LIMIT_DELAY );
|
||||
|
||||
if ( $this->is_dev_or_local_environment() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->wp_safe_remote_post(
|
||||
self::LOG_ENDPOINT,
|
||||
array(
|
||||
'body' => $this->wp_json_encode( $body ),
|
||||
'timeout' => 3,
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'blocking' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$this->wc_get_logger()->error( 'Failed to send the log to the remote logging service: ' . $response->get_error_message(), array( 'source' => 'remote-logging' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,7 +265,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return bool
|
||||
*/
|
||||
private function is_variant_assignment_allowed() {
|
||||
$assignment = get_option( 'woocommerce_remote_variant_assignment', 0 );
|
||||
$assignment = $this->get_option( 'woocommerce_remote_variant_assignment', 0 );
|
||||
return ( $assignment <= 12 ); // Considering 10% of the 0-120 range.
|
||||
}
|
||||
|
||||
|
@ -270,12 +275,12 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return bool
|
||||
*/
|
||||
private function should_current_version_be_logged() {
|
||||
$new_version = get_site_transient( self::WC_NEW_VERSION_TRANSIENT );
|
||||
$new_version = $this->get_site_transient( self::WC_NEW_VERSION_TRANSIENT );
|
||||
|
||||
if ( false === $new_version ) {
|
||||
$new_version = $this->fetch_new_woocommerce_version();
|
||||
// Cache the new version for a week since we want to keep logging in with the same version for a while even if the new version is available.
|
||||
set_site_transient( self::WC_NEW_VERSION_TRANSIENT, $new_version, WEEK_IN_SECONDS );
|
||||
$this->set_site_transient( self::WC_NEW_VERSION_TRANSIENT, $new_version, WEEK_IN_SECONDS );
|
||||
}
|
||||
|
||||
if ( ! is_string( $new_version ) || '' === $new_version ) {
|
||||
|
@ -284,7 +289,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
}
|
||||
|
||||
// If the current version is the latest, we don't want to log errors.
|
||||
return version_compare( WC()->version, $new_version, '>=' );
|
||||
return version_compare( $this->get_wc_version(), $new_version, '>=' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,6 +329,9 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'apply_filters' ) ) {
|
||||
require_once ABSPATH . WPINC . '/plugin.php';
|
||||
}
|
||||
/**
|
||||
* Filter to allow other plugins to overwrite the result of the third-party error check for remote logging.
|
||||
*
|
||||
|
@ -342,14 +350,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return string|null New version if an update is available, null otherwise.
|
||||
*/
|
||||
private function fetch_new_woocommerce_version() {
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
if ( ! function_exists( 'get_plugin_updates' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
}
|
||||
|
||||
$plugin_updates = get_plugin_updates();
|
||||
$plugin_updates = $this->get_plugin_updates();
|
||||
|
||||
// Check if WooCommerce plugin update information is available.
|
||||
if ( ! is_array( $plugin_updates ) || ! isset( $plugin_updates[ WC_PLUGIN_BASENAME ] ) ) {
|
||||
|
@ -429,7 +430,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
|
||||
$is_array_by_file = isset( $sanitized_trace[0]['file'] );
|
||||
if ( $is_array_by_file ) {
|
||||
return wc_print_r( $sanitized_trace, true );
|
||||
return $this->wc_print_r( $sanitized_trace, true );
|
||||
}
|
||||
|
||||
return implode( "\n", $sanitized_trace );
|
||||
|
@ -443,7 +444,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
* @return bool
|
||||
*/
|
||||
protected function is_dev_or_local_environment() {
|
||||
return in_array( wp_get_environment_type(), array( 'development', 'local' ), true );
|
||||
return in_array( $this->wp_get_environment_type(), array( 'development', 'local' ), true );
|
||||
}
|
||||
/**
|
||||
* Sanitize the request URI to only allow certain query parameters.
|
||||
|
@ -474,7 +475,7 @@ class RemoteLogger extends \WC_Log_Handler {
|
|||
*/
|
||||
$whitelist = apply_filters( 'woocommerce_remote_logger_request_uri_whitelist', $default_whitelist );
|
||||
|
||||
$parsed_url = wp_parse_url( $request_uri );
|
||||
$parsed_url = $this->wp_parse_url( $request_uri );
|
||||
if ( ! isset( $parsed_url['query'] ) ) {
|
||||
return $request_uri;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,413 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Automattic\WooCommerce\Internal\Logging;
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
|
||||
|
||||
/**
|
||||
* UseNonBuiltInFunctions Trait
|
||||
*
|
||||
* This trait creates a wrapper for non-built-in functions for safety.
|
||||
*
|
||||
* @since 9.4.0
|
||||
* @package Automattic\WooCommerce\Internal\Logging
|
||||
*/
|
||||
trait UseNonBuiltInFunctions {
|
||||
|
||||
/**
|
||||
* Wp_parse_url wrapper.
|
||||
*
|
||||
* @param string $url The URL to parse.
|
||||
* @param int $component The specific component to retrieve. Use one of the PHP
|
||||
* predefined constants to specify which one.
|
||||
* Defaults to -1 (= return all parts as an array).
|
||||
* @return mixed False on parse failure; Array of URL components on success;
|
||||
* When a specific component has been requested: null if the component
|
||||
* doesn't exist in the given URL; a string or - in the case of
|
||||
* PHP_URL_PORT - integer when it does. See parse_url()'s return values.
|
||||
*/
|
||||
private function wp_parse_url( $url, $component = -1 ) {
|
||||
try {
|
||||
if ( ! function_exists( 'wp_parse_url' ) ) {
|
||||
require_once ABSPATH . WPINC . '/http.php';
|
||||
}
|
||||
|
||||
return wp_parse_url( $url, $component );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'url' => $url,
|
||||
'component' => $component,
|
||||
)
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Home_url wrapper.
|
||||
*
|
||||
* @param string $path The path to append to the home URL.
|
||||
* @param string $scheme The scheme to use for the home URL.
|
||||
* @return string The home URL with the path appended.
|
||||
*/
|
||||
private function home_url( $path = '', $scheme = null ) {
|
||||
try {
|
||||
if ( ! function_exists( 'home_url' ) ) {
|
||||
require_once ABSPATH . WPINC . '/link-template.php';
|
||||
}
|
||||
|
||||
return home_url( $path, $scheme );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'path' => $path,
|
||||
'scheme' => $scheme,
|
||||
)
|
||||
);
|
||||
|
||||
return 'Unable to retrieve';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get_bloginfo wrapper.
|
||||
*
|
||||
* @param string $show Optional. Site info to retrieve. Default empty (site name).
|
||||
* @param string $filter Optional. How to filter what is retrieved. Default 'raw'.
|
||||
* @return string Mostly string values, might be empty.
|
||||
*/
|
||||
private function get_bloginfo( $show = '', $filter = 'raw' ) {
|
||||
try {
|
||||
if ( ! function_exists( 'get_bloginfo' ) ) {
|
||||
require_once ABSPATH . WPINC . '/general-template.php';
|
||||
}
|
||||
|
||||
return get_bloginfo( $show, $filter );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'show' => $show,
|
||||
'filter' => $filter,
|
||||
)
|
||||
);
|
||||
|
||||
return 'Unable to retrieve';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get_option wrapper.
|
||||
*
|
||||
* @param string $option Name of the option to retrieve. Expected to not be SQL-escaped.
|
||||
* @param mixed $_default Optional. Default value to return if the option does not exist.
|
||||
* @return mixed Value of the option. A value of any type may be returned, including
|
||||
* scalar (string, boolean, float, integer), null, array, object.
|
||||
* Scalar and null values will be returned as strings as long as they originate
|
||||
* from a database stored option value. If there is no option in the database,
|
||||
* boolean `false` is returned.
|
||||
*/
|
||||
private function get_option( $option, $_default = false ) {
|
||||
try {
|
||||
if ( ! function_exists( 'get_option' ) ) {
|
||||
require_once ABSPATH . WPINC . '/option.php';
|
||||
}
|
||||
|
||||
return get_option( $option, $_default );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'option' => $option,
|
||||
'_default' => $_default,
|
||||
)
|
||||
);
|
||||
return 'Unable to retrieve';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get_site_transient wrapper.
|
||||
*
|
||||
* @param string $transient Transient name. Expected to not be SQL-escaped.
|
||||
* @return mixed Value of the transient.
|
||||
*/
|
||||
private function get_site_transient( $transient ) {
|
||||
if ( ! function_exists( 'get_site_transient' ) ) {
|
||||
require_once ABSPATH . WPINC . '/option.php';
|
||||
}
|
||||
|
||||
try {
|
||||
return get_site_transient( $transient );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'transient' => $transient,
|
||||
)
|
||||
);
|
||||
return 'Unable to retrieve';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set_site_transient wrapper.
|
||||
*
|
||||
* @param string $transient Transient name. Expected to not be SQL-escaped.
|
||||
* @param mixed $value Value of the transient.
|
||||
* @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
|
||||
* @return bool True if the transient was set successfully, false otherwise.
|
||||
*/
|
||||
private function set_site_transient( $transient, $value, $expiration = 0 ) {
|
||||
try {
|
||||
if ( ! function_exists( 'set_site_transient' ) ) {
|
||||
require_once ABSPATH . WPINC . '/option.php';
|
||||
}
|
||||
|
||||
return set_site_transient( $transient, $value, $expiration );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'transient' => $transient,
|
||||
'value' => $value,
|
||||
'expiration' => $expiration,
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wp_safe_remote_post wrapper.
|
||||
*
|
||||
* @param string $url URL to send the request to.
|
||||
* @param array $args Optional. Additional arguments for the request.
|
||||
* @return array|WP_Error The response or WP_Error on failure.
|
||||
*
|
||||
* @throws \Exception If wp_safe_remote_post function does not exist.
|
||||
*/
|
||||
private function wp_safe_remote_post( $url, $args = array() ) {
|
||||
try {
|
||||
if ( ! function_exists( 'wp_safe_remote_post' ) ) {
|
||||
require_once ABSPATH . WPINC . '/http.php';
|
||||
}
|
||||
|
||||
return wp_safe_remote_post( $url, $args );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'url' => $url,
|
||||
'args' => $args,
|
||||
)
|
||||
);
|
||||
|
||||
return new \WP_Error( 'remote_post_error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is_wp_error wrapper.
|
||||
*
|
||||
* @param mixed $thing The variable to check.
|
||||
* @return bool Whether the variable is an instance of WP_Error.
|
||||
*
|
||||
* @throws \Exception If is_wp_error function does not exist.
|
||||
*/
|
||||
private function is_wp_error( $thing ) {
|
||||
try {
|
||||
if ( ! function_exists( 'is_wp_error' ) ) {
|
||||
require_once ABSPATH . WPINC . '/load.php';
|
||||
}
|
||||
|
||||
return is_wp_error( $thing );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'thing' => $thing,
|
||||
)
|
||||
);
|
||||
|
||||
// We can't determine if the variable is an instance of WP_Error so we throw an exception.
|
||||
throw new \Exception( 'is_wp_error function does not exist' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get_plugin_updates wrapper.
|
||||
*
|
||||
* @return array|null The plugin updates array or null if not available.
|
||||
*/
|
||||
private function get_plugin_updates() {
|
||||
try {
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'get_plugin_updates' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
}
|
||||
|
||||
return get_plugin_updates();
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array()
|
||||
);
|
||||
|
||||
// If the function does not exist, return null since the update is not available.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get_wp_environment_type wrapper.
|
||||
*
|
||||
* @return string The environment type.
|
||||
*
|
||||
* @throws \Exception If wp_get_environment_type function does not exist.
|
||||
*/
|
||||
private function wp_get_environment_type() {
|
||||
try {
|
||||
if ( ! function_exists( 'wp_get_environment_type' ) ) {
|
||||
require_once ABSPATH . WPINC . '/load.php';
|
||||
}
|
||||
|
||||
return wp_get_environment_type();
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array()
|
||||
);
|
||||
|
||||
// If the function does not exist, return production since the wp default value is production.
|
||||
return 'production';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wp_json_encode wrapper.
|
||||
*
|
||||
* @param mixed $data The data to encode.
|
||||
* @return string The JSON encoded string.
|
||||
*
|
||||
* @throws \Exception If wp_json_encode function does not exist.
|
||||
*/
|
||||
private function wp_json_encode( $data ) {
|
||||
try {
|
||||
if ( ! function_exists( 'wp_json_encode' ) ) {
|
||||
require_once ABSPATH . WPINC . '/functions.php';
|
||||
}
|
||||
|
||||
return wp_json_encode( $data );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array(
|
||||
'data' => $data,
|
||||
)
|
||||
);
|
||||
|
||||
return 'Unable to encode';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get_wc_version wrapper.
|
||||
*
|
||||
* @return string The WooCommerce version.
|
||||
*
|
||||
* @throws \Exception If get_wc_version function does not exist.
|
||||
*/
|
||||
private function get_wc_version() {
|
||||
try {
|
||||
return Constants::get_constant( 'WC_VERSION' );
|
||||
} catch ( \Throwable $e ) {
|
||||
$this->log_wrapper_error(
|
||||
__FUNCTION__,
|
||||
$e->getMessage(),
|
||||
array()
|
||||
);
|
||||
|
||||
return 'Unable to retrieve';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wc_get_logger wrapper.
|
||||
*
|
||||
* @return \WC_Logger The WooCommerce logger.
|
||||
*
|
||||
* @throws \Exception If wc_get_logger function does not exist.
|
||||
*/
|
||||
private function wc_get_logger() {
|
||||
try {
|
||||
if ( ! function_exists( 'wc_get_logger' ) ) {
|
||||
require_once WC_ABSPATH . 'includes/class-wc-logger.php';
|
||||
}
|
||||
|
||||
return wc_get_logger();
|
||||
} catch ( \Throwable $e ) {
|
||||
throw new \Exception( 'wc_get_logger function does not exist' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wc_print_r wrapper.
|
||||
*
|
||||
* @param mixed $data The data to print.
|
||||
* @param bool $_return Whether to return the output instead of printing it.
|
||||
* @return string The printed data.
|
||||
*/
|
||||
private function wc_print_r( $data, $_return = false ) {
|
||||
if ( ! function_exists( 'wc_print_r' ) ) {
|
||||
require_once WC_ABSPATH . 'includes/wc-core-functions.php';
|
||||
}
|
||||
|
||||
return wc_print_r( $data, $_return );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log wrapper function errors to "local logging" for debugging.
|
||||
*
|
||||
* @param string $function_name The name of the wrapped function.
|
||||
* @param string $error_message The error message.
|
||||
* @param array $context Additional context for the error.
|
||||
*/
|
||||
private function log_wrapper_error( $function_name, $error_message, $context = array() ) {
|
||||
$this->wc_get_logger()->error(
|
||||
'[Wrapper function error] ' . sprintf( 'Error in %s: %s', $function_name, $error_message ),
|
||||
array_merge(
|
||||
array(
|
||||
'function' => $function_name,
|
||||
'source' => 'remote-logging',
|
||||
),
|
||||
$context
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ declare( strict_types = 1 );
|
|||
// phpcs:disable Universal.Namespaces.OneDeclarationPerFile.MultipleFound -- same
|
||||
namespace Automattic\WooCommerce\Tests\Internal\Logging {
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\WooCommerce\Internal\Logging\RemoteLogger;
|
||||
use WC_Rate_Limiter;
|
||||
use WC_Cache_Helper;
|
||||
|
@ -43,6 +44,7 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
|
|||
global $wpdb;
|
||||
$wpdb->query( "DELETE FROM {$wpdb->prefix}wc_rate_limits" );
|
||||
WC_Cache_Helper::invalidate_cache_group( WC_Rate_Limiter::CACHE_GROUP );
|
||||
Constants::clear_constants();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,8 +141,7 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
|
|||
* @param bool $expected The expected result.
|
||||
*/
|
||||
public function test_should_current_version_be_logged( $current_version, $new_version, $transient_value, $expected ) {
|
||||
$wc_version = WC()->version;
|
||||
WC()->version = $current_version;
|
||||
Constants::set_constant( 'WC_VERSION', $current_version );
|
||||
|
||||
// Set up the transient.
|
||||
if ( null !== $transient_value ) {
|
||||
|
@ -156,8 +157,6 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
|
|||
|
||||
// Clean up.
|
||||
delete_site_transient( RemoteLogger::WC_NEW_VERSION_TRANSIENT );
|
||||
|
||||
WC()->version = $wc_version;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue