PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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.63.2.1 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