This repository has been archived by the owner on Jun 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 147
Add explat variation for wc pay promotion #7554
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<?php | ||
/** | ||
* NOTE: this is a temporary class and can be replaced by jetpack-abtest after | ||
* https://github.com/Automattic/jetpack/issues/19596 has been fixed. | ||
* | ||
* A class that interacts with Explat A/B tests. | ||
* | ||
* This class is experimental. It is a fork of the jetpack-abtest package and | ||
* updated for use with ExPlat. These changes are planned to be contributed | ||
* back to the upstream Jetpack package. If accepted, this class should then | ||
* be superseded by the Jetpack class using Composer. | ||
* | ||
* This class should not be used externally. | ||
* | ||
* @package WooCommerce\Admin | ||
* @link https://packagist.org/packages/automattic/jetpack-abtest | ||
*/ | ||
|
||
namespace WooCommerce\Admin; | ||
|
||
/** | ||
* This class provides an interface to the Explat A/B tests. | ||
* | ||
* @internal This class is experimental and should not be used externally due to planned breaking changes. | ||
*/ | ||
final class Experimental_Abtest { | ||
|
||
/** | ||
* A variable to hold the tests we fetched, and their variations for the current user. | ||
* | ||
* @var array | ||
*/ | ||
private $tests = array(); | ||
|
||
/** | ||
* ExPlat Anonymous ID. | ||
* | ||
* @var string | ||
*/ | ||
private $anon_id = null; | ||
|
||
/** | ||
* ExPlat Platform name. | ||
* | ||
* @var string | ||
*/ | ||
private $platform = 'woocommerce'; | ||
|
||
/** | ||
* Whether trcking consent is given. | ||
* | ||
* @var bool | ||
*/ | ||
private $consent = false; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param string $anon_id ExPlat anonymous ID. | ||
* @param string $platform ExPlat platform name. | ||
* @param bool $consent Whether tracking consent is given. | ||
*/ | ||
public function __construct( string $anon_id, string $platform, bool $consent ) { | ||
$this->anon_id = $anon_id; | ||
$this->platform = $platform; | ||
$this->consent = $consent; | ||
} | ||
|
||
/** | ||
* Retrieve the test variation for a provided A/B test. | ||
* | ||
* @param string $test_name Name of the A/B test. | ||
* @return mixed|null A/B test variation, or null on failure. | ||
*/ | ||
public function get_variation( $test_name ) { | ||
// Default to the control variation when users haven't consented to tracking. | ||
if ( ! $this->consent ) { | ||
return 'control'; | ||
} | ||
|
||
$variation = $this->fetch_variation( $test_name ); | ||
|
||
// If there was an error retrieving a variation, conceal the error for the consumer. | ||
if ( is_wp_error( $variation ) ) { | ||
return 'control'; | ||
} | ||
|
||
return $variation; | ||
} | ||
|
||
/** | ||
* Fetch and cache the test variation for a provided A/B test from WP.com. | ||
* | ||
* ExPlat returns a null value when the assigned variation is control or | ||
* an assignment has not been set. In these instances, this method returns | ||
* a value of "control". | ||
* | ||
* @param string $test_name Name of the A/B test. | ||
* @return array|\WP_Error A/B test variation, or error on failure. | ||
*/ | ||
protected function fetch_variation( $test_name ) { | ||
// Make sure test name exists. | ||
if ( ! $test_name ) { | ||
return new \WP_Error( 'test_name_not_provided', 'A/B test name has not been provided.' ); | ||
} | ||
|
||
// Make sure test name is a valid one. | ||
if ( ! preg_match( '/^[A-Za-z0-9_]+$/', $test_name ) ) { | ||
return new \WP_Error( 'invalid_test_name', 'Invalid A/B test name.' ); | ||
} | ||
|
||
// Return internal-cached test variations. | ||
if ( isset( $this->tests[ $test_name ] ) ) { | ||
return $this->tests[ $test_name ]; | ||
} | ||
|
||
// Return external-cached test variations. | ||
if ( ! empty( get_transient( 'abtest_variation_' . $test_name ) ) ) { | ||
return get_transient( 'abtest_variation_' . $test_name ); | ||
} | ||
|
||
// Make the request to the WP.com API. | ||
$response = $this->request_variation( $test_name ); | ||
|
||
// Bail if there was an error or malformed response. | ||
if ( is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['body'] ) ) { | ||
return new \WP_Error( 'failed_to_fetch_data', 'Unable to fetch the requested data.' ); | ||
} | ||
|
||
// Decode the results. | ||
$results = json_decode( $response['body'], true ); | ||
|
||
// Bail if there were no results or there is no test variation returned. | ||
if ( ! is_array( $results ) || empty( $results['variations'] ) ) { | ||
return new \WP_Error( 'unexpected_data_format', 'Data was not returned in the expected format.' ); | ||
} | ||
|
||
// Store the variation in our internal cache. | ||
$this->tests[ $test_name ] = $results['variations'][ $test_name ]; | ||
|
||
$variation = $results['variations'][ $test_name ] ?? 'control'; | ||
|
||
// Store the variation in our external cache. | ||
if ( ! empty( $results['ttl'] ) ) { | ||
set_transient( 'abtest_variation_' . $test_name, $variation, $results['ttl'] ); | ||
} | ||
|
||
return $variation; | ||
} | ||
|
||
/** | ||
* Perform the request for a variation of a provided A/B test from WP.com. | ||
* | ||
* @param string $test_name Name of the A/B test. | ||
* @return array|\WP_Error A/B test variation error on failure. | ||
*/ | ||
protected function request_variation( $test_name ) { | ||
$args = array( | ||
'experiment_name' => $test_name, | ||
'anon_id' => $this->anon_id, | ||
); | ||
|
||
$url = add_query_arg( | ||
$args, | ||
sprintf( | ||
'https://public-api.wordpress.com/wpcom/v2/experiments/0.1.0/assignments/%s', | ||
$this->platform | ||
) | ||
); | ||
|
||
$get = wp_remote_get( $url ); | ||
|
||
return $get; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,10 +101,25 @@ public static function should_register_pre_install_wc_pay_promoted_gateway() { | |
} | ||
$wc_pay_spec = self::get_wc_pay_promotion_spec(); | ||
|
||
if ( ! $wc_pay_spec ) { | ||
if ( ! $wc_pay_spec || ! isset( $wc_pay_spec->additional_info ) || ! isset( $wc_pay_spec->additional_info->experiment_version ) ) { | ||
return false; | ||
} | ||
return true; | ||
|
||
$anon_id = isset( $_COOKIE['tk_ai'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['tk_ai'] ) ) : null; | ||
$allow_tracking = 'yes' === get_option( 'woocommerce_allow_tracking' ); | ||
$abtest = new \WooCommerce\Admin\Experimental_Abtest( | ||
$anon_id, | ||
'woocommerce', | ||
$allow_tracking | ||
); | ||
|
||
$variation_name = $abtest->get_variation( 'woocommerce_wc_pay_promotion_payment_methods_table_' . $wc_pay_spec->additional_info->experiment_version ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to double check that This will be a public API, so anything we add here will continue to be used for the same request in the future with this version of WooCommerce Admin. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I should probably do that as well |
||
|
||
if ( 'treatment' === $variation_name ) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add some comments here with the source URL this was copied from and any notes about when we can remove this in the future (if applicable)?