• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wingify / vwo-php-sdk / 6336712340

28 Sep 2023 08:52AM UTC coverage: 92.367% (-0.2%) from 92.609%
6336712340

push

github

rohitesh-wingify
fix(userStorageMAB): check userStorage is configured if campaign has MAB enabled

14 of 14 new or added lines in 2 files covered. (100.0%)

1924 of 2083 relevant lines covered (92.37%)

85.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.12
/src/VWO.php
1
<?php
2

3
/**
4
 * Copyright 2019-2022 Wingify Software Pvt. Ltd.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *    http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18

19
namespace vwo;
20

21
use Exception as Exception;
22
use vwo\Constants\Constants as Constants;
23
use vwo\Constants\EventEnum;
24
use vwo\Constants\FileNameEnum;
25
use vwo\Constants\Urls;
26
use vwo\Constants\Urls as UrlConstants;
27
use vwo\Constants\CampaignTypes;
28
use vwo\Services\HooksManager;
29
use vwo\Services\UsageStats;
30
use vwo\Storage\UserStorageInterface;
31
use vwo\Utils\AccountUtil;
32
use vwo\Utils\Campaign as CampaignUtil;
33
use vwo\Utils\Common as CommonUtil;
34
use vwo\Utils\DataLocationManager;
35
use vwo\Utils\Validations as ValidationsUtil;
36
use vwo\Utils\ImpressionBuilder as ImpressionBuilder;
37
use vwo\Utils\EventDispatcher as EventDispatcher;
38
use Monolog\Logger as Logger;
39
use vwo\Logger\LoggerInterface;
40
use vwo\Services\LoggerService as LoggerService;
41
use vwo\Logger\VWOLogger as VWOLogger;
42
use vwo\Core\Bucketer as Bucketer;
43
use vwo\Core\VariationDecider as VariationDecider;
44
use vwo\Utils\LogMessagesUtil;
45

46
/***
47
 * Class for exposing various APIs
48
 */
