17
17
18
18
namespace Optimizely \Utils ;
19
19
20
+ use Monolog \Logger ;
21
+ use Optimizely \Enums \AudienceEvaluationLogs as logs ;
20
22
use Optimizely \Utils \Validator ;
21
23
22
24
class CustomAttributeConditionEvaluator
@@ -31,17 +33,19 @@ class CustomAttributeConditionEvaluator
31
33
32
34
/**
33
35
* @var UserAttributes
34
- */
36
+ */
35
37
protected $ userAttributes ;
36
38
37
39
/**
38
40
* CustomAttributeConditionEvaluator constructor
39
41
*
40
42
* @param array $userAttributes Associative array of user attributes to values.
43
+ * @param $logger LoggerInterface.
41
44
*/
42
- public function __construct (array $ userAttributes )
45
+ public function __construct (array $ userAttributes, $ logger )
43
46
{
44
47
$ this ->userAttributes = $ userAttributes ;
48
+ $ this ->logger = $ logger ;
45
49
}
46
50
47
51
/**
@@ -73,7 +77,7 @@ protected function getMatchTypes()
73
77
/**
74
78
* Gets the evaluator method name for the given match type.
75
79
*
76
- * @param string $matchType Match type for which to get evaluator.
80
+ * @param string $matchType Match type for which to get evaluator.
77
81
*
78
82
* @return string Corresponding evaluator method name.
79
83
*/
@@ -92,13 +96,13 @@ protected function getEvaluatorByMatchType($matchType)
92
96
/**
93
97
* Checks if the given input is a valid value for exact condition evaluation.
94
98
*
95
- * @param $value Input to check.
99
+ * @param $value Input to check.
96
100
*
97
- * @return boolean true if given input is a string/boolean/finite number, false otherwise.
101
+ * @return boolean true if given input is a string/boolean/number, false otherwise.
98
102
*/
99
- protected function isValueValidForExactConditions ($ value )
103
+ protected function isValueTypeValidForExactConditions ($ value )
100
104
{
101
- if (is_string ($ value ) || is_bool ($ value ) || Validator:: isFiniteNumber ($ value )) {
105
+ if (is_string ($ value ) || is_bool ($ value ) || is_int ( $ value ) || is_float ($ value )) {
102
106
return true ;
103
107
}
104
108
@@ -108,7 +112,7 @@ protected function isValueValidForExactConditions($value)
108
112
/**
109
113
* Evaluate the given exact match condition for the given user attributes.
110
114
*
111
- * @param object $condition
115
+ * @param object $condition
112
116
*
113
117
* @return null|boolean true if the user attribute value is equal (===) to the condition value,
114
118
* false if the user attribute value is not equal (!==) to the condition value,
@@ -122,11 +126,34 @@ protected function exactEvaluator($condition)
122
126
$ conditionValue = $ condition ['value ' ];
123
127
$ userValue = isset ($ this ->userAttributes [$ conditionName ]) ? $ this ->userAttributes [$ conditionName ]: null ;
124
128
125
- if (!$ this ->isValueValidForExactConditions ($ userValue )
126
- || !$ this ->isValueValidForExactConditions ($ conditionValue )
127
- || !Validator::areValuesSameType ($ conditionValue , $ userValue )
128
- ) {
129
- return null ;
129
+ if (!$ this ->isValueTypeValidForExactConditions ($ conditionValue ) ||
130
+ ((is_int ($ conditionValue ) || is_float ($ conditionValue )) && !Validator::isFiniteNumber ($ conditionValue ))) {
131
+ $ this ->logger ->log (Logger::WARNING , sprintf (
132
+ logs::UNKNOWN_CONDITION_VALUE ,
133
+ json_encode ($ condition )
134
+ ));
135
+ return null ;
136
+ }
137
+
138
+ if (!$ this ->isValueTypeValidForExactConditions ($ userValue ) ||
139
+ !Validator::areValuesSameType ($ conditionValue , $ userValue )) {
140
+ $ this ->logger ->log (Logger::WARNING , sprintf (
141
+ logs::UNEXPECTED_TYPE ,
142
+ json_encode ($ condition ),
143
+ gettype ($ userValue ),
144
+ $ conditionName
145
+ ));
146
+ return null ;
147
+ }
148
+
149
+ if ((is_int ($ userValue ) || is_float ($ userValue )) &&
150
+ !Validator::isFiniteNumber ($ userValue )) {
151
+ $ this ->logger ->log (Logger::WARNING , sprintf (
152
+ logs::INFINITE_ATTRIBUTE_VALUE ,
153
+ json_encode ($ condition ),
154
+ $ conditionName
155
+ ));
156
+ return null ;
130
157
}
131
158
132
159
return $ conditionValue == $ userValue ;
@@ -135,7 +162,7 @@ protected function exactEvaluator($condition)
135
162
/**
136
163
* Evaluate the given exists match condition for the given user attributes.
137
164
*
138
- * @param object $condition
165
+ * @param object $condition
139
166
*
140
167
* @return null|boolean true if both:
141
168
* 1) the user attributes have a value for the given condition, and
@@ -151,7 +178,7 @@ protected function existsEvaluator($condition)
151
178
/**
152
179
* Evaluate the given greater than match condition for the given user attributes.
153
180
*
154
- * @param object $condition
181
+ * @param object $condition
155
182
*
156
183
* @return boolean true if the user attribute value is greater than the condition value,
157
184
* false if the user attribute value is less than or equal to the condition value,
@@ -164,7 +191,30 @@ protected function greaterThanEvaluator($condition)
164
191
$ conditionValue = $ condition ['value ' ];
165
192
$ userValue = isset ($ this ->userAttributes [$ conditionName ]) ? $ this ->userAttributes [$ conditionName ]: null ;
166
193
167
- if (!Validator::isFiniteNumber ($ userValue ) || !Validator::isFiniteNumber ($ conditionValue )) {
194
+ if (!Validator::isFiniteNumber ($ conditionValue )) {
195
+ $ this ->logger ->log (Logger::WARNING , sprintf (
196
+ logs::UNKNOWN_CONDITION_VALUE ,
197
+ json_encode ($ condition )
198
+ ));
199
+ return null ;
200
+ }
201
+
202
+ if (!(is_int ($ userValue ) || is_float ($ userValue ))) {
203
+ $ this ->logger ->log (Logger::WARNING , sprintf (
204
+ logs::UNEXPECTED_TYPE ,
205
+ json_encode ($ condition ),
206
+ gettype ($ userValue ),
207
+ $ conditionName
208
+ ));
209
+ return null ;
210
+ }
211
+
212
+ if (!Validator::isFiniteNumber ($ userValue )) {
213
+ $ this ->logger ->log (Logger::WARNING , sprintf (
214
+ logs::INFINITE_ATTRIBUTE_VALUE ,
215
+ json_encode ($ condition ),
216
+ $ conditionName
217
+ ));
168
218
return null ;
169
219
}
170
220
@@ -174,7 +224,7 @@ protected function greaterThanEvaluator($condition)
174
224
/**
175
225
* Evaluate the given less than match condition for the given user attributes.
176
226
*
177
- * @param object $condition
227
+ * @param object $condition
178
228
*
179
229
* @return boolean true if the user attribute value is less than the condition value,
180
230
* false if the user attribute value is greater than or equal to the condition value,
@@ -187,30 +237,67 @@ protected function lessThanEvaluator($condition)
187
237
$ conditionValue = $ condition ['value ' ];
188
238
$ userValue = isset ($ this ->userAttributes [$ conditionName ]) ? $ this ->userAttributes [$ conditionName ]: null ;
189
239
190
- if (!Validator::isFiniteNumber ($ userValue ) || !Validator::isFiniteNumber ($ conditionValue )) {
240
+ if (!Validator::isFiniteNumber ($ conditionValue )) {
241
+ $ this ->logger ->log (Logger::WARNING , sprintf (
242
+ logs::UNKNOWN_CONDITION_VALUE ,
243
+ json_encode ($ condition )
244
+ ));
245
+ return null ;
246
+ }
247
+
248
+ if (!(is_int ($ userValue ) || is_float ($ userValue ))) {
249
+ $ this ->logger ->log (Logger::WARNING , sprintf (
250
+ logs::UNEXPECTED_TYPE ,
251
+ json_encode ($ condition ),
252
+ gettype ($ userValue ),
253
+ $ conditionName
254
+ ));
255
+ return null ;
256
+ }
257
+
258
+ if (!Validator::isFiniteNumber ($ userValue )) {
259
+ $ this ->logger ->log (Logger::WARNING , sprintf (
260
+ logs::INFINITE_ATTRIBUTE_VALUE ,
261
+ json_encode ($ condition ),
262
+ $ conditionName
263
+ ));
191
264
return null ;
192
265
}
193
266
194
267
return $ userValue < $ conditionValue ;
195
268
}
196
269
197
270
/**
198
- * Evaluate the given substring than match condition for the given user attributes.
199
- *
200
- * @param object $condition
201
- *
202
- * @return boolean true if the condition value is a substring of the user attribute value,
203
- * false if the condition value is not a substring of the user attribute value,
204
- * null if the condition value isn't a string or the user attribute value
205
- * isn't a string.
206
- */
271
+ * Evaluate the given substring than match condition for the given user attributes.
272
+ *
273
+ * @param object $condition
274
+ *
275
+ * @return boolean true if the condition value is a substring of the user attribute value,
276
+ * false if the condition value is not a substring of the user attribute value,
277
+ * null if the condition value isn't a string or the user attribute value
278
+ * isn't a string.
279
+ */
207
280
protected function substringEvaluator ($ condition )
208
281
{
209
282
$ conditionName = $ condition ['name ' ];
210
283
$ conditionValue = $ condition ['value ' ];
211
284
$ userValue = isset ($ this ->userAttributes [$ conditionName ]) ? $ this ->userAttributes [$ conditionName ]: null ;
212
285
213
- if (!is_string ($ userValue ) || !is_string ($ conditionValue )) {
286
+ if (!is_string ($ conditionValue )) {
287
+ $ this ->logger ->log (Logger::WARNING , sprintf (
288
+ logs::UNKNOWN_CONDITION_VALUE ,
289
+ json_encode ($ condition )
290
+ ));
291
+ return null ;
292
+ }
293
+
294
+ if (!is_string ($ userValue )) {
295
+ $ this ->logger ->log (Logger::WARNING , sprintf (
296
+ logs::UNEXPECTED_TYPE ,
297
+ json_encode ($ condition ),
298
+ gettype ($ userValue ),
299
+ $ conditionName
300
+ ));
214
301
return null ;
215
302
}
216
303
@@ -220,7 +307,7 @@ protected function substringEvaluator($condition)
220
307
/**
221
308
* Function to evaluate audience conditions against user's attributes.
222
309
*
223
- * @param array $leafCondition Condition to be evaluated.
310
+ * @param array $leafCondition Condition to be evaluated.
224
311
*
225
312
* @return null|boolean true/false if the given user attributes match/don't match the given conditions,
226
313
* null if the given user attributes and conditions can't be evaluated.
@@ -230,6 +317,10 @@ public function evaluate($leafCondition)
230
317
$ leafCondition = $ this ->setNullForMissingKeys ($ leafCondition );
231
318
232
319
if ($ leafCondition ['type ' ] !== self ::CUSTOM_ATTRIBUTE_CONDITION_TYPE ) {
320
+ $ this ->logger ->log (Logger::WARNING , sprintf (
321
+ logs::UNKNOWN_CONDITION_TYPE ,
322
+ json_encode ($ leafCondition )
323
+ ));
233
324
return null ;
234
325
}
235
326
@@ -240,9 +331,35 @@ public function evaluate($leafCondition)
240
331
}
241
332
242
333
if (!in_array ($ conditionMatch , $ this ->getMatchTypes ())) {
334
+ $ this ->logger ->log (Logger::WARNING , sprintf (
335
+ logs::UNKNOWN_MATCH_TYPE ,
336
+ json_encode ($ leafCondition )
337
+ ));
243
338
return null ;
244
339
}
245
340
341
+ $ conditionName = $ leafCondition ['name ' ];
342
+
343
+ if ($ leafCondition ['match ' ] !== self ::EXISTS_MATCH_TYPE ) {
344
+ if (!array_key_exists ($ conditionName , $ this ->userAttributes )) {
345
+ $ this ->logger ->log (Logger::DEBUG , sprintf (
346
+ logs::MISSING_ATTRIBUTE_VALUE ,
347
+ json_encode ($ leafCondition ),
348
+ $ conditionName
349
+ ));
350
+ return null ;
351
+ }
352
+
353
+ if (!isset ($ this ->userAttributes [$ conditionName ])) {
354
+ $ this ->logger ->log (Logger::DEBUG , sprintf (
355
+ logs::NULL_ATTRIBUTE_VALUE ,
356
+ json_encode ($ leafCondition ),
357
+ $ conditionName
358
+ ));
359
+ return null ;
360
+ }
361
+ }
362
+
246
363
$ evaluatorForMatch = $ this ->getEvaluatorByMatchType ($ conditionMatch );
247
364
return $ this ->$ evaluatorForMatch ($ leafCondition );
248
365
}
0 commit comments