Skip to content

Commit 54fd505

Browse files
author
sakshamg1304
committed
feat: web insights connectivity support with get/set sessionId methods
1 parent 23cedde commit 54fd505

File tree

11 files changed

+157
-24
lines changed

11 files changed

+157
-24
lines changed

CHANGELOG.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.18.0] - 2026-02-05
9+
10+
### Added
11+
12+
- Added session management capabilities to enable integration with VWO's web client testing campaigns. The SDK now automatically generates and manages session IDs to connect server-side feature flag decisions with client-side user sessions.
13+
14+
Example usage:
15+
16+
```php
17+
use vwo\VWO;
18+
19+
$options = [
20+
'sdkKey' => '32-alpha-numeric-sdk-key',
21+
'accountId' => '123456',
22+
];
23+
24+
$vwoClient = VWO::init($options);
25+
26+
// Session ID is automatically generated if not provided
27+
$context = ['id' => 'user-123'];
28+
$flag = $vwoClient->getFlag('feature-key', $context);
29+
30+
// Access the session ID to pass to web client for session recording
31+
$sessionId = $flag->getSessionId();
32+
echo "Session ID for web client: " . $sessionId;
33+
```
34+
35+
You can also explicitly set a session ID to match a web client session:
36+
37+
```php
38+
use vwo\VWO;
39+
40+
$vwoClient = VWO::init($options);
41+
42+
$userContext = [
43+
'id' => 'user-123',
44+
'sessionId' => 1697123456 // Custom session ID matching web client
45+
];
46+
47+
$flag = $vwoClient->getFlag('feature-key', $userContext);
48+
```
49+
50+
This enhancement enables seamless integration between server-side feature flag decisions and client-side session recording, allowing for comprehensive user behavior analysis across both server and client environments.
51+
852
## [1.17.0] - 2026-01-09
953

1054
### Added
@@ -309,4 +353,4 @@ $vwoClient->setAlias('userId', 'aliasId');
309353
// set Attribute
310354
$setAttribute = $vwoClient->setAttribute('attribute-name', 'attribute-value', $userContext);
311355

312-
```
356+
```

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,33 @@ $vwoClient->setAttribute($attributes, $userContext);
169169

170170
See [Pushing Attributes](https://developers.vwo.com/v2/docs/fme-php-attributes#usage) documentation for additional information.
171171

172+
### Generating UUID
173+
174+
The `getUUID` method allows you to generate a UUID that gets stored on VWO by providing a `userId` and `accountId`. This UUID is generated using a deterministic algorithm based on the user and account identifiers, ensuring consistent UUID generation for the same user-account combination.
175+
176+
| **Parameter** | **Description** | **Required** | **Type** | **Example** |
177+
| ------------- | ---------------------------------- | ------------ | -------- | ------------ |
178+
| `userId` | The unique identifier for the user | Yes | String | `'user-123'` |
179+
| `accountId` | The account ID | Yes | String | `'123456'` |
180+
181+
#### Return Value
182+
183+
Returns a UUID string formatted without dashes and in uppercase (e.g., `'CC25A368ADA0542699EAD62489811105'`).
184+
185+
#### Example Usage
186+
187+
```php
188+
use vwo\VWO;
189+
190+
// Generate UUID for a user
191+
$userId = 'user-123';
192+
$accountId = '123456';
193+
$uuid = VWO::getUUID($userId, $accountId);
194+
195+
echo 'Generated UUID:', $uuid;
196+
// Output: Generated UUID: CC25A368ADA0542699EAD62489811105
197+
```
198+
172199
### Polling Interval Adjustment
173200

174201
The `pollInterval` is an optional parameter that allows the SDK to automatically fetch and update settings from the VWO server at specified intervals. Setting this parameter ensures your application always uses the latest configuration.

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vwo/vwo-fme-php-sdk",
33

4-
"version": "1.17.0",
4+
"version": "1.18.0",
55
"keywords": ["vwo", "fme", "sdk"],
66
"license": "Apache-2.0",
77
"authors": [{
@@ -35,4 +35,4 @@
3535
"require-dev": {
3636
"phpunit/phpunit": "^6.5 || ^9.5"
3737
}
38-
}
38+
}

src/Api/GetFlag.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ public function get(
142142
return new GetFlagResultUtil(false, [], $ruleStatus);
143143
}
144144

145+
// Set session ID if not present
146+
if ($context->getSessionId() === null) {
147+
$context->setSessionId(FunctionUtil::getCurrentUnixTimestamp());
148+
}
149+
145150
$segmentationManager = $serviceContainer->getSegmentationManager();
146151
$segmentationManager->setContextualData($serviceContainer, $feature, $context);
147152

@@ -369,7 +374,7 @@ public function get(
369374
ImpressionUtil::SendImpressionForVariationShownInBatch($batchPayload, $serviceContainer);
370375
}
371376

372-
return new GetFlagResultUtil($isEnabled, $variablesForEvaluatedFlag, $ruleStatus);
377+
return new GetFlagResultUtil($isEnabled, $variablesForEvaluatedFlag, $ruleStatus, $context->getSessionId());
373378
}
374379