49
class VWO
50
{
51
    /****
52
     * @var static variables for log levels
53
     */
54

55
    // Levels are as per monolog docs - https://github.com/Seldaek/monolog/blob/master/doc/01-usage.md#log-levels
56
    static $LOG_LEVEL_DEBUG = 100;
57
    static $LOG_LEVEL_INFO = 200;
58
    static $LOG_LEVEL_WARNINGG = 300;
59
    static $LOG_LEVEL_ERROR = 400;
60

61
    const CLASSNAME = FileNameEnum::VWO;
62

63
    static $apiName;
64

65
    static $_variationDecider;
66
    /**
67
     * @var mixed|string to save settings
68
     */
69
    var $settings = '';
70
    /**
71
     * @var Connection to save connection object for curl requests
72
     */
73
    // var $connection;
74
    /**
75
     * @var string to save userStorage interface object
76
     */
77

78
    var $_userStorageObj;
79
    /**
80
     * @var int to save if dev mode is enabled or not
81
     */
82
    var $isDevelopmentMode;
83

84
    private $goalTypeToTrack;
85

86
    private $isOptedOut = false;
87

88
    const GOAL_TYPES = [
89
        'REVENUE' => 'REVENUE_TRACKING',
90
        'CUSTOM' => 'CUSTOM_GOAL',
91
        'ALL' => 'ALL'
92
    ];
93

94
    /**
95
     * VWO constructor.
96
     *
97
     * @param  $config
98
     * @throws Exception
99
     */
100
    function __construct($config)
101
    {
102
        self::$apiName = 'init';
432✔
103
        LoggerService::setApiName(self::$apiName);
432✔
104
        if (!is_array($config)) {
432✔
105
            return (object)[];
6✔
106
        }
107

108
        if (!ValidationsUtil::validateSDKConfiguration($config, self::$apiName)) {
426✔
109
            LoggerService::log(Logger::ERROR, 'CONFIG_CORRUPTED', [], self::CLASSNAME);
×
110
            return (object)[];
×
111
        }
112
        LogMessagesUtil::instance();
426✔
113

114
        $usageStats = [];
426✔
115
        // is settings and logger files are provided then set the values to the object
116
        $settings = isset($config['settingsFile']) ? $config['settingsFile'] : '';
426✔
117
        $logger = isset($config['logging']) ? $config['logging'] : null;
426✔
118
        if ($settings) {
426✔
119
            DataLocationManager::instance()->setSettings($settings);
420✔
120
        }
70✔
121

122
        // dev mode enable wont send tracking hits to the servers
123
        $this->isDevelopmentMode = (isset($config['isDevelopmentMode']) && $config['isDevelopmentMode'] == 1) ? 1 : 0;
426✔
124

125
        $this->eventDispatcher = new EventDispatcher($this->isDevelopmentMode);
426✔
126

127
        if ($logger == null) {
426✔
128
            $_logger = new VWOLogger(Logger::DEBUG, 'php://stdout');
36✔
129

130
            LoggerService::setLogger($_logger);
36✔
131
        } elseif ($logger instanceof LoggerInterface) {
396✔
132
            LoggerService::setLogger($logger);
390✔
133
            LoggerService::log(Logger::DEBUG, 'CONFIG_CUSTOM_LOGGER_USED', [], self::CLASSNAME);
390✔
134
            $usageStats['cl'] = 1;
390✔
135
        }
65✔
136

137
        // user storage service
138
        if (isset($config['userStorageService']) && ($config['userStorageService'] instanceof UserStorageInterface)) {
426✔
139
            $this->_userStorageObj = $config['userStorageService'];
84✔
140
            $usageStats['ss'] = 1;
84✔
141
        } else {
14✔
142
            $this->_userStorageObj = '';
342✔
143
        }
144

145
        if (isset($config['goalTypeToTrack'])) {
426✔
146
            if (array_key_exists($config['goalTypeToTrack'], self::GOAL_TYPES)) {
24✔
147
                $this->goalTypeToTrack = $config['goalTypeToTrack'];
24✔
148
                $usageStats['gt'] = 1;
24✔
149
            } else {
4✔
150
                LoggerService::log(Logger::ERROR, 'CONFIG_PARAMETER_INVALID', ['{parameter}' => 'goalTypeToTrack', '{api}' => self::$apiName, '{type}' => 'strings(REVENUE, CUSTOM, ALL)'], self::CLASSNAME);
20✔
151
            }
152
        } else {
4✔
153
            $this->goalTypeToTrack = 'ALL';
408✔
154
        }
155

156
        // initial logging started for each new object
157
        if ($this->isDevelopmentMode) {
426✔
158
            LoggerService::log(
204✔
159
                Logger::DEBUG,
204✔
160
                'CONFIG_DEVELOPMENT_MODE_STATUS',
204✔
161
                [],
204✔
162
                self::CLASSNAME
170✔
163
            );
34✔
164
        }
34✔
165

166
        $res = ValidationsUtil::checkSettingSchema($settings);
426✔
167
        if ($res) {
426✔
168
            $this->settings = CampaignUtil::makeRanges($settings);
414✔
169
            LoggerService::log(
414✔
170
                Logger::DEBUG,
414✔
171
                'SETTINGS_FILE_PROCESSED',
414✔
172
                ['{accountId}' => $this->settings['accountId']],
414✔
173
                self::CLASSNAME
345✔
174
            );
69✔
175
        } else {
69✔
176
            LoggerService::log(Logger::ERROR, 'SETTINGS_FILE_INVALID', [], self::CLASSNAME);
12✔
177
            return (object)[];
12✔
178
        }
179

180
        // $this->connection = new Connection();
181
        LoggerService::log(Logger::INFO, 'SDK_INITIALIZED', [], self::CLASSNAME);
414✔
182

183
        $this->variationDecider = new VariationDecider($this->settings);
414✔
184
        if (isset($this->settings['accountId'])) {
414✔
185
            $this->variationDecider->setAccountId($this->settings['accountId']);
414✔
186
            $accountUtil = AccountUtil::instance();
414✔
187
            $accountUtil->setAccountId($this->settings['accountId']);
414✔
188
        }
69✔
189
        // Initialize Hooks manager so that callbacks can be invoked
190
        $this->variationDecider->setHooksManager(new HooksManager($config));
414✔
191

192
        $this->usageStats = new UsageStats($usageStats, $config, $this->isDevelopmentMode);
414✔
193
        return $this;
414✔
194
    }
195

196
    /**
197
     * @param  String|Integer $accountId
198
     * @param  String         $sdkKey
199
     * @param  bool           $isTriggeredByWebhook
200
     * @return bool|mixed
201
     */
202
    public static function getSettingsFile($accountId, $sdkKey, $isTriggeredByWebhook = false)
203
    {
204
        self::$apiName = 'getSettingsFile';
12✔
205
        LoggerService::setApiName(self::$apiName);
12✔
206
        if (!$accountId || !$sdkKey) {
12✔
207
            LoggerService::log(Logger::ERROR, 'MISSING_IMPORT_SETTINGS_MANDATORY_PARAMS', [], self::CLASSNAME);
×
208
            return false;
1✔
209
        }
210
        try {
1✔
211
            $parameters = ImpressionBuilder::getSettingsFileQueryParams($accountId, $sdkKey);
12✔
212
            $eventDispatcher = new EventDispatcher(false);
12✔
213

214
            if ($isTriggeredByWebhook) {
12✔
215
                $url = UrlConstants::WEBHOOK_SETTINGS_URL;
6✔
216
            } else {
1✔
217
                $url = UrlConstants::SETTINGS_URL;
6✔
218
            }
219

220
            return $eventDispatcher->send($url, $parameters);
12✔
221
        } catch (Exception $e) {
×
222
            LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
×
223
        }
224
        return false;
×
225
    }
226

227
    /**
228
     * @param  $campaignKey
229
     * @param  $userId
230
     * @param  $options
231
     * @return bool|null
232
     */
233
    public function isFeatureEnabled($campaignKey, $userId, $options = [])
234
    {
235
        self::$apiName = 'isFeatureEnabled';
90✔
236
        LoggerService::setApiName(self::$apiName);
90✔
237
        $visitorUserAgent = CommonUtil::getValueFromOptions($options, 'userAgent');
90✔
238
        $userIpAddress = CommonUtil::getValueFromOptions($options, 'userIpAddress');
90✔
239

240
        if ($this->isOptedOut()) {
90✔
241
            return false;
6✔
242
        }
243

244
        try {
245
            if (!ValidationsUtil::validateIsFeatureEnabledParams($campaignKey, $userId, self::$apiName)) {
84✔
246
                LoggerService::log(Logger::ERROR, 'API_BAD_PARAMETERS', ['{api}' => self::$apiName], self::CLASSNAME);
6✔
247
                return null;
6✔
248
            }
249
            // get campaigns
250
            $campaign = ValidationsUtil::getCampaignFromCampaignKey($campaignKey, $this->settings, self::$apiName);
84✔
251
            // Check if MAB enabled, if yes, then userStorage must be defined
252
            if ($campaign != null && isset($campaign['isMAB']) && $campaign['isMAB']) {
84✔
253
                if ($this->_userStorageObj == null) {
×
254
                    LoggerService::log(Logger::ERROR, 'This campaign: ' .$campaignKey. ' has MAB configured. Please configure User Storage to proceed.', [], self::CLASSNAME);
×
255
                    return null;
×
256
                }
257
            }
258
            if ($campaign == null) {
84✔
259
                return null;
12✔
260
            }
261
            if ($campaign['type'] == CampaignTypes::AB) {
78✔
262
                LoggerService::log(
12✔
263
                    Logger::WARNING,
13✔
264
                    'CAMPAIGN_NOT_RUNNING',
12✔
265
                    ['{api}' => 'isFeatureEnabled', '{campaignKey}' => $campaignKey, '{userId}' => $userId],
12✔
266
                    self::CLASSNAME
10✔
267
                );
2✔
268
                return null;
13✔
269
            }
270

271
            $result['response'] = false;
78✔
272
            $variationData = $this->variationDecider->fetchVariationData($this->_userStorageObj, $campaign, $userId, $options, self::$apiName);
78✔
273
            // below condition says that if bucket is there and isFeatureEnabled is not present it means it will be feature rollout type campaign and return true
274
            // if isFeatureEnabled is there and it must be true then result is true
275
            // else return to false
276
            $result['response'] = ((isset($variationData) && !isset($variationData['isFeatureEnabled'])) || (isset($variationData['isFeatureEnabled']) && $variationData['isFeatureEnabled']) == true) ? true : false;
78✔
277

278
            if ($variationData) {
78✔
279
                if ($this->isEventArchEnabled()) {
60✔
280
                    $parameters = ImpressionBuilder::getEventsBaseProperties($this->settings['accountId'], $this->getSDKKey(), EventEnum::VWO_VARIATION_SHOWN, $visitorUserAgent, $userIpAddress, $this->usageStats->getUsageStats());
6✔
281
                    $payload = ImpressionBuilder::getTrackUserPayloadData(
6✔
282
                        $this->settings,
6✔
283
                        $userId,
4✔
284
                        EventEnum::VWO_VARIATION_SHOWN,
6✔
285
                        $campaign['id'],
6✔
286
                        $variationData['id']
6✔
287
                    );
1✔
288
                } else {
1✔
289
                    $parameters = ImpressionBuilder::getVisitorQueryParams(
54✔
290
                        $this->settings['accountId'],
54✔
291
                        $campaign,
36✔
292
                        $userId,
36✔
293
                        $variationData['id'],
54✔
294
                        $this->getSDKKey(),
54✔
295
                        $visitorUserAgent,
36✔
296
                        $userIpAddress
27✔
297
                    );
9✔
298
                    $parameters = array_merge($parameters, $this->usageStats->getUsageStats());
54✔
299
                }
300
            }
10✔
301

302
            if (isset($variationData) && $result['response'] == false) {
78✔
303
                if ($this->isEligibleToSendImpressionToVWO()) {
22✔
304
                    if ($this->isEventArchEnabled()) {
22✔
305
                        $response = $this->eventDispatcher->sendEventRequest($parameters, $payload);
6✔
306
                    } else {
1✔
307
                        LoggerService::log(
16✔
308
                            Logger::DEBUG,
16✔
309
                            'IMPRESSION_FOR_TRACK_USER',
16✔
310
                            ['{properties}' => $this->getAllowedToLogImpressionParams($parameters)],
16✔
311
                            self::CLASSNAME
13✔
312
                        );
3✔
313
                        $response = $this->eventDispatcher->sendAsyncRequest(CommonUtil::getUrl(Urls::TRACK_USER_ENDPOINT), 'GET', $parameters);
16✔
314
                    }
315
                    LoggerService::log(
22✔
316
                        Logger::INFO,
22✔
317
                        'FEATURE_STATUS',
22✔
318
                        ['{campaignKey}' => $campaignKey, '{userId}' => $userId, '{status}' => 'disabled'],
22✔
319
                        self::CLASSNAME
18✔
320
                    );
4✔
321
                    if ($response) {
22✔
322
                        LoggerService::log(
10✔
323
                            Logger::INFO,
10✔
324
                            'IMPRESSION_SUCCESS',
10✔
325
                            [
326
                                '{endPoint}' => 'track-user',
10✔
327
                                '{mainKeys}' => json_encode(["campaignId" => $campaign['id']]),
10✔
328
                                '{accountId}' => $this->settings['accountId']
10✔
329
                            ],
2✔
330
                            self::CLASSNAME
18✔
331
                        );
2✔
332
                    }
2✔
333
                } else {
4✔
334
                    LoggerService::log(
×
335
                        Logger::INFO,
×
336
                        'CAMPAIGN_USER_ALREADY_TRACKED',
×
337
                        ['{userId}' => $userId, '{campaignKey}' => $campaignKey, '{api}' => self::$apiName],
×
338
                        self::CLASSNAME
339
                    );
340
                }
341
                return false;
22✔
342
            }
343
            if ($result !== false && isset($result['response']) && $result['response'] == true && isset($variationData)) {
74✔
344
                if ($this->isEligibleToSendImpressionToVWO()) {
56✔
345
                    if ($this->isEventArchEnabled()) {
56✔
346
                        $response = $this->eventDispatcher->sendEventRequest($parameters, $payload);
6✔
347
                    } else {
1✔
348
                        LoggerService::log(
50✔
349
                            Logger::DEBUG,
50✔
350
                            'IMPRESSION_FOR_TRACK_USER',
50✔
351
                            ['{properties}' => $this->getAllowedToLogImpressionParams($parameters)],
50✔
352
                            self::CLASSNAME
42✔
353
                        );
8✔
354
                        $response = $this->eventDispatcher->sendAsyncRequest(CommonUtil::getUrl(Urls::TRACK_USER_ENDPOINT), 'GET', $parameters);
50✔
355
                    }
356
                    LoggerService::log(
56✔
357
                        Logger::INFO,
56✔
358
                        'FEATURE_STATUS',
56✔
359
                        ['{campaignKey}' => $campaignKey, '{userId}' => $userId, '{status}' => 'enabled'],
56✔
360
                        self::CLASSNAME
47✔
361
                    );
9✔
362

363
                    if ($response) {
56✔
364
                        LoggerService::log(
32✔
365
                            Logger::INFO,
32✔
366
                            'IMPRESSION_SUCCESS',
32✔
367
                            [
368
                                '{mainKeys}' => json_encode(["campaignId" => $campaign['id']]),
32✔
369
                                '{endPoint}' => Urls::TRACK_USER_ENDPOINT,
32✔
370
                                '{campaignId}' => $campaign['id'],
32✔
371
                                '{accountId}' => $this->settings['accountId']
32✔
372
                            ],
5✔
373
                            self::CLASSNAME
47✔
374
                        );
5✔
375
                    }
5✔
376
                } else {
9✔
377
                    LoggerService::log(
×
378
                        Logger::INFO,
×
379
                        'CAMPAIGN_USER_ALREADY_TRACKED',
×
380
                        ['{userId}' => $userId, '{campaignKey}' => $campaignKey, '{api}' => self::$apiName],
×
381
                        self::CLASSNAME
382
                    );
383
                }
384
                return true;
56✔
385
            }
386
            return $campaign['type'] == CampaignTypes::FEATURE_ROLLOUT ? false : null;
30✔
387
        } catch (Exception $e) {
6✔
388
            LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
6✔
389
        }
390

391
        return isset($campaign) && isset($campaign['type']) && ($campaign['type'] == CampaignTypes::FEATURE_ROLLOUT) ? false : null;
6✔
392
    }
393

394
    /**
395
     * @param  $campaignKey
396
     * @param  $variableKey
397
     * @param  $userId
398
     * @return bool|float|int|null|string
399
     */
400
    public function getFeatureVariableValue($campaignKey, $variableKey, $userId, $options = [])
401
    {
402
        self::$apiName = 'getFeatureVariableValue';
90✔
403
        LoggerService::setApiName(self::$apiName);
90✔
404

405
        if ($this->isOptedOut()) {
90✔
406
            return false;
6✔
407
        }
408

409
        try {
410
            if (!ValidationsUtil::validateIsFeatureEnabledParams($campaignKey, $userId, self::$apiName)) {
84✔
411
                LoggerService::log(Logger::ERROR, 'API_BAD_PARAMETERS', ['{api}' => self::$apiName], self::CLASSNAME);
6✔
412
                return null;
6✔
413
            }
414

415
            $campaign = ValidationsUtil::getCampaignFromCampaignKey($campaignKey, $this->settings, self::$apiName);
84✔
416
            if ($campaign != null && $campaign['type'] == CampaignTypes::AB) {
84✔
417
                LoggerService::log(
6✔
418
                    Logger::ERROR,
6✔
419
                    'API_NOT_APPLICABLE',
6✔
420
                    [
421
                        '{api}' => 'getFeatureVariableValue',
6✔
422
                        '{userId}' => $userId,
6✔
423
                        '{campaignKey}' => $campaignKey,
6✔
424
                        '{campaignType}' => 'SERVER AB'
5✔
425
                    ],
1✔
426
                    self::CLASSNAME
5✔
427
                );
1✔
428
                return null;
6✔
429
            }
430
            $value = null;
78✔
431

432
            $featureData['response'] = false;
78✔
433
            $variationData = $this->variationDecider->fetchVariationData($this->_userStorageObj, $campaign, $userId, $options, self::$apiName);
78✔
434
            $featureData['variationData'] = $variationData;
72✔
435
            // below condition says that if bucket is there and isFeatureEnabled is not present it means it will be feature rollout type campaign and return true
436
            // if isFeatureEnabled is there and it must be true then result is true
437
            // else return to false
438
            $featureData['response'] = ((isset($variationData) && !isset($variationData['isFeatureEnabled'])) || (isset($variationData['isFeatureEnabled']) && $variationData['isFeatureEnabled']) == true) ? true : false;
72✔
439

440
            if ($featureData) {
72✔
441
                if (isset($featureData['variationData'])) {
72✔
442
                    if ($campaign['type'] == CampaignTypes::FEATURE_ROLLOUT) {
54✔
443
                        $featureVariable = $campaign['variables'];
36✔
444
                    } else {
6✔
445
                        // it is part of feature test
446
                        if ($featureData['response'] == 1 && isset($featureData['variationData']['variables'])) {
18✔
447
                            $featureVariable = $featureData['variationData']['variables'];
18✔
448
                        } else {
3✔
449
                            $featureVariable = CommonUtil::fetchControlVariation(
6✔
450
                                $campaign['variations']
6✔
451
                            )['variables'];
6✔
452
                        }
453
                    }
454
                    $value = CommonUtil::getVariableValue($featureVariable, $variableKey);
54✔
455
                }
9✔
456
            }
12✔
457
            if ($value == null) {
72✔
458
                LoggerService::log(
30✔
459
                    Logger::INFO,
30✔
460
                    'FEATURE_VARIABLE_DEFAULT_VALUE',
30✔
461
                    [
462
                        '{variableKey}' => $variableKey,
30✔
463
                        '{variationName}' => $variationData["name"]
30✔
464
                    ],
5✔
465
                    self::CLASSNAME
21✔
466
                );
5✔
467
            } else {
5✔
468
                if (is_array($value)) {
54✔
469
                    $value = json_encode($value);
×
470
                }
471
                LoggerService::log(
54✔
472
                    Logger::INFO,
54✔
473
                    'FEATURE_VARIABLE_VALUE',
54✔
474
                    [
475
                        '{userId}' => $userId,
54✔
476
                        '{variableKey}' => $variableKey,
54✔
477
                        '{campaignKey}' => $campaignKey,
54✔
478
                        '{variableValue}' => $value
45✔
479
                    ],
9✔
480
                    self::CLASSNAME
45✔
481
                );
9✔
482
            }
483

484
            return $value;
69✔
485
        } catch (Exception $e) {
10✔
486
            LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
10✔
487
        }
488

489
        return null;
10✔
490
    }
491

492
    /**
493
     * API for track the user goals and revenueValue
494
     *
495
     * @param  string $campaignKey
496
     * @param  string $userId
497
     * @param  string $goalIdentifier
498
     * @param  array  $options
499
     * @return array|bool|null
500
     */
501
    public function track($campaignKey = '', $userId = '', $goalIdentifier = '', array $options = [])
502
    {
503
        self::$apiName = 'track';
156✔
504
        LoggerService::setApiName(self::$apiName);
156✔
505

506
        if ($this->isOptedOut()) {
156✔
507
            return false;
12✔
508
        }
509

510
        $revenueValue = CommonUtil::getValueFromOptions($options, 'revenueValue');
144✔
511
        $bucketInfo = null;
144✔
512

513
        if (
514
            empty($userId)
144✔
515
            || empty($goalIdentifier)
120✔
516
            || !(is_null($campaignKey) || is_array($campaignKey) || is_string($campaignKey))
144✔
517
        ) {
24✔
518
            LoggerService::log(Logger::ERROR, 'API_BAD_PARAMETERS', ['{api}' => self::$apiName], self::CLASSNAME);
6✔
519
            return null;
6✔
520
        }
521

522
        $goalTypeToTrack = $this->getGoalTypeToTrack($options);
144✔
523
        $campaigns = ValidationsUtil::getCampaigns($campaignKey, $this->settings, $goalIdentifier, $goalTypeToTrack, self::$apiName);
144✔
524

525
        if (empty($campaigns)) {
144✔
526
            return null;
30✔
527
        }
528

529
        $metricMap = [];
132✔
530
        $revenueProps = [];
132✔
531
        $result = [];
132✔
532
        $batchEventData = [];
132✔
533
        $eventProperties = CommonUtil::getValueFromOptions($options, 'eventProperties');
132✔
534
        $visitorUserAgent = CommonUtil::getValueFromOptions($options, 'userAgent');
132✔
535
        $userIpAddress = CommonUtil::getValueFromOptions($options, 'userIpAddress');
132✔
536

537
        if (!$eventProperties) {
132✔
538
            $eventProperties = [];
120✔
539
        }
20✔
540

541
        foreach ($campaigns as $campaign) {
132✔
542
            // Check if MAB enabled, if yes, then userStorage must be defined
543
            if ($campaign != null && isset($campaign['isMAB']) && $campaign['isMAB']) {
132✔
544
                if ($this->_userStorageObj == null) {
×
545
                    LoggerService::log(Logger::ERROR, 'This campaign: ' .$campaignKey. ' has MAB configured. Please configure User Storage to proceed.', [], self::CLASSNAME);
×
546
                    return null;
×
547
                }
548
            }
549
            try {
550
                if ($campaign['type'] == CampaignTypes::FEATURE_ROLLOUT) {
132✔
551
                    LoggerService::log(
6✔
552
                        Logger::ERROR,
6✔
553
                        'API_NOT_APPLICABLE',
6✔
554
                        [
555
                            '{api}' => 'track',
6✔
556
                            '{userId}' => $userId,
6✔
557
                            '{campaignKey}' => $campaign['key'],
6✔
558
                            '{campaignType}' => $campaign['type']
6✔
559
                        ],
1✔
560
                        self::CLASSNAME
5✔
561
                    );
1✔
562
                    $result[$campaign['key']] = null;
6✔
563
                    continue;
6✔
564
                }
565

566
                $bucketInfo = $this->variationDecider->fetchVariationData($this->_userStorageObj, $campaign, $userId, $options, self::$apiName, $goalIdentifier);
126✔
567
                if ($bucketInfo === null) {
120✔
568
                    $result[$campaign['key']] = null;
60✔
569
                    continue;
60✔
570
                }
571

572
                $goal = CommonUtil::getGoalFromGoals($campaign['goals'], $goalIdentifier);
96✔
573
                $goalId = isset($goal['id']) ? $goal['id'] : 0;
96✔
574
                $mca = isset($goal['mca']) ? $goal['mca'] : null;
96✔
575
                if ($goalId && isset($bucketInfo['id']) && $bucketInfo['id'] > 0) {
96✔
576
                    if ($goal['type'] == "REVENUE_TRACKING") {
96✔
577
                        if ($this->isEventArchEnabled()) {
42✔
578
                            if (!$revenueValue) {
30✔
579
                                $doesRevenuePropExist = false;
30✔
580

581
                                if (isset($goal['revenueProp'])) {
30✔
582
                                    $doesRevenuePropExist = true;
24✔
583
                                }
4✔
584

585
                                //If it's a metric of type - value of an event property and calculation logic is first Value (mca doesn't exist)
586
                                if (!isset($mca)) {
30✔
587
                                    /*
588
                                    In this case it is expected that goal will have revenueProp
589
                                    Error should be logged if eventProperties is not Defined ` OR ` eventProperties does not have revenueProp key
590
                                */
591
                                    if (!isset($eventProperties) || !array_key_exists($goal['revenueProp'], $eventProperties)) {
24✔
592
                                        LoggerService::log(
12✔
593
                                            Logger::ERROR,
12✔
594
                                            'TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL',
12✔
595
                                            [
596
                                                '{goalIdentifier}' => $goalIdentifier,
12✔
597
                                                '{campaignKey}' => $campaign['key'],
12✔
598
                                                '{userId}' => $userId
10✔
599
                                            ],
2✔
600
                                            self::CLASSNAME
10✔
601
                                        );
2✔
602
                                        $result[$campaign['key']] = null;
12✔
603
                                        continue;
22✔
604
                                    }
605
                                } else {
2✔
606
                                    /*
607
                                here mca == -1 so there could only be 2 scenarios,
608
                                1. If revenueProp is defined then eventProperties should have revenueProp key
609
                                2. if revenueProp is not defined then it's a metric of type - Number of times an event has been triggered.
610
                                */
611
                                    if ($doesRevenuePropExist) {
6✔
612
                                        // Error should be logged if eventProperties is not Defined ` OR ` eventProperties does not have revenueProp key
613
                                        if (!isset($eventProperties) || !array_key_exists($goal['revenueProp'], $eventProperties)) {
×
614
                                            LoggerService::log(
×
615
                                                Logger::ERROR,
×
616
                                                'TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL',
×
617
                                                [
618
                                                    '{goalIdentifier}' => $goalIdentifier,
×
619
                                                    '{campaignKey}' => $campaign['key'],
×
620
                                                    '{userId}' => $userId
621
                                                ],
622
                                                self::CLASSNAME
623
                                            );
624
                                            $result[$campaign['key']] = null;
×
625
                                            continue;
15✔
626
                                        }
627
                                    }
628
                                }
629
                            } else {
3✔
630
                                $revProp = $goal['revenueProp'];
×
631
                                $eventProperties[$revProp] = $revenueValue;
15✔
632
                            }
633
                        } elseif (is_null($revenueValue)) {
15✔
634
                            LoggerService::log(
6✔
635
                                Logger::ERROR,
6✔
636
                                'TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL',
6✔
637
                                [
638
                                    '{goalIdentifier}' => $goalIdentifier,
6✔
639
                                    '{campaignKey}' => $campaign['key'],
6✔
640
                                    '{userId}' => $userId
5✔
641
                                ],
1✔
642
                                self::CLASSNAME
5✔
643
                            );
1✔
644
                            $result[$campaign['key']] = null;
6✔
645
                            continue;
6✔
646
                         }
647
                    }
5✔
648

649
                    if (isset($goalIdentifier)) {
84✔
650
                        if (isset($bucketInfo['goalIdentifier'])) {
84✔
651
                            $identifiers = explode("_vwo_", $bucketInfo['goalIdentifier']);
6✔
652
                        } else {
1✔
653
                            $bucketInfo['goalIdentifier'] = '';
78✔
654
                            $identifiers = [];
78✔
655
                        }
656

657

658
                        if (!in_array($goalIdentifier, $identifiers)) {
84✔
659
                            $bucketInfo['goalIdentifier'] .=  "_vwo_$goalIdentifier";
78✔
660
                            if (!empty($this->_userStorageObj)) {
78✔
661
                                $this->variationDecider->userStorageSet($this->_userStorageObj, $userId, $campaign['key'], $bucketInfo, $bucketInfo['goalIdentifier']);
67✔
662
                            }
2✔
663
                        } elseif ($mca != -1) {
19✔
664
                            LoggerService::log(
6✔
665
                                Logger::INFO,
6✔
666
                                'CAMPAIGN_GOAL_ALREADY_TRACKED',
6✔
667
                                [
668
                                    '{goalIdentifier}' => $goalIdentifier,
6✔
669
                                    '{campaignKey}' => $campaign['key'],
6✔
670
                                    '{userId}' => $userId
5✔
671
                                ],
1✔
672
                                self::CLASSNAME
5✔
673
                            );
1✔
674
                            $result[$campaign['key']] = false;
6✔
675
                            continue;
6✔
676
                        }
677
                    }
13✔
678

679
                    if ($this->isEventArchEnabled()) {
78✔
680
                        if ($goal['type'] == "REVENUE_TRACKING" && isset($goal['revenueProp']) && !in_array($goal['revenueProp'], $revenueProps)) {
18✔
681
                            $revenueProps[] = $goal['revenueProp'];
12✔
682
                        }
2✔
683
                        $metricMap[$campaign['id']] = $goal["id"];
18✔
684
                    } else {
3✔
685
                        if (count($campaigns) == 1) {
60✔
686
                            $parameters = ImpressionBuilder::getConversionQueryParams(
42✔
687
                                $this->settings['accountId'],
42✔
688
                                $campaign,
28✔
689
                                $userId,
28✔
690
                                $bucketInfo['id'],
42✔
691
                                $goal,
28✔
692
                                $revenueValue,
28✔
693
                                $this->getSDKKey(),
42✔
694
                                $visitorUserAgent,
28✔
695
                                $userIpAddress
21✔
696
                            );
7✔
697
                            LoggerService::log(
42✔
698
                                Logger::DEBUG,
42✔
699
                                'IMPRESSION_FOR_TRACK_GOAL',
42✔
700
                                ['{properties}' => $this->getAllowedToLogImpressionParams($parameters)],
42✔
701
                                self::CLASSNAME
35✔
702
                            );
7✔
703
                            $resp = $this->eventDispatcher->sendAsyncRequest(CommonUtil::getUrl(Urls::TRACK_GOAL_ENDPOINT), 'GET', $parameters);
42✔
704
                            if ($resp) {
42✔
705
                                LoggerService::log(
12✔
706
                                    Logger::INFO,
12✔
707
                                    'IMPRESSION_SUCCESS',
12✔
708
                                    [
709
                                        '{endPoint}' => Urls::TRACK_GOAL_ENDPOINT,
12✔
710
                                        '{mainKeys}' => json_encode(["campaignId" => $campaign['id'], "variationId" => $bucketInfo['id'], "goalId" => $goal['id']]),
12✔
711
                                        '{accountId}' => $this->settings['accountId']
12✔
712
                                    ],
2✔
713
                                    self::CLASSNAME
35✔
714
                                );
2✔
715
                            }
2✔
716
                        } else {
7✔
717
                            $batchEventData["ev"][] = ImpressionBuilder::getTrackBatchEventData($this->settings['accountId'], $userId, $campaign['id'], $bucketInfo['id'], $goal, $revenueValue);
18✔
718
                        }
719
                    }
720

721
                    if ($this->isDevelopmentMode) {
78✔
722
                        $result[$campaign['key']] = true;
66✔
723
                        continue;
66✔
724
                    }
725

726
                    $result[$campaign['key']] = true;
12✔
727
                } else {
2✔
728
                    LoggerService::log(
×
729
                        Logger::ERROR,
×
730
                        'TRACK_API_GOAL_NOT_FOUND',
×
731
                        ['{campaignKey}' => $campaign['key'], '{userId}' => $userId, "{goalIdentifier}" => $goalIdentifier],
×
732
                        self::CLASSNAME
733
                    );
734

735
                    $result[$campaign['key']] = null;
10✔
736
                }
737
            } catch (Exception $e) {
8✔
738
                LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
10✔
739
            }
740
        }
22✔
741

742
        if ($this->isEventArchEnabled()) {
132✔
743
            $parameters = ImpressionBuilder::getEventsBaseProperties($this->settings['accountId'], $this->getSDKKey(), $goalIdentifier, $visitorUserAgent, $userIpAddress);
30✔
744
            $payload = ImpressionBuilder::getTrackGoalPayloadData(
30✔
745
                $this->settings,
30✔
746
                $userId,
20✔
747
                $goalIdentifier,
20✔
748
                $metricMap,
20✔
749
                $eventProperties
15✔
750
            );
5✔
751

752
            $eventArchResponse = $this->eventDispatcher->sendEventRequest($parameters, $payload);
30✔
753
            if ($eventArchResponse) {
30✔
754
                LoggerService::log(
24✔
755
                    Logger::INFO,
24✔
756
                    'IMPRESSION_SUCCESS_FOR_EVENT_ARCH',
24✔
757
                    [
758
                        '{accountId}' => $parameters["a"],
24✔
759
                        '{event}' => 'visitor property:' . json_encode($payload["d"]["visitor"]["props"]),
24✔
760
                        '{endPoint}' => CommonUtil::getEventsUrl()
24✔
761
                    ],
4✔
762
                    self::CLASSNAME
25✔
763
                );
4✔
764
            }
4✔
765
        } elseif (count($batchEventData)) {
107✔
766
            $parameters = ImpressionBuilder::getBatchEventQueryParams($this->settings['accountId'], $this->getSDKKey(), $this->usageStats->getUsageStats());
18✔
767
            LoggerService::log(
18✔
768
                Logger::DEBUG,
18✔
769
                'IMPRESSION_FOR_TRACK_GOAL',
18✔
770
                ['{properties}' => json_encode($batchEventData)],
18✔
771
                self::CLASSNAME
15✔
772
            );
3✔
773
            $batchEventsResponse = $this->eventDispatcher->sendBatchEventRequest($this->getSDKKey(), $parameters, $batchEventData);
18✔
774
        }
3✔
775

776
        if (count($result) == 0 || (count($batchEventData) && !$batchEventsResponse)) {
132✔
777
            return null;
6✔
778
        }
779
        if (is_string($campaignKey)) {
126✔
780
            return $result[$campaignKey];
108✔
781
        }
782
        return $result;
18✔
783
    }
784

785
    /**
786
     * to send variation name along with api hit to send add visitor hit
787
     *
788
     * @param  string $campaignKey
789
     * @param  string $userId
790
     * @param  array  $options
791
     * @return string|null
792
     */
793
    public function activate($campaignKey, $userId, $options = [])
794
    {
795
        self::$apiName = 'activate';
174✔
796
        LoggerService::setApiName(self::$apiName);
174✔
797

798
        if ($this->isOptedOut()) {
174✔
799
            return false;
12✔
800
        }
801

802
        return $this->getVariation($campaignKey, $userId, $options, 1, self::$apiName);
162✔
803
    }
804

805
    /**
806
     * fetch the variation name
807
     *
808
     * @param  $campaignKey
809
     * @param  $userId
810
     * @param  array  $options
811
     * @param  int    $trackVisitor
812
     * @param  string $apiName
813
     * @return null|string
814
     */
815
    private function getVariation($campaignKey, $userId, $options, $trackVisitor, $apiName)
816
    {
817
        if (empty($userId) || !is_string($campaignKey)) {
192✔
818
            LoggerService::log(Logger::ERROR, 'API_BAD_PARAMETERS', ['{api}' => self::$apiName], self::CLASSNAME);
×
819
            return null;
×
820
        }
821
        $visitorUserAgent = CommonUtil::getValueFromOptions($options, 'userAgent');
192✔
822
        $userIpAddress = CommonUtil::getValueFromOptions($options, 'userIpAddress');
192✔
823
        $bucketInfo = null;
192✔
824
        try {
825
            $campaign = ValidationsUtil::getCampaignFromCampaignKey($campaignKey, $this->settings, $apiName);
192✔
826
            // Check if MAB enabled, if yes, then userStorage must be defined
827
            if ($campaign != null && isset($campaign['isMAB']) && $campaign['isMAB']) {
192✔
828
                if ($this->_userStorageObj == null) {
12✔
829
                    LoggerService::log(Logger::ERROR, 'This campaign: ' .$campaignKey. ' has MAB configured. Please configure User Storage to proceed.', [], self::CLASSNAME);
6✔
830
                    return null;
6✔
831
                }
832
            }
1✔
833
            if ($campaign !== null) {
186✔
834
                if (($campaign['type'] == CampaignTypes::FEATURE_ROLLOUT) || ($campaign['type'] == CampaignTypes::FEATURE_TEST && $trackVisitor == 1)) {
180✔
835
                    LoggerService::log(
6✔
836
                        Logger::ERROR,
6✔
837
                        'API_NOT_APPLICABLE',
6✔
838
                        [
839
                            '{api}' => $trackVisitor == 1 ? 'activate' : 'getVariationName',
6✔
840
                            '{userId}' => $userId,
6✔
841
                            '{campaignKey}' => $campaignKey,
6✔
842
                            '{campaignType}' => $campaign['type']
6✔
843
                        ],
1✔
844
                        self::CLASSNAME
5✔
845
                    );
1✔
846
                    return $bucketInfo;
151✔
847
                }
848
            } else {
30✔
849
                return $bucketInfo;
6✔
850
            }
851
            $bucketInfo = $this->variationDecider->fetchVariationData($this->_userStorageObj, $campaign, $userId, $options, $trackVisitor ? 'activate' : 'getVariationName');
180✔
852
            if ($bucketInfo !== null) {
174✔
853
                if ($trackVisitor) {
144✔
854
                    if ($this->isEligibleToSendImpressionToVWO()) {
108✔
855
                        if ($this->isEventArchEnabled()) {
78✔
856
                            $parameters = ImpressionBuilder::getEventsBaseProperties($this->settings['accountId'], $this->getSDKKey(), EventEnum::VWO_VARIATION_SHOWN, $visitorUserAgent, $userIpAddress, $this->usageStats->getUsageStats());
6✔
857
                            $payload = ImpressionBuilder::getTrackUserPayloadData(
6✔
858
                                $this->settings,
6✔
859
                                $userId,
4✔
860
                                EventEnum::VWO_VARIATION_SHOWN,
6✔
861
                                $campaign['id'],
6✔
862
                                $bucketInfo['id']
6✔
863
                            );
1✔
864
                            $this->eventDispatcher->sendEventRequest($parameters, $payload);
6✔
865
                        } else {
1✔
866
                            $parameters = ImpressionBuilder::getVisitorQueryParams(
72✔
867
                                $this->settings['accountId'],
72✔
868
                                $campaign,
48✔
869
                                $userId,
48✔
870
                                $bucketInfo['id'],
72✔
871
                                $this->getSDKKey(),
72✔
872
                                $visitorUserAgent,
48✔
873
                                $userIpAddress
36✔
874
                            );
12✔
875

876
                            $parameters =  array_merge($parameters, $this->usageStats->getUsageStats());
72✔
877
                            $this->eventDispatcher->sendAsyncRequest(CommonUtil::getUrl(Urls::TRACK_USER_ENDPOINT), 'GET', $parameters);
72✔
878
                            LoggerService::log(
72✔
879
                                Logger::DEBUG,
72✔
880
                                'IMPRESSION_FOR_TRACK_USER',
72✔
881
                                ['{properties}' => $this->getAllowedToLogImpressionParams($parameters)],
72✔
882
                                self::CLASSNAME
60✔
883
                            );
12✔
884
                        }
885

886
                        if (!$this->isDevelopmentMode) {
78✔
887
                            if ($this->isEventArchEnabled()) {
6✔
888
                                LoggerService::log(
×
889
                                    Logger::INFO,
×
890
                                    'IMPRESSION_SUCCESS_FOR_EVENT_ARCH',
×
891
                                    [
892
                                        '{accountId}' => $parameters["a"],
×
893
                                        '{event}' => 'visitor property:' . json_encode($payload["d"]["visitor"]["props"]),
×
894
                                        '{endPoint}' => CommonUtil::getEventsUrl()
×
895
                                    ]
896
                                );
897
                            } else {
898
                                LoggerService::log(
6✔
899
                                    Logger::INFO,
6✔
900
                                    'IMPRESSION_SUCCESS',
6✔
901
                                    [
902
                                        '{mainKeys}' => json_encode(["campaignId" => $campaign['id'], "variationId" => $bucketInfo['id']]),
6✔
903
                                        '{endPoint}' => Urls::TRACK_USER_ENDPOINT,
6✔
904
                                        '{accountId}' => $this->settings['accountId']
6✔
905
                                    ],
1✔
906
                                    self::CLASSNAME
65✔
907
                                );
1✔
908
                            }
909
                        }
1✔
910
                    } else {
13✔
911
                        LoggerService::log(
36✔
912
                            Logger::INFO,
36✔
913
                            'CAMPAIGN_USER_ALREADY_TRACKED',
36✔
914
                            ['{userId}' => $userId, '{campaignKey}' => $campaignKey, '{api}' => self::$apiName],
36✔
915
                            self::CLASSNAME
30✔
916
                        );
6✔
917
                    }
918
                }
18✔
919

920
                return $bucketInfo['name'];
169✔
921
            }
922
        } catch (Exception $e) {
21✔
923
            LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
8✔
924
        }
925
        return null;
84✔
926
    }
927

928
    /**
929
     * Gets the variation assigned for the user for the campaign
930
     *
931
     * @param  string $campaignKey
932
     * @param  string $userId
933
     * @param  array  $options
934
     * @return string|null
935
     */
936
    public function getVariationName($campaignKey, $userId, $options = [])
937
    {
938
        self::$apiName = 'getVariationName';
108✔
939
        LoggerService::setApiName(self::$apiName);
108✔
940

941
        if ($this->isOptedOut()) {
108✔
942
            return false;
12✔
943
        }
944
        return $this->getVariation($campaignKey, $userId, $options, 0, self::$apiName);
96✔
945
    }
946

947
    /**
948
     * @param  $tagKey
949
     * @param  $tagValue
950
     * @param  $userId
951
     * @return array
952
     */
953
    public function push($tagKey, $tagValue, $userId = '')
954
    {
955
        self::$apiName = 'push';
30✔
956
        LoggerService::setApiName(self::$apiName);
30✔
957

958
        if ($this->isOptedOut()) {
30✔
959
            return [];
6✔
960
        }
961

962
        $customDimensionMap = [];
24✔
963
        //reshuffling
964
        if (!$userId || is_array($tagKey)) {
24✔
965
            $customDimensionMap = $tagKey;
18✔
966
            $userId = $tagValue;
18✔
967
        } else {
3✔
968
            $customDimensionMap[$tagKey] = $tagValue;
18✔
969
        }
970

971
        try {
972
            list($validParams, $respResult, $customDimensionMap) = ValidationsUtil::pushApiParams($userId, $customDimensionMap);
24✔
973
            if (!$validParams) {
24✔
974
                LoggerService::log(Logger::ERROR, 'API_BAD_PARAMETERS', ['{api}' => self::$apiName], self::CLASSNAME);
12✔
975
                return $respResult;
12✔
976
            }
977

978
            if ($this->isEventArchEnabled()) {
24✔
979
                $parameters = ImpressionBuilder::getEventsBaseProperties($this->settings['accountId'], $this->getSDKKey(), EventEnum::VWO_SYNC_VISITOR_PROP);
6✔
980
                $payload = ImpressionBuilder::getPushPayloadData(
6✔
981
                    $this->settings,
6✔
982
                    $userId,
4✔
983
                    EventEnum::VWO_SYNC_VISITOR_PROP,
6✔
984
                    $customDimensionMap
3✔
985
                );
1✔
986
                $result = $this->eventDispatcher->sendEventRequest($parameters, $payload);
6✔
987
            } else {
1✔
988
                if (count($customDimensionMap) == 1) {
18✔
989
                    foreach ($customDimensionMap as $tagKey => $tagValue) {
12✔
990
                        $parameters = ImpressionBuilder::getPushQueryParams($this->settings['accountId'], $userId, $this->getSDKKey(), $tagKey, $tagValue);
12✔
991
                        LoggerService::log(
12✔
992
                            Logger::DEBUG,
12✔
993
                            'IMPRESSION_FOR_PUSH',
12✔
994
                            ['{properties}' => $this->getAllowedToLogImpressionParams($parameters)],
12✔
995
                            self::CLASSNAME
10✔
996
                        );
2✔
997
                        $result = $this->eventDispatcher->sendAsyncRequest(CommonUtil::getUrl(Urls::PUSH_ENDPOINT), 'GET', $parameters);
12✔
998
                        if ($result) {
6✔
999
                            LoggerService::log(
6✔
1000
                                Logger::INFO,
6✔
1001
                                'IMPRESSION_SUCCESS',
6✔
1002
                                [
1003
                                    '{endPoint}' => Urls::PUSH_ENDPOINT,
6✔
1004
                                    '{accountId}' => $this->settings['accountId'],
6✔
1005
                                    '{mainKeys}' => json_encode(["tags" => $parameters['tags']])
6✔
1006
                                ],
1✔
1007
                                self::CLASSNAME
5✔
1008
                            );
1✔
1009
                        }
1✔
1010
                    }
1✔
1011
                } else {
1✔
1012
                    $postData = ImpressionBuilder::getPushBatchEventData($this->settings['accountId'], $userId, $customDimensionMap);
6✔
1013
                    LoggerService::log(
6✔
1014
                        Logger::DEBUG,
6✔
1015
                        'IMPRESSION_FOR_PUSH',
6✔
1016
                        ['{properties}' => json_encode($postData)],
6✔
1017
                        self::CLASSNAME
5✔
1018
                    );
1✔
1019
                    $parameters = ImpressionBuilder::getBatchEventQueryParams($this->settings['accountId'], $this->getSDKKey(), $this->usageStats->getUsageStats());
6✔
1020
                    $result = $this->eventDispatcher->sendBatchEventRequest($this->getSDKKey(), $parameters, $postData);
6✔
1021
                }
1022
            }
1023

1024
            if ($this->isDevelopmentMode) {
18✔
1025
                return $this->preparePushResponse($customDimensionMap, true, $respResult);
12✔
1026
            } elseif ($result) {
12✔
1027
                return $this->preparePushResponse($customDimensionMap, $result, $respResult);
12✔
1028
            }
1029
        } catch (Exception $e) {
6✔
1030
            LoggerService::log(Logger::ERROR, $e->getMessage(), [], self::CLASSNAME);
6✔
1031
        }
1032

1033
        return [];
6✔
1034
    }
1035

1036
    /**
1037
     * @param array $customDimensionMap
1038
     * @param bool  $result
1039
     * @param array $respResult
1040
     * @return array
1041
     */
1042
    private function preparePushResponse($customDimensionMap, $result, $respResult)
1043
    {
1044
        foreach ($customDimensionMap as $tagKey => $tagValue) {
18✔
1045
            $respResult[$tagKey] = $result;
18✔
1046
        }
3✔
1047
        return $respResult;
18✔
1048
    }
1049

1050
    public function getSDKKey()
1051
    {
1052
        $sdkKey = '';
222✔
1053
        if (isset($this->settings["sdkKey"])) {
222✔
1054
            $sdkKey = $this->settings["sdkKey"];
174✔
1055
        }
29✔
1056
        return $sdkKey;
222✔
1057
    }
1058

1059
    private function isEligibleToSendImpressionToVWO()
1060
    {
1061
        return (empty($this->_userStorageObj) ||
162✔
1062
            !$this->variationDecider->hasStoredVariation
141✔
1063
        );
27✔
1064
    }
1065

1066
    private function getGoalTypeToTrack($options)
1067
    {
1068
        $goalTypeToTrack = null;
144✔
1069
        if (!isset($options['goalTypeToTrack'])) {
144✔
1070
            if ($this->goalTypeToTrack) {
138✔
1071
                $goalTypeToTrack = $this->goalTypeToTrack;
138✔
1072
            } else {
23✔
1073
                $goalTypeToTrack = self::GOAL_TYPES['ALL'];
115✔
1074
            }
1075
        } elseif (array_key_exists($options['goalTypeToTrack'], self::GOAL_TYPES)) {
34✔
1076
            $goalTypeToTrack = $options['goalTypeToTrack'];
6✔
1077
        } else {
1✔
1078
            LoggerService::log(
6✔
1079
                Logger::ERROR,
6✔
1080
                'CONFIG_PARAMETER_INVALID',
6✔
1081
                ['{parameter}' => 'goalTypeToTrack', '{api}' => self::$apiName, '{type}' => 'strings(REVENUE, CUSTOM, ALL)'],
6✔
1082
                self::CLASSNAME
5✔
1083
            );
1✔
1084
        }
1085
        return $goalTypeToTrack;
144✔
1086
    }
1087

1088
    private function getAllowedToLogImpressionParams($parameters)
1089
    {
1090
        unset($parameters['env']);
150✔
1091
        return json_encode($parameters);
150✔
1092
    }
1093

1094
    /**
1095
     * Manually opting out of VWO SDK, No tracking will happen
1096
     *
1097
     * @return bool
1098
     */
1099
    public function setOptOut()
1100
    {
1101
        self::$apiName = 'optOut';
18✔
1102
        LoggerService::setApiName(self::$apiName);
18✔
1103

1104
        LoggerService::log(
18✔
1105
            Logger::INFO,
18✔
1106
            'OPT_OUT_API_CALLED',
18✔
1107
            [],
18✔
1108
            self::CLASSNAME
15✔
1109
        );
3✔
1110

1111
        $this->isOptedOut = true;
18✔
1112
        $this->settings = null;
18✔
1113
        $this->_userStorageObj = null;
18✔
1114
        $this->eventDispatcher = null;
18✔
1115
        $this->variationDecider = null;
18✔
1116
        return $this->isOptedOut;
18✔
1117
    }
1118

1119
    /**
1120
     * Check if VWO SDK is manually opted out
1121
     *
1122
     * @return bool
1123
     */
1124
    private function isOptedOut()
1125
    {
1126
        if ($this->isOptedOut) {
378✔
1127
            LoggerService::log(
12✔
1128
                Logger::INFO,
12✔
1129
                'API_NOT_ENABLED',
12✔
1130
                ['{api}' => self::$apiName],
12✔
1131
                self::CLASSNAME
10✔
1132
            );
2✔
1133
        }
2✔
1134
        return $this->isOptedOut;
378✔
1135
    }
1136

1137
    private function isEventArchEnabled()
1138
    {
1139
        return isset($this->settings['isEventArchEnabled']) && $this->settings['isEventArchEnabled'];
258✔
1140
    }
1141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc