1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* A class that interacts with WP.com A/B tests. |
4
|
|
|
* |
5
|
|
|
* @package automattic/jetpack-abtest |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Automattic\Jetpack; |
9
|
|
|
|
10
|
|
|
use Automattic\Jetpack\Connection\Client; |
11
|
|
|
use Automattic\Jetpack\Error; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* This class provides an interface to the WP.com A/B tests. |
15
|
|
|
*/ |
16
|
|
|
class Abtest { |
17
|
|
|
/** |
18
|
|
|
* A variable to hold the tests we fetched, and their variations for the current user. |
19
|
|
|
* |
20
|
|
|
* @access private |
21
|
|
|
* |
22
|
|
|
* @var array |
23
|
|
|
*/ |
24
|
|
|
private $tests = array(); |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Retrieve the test variation for a provided A/B test. |
28
|
|
|
* |
29
|
|
|
* @access public |
30
|
|
|
* |
31
|
|
|
* @param string $test_name Name of the A/B test. |
32
|
|
|
* @return mixed|null A/B test variation, or null on failure. |
33
|
|
|
*/ |
34
|
|
|
public function get_variation( $test_name ) { |
35
|
|
|
$variation = $this->fetch_variation( $test_name ); |
36
|
|
|
|
37
|
|
|
// If there was an error retrieving a variation, conceal the error for the consumer. |
38
|
|
|
if ( is_wp_error( $variation ) ) { |
39
|
|
|
return null; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
return $variation; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Fetch and cache the test variation for a provided A/B test from WP.com. |
47
|
|
|
* |
48
|
|
|
* @access protected |
49
|
|
|
* |
50
|
|
|
* @param string $test_name Name of the A/B test. |
51
|
|
|
* @return mixed|Automattic\Jetpack\Error A/B test variation, or Automattic\Jetpack\Error on failure. |
52
|
|
|
*/ |
53
|
|
|
protected function fetch_variation( $test_name ) { |
54
|
|
|
// Make sure test name exists. |
55
|
|
|
if ( ! $test_name ) { |
56
|
|
|
return new Error( 'test_name_not_provided', 'A/B test name has not been provided.' ); |
|
|
|
|
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
// Make sure test name is a valid one. |
60
|
|
|
if ( ! preg_match( '/^[A-Za-z0-9_]+$/', $test_name ) ) { |
61
|
|
|
return new Error( 'invalid_test_name', 'Invalid A/B test name.' ); |
|
|
|
|
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
// Return cached test variations. |
65
|
|
|
if ( isset( $this->tests[ $test_name ] ) ) { |
66
|
|
|
return $this->tests[ $test_name ]; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
// Make the request to the WP.com API. |
70
|
|
|
$response = $this->request_variation( $test_name ); |
71
|
|
|
|
72
|
|
|
// Bail if there was an error or malformed response. |
73
|
|
|
if ( is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['body'] ) ) { |
74
|
|
|
return new Error( 'failed_to_fetch_data', 'Unable to fetch the requested data.' ); |
|
|
|
|
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
// Decode the results. |
78
|
|
|
$results = json_decode( $response['body'], true ); |
79
|
|
|
|
80
|
|
|
// Bail if there were no results or there is no test variation returned. |
81
|
|
|
if ( ! is_array( $results ) || empty( $results['variation'] ) ) { |
82
|
|
|
return new Error( 'unexpected_data_format', 'Data was not returned in the expected format.' ); |
|
|
|
|
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
// Store the variation in our internal cache. |
86
|
|
|
$this->tests[ $test_name ] = $results['variation']; |
87
|
|
|
|
88
|
|
|
return $results['variation']; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Perform the request for a variation of a provided A/B test from WP.com. |
93
|
|
|
* |
94
|
|
|
* @access protected |
95
|
|
|
* |
96
|
|
|
* @param string $test_name Name of the A/B test. |
97
|
|
|
* @return mixed|Automattic\Jetpack\Error A/B test variation, or Automattic\Jetpack\Error on failure. |
98
|
|
|
*/ |
99
|
|
|
protected function request_variation( $test_name ) { |
100
|
|
|
return Client::wpcom_json_api_request_as_blog( sprintf( '/abtest/%s', $test_name ), '2', array(), null, 'wpcom' ); |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.