@@ -254,13 +254,52 @@ public function getFeatureFlag(
254254 bool $ onlyEvaluateLocally = false ,
255255 bool $ sendFeatureFlagEvents = true
256256 ): null | bool | string {
257+ $ result = $ this ->getFeatureFlagResult (
258+ $ key ,
259+ $ distinctId ,
260+ $ groups ,
261+ $ personProperties ,
262+ $ groupProperties ,
263+ $ onlyEvaluateLocally ,
264+ $ sendFeatureFlagEvents
265+ );
266+
267+ return $ result ?->getValue();
268+ }
269+
270+ /**
271+ * Get the feature flag result including value and payload.
272+ *
273+ * This is the recommended method for getting feature flag data as it returns
274+ * both the flag value and payload in a single call, while properly tracking analytics.
275+ *
276+ * @param string $key
277+ * @param string $distinctId
278+ * @param array $groups
279+ * @param array $personProperties
280+ * @param array $groupProperties
281+ * @param bool $onlyEvaluateLocally
282+ * @param bool $sendFeatureFlagEvents
283+ * @return FeatureFlagResult|null
284+ * @throws Exception
285+ */
286+ public function getFeatureFlagResult (
287+ string $ key ,
288+ string $ distinctId ,
289+ array $ groups = array (),
290+ array $ personProperties = array (),
291+ array $ groupProperties = array (),
292+ bool $ onlyEvaluateLocally = false ,
293+ bool $ sendFeatureFlagEvents = true
294+ ): ?FeatureFlagResult {
257295 [$ personProperties , $ groupProperties ] = $ this ->addLocalPersonAndGroupProperties (
258296 $ distinctId ,
259297 $ groups ,
260298 $ personProperties ,
261299 $ groupProperties
262300 );
263301 $ result = null ;
302+ $ payload = null ;
264303 $ featureFlagError = null ;
265304
266305 foreach ($ this ->featureFlags as $ flag ) {
@@ -309,6 +348,12 @@ public function getFeatureFlag(
309348 $ result = null ;
310349 }
311350
351+ // Extract payload from response
352+ $ rawPayload = $ response ['featureFlagPayloads ' ][$ key ] ?? null ;
353+ if ($ rawPayload !== null ) {
354+ $ payload = json_decode ($ rawPayload , true );
355+ }
356+
312357 if (!empty ($ errors )) {
313358 $ featureFlagError = implode (', ' , $ errors );
314359 }
@@ -371,13 +416,22 @@ public function getFeatureFlag(
371416 $ this ->distinctIdsFeatureFlagsReported ->add ($ key , $ distinctId );
372417 }
373418
374- if (!is_null ($ result )) {
375- return $ result ;
419+ if (is_null ($ result )) {
420+ return null ;
421+ }
422+
423+ // Determine enabled and variant from result
424+ if (is_bool ($ result )) {
425+ return new FeatureFlagResult ($ key , $ result , null , $ payload );
426+ } else {
427+ return new FeatureFlagResult ($ key , true , $ result , $ payload );
376428 }
377- return null ;
378429 }
379430
380431 /**
432+ * @deprecated Use `getFeatureFlagResult()` instead which properly tracks the feature flag call,
433+ * and includes both the flag value and payload in a single method.
434+ *
381435 * @param string $key
382436 * @param string $distinctId
383437 * @param array $groups
@@ -392,20 +446,17 @@ public function getFeatureFlagPayload(
392446 array $ personProperties = array (),
393447 array $ groupProperties = array (),
394448 ): mixed {
395- $ results = $ this ->flags ($ distinctId , $ groups , $ personProperties , $ groupProperties );
396-
397- if (isset ($ results ['featureFlags ' ][$ key ]) === false || $ results ['featureFlags ' ][$ key ] !== true ) {
398- return null ;
399- }
400-
401- $ payload = $ results ['featureFlagPayloads ' ][$ key ] ?? null ;
402-
403- if ($ payload === null ) {
404- return null ;
405- }
449+ $ result = $ this ->getFeatureFlagResult (
450+ $ key ,
451+ $ distinctId ,
452+ $ groups ,
453+ $ personProperties ,
454+ $ groupProperties ,
455+ false ,
456+ false
457+ );
406458
407- # feature flag payloads are always JSON encoded strings.
408- return json_decode ($ payload , true );
459+ return $ result ?->getPayload();
409460 }
410461
411462 /**
0 commit comments