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 +30 -11 3.1.0 → trunk View file →
@@ -19,9 +19,9 @@
19 19 class Insights
20 20 {
21 21 /**
22 22 * Option name storing each site's A/B test assignments, keyed by the
23 - * screen/feature under test (e.g. 'AutoLaunch.WebsiteTitle').
23 + * screen/feature under test (e.g. 'AutoLaunch.HideEnhanceAI').
24 24 *
25 25 * @var string
26 26 */
27 27 // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
@@ -27,15 +27,19 @@
27 27 // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
28 28 const ACTIVE_TESTS_OPTION = 'extendify_active_tests';
29 29
30 30 /**
31 - * Tests the plugin knows how to run, each mapped to its available variants.
31 + * Tests the plugin knows how to run. Each is rolled independently against
32 + * its own rollout percentage, which the partner config supplies.
32 33 *
33 - * @var array<string, string[]>
34 + * @var string[]
34 35 */
35 36 // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
36 - const ACTIVE_TESTS = [
37 - 'AutoLaunch.WebsiteTitle' => ['A', 'B'],
37 + const AVAILABLE_TESTS = [
38 + 'AutoLaunch.HideEnhanceAI',
39 + 'AutoLaunch.SubmitCreateWebsite',
40 + 'AutoLaunch.DescriptionPlaceholderLaw',
41 + 'AutoLaunch.MigrateScreen',
38 42 ];
39 43
40 44 /**
41 45 * Process the readme file to get version and name
@@ -68,12 +72,14 @@
68 72 }
69 73
70 74 /**
71 75 * Assign A/B variants for the known tests based on the partner's active
72 - * tests. Each active test is rolled once and kept on return visits;
76 + * tests. Each active test is rolled once;
73 77 * inactive tests are dropped.
74 78 *
75 - * @param string[] $activeTests Test keys the partner has enabled.
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.
76 82 * @return void
77 83 */
78 84 public static function setup(array $activeTests = [])
79 85 {
@@ -78,17 +84,30 @@
78 84 public static function setup(array $activeTests = [])
79 85 {
80 86 $assignments = \get_option(self::ACTIVE_TESTS_OPTION, []);
81 87
82 - foreach (self::ACTIVE_TESTS as $key => $variants) {
83 - if (!in_array($key, $activeTests, true)) {
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;
92 + }
93 +
94 + foreach (self::AVAILABLE_TESTS as $key) {
95 + if (!array_key_exists($key, $percentages)) {
84 96 unset($assignments[$key]);
85 97 continue;
86 98 }
87 99
88 - // Roll once so a returning visitor keeps the same variant.
100 + // Roll once so the site keeps the same variant.
89 101 if (!isset($assignments[$key])) {
90 - $assignments[$key] = $variants[random_int(0, count($variants) - 1)];
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 + ];
91 110 }
92 111 }
93 112
94 113 \update_option(self::ACTIVE_TESTS_OPTION, Sanitizer::sanitizeArray($assignments));