Add a generic function to determine remote logging eligibility (#49371)
* Add wc remote logger * Add changelog * Add remote logging feature * Update tests and remove private $latest_wc_version; * Fix lint * Rename is_user_opted_in -> is_tracking_opted_in
This commit is contained in:
parent
b32c742f3f
commit
21d08c7f56
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add a generic function to determine remote logging eligibility
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
declare( strict_types = 1 );
|
||||
|
||||
use Automattic\WooCommerce\Utilities\FeaturesUtil;
|
||||
|
||||
/**
|
||||
* WooCommerce Remote Logger
|
||||
*
|
||||
* The WooCommerce remote logger class adds functionality to log WooCommerce errors remotely based on if the customer opted in and several other conditions.
|
||||
*
|
||||
* No personal information is logged, only error information and relevant context.
|
||||
*
|
||||
* @class WC_Remote_Logger
|
||||
* @since 9.2.0
|
||||
* @package WooCommerce\Classes
|
||||
*/
|
||||
class WC_Remote_Logger {
|
||||
/**
|
||||
* Determines if remote logging is allowed based on the following conditions:
|
||||
*
|
||||
* 1. The feature flag for remote error logging is enabled.
|
||||
* 2. The user has opted into tracking/logging.
|
||||
* 3. The store is allowed to log based on the variant assignment percentage.
|
||||
* 4. The current WooCommerce version is the latest so we don't log errors that might have been fixed in a newer version.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_remote_logging_allowed() {
|
||||
if ( ! FeaturesUtil::feature_is_enabled( 'remote_logging' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_tracking_opted_in() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_variant_assignment_allowed() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_latest_woocommerce_version() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has opted into tracking/logging.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_tracking_opted_in() {
|
||||
return 'yes' === get_option( 'woocommerce_allow_tracking', 'no' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store is allowed to log based on the variant assignment percentage.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_variant_assignment_allowed() {
|
||||
$assignment = get_option( 'woocommerce_remote_variant_assignment', 0 );
|
||||
return ( $assignment <= 12 ); // Considering 10% of the 0-120 range.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current WooCommerce version is the latest.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_latest_woocommerce_version() {
|
||||
$latest_wc_version = $this->fetch_latest_woocommerce_version();
|
||||
|
||||
if ( is_null( $latest_wc_version ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return version_compare( WC()->version, $latest_wc_version, '>=' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the latest WooCommerce version using the WordPress API and cache it.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function fetch_latest_woocommerce_version() {
|
||||
$transient_key = 'latest_woocommerce_version';
|
||||
$cached_version = get_transient( $transient_key );
|
||||
if ( $cached_version ) {
|
||||
return $cached_version;
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'plugins_api' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||
}
|
||||
|
||||
$plugin_info = plugins_api( 'plugin_information', array( 'slug' => 'woocommerce' ) );
|
||||
if ( is_wp_error( $plugin_info ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! empty( $plugin_info->version ) ) {
|
||||
$latest_version = $plugin_info->version;
|
||||
set_transient( $transient_key, $latest_version, DAY_IN_SECONDS );
|
||||
return $latest_version;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -29,7 +29,6 @@ use Automattic\WooCommerce\Internal\Admin\Marketplace;
|
|||
use Automattic\WooCommerce\Proxies\LegacyProxy;
|
||||
use Automattic\WooCommerce\Utilities\{LoggingUtil, RestApiUtil, TimeUtil};
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
|
||||
/**
|
||||
* Main WooCommerce Class.
|
||||
|
@ -647,6 +646,7 @@ final class WooCommerce {
|
|||
include_once WC_ABSPATH . 'includes/class-wc-structured-data.php';
|
||||
include_once WC_ABSPATH . 'includes/class-wc-shortcodes.php';
|
||||
include_once WC_ABSPATH . 'includes/class-wc-logger.php';
|
||||
include_once WC_ABSPATH . 'includes/class-wc-remote-logger.php';
|
||||
include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php';
|
||||
include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php';
|
||||
include_once WC_ABSPATH . 'includes/admin/marketplace-suggestions/class-wc-marketplace-updater.php';
|
||||
|
|
|
@ -247,6 +247,17 @@ class FeaturesController {
|
|||
'is_legacy' => true,
|
||||
'option_key' => CustomOrdersTableController::HPOS_FTS_INDEX_OPTION,
|
||||
),
|
||||
'remote_logging' => array(
|
||||
'name' => __( 'Remote Logging', 'woocommerce' ),
|
||||
'description' => __(
|
||||
'Enable this feature to log errors and related data to Automattic servers for debugging purposes and to improve WooCommerce',
|
||||
'woocommerce'
|
||||
),
|
||||
'enabled_by_default' => false,
|
||||
'disable_ui' => true,
|
||||
'is_legacy' => false,
|
||||
'is_experimental' => true,
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $legacy_features as $slug => $definition ) {
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
declare( strict_types = 1 );
|
||||
|
||||
/**
|
||||
* Class WC_Remote_Logger_Test.
|
||||
*/
|
||||
class WC_Remote_Logger_Test extends \WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* Set up test
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
include_once WC_ABSPATH . 'includes/class-wc-remote-logger.php';
|
||||
|
||||
WC()->version = '9.2.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
$this->cleanup_filters();
|
||||
|
||||
delete_option( 'woocommerce_feature_remote_logging_enabled' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cleanup_filters() {
|
||||
remove_all_filters( 'option_woocommerce_admin_remote_feature_enabled' );
|
||||
remove_all_filters( 'option_woocommerce_allow_tracking' );
|
||||
remove_all_filters( 'option_woocommerce_version' );
|
||||
remove_all_filters( 'option_woocommerce_remote_variant_assignment' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remote logging is allowed when all conditions are met.
|
||||
*/
|
||||
public function test_remote_logging_allowed() {
|
||||
update_option( 'woocommerce_feature_remote_logging_enabled', 'yes' );
|
||||
|
||||
add_filter(
|
||||
'option_woocommerce_allow_tracking',
|
||||
function () {
|
||||
return 'yes';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_remote_variant_assignment',
|
||||
function () {
|
||||
return 5;
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'plugins_api',
|
||||
function ( $result, $action, $args ) {
|
||||
if ( 'plugin_information' === $action && 'woocommerce' === $args->slug ) {
|
||||
return (object) array(
|
||||
'version' => '9.2.0',
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
$checker = new WC_Remote_Logger();
|
||||
$this->assertTrue( $checker->is_remote_logging_allowed() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remote logging is not allowed when the feature flag is disabled.
|
||||
*/
|
||||
public function test_remote_logging_not_allowed_feature_flag_disabled() {
|
||||
update_option( 'woocommerce_feature_remote_logging_enabled', 'no' );
|
||||
|
||||
add_filter(
|
||||
'option_woocommerce_allow_tracking',
|
||||
function () {
|
||||
return 'yes';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_remote_variant_assignment',
|
||||
function () {
|
||||
return 5;
|
||||
}
|
||||
);
|
||||
|
||||
set_transient( 'latest_woocommerce_version', '9.2.0', DAY_IN_SECONDS );
|
||||
|
||||
$checker = new WC_Remote_Logger();
|
||||
$this->assertFalse( $checker->is_remote_logging_allowed() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remote logging is not allowed when user tracking is not opted in.
|
||||
*/
|
||||
public function test_remote_logging_not_allowed_tracking_opted_out() {
|
||||
update_option( 'woocommerce_feature_remote_logging_enabled', 'yes' );
|
||||
add_filter(
|
||||
'option_woocommerce_allow_tracking',
|
||||
function () {
|
||||
return 'no';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_remote_variant_assignment',
|
||||
function () {
|
||||
return 5;
|
||||
}
|
||||
);
|
||||
|
||||
set_transient( 'latest_woocommerce_version', '9.2.0', DAY_IN_SECONDS );
|
||||
|
||||
$checker = new WC_Remote_Logger();
|
||||
$this->assertFalse( $checker->is_remote_logging_allowed() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remote logging is not allowed when the WooCommerce version is outdated.
|
||||
*/
|
||||
public function test_remote_logging_not_allowed_outdated_version() {
|
||||
update_option( 'woocommerce_feature_remote_logging_enabled', 'yes' );
|
||||
add_filter(
|
||||
'option_woocommerce_allow_tracking',
|
||||
function () {
|
||||
return 'yes';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_remote_variant_assignment',
|
||||
function () {
|
||||
return 5;
|
||||
}
|
||||
);
|
||||
|
||||
set_transient( 'latest_woocommerce_version', '9.2.0', DAY_IN_SECONDS );
|
||||
WC()->version = '9.0.0';
|
||||
|
||||
$checker = new WC_Remote_Logger();
|
||||
$this->assertFalse( $checker->is_remote_logging_allowed() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remote logging is not allowed when the variant assignment is high.
|
||||
*/
|
||||
public function test_remote_logging_not_allowed_high_variant_assignment() {
|
||||
update_option( 'woocommerce_feature_remote_logging_enabled', 'yes' );
|
||||
add_filter(
|
||||
'option_woocommerce_allow_tracking',
|
||||
function () {
|
||||
return 'yes';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_version',
|
||||
function () {
|
||||
return '9.2.0';
|
||||
}
|
||||
);
|
||||
add_filter(
|
||||
'option_woocommerce_remote_variant_assignment',
|
||||
function () {
|
||||
return 15;
|
||||
}
|
||||
);
|
||||
|
||||
set_transient( 'latest_woocommerce_version', '9.2.0', DAY_IN_SECONDS );
|
||||
|
||||
$checker = new WC_Remote_Logger();
|
||||
$this->assertFalse( $checker->is_remote_logging_allowed() );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue