PluginProbe
Extendify / trunk
Extendify vtrunk
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
← All changes | app/Insights.php +53 -16 3.0.4 → trunk View file →
@@ -18,16 +18,31 @@
18 18
19 19 class Insights
20 20 {
21 21 /**
22 - * An array of active tests. 'A' should be the control.
23 - * For weighted tests, try ['A', 'A', 'A', 'A', 'B']
22 + * Option name storing each site's A/B test assignments, keyed by the
23 + * screen/feature under test (e.g. 'AutoLaunch.HideEnhanceAI').
24 24 *
25 - * @var array
25 + * @var string
26 26 */
27 - protected $activeTests = [];
27 + // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
28 + const ACTIVE_TESTS_OPTION = 'extendify_active_tests';
28 29
29 30 /**
31 + * Tests the plugin knows how to run. Each is rolled independently against
32 + * its own rollout percentage, which the partner config supplies.
33 + *
34 + * @var string[]
35 + */
36 + // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
37 + const AVAILABLE_TESTS = [
38 + 'AutoLaunch.HideEnhanceAI',
39 + 'AutoLaunch.SubmitCreateWebsite',
40 + 'AutoLaunch.DescriptionPlaceholderLaw',
41 + 'AutoLaunch.MigrateScreen',
42 + ];
43 +
44 + /**
30 45 * Process the readme file to get version and name
31 46 *
32 47 * @return void
33 48 */
@@ -51,30 +66,52 @@
51 66 \spawn_cron();
52 67 });
53 68 }
54 69
55 - $this->setUpActiveTests();
56 70 $this->filterExternalInsights();
57 71 $this->setupAdminLoginInsights();
58 72 }
59 73
60 74 /**
61 - * Returns the active tests for the user, and sets up tests as needed.
75 + * Assign A/B variants for the known tests based on the partner's active
76 + * tests. Each active test is rolled once;
77 + * inactive tests are dropped.
62 78 *
79 + * @param string[] $activeTests Active tests in `Name:Percentage` form
80 + * (e.g. 'AutoLaunch.HideEnhanceAI:20'); a bare
81 + * name defaults to a 50% rollout.
63 82 * @return void
64 83 */
65 - public function setUpActiveTests()
84 + public static function setup(array $activeTests = [])
66 85 {
67 - // Make sure that the active tests are set.
68 - $currentTests = \get_option('extendify_active_tests', []);
69 - $newTests = array_map(function ($test) {
70 - // Pick from value randomly.
71 - return $test[array_rand($test)];
72 - }, array_diff_key($this->activeTests, $currentTests));
73 - $testsCombined = array_merge($currentTests, $newTests);
74 - if ($newTests) {
75 - \update_option('extendify_active_tests', Sanitizer::sanitizeArray($testsCombined));
86 + $assignments = \get_option(self::ACTIVE_TESTS_OPTION, []);
87 +
88 + $percentages = [];
89 + foreach ($activeTests as $entry) {
90 + list($key, $percentage) = array_pad(explode(':', $entry, 2), 2, null);
91 + $percentages[$key] = is_numeric($percentage) ? (float) $percentage : 50.0;
76 92 }
93 +
94 + foreach (self::AVAILABLE_TESTS as $key) {
95 + if (!array_key_exists($key, $percentages)) {
96 + unset($assignments[$key]);
97 + continue;
98 + }
99 +
100 + // Roll once so the site keeps the same variant.
101 + if (!isset($assignments[$key])) {
102 + $assignments[$key] = [
103 + // The percentage is variant B's rollout share: 50 -> 50% A / 50% B,
104 + // 20 -> 80% A / 20% B.
105 + 'variant' => random_int(1, 10000) <= $percentages[$key] * 100 ? 'B' : 'A',
106 + 'percentage' => $percentages[$key],
107 + // ISO 8601 (UTC)
108 + 'assignedAt' => gmdate('c'),
109 + ];
110 + }
111 + }
112 +
113 + \update_option(self::ACTIVE_TESTS_OPTION, Sanitizer::sanitizeArray($assignments));
77 114 }
78 115
79 116 /**
80 117 * Add additional data to the opt-in insights