1
1
<?php
2
2
/**
3
- * Copyright 2016-2020 , Optimizely
3
+ * Copyright 2016-2021 , Optimizely
4
4
*
5
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
6
* you may not use this file except in compliance with the License.
@@ -110,23 +110,26 @@ protected function generateBucketValue($bucketingKey)
110
110
* @param $parentId mixed ID representing Experiment or Group.
111
111
* @param $trafficAllocations array Traffic allocations for variation or experiment.
112
112
*
113
- * @return string ID representing experiment or variation.
113
+ * @return [ string, array ] ID representing experiment or variation and array of log messages representing decision making .
114
114
*/
115
115
private function findBucket ($ bucketingId , $ userId , $ parentId , $ trafficAllocations )
116
116
{
117
+ $ decideReasons = [];
117
118
// Generate the bucketing key based on combination of user ID and experiment ID or group ID.
118
119
$ bucketingKey = $ bucketingId .$ parentId ;
119
120
$ bucketingNumber = $ this ->generateBucketValue ($ bucketingKey );
120
- $ this ->_logger ->log (Logger::DEBUG , sprintf ('Assigned bucket %s to user "%s" with bucketing ID "%s". ' , $ bucketingNumber , $ userId , $ bucketingId ));
121
+ $ message = sprintf ('Assigned bucket %s to user "%s" with bucketing ID "%s". ' , $ bucketingNumber , $ userId , $ bucketingId );
122
+ $ this ->_logger ->log (Logger::DEBUG , $ message );
123
+ $ decideReasons [] = $ message ;
121
124
122
125
foreach ($ trafficAllocations as $ trafficAllocation ) {
123
126
$ currentEnd = $ trafficAllocation ->getEndOfRange ();
124
127
if ($ bucketingNumber < $ currentEnd ) {
125
- return $ trafficAllocation ->getEntityId ();
128
+ return [ $ trafficAllocation ->getEntityId (), $ decideReasons ] ;
126
129
}
127
130
}
128
131
129
- return null ;
132
+ return [ null , $ decideReasons ] ;
130
133
}
131
134
132
135
/**
@@ -137,12 +140,14 @@ private function findBucket($bucketingId, $userId, $parentId, $trafficAllocation
137
140
* @param $bucketingId string A customer-assigned value used to create the key for the murmur hash.
138
141
* @param $userId string User identifier.
139
142
*
140
- * @return Variation Variation which will be shown to the user.
143
+ * @return [ Variation, array ] Variation which will be shown to the user and array of log messages representing decision making .
141
144
*/
142
145
public function bucket (ProjectConfigInterface $ config , Experiment $ experiment , $ bucketingId , $ userId )
143
146
{
147
+ $ decideReasons = [];
148
+
144
149
if (is_null ($ experiment ->getKey ())) {
145
- return null ;
150
+ return [ null , $ decideReasons ] ;
146
151
}
147
152
148
153
// Determine if experiment is in a mutually exclusive group.
@@ -151,47 +156,52 @@ public function bucket(ProjectConfigInterface $config, Experiment $experiment, $
151
156
$ group = $ config ->getGroup ($ experiment ->getGroupId ());
152
157
153
158
if (is_null ($ group ->getId ())) {
154
- return null ;
159
+ return [ null , $ decideReasons ] ;
155
160
}
156
161
157
- $ userExperimentId = $ this ->findBucket ($ bucketingId , $ userId , $ group ->getId (), $ group ->getTrafficAllocation ());
162
+ list ($ userExperimentId , $ reasons ) = $ this ->findBucket ($ bucketingId , $ userId , $ group ->getId (), $ group ->getTrafficAllocation ());
163
+ $ decideReasons = array_merge ($ decideReasons , $ reasons );
164
+
158
165
if (empty ($ userExperimentId )) {
159
- $ this ->_logger ->log (Logger::INFO , sprintf ('User "%s" is in no experiment. ' , $ userId ));
160
- return null ;
166
+ $ message = sprintf ('User "%s" is in no experiment. ' , $ userId );
167
+ $ this ->_logger ->log (Logger::INFO , $ message );
168
+ $ decideReasons [] = $ message ;
169
+ return [ null , $ decideReasons ];
161
170
}
162
171
163
172
if ($ userExperimentId != $ experiment ->getId ()) {
164
- $ this ->_logger ->log (
165
- Logger::INFO ,
166
- sprintf (
167
- 'User "%s" is not in experiment %s of group %s. ' ,
168
- $ userId ,
169
- $ experiment ->getKey (),
170
- $ experiment ->getGroupId ()
171
- )
172
- );
173
- return null ;
174
- }
175
-
176
- $ this ->_logger ->log (
177
- Logger::INFO ,
178
- sprintf (
179
- 'User "%s" is in experiment %s of group %s. ' ,
173
+ $ message = sprintf (
174
+ 'User "%s" is not in experiment %s of group %s. ' ,
180
175
$ userId ,
181
176
$ experiment ->getKey (),
182
177
$ experiment ->getGroupId ()
183
- )
178
+ );
179
+
180
+ $ this ->_logger ->log (Logger::INFO , $ message );
181
+ $ decideReasons [] = $ message ;
182
+ return [ null , $ decideReasons ];
183
+ }
184
+
185
+ $ message = sprintf (
186
+ 'User "%s" is in experiment %s of group %s. ' ,
187
+ $ userId ,
188
+ $ experiment ->getKey (),
189
+ $ experiment ->getGroupId ()
184
190
);
191
+
192
+ $ this ->_logger ->log (Logger::INFO , $ message );
193
+ $ decideReasons [] = $ message ;
185
194
}
186
195
187
196
// Bucket user if not in whitelist and in group (if any).
188
- $ variationId = $ this ->findBucket ($ bucketingId , $ userId , $ experiment ->getId (), $ experiment ->getTrafficAllocation ());
197
+ list ($ variationId , $ reasons ) = $ this ->findBucket ($ bucketingId , $ userId , $ experiment ->getId (), $ experiment ->getTrafficAllocation ());
198
+ $ decideReasons = array_merge ($ decideReasons , $ reasons );
189
199
if (!empty ($ variationId )) {
190
200
$ variation = $ config ->getVariationFromId ($ experiment ->getKey (), $ variationId );
191
201
192
- return $ variation ;
202
+ return [ $ variation, $ decideReasons ] ;
193
203
}
194
204
195
- return null ;
205
+ return [ null , $ decideReasons ] ;
196
206
}
197
207
}
0 commit comments