375380
private function updateIntegrationsDecisionObject(CampaignModel $campaign, VariationModel $variation, array &$passedRulesInformation, array &$decision)

src/Api/SetAttribute.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,9 @@ private function createImpressionForAttributes(SettingsModel $settings, array $a
7171
// Construct payload data for multiple attributes
7272
$payload = $networkUtil->getAttributePayloadData(
7373
$settings,
74-
$context->getId(),
74+
$context,
7575
EventEnum::VWO_SYNC_VISITOR_PROP,
76-
$attributes,
77-
$context->getUserAgent(),
78-
$context->getIpAddress()
76+
$attributes
7977
);
8078

8179
// Send the constructed payload via POST request

src/Api/TrackEvent.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,9 @@ private function createImpressionForTrack(SettingsModel $settings, string $event
9797
// Prepare the payload for the track goal
9898
$payload = $networkUtil->getTrackGoalPayloadData(
9999
$settings,
100-
$context->getId(),
100+
$context,
101101
$eventName,
102102
$eventProperties,
103-
$context->getUserAgent(),
104-
$context->getIpAddress()
105103
);
106104

107105
// Send the prepared payload via POST API request

src/Constants/Constants.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Constants {
4040
const DEFAULT_EVENTS_PER_REQUEST = 100;
4141
const SDK_NAME = 'vwo-fme-php-sdk';
4242

43-
const SDK_VERSION = '1.17.0';
43+
const SDK_VERSION = '1.18.0';
4444
const AP = 'server';
4545

4646
const SETTINGS = 'settings';

src/Models/User/ContextModel.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ContextModel
2727
private $variationTargetingVariables = [];
2828
private $_vwo;
2929
private $postSegmentationVariables = [];
30+
private $sessionId;
3031

3132
public function modelFromDictionary($context)
3233
{
@@ -50,6 +51,10 @@ public function modelFromDictionary($context)
5051
$this->postSegmentationVariables = $context['postSegmentationVariables'];
5152
}
5253

54+
if (isset($context['sessionId'])) {
55+
$this->sessionId = $context['sessionId'];
56+
}
57+
5358
return $this;
5459
}
5560

@@ -107,6 +112,16 @@ public function setPostSegmentationVariables($postSegmentationVariables)
107112
{
108113
$this->postSegmentationVariables = $postSegmentationVariables;
109114
}
115+
116+
public function getSessionId()
117+
{
118+
return $this->sessionId;
119+
}
120+
121+
public function setSessionId($sessionId)
122+
{
123+
$this->sessionId = $sessionId;
124+
}
110125
}
111126

112127
?>

src/Utils/GetFlagResultUtil.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,19 @@ class GetFlagResultUtil
2424
private $isEnabled;
2525
private $variables;
2626
private $ruleStatus;
27+
private $sessionId;
2728

28-
public function __construct($isEnabled, $variables, $ruleStatus)
29+
public function __construct($isEnabled, $variables, $ruleStatus, $sessionId = null)
2930
{
3031
$this->isEnabled = $isEnabled;
3132
$this->variables = $variables;
3233
$this->ruleStatus = $ruleStatus;
34+
$this->sessionId = $sessionId;
35+
}
36+
37+
public function getSessionId()
38+
{
39+
return $this->sessionId;
3340
}
3441

3542
public function isEnabled()

src/Utils/NetworkUtil.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public function getEventsBaseProperties($eventName, $visitorUserAgent = '', $ipA
188188
* @param int|null $usageStatsAccountId The account ID for usage statistics (optional)
189189
* @return array Array containing the base event payload structure
190190
*/
191-
public function getEventBasePayload($settings, $userId, $eventName, $visitorUserAgent = '', $ipAddress = '', $isUsageStatsEvent = false, $usageStatsAccountId = null) {
191+
public function getEventBasePayload($settings, $userId, $sessionId, $eventName, $visitorUserAgent = '', $ipAddress = '', $isUsageStatsEvent = false, $usageStatsAccountId = null) {
192192
$settingsService = $this->serviceContainer ? $this->serviceContainer->getSettingsService() : SettingsService::instance();
193193
$accountId = $isUsageStatsEvent ? $usageStatsAccountId : $settingsService->accountId;
194194
$uuid = UuidUtil::getUUID($userId, $accountId);
@@ -210,12 +210,13 @@ public function getEventBasePayload($settings, $userId, $eventName, $visitorUser
210210
// set env key for standard sdk events
211211
$props['vwo_envKey'] = $settingsService->sdkKey;
212212
}
213+
$sessionId = $sessionId !== null ? $sessionId : FunctionUtil::getCurrentUnixTimestamp();
213214

214215
$properties = [
215216
'd' => [
216217
'msgId' => "{$uuid}-" . FunctionUtil::getCurrentUnixTimestampInMillis(),
217218
'visId' => $uuid,
218-
'sessionId' => FunctionUtil::getCurrentUnixTimestamp(),
219+
'sessionId' => $sessionId,
219220
'event' => [
220221
'props' => $props,
221222
'name' => $eventName,
@@ -261,7 +262,7 @@ public function getTrackUserPayloadData($settings, $eventName, $campaignId, $var
261262
$postSegmentationVariables = $context->getPostSegmentationVariables();
262263
$customVariables = $context->getCustomVariables();
263264

264-
$properties = $this->getEventBasePayload($settings, $userId, $eventName, $visitorUserAgent, $ipAddress);
265+
$properties = $this->getEventBasePayload($settings, $userId, $context->getSessionId(), $eventName, $visitorUserAgent, $ipAddress);
265266

266267
$properties['d']['event']['props']['id'] = $campaignId;
267268
$properties['d']['event']['props']['variation'] = $variationId;
@@ -311,8 +312,8 @@ public function getTrackUserPayloadData($settings, $eventName, $campaignId, $var
311312
* @param string $ipAddress The IP address of the visitor (optional)
312313
* @return array Array containing the track goal payload data
313314
*/
314-
public function getTrackGoalPayloadData($settings, $userId, $eventName, $eventProperties, $visitorUserAgent = '', $ipAddress = '' ) {
315-
$properties = $this->getEventBasePayload($settings, $userId, $eventName, $visitorUserAgent, $ipAddress);
315+
public function getTrackGoalPayloadData($settings, $context, $eventName, $eventProperties) {
316+
$properties = $this->getEventBasePayload($settings, $context->getId(), $context->getSessionId(), $eventName, $context->getUserAgent(), $context->getIpAddress());
316317
$properties['d']['event']['props']['isCustomEvent'] = true;
317318
$properties['d']['event']['props']['variation'] = 1; // temporary value
318319
$properties['d']['event']['props']['id'] = 1; // temporary value
@@ -324,7 +325,7 @@ public function getTrackGoalPayloadData($settings, $userId, $eventName, $eventPr
324325
}
325326

326327
$this->serviceContainer->getLogManager()->debug(
327-
"IMPRESSION_FOR_TRACK_GOAL: Impression built for {$eventName} event for Account ID:{$settings->getAccountId()}, User ID:{$userId}"
328+
"IMPRESSION_FOR_TRACK_GOAL: Impression built for {$eventName} event for Account ID:{$settings->getAccountId()}, User ID:{$context->getId()}"
328329
);
329330

330331
return $properties;
@@ -341,8 +342,8 @@ public function getTrackGoalPayloadData($settings, $userId, $eventName, $eventPr
341342
* @param string $ipAddress The IP address of the visitor (optional)
342343
* @return array Array containing the attribute payload data
343344
*/
344-
public function getAttributePayloadData($settings, $userId, $eventName, $attributes, $visitorUserAgent = '', $ipAddress = '') {
345-
$properties = $this->getEventBasePayload($settings, $userId, $eventName, $visitorUserAgent, $ipAddress);
345+
public function getAttributePayloadData($settings, $context, $eventName, $attributes) {
346+
$properties = $this->getEventBasePayload($settings, $context->getId(), $context->getSessionId(), $eventName, $context->getUserAgent(), $context->getIpAddress());
346347
$properties['d']['event']['props']['isCustomEvent'] = true;
347348
$properties['d']['event']['props'][Constants::VWO_FS_ENVIRONMENT] = $settings->getSdkKey();
348349
// Iterate over the attributes map and append to the visitor properties
@@ -351,7 +352,7 @@ public function getAttributePayloadData($settings, $userId, $eventName, $attribu
351352
}
352353

353354
$this->serviceContainer->getLogManager()->debug(
354-
"IMPRESSION_FOR_SYNC_VISITOR_PROP: Impression built for {$eventName} event for Account ID: {$settings->getAccountId()}, User ID: {$userId}"
355+
"IMPRESSION_FOR_SYNC_VISITOR_PROP: Impression built for {$eventName} event for Account ID: {$settings->getAccountId()}, User ID: {$context->getId()}"
355356
);
356357

357358
return $properties;
@@ -466,7 +467,7 @@ public function sendGetApiRequest($properties, $endpoint) {
466467
public function getMessagingEventPayload($messageType, $message, $eventName) {
467468
$settingsService = $this->serviceContainer ? $this->serviceContainer->getSettingsService() : SettingsService::instance();
468469
$userId = $settingsService->accountId . '_' . $settingsService->sdkKey;
469-
$properties = $this->getEventBasePayload(null, $userId, $eventName, null, null);
470+
$properties = $this->getEventBasePayload(null, $userId, null, $eventName, null, null);
470471

471472
// Set environment key
472473
$properties['d']['event']['props'][Constants::VWO_FS_ENVIRONMENT] = $settingsService->sdkKey;
@@ -556,7 +557,7 @@ public function getSdkInitEventPayload($eventName, $settingsFetchTime = null, $s
556557
{
557558
$settingsService = $this->serviceContainer ? $this->serviceContainer->getSettingsService() : SettingsService::instance();
558559
$userId = $settingsService->accountId . '_' . $settingsService->sdkKey;
559-
$properties = $this->getEventBasePayload(null, $userId, $eventName, null, null);
560+
$properties = $this->getEventBasePayload(null, $userId, FunctionUtil::getCurrentUnixTimestamp(), $eventName, null, null);
560561

561562
// Set the required fields as specified
562563
$properties['d']['event']['props'][Constants::VWO_FS_ENVIRONMENT] = $settingsService->sdkKey;
@@ -590,6 +591,7 @@ public function getSDKUsageStatsEventPayload($eventName, $usageStatsAccountId)
590591
$properties = $this->getEventBasePayload(
591592
null,
592593
$userId,
594+
FunctionUtil::getCurrentUnixTimestamp(),
593595
$eventName,
594596
null,
595597
null,

0 commit comments

Comments
 (0